EIP-8237 Independent sync for the consensus and execution layers (Independent CL/EL Sync)
Hegota Declined for Inclusion · Networking & nodes · EIP status Draft · created 2026-04-22
Replaces the execution_requests_root in the bid with partial_header_hash, a SHA256 accumulator hash, so the consensus layer can do range sync without downloading execution payloads.
Why it is needed
Today, when a new node does range sync to catch up with the chain, the consensus layer (CL) must download blocks in bulk, run the consensus state transition, and send each block's execution payload to the execution engine for validation. Because EIP-7732 separated the payload from the beacon block, in principle the CL only needs to download beacon blocks. That would greatly reduce bandwidth and CPU latency. However, without the payload envelope (ExecutionPayloadEnvelope), there is no way to check whether the payload's block hash matches the block_hash in the bid, or whether fields such as execution requests match the execution_requests_root in the bid. This EIP solves the problem by bundling the fields that need validation into one value and keeping a SHA256 accumulator hash that chains across blocks. Once the execution layer (EL) catches up later, the CL can check in one step that the entire commitment chain is consistent, without the individual payloads.
What changes
Today
- During range sync, the CL downloads the payload for each block and sends it to the execution engine for validation
- The bid (ExecutionPayloadBid) has an execution_requests_root field
- Even during sync, the CL and EL must keep communicating to validate block hashes
After EIP-8237
- The CL does range sync by downloading only beacon blocks, without payloads
- execution_requests_root is removed from the bid, and a partial_header_hash accumulator is added to BeaconBlockBody and ExecutionPayload
- After the EL catches up, a single accumulator checks the consistency of the whole chain in one batch
Who is affected
- CL client teams: They must change the range sync logic to sync without payload downloads and per-block engine calls, and implement the accumulator validation in two places (verify_execution_payload_envelope, process_parent_execution_payload)
- EL client teams: They must add a partial_header_hash field to ExecutionPayload and the block header, and independently compute and validate the same accumulator function. A new Engine API method for finding the divergence point is also needed
- Node operators: The bandwidth and CPU load of syncing when starting a new node goes down
- Builder: The structure of the bid container that builders submit changes
In depth
Remove execution_requests_root from ExecutionPayloadBid
Removes the execution_requests_root field from the ExecutionPayloadBid container introduced by EIP-7732. The remaining fields are parent_block_hash, parent_block_root, block_hash, prev_randao, fee_recipient, gas_limit, builder_index, slot, value, execution_payment and blob_kzg_commitments. The commitment to execution requests moves from a root hash to the accumulator approach.
partial_header_hash accumulator definition
A partial_header_hash of type Hash32 is added to BeaconBlockBody. compute_partial_header_hash is the value obtained by concatenating parent_hash, prev_randao, gas_limit, timestamp, withdrawals, slot_number and execution_requests as bytes and running SHA256 once. A uint64 is 8 bytes little-endian, and a list concatenates the bytes of each element as they are. Plain SHA256 is used instead of SSZ hash_tree_root because the EL does not implement SSZ hashing infrastructure. This value needs no Merkle proof and only has to be a binding commitment to the chain of values.
Consensus layer validation changes
In verify_execution_payload_envelope, the check hash_tree_root(envelope.execution_requests) == bid.execution_requests_root is removed. Instead, it checks that the compute_partial_header_hash computed from state.latest_execution_payload_bid's parent_block_hash, prev_randao, gas_limit, compute_timestamp_at_slot(state, bid.slot), state.payload_expected_withdrawals, bid.slot and requests equals envelope.payload.partial_header_hash. The check hash_tree_root(requests) == parent_bid.execution_requests_root in process_parent_execution_payload likewise becomes a check against block.body.partial_header_hash. The latter applies to blocks built as full.
Independent validation by the execution layer
A partial_header_hash: Hash32 field is added to the ExecutionPayload container, and the same field goes into the EL block header (Header) so that block_hash covers this value. The EL must independently compute the same accumulator function from block.parent_hash, block.prev_randao, block.gas_limit, block.timestamp, block.withdrawals, block.slot_number and execution_requests, and verify that it matches the payload's value. Because the two layers each maintain and validate the same commitment chain, each layer can detect a mismatch on its own during sync, without communication between layers.
Engine API method for finding the divergence point
After a long range sync ends, if the accumulators of the two layers disagree when the CL sends the first gossiped payload, it is known that the chain is wrong but not where they diverged. For this, a new Engine API method is needed that returns the accumulator value of the block for a given block_hash, and the CL looks up values per block hash to find the divergence point.
Security assumptions and compatibility
There are no new trust assumptions. The CL still validates every execution payload in the end and only defers that validation during range sync. The accumulator cryptographically guarantees that the deferred validation catches any mismatch. However, it is a consensus-breaking change to the ExecutionPayloadBid, BeaconBlockBody and ExecutionPayload containers, so it must be activated by a hard fork.
Status and fork decision
This EIP is in Draft status, so the specification may still change. At the ACDC #187 call on September 17, 2026, EIP-8237 was declined (DFI) from the Hegotá candidates along with EIP-8341, 8367, 8321, 8243, 8146 and 8375.