# Merged EL review: Geth, Nethermind, Besu — Amsterdam (Glamsterdam) spec conformance

Merge of three public-source, static reviews (item-geth, item-nethermind, item-besu). Nothing was run against any node or network. No finding of the merger's own is added and no candidate is dropped. Candidates are numbered `<client>-<n>`. Nethermind and Besu each reported **no candidate**; Geth reported **two**. Only Geth was reviewed against Nethermind as a control; Erigon and Reth were not covered by this group (not checked). Scope of all three items: EIP-8282, EIP-7843, EIP-7928, EIP-7997 and the matching Engine API methods (newPayloadV5, getPayloadV6, forkchoiceUpdatedV4). The other scheduled EIPs were inventoried, not audited.

## 1. Pins

Citation convention: every `path#Lstart-Lend` below is at the pin of the repository named in its prefix: `geth:` / `neth:` / `besu:` / `eels:` (execution-specs) / `api:` (execution-apis) / `eips:` / `cs:` (consensus-specs). The pins are in the table.

| Client / source | Branch | Commit (pin) | Spec commit used (EELS, `forks/bogota`, Amsterdam dir) |
|---|---|---|---|
| Geth (`ethereum/go-ethereum`) | master | `8817f99f92852f8ac53e596de6202dd9e3494065` (2026-10-27 03:32:47 UTC) | `7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b` |
| Nethermind (`NethermindEth/nethermind`) | master | `d48833af88ec4224c86afadd1c596e8f619c406b` (2026-10-27 12:00:20 UTC) | `7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b` |
| Besu (`besu-eth/besu`) | main | `aa06c4f8dfc461e483d46c6a1ac72b5bfef8d945` | `7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b` |
| execution-specs (EELS) | forks/bogota | `7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b` (2026-10-27 17:40:55 UTC) | — |
| execution-apis (Engine API) | main | `3284ee80c3da3e516c53782dde75157cccf1ebdc` (Geth and Nethermind items) | — |
| EIPs | master | `d4c575521d99ec881a444ab3af604e684b5f0743` (2026-10-27 16:04:29 UTC) | — |
| consensus-specs | master | `8a80ffa82bd49aac0dd6db17f9e8150aa257fbc2` (2026-10-27 16:28:12 UTC) | — |

Pin source for each: `https://api.github.com/repos/<owner>/<repo>/commits/<branch>`.

Notes on pins and where the items differ:
- The `execution-apis` `commits/master` endpoint returned HTTP 422 (Geth, Nethermind items) / "No commit found for SHA: master" (Besu item). Geth item found raw `master` `src/engine/amsterdam.md` byte-identical to the pinned `main` file (SHA-256 `43fadd7a8bacab0cc906658599650ee7d14b2cb4717912718a81a8475937fcc7`). The Besu item recorded no commit for execution-apis and read the raw `master` document; it did not hash it. Besu's Engine API line numbers (`#L100-L127`, `#L49-L91`, `#L128-L152`, `#L203-L242`) refer to that raw `master` file, which the Geth item found identical to the pin above.
- The Geth item dated its review 2026-10-28; the others 2026-10-27. Pins are as each item stated.
- Besu's item lists the Geth pin only as a cross-check source; it did not pin Nethermind, and did not pin EIPs or consensus-specs.

## 2. Scheduled EIPs and spec versions (from the Geth and Nethermind items)

Meta EIP-7773 (`eips:EIPS/eip-7773.md#L21-L55`; Nethermind item cites `#L22-L82`) lists 18 scheduled EIPs: **2780, 7688, 7708, 7732, 7778, 7843, 7928, 7954, 7976, 7981, 7997, 8024, 8037, 8038, 8045, 8061, 8246, 8282**. Networking EIPs 7975, 8070, 8136, 8159, 8189 and informational EIPs 7904, 8261 are listed separately and are not added to the scheduled list. Mainnet activation is blank (`eips:EIPS/eip-7773.md#L62-L70`); `geth:params/chainspecs/mainnet.json#L1-L51` contains no Amsterdam activation. Besu's item notes EIP-7773 is not Final and its scope can change. EL membership is corroborated by `eels:src/ethereum/forks/amsterdam/__init__.py#L7-L20` (Nethermind item: `#L1-L40`); Gloas references are at `cs:specs/gloas/beacon-chain.md#L165-L182`.

"Current spec version" = the text of `EIPS/eip-<n>.md` at the EIPs pin (no semantic version). Status at the pin and the older EIP revision recorded in EELS test metadata (`eels:tests/amsterdam/<eip dir>/spec.py`) or by Gloas:

