# Besu vs EIP-7928 Block-Level Access Lists (Amsterdam): spec-conformance review

Item `besu`, batch `el-bal`. Public-page code review only. Nothing was run against a network or a node. EIP-7928 is scheduled for Amsterdam (Glamsterdam) and is **not live on Ethereum mainnet**, so file and line citations are given in full.

## 1. Pins

| Repository | Branch | Commit | Committer date |
|---|---|---|---|
| besu-eth/besu | main | `aa06c4f8dfc461e483d46c6a1ac72b5bfef8d945` | 2026-10-27T13:41:33Z |
| ethereum/execution-specs | forks/bogota (default; no master) | `7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b` | 2026-10-27T17:40:55Z |
| ethereum/go-ethereum | master | `8817f99f92852f8ac53e596de6202dd9e3494065` | 2026-10-27T03:32:47Z |

Pinned via `https://api.github.com/repos/<owner>/<repo>/commits/<branch>`. Besu code was read from a shallow sparse clone of `https://github.com/besu-eth/besu` at that commit (`git rev-parse HEAD` = `aa06c4f8…`). Spec and Geth files were read from `raw.githubusercontent.com` at the pinned commits. EIP text from `https://raw.githubusercontent.com/ethereum/EIPs/master/EIPS/eip-7928.md` (the rendered page is `https://eips.ethereum.org/EIPS/eip-7928`). Spec path prefix used below: `src/ethereum/forks/amsterdam/`.

Every `file#Lstart-Lend` below is at the pinned commit of that repository.

## 2. Result in one paragraph

Besu's EIP-7928 implementation at the pin agrees with the execution-specs Amsterdam BAL semantics and the EIP text on every rule I checked (section 4, 34 rules). This includes the one rule named in the brief as wrong in Geth: netting of writes across the shared post-execution index n+1 (and index 0). Besu captures the account and slot values at the first write of a shared index, diffs every later view against that capture, and replaces (not merges) the index's recorded changes, which is exactly what the spec's `index_start_accounts`/`index_start_storage` plus `remove_*_change` do. **No candidate is reported.** Per the brief ("prefer no candidate to a weak one") I list below the three places where I spent the most effort trying to find a divergence and why each closed, so a merge can see what was tried.

## 3. Candidates

None. Three near-candidates were investigated to closure:

### 3a. Shared-index netting (withdrawal credit forwarded away; slot restored by a later system call)

