service
service
¶
Validator service for BigBrotr.
Validates relay candidates discovered by the Finder service by checking whether they speak the Nostr protocol via WebSocket. Valid candidates are promoted to the relays table; invalid ones have their failure counter incremented and are retried in future cycles.
Validation criteria: a candidate is valid if it accepts a WebSocket connection and responds to a Nostr REQ message with EOSE, EVENT, NOTICE, or AUTH, as determined by is_nostr_relay.
Note
Each cycle initializes per-network semaphores from NetworksConfig, cleans up stale/exhausted candidates, then processes remaining candidates in configurable chunks. Candidate priority is ordered by fewest failures first (most likely to succeed).
See Also
ValidatorConfig:
Configuration model for networks, processing, and cleanup.
BaseService: Abstract base
class providing run(), run_forever(), and from_yaml().
Brotr: Database facade used for
candidate queries and relay promotion.
Finder: Upstream service that
discovers and inserts candidates.
Monitor: Downstream service
that health-checks promoted relays.
is_nostr_relay: WebSocket
probe function used for validation.
promote_candidates:
Atomic insert+delete query for promotion.
Examples:
from bigbrotr.core import Brotr
from bigbrotr.services import Validator
brotr = Brotr.from_yaml("config/brotr.yaml")
validator = Validator.from_yaml("config/services/validator.yaml", brotr=brotr)
async with brotr:
async with validator:
await validator.run_forever()
Classes¶
Candidate
dataclass
¶
Candidate(relay: Relay, data: dict[str, Any])
Relay candidate pending validation.
Wraps a Relay object with its
service_state metadata, providing convenient access to validation
state (e.g., failure count).
Attributes:
-
relay(Relay) –Relay object with URL and network information.
-
data(dict[str, Any]) –Metadata from the
service_statetable (network,failures, etc.).
See Also
fetch_candidate_chunk: Query that produces the rows from which candidates are built.
Validator
¶
Validator(
brotr: Brotr, config: ValidatorConfig | None = None
)
Bases: ChunkProgressMixin, NetworkSemaphoresMixin, BaseService[ValidatorConfig]
Validates relay candidates by checking if they speak the Nostr protocol.
Processes candidate URLs discovered by the Finder service. Valid relays are promoted to the relays table via promote_candidates; invalid ones have their failure counter incremented for retry in future cycles.
Each cycle initializes per-network semaphores via NetworkSemaphoresMixin, cleans up stale/exhausted candidates, then processes remaining candidates in configurable chunks. Supports clearnet (direct), Tor (.onion via SOCKS5), I2P (.i2p via SOCKS5), and Lokinet (.loki via SOCKS5).
See Also
ValidatorConfig:
Configuration model for this service.
Finder: Upstream service that
creates the candidates validated here.
Monitor: Downstream service
that health-checks promoted relays.
is_nostr_relay:
WebSocket probe used by validate_candidate().
Source code in src/bigbrotr/services/validator/service.py
Functions¶
run
async
¶
Execute one complete validation cycle.
Orchestrates cleanup, validation, and cycle-level logging.
Delegates the core work to cleanup_stale, cleanup_exhausted,
and validate.
Source code in src/bigbrotr/services/validator/service.py
validate
async
¶
Count, validate, and persist all pending candidates.
High-level entry point that counts available candidates, processes
them in chunks via validate_chunks, persists results, and emits
progress metrics. Returns the total number of candidates processed.
This is the method run() delegates to after cleanup. It can also
be called standalone when cleanup is not desired.
Returns:
-
int–Total number of candidates processed (valid + invalid).
Source code in src/bigbrotr/services/validator/service.py
cleanup_stale
async
¶
Remove candidates whose URLs already exist in the relays table.
Stale candidates appear when a relay was validated by another cycle, manually added, or re-discovered by the Finder. Removing them prevents wasted validation attempts.
Returns:
-
int–Number of stale candidates removed.
See Also
delete_stale_candidates: The SQL query executed by this method.
Source code in src/bigbrotr/services/validator/service.py
cleanup_exhausted
async
¶
Remove candidates that have exceeded the maximum failure threshold.
Prevents permanently broken relays from consuming validation resources.
Controlled by cleanup.enabled and cleanup.max_failures in
CleanupConfig.
Returns:
-
int–Number of exhausted candidates removed.
See Also
delete_exhausted_candidates: The SQL query executed by this method.
Source code in src/bigbrotr/services/validator/service.py
validate_candidate
async
¶
validate_candidate(candidate: Candidate) -> bool
Validate a single relay candidate by connecting and testing the Nostr protocol.
Uses the network-specific semaphore and proxy settings from NetworksConfig. Delegates the actual WebSocket probe to is_nostr_relay.
Parameters:
Returns:
-
bool–Trueif the relay speaks Nostr protocol,Falseotherwise.
Source code in src/bigbrotr/services/validator/service.py
validate_chunks
async
¶
Yield (valid_relays, invalid_candidates) for each processed chunk.
Handles chunk fetching, budget calculation, and concurrent validation. Persistence is left to the caller. Networks, chunk size, and candidate limit are read from ValidatorConfig.
Yields:
-
AsyncIterator[tuple[list[Relay], list[Candidate]]]–Tuple of (valid Relay list, invalid Candidate list) per chunk.