EIP-8247 - Ancestor-Indexed BALs

Created 2026-05-03
Status Draft
Category Core
Type Standards Track
Authors
Requires

Abstract

Replace repeated 20-byte addresses and 32-byte storage keys in EIP-7928 Block Access Lists (BALs) with compact references into one of the last eight canonical ancestor BALs. Expected reduction in BAL size is approximately 30–50%, depending on cross-block reuse.

Motivation

A large share of BAL bytes are addresses and storage keys that already appeared in a recent block. Referencing the prior position is shorter than re-emitting the literal.

Specification

The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Types

AddressKey    = Address    | AccountRef
StorageKeyRef = StorageKey | SlotRef

AccountRef = [ancestor_offset: uint8, account_index: uint32]
SlotRef    = [ancestor_offset: uint8, account_index: uint32, slot_index: uint32]

ancestor_offset ∈ [0..7], where 0 is the parent block, 1 the grandparent, and so on up to 7 (the 8th ancestor).

AccountRef MUST be an RLP list of length 2. SlotRef MUST be an RLP list of length 3.

References and literals are disambiguated by RLP type: an Address is a 20-byte string and an AccountRef is a list; a StorageKey is an RLP-encoded 32-byte value and a SlotRef is a list.

Modified Structures

The EIP-7928 structures are amended to accept references:

SlotChanges     = [StorageKeyRef, List[StorageChange]]
AccountChanges  = [AddressKey, List[SlotChanges], List[StorageKeyRef],
                   List[BalanceChange], List[NonceChange], List[CodeChange]]
BlockAccessList = List[AccountChanges]

All other EIP-7928 fields and semantics are unchanged.

Reference Targets

A reference target is the expanded view of a canonical ancestor BAL: the literal-only BlockAccessList that has already passed EIP-7928 validation, with all of this EIP's references resolved. References MUST NOT target encoded ancestor BALs. References MUST NOT target the current block.

For an expanded ancestor BAL:

This EIP does not redefine ancestor BAL ordering beyond defining the per-account slot dictionary used for slot_index lookup.

Clients MUST retain or reconstruct expanded views and their per-account slot dictionaries for the last eight post-activation canonical blocks.

Canonical Encoding

The targeted ancestor of a reference is the block at height block_number(B) - ancestor_offset - 1.

For any literal Address or StorageKey in the current BAL B, a valid reference is any AccountRef or SlotRef with ancestor_offset ∈ [0..7] that resolves to the same value against an expanded ancestor view available among the last eight canonical post-activation ancestor BALs. If multiple references resolve to the same literal value, all are valid candidates.

The canonical order over valid references is:

A literal MUST NOT be used if a valid reference exists. The encoding MUST use the smallest valid reference under the canonical order.

Validation

For a block with BlockAccessList B:

  1. Reject any reference with ancestor_offset ∉ [0..7].
  2. Reject any reference whose targeted ancestor (block_number(B) - ancestor_offset - 1) is < 0 or < activation height.
  3. Reject any AccountRef whose account_index is out of bounds in the targeted ancestor.
  4. Reject any SlotRef whose account_index or slot_index is out of bounds in the targeted ancestor.
  5. Resolve each AccountRef and SlotRef against the cached expanded view of the corresponding ancestor and replace it in B with its resolved literal to obtain the expanded B'.
  6. Apply EIP-7928 validation to B'.
  7. Reject B if any literal Address or StorageKey in it has a valid reference in the last eight expanded ancestor views.
  8. Reject B if any reference is not the smallest valid reference under the canonical order defined above.

Activation

References to blocks prior to activation are invalid. References are only valid if the targeted ancestor lies within the last eight canonical post-activation blocks.

Size Constraint

The bal_items count from EIP-7928 is computed on the expanded BAL.

Rationale

Encoding Savings

Address    20 bytes → AccountRef ≈ 5 bytes (1 + 4)
StorageKey 32 bytes → SlotRef    ≈ 9 bytes (1 + 4 + 4)

Window of Eight

Eight blocks bounds the ancestor state held for validation while capturing most cross-block reuse, and fits ancestor_offset in 3 bits.

Canonical Encoding Rule

Forcing the smallest valid reference makes the encoded BAL a function of the block and its ancestors only, preventing producers from bloating the encoding by choosing literals or larger offsets.

Backwards Compatibility

Hard fork. Pre-activation BALs are unreachable from references and remain valid in their original literal form.

Test Cases

TBD

Security Considerations

Validation requires retaining eight expanded ancestor BAL views and their per-account slot dictionaries. Reference resolution is then a bounded array lookup, with no recursion, bounding DoS risk. The EIP-7928 bal_items budget continues to bound the expanded size.

A reorg invalidates blocks whose references no longer resolve under the new canonical chain, consistent with normal handling of block-bound data.

Copyright

Copyright and related rights waived via CC0.