EIP-7642 eth/69: History Expiry and Simpler Receipts (eth/69 - history expiry and simpler receipts)
Final · Networking & nodes · EIP status Final · created 2024-02-29
Upgrades the communication protocol nodes use to exchange blocks (the eth protocol) to eth/69. It has each node announce the range of blocks it keeps and drops the unnecessary Bloom filter from receipts, which greatly reduces the amount of sync data.
Why it is needed
Ethereum nodes exchange block and transaction data using a protocol called eth. The History Expiry working group decided that, from May 1, 2025, clients may delete old block records from before the Merge. However, the existing protocol gives no way to ask a peer whether it still holds old records, so a node that wants past data has to send a request and assume the peer does not have it if the request fails. In addition, the Bloom filter (summary data for log search) inside a receipt (the record of a transaction's processing result) is not stored by any client and is recomputed when needed, yet the protocol required it to be transmitted. As a result, for every newly syncing node the serving node had to regenerate and send about 530GB of Bloom filters, and the receiving side only verified and discarded them, a waste that repeated each time. Finally, the total difficulty (TD) value, which has been meaningless since the Merge, still remained in the handshake message.
What changes
Today
- A node cannot know which range of blocks a peer keeps, so it can only infer that the peer lacks them when a request fails
- Receipts must include the Bloom filter when sent, so about 530GB of extra data is exchanged for every sync
- The total difficulty (td) value, which has been useless since the Merge, is still included in the Status message
After EIP-7642
- The Status message and a new BlockRangeUpdate message announce the range of blocks each node keeps (earliestBlock to latestBlock)
- The Bloom filter is removed from receipts and the receiving side recomputes it itself. This saves at least 95GiB per sync (compressed)
- The td field is removed and the forkid is used instead to tell whether peers are in sync
Who is affected
- Client teams: eth/69 must be implemented. The burden of regenerating receipt Bloom filters disappears, which reduces CPU and bandwidth load on serving nodes.
- Node operators: The data exchanged during a fresh sync drops by about 530GiB per sync (at least 95GiB when compressed). It also becomes easier to find peers that hold old records.
- Ordinary users: Consensus rules and the EVM do not change, so there is no direct effect on wallet use or transactions.
- Researchers and crawler operators: The earliestBlock field lets them survey (census) how many nodes keep historical records and in which implementations.
In depth
Status (0x00) message changes
In eth/68, Status was [version, networkid, td, blockhash, genesis, forkid]. In eth/69 it becomes [version, networkid, genesis, forkid, earliestBlock, latestBlock, latestBlockHash]. td is removed and three fields for the kept block range are added, and blockhash moves to the end and becomes latestBlockHash to match the format of BlockRangeUpdate. The reason for removing td is that block difficulty has been 0 since the Merge so it lost its meaning, and telling whether peers are in sync is possible with forkid.
Receipts (0x10) encoding changes
In eth/68, legacy-receipt and typed-receipt were distinguished, typed-receipt was wrapped as tx-type || rlp(legacy-receipt), and it contained a bloom: B_256 field internally. eth/69 unifies them into one flat list: receipt = [tx-type, post-state-or-status, cumulative-gas, logs]. The consensus layer uses an opaque encoding in which typed transaction receipts are wrapped as a byte array, but since every receipt type ultimately carries the same four fields, the judgment is that there is no reason for the network layer to imitate that costly encoding.
Effect of removing the Bloom filter
No client stores the Bloom field of a receipt; each recomputes it when needed, yet the old protocol required it to be transmitted. As a result, serving nodes regenerated and sent a 256-byte Bloom filter for each of about 2.3 billion transactions, roughly 530GB in total, and receiving nodes discarded them after verification. Removing it saves about 530GiB of bandwidth per syncing node, at least 95GiB with snappy compression, and CPU load on serving nodes. In exchange, a receiving node must recompute the Bloom filter to fully verify the receipt hash, but this computation is not a heavy CPU burden.
New BlockRangeUpdate (0x11)
A new message encoded as [earliestBlock: P, latestBlock: P, latestBlockHash: B_32]. A client sends it whenever the block range it can serve changes, but to reduce traffic it need not send one per block and must send at most one per epoch (32 blocks). It is used to detect a peer's sync state and to adjust data request strategy.
Why earliestBlock is included
The field is not strictly necessary for history expiry itself, but it has three benefits. First, it improves peer discovery for clients that want to fetch historical data over p2p even after the agreed removal of pre-merge history takes effect. Without this field, a client must send a request and assume the data is unavailable if it fails. Second, a dedicated crawler can survey how many nodes, running which implementations, have history enabled. Third, it prepares for a future in which the history expiry window changes dynamically. A similar idea was proposed as EIP-7542, but it was withdrawn because no political decision on history expiry had been made at the time.
Backwards Compatibility and Status
This EIP introduces eth/69, a new version of the wire protocol. Because multiple versions can be supported at the same time, existing clients can keep using eth/68 and will not break immediately. The EVM consensus rules do not change, and no hard fork is required. Protocol version negotiation depends on EIP-5793 (requires). The status of this EIP is confirmed as Final.