EIP-7862 Delayed state root

Hegota Declined for Inclusion · Scaling & data · EIP status Draft · created 2024-12-23

A proposal that places the previous block's post-state root in the block header instead of the block's own state root, decoupling state root computation from block validation.

Why it is needed

An Ethereum block header contains the state root, a summary value of the ledger after executing all of that block's transactions. Computing this value is a major bottleneck in block production. During the MEV auction, where builders compete over which combination of transactions is most profitable, a builder must recompute the state root every time it changes the combination, so it ends up computing it thousands of times per slot. Once ePBS (EIP-7732) is introduced, builders will have even less time to spare. Block-Level Access Lists (BAL, EIP-7928), the list of storage locations a block touched, parallelize state reads and writes, but the state root is only known once execution finishes, so they do not help within the same slot. This proposal places the state root in the header one block later, so validators can attest to a block's validity without waiting for the state root computation.

What changes

Today

After EIP-7862

Who is affected

In depth

Header: meaning changes, no new fields

The meaning of the Header's state_root field changes. The state_root of block n points to the post-state of block n-1, which is the pre-state of block n. No new field is added. The specification's Header class contains the existing fields such as parent_hash, state_root, transactions_root and receipt_root, along with block_access_list_hash, so it presupposes the BAL (EIP-7928).

last_computed_state_root and header validation

A last_computed_state_root field is added to the BlockChain object to track the most recently computed state root. validate_header raises InvalidBlock if header.number is less than 1, and raises InvalidBlock if header.state_root differs from chain.last_computed_state_root. The rest of header validation is unchanged. In other words, state root validation of a block changes from "does it match the result of executing this block" to "does it match the value computed after executing the previous block".

State transition: root computation moves after execution

state_transition first performs validate_header, then runs the transactions and withdrawals with apply_body. The state_root is excluded from execution result validation, because the header validation has already checked it. Other checks, such as a mismatch between block_gas_used and header.gas_used, are kept. When execution finishes, it computes state_root(block_env.state), stores it in chain.last_computed_state_root, and this value is used in the next block's header validation. The block list keeps only the most recent 255 entries.

Fork activation and backwards compatibility

At the activation block F, apply_fork initializes last_computed_state_root to the current state root, which is the post-state root of block F-1. Block F MUST contain the post-state root of block F-1, and from F+1 onward each block contains the post-state root of its parent block. This change requires a hard fork, and clients that have not implemented it will reject blocks that carry a delayed state root.

ePBS compatibility and BAL synergy

In EIP-7732 (ePBS), the ExecutionPayloadEnvelope carries the consensus layer (CL) state_root, which is verified at the end of process_execution_payload. This proposal only changes the meaning of the state_root in the execution layer (EL) header, so CL-side validation is unaffected. The key point is the synergy with the BAL (EIP-7928). A client receives block n together with its BAL, uses the BAL to parallelize the state root computation of block n, and then includes that root in block n+1. Without this proposal, the state root is only known once execution finishes, so within the same slot the BAL does not help with root computation. In addition, a builder can apply the BAL's state changes to the slot's pre-state and start building a block without fully executing the previous block.

Light client impact

A state proof for block n must wait until block n+1 appears. Most light client protocols already tolerate a delay of several blocks in proof generation, so the impact is limited. The security model does not change, and only the timing is one slot later.

Security considerations: reorgs and pre-state retention

When a chain reorganization (reorg) occurs, the client MUST recompute last_computed_state_root for each block on the new canonical chain. The delayed root does not by itself change reorg logic. The client also MUST retain the pre-state (the post-state of the parent block) until the current block's state root is included in the next block, which is already standard practice for handling reorgs.

Status: dropped from Hegotá candidates

At ACDE #240 on 07.02, EIP-7862 was accepted as a Hegotá candidate (PFI), but it was dropped at ACDE #245 on 09.10 (DFI). The prevailing argument was that parallel computation is possible after the BAL, so the state root is not a major bottleneck, and the decision was that it can be revisited in a future fork together with the binary trie work. The source status is also Draft, so the specification may change.

Original EIP · ← EIPs