Summary
EIP-7928 (Block-Level Access Lists) is the headliner EIP for the Glamsterdam upgrade (H1 2026). The block builder generates a complete map of every transaction’s state reads and writes, attaching it to the block. Verifiers use this map to execute transactions in parallel and prefetch all necessary state in a single I/O pass — targeting significant validation speedups and enabling higher gas limits.
The Core Problem
Ethereum transactions execute sequentially because verifiers can’t know which transactions conflict without running them (Turing completeness). But many transactions in a typical block are independent — they touch different state — and could run in parallel if dependencies were known in advance.
Example dependency:
- Tx A: writes
USDC.balances[Alice]→ 100 - Tx B: reads
USDC.balances[Alice]
B depends on A; they must execute in order.
Example independence:
- Tx A: writes
USDC.balances[Alice]→ 100 - Tx B: writes
WETH.balances[Bob]→ 50
No conflict; can execute in parallel.
How BALs Work
The block builder already executes transactions sequentially (to maximize MEV). During this sequential execution, BALs record:
- For each transaction: every state read and write (address, storage slot, balance, nonce, code)
- The final value of every write (state diff)
This produces a block-level map: {tx_index → {reads: [...state_keys], writes: {state_key → new_value}}}
Parallel Execution Algorithm
With BALs, verifiers can:
- Prefetch: before execution starts, load all state keys mentioned in any read or write
- Build dependency graph: a → b if a writes something that b reads (and a precedes b)
- Execute in parallel: run all transactions in the same “batch” (no dependencies within the batch) simultaneously
- Use state diffs: reads from a later transaction can use the pre-computed state diff from an earlier one, avoiding disk I/O
def read(tx_j, state_key):
last_writer = find_last_writer_before(tx_j, state_key)
if last_writer:
return state_diff[last_writer][state_key]
else:
return disk_state[state_key] # prefetched; no I/O during execution
Real Block Statistics
From dependency.pics analysis:
- Block 23710031 (161 txs): entire block executable in 4 batches — good parallelism
- Block 23710002 (dense DeFi): long dependency chain — limited parallelism
- Real blocks vary widely; DeFi-heavy blocks (all touching Uniswap state) benefit less
BAL Format (Simplified)
BlockAccessList = List[AccountChanges]
AccountChanges = [
address: Address,
slot_changes: List[(StorageKey, List[StorageChange])],
balance_changes: List[BalanceChange],
nonce_changes: List[NonceChange],
code_changes: List[CodeChange]
]
Includes both reads (for I/O prefetch) and writes (for state diff propagation). The full EIP-7928 spec is more detailed.
Benefits
- Parallel execution: transactions with independent state can run simultaneously
- I/O prefetch: all disk accesses happen in one batch before execution begins — no I/O during parallel execution
- zkEVM compatibility: known state access patterns enable more efficient ZK witness generation
- Stateless client support:
blockAccessListHashin the block header allows execution-less validation (check hash without re-executing) - Snap v2 / Trie healing: BALs provide the state diff data needed for faster state sync (see related pages)
Downsides
- Block size increase: BALs add significant data to each block (size proportional to total state accessed)
- Propagation latency: larger blocks → slower propagation → potential missed-slot risk
- Builder overhead: builders must generate and attach the full BAL (they already have the data; encoding and attachment has cost)
The EIP argues the parallelism speedup outweighs the propagation cost; a worst-case analysis (notes.ethereum.org) shows the tradeoff is positive for expected block sizes.
Pruning
BALs are not part of the permanent blockchain state:
- Clients are required to keep BALs for 3553 epochs (~2 weeks) after which they can be pruned
- The
blockAccessListHashin the block header is permanent, allowing BAL integrity verification at any time - API: new
eth_getBlockAccessListmethod; BALs available for the 2-week window only
Historical Note
BALs were originally proposed as read-only “access lists” for I/O prefetch (Dankrad 2021). Writes were added later to enable parallel execution. The name “access list” stuck even though “state diff” would be more accurate.
Distinction from Transaction Access Lists
EIP-2930 introduced optional per-transaction access lists that pre-declare state to access (for gas discounts). These are completely different:
- Per-transaction, not per-block
- Reads only, no state diffs
- Optional and incomplete (can omit accesses)
- Can be incorrect (no strict verification)
- BALs are complete, correct, and mandatory (block is invalid if BAL is wrong)
Related Pages
- Ethereum Protocol Roadmap 2026 — Glamsterdam; BALs as headliner EIP
- ePBS: Enshrined Proposer-Builder Separation (EIP-7732) — ePBS running in the same Glamsterdam upgrade
- Frame Transactions and Native Account Abstraction (EIP-8141) — FOCIL + FrameTx eligibility uses BAL-like state access for index-based validation (alternative builder algorithm)
Key Sources
- Understanding Block-Level Access Lists (Franco Victorio, Mar 2026) — primary explainer; dependency graphs; algorithm; format; historical note