| EIP | Title; status at EIPs pin | Reference revision recorded by tests/Gloas |
|---|---|---|
| 2780 | Resource-Based Intrinsic Transaction Gas; Last Call | EL `7243c92ba812437c64bae9fc6524ee269b29daa9` (`eip2780_reduce_intrinsic_tx_gas/spec.py#L14-L17`) |
| 7688 | Forward Compatible Consensus Data Structures; Review | CL `f2e6d7fb01194d590e16fcdcae8061d06cf1a7f1` |
| 7708 | ETH Transfers Emit a Log; Last Call | EL `f7230c46a743313957d8f38a159bda934cc735b2` (`eip7708_eth_transfer_logs/spec.py#L14-L18`) |
| 7732 | Enshrined Proposer-Builder Separation; Last Call | CL `c36a2e58a4496ed21bef6b1c97505b03fd159f0a` |
| 7778 | Block Gas Accounting without Refunds; Last Call | EL `4897aec97160c72d2080acf928b132f2efc1a886` (`eip7778_block_gas_accounting_without_refunds/spec.py#L12-L16`) |
| 7843 | SLOTNUM Opcode; Last Call | EL `c3bfd4ba41cf0fcbfe8c404f33ba89f5174971e0` (`eip7843_slotnum/spec.py#L14-L16`) |
| 7928 | Block-Level Access Lists; Last Call | EL `f834f0004aa5110a5f1ac0d6b80e3dc4b842d040` (`eip7928_block_level_access_lists/spec.py#L14-L16`) |
| 7954 | Increase Maximum Contract Size; Last Call | EL `2e62d6a88aa596e4efbf3592cda7706f8a51dac3` (`eip7954_increase_max_contract_size/spec.py#L14-L17`) |
| 7976 | Increase Calldata Floor Cost; Last Call | EL `c998ef94eb16a6af8a9b8e2084f947b17ea14865` (`eip7976_increase_calldata_floor_cost/spec.py#L12-L16`) |
| 7981 | Increase Access List Cost; Last Call | EL `8da3cf91d4bc688c43cc25f2f03b7c86c7bbc257` (`eip7981_increase_access_list_cost/spec.py#L12-L16`) |
| 7997 | Deterministic Factory Contract; Last Call | EL `192193facea01dfb8b87ad59d67e8385bf9304b1` (`eip7997_deterministic_factory_contract/spec.py#L16-L18`) |
| 8024 | Backward Compatible SWAPN, DUPN, EXCHANGE; Last Call | EL `34b49095ca5f7343045da279f04e7ecd1e451393` (`eip8024_dupn_swapn_exchange/spec.py#L15-L19`) |
| 8037 | State Creation Gas Cost Increase; Last Call | EL `19bdfb4f97064dfbeb3d41d31efac211265b49a6` (`eip8037_state_creation_gas_cost_increase/spec.py#L23-L27`) |
| 8038 | State-Access Gas Cost Update; Last Call | EL `f83531466a3862853424a81d000727b3043ef2cc` (`eip8038_state_access_gas_cost_increase/spec.py#L12-L16`) |
| 8045 | Exclude Slashed Validators from Proposing; Last Call | CL `414a8404198c5afaa3cfed10a385a9aae1dfaae3` |
| 8061 | Increase Exit and Consolidation Churn; Last Call | CL `01f15c37c64114c478cb1136e0a6966084e4db14` |
| 8246 | Remove SELFDESTRUCT Burn; Last Call | EL `8be64cf6a01350938b93332cf0062ab7a3166f23` (`eip8246_selfdestruct_no_burn/spec.py#L14-L17`) |
| 8282 | Builder Execution Requests; Last Call | EL `45e570a246207d5b1fb095e259e3f98bb0922639` (`eip8282_builder_execution_requests/spec.py#L18-L20`); Gloas `de4c6f02c7bec4686762c55f8ab6abcf97a77d7d` |

The four scoped EIPs (7843, 7928, 7997, 8282) have Last Call deadline 2026-11-01 (Geth item). The test-metadata revisions are provenance, not proof of coverage of later edits; judgments use the pinned executable Amsterdam spec and Engine spec. Gloas separately references EIP-8070 and EIP-8261 (`cs:specs/gloas/beacon-chain.md#L163-L186`). Builder type allocation and request ordering agree between EL and Gloas (`cs:specs/gloas/beacon-chain.md#L587-L592`, `#L2123-L2141`) per the Nethermind item.

## 3. Candidates

### Geth

#### geth-1 — missing `targetGasLimit` accepted by forkchoiceUpdatedV4