- **Spec** (`block_access_lists.py#L765-L824`, pinned 7f2f4c9): "Compare the transaction's writes against the state at the start of the current block access index … A write that leaves a value where the index found it records no change, and drops one recorded earlier at the same index by another transaction sharing it, such as a second system call." Index-start capture: `_index_start_account` `#L727-L744`, `_index_start_storage` `#L747-L762`; removal: `remove_balance_change` `#L543-L561`, `remove_storage_write` `#L516-L540`. Index assignment: `fork.py#L830-L835` (withdrawals and requests share `len(transactions)+1`), `#L815-L825` (both pre-execution calls share index 0 via the builder default `block_access_lists.py#L305`).
- **Besu**: one `AccessLocationTracker` per shared index (`AbstractBlockProcessor.java#L202-L204` pre-execution, `#L361-L365` post-execution), with `sharedIndex=true` (`BlockAccessList.java#L196-L203`). `AccessLocationTracker.java#L212-L265` `addChangesSinceIndexStart` diffs the current account against `indexStartAccounts`, which is filled on the first write at the index via `captureIndexStart` (`#L267-L278`, `computeIfAbsent`, so a later call cannot overwrite the capture) and for storage records `getOriginalStorageValue` of the slot the first time the index writes it (`#L272-L277`). The builder then **replaces** the index's entries: `BlockAccessList.java#L224-L232` calls `removeChangesAt(txIndex)` (`#L440-L448`) before re-adding the view's writes, balance, nonce and code, and a slot that netted out is re-added as a read (`#L243`, `#L430-L434`). The withdrawals updater is applied through the same tracker (`WithdrawalsProcessor.java#L33-L44`), each system call is applied against its own pre-commit updater (`SystemCallProcessor.java#L146-L187`, apply at `#L182` precedes `commit()` at `#L185`), and a final apply with a fresh updater re-nets all touched accounts after the last system call (`AbstractBlockProcessor.java#L409-L412`).
- **Walk-through (withdrawal credit forwarded away):** withdrawal credits A from B0 to B0+w; the view captures B0 and records post-balance B0+w at n+1. A later system call at n+1 moves w out of A; its view finds A still in `touchedAccounts`, `indexStart.balance` = B0 (kept by `computeIfAbsent`), current balance B0, so no balance entry; `apply` removes the earlier n+1 entry. Result: A present with no balance change, as in the spec. Slot restored: same path through `#L251-L264`, change replaced by a read.
- **Index-start value correctness:** the tx/system-call updater's `getOriginalStorageValue` resolves to the Bonsai accumulator's `getPriorStorageValue` (`UpdateTrackingAccount.java#L302-L310` → `BonsaiAccount.java#L298-L301` → `PathBasedWorldStateUpdateAccumulator.java#L707-L734`), which returns the value committed by earlier transactions in the block (or zero for storage cleared earlier in the block), i.e. the cumulative pre-index value the EIP note at line 218 requires, not the pre-block value.
- **Geth** at 8817f99: `core/types/bal/bal.go#L145-L195` `Merge` keeps "the value from other" for a colliding `(slot, txIdx)` and txIdx-keyed balance/nonce/code, and `core/state/statedb.go#L825-L854` diffs each system call only against its own journal originals. Geth therefore agrees with neither the spec nor Besu here; this is go-ethereum issue 35776 (open, "Merge keeps the last write when two system calls touch the same slot at the last index").
- **Disproof attempted:** traced both the "first call writes, second restores" and "first call reads only, second writes" orders; traced a zero-amount withdrawal to a non-existent address (account deleted by `clearAccountsThatAreEmpty`, `WithdrawalsProcessor.java#L39`, handled by the `isDeleted` branch `AccessLocationTracker.java#L219-L221`, `#L228-L236`: no balance entry, address kept). No divergence found. Confidence that Besu matches the spec: high.

### 3b. Header without `block_access_list_hash` skips the executed-BAL check

- `MainnetBlockAccessListValidator.java#L99-L101`: `if (blockHeader.getBalHash().isEmpty()) return Optional.empty();` so an Amsterdam block whose header lacks the field would never have its executed BAL compared to anything. `BlockHeader.java#L357-L359` decodes a header with the two trailing fields absent without error.
- Closed because Besu requires the EIP-7843 `slotNumber` field, which is encoded **after** `balHash`, on every Amsterdam header: `MainnetProtocolSpecs.java#L1191-L1195` (`slotNumberAwareBlockHeaderValidator`, `.slotNumberRequired(true)`). A header missing `balHash` necessarily misses `slotNumber` and is rejected. On the engine path the field is always set from the payload (`ethereum/api/.../engine/EngineNewPayloadV5.java#L70-L72`). Pre-Amsterdam specs reject any supplied BAL or BAL hash (`MainnetProtocolSpecs.java#L199`, `BlockAccessListValidator.java#L30-L32`). This indirect enforcement is fragile if `slotNumber` were ever made optional, but produces the spec result today. Not a candidate.

### 3c. SSTORE halting after the current-value read records the slot

- Besu `SStoreOperation.java#L98-L115`: checks the stipend sentry (`#L88-L90`) and the access cost (`#L101-L103`) **before** reading, then reads the current value (`#L105-L111`, recording the slot through `AbstractOperation.java#L170-L178`) and may still halt on the full write cost at `#L113-L115`, leaving the slot in `storage_reads`.
- Spec `vm/instructions/storage.py#L103-L116` does the same: `check_gas(max(access_cost, CALL_STIPEND+1))` before `get_storage` (which records the read, `state_tracker.py#L274`), and `charge_gas(evm, gas_cost)` only at `#L156`. EIP line 176 only forbids the slot when the *access-cost* check fails. Reads survive the revert in both (spec: shared `storage_reads` set across snapshots, `state_tracker.py#L762-L765`; Besu: tracker is independent of the updater). Identical. Not a candidate.

## 4. Rules checked and found consistent

