Ethras Blog
Glamsterdam's Block-Level Access Lists: What RPC Developers Should Test
Understand Ethereum's planned block-level access lists, how they differ from transaction access lists, and how to prepare your RPC integrations.
Ethereum's planned Glamsterdam upgrade puts block production and state processing back in focus. For teams building wallets, indexers, or RPC integrations, one useful feature to understand is the block-level access list, usually shortened to BAL.
Status checked November 6, 2026: the Ethereum Foundation's October 22 update postponed Glamsterdam on Hoodi. It did not provide a replacement activation date or set a mainnet date. The guidance below is preparation for the planned feature. Check the latest official announcement and your client's network configuration before running upgrade-specific tests.
What a block-level access list records
Executing a transaction involves reading and updating Ethereum state: account balances, contract code, storage slots, and more. Doing that work efficiently becomes harder when a node has to discover each required disk read while execution is already underway.
EIP-7928 proposes an enforced record covering the accounts and storage locations accessed across an entire block, together with state changes after individual transactions. Clients can use that information to prepare disk reads, validate transactions in parallel, and compute the resulting state root more efficiently.
The proposal also commits to the BAL in the block header and carries the list through the Engine API between consensus and execution clients. That protocol data belongs to block processing. It should not be confused with a promise that a public RPC endpoint exposes a particular new method or response field.
For an application developer, the practical question is which assumptions your integration makes about the data it receives, and which of those assumptions deserve an explicit test.
The access list you already know has a different role
Ethereum already has transaction access lists. EIP-2930 lets a transaction specify addresses and storage keys it expects to access. These lists are optional, and execution can access locations outside them under the applicable gas rules.
A BAL covers a whole block and is enforced as part of the proposed protocol rules. A transaction access list is supplied for an individual transaction. Treat them as distinct data structures in code, documentation, and dashboards.
| Concept | Scope | Purpose |
|---|---|---|
| Transaction access list | One transaction | Declare anticipated account and storage access |
| Block-level access list | An entire block | Record accesses and state changes for client processing |
If your tooling calls eth_createAccessList, it is working with the transaction-level concept. Geth's method documentation describes the result as an estimate: the list can change before inclusion, and adding it does not necessarily reduce gas usage. Keep measuring the transaction you intend to send rather than assuming that any access list is automatically a gas optimization.
Establish a small RPC baseline
Start with requests your application already depends on. For a block reader, a useful first check is a normal request for the finalized execution block:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getBlockByNumber",
"params": ["finalized", false]
}
The Ethereum JSON-RPC reference documents this method and its block tags. The second parameter requests transaction hashes instead of full transaction objects, keeping the response focused on your block-processing baseline.
Record the network, block number, block hash, client or provider, SDK version, and response you used. Exercise your actual decoding and persistence code against that fixture. Repeat with latest and safe if those tags are part of your application's normal workflow; each tag expresses a different view of chain progress.
A successful block request establishes that this path works for that endpoint and network. Keep fork activation checks and optional method capability checks separate in your test report.
A practical integration test plan
The following are engineering recommendations for your own application, rather than claims about new RPC behavior.
- Exercise your response decoder. Test a normal response, missing data, an RPC error, and a response containing an unfamiliar field. Decide deliberately how your SDK and database mapping should handle each case. Preserve the fields your application needs without allowing an unexpected shape to crash the processing loop.
- Separate transaction access-list logic. Name helpers and stored records clearly enough that a future BAL integration cannot accidentally reuse a transaction access-list schema. If you use
eth_createAccessList, keep its estimation tests alongside transaction construction tests. - Test your real contract calls. Where your application relies on gas estimation or fixed transaction gas limits, replay representative workflows on an appropriate upgraded test environment once its activation and client compatibility are confirmed. Record success, reverts, and gas results instead of assuming an infrastructure upgrade preserves every application assumption.
- Measure your own workload. Compare request latency, response sizes, decoding time, and error handling using the same query set. Protocol support for parallel processing does not supply a measured performance result for your endpoint, SDK, or database.
Keep this small enough to run again when client releases or the fork schedule change. A handful of representative reads and transaction simulations, with their network and block context recorded, is easier to review than a large report whose inputs cannot be reproduced.
If you are starting with the underlying request shapes, the RPC documentation provides a place to review method parameters. For Glamsterdam-specific work, follow the current official schedule and the client documentation for the network you actually test.
Share this article
Share on XReview your account and post on X. Opening X or copying text does not send a post.