Skip to content

Unify discovery protocol GenServers into a single DiscoveryServer #5990

@ElFantasma

Description

@ElFantasma

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

  1. Combine state structs: Create Discv4State and Discv5State structs for protocol-specific fields
  2. Unified InMessage enum: Single enum with protocol-tagged variants
    enum InMessage {
        Discv4(Discv4Message),
        Discv5(Discv5Message),
        Revalidate(DiscoveryProtocol),
        Lookup(DiscoveryProtocol),
        Prune,
        Shutdown,
    }
  3. Protocol dispatch: Route to handle_discv4_message() or handle_discv5_packet() based on variant
  4. Unified timers: Single timer management with protocol parameter where intervals differ
  5. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    L1Ethereum clientp2pIssues related to p2p network

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions