This EIP removes the block access list (BAL) from the ExecutionPayloadEnvelope and propagates it as an independent sidecar on a dedicated gossip topic. Builders commit to the BAL root in their ExecutionPayloadBid. Sidecar verification uses this commitment; no separate signature is required. The Payload Timeliness Committee (PTC) enforces BAL availability at the attestation deadline.
EIP-7928 adds block access lists to the ExecutionPayload. Under EIP-7732, the execution payload travels inside a SignedExecutionPayloadEnvelope that the builder broadcasts after the beacon block. Including the BAL (~70 KiB average, up to 1 MiB) in the envelope increases its size and propagation latency on the critical path.
Separating the BAL into a sidecar reduces envelope size, improving propagation. The BAL remains required for execution validation; the PTC enforces availability so that the BAL is present before the payload processing deadline.
| Name | Value |
|---|---|
MAX_BLOCK_ACCESS_LIST_SIZE | uint64(2**23) (= 8 MiB) |
The BlockAccessList type from EIP-7928:
| Name | SSZ equivalent | Description |
|---|---|---|
BlockAccessList | ByteList[MAX_BLOCK_ACCESS_LIST_SIZE] | RLP-encoded block access list |
ExecutionPayloadThe block_access_list field introduced by EIP-7928 is removed:
ExecutionPayloadBidA block_access_list_root field is added:
PayloadAttestationDataA block_access_list_present field is added:
BlockAccessListSidecarblock_access_list_sidecarThis topic propagates BlockAccessListSidecar objects.
The following validations MUST pass before forwarding a sidecar on the network:
sidecar.beacon_block_root has been seen (via gossip or non-gossip sources). A client MAY queue the sidecar for processing once the block is retrieved.BlockAccessListSidecar for this beacon_block_root has been seen.sidecar.slot >= compute_start_slot_at_epoch(store.finalized_checkpoint.epoch).Let block be the beacon block with root sidecar.beacon_block_root. Let bid alias block.body.signed_execution_payload_bid.message:
block passes validation.sidecar.slot == block.slot.hash_tree_root(sidecar.block_access_list) == bid.block_access_list_root.BlockAccessListSidecarsByRange v1Protocol ID: /eth2/beacon_chain/req/block_access_list_sidecars_by_range/1/
Request Content:
Response Content:
Returns sidecars in slot range [start_slot, start_slot + count), ordered by slot. The response MUST contain no more than MAX_REQUEST_PAYLOADS sidecars. Clients SHOULD respond with at least one sidecar if available.
BlockAccessListSidecarsByRoot v1Protocol ID: /eth2/beacon_chain/req/block_access_list_sidecars_by_root/1/
Request Content:
Response Content:
Returns sidecars matching the requested beacon block roots.
Storeon_blockWhen a new block is added to the store, initialize the BAL PTC vote tracker (alongside the existing ptc_vote initialization):
on_payload_attestation_messageThe handler records the BAL availability vote alongside the existing payload presence vote:
notify_ptc_messagesWhen extracting PayloadAttestationMessage objects from PayloadAttestation aggregates in a beacon block, the block_access_list_present field is propagated from the attestation data.
on_block_access_list_sidecaron_execution_payloadBAL availability is required before processing the execution payload. The BAL has already been delivered to the EL via engine_notifyBlockAccessListV1 when the sidecar was received; process_execution_payload itself is unchanged.
engine_getPayloadV6 returns the BAL as a separate blockAccessList field (RLP-encoded bytes) outside the ExecutionPayload. The builder computes block_access_list_root = hash_tree_root(ByteList(blockAccessList)) for inclusion in the bid.
engine_notifyBlockAccessListV1 is a new method that delivers the BAL to the EL independently of the execution payload. It accepts blockAccessList (RLP-encoded bytes) and blockHash (to associate the BAL with the corresponding payload). The EL stores the BAL and begins prefetching the referenced state. The CL calls this method when the BAL sidecar is received (in on_block_access_list_sidecar).
engine_newPayloadV5 is unchanged from EIP-7732. It does not include the BAL. The EL uses the BAL previously delivered via engine_notifyBlockAccessListV1, matching by blockHash.
The execution block header field block_access_list_hash (keccak256 of RLP-encoded BAL) is unchanged from EIP-7928. BAL construction and validation rules are as specified in EIP-7928.
When constructing a bid, the builder:
engine_getPayloadV6.block_access_list_root = hash_tree_root(ByteList(blockAccessList)) and includes it in the ExecutionPayloadBid.BlockAccessListSidecar on the block_access_list_sidecar gossip topic.SignedExecutionPayloadEnvelope (which no longer contains the BAL).Builders SHOULD broadcast the BAL sidecar as early as possible to enable prefetching by the next block's builder.
PTC members set block_access_list_present = True in their PayloadAttestationData if they have received a valid BlockAccessListSidecar for the block (i.e., the sidecar passes gossip validation including the hash_tree_root commitment check).
PTC members set payload_present and blob_data_available per EIP-7732 rules, independently of block_access_list_present.
The BAL sidecar requires no BLS signature. The builder commits to block_access_list_root in the signed ExecutionPayloadBid; verification is hash_tree_root(sidecar.block_access_list) == bid.block_access_list_root. This mirrors DataColumnSidecar verification via KZG proofs against commitments in the bid.
BAL availability is tracked as a dedicated block_access_list_present boolean in PayloadAttestationData, following the same pattern as blob_data_available. This keeps concerns separated: payload_present signals envelope timeliness, blob_data_available signals blob availability, and block_access_list_present signals BAL availability. The fork choice on_execution_payload handler independently gates on local BAL availability (assert root in store.block_access_lists), ensuring execution validation cannot proceed without the BAL regardless of PTC votes.
EIP-7732 applies a variable PTC deadline to the execution payload based on payload size. Since the BAL travels as an independent sidecar, and its size scales inversely with the payload size, this variable deadline does not apply to it.
The BAL is delivered to the EL exclusively via engine_notifyBlockAccessListV1, separate from engine_newPayloadV5. This enables early delivery: the BAL sidecar typically arrives before the execution payload envelope, so the EL can begin prefetching storage slots immediately, or start calculating the post-state root. When the payload arrives later, engine_newPayloadV5 proceeds without the BAL -- the EL already has it, matched by blockHash.
Clients MUST retain BAL sidecars for at least MIN_EPOCHS_FOR_BAL_SIDECARS_REQUESTS epochs to support syncing nodes. After this period, clients MAY prune sidecars.
This EIP requires a hard fork. It modifies the ExecutionPayload and ExecutionPayloadBid containers from EIP-7732 and changes how EIP-7928 BALs are propagated.
Withholding: A builder can withhold the BAL sidecar. PTC members will vote block_access_list_present = False, providing network-wide visibility. The fork choice on_execution_payload handler gates on local BAL availability, so the payload cannot be validated without the BAL. The builder withhold safety properties from EIP-7732 apply: if the beacon block was not timely, the builder is not charged.
Network overhead: The BAL sidecar adds ~70 KiB average per slot to gossip traffic, equal to the current overhead when BAL is inside the envelope. Total network load is unchanged; it is redistributed across topics.
Verification cost: Sidecar verification requires one hash_tree_root computation on up to 1 MiB. This is negligible compared to execution validation.
Copyright and related rights waived via CC0.