Skip to content

discv5/discv5_constants.hpp

Namespaces

Name
discv5

Classes

Name
struct discv5::IPv4Wire
Wire layout of a 4-byte IPv4 address as stored in an ENR "ip" field.
struct discv5::IPv6Wire
Wire layout of a 16-byte IPv6 address as stored in an ENR "ip6" field.
struct discv5::Keccak256Wire
Wire layout of a Keccak-256 hash.
struct discv5::CompressedPubKeyWire
Wire layout of a compressed secp256k1 public key.
struct discv5::EnrSigWire
Wire layout of an ENR compact secp256k1 signature (no recovery id).
struct discv5::UncompressedPubKeyWire
Wire layout of an uncompressed secp256k1 public key (with 0x04 prefix).
struct discv5::MaskingIvWire
Masking IV that precedes the static packet header.
struct discv5::GcmNonceWire
AES-GCM nonce embedded in the discv5 static header.
struct discv5::StaticHeaderWire
discv5 static packet header, as defined by the EIP-8020 spec.
struct discv5::WhoareyouAuthDataWire
WHOAREYOU auth-data layout: id-nonce + highest ENR sequence.

Attributes

Name
uint16_t kDefaultUdpPort
Default UDP port for discv5 (IANA-assigned).
uint16_t kDefaultTcpPort
Default TCP/RLPx port advertised to discovered peers.
size_t kNodeIdBytes
Bytes in an uncompressed secp256k1 public key WITHOUT the 0x04 prefix. This is the 64-byte "node id" used by discv4 and passed to DialHistory.
size_t kCompressedKeyBytes
Bytes in a compressed secp256k1 public key (03/02 prefix + 32 bytes).
size_t kPrivateKeyBytes
Bytes in a secp256k1 private key.
size_t kUncompressedPrefixLen
Bytes in the 0x04 uncompressed-point prefix.
uint8_t kUncompressedPubKeyPrefix
size_t kUncompressedPubKeyDataOffset
size_t kKeccak256Bytes
Keccak-256 (legacy) digest size in bytes.
size_t kIPv4Bytes
IPv4 address wire size in bytes.
size_t kIPv6Bytes
IPv6 address wire size in bytes.
size_t kIPv4OctetMsb
Byte offset of the most-significant octet in a 4-byte IPv4 field.
size_t kIPv4Octet1
Byte offset of the second octet.
size_t kIPv4Octet2
Byte offset of the third octet.
size_t kIPv4OctetLsb
Byte offset of the least-significant octet.
uint32_t kIPv4MsbShift
Left-shift amount to place the MSB octet in a uint32 (big-endian).
uint32_t kIPv4Octet1Shift
Left-shift amount for the second octet.
uint32_t kIPv4Octet2Shift
Left-shift amount for the third octet.
uint32_t kIPv4LsbShift
Left-shift amount for the least-significant octet (no shift).
size_t kMaxPortBytes
Maximum bytes an RLP-encoded UDP/TCP port occupies (big-endian uint16).
size_t kForkHashBytes
Byte count of the fork-hash field inside an ENR "eth" entry.
size_t kProtocolIdBytes
Byte length of the "discv5" protocol-ID magic string.
char[] kProtocolId
The discv5 packet protocol-ID string.
size_t kGcmNonceBytes
Byte length of the AES-GCM nonce used for message encryption.
size_t kMaskingIvBytes
Byte length of the masking IV that precedes the static header.
size_t kWhoareyouIdNonceBytes
Byte length of the WHOAREYOU id-nonce field.
size_t kMinPacketBytes
Minimum valid discv5 packet size (go-ethereum minPacketSize).
size_t kMaxPacketBytes
Maximum valid discv5 packet size in bytes.
size_t kAes128KeyBytes
AES-128 session key size in bytes.
size_t kGcmTagBytes
AES-GCM authentication tag size in bytes.
size_t kRandomMessageCiphertextBytes
Random encrypted payload size used for pre-handshake message placeholders.
uint32_t kFindNodeDistanceAll
FINDNODE distance that requests the full routing table (log2 space upper bound + 1).
uint8_t kHkdfFirstBlockCounter
Single-byte HKDF expansion block counter used for the first output block.
size_t kMessageTypePrefixBytes
Byte size of the leading message-type prefix in decrypted discv5 payloads.
uint8_t kNodesResponseCountSingle
Number of ENR records returned by the local single-record NODES reply helper.
size_t kEnrMaxBytes
Maximum total size of a serialised ENR record (EIP-778 SizeLimit).
size_t kEnrSigBytes
Compact secp256k1 ECDSA signature size stored in an ENR (no recid).
size_t kEnrPrefixLen
Byte length of the "enr:" URI prefix.
char[] kEnrPrefix
The "enr:" URI prefix string.
uint8_t kInitialEnrSeq
Initial ENR sequence number for locally generated records.
char[] kIdentitySchemeV4
ENR identity scheme string for secp256k1-v4.
size_t kIdentitySchemeV4Bytes
char[] kEnrKeyId
Common ENR field key strings and lengths.
size_t kEnrKeyIdBytes
char[] kEnrKeyIp
size_t kEnrKeyIpBytes
char[] kEnrKeySecp256k1
size_t kEnrKeySecp256k1Bytes
char[] kEnrKeyTcp
size_t kEnrKeyTcpBytes
char[] kEnrKeyUdp
size_t kEnrKeyUdpBytes
uint8_t kBase64UpperCount
Number of upper-case letters (A–Z) in the base64url alphabet.
uint8_t kBase64LowerCount
Number of lower-case letters (a–z) in the base64url alphabet.
uint8_t kBase64DigitCount
Number of decimal digits (0–9) in the base64url alphabet.
uint8_t kBase64LowerStart
Start index of the lower-case letter block (after A–Z).
uint8_t kBase64DigitStart
Start index of the digit block (after A–Z and a–z).
uint8_t kBase64DashIndex
Table index for the '-' character in base64url.
uint8_t kBase64UnderIndex
Table index for the '_' character in base64url.
uint8_t kBase64Invalid
Sentinel value meaning "not a valid base64url character".
size_t kBase64BitsPerChar
Number of bits encoded by one base64 character.
size_t kBase64BitsPerByte
Number of bits in one output byte.
size_t kDefaultMaxConcurrent
Default maximum concurrent outbound FINDNODE queries.
uint32_t kDefaultQueryIntervalSec
Default interval between crawler sweep rounds (seconds).
uint32_t kDefaultPeerExpirySec
Seconds before an unseen peer is evicted from the peer table.
size_t kMaxBootnodeEnrs
Maximum bootstrap ENR entries accepted per chain source.
size_t kUncompressedKeyBytes
Total byte count of an uncompressed public key including the 0x04 prefix.
size_t kStaticHeaderBytes
Byte count of the static header (derived from wire struct, NOT a magic literal).
size_t kStaticHeaderVersionOffset
size_t kStaticHeaderFlagOffset
size_t kStaticHeaderNonceOffset
size_t kStaticHeaderAuthSizeOffset
size_t kWhoareyouAuthDataBytes
Byte count of WHOAREYOU auth data.
size_t kHandshakeAuthSizeFieldBytes
HANDSHAKE auth-data layout prefixes.
size_t kHandshakeAuthSizeFieldCount
size_t kHandshakeAuthSigSizeOffset
size_t kHandshakeAuthPubkeySizeOffset
size_t kHandshakeAuthFixedBytes
size_t kStaticPacketBytes
Total fixed bytes at the front of every discv5 packet: masking IV + static header.
uint8_t kFlagMessage
Flag value for an ordinary encrypted message packet.
uint8_t kFlagWhoareyou
Flag value for a WHOAREYOU session-challenge packet.
uint8_t kFlagHandshake
Flag value for a HANDSHAKE message.
uint8_t kMsgPing
PING message type byte.
uint8_t kMsgPong
PONG message type byte.
uint8_t kMsgFindNode
FINDNODE message type byte.
uint8_t kMsgNodes
NODES message type byte.
uint8_t kMsgTalkReq
TALKREQ message type byte.
uint8_t kMsgTalkResp
TALKRESP message type byte.
uint16_t kProtocolVersion
discv5 protocol version (current).

