5.6 KiB
eip | title | author | discussions-to | status | type | category | created | requires |
---|---|---|---|---|---|---|---|---|
2364 | eth/64: forkid-extended protocol handshake | Péter Szilágyi <peterke@gmail.com> | https://github.com/ethereum/EIPs/issues/2365 | Draft | Standards Track | Networking | 2019-11-08 | 2124 |
Abstract
The forkid
(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 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.
- Implement
forkid
generation and validation per EIP-2124. - Advertise a new
eth
protocol capability (version) ateth/64
.- The old
eth/63
protocol should still be kept alive side-by-side, untileth/64
is sufficiently adopted by implementors.
- The old
- Redefine
Status (0x00)
foreth/64
to add a trailingforkid
field:- Old packet:
[protocolVersion, networkId, td, bestHash, genesisHash]
- New packet:
[protocolVersion, networkId, td, bestHash, genesisHash, forkid]
, whereforkid
is[forkHash: [4]byte, forkNext: uint64]
(fields per EIP-2124 ).
- Old packet:
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) and ENR extension support (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)) 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.
Testing proper advertising and validation at the networking level will require a hive test.
Implementation
Geth: https://github.com/ethereum/go-ethereum/pull/20140
Copyright
Copyright and related rights waived via CC0.