Skip to content

discv4

Classes

Name
class discv4::DialHistory
Tracks recently-dialed peers and suppresses retry attempts until a configurable cooldown expires.
struct discv4::ValidatedPeer
A discovered peer whose public key has already been validated.
struct discv4::WatcherPool
Global resource pool shared across all chain DialSchedulers. Enforces a two-level fd cap: total across all chains, and per chain. max_total — global fd cap (mobile default 12, desktop 200) max_per_chain — per-chain cap (mobile default 3, desktop 50).
struct discv4::DialScheduler
Per-chain dial scheduler mirroring go-ethereum's dialScheduler. Maintains up to pool->max_per_chain concurrent dial coroutines, respecting the global pool->max_total cap across all chains. All methods run on the single io_context thread — no mutex needed.
struct discv4::DiscoveredPeer
struct discv4::discv4Config
class discv4::discv4_client
Discovery v4 protocol client.
struct discv4::discv4_enr_request
ENRRequest packet — discv4 wire type 0x05 (EIP-868).
struct discv4::ForkId
Fork identifier per EIP-2124.
struct discv4::discv4_enr_response
Parsed ENRResponse — discv4 wire type 0x06 (EIP-868).
class discv4::discv4_packet
Base class for all Discovery V4 packets.
class discv4::discv4_ping
struct discv4::discv4_pong
class discv4::PacketFactory

Types

Name
enum class discv4Error { kNetworkSendFailed, kNetworkReceiveFailed, kPacketTooSmall, kInvalidPacketType, kHashMismatch, kSignatureParseFailed, kSignatureRecoveryFailed, kSigningFailed, kContextCreationFailed, kInvalidPublicKey, kRlpPayloadEmpty, kPongTimeout, kPongParseFailed}
Discovery v4 protocol error codes.
enum class PacketError
using std::function< void( ValidatedPeer vp, std::function< void()> on_done, std::function< void(std::shared_ptr< rlpx::RlpxSession >)> on_connected, boost::asio::yield_context yield)> DialFn
using std::function< bool(const DiscoveredPeer &)> FilterFn
Predicate applied to a DiscoveredPeer before it is enqueued for dialing. Return true to allow dialing, false to drop. When unset (nullptr), all peers are accepted. Mirrors go-ethereum UDPv4::NewNodeFilter (eth/protocols/eth/discovery.go).
using asio::ip::udp udp
using std::array< uint8_t, 64 > NodeId
using std::function< void(const DiscoveredPeer &)> PeerDiscoveredCallback
using std::function< void(const std::string &)> ErrorCallback
template <typename T >
using outcome::result< T, discv4Error, outcome::policy::all_narrow >
Result
Result type for Discovery v4 operations.
using outcome::result< void, discv4Error, outcome::policy::all_narrow > VoidResult
Result type for Discovery v4 operations without return value.
using outcome::result< void, PacketError > PacketResult
using std::function< void(const std::vector< uint8_t > &, const udp::endpoint &)> SendCallback
using std::shared_ptr< spdlog::logger > Logger

Functions

Name
const char * to_string(discv4Error error)
Convert error code to human-readable string.
FilterFn make_fork_id_filter(const std::array< uint8_t, 4U > & expected_hash)
Create a FilterFn that accepts only peers whose ENR eth entry carries a ForkId with the given 4-byte hash (CRC32 of genesis + applied forks).
std::shared_ptr< spdlog::logger > createLogger(const std::string & tag, const std::string & basepath ="")
Create a logger instance.

Attributes