Attributes Documentation

variable kDefaultUdpPort

static uint16_t kDefaultUdpPort = 9000U;

Default UDP port for discv5 (IANA-assigned).

variable kDefaultTcpPort

static uint16_t kDefaultTcpPort = 30303U;

Default TCP/RLPx port advertised to discovered peers.

variable kNodeIdBytes

static size_t kNodeIdBytes = 64U;

Bytes in an uncompressed secp256k1 public key WITHOUT the 0x04 prefix. This is the 64-byte "node id" used by discv4 and passed to DialHistory.

variable kCompressedKeyBytes

static size_t kCompressedKeyBytes = 33U;

Bytes in a compressed secp256k1 public key (03/02 prefix + 32 bytes).

variable kPrivateKeyBytes

static size_t kPrivateKeyBytes = 32U;

Bytes in a secp256k1 private key.

variable kUncompressedPrefixLen

static size_t kUncompressedPrefixLen = 1U;

Bytes in the 0x04 uncompressed-point prefix.

variable kUncompressedPubKeyPrefix

static uint8_t kUncompressedPubKeyPrefix = 0x04U;

variable kUncompressedPubKeyDataOffset

static size_t kUncompressedPubKeyDataOffset = kUncompressedPrefixLen;

variable kKeccak256Bytes

