feat(discv5): add standalone discovery v5 module - #2
Open
lodekeeper-z wants to merge 120 commits into
Open
lodekeeper-z wants to merge 120 commits into
lodekeeper-z wants to merge 120 commits into
Conversation
Implement ENR and RLP codecs, wire messages and packet handling, authenticated sessions, request tracking, routing, lookup orchestration, ingress rate limiting, and a std.Io runtime service. Cover official wire vectors, malformed encodings, bounded attacker-controlled state, ownership, retries, event delivery, and service-level discovery flows.
Add a runnable std.Io.Threaded example that seeds public bootnodes, performs random or targeted recursive lookups, prints discovered ENRs, and shuts down cleanly.
Replace the split Protocol, Service, and request-index architecture with a single-writer actor and request-owned lifecycle state. Transport sends now follow prepare, send, and infallible commit transitions, while admission permits, handshake recovery, lookups, sessions, peers, and public events each have one authoritative owner.\n\nKeep all remote state bounded, retain endpoint-gated relay trust, add deterministic low-S secp256k1 signing, and preserve late-response, retry, replay, graceful-shutdown, and malformed-input behavior through focused regressions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a standalone Discovery v5 implementation built on Zig 0.16
std.Io, organized around one publicRuntimeand one internal single-writer actor.The actor is the authoritative owner of sessions, requests, lookups, peers, address votes, local ENR state, and protocol metrics. Every outbound datagram becomes a move-owned value in one bounded global
ActorEffectFIFO. Runtime is the sole transport executor and returns exactly onesent,failed, orruntime_stoppedcompletion to the actor, which commits or aborts the prepared protocol transition. Request records own response correlation, retry and rekey state, admission permits, lookup association, and cleanup obligations.Transport is the sole socket owner. Internal completion is synchronous. Best-effort discovery observations use a bounded event outbox, while API requests and lookups reserve capacity in separate reliable result planes before any network work is accepted. Cancellation, timeout, shutdown, payload ownership, and stalled consumers therefore produce one authoritative terminal result without blocking the actor.
Remote state remains explicitly bounded, including sessions, challenges, response recovery, admission permits, queued requests, lookup candidates, events, votes, and retained metadata. Expected traffic receives owned packet budgets before ordinary source-IP bans, replay epochs never forget authenticated nonces under live keys, retries use fresh ciphertext, duplicate probes retransmit the exact retained WHOAREYOU challenge, and response recovery keeps stable keys until candidate-key traffic proves adoption.
Lookup traversal keeps the 16-result and 16-request limits with a bounded 32-candidate frontier. Synchronous candidate failures cannot strand a lookup, temporary local request pressure is deferred for bounded maintenance repumping, and returned candidates retain validated contact metadata locally so traversal and final results do not depend on the global contact cache. Duplicate candidates preserve the newest retained ENR and endpoint.
Returned NODES ENRs are signature-validated once at the packet boundary and reused as owned validated values for distance checks, peer learning, events, request results, and lookup candidates. Routing preserves endpoint-specific relay trust: locally configured records are immediately trusted, while network-learned ENRs become relayable only after authenticated traffic from their advertised UDP endpoint.
Stable-session expiration is maintenance-owned. Observational metrics do not mutate TTL or LRU state, unauthenticated and rejected traffic cannot refresh recency, and only accepted authenticated traffic refreshes a session. Capacity-safe insertion reuses expired storage before evicting live state.
The runtime exposes per-event-kind drops, contact retention and rejection totals, stable-session churn, and point-in-time actor workload gauges. The discovery executable supports sustained replenishing stress runs and reports reliable lookup completions independently from lossy observations.
Canonical RLP/ENR decoding rejects malformed remote input without assertions, including unsupported signed ENR fields. secp256k1 signing is deterministic RFC6979 over the supplied digest and emits canonical low-S signatures compatible with ChainSafe's Noble-based implementation. Empty request IDs remain wire-valid and multipart NODES responses remain bounded. Normal stop closes command intake, interrupts blocked transport through Runtime-owned cancellation, reaps internal work, and terminalizes every accepted command, effect, lookup, and request exactly once.
AI assistance was used for implementation, test development, profiling, and review; all changes were exercised through the repository's deterministic verification and stress workflows.