EIP-4938 eth/67: Remove the GetNodeData message ("eth/67 - Removal of GetNodeData")
Final · Networking & nodes · EIP status Final · created 2022-03-23
Removes the GetNodeData and NodeData messages from the wire protocol that nodes use to exchange data, and introduces a new protocol version, eth/67.
Why it is needed
Ethereum nodes exchange blocks and state data through a shared specification called the wire protocol. Among its messages, GetNodeData requests pieces of the state trie or contract code by hash, and it was created for fast sync, which downloads state without executing every block. Answering this request requires a node to store state as a 'mapping from hash to trie node', which is a problem. This storage method is costly, and in practice some clients store state differently and so cannot respond to this request at all. A protocol should contain only what clients can actually do, so this proposal removes from the specification a message that cannot be implemented.
What changes
Today
- The wire protocol includes the GetNodeData and NodeData messages
- To answer this request, a node must store a mapping from hashes to trie nodes in its database
- Some clients store state differently and cannot handle this request
After EIP-4938
- The new version eth/67 removes both messages
- Nodes no longer need to store a hash-based mapping
- The same function is replaced by GetByteCodes and GetTrieNodes in the snap protocol
Who is affected
- Client teams: There is no longer a need to keep hash-based state storage just to serve GetNodeData, and the new eth/67 version must be rolled out.
- Node operators: Nodes that sync from scratch will use snap protocol based sync instead of fast sync. Older clients keep working on eth/66 for the time being.
- Ordinary users: This is a cleanup of the communication protocol between nodes, so nothing changes for transactions, fees, or wallet use.
In depth
The two messages being removed
GetNodeData (0x0d) and NodeData (0x0e) are removed from the eth protocol. Their eth/66 encodings are [request_id: P, [hash_0: B_32, hash_1: B_32, ...]] and [request_id: P, [value_0: B, value_1: B, ...]] respectively. That is, you sent a request ID and a list of 32-byte hashes, and got back a list of the values (trie nodes or contract code) corresponding to those hashes.
Motivation for removal: forced storage structure and infeasibility
GetNodeData and NodeData were introduced in eth/63 for fast sync. Fast sync downloads state by requesting state trie nodes and contract code by hash, without executing every block. Serving this request requires a client to store state as a 'hash to trie node' mapping, and the main motivation for the removal is to stop requiring such a mapping in the database. Some clients today do not store state in a compatible way and cannot serve this request. The original text's argument is that the wire protocol must accurately reflect clients' actual capabilities and must not contain messages that some clients cannot implement.
Replacement: the snap protocol
A replacement for GetNodeData already exists in the separate snap protocol. Specifically, the GetByteCodes (0x04) and GetTrieNodes (0x06) messages can be used instead. It is also possible to implement the fast sync algorithm on the snap protocol, but the original text recommends using it for snap sync.
Backward compatibility: a version swap without a hard fork
This EIP changes the eth protocol, so it requires rolling out the new version eth/67. The wire protocol can support multiple versions at once, so even when a new version is released, older clients can keep using eth/66 and do not break immediately. It does not change the EVM consensus rules, so no hard fork is needed. The original text explicitly states 'none' for security considerations, and the status is Final, a settled networking standard.