static size_t kKeccak256Bytes = 32U;

Keccak-256 (legacy) digest size in bytes.

variable kIPv4Bytes

static size_t kIPv4Bytes = 4U;

IPv4 address wire size in bytes.

variable kIPv6Bytes

static size_t kIPv6Bytes = 16U;

IPv6 address wire size in bytes.

variable kIPv4OctetMsb

static size_t kIPv4OctetMsb = 0U;

Byte offset of the most-significant octet in a 4-byte IPv4 field.

variable kIPv4Octet1

static size_t kIPv4Octet1 = 1U;

Byte offset of the second octet.

variable kIPv4Octet2

static size_t kIPv4Octet2 = 2U;

Byte offset of the third octet.

variable kIPv4OctetLsb

static size_t kIPv4OctetLsb = 3U;

Byte offset of the least-significant octet.

variable kIPv4MsbShift

static uint32_t kIPv4MsbShift = 24U;

Left-shift amount to place the MSB octet in a uint32 (big-endian).

variable kIPv4Octet1Shift

static uint32_t kIPv4Octet1Shift = 16U;

Left-shift amount for the second octet.

variable kIPv4Octet2Shift

static uint32_t kIPv4Octet2Shift =  8U;

Left-shift amount for the third octet.

variable kIPv4LsbShift

static uint32_t kIPv4LsbShift =  0U;

Left-shift amount for the least-significant octet (no shift).

variable kMaxPortBytes

static size_t kMaxPortBytes = 2U;

Maximum bytes an RLP-encoded UDP/TCP port occupies (big-endian uint16).

variable kForkHashBytes

static size_t kForkHashBytes = 4U;

Byte count of the fork-hash field inside an ENR "eth" entry.

variable kProtocolIdBytes

static size_t kProtocolIdBytes = 6U;

Byte length of the "discv5" protocol-ID magic string.

variable kProtocolId

static char[] kProtocolId = "discv5";

The discv5 packet protocol-ID string.

variable kGcmNonceBytes

static size_t kGcmNonceBytes = 12U;

Byte length of the AES-GCM nonce used for message encryption.

variable kMaskingIvBytes

static size_t kMaskingIvBytes = 16U;

Byte length of the masking IV that precedes the static header.

variable kWhoareyouIdNonceBytes

static size_t kWhoareyouIdNonceBytes = 16U;

Byte length of the WHOAREYOU id-nonce field.

variable kMinPacketBytes

static size_t kMinPacketBytes = 63U;

Minimum valid discv5 packet size (go-ethereum minPacketSize).

variable kMaxPacketBytes

static size_t kMaxPacketBytes = 1280U;