Spec paths are under `src/ethereum/forks/amsterdam/` at 7f2f4c9; Besu paths at aa06c4f.

| # | Rule | Spec | Besu | Note |
|---|---|---|---|---|
| 1 | Index 0 for both pre-execution system calls, i+1 for tx i, n+1 for withdrawals and requests | `fork.py#L815-L835`, `#L1034-L1036`, `block_access_lists.py#L305-L312` | `BlockAccessList.java#L196-L208`; `AbstractBlockProcessor.java#L202-L204`, `#L265-L266`, `#L361-L365` | same arithmetic |
| 2 | Netting across a shared index (see 3a) | `block_access_lists.py#L727-L824` | `AccessLocationTracker.java#L212-L302`, `BlockAccessList.java#L224-L265`, `#L440-L448` | Geth differs (issue 35776) |
| 3 | No-op write within a non-shared index records no change, slot surfaces as read | `#L821-L824` | `AccessLocationTracker.java#L185-L207` (`isUpdate` false → `addStorageRead`) | `getOriginalStorageValue` is never null here (`UpdateTrackingAccount.java#L302-L310`), so `isSet`/`isReset` branches are dead |
| 4 | Slot both read and written appears only in `storage_changes` | `#L656-L659` | `BlockAccessList.java#L416-L434` | read removed on write, write blocks later read |
| 5 | Address order lexicographic; slots ascending numeric; changes by index ascending | `#L646-L687` | `BlockAccessList.java#L303-L307`, `#L481-L524`, `#L462-L470` | unsigned 32-byte compare equals numeric |
| 6 | Balance change = post-balance when pre ≠ post | `#L787-L792` | `AccessLocationTracker.java#L162-L165`, `#L173-L176` | |
| 7 | Nonce change when pre ≠ post | `#L794-L799` | `#L166-L168` uses `>` | equivalent: a post-EIP-6780 account cannot lose nonce without deletion, and deletion is handled first at `#L135-L147` |
| 8 | Code change carries post code; cleared code recorded as empty bytes (EIP-7702 clear) | `#L801-L811` | `#L169-L172`, `#L180-L182` | `withNewCode(account.getCode())` yields empty bytes on clear |
| 9 | Max nonce (2^64−1): no nonce change when CREATE fails, encoding as U64 | `fork_types`/`U64(post_nonce)` `#L797` | `RLPOutput.java#L117-L119` (`Bytes.minimalBytes(long)` → 8 bytes for values ≥2^63), `BytesValueRLPInput.java#L322-L337` | unreachable on chain; encodes the same bytes |
| 10 | Zero-value transfer and self-transfer: sender and recipient present; no balance entry when net zero | `state_tracker.py#L606-L637`, `#L591-L603`; EIP l.235 | `MainnetTransactionProcessor.java#L230`, `#L882`; diff at `AccessLocationTracker.java#L162-L165` | |
| 11 | Coinbase touched even with zero fee | `fork.py` `disburse_gas_fees` (create_ether → `get_account` → `account_reads`, `state_tracker.py#L190`); EIP l.259 | `MainnetTransactionProcessor.java#L618-L624` | explicit comment "EIP-158 & EIP-7928" |
| 12 | Zero block reward never creates an entry | EIP l.242 | `AbstractBlockProcessor.java#L442-L444` (PoS reward processor adds nothing); no tracker passed | |
| 13 | Created-then-selfdestructed account (EIP-8246 in both): no nonce/code change, written slots become reads, balance zero recorded only if it was positive | `state_tracker.py#L494-L539`, `fork.py#L1088-L1089`; EIP l.262 | `MainnetTransactionProcessor.java#L987-L1001` (`settleSelfDestructs`), `#L650-L657`; `AccessLocationTracker.java#L135-L147` (deleted) or `#L173-L183` (kept with balance) | self-beneficiary case: both keep the account with its balance and record a balance change |
| 14 | Destroyed-then-recreated account: later reads see zero and are recorded as reads | `state_tracker.py#L278-L284`, `#L518-L539` | `PathBasedWorldStateUpdateAccumulator.java#L717-L719`, `#L730-L732`; recreated account has `wrappedAccount == null` → reads at `AccessLocationTracker.java#L185-L194` | |
| 15 | Reverted frames: reads kept, writes dropped | `state_tracker.py#L734-L765` (shared read sets) | tracker independent of updater; writes only from committed `getUpdatedStorage` (`AccessLocationTracker.java#L185`) | |
| 16 | Touched accounts for BALANCE/EXTCODE*/CALL family/CREATE target/7702 authority and delegation target | `block_access_lists.py#L223-L229`, `#L606-L622` | `AbstractOperation.java#L100-L160`, `AbstractCallOperation.java#L256-L257`, `#L412`, `ContractCreationProcessor.java#L138`, `MessageCallProcessor.java#L151-L154`, `CodeDelegationHelper.java#L115`, `MainnetTransactionProcessor.java#L337-L341`, `#L916-L917`, `#L973` | call-site level only; per-opcode gas ordering not re-derived except SSTORE (3c) |
| 17 | SSTORE access-cost check precedes the read; later OOG keeps the read | `storage.py#L103-L116`, `#L156` | `SStoreOperation.java#L88-L115` | see 3c |
| 18 | System contract address included even when the contract is absent | `fork.py#L748-L780` (`process_top_level` reads target) | `SystemCallProcessor.java#L148-L155` | |
| 19 | Failed unchecked system call: reads kept, no writes | `fork.py#L774-L778` | `SystemCallProcessor.java#L182-L187` (apply on uncommitted updater) | |
| 20 | `SYSTEM_ADDRESS` not included unless accessed | EIP l.108 | `SystemCallProcessor.java#L218`, `#L230`: originator/sender only; not touched | `miningBeneficiary(Address.ZERO)` at `#L225` is not touched either |
| 21 | Withdrawals: balance at n+1, address touched, empty account cleared | `fork.py#L1096-L1115` | `WithdrawalsProcessor.java#L33-L46` | |
| 22 | BAL hash = keccak(rlp(list)); empty list → `0x1dcc…9347` | `block_access_lists.py#L850-L856`; EIP l.33 | `BodyValidation.java#L146-L149`; `Hash.java#L62` (`EMPTY_BAL_HASH = EMPTY_LIST_HASH`); `GenesisState.java#L230` | supplied BAL hashed over its raw bytes (`BlockAccessListDecoder.java#L114`), so a non-canonical re-encoding cannot match the header |
| 23 | Header hash check after execution; mismatch → block invalid | `fork.py#L331-L333`, `#L355-L356` | `AbstractBlockProcessor.java#L452-L473`, `MainnetBlockAccessListValidator.java#L93-L119`, `#L188-L213` | |
| 24 | `block_access_list_hash` required on Amsterdam headers, forbidden before | `blocks.py` Header dataclass (field mandatory) | indirect via `slotNumberRequired(true)` `MainnetProtocolSpecs.java#L1191-L1195`; pre-fork `#L199`, `BlockAccessListValidator.java#L30-L32` | see 3b |
| 25 | First Amsterdam block: BAL factory and validator installed with the fork spec | `fork.py#L301-L323` | `MainnetProtocolSpecs.java#L1166-L1167` (`blockAccessListFactory`, `MainnetBlockAccessListValidator::create`) | parent-fork state not special-cased anywhere; none needed |
| 26 | Item limit: addresses + unique slots ≤ gas_limit // 2000, checked after full execution | `block_access_lists.py#L859-L892`, `vm/gas.py#L140`, `fork.py#L846-L850` | `AmsterdamGasCalculator.java#L143`, `#L179-L181`; `MainnetBlockAccessListValidator.java#L68-L91`; count `BlockAccessList.java#L81-L88`, `#L316-L318` | Besu also rejects early per transaction (`#L324-L347`); sound because the running count never decreases (a netted-out write is re-added as a read, `#L440-L448` then `#L430-L434`) |
| 27 | Index type uint32; nonce uint64; values uint256 | `fork_types.py#L25` (`BlockAccessIndex = U32`); EIP l.55-l.57 | `BlockAccessListDecoder.java#L63`, `#L82`, `#L92`, `#L102` (`readUnsignedIntScalar`, 4 bytes max `BytesValueRLPInput.java#L353-L356`), `#L93` (`readLongScalar`, 8 bytes), `#L58`, `#L64`, `#L83` (`readUInt256Scalar`, 32 bytes) | |
| 28 | Non-minimal scalars (leading zero bytes) rejected | EIP l.91 | `BytesValueRLPInput.java#L293-L306` (`checkScalar`) used by all four readers above; `#L395-L406` | fixed by besu PR 11234 (merged) |
| 29 | Address exactly 20 bytes; code variable length | EIP l.91 | `BlockAccessListDecoder.java#L52` (`Address.readFrom`), `#L103` | |
| 30 | Canonical encoding on output: minimal scalars, index via `writeUnsignedInt` | EIP l.91 | `BlockAccessListEncoder.java#L26-L82`, `RLPOutput.java#L89-L91`, `#L117-L119` | |
| 31 | Supplied-BAL structural rules: order, uniqueness, no slot in both lists, non-empty `SlotChanges`, index ≤ n+1 | EIP l.180-l.194, l.411 | `MainnetBlockAccessListValidator.java#L121-L163`, `#L220-L393`; decoder leaves empty change lists to the validator (`BlockAccessListDecoder.java#L68-L71`) | only affects engine/p2p supplied BALs; spec never decodes one |
| 32 | Parallel execution determinism | n/a (spec is sequential) | `BalConcurrentTransactionProcessor.java#L78-L95` (overlay from the *supplied* BAL at index i+1), `#L151-L201` (per-tx tracker), `#L203-L241`; views merged in tx order `AbstractBlockProcessor.java#L247-L295` | A wrong supplied BAL makes some tx's executed view differ from it, so the built BAL cannot hash to the header: by induction over tx index, only the honest BAL passes. Lists are sorted at build (`BlockAccessList.java#L462-L524`), so merge order cannot change the output |
| 33 | Block gas limit used for the item budget is the header's | `fork.py#L306`, `#L849` | `MainnetBlockAccessListValidator.java#L77` | |
| 34 | Sort comparator in validator is unsigned | EIP l.183-l.185 | `MainnetBlockAccessListValidator.java#L225-L226`, `#L395-L398` (Tuweni `Bytes.compareTo`: bit-length then unsigned bytes; equal-length inputs → numeric) | |

