Description
Refactor the discovery protocol architecture to use a single GenServer instead of three separate ones (DiscoveryMultiplexer + Discv4Server + Discv5Server). Since PeerTable is already shared and the multiplexer already discriminates packets, merging these GenServers simplifies the architecture and eliminates inter-GenServer communication overhead.
Current Architecture (4 GenServers)
┌─────────────────────┐
│ DiscoveryMultiplexer│ ← routes packets
└──────────┬──────────┘
│
┌─────┴─────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ Discv4 │ │ Discv5 │ ← separate GenServers
│ Server │ │ Server │
└────┬────┘ └────┬────┘
│ │
└─────┬─────┘
▼
┌───────────┐
│ PeerTable │ ← shared state
└───────────┘
Proposed Architecture (2 GenServers)
┌──────────────────────────────────┐
│ DiscoveryServer │
│ ┌─────────────┬──────────────┐ │
│ │ Discv4State │ Discv5State │ │ ← protocol-specific state
│ └─────────────┴──────────────┘ │
│ ┌────────────────────────────┐ │
│ │ Shared: socket, signer, │ │ ← common fields
│ │ local_node, bootnodes │ │
│ └────────────────────────────┘ │
│ • Single message loop │
│ • Protocol dispatch via enum │
│ • Unified timers │
└───────────────┬──────────────────┘
▼
┌───────────┐
│ PeerTable │
└───────────┘
Benefits
- Eliminates inter-GenServer communication overhead (no more casting between multiplexer and protocol servers)
- Single lifecycle & shutdown coordination
- Unified logging with protocol tags
- Simpler architecture to reason about
- Single place for revalidate/lookup/prune logic with protocol parameter
- Reduced code duplication (~30-40% of current code is duplicated between servers)
Implementation Approach
- Combine state structs: Create
Discv4State and Discv5State structs for protocol-specific fields
- Unified InMessage enum: Single enum with protocol-tagged variants
enum InMessage {
Discv4(Discv4Message),
Discv5(Discv5Message),
Revalidate(DiscoveryProtocol),
Lookup(DiscoveryProtocol),
Prune,
Shutdown,
}
- Protocol dispatch: Route to
handle_discv4_message() or handle_discv5_packet() based on variant
- Unified timers: Single timer management with protocol parameter where intervals differ
- Extract shared logic: Common implementations for
revalidate(), lookup(), prune() with protocol parameter
Protocol-Specific State
Discv4:
find_node_message: BytesMut (cached, re-signed every 5 seconds)
- Revalidation interval: 12 hours
Discv5:
counter: u32 (nonce generation)
pending_by_nonce: FxHashMap (messages awaiting WhoAreYou)
pending_challenges: FxHashMap (WhoAreYou challenges)
whoareyou_rate_limit: FxHashMap (per-IP rate limiting)
ip_votes + voting state (external IP detection)
- Revalidation interval: 30 seconds
Dependencies
Related Issues
Description
Refactor the discovery protocol architecture to use a single GenServer instead of three separate ones (DiscoveryMultiplexer + Discv4Server + Discv5Server). Since PeerTable is already shared and the multiplexer already discriminates packets, merging these GenServers simplifies the architecture and eliminates inter-GenServer communication overhead.
Current Architecture (4 GenServers)
Proposed Architecture (2 GenServers)
Benefits
Implementation Approach
Discv4StateandDiscv5Statestructs for protocol-specific fieldshandle_discv4_message()orhandle_discv5_packet()based on variantrevalidate(),lookup(),prune()with protocol parameterProtocol-Specific State
Discv4:
find_node_message: BytesMut(cached, re-signed every 5 seconds)Discv5:
counter: u32(nonce generation)pending_by_nonce: FxHashMap(messages awaiting WhoAreYou)pending_challenges: FxHashMap(WhoAreYou challenges)whoareyou_rate_limit: FxHashMap(per-IP rate limiting)ip_votes+ voting state (external IP detection)Dependencies
Related Issues