Maximum valid discv5 packet size in bytes.

variable kAes128KeyBytes

static size_t kAes128KeyBytes = 16U;

AES-128 session key size in bytes.

variable kGcmTagBytes

static size_t kGcmTagBytes = 16U;

AES-GCM authentication tag size in bytes.

variable kRandomMessageCiphertextBytes

static size_t kRandomMessageCiphertextBytes = 20U;

Random encrypted payload size used for pre-handshake message placeholders.

variable kFindNodeDistanceAll

static uint32_t kFindNodeDistanceAll = 256U;

FINDNODE distance that requests the full routing table (log2 space upper bound + 1).

variable kHkdfFirstBlockCounter

static uint8_t kHkdfFirstBlockCounter = 0x01U;

Single-byte HKDF expansion block counter used for the first output block.

variable kMessageTypePrefixBytes

static size_t kMessageTypePrefixBytes = 1U;

Byte size of the leading message-type prefix in decrypted discv5 payloads.

variable kNodesResponseCountSingle

static uint8_t kNodesResponseCountSingle = 1U;

Number of ENR records returned by the local single-record NODES reply helper.

variable kEnrMaxBytes

static size_t kEnrMaxBytes = 300U;

Maximum total size of a serialised ENR record (EIP-778 SizeLimit).

variable kEnrSigBytes

static size_t kEnrSigBytes = 64U;

Compact secp256k1 ECDSA signature size stored in an ENR (no recid).

variable kEnrPrefixLen

static size_t kEnrPrefixLen = 4U;

Byte length of the "enr:" URI prefix.

variable kEnrPrefix

static char[] kEnrPrefix = "enr:";

The "enr:" URI prefix string.

variable kInitialEnrSeq

static uint8_t kInitialEnrSeq = 1U;

Initial ENR sequence number for locally generated records.

variable kIdentitySchemeV4

static char[] kIdentitySchemeV4 = "v4";

ENR identity scheme string for secp256k1-v4.

variable kIdentitySchemeV4Bytes

static size_t kIdentitySchemeV4Bytes = 2U;

variable kEnrKeyId

static char[] kEnrKeyId = "id";

Common ENR field key strings and lengths.

variable kEnrKeyIdBytes

static size_t kEnrKeyIdBytes = 2U;

variable kEnrKeyIp

static char[] kEnrKeyIp = "ip";

variable kEnrKeyIpBytes

static size_t kEnrKeyIpBytes = 2U;

variable kEnrKeySecp256k1

static char[] kEnrKeySecp256k1 = "secp256k1";

variable kEnrKeySecp256k1Bytes

static size_t kEnrKeySecp256k1Bytes = 9U;

variable kEnrKeyTcp

static char[] kEnrKeyTcp = "tcp";

variable kEnrKeyTcpBytes

static size_t kEnrKeyTcpBytes = 3U;

variable kEnrKeyUdp

static char[] kEnrKeyUdp = "udp";

variable kEnrKeyUdpBytes

static size_t kEnrKeyUdpBytes = 3U;

variable kBase64UpperCount

static uint8_t kBase64UpperCount = 26U;

Number of upper-case letters (A–Z) in the base64url alphabet.

variable kBase64LowerCount

static uint8_t kBase64LowerCount = 26U;

Number of lower-case letters (a–z) in the base64url alphabet.

variable kBase64DigitCount

static uint8_t kBase64DigitCount = 10U;

Number of decimal digits (0–9) in the base64url alphabet.

variable kBase64LowerStart

static uint8_t kBase64LowerStart = kBase64UpperCount;

Start index of the lower-case letter block (after A–Z).

variable kBase64DigitStart

static uint8_t kBase64DigitStart                                              =
kBase64UpperCount + kBase64LowerCount;

Start index of the digit block (after A–Z and a–z).

variable kBase64DashIndex

static uint8_t kBase64DashIndex = 62U;

Table index for the '-' character in base64url.

variable kBase64UnderIndex

static uint8_t kBase64UnderIndex = 63U;

Table index for the '_' character in base64url.

variable kBase64Invalid

static uint8_t kBase64Invalid = 0xFFU;