**1. Spec, verbatim.** `api:src/engine/amsterdam.md#L81-L91` defines:

> - `targetGasLimit`: `QUANTITY`, 64 Bits - target value for the `gasLimit` field of the new payload

`api:src/engine/amsterdam.md#L222-L228` requires:

> `payloadAttributes` matches the [`PayloadAttributesV4`](#payloadattributesv4) structure, return `-38003: Invalid payload attributes` on failure.

**2. Geth, quoted at the pin.** `geth:eth/catalyst/api.go#L223-L243` checks withdrawals, root and slot, then fork time, but not `TargetGasLimit`:

```go
case params.SlotNumber == nil:
    return engine.STATUS_INVALID, attributesErr("missing slot number")
case !api.checkFork(params.Timestamp, forks.Amsterdam, forks.BPO3, forks.BPO4, forks.BPO5, forks.Bogota):
    return engine.STATUS_INVALID, unsupportedForkErr("fcuV4 must only be called for amsterdam payloads")
```

`geth:beacon/engine/pa_codec.go#L39-L77` permits the absent pointer; `geth:eth/catalyst/api.go#L388-L411` passes it to the builder. `geth:miner/worker.go#L290-L300` falls back:

```go
gasCeil := miner.config.GasCeil
if miner.chainConfig.IsAmsterdam(number, timestamp) && genParams.targetGasLimit != nil {
    gasCeil = *genParams.targetGasLimit
}
```

**3. Trigger/result, in words.** A synchronized Geth receives FCU V4 for a valid known head and future Amsterdam timestamp. Attributes contain all other required fields but omit `targetGasLimit`, or set it null. Geth can return a build ID and steer toward its configured ceiling; the pinned spec requires invalid payload attributes. The resulting block need not be consensus-invalid.

**4. Nethermind (comparison).** `neth:src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs#L281-L308` contains:

```csharp
>= PayloadAttributesVersions.V4 when TargetGasLimit is null => $"{nameof(TargetGasLimit)} must be provided",
```

The enclosing validator returns `InvalidPayloadAttributes`; `neth:src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs#L316-L333` identifies slot-bearing attributes as V4 and expects V4 for Amsterdam. **Agrees with the pinned spec.** (Besu's item reports its V4 attribute handling at `besu:EngineForkchoiceUpdatedV4.java#L151-L183` as requiring slot number and target gas limit; see section 4.)

**5. Confidence / disproof.** **High** for the source difference, **medium** that Geth rather than the spec should change. Decoder and builder checks do not reject the missing field. However, go-ethereum PR #35514, **closed/merged**, deliberately made it optional for devnet 8. PR #35353, **closed/unmerged**, earlier proposed requiring it. This is an intentional implementation/spec disagreement. Supplied targets are honored; a target does not bypass the parent gas-limit adjustment.

**6. Severity.** **Cosmetic**, meaning Engine input-validation incompatibility under the prescribed categories, not wrong gas charges/fees or invalid-block acceptance.

**Known-check: known** via go-ethereum #35514 and #35353. EIP/name searches: `7843`, `SLOTNUM`, `7928`, `"block access list"`, plus `"targetGasLimit"` and `"forkchoiceUpdatedV4"`, all scoped to Geth and both issue/PR states. No additional omission report found; Hive unavailable to this item.

#### geth-2 — final-index BAL merges retain zero-net changes

**1. Spec, verbatim.** EIP-7928 recording semantics (`eips:EIPS/eip-7928.md#L196-L235`) compare writes with the value before the index. `eels:src/ethereum/forks/amsterdam/block_access_lists.py#L765-L824` implements:

```python
pre_balance = pre_account.balance if pre_account else U256(0)
post_balance = post_account.balance if post_account else U256(0)
if pre_balance != post_balance:
    add_balance_change(builder, address, idx, post_balance)
else:
    remove_balance_change(builder, address, idx)
```

It similarly calls `remove_storage_write(builder, address, u256_slot, idx)` for restored slots. `eels:src/ethereum/forks/amsterdam/block_access_lists.py#L727-L762` caches index-start values; `eels:src/ethereum/forks/amsterdam/fork.py#L830-L844` assigns withdrawals and request calls the same final index.

**2. Geth, quoted at the pin.** `geth:core/state_processor.go#L194-L229` merges separate withdrawals/request scopes. The request helper `geth:core/state_processor.go#L469-L510` starts a fresh scope at the same index:

```go
evm.StateDB.Prepare(evm.GetRules(), common.Address{}, common.Address{}, nil, nil, nil)
evm.StateDB.SetTxContext(common.Hash{}, 0, blockAccessIndex)
```

After the call, `bal := evm.StateDB.Finalise(evm.GetRules())`. `geth:core/state/statedb.go#L825-L854` compares metadata with this individual scope's journal pre-value. `geth:core/types/bal/bal.go#L158-L195` only overwrites collisions:

```go
existing[txIdx] = value
```

```go
for txIdx, balance := range otherAcc.BalanceChanges {
    acc.BalanceChanges[txIdx] = balance
}
```

`geth:core/block_validator.go#L181-L195` rejects a different computed BAL commitment.

**3. Trigger/result, in words.** In an Amsterdam **test prestate with substituted request-contract code**, a withdrawal credits a request predeploy whose system call forwards the credit away. The balance returns to its pre-final-index value. Geth retains a balance-change entry; EELS omits it but retains the address. The published balance fixture includes the two builder predeploys. A companion fixture has two request calls change and restore a shared slot: Geth retains a write instead of a read. Identical final state/requests can thus give different BAL hashes and block validity.

The storage fixture `eels:tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py#L536-L650` explicitly substitutes old request-contract code. go-ethereum issue #35894 documents the balance fixture's builder recipients. **No canonical Ethereum-predeploy trigger was established:** the specified queue runtimes do not forward balances or call each other, and users cannot simply replace their code. This is arbitrary-prestate conformance evidence, not a demonstrated canonical-network exploit.

**4. Nethermind (comparison).** `neth:src/Nethermind/Nethermind.Consensus/Processing/BlockAccessListManager.SystemContracts.cs#L72-L91` shares the post-execution world state. `neth:src/Nethermind/Nethermind.Core/BlockAccessLists/BlockAccessListAtIndex.cs#L107-L132` preserves the baseline:

```csharp
UInt256 preTxBalance = accountChanges.PreTxBalance ??= before;
accountChanges.BalanceChange = preTxBalance != after
    ? new BalanceChange(Index, after)
    : null;
```

`neth:src/Nethermind/Nethermind.Core/BlockAccessLists/BlockAccessListAtIndex.cs#L212-L241` removes restored storage changes and adds reads. **Agrees with EELS**, unlike Geth; not locally executed.

**5. Confidence / disproof.** **High** for the source/fixture difference; **low** for canonical-state reachability. Withdrawals already precede calls, so the old ordering bug is not this defect. Merge still only overwrites. `geth:tests/block_test.go#L90-L96` skips both fixtures with `TODO: these require netting the BAL changes over a whole block access index`. go-ethereum PR #35843 proposes reconciliation but is **open/unmerged**. The canonical-runtime reachability check defeats an unqualified Ethereum consensus-split claim, not the executable-spec difference.

**6. Severity.** **Valid block rejected**, conditional on the arbitrary-prestate fixture model; building also produces a different BAL encoding. Not an established canonical-network consensus split. This defect depends on Amsterdam BAL processing, not active mainnet behavior.

**Known-check: known.** go-ethereum #35776, **open**, covers storage; #35894, **closed**, covers balances and limits reachability; PR #35843, **open/unmerged**, proposes the fix. A closed report is not evidence of a merged fix. PR #35806, **closed**, reordered withdrawals, which the current code confirms. EELS tracker #3217 lists netting coverage (#3566). Searches covered `7928` / `"block access list"` and `8282` / `"builder requests"`. Hive unavailable to this item.

**Mainnet applicability gate (Geth item):** both Geth candidates depend on Amsterdam features not active on mainnet; no live-code finding is included, so no detail is withheld.

### Nethermind

No candidate (nethermind-n: none). The item states no concrete divergent Amsterdam result survived review. Rejected hypotheses are recorded in section 5.

### Besu

No candidate (besu-n: none). The item did not promote the EIP-7997 coverage gap to a candidate, because the six-part format needs a concrete client file and trigger and none can be supplied for an absent implementation (see section 4, row EIP-7997).

## 4. Cross-client table

Cells: `agrees with spec`, `differs (see <client>-<n>)`, or `not checked`. Erigon and Reth are outside this group and so not checked for every row (omitted from the table). Qualifiers in brackets come from the item that checked it. A "Besu not checked" below means the Besu item did not list that rule.

| Rule | Geth | Nethermind | Besu |
|---|---|---|---|
| EIP-8282 builder addresses (0x…D8282 / 0x…E8282) and request types 03/04 | agrees with spec | agrees with spec | agrees with spec |
| EIP-8282 runtime bytes of deposit/exit predeploys | agrees with spec (deposit 628 B and exit 458 B equal EELS `.bin`; in-memory comparison, no VM run) | not checked (deployed bytecode identity not audited) | not checked |
| Builder calls run after ordinary execution, withdrawals and types 00/01/02; deposit then exit | agrees with spec | agrees with spec | agrees with spec (ascending sorted map) |
| System caller, empty calldata, zero value | agrees with spec | agrees with spec | agrees with spec (empty-data system calls) |
| 30,000,000 execution gas with separate state-gas reservoir, not charged to block gas | agrees with spec | agrees with spec | agrees with spec (Amsterdam reservoir support) |
| Empty predeploy code / failed call invalidates block | agrees with spec | agrees with spec | agrees with spec |
| Empty request data omitted; requests ascending by type; requests_hash construction | agrees with spec | agrees with spec | agrees with spec (hash helper not exposed in the inspected slice; no discrepancy in inspected path) |
| Execution recomputes requests commitment, does not trust CL list | agrees with spec | agrees with spec | not checked |
| newPayloadV5 executionRequests: rejects null/type-only/duplicate/descending | agrees with spec | agrees with spec | not checked |
| newPayloadV5 requires slotNumber and BAL; missing → invalid params | agrees with spec | agrees with spec | agrees with spec |
| Malformed BAL RLP → INVALID payload (not a params error) | agrees with spec | agrees with spec (latestValidHash null on this path) | agrees with spec |
| BAL header hash = keccak of supplied raw RLP bytes | agrees with spec | agrees with spec | agrees with spec |
| newPayloadV5 / getPayloadV6 timestamp gating, -38005 UnsupportedFork | agrees with spec (no claim on malformed-input error precedence) | agrees with spec (V5 rejects Bogota; V6 retrieval continues under BAL-enabled specs, successor fork out of scope) | agrees with spec (UnsupportedFork for timestamps outside Amsterdam) |
| getPayloadV6 response fields (V4 payload, blobs bundle, executionRequests, value, override) | agrees with spec | agrees with spec | agrees with spec |
| getPayloadV6 pre-Amsterdam payload rejected; unknown ID stays unknown | agrees with spec (gating) | agrees with spec | not checked |
| PayloadAttributesV4: `targetGasLimit` required, else -38003 | differs (see geth-1) | agrees with spec | agrees with spec |
| PayloadAttributesV4: `slotNumber` required and passed to builder/header; zero distinct from absent | agrees with spec | agrees with spec | agrees with spec (any uint64 slot incl. zero) |
| forkchoiceUpdatedV4 attribute errors vs fork-mismatch errors | agrees with spec | agrees with spec | not checked beyond attribute validation |
| FCU V4 `custodyColumns` third parameter (null / exactly 16 bytes), update independent of FCU result | agrees with spec (dispatch error not propagated to FCU; sampling timing untested) | agrees with spec (tracker updated before forkchoice, failures caught; sampler scheduling not audited) | agrees with spec (wrong-length bitmap boundary) |
| EIP-7928 BAL final-index (withdrawals + request calls) zero-net balance/storage netting | differs (see geth-2) | agrees with spec (agrees with EELS) | not checked |
| EIP-7997 factory: no fork-boundary state mutation, no existence check, no incidental BAL read | agrees with spec (no factory operation in pre/post-processing; PR #35458 removed old transition) | agrees with spec (no factory hook; no Eip7997 implementation found) | not checked (no matching factory or state-transition implementation path found in the pinned tree; not verifiable as an implemented surface) |

Fee arithmetic, drain caps and record endianness of EIP-8282 are enforced by deployed bytecode and not audited by the Nethermind item. The same limit applies to the other clients. The EIPs other than 7843, 7928, 7997 and 8282 (for example 2780, 7708, 7778, 7954, 7976, 7981, 8024, 8037, 8038, 8246) were not checked for any client in this group.

## 5. Evidence supporting the "agrees" cells and rejected hypotheses

### Geth evidence (item-geth, "Rules checked and found correct")
- Addresses and types 03/04: `geth:params/protocol_params.go#L265-L269`, `geth:core/state_processor.go#L457-L466`; spec `eels:src/ethereum/forks/amsterdam/fork.py#L121-L126`.
- System call, gas budget and error propagation: `geth:core/state_processor.go#L360-L373`, `#L469-L510`, `#L220-L227`; spec `eels:src/ethereum/forks/amsterdam/fork.py#L689-L719`. A direct EVM call does not debit the block gas pool.
- Request ordering, omission and hash: `geth:core/state_processor.go#L194-L229`; `geth:eth/catalyst/api.go#L1387-L1400` (rejects type-only, duplicate, descending); `geth:core/types/block.go#L479-L491` (hashes entries longer than one byte); `geth:core/block_validator.go#L172-L179`; spec `eels:src/ethereum/forks/amsterdam/fork.py#L870-L921`, `eels:src/ethereum/forks/amsterdam/requests.py#L307-L326`. EELS' hash helper has no local nonempty filter and relies on its producer's invariant; not a finding.
- V5 fields, raw BAL: `geth:eth/catalyst/api.go#L837-L895`, `geth:beacon/engine/types.go#L340-L379`, `#L271-L288`, `#L393-L401`, `geth:eth/catalyst/api.go#L923-L958`; spec `api:src/engine/amsterdam.md#L100-L126`.
- getPayloadV6: `geth:eth/catalyst/api.go#L498-L543`, `geth:beacon/engine/types.go#L422-L465`, `#L138-L145`; spec `api:src/engine/amsterdam.md#L128-L152`.
- Fork gating: `geth:eth/catalyst/api.go#L203-L218`, `#L1228-L1238`, `geth:beacon/engine/errors.go#L77-L84` (-38005); spec `api:src/engine/amsterdam.md#L276-L284`.
- Slot to header: `geth:beacon/engine/pa_codec.go#L39-L77`, `geth:miner/worker.go#L340-L345`, `geth:consensus/beacon/consensus.go#L272-L287`; spec `eels:src/ethereum/forks/amsterdam/blocks.py#L241-L271`.
- custodyColumns: `geth:eth/catalyst/api.go#L223-L243`, `geth:core/types/custody_bitmap.go#L28-L46` (requires 16 bytes), `geth:eth/fetcher/blob_fetcher.go#L303-L311`; spec `api:src/engine/amsterdam.md#L207-L242`. Geth does not share Erigon's missing-parameter issue (erigontech/erigon #22896, closed).
- Factory: `geth:core/state_processor.go#L167-L185`, `#L194-L229` contain no factory operation; `geth:params/protocol_params.go#L271-L273`, `geth:core/genesis.go#L687-L697`; spec `eels:src/ethereum/forks/amsterdam/fork.py#L165-L185`. go-ethereum PR #35458 (closed/merged) removed the old transition. Ordinary transactions touching the factory still produce ordinary BAL entries.

### Nethermind evidence (item-nethermind)
Paths below are under `neth:src/Nethermind/`.
- Constants/types: `Nethermind.Core/Eip8282Constants.cs#L18-L22`; `Nethermind.Core/ExecutionRequest/ExecutionRequest.cs#L9-L16`; spec `eels:src/ethereum/forks/amsterdam/fork.py#L116-L126`.
- Order and calls: `Nethermind.Consensus/Processing/BlockProcessor.cs#L295-L302`; `Nethermind.Consensus/ExecutionRequests/ExecutionRequestsProcessor.cs#L151-L187`, `#L68-L86` (SystemUser, empty data), `#L299-L311` (HasCode check, failed call throws InvalidBlockException), `#L313-L321`, `#L184-L186`; spec `eels:…/fork.py#L870-L921`, `#L748-L769`, `#L689-L719`.
- Gas: `Nethermind.Core/Eip8037Constants.cs#L19-L22`; `Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs#L54-L77`; `Nethermind.Evm/TransactionProcessing/SystemTransactionProcessor.cs#L77-L134`; spec `eels:…/fork.py#L750-L766`. The apparent excess over 30M is the EIP-8037 state allowance; subtracting the reservoir leaves exactly 30M. The shared two-dimensional gas implementation was not exhaustively audited.
- Requests hash: `Nethermind.Core/ExecutionRequest/ExecutionRequestExtensions.cs#L33-L49`; `Nethermind.Consensus/Validators/BlockValidator.cs#L264-L269`; spec `eels:src/ethereum/forks/amsterdam/requests.py#L307-L326`, `fork.py#L330-L355`, `#L899-L921`.
- newPayloadV5: `Nethermind.Merge.Plugin/EngineRpcModule.Amsterdam.cs#L25-L29`; `Nethermind.Merge.Plugin/Data/IExecutionPayloadParams.cs#L48-L79`, `#L259-L275`, `#L157-L179`; `Nethermind.Merge.Plugin/EngineRpcModule.Paris.cs#L119-L125` (-32602), `#L101-L112`; spec `api:src/engine/amsterdam.md#L45-L67`, `#L100-L129`.
- BAL hash: `Nethermind.Serialization.Rlp/Eip7928/BlockAccessListDecoder.cs#L26-L50`; `Nethermind.Merge.Plugin/Data/ExecutionPayloadV4.cs#L36-L59`, `#L146-L154`; spec `eips:EIPS/eip-7928.md` header commitment, `eels:src/ethereum/forks/amsterdam/blocks.py#L251-L266`.
- getPayloadV6: `Nethermind.Merge.Plugin/Handlers/GetPayloadV6Handler.cs#L18-L27`; `Nethermind.Merge.Plugin/Data/GetPayloadV6Result.cs#L9-L13`; `Nethermind.Merge.Plugin/Handlers/GetPayloadHandlerBase.cs#L29-L54`; spec `api:src/engine/amsterdam.md#L130-L156`.
- Attributes and FCU: `Nethermind.Consensus/Producers/PayloadAttributes.cs#L224-L333`; `Nethermind.Consensus/Producers/BlockProducerBase.cs#L209-L224`; `Nethermind.Merge.Plugin/Handlers/ForkchoiceUpdatedHandler.cs#L373-L383`; spec `api:src/engine/amsterdam.md#L74-L83`, `#L203-L228`.
- custodyColumns: `Nethermind.Merge.Plugin/IEngineRpcModule.Amsterdam.cs#L39-L42`; `Nethermind.Merge.Plugin/EngineRpcModule.Amsterdam.cs#L39-L42`; `Nethermind.Merge.Plugin/EngineRpcModule.cs#L207-L222`; spec `api:src/engine/amsterdam.md#L207-L242`.
- EIP-7997: `Nethermind.Consensus/Processing/BlockProcessor.cs#L227-L237`; `Nethermind.Consensus/Processing/BlockAccessListManager.SystemContracts.cs#L24-L64`; `Nethermind.Specs/Forks/25_Amsterdam.cs#L9-L32`.
- Nethermind PR #12714 (install factory on activation) is **closed**, its hook is absent at the pin; devnet-8 tracker #3167 strikes out the proposal.

Rejected hypotheses recorded by the Nethermind item (as disproof attempts, not candidates): raw-BAL re-encoding hash bug; system-call gas over 30M; successor-fork (Bogota/BPO) gating differences ("supports a successor fork" alone is not an Amsterdam bug); omitted `custodyColumns` argument; factory transition hook from a superseded proposal.

### Besu evidence (item-besu)
Paths under `besu:` are given as in the item (directory prefixes only where the item gave them).
- `ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java#L31-L37`; `MainnetRequestsProcessor.java#L27-L49` (also `#L31-L49`); `SystemCallRequestProcessor.java#L49-L60`; `SystemCallProcessor.java#L69-L106`, `#L45-L57`, `#L210-L254` (no-code and non-success rejected; 30M and state-gas reservoir).
- `RequestProcessorCoordinator.java#L39-L49` (sorted map); `ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java#L62-L75` (canonicalization filters empty data), `#L52-L60` (hash construction).
- `EngineNewPayloadV5.java#L61-L73`, `#L75-L93`, `#L108-L138`; `EngineGetPayloadV6.java#L44-L67`; `EngineForkchoiceUpdatedV4.java#L87-L119`, `#L122-L143`, `#L151-L183`.
- Spec anchors the item used: `eels:src/ethereum/forks/amsterdam/requests.py#L93-L105`, `#L307-L326`; `eels:src/ethereum/forks/amsterdam/fork.py#L103-L125`, `#L699-L721`, `#L855-L921`; `eels:src/ethereum/forks/amsterdam/blocks.py#L241-L268`; `api:src/engine/amsterdam.md#L100-L127`, `#L49-L91`, `#L128-L152`, `#L203-L242`.
- Besu's item also cross-checked Geth's `geth:eth/catalyst/api.go#L221-L243` and `#L865-L887`; it found them in agreement on the Engine API edge cases (it did not note the missing-`targetGasLimit` check in Geth, which the Geth item reports as geth-1; see disagreement below).
- Besu disproof attempts: empty request output, absent code, failed system call, missing vs malformed BAL, zero-valued/any uint64 slot, wrong-length custody bitmap, and EIP-7997 factory address/transition (none found in the Besu tree).

### Disagreement between items
- Besu's item states Geth's FCU V4 handling "agrees" on the Engine API edge cases; the Geth item found Geth does not enforce `targetGasLimit` presence (geth-1). Both are recorded as reported; Besu's cross-check listed slot number, fork gating and custody update, not `targetGasLimit`, so the two statements are not directly contradictory.
- Hive availability: Geth and Nethermind items got HTTP 403 from the Hive listing and web retrieval also failed; the Besu item reports reading it (see section 6). Not reconciled by the merger.

## 6. Known-check summary

| Candidate | Known? | Public records |
|---|---|---|
| geth-1 (missing `targetGasLimit`) | **known** | go-ethereum PR #35514 (closed/merged, made field optional for devnet 8); PR #35353 (closed/unmerged, proposed requiring it). No other omission report found. |
| geth-2 (final-index BAL netting) | **known** | go-ethereum #35776 (open, storage); #35894 (closed, balances, limits reachability); PR #35843 (open/unmerged, proposed fix); PR #35806 (closed, reordered withdrawals); EELS tracker #3217 (open) lists netting coverage (#3566). `geth:tests/block_test.go#L90-L96` skips both fixtures. |
| Nethermind | no candidate; nothing to label | Context only: NethermindEth/nethermind PR #12478 (closed, EIP-8282 predeploy addresses; current constants match), PR #12714 (closed, factory on activation; not adopted), #15223 (open, parallel BAL mismatch) and PR #15249 (open, retry sequentially) — related Amsterdam regression publicly tracked, not reproduced and not repackaged as a finding. |
| Besu | no candidate; none marked "known" | Context only: besu-eth/besu PR #10743 (closed, EIP-8282), PR #10929 (closed, builder predeploy addresses), issue #11726 (open, Amsterdam network support). |

Search coverage:
- Geth: `repo:ethereum/go-ethereum` for `8282`, `"builder requests"`, `7843`, `SLOTNUM`, `7928`, `"block access list"`, `7997`, `"deterministic factory"`, `"targetGasLimit"`, `"forkchoiceUpdatedV4"`, issues and PRs in both states. Follow-up searches (`"Unsupported fork" "Amsterdam"`; execution-specs `"Test Release Tracker"`) hit HTTP 403 rate limits.
- Nethermind: `8282` (38 hits), `"builder requests"` (15), `"builder deposit"` (17), `"builder exit"` (12), `7997` (4), `"factory"` (541 hits; first 100 only). **Not completed (HTTP 403 rate limit):** `7843`, `7928`, `"newPayloadV5"`, `"getPayloadV6"`, `"forkchoiceUpdatedV4"`, `"custodyColumns"`, and execution-specs `"Test Release Tracker"`. These are incomplete, not "not found".
- Besu: `EIP-8282`, `EIP-7997`, `newPayloadV5`, `forkchoiceUpdatedV4`, `Amsterdam`, open and closed issues and PRs.
- Search is not a guarantee of complete indexing.

Public test evidence:
- EELS Test Release Tracker #3147 (closed; devnet 7.2.0; EIP-8282 contract/address changes and malformed/missing BAL coverage); #3167 (closed; devnet 8.0.0; withdraws the factory activation/BAL proposal; factory-absent-at-fork test); #3217 (open; tests@v21.0.0; builder dequeue/BAL/gas-exhaustion/transition work and factory boundary cases; final all-client consume-engine sweep unchecked in the observed body; Nethermind item did not extract checkbox state reliably); #3295 (closed; devnet-8.1.0 repricing/coverage follow-up). Besu item also lists closed Glamsterdam trackers #3311, #3452, #3479, #3518. None of these certifies a client build at its pin.
- ethpandaops/benchmarkoor PR #353 (closed/merged), via the Geth item: reports replay rejection without builder predeploys and some stateful BAL disagreements; missing-code rejection is now required by EIP-8282; its generic BAL failures cannot be attributed to geth-2 without per-test evidence.
- execution-specs release v21.0.2 (Nethermind item): advertises Amsterdam invalid-transaction BAL fixture updates; release context only.
- **Hive** (`https://hive.ethpandaops.io/glamsterdam/listing.jsonl`): Geth and Nethermind items got **HTTP 403** (web retrieval also failed), so no per-test results or pass counts, and no pass/fail claim is made for those clients. The Besu item reports reading the listing: `consume-enginex` 83,189/83,258 passing (69 failing), `consume-engine` 44,216/44,225 passing (9 failing), `execute` 173/173 passing for the listed develop builds. These aggregates identify no failure for a reviewed rule and are not proof of conformance; they are Besu-item observations that the other items could not reproduce.

## 7. Limits

- Static source review only; nothing was built or executed. Comparison of runtime bytes (Geth item) was in memory only.
- Erigon and Reth, and all consensus clients, are outside this group.
- Mainnet gate: all reviewed behavior is Amsterdam-specific and not active on mainnet; no live-code candidate was reported, so no "affects live code, details withheld" entries exist.
- Dropped from this merge, as the brief directs: URL ledgers and link-reference lists of the individual items. Geth's inline GitHub-search query template was kept only as the query list in section 6.