Name
size_t kHashSize
size_t kSigSize
size_t kPacketTypeSize
size_t kPacketHeaderSize
size_t kPacketTypeOffset
size_t kUncompressedPubKey
std::array< uint8_t, 3U > kEthKey
size_t kWireHashSize
Outer Keccak-256 hash.
size_t kWireSigSize
Recoverable ECDSA signature.
size_t kWirePacketTypeSize
Single packet-type byte.
size_t kWireRecoveryIdSize
Recoverable ECDSA recovery id.
size_t kWireCompactSigSize
size_t kWireHeaderSize
size_t kWirePacketTypeOffset
size_t kNodeIdSize
Node identity.
size_t kNodeIdHexSize
size_t kUncompressedPubKeySize
0x04 prefix + 64 bytes
size_t kIPv4Size
Network.
size_t kUdpBufferSize
uint8_t kPacketTypePing
Packet type identifiers.
uint8_t kPacketTypePong
uint8_t kPacketTypeFindNode
uint8_t kPacketTypeNeighbours
uint8_t kPacketTypeEnrRequest
uint8_t kPacketTypeEnrResponse
uint8_t kProtocolVersion
Protocol version advertised in PING packets.
uint32_t kPacketExpirySeconds
Default packet expiry window (seconds).
auto kDefaultPingTimeout
Default networking timers.
auto kDefaultPeerExpiry
auto kDefaultDialHistoryExpiry
size_t kEnrSeqSize
ENR sequence number field size in PONG (optional, 6-byte big-endian uint48).

Types Documentation

enum discv4Error

Enumerator Value Description
kNetworkSendFailed
kNetworkReceiveFailed
kPacketTooSmall
kInvalidPacketType
kHashMismatch
kSignatureParseFailed
kSignatureRecoveryFailed
kSigningFailed
kContextCreationFailed
kInvalidPublicKey
kRlpPayloadEmpty
kPongTimeout
kPongParseFailed

Discovery v4 protocol error codes.

enum PacketError

Enumerator Value Description
kNullPacket
kSignFailure

using DialFn

using discv4::DialFn = std::function<void(
   ValidatedPeer                                               vp,
   std::function<void()>                                       on_done,
   std::function<void(std::shared_ptr<rlpx::RlpxSession>)>    on_connected,
   boost::asio::yield_context                                  yield)>;

Callback signature for what to run per dial attempt. vp — the peer to connect to on_done — call on every exit path (recycling the slot) on_connected — call once the ETH handshake is confirmed yield — coroutine yield context

using FilterFn

using discv4::FilterFn = std::function<bool( const DiscoveredPeer& )>;

Predicate applied to a DiscoveredPeer before it is enqueued for dialing. Return true to allow dialing, false to drop. When unset (nullptr), all peers are accepted. Mirrors go-ethereum UDPv4::NewNodeFilter (eth/protocols/eth/discovery.go).

using udp

using discv4::udp = asio::ip::udp;

using NodeId

using discv4::NodeId = std::array<uint8_t, 64>;

using PeerDiscoveredCallback

using discv4::PeerDiscoveredCallback = std::function<void(const DiscoveredPeer&)>;

using ErrorCallback

using discv4::ErrorCallback = std::function<void(const std::string&)>;

using Result

template <typename T >
using discv4::Result = outcome::result<T, discv4Error, outcome::policy::all_narrow>;

Result type for Discovery v4 operations.

Template Parameters:

  • T The success value type

using VoidResult

using discv4::VoidResult = outcome::result<void, discv4Error, outcome::policy::all_narrow>;

Result type for Discovery v4 operations without return value.

using PacketResult

using discv4::PacketResult = outcome::result<void, PacketError>;

using SendCallback

using discv4::SendCallback = std::function<void(const std::vector<uint8_t>&, const udp::endpoint&)>;

using Logger

using rlp::base::Logger = std::shared_ptr<spdlog::logger>;

Functions Documentation

function to_string

const char * to_string(
    discv4Error error
)

Convert error code to human-readable string.

Parameters:

  • error The error code

Return: Error description string

function make_fork_id_filter

inline FilterFn make_fork_id_filter(
    const std::array< uint8_t, 4U > & expected_hash
)

Create a FilterFn that accepts only peers whose ENR eth entry carries a ForkId with the given 4-byte hash (CRC32 of genesis + applied forks).

Parameters:

  • expected_hash 4-byte CRC32 fork hash to match against.

Return: FilterFn suitable for assignment to DialScheduler::filter_fn.

Mirrors go-ethereum NewNodeFilter (eth/protocols/eth/discovery.go):

return func(n *enode.Node) bool {
    var entry enrEntry
    if err := n.Load(&entry); err != nil { return false }
    return filter(entry.ForkID) == nil
}