Sentinel value meaning "not a valid base64url character".

variable kBase64BitsPerChar

static size_t kBase64BitsPerChar = 6U;

Number of bits encoded by one base64 character.

variable kBase64BitsPerByte

static size_t kBase64BitsPerByte = 8U;

Number of bits in one output byte.

variable kDefaultMaxConcurrent

static size_t kDefaultMaxConcurrent = 8U;

Default maximum concurrent outbound FINDNODE queries.

variable kDefaultQueryIntervalSec

static uint32_t kDefaultQueryIntervalSec = 30U;

Default interval between crawler sweep rounds (seconds).

variable kDefaultPeerExpirySec

static uint32_t kDefaultPeerExpirySec = 600U;

Seconds before an unseen peer is evicted from the peer table.

variable kMaxBootnodeEnrs

static size_t kMaxBootnodeEnrs = 64U;

Maximum bootstrap ENR entries accepted per chain source.

variable kUncompressedKeyBytes

static size_t kUncompressedKeyBytes                                           =
sizeof(UncompressedPubKeyWire);

Total byte count of an uncompressed public key including the 0x04 prefix.

variable kStaticHeaderBytes

static size_t kStaticHeaderBytes = sizeof(StaticHeaderWire);

Byte count of the static header (derived from wire struct, NOT a magic literal).

variable kStaticHeaderVersionOffset

static size_t kStaticHeaderVersionOffset = offsetof(StaticHeaderWire, version);

variable kStaticHeaderFlagOffset

static size_t kStaticHeaderFlagOffset = offsetof(StaticHeaderWire, flag);

variable kStaticHeaderNonceOffset

static size_t kStaticHeaderNonceOffset = offsetof(StaticHeaderWire, nonce);

variable kStaticHeaderAuthSizeOffset

static size_t kStaticHeaderAuthSizeOffset = offsetof(StaticHeaderWire, auth_size);

variable kWhoareyouAuthDataBytes

static size_t kWhoareyouAuthDataBytes = sizeof(WhoareyouAuthDataWire);

Byte count of WHOAREYOU auth data.

variable kHandshakeAuthSizeFieldBytes

static size_t kHandshakeAuthSizeFieldBytes = sizeof(uint8_t);

HANDSHAKE auth-data layout prefixes.

variable kHandshakeAuthSizeFieldCount

static size_t kHandshakeAuthSizeFieldCount = 2U;

variable kHandshakeAuthSigSizeOffset

static size_t kHandshakeAuthSigSizeOffset = kKeccak256Bytes;

variable kHandshakeAuthPubkeySizeOffset

static size_t kHandshakeAuthPubkeySizeOffset = kHandshakeAuthSigSizeOffset + kHandshakeAuthSizeFieldBytes;

variable kHandshakeAuthFixedBytes

static size_t kHandshakeAuthFixedBytes                                              =
kKeccak256Bytes + (kHandshakeAuthSizeFieldCount * kHandshakeAuthSizeFieldBytes);

variable kStaticPacketBytes

static size_t kStaticPacketBytes                                        =
sizeof(MaskingIvWire) + sizeof(StaticHeaderWire);

Total fixed bytes at the front of every discv5 packet: masking IV + static header.

variable kFlagMessage

static uint8_t kFlagMessage = 0U;

Flag value for an ordinary encrypted message packet.

variable kFlagWhoareyou

static uint8_t kFlagWhoareyou = 1U;

Flag value for a WHOAREYOU session-challenge packet.

variable kFlagHandshake

static uint8_t kFlagHandshake = 2U;

Flag value for a HANDSHAKE message.

variable kMsgPing

static uint8_t kMsgPing = 0x01U;

PING message type byte.

variable kMsgPong

static uint8_t kMsgPong = 0x02U;

PONG message type byte.

variable kMsgFindNode

static uint8_t kMsgFindNode = 0x03U;

FINDNODE message type byte.

variable kMsgNodes

static uint8_t kMsgNodes = 0x04U;

NODES message type byte.

variable kMsgTalkReq

static uint8_t kMsgTalkReq = 0x05U;

