Skip to main content
netspecsEthereum networking

3.1.4.Execution discovery profile

Stage
Current
Validity
Active non-fork protocol.
Pulled
devp2peth.mdEIPseip-2124.mddevp2peth.md
Related
Node bootstrapdiscv4discv5DNS discoveryExecution peering

This specification defines the “eth” ENR entry, which provides information about the eth capability on a certain node.

Entry Format

entry-key   = "eth"
entry-value = [[ forkHash, forkNext ]]

At this time, the “eth” entry is a single element list containing an EIP-2124 fork ID value. Please see the EIP for definitions of forkHash and forkNext.

In order to be compatible with future versions of this specifications, implementations should ignore any additional list elements in entry-value.

Historical block-number fork identifiers and validation (EIP-2124)

Each node maintains the following values:

  • FORK_HASH: IEEE CRC32 checksum ([4]byte) of the genesis hash and fork blocks numbers that already passed.
    • The fork block numbers are fed into the CRC32 checksum in ascending order.
    • If multiple forks are applied at the same block, the block number is checksummed only once.
    • Block numbers are regarded as uint64 integers, encoded in big endian format when checksumming.
    • If a chain is configured to start with a non-Frontier ruleset already in its genesis, that is NOT considered a fork.
  • FORK_NEXT: Block number (uint64) of the next upcoming fork, or 0 if no next fork is known.

E.g. FORK_HASH for mainnet would be:

  • forkhash₀ = 0xfc64ec04 (Genesis) = CRC32(<genesis-hash>)
  • forkhash₁ = 0x97c2c34c (Homestead) = CRC32(<genesis-hash> || uint64(1150000))
  • forkhash₂ = 0x91d1f948 (DAO fork) = CRC32(<genesis-hash> || uint64(1150000) || uint64(1920000))

The fork identifier is defined as RLP([FORK_HASH, FORK_NEXT]). This forkid is cross validated (NOT naively compared) to assess a remote chain’s compatibility. Irrespective of fork state, both parties must come to the same conclusion to avoid indefinite reconnect attempts from one side.

Validation rules

    1. If local and remote FORK_HASH matches, compare local head to FORK_NEXT.
    • The two nodes are in the same fork state currently. They might know of differing future forks, but that’s not relevant until the fork triggers (might be postponed, nodes might be updated to match).
      • 1a) A remotely announced but remotely not passed block is already passed locally, disconnect, since the chains are incompatible.
      • 1b) No remotely announced fork; or not yet passed locally, connect.
    1. If the remote FORK_HASH is a subset of the local past forks and the remote FORK_NEXT matches with the locally following fork block number, connect.
    • Remote node is currently syncing. It might eventually diverge from us, but at this current point in time we don’t have enough information.
    1. If the remote FORK_HASH is a superset of the local past forks and can be completed with locally known future forks, connect.
    • Local node is currently syncing. It might eventually diverge from the remote, but at this current point in time we don’t have enough information.
    1. Reject in all other cases.

Stale software examples

The examples below try to exhaust the fork combination possibilities that arise when nodes do not run matching software versions, but otherwise follow the same chain (mainnet nodes, testnet nodes, etc).

Past forksFuture forksHeadRemote FORK_HASHRemote FORK_NEXTConnectReason
AAYes (1b)Same forks, same sync state.
A< BABYes (1b)Remote is advertising a future fork, but that is uncertain.
A>= BABNo (1a)Remote is advertising a future fork that passed locally.
ABAYes (1b)Local knows about a future fork, but that is uncertain.
ABABYes (1b)Both know about a future fork, but that is uncertain.
AB1< B2AB2Yes (1b)Both know about differing future forks, but those are uncertain.
AB1>= B2AB2No (1a)Both know about differing future forks, but the remote one passed locally.
[A,B]ABYes (2)Remote out of sync.
[A,B,C]ABYes¹ (2)Remote out of sync. Remote will need a software update, but we don’t know it yet.
ABA ⊕ BYes (3)Local out of sync.
AB,CA ⊕ BYes (3)Local out of sync. Local also knows about a future fork, but that is uncertain yet.
AA ⊕ BNo (4)Local needs software update.
ABA ⊕ B ⊕ CNo² (4)Local needs software update.
[A,B]ANo (4)Remote needs software update.

Note, there’s one asymmetry in the table, marked with ¹ and ². Since we don’t have access to a remote node’s future fork list (just the next one), we can’t detect that it’s software is stale until it syncs up. This is acceptable as 1) the remote node will disconnect from us anyway, and 2) this is a temporary fluke during sync, not permanent with a leftover node.

Connection handoff to eth

Once a connection is established, a Status message must be sent. Following the reception of the peer’s Status message, the Ethereum session is active and any other message may be sent.