Peers with no eth_fork_id (ENR absent or eth entry missing) are dropped.

function createLogger

std::shared_ptr< spdlog::logger > createLogger(
    const std::string & tag,
    const std::string & basepath =""
)

Create a logger instance.

Parameters:

  • tag Tagging name for identifying logger.
  • basepath Optional base path for log output (platform dependent).

Return: Logger object.

Attributes Documentation

variable kHashSize

static size_t kHashSize = kWireHashSize;

variable kSigSize

static size_t kSigSize = kWireSigSize;

variable kPacketTypeSize

static size_t kPacketTypeSize = kWirePacketTypeSize;

variable kPacketHeaderSize

static size_t kPacketHeaderSize = kWireHeaderSize;

variable kPacketTypeOffset

static size_t kPacketTypeOffset = kWirePacketTypeOffset;

variable kUncompressedPubKey

static size_t kUncompressedPubKey = kUncompressedPubKeySize;

variable kEthKey

static std::array< uint8_t, 3U > kEthKey { 0x65U, 0x74U, 0x68U };

variable kWireHashSize

static size_t kWireHashSize = 32;

Outer Keccak-256 hash.

discv4 wire-packet layout constants Layout: hash(32) || signature(65) || packet-type(1) || RLP(payload)

variable kWireSigSize

static size_t kWireSigSize = 65;

Recoverable ECDSA signature.

variable kWirePacketTypeSize

static size_t kWirePacketTypeSize = 1;

Single packet-type byte.

variable kWireRecoveryIdSize

static size_t kWireRecoveryIdSize = 1;

Recoverable ECDSA recovery id.

variable kWireCompactSigSize

static size_t kWireCompactSigSize = kWireSigSize - kWireRecoveryIdSize;

variable kWireHeaderSize

static size_t kWireHeaderSize = kWireHashSize + kWireSigSize + kWirePacketTypeSize;

variable kWirePacketTypeOffset

static size_t kWirePacketTypeOffset = kWireHashSize + kWireSigSize;

variable kNodeIdSize

static size_t kNodeIdSize = 64;

Node identity.

Uncompressed secp256k1 pubkey without 0x04 prefix

variable kNodeIdHexSize

static size_t kNodeIdHexSize = kNodeIdSize * 2;

variable kUncompressedPubKeySize

static size_t kUncompressedPubKeySize = kNodeIdSize + kWirePacketTypeSize;

0x04 prefix + 64 bytes

variable kIPv4Size

static size_t kIPv4Size = 4;

Network.

variable kUdpBufferSize

static size_t kUdpBufferSize = 2048;

variable kPacketTypePing

static uint8_t kPacketTypePing = 0x01U;

Packet type identifiers.

variable kPacketTypePong

static uint8_t kPacketTypePong = 0x02U;

variable kPacketTypeFindNode

static uint8_t kPacketTypeFindNode = 0x03U;

variable kPacketTypeNeighbours

static uint8_t kPacketTypeNeighbours = 0x04U;

variable kPacketTypeEnrRequest

static uint8_t kPacketTypeEnrRequest = 0x05U;

variable kPacketTypeEnrResponse

static uint8_t kPacketTypeEnrResponse = 0x06U;

variable kProtocolVersion

static uint8_t kProtocolVersion = 0x04U;

Protocol version advertised in PING packets.

variable kPacketExpirySeconds

static uint32_t kPacketExpirySeconds = 60U;

Default packet expiry window (seconds).

variable kDefaultPingTimeout

auto kDefaultPingTimeout = std::chrono::milliseconds(5000);

Default networking timers.

variable kDefaultPeerExpiry

auto kDefaultPeerExpiry = std::chrono::seconds(300);

variable kDefaultDialHistoryExpiry

auto kDefaultDialHistoryExpiry = std::chrono::seconds(35);

variable kEnrSeqSize

static size_t kEnrSeqSize = 6;

ENR sequence number field size in PONG (optional, 6-byte big-endian uint48).


Updated on 2026-04-13 at 23:22:46 -0700