TALKREQ message type byte.

variable kMsgTalkResp

static uint8_t kMsgTalkResp = 0x06U;

TALKRESP message type byte.

variable kProtocolVersion

static uint16_t kProtocolVersion = 1U;

discv5 protocol version (current).

Source code

// Copyright 2025 GeniusVentures
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <cassert>
#include <cstddef>
#include <cstdint>

namespace discv5
{

// ===========================================================================
// Part 1 — Fundamental domain sizes (every value has a name; no bare literals
//          anywhere in the module that refers to these quantities).
// ===========================================================================

// ---------------------------------------------------------------------------
// Networking defaults
// ---------------------------------------------------------------------------

static constexpr uint16_t kDefaultUdpPort        = 9000U;

static constexpr uint16_t kDefaultTcpPort        = 30303U;

// ---------------------------------------------------------------------------
// secp256k1 key sizes (domain constants — all other sizes are derived below)
// ---------------------------------------------------------------------------

static constexpr size_t   kNodeIdBytes           = 64U;

static constexpr size_t   kCompressedKeyBytes    = 33U;

static constexpr size_t   kPrivateKeyBytes       = 32U;

static constexpr size_t   kUncompressedPrefixLen = 1U;
static constexpr uint8_t  kUncompressedPubKeyPrefix = 0x04U;
static constexpr size_t   kUncompressedPubKeyDataOffset = kUncompressedPrefixLen;

// ---------------------------------------------------------------------------
// Cryptographic hash sizes
// ---------------------------------------------------------------------------

static constexpr size_t   kKeccak256Bytes        = 32U;

// ---------------------------------------------------------------------------
// IPv4 / IPv6 wire sizes
// ---------------------------------------------------------------------------

static constexpr size_t   kIPv4Bytes             = 4U;

static constexpr size_t   kIPv6Bytes             = 16U;

// ---------------------------------------------------------------------------
// IPv4 octet offsets and big-endian shift amounts
// ---------------------------------------------------------------------------

static constexpr size_t   kIPv4OctetMsb         = 0U;
static constexpr size_t   kIPv4Octet1           = 1U;
static constexpr size_t   kIPv4Octet2           = 2U;
static constexpr size_t   kIPv4OctetLsb         = 3U;

static constexpr uint32_t kIPv4MsbShift         = 24U;
static constexpr uint32_t kIPv4Octet1Shift      = 16U;
static constexpr uint32_t kIPv4Octet2Shift      =  8U;
static constexpr uint32_t kIPv4LsbShift         =  0U;

// ---------------------------------------------------------------------------
// Port field sizes
// ---------------------------------------------------------------------------

static constexpr size_t   kMaxPortBytes          = 2U;

// ---------------------------------------------------------------------------
// ENR "eth" fork-id field sizes
// ---------------------------------------------------------------------------

static constexpr size_t   kForkHashBytes         = 4U;

// ---------------------------------------------------------------------------
// discv5 wire-packet field sizes (from EIP-8020 / go-ethereum v5wire)
// ---------------------------------------------------------------------------

static constexpr size_t   kProtocolIdBytes       = 6U;

static constexpr char     kProtocolId[]          = "discv5";

static constexpr size_t   kGcmNonceBytes         = 12U;

static constexpr size_t   kMaskingIvBytes        = 16U;

static constexpr size_t   kWhoareyouIdNonceBytes = 16U;

static constexpr size_t   kMinPacketBytes        = 63U;

static constexpr size_t   kMaxPacketBytes        = 1280U;

static constexpr size_t   kAes128KeyBytes        = 16U;

static constexpr size_t   kGcmTagBytes           = 16U;

static constexpr size_t   kRandomMessageCiphertextBytes = 20U;

static constexpr uint32_t kFindNodeDistanceAll   = 256U;

static constexpr uint8_t  kHkdfFirstBlockCounter = 0x01U;

static constexpr size_t   kMessageTypePrefixBytes = 1U;

static constexpr uint8_t  kNodesResponseCountSingle = 1U;

// ---------------------------------------------------------------------------
// ENR record sizes
// ---------------------------------------------------------------------------

static constexpr size_t   kEnrMaxBytes           = 300U;

static constexpr size_t   kEnrSigBytes           = 64U;

static constexpr size_t   kEnrPrefixLen          = 4U;

static constexpr char     kEnrPrefix[]           = "enr:";

static constexpr uint8_t  kInitialEnrSeq         = 1U;

static constexpr char     kIdentitySchemeV4[]    = "v4";
static constexpr size_t   kIdentitySchemeV4Bytes = 2U;

static constexpr char     kEnrKeyId[]            = "id";
static constexpr size_t   kEnrKeyIdBytes         = 2U;
static constexpr char     kEnrKeyIp[]            = "ip";
static constexpr size_t   kEnrKeyIpBytes         = 2U;
static constexpr char     kEnrKeySecp256k1[]     = "secp256k1";
static constexpr size_t   kEnrKeySecp256k1Bytes  = 9U;
static constexpr char     kEnrKeyTcp[]           = "tcp";
static constexpr size_t   kEnrKeyTcpBytes        = 3U;
static constexpr char     kEnrKeyUdp[]           = "udp";
static constexpr size_t   kEnrKeyUdpBytes        = 3U;

// ---------------------------------------------------------------------------
// Base64url alphabet sizes (RFC-4648 §5) — used by the ENR URI decoder
// ---------------------------------------------------------------------------

static constexpr uint8_t  kBase64UpperCount      = 26U;

static constexpr uint8_t  kBase64LowerCount      = 26U;

static constexpr uint8_t  kBase64DigitCount      = 10U;

static constexpr uint8_t  kBase64LowerStart      = kBase64UpperCount;

static constexpr uint8_t  kBase64DigitStart      =
    kBase64UpperCount + kBase64LowerCount;

static constexpr uint8_t  kBase64DashIndex       = 62U;

static constexpr uint8_t  kBase64UnderIndex      = 63U;

static constexpr uint8_t  kBase64Invalid         = 0xFFU;

static constexpr size_t   kBase64BitsPerChar     = 6U;

static constexpr size_t   kBase64BitsPerByte     = 8U;

// ---------------------------------------------------------------------------
// Crawler tuning defaults
// ---------------------------------------------------------------------------

static constexpr size_t   kDefaultMaxConcurrent  = 8U;

static constexpr uint32_t kDefaultQueryIntervalSec  = 30U;

static constexpr uint32_t kDefaultPeerExpirySec     = 600U;

static constexpr size_t   kMaxBootnodeEnrs           = 64U;

// ===========================================================================
// Part 2 — Wire-layout POD structs.
//
// Every on-wire field size must be derived from sizeof(SomeWireStruct) so
// that no magic number appears in protocol code.  The static_asserts below
// verify that the compiler's layout matches the domain constants.
// ===========================================================================

// ---------------------------------------------------------------------------
// Cryptographic wire types
// ---------------------------------------------------------------------------

struct IPv4Wire
{
    uint8_t msb;    
    uint8_t b1;     
    uint8_t b2;     
    uint8_t lsb;    
};
static_assert(sizeof(IPv4Wire) == kIPv4Bytes, "IPv4Wire layout must be 4 bytes");

struct IPv6Wire
{
    uint8_t bytes[kIPv6Bytes];  
};
static_assert(sizeof(IPv6Wire) == kIPv6Bytes, "IPv6Wire layout must be 16 bytes");

struct Keccak256Wire
{
    uint8_t bytes[kKeccak256Bytes];  
};
static_assert(sizeof(Keccak256Wire) == kKeccak256Bytes,
              "Keccak256Wire layout must be 32 bytes");

struct CompressedPubKeyWire
{
    uint8_t bytes[kCompressedKeyBytes];  
};
static_assert(sizeof(CompressedPubKeyWire) == kCompressedKeyBytes,
              "CompressedPubKeyWire layout must be 33 bytes");

struct EnrSigWire
{
    uint8_t bytes[kEnrSigBytes];  
};
static_assert(sizeof(EnrSigWire) == kEnrSigBytes,
              "EnrSigWire layout must be 64 bytes");

struct UncompressedPubKeyWire
{
    uint8_t prefix;                       
    uint8_t xy[kNodeIdBytes];             
};
static_assert(sizeof(UncompressedPubKeyWire) == kUncompressedPrefixLen + kNodeIdBytes,
              "UncompressedPubKeyWire size mismatch");

static constexpr size_t kUncompressedKeyBytes =
    sizeof(UncompressedPubKeyWire);  // = kUncompressedPrefixLen + kNodeIdBytes = 65

// ---------------------------------------------------------------------------
// discv5 packet wire types (EIP-8020 / go-ethereum v5wire)
// ---------------------------------------------------------------------------

struct MaskingIvWire
{
    uint8_t bytes[kMaskingIvBytes];  
};
static_assert(sizeof(MaskingIvWire) == kMaskingIvBytes,
              "MaskingIvWire layout must be 16 bytes");

struct GcmNonceWire
{
    uint8_t bytes[kGcmNonceBytes];  
};
static_assert(sizeof(GcmNonceWire) == kGcmNonceBytes,
              "GcmNonceWire layout must be 12 bytes");

#pragma pack(push, 1)
struct StaticHeaderWire
{
    uint8_t       protocol_id[kProtocolIdBytes];  
    uint16_t      version;                         
    uint8_t       flag;                            
    GcmNonceWire  nonce;                           
    uint16_t      auth_size;                       
};
#pragma pack(pop)

static constexpr size_t kStaticHeaderBytes = sizeof(StaticHeaderWire);
static constexpr size_t kStaticHeaderVersionOffset = offsetof(StaticHeaderWire, version);
static constexpr size_t kStaticHeaderFlagOffset = offsetof(StaticHeaderWire, flag);
static constexpr size_t kStaticHeaderNonceOffset = offsetof(StaticHeaderWire, nonce);
static constexpr size_t kStaticHeaderAuthSizeOffset = offsetof(StaticHeaderWire, auth_size);

#pragma pack(push, 1)
struct WhoareyouAuthDataWire
{
    uint8_t  id_nonce[kWhoareyouIdNonceBytes];  
    uint64_t record_seq;                        
};
#pragma pack(pop)

static constexpr size_t kWhoareyouAuthDataBytes = sizeof(WhoareyouAuthDataWire);

static constexpr size_t kHandshakeAuthSizeFieldBytes = sizeof(uint8_t);
static constexpr size_t kHandshakeAuthSizeFieldCount = 2U;
static constexpr size_t kHandshakeAuthSigSizeOffset = kKeccak256Bytes;
static constexpr size_t kHandshakeAuthPubkeySizeOffset = kHandshakeAuthSigSizeOffset + kHandshakeAuthSizeFieldBytes;
static constexpr size_t kHandshakeAuthFixedBytes =
    kKeccak256Bytes + (kHandshakeAuthSizeFieldCount * kHandshakeAuthSizeFieldBytes);

static constexpr size_t kStaticPacketBytes =
    sizeof(MaskingIvWire) + sizeof(StaticHeaderWire);

// ---------------------------------------------------------------------------
// discv5 packet-type flag values (stored in StaticHeaderWire::flag)
// ---------------------------------------------------------------------------

static constexpr uint8_t  kFlagMessage     = 0U;

static constexpr uint8_t  kFlagWhoareyou   = 1U;

static constexpr uint8_t  kFlagHandshake   = 2U;

// ---------------------------------------------------------------------------
// discv5 application message type bytes (inside decrypted message payload)
// ---------------------------------------------------------------------------

static constexpr uint8_t  kMsgPing        = 0x01U;

static constexpr uint8_t  kMsgPong        = 0x02U;

static constexpr uint8_t  kMsgFindNode    = 0x03U;

static constexpr uint8_t  kMsgNodes       = 0x04U;

static constexpr uint8_t  kMsgTalkReq     = 0x05U;

static constexpr uint8_t  kMsgTalkResp    = 0x06U;

static constexpr uint16_t kProtocolVersion = 1U;

} // namespace discv5

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