Not checked (out of time, stated so a merge does not count them as verified): per-opcode gas-before-touch ordering for BALANCE, EXTCODE*, CALL family and CREATE beyond the call-site inventory in rule 16; `BlockAccessListOverlay`/`importStateChangesFromPartialView` state-root effects for touched pre-existing empty accounts (`BalConcurrentTransactionProcessor.java#L235-L236`); EVM v2 operation variants (`evm/.../v2/operation/*V2.java`), which carry the same hooks at `AbstractOperationV2.java#L141-L205` but were not traced.

## 5. Known-check

Queries run against `https://api.github.com/search/issues?q=repo:besu-eth/besu <term>` on 2026-10-27: `7928` (72 results), `block access list` (270), `bal hash` (95), `BAL netting` (0), plus the EEST "Test Release Tracker" search (36) and `https://hive.ethpandaops.io/glamsterdam/listing.jsonl` (999 rows, 112 with Besu).

Since no candidate is reported, the known-check records the Besu items relevant to the rules above:

- Shared-index netting: no Besu issue or PR found with queries `BAL netting`, `7928`, `block access list` mentioning the n+1 netting; the behaviour is implemented in `AccessLocationTracker.java#L212-L302` with comments describing it. Geth side: `https://github.com/ethereum/go-ethereum/issues/35776` (open).
- Minimal scalars: `https://github.com/besu-eth/besu/pull/11234` "fix(bal): decode block access list uint256 fields as minimal scalars" (closed/merged).
- Empty change set per slot: `https://github.com/besu-eth/besu/pull/10582` (closed/merged).
- Item budget: `https://github.com/besu-eth/besu/pull/10250`, `.../pull/10621`, `.../pull/11195`, `.../pull/11454` (all closed).
- System calls and contract creation in BALs: `https://github.com/besu-eth/besu/pull/11397` (closed), `.../pull/10926` "exclude the recipient when a runtime halt precedes its load" (closed), `.../issues/10543` "7702 insufficient gas edge case" (closed).
- Engine BAL params: `https://github.com/besu-eth/besu/pull/10785` (closed).
- Already indexed by the requester and not re-derived here: ACDT 95 devnet-8 Besu outage (pm 2209), execution-apis 868, hive engine 9 / enginex 69 fails. The hive listing confirms the latter at the newest Besu runs: `eels/consume-engine` 2026-10-25 pass 44216 fail 9; `eels/consume-enginex` 2026-10-26 pass 83189 fail 69; `eels/consume-rlp` 2026-10-25 pass 44161 fail 0; `eels/execute` 2026-10-26 pass 173 fail 0. The failing test names were not fetched (listing only), so whether any of the 9/69 are BAL tests is **not known** from this item.
- Related open Besu issues seen, not spec-conformance: `.../issues/11248` (OOM on devnet-8), `.../issues/11546` (snap/2 GetBlockAccessLists empty for cached BALs), `.../issues/11475` (no per-request cap).
- EEST trackers seen: `https://github.com/ethereum/execution-specs/issues/3889` (bogota-devnet v2.0.0, open), `.../issues/3518` (glamsterdam-devnet v8.1.4, closed), `.../issues/3217` (tests v21.0.0, open); `.../pull/3566` "eip7928 extended coverage" (closed). Not opened in detail.

