--- eip: 2364 title: "eth/64: forkid-extended protocol handshake" author: Péter Szilágyi discussions-to: https://github.com/ethereum/EIPs/issues/2365 status: Draft type: Standards Track category: Networking created: 2019-11-08 requires: 2124 --- ## Abstract The [`forkid` (EIP-2124)](https://eips.ethereum.org/EIPS/eip-2124) was designed to permit two Ethereum nodes to quickly and cheaply decide if they are compatible or not, not only at a genesis/networking level, but also from the perspective of the currently passed network updates (i.e. forks). [EIP-2124](https://eips.ethereum.org/EIPS/eip-2124) only defines how the `forkid` is calculated and validated, but does not specify how the `forkid` should be exchanged between peers. This EIP specifies the inclusion of the `forkid` as a new field in the Ethereum wire protocol (`eth`) handshake (releasing a new version, `eth/64`). By cross-validating `forkid` during the handshake, incompatible nodes can disconnect before expensive block exchanges and validations take place (PoW check, EVM execution, state reconstruction). This further prevents peer slots from being taken up by nodes that are incompatible, but have not yet been detected as such. ## Motivation From a micro perspective, cutting off incompatible nodes from one another ensures that a node only spends its resources on tasks that are genuinely useful to it. The sooner we can decide the remote peer is useless, the less time and processing we expend in vain. From a macro perspective, keeping incompatible nodes partitioned from one another ensures that disjoint clusters retain more resources for maintaining their own chain, thus raising the quality of service for all networks globally. ## Specification The specification is tiny since most parts are already specified in EIP-2124. `eth/63` is not specified as an EIP, but is maintained [here](https://github.com/ethereum/devp2p/blob/master/caps/eth.md). - Implement `forkid` generation and validation per [EIP-2124](https://eips.ethereum.org/EIPS/eip-2124). - Advertise a new `eth` protocol capability (version) at `eth/64`. - The old `eth/63` protocol should still be kept alive side-by-side, until `eth/64` is sufficiently adopted by implementors. - Redefine `Status (0x00)` for `eth/64` to add a trailing `forkid` field: - Old packet: `[protocolVersion, networkId, td, bestHash, genesisHash]` - New packet: `[protocolVersion, networkId, td, bestHash, genesisHash, forkid]`, where `forkid` is `[forkHash: [4]byte, forkNext: uint64]` (fields per [EIP-2124](https://eips.ethereum.org/EIPS/eip-2124) ). Whenever two peers connect using the `eth/64` protocol, the updated `Status` message must be sent as the protocol handshake, and each peer must validate the remote `forkid`, disconnecting at a detected incompatibility. ## Rationale ##### EIP-2124 mentions advertising the `forkid` in the discovery protocol too. How does that compare to advertising in the `eth` protocol? Why is the redundancy needed? Advertising and validating the `forkid` in the discovery protocol is a more optimal solution, as it can help avoid the cost of setting up the TCP connection and cryptographic RLPx stream, only to be torn down if `eth/64` rejects it. Compared to the `eth` protocol however, discovery is a bit fuzzy. The goal there is to suggest potential peers, not to be fool-proof. Information may be outdated, nodes may have changed or disappeared. Discovery can do a rough filtering, but more precision is still needed afterwards. Additionally, `forkid` validation via the discovery protocol requires ENR implementation ([EIP-778](https://eips.ethereum.org/EIPS/eip-778)) and ENR extension support ([EIP-868](https://eips.ethereum.org/EIPS/eip-868)), which is not mandated by the Ethereum network currently. Lastly, the discovery protocol is just one way to find peers, but systems that cannot use UDP or that rely on other mechanism (e.g. DNS discovery ([EIP-1459](https://eips.ethereum.org/EIPS/eip-1459))) still need a way to filter connections. ##### The `forkid` implicitly contains the genesis hash checksummed into the `FORK_HASH` field. Why doesn't this proposal remove the `genesisHash` field from the `eth` handshake? Originally this EIP did remove it as redundant data, since filtering based on the `forkid` is a superset of filtering based on genesis hash. The reason for backing out of that decision was that the genesis hash may be useful for other things too, not just connection filtering (network crawlers use it currently to split nodes across networks). Although the `forkid` will hopefully take over all the roles of the genesis hash currently in use, there's no reason to be overly aggressive in deduplicating data. It's fine to keep both side-by-side for now, and remove in a future version when 3rd party infrastructures switch over. ## Backwards Compatibility This EIP extends the `eth` protocol handshake in a backwards incompatible way and requires rolling out a new version, `eth/64`. However, `devp2p` supports running multiple versions of the same wire protocol side-by-side, so rolling out `eth/64` does not require client coordination, since non-updated clients can keep using `eth/63`. This EIP does not change the consensus engine, thus does _not_ require a hard fork. ## Test Cases For calculating and validating fork IDs, see test cases in [EIP-2124](https://eips.ethereum.org/EIPS/eip-2124). Testing proper advertising and validation at the networking level will require a [hive](https://github.com/ethereum/hive) test. ## Implementation Geth: https://github.com/ethereum/go-ethereum/pull/20140 ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).