EIP-8146 Block access list sidecar (Block Access List Sidecars)

Hegota Declined for Inclusion · Scaling & data · EIP status Draft · created 2026-02-03

Separates the block access list (BAL) from the execution payload and propagates it first in a dedicated sidecar. The block size on the critical propagation path is halved, and execution clients can pre-read state before the payload arrives.

Why it is needed

EIP-7928 puts the block access list (BAL) inside the execution payload. Under EIP-7732 (ePBS), this payload is carried in the envelope (SignedExecutionPayloadEnvelope) that the builder reveals during the slot, so the BAL arrives on the same topic and by the same deadline as the transactions. Size is the problem. In an analysis based on a 60 million gas limit, the BAL is about 72.4 KiB, nearly the same as the rest of the compressed block (about 71.7 KiB), so the object passing through the most urgent propagation stage becomes twice as heavy. Also, as long as the BAL is inside the envelope, it cannot be used before the payload arrives, so execution clients cannot take advantage of prefetching state in advance. This proposal separates the BAL into a standalone sidecar that arrives at least 1 second before the payload, and in that interval lets execution clients start state prefetching and computing the post-state root.

What changes

Today

After EIP-8146

Who is affected

In depth

Execution layer rules stay the same, only the delivery path changes

The BAL's construction and validation, and the block_access_list_hash field in the execution block header, remain exactly as specified in EIP-7928. Only the delivery method changes. Instead of arriving inside the payload, the BAL reaches the execution layer through a dedicated Engine API method. The consensus layer treats the BAL only as opaque bytes (ByteList) and does not interpret the RLP.

Constant and container changes

Three constants are added. MAX_BLOCK_ACCESS_LIST_SIZE is uint64(2**23) (8 MiB), the SSZ limit for the encoded BAL. MIN_EPOCHS_FOR_BLOCK_ACCESS_LIST_SIDECARS_REQUESTS is uint64(3533), equal to the BAL retention period in EIP-7928. BLOCK_ACCESS_LIST_LEAD_TIME is uint64(1), the number of seconds by which a sidecar must precede the attestation deadline to count as available. Three containers change. The block_access_list field that EIP-7928 added is removed from ExecutionPayload, block_access_list_hash (keccak256(rlp(BlockAccessList))) is added to ExecutionPayloadBid, and a block_access_list_present boolean is added to PayloadAttestationData. The sidecar itself is a BlockAccessListSidecar container with three fields: beacon_block_root, slot, and block_access_list.

Fork choice: the payload is not passed to the execution layer without the BAL

Two fields, block_access_lists and block_access_list_availability_vote, are added to the Store. on_block_access_list_sidecar checks the sidecar's hash against the bid's block_access_list_hash, stores it, and immediately calls EXECUTION_ENGINE.notify_block_access_list without waiting for the payload. An assert is added to on_execution_payload_envelope requiring that the block's BAL be present locally, which prevents a payload from reaching the execution layer before the BAL of the same block. An envelope that arrives before the sidecar is not discarded. It is cached, and the handler is run again once the BAL is stored.

Networking: a dedicated gossip topic and two request-response protocols

A new global gossip topic called block_access_list_sidecar is created. Before forwarding, a sidecar must pass IGNORE conditions such as slot range, one sidecar per block root, and whether the beacon block has been received, as well as REJECT conditions for block validity, slot match, and keccak256 hash match. Two request-response protocols are added: BlockAccessListSidecarsByRoot v1 (lookup by a list of block roots) and BlockAccessListSidecarsByRange v1 (lookup by slot range). Clients must serve sidecars through both methods for the most recent MIN_EPOCHS_FOR_BLOCK_ACCESS_LIST_SIDECARS_REQUESTS epochs and may prune anything older. This period equals the weak subjectivity period, so a node syncing within it can obtain the BAL from either the consensus or the execution layer.

Engine API: notify comes before newPayload

engine_getPayloadV6 returns blockAccessList as a top-level field of the response rather than a field of the payload structure. The new method engine_notifyBlockAccessListV1 takes the RLP-encoded BAL and blockHash, stores the BAL, starts prefetching the declared accounts and storage slots, and MAY start computing the post-state root from the post-values. This call is not a validity check. It only acknowledges receipt, and validation happens during payload execution by checking against the header. The blockAccessList field that EIP-7928 added is removed from engine_newPayloadV5. For the same blockHash, the consensus layer must call notify before newPayload, and the time between these two calls is the lead time this EIP creates.

Reusing the hash commitment and the unsigned design

Because EIP-7928 already commits to the BAL in the execution block header as keccak256(rlp(BAL)), putting the same 32 bytes in the bid lets the consensus layer authenticate the sidecar without a separate hashing scheme or RLP interpretation. The builder cannot produce contradictory values. Since bid.block_hash indirectly commits to the header, if the bid's BAL hash differs from the revealed payload, the envelope is rejected for a block hash mismatch or the payload is rejected because the execution layer's BAL recomputation does not match. Because the builder has already signed the bid, no separate BLS signature is attached to the sidecar, which is the same way blob data is verified against the bid's commitment. The PTC's block_access_list_present vote is only a signal following the same pattern as blob_data_available, carries no penalty, and availability is enforced by the local gate in on_execution_payload_envelope.

Security: withholding, early exposure, and network load

If a builder withholds the sidecar, the PTC votes False so the failure is visible to the whole network, and no node can verify that payload, so no block is built on top of it. Withholding therefore costs the builder its own block. On early exposure, the sidecar contains no signed transactions, only the access list and post-state values, so unbundling, where a bundle is intercepted within the same slot, is not possible. This risk is exactly why ePBS reveals the envelope late, but the BAL is not exposed to it. Total bytes per slot stay the same, and the load is spread over a wider time window per topic. Verifying a sidecar costs a single keccak256 over at most 8 MiB, which is negligible, and BAL caches for payloads that never arrive SHOULD be bounded by slot distance or finalization.

Status: Draft, excluded from Hegotá candidates

This EIP is in Draft status, so the specification may still change. According to the call records, it was accepted as a Hegotá candidate (PFI) at ACDE #240 on 07.02, but at ACDC #187 on 09.17 it was removed from Hegotá candidacy (DFI) along with EIP-8237, 8341, 8367, 8321, 8243, and 8375. It also requires a hard fork, and BALs of blocks before the fork remain inside the execution payload and are looked up the EIP-7928 way.

Original EIP · ← EIPs