## 6. URLs read

- https://api.github.com/repos/besu-eth/besu/commits/main
- https://api.github.com/repos/ethereum/execution-specs/commits/forks/bogota
- https://api.github.com/repos/ethereum/go-ethereum/commits/master
- https://github.com/besu-eth/besu (shallow sparse clone at aa06c4f8dfc461e483d46c6a1ac72b5bfef8d945; files: `ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/block/access/list/{AccessLocationTracker,BlockAccessList,PartialBlockAccessView}.java`, `.../mainnet/{AbstractBlockProcessor,MainnetBlockAccessListValidator,BlockAccessListValidator,BlockAccessListItemSizeCheck,BodyValidation,WithdrawalsProcessor,MainnetTransactionProcessor,MainnetProtocolSpecs}.java`, `.../mainnet/systemcall/SystemCallProcessor.java`, `.../mainnet/parallelization/BalConcurrentTransactionProcessor.java`, `.../core/encoding/{BlockAccessListDecoder,BlockAccessListEncoder}.java`, `.../core/{BlockHeader,BlockHeaderBuilder,SealableBlockHeader}.java`, `.../chain/GenesisState.java`, `.../trie/pathbased/bonsai/account/BonsaiAccount.java`, `.../trie/pathbased/bonsai/worldview/accumulator/PathBasedWorldStateUpdateAccumulator.java`, `ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/{BytesValueRLPInput,RLPInput,RLPOutput}.java`, `evm/src/main/java/org/hyperledger/besu/evm/operation/{AbstractOperation,SStoreOperation,AbstractCallOperation}.java`, `evm/.../worldstate/UpdateTrackingAccount.java`, `evm/.../gascalculator/AmsterdamGasCalculator.java`, `evm/.../frame/Eip7928AccessList.java`, `datatypes/src/main/java/org/hyperledger/besu/datatypes/Hash.java`, `ethereum/api/.../engine/EngineNewPayloadV5.java`)
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/block_access_lists.py
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/fork.py
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/blocks.py
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/state_tracker.py
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/fork_types.py
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/vm/gas.py
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/vm/instructions/storage.py
- https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/vm/instructions/system.py
- https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/types/bal/bal.go
- https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/state/statedb.go
- https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/state_processor.go
- https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/state/journal.go
- https://api.github.com/repos/ethereum/go-ethereum/git/trees/8817f99f92852f8ac53e596de6202dd9e3494065?recursive=1
- https://api.github.com/repos/ethereum/go-ethereum/issues/35776
- https://raw.githubusercontent.com/ethereum/EIPs/master/EIPS/eip-7928.md
- https://api.github.com/search/issues?q=repo:besu-eth/besu%207928 (and the other query terms listed in section 5)
- https://api.github.com/search/issues?q=repo:ethereum/execution-specs%20%22Test%20Release%20Tracker%22
- https://hive.ethpandaops.io/glamsterdam/listing.jsonl
