Skip to main content
This document covers the peer-to-peer networking layer that manages connections between StableNet nodes.
It focuses on the p2p.Server architecture, peer lifecycle management, connection types, and protocol multiplexing.
For peer discovery mechanisms, see Discovery Mechanisms.
For blockchain synchronization protocols, see Chain Synchronization.
For protocol handler implementations, see Protocol Handlers.

Server Architecture

The P2P layer is centered around the p2p.Server structure, which manages all peer connections and implements the core networking functionality of a StableNet node.
It unifies inbound and outbound connections and acts as an intermediary between discovery protocols and protocol handlers.

Server Structure

The Server structure maintains the following core components:
ComponentTypePurpose
Configp2p.ConfigNetwork configuration such as maximum peers, listen address, and enabled protocols
localnode*enode.LocalNodeLocal node identity and ENR management
listenernet.ListenerAccepts inbound TCP connections
dialsched*dialSchedulerSchedules outbound connection attempts
discmix*enode.FairMixAggregates multiple discovery sources
ntab*discover.UDPv4Discovery v4 protocol handler
DiscV5*discover.UDPv5Discovery v5 protocol handler
nodedb*enode.DBPersistent node database

Server Configuration and Initialization

Server initialization proceeds through the following steps:
  1. setupLocalNode()
    Generates the local node ID and ENR from the private key and initializes the node database.
  2. setupListening()
    Starts the TCP listener on the configured network address.
  3. setupDiscovery()
    Initializes Discovery v4/v5 and configures the discovery mixer.
  4. setupDialScheduler()
    Creates the dial scheduler for static and discovered nodes.
  5. run()
    Starts the server’s main event loop for peer event handling.
  6. listenLoop()
    Continuously accepts inbound connections.

Server Main Loop

The server’s main event loop performs the following tasks:
  • Handles peer addition and removal events
  • Processes connection requests from the dial scheduler
  • Gracefully shuts down all peers on termination signals
  • Broadcasts peer state changes via the event feed

Peer Lifecycle

Each connected peer is represented by a Peer structure that encapsulates connection state, protocol handlers, and lifecycle metadata.

Connection Establishment Flow

Peer connections follow this sequence:
  1. TCP connection establishment
  2. Encrypted handshake
  3. Protocol handshake and capability negotiation
  4. Protocol multiplexing setup
  5. Peer registration and event emission

Handshake Protocols

Connection setup consists of two handshake phases:
  1. Encryption Handshake (doEncHandshake)
    Establishes an RLPx-encrypted communication channel.
  2. Protocol Handshake (doProtoHandshake)
    Negotiates supported protocols and versions.
The protoHandshake structure includes:
FieldTypeDescription
Versionuint64P2P protocol version
NamestringClient identification string
Caps[]CapList of supported protocol capabilities
ListenPortuint64Listening port
ID[]byteNode public key

Protocol Multiplexing

After the handshake, the server matches commonly supported protocols and assigns message code ranges to each protocol.
  • Base P2P messages: codes 0–15
  • First matched subprotocol: starting at code 16
  • Subsequent protocols: offset increased by the previous protocol’s length
This design allows multiple protocols to be safely multiplexed over a single connection.

Connection Types and Management

The P2P server uses connFlag values to distinguish connection types:
FlagValueDescription
dynDialedConn1 << 0Outbound connection created via discovery
staticDialedConn1 << 1Outbound connection to a static node
inboundConn1 << 2Inbound connection initiated externally
trustedConn1 << 3Trusted peer (may exceed MaxPeers limit)

Peer Limits and Capacity

Default peer capacity control policies include:
  • MaxPeers: total peer count limit
  • MaxPendingPeers: limit on pending connection attempts (default 50 per direction)
  • DialRatio: outbound peer ratio (default 1/3)

Dial Scheduler

The dialScheduler manages outbound connection attempts:
  • Tracks recent dial history to avoid excessive retries
  • Prioritizes static nodes over discovered nodes
  • Enforces maximum concurrent dial limits
  • Uses exponential backoff to throttle retries for failed endpoints

Peer Operations and Lifecycle

Adding and Removing Peers

The server manages its peer set using the following methods:
MethodPurpose
AddPeer(node)Add a static peer with automatic reconnection
RemovePeer(node)Remove a static peer and disconnect
AddTrustedPeer(node)Add a trusted peer
RemoveTrustedPeer(node)Remove a trusted peer

Disconnect Reasons

Disconnect reasons are recorded using DiscReason codes:
ReasonCodeDescription
DiscRequested0x00Graceful shutdown
DiscNetworkError0x01Network error
DiscProtocolError0x02Protocol violation
DiscUselessPeer0x03Invalid or unhelpful peer
DiscTooManyPeers0x04Peer limit exceeded
DiscAlreadyConnected0x05Duplicate connection
DiscIncompatibleVersion0x06Version mismatch
DiscInvalidIdentity0x07Invalid node identity
DiscQuitting0x08Server shutting down
DiscSubprotocolError0x10Subprotocol error

Peer Event Feed

The server emits peer state changes via PeerEvent notifications:
Event TypeDescription
PeerEventTypeAddPeer connected and registered
PeerEventTypeDropPeer disconnected
PeerEventTypeMsgSendMessage sent
PeerEventTypeMsgRecvMessage received

Integration with the Ethereum Backend

The Ethereum backend integrates with the P2P server through protocol registration. Integration flow:
  1. eth.Ethereum.Protocols() – returns protocol definitions
  2. eth.MakeProtocols() – creates eth subprotocol handlers
  3. snap.MakeProtocols() – creates snap protocol handlers (if enabled)
  4. node.Stack.RegisterProtocols() – registers protocols with the P2P server
  5. handler.Start() – begins protocol message processing

Backend Access to the P2P Server

The backend maintains a reference to the P2P server for RPC services, used for:
  • NetAPI – network information queries
  • AdminAPI – peer management RPCs
  • Dynamic ENR updates

Configuration Flags

Key flags used to configure the P2P network include:
FlagTypeDefaultDescription
--maxpeersintDefaultConfig.P2P.MaxPeersMaximum number of peers
--maxpendpeersint0Pending peer limit
--portint30303Network listening port
--bootnodesstringNetwork-specificBootstrap nodes
--nodekeystring-P2P node key file path
--nodekeyhexstring-Test node key (hex)
--nodiscoverboolfalseDisable peer discovery
--netrestrictstring-CIDR-based network restriction
These configuration values are applied during node initialization via SetP2PConfig() and setNodeKey().