EIP-2364 eth/64: fork ID handshake extension ("eth/64: forkid-extended protocol handshake")
Final · Networking & nodes · EIP status Final · created 2019-11-08
Introduces eth/64, a new communication protocol that adds a fork identifier (forkid) to the handshake nodes exchange when first connecting. It disconnects incompatible nodes immediately, before expensive work.
Why it is needed
Ethereum nodes connect to each other to exchange blocks and data. But it is hard to tell at first whether a peer follows the same network and the same history of upgrades (forks) as you do. EIP-2124 defined a fork ID that summarizes a node's fork history into a single short value, and a way to validate it, but it did not define when or how nodes would exchange that value with each other. As a result, a connection would be kept with an incompatible node for a while, and only after receiving a block and going through expensive validation such as proof-of-work (PoW) checking, EVM execution, and state reconstruction would it become clear that the peer did not match. In the meantime, a useless peer would also occupy a limited peer slot. This EIP has nodes validate each other's fork ID right at the handshake immediately after connecting, so that incompatible nodes are disconnected on the spot. Each node then spends resources only on peers that are useful to it, and across the network as a whole, groups of nodes following different chains separate from each other, letting each spend more resources maintaining its own chain.
What changes
Today
- The handshake only checks things like protocol version, network ID, and genesis hash
- Whether a peer has a different fork history only becomes known after receiving a block and validating it
- An incompatible node can remain, occupying a peer slot
After EIP-2364
- A fork ID field is added to the Status message in the handshake
- Both nodes validate each other's fork ID and disconnect immediately if incompatible
- Useless connections are filtered out before expensive block exchange and validation
Who is affected
- Client teams: eth/64 must be implemented and the existing eth/63 kept running alongside it until it is sufficiently adopted.
- Node operators: Nodes end up spending resources only on compatible peers, improving sync and peer management efficiency.
- The whole network: Groups of nodes with different fork histories separate from each other, improving the quality of service on each network.
In depth
Redefinition of the Status (0x00) message
In eth/64, a forkid field is added to the end of the handshake's Status (0x00) packet. The existing packet is [protocolVersion, networkId, td, bestHash, genesisHash], and the new packet is [protocolVersion, networkId, td, bestHash, genesisHash, forkid]. forkid has the structure [forkHash: [4]byte, forkNext: uint64], and the meaning of each field follows EIP-2124. Once two peers connect via eth/64, they must send this updated Status message as the handshake, and each peer must validate the peer's forkid and disconnect if incompatibility is detected.
Parallel operation and backwards compatibility with eth/63
This change modifies the eth protocol handshake in a backward-incompatible way, so it is shipped as a new version, eth/64. However, since devp2p supports running multiple versions of the same wire protocol side by side, clients that have not updated can keep using eth/63, and no cross-client coordination of timing is required. Existing eth/63 must be kept alive alongside eth/64 until eth/64 sees sufficient adoption among implementers. Because this does not change the consensus engine, no hard fork is required.
Relationship to discovery protocol advertisement
EIP-2124 mentions advertising the fork ID in the peer discovery protocol as well. Verifying at the discovery stage is more efficient because it avoids the cost of establishing a TCP connection and RLPx encrypted stream only to have it rejected and torn down at eth/64. However, since discovery is meant to merely suggest potential peers, the information can be stale or the node may have changed, so precise verification is still needed after this rough filtering. Verifying forkid at discovery also requires ENR (EIP-778) and ENR extension (EIP-868) support, which the current Ethereum network does not mandate. Systems that cannot use UDP, or that discover peers through other means such as DNS discovery, also need a way to filter connections, so verification at the handshake stage is required as a separate layer.
Why the genesisHash field was kept
The FORK_HASH in forkid includes the genesis hash as a checksum, so forkid-based filtering is a superset of genesis-hash-based filtering. For that reason, this EIP originally treated the genesisHash field in the handshake as redundant data and removed it. That decision was reversed because the genesis hash is also used for purposes beyond connection filtering. Network crawlers use this value to classify current nodes by network. The expectation is that forkid will eventually take over the genesis hash's role, but there is no reason to rush removing the duplicate, so the two are kept side by side for now and the field will be removed in a future version once third-party infrastructure has migrated.
Testing, security, and current status
The test cases for computing and verifying fork ID use the ones defined in EIP-2124 as is. Security considerations are explicitly stated as None in the original text. This EIP is a Standards Track, Networking category EIP with status Final, meaning the specification is finalized and will not change further. eth/63 itself is not specified as an EIP and is maintained in the ethereum/devp2p GitHub repository.