# Geth vs spec: EIP-7843 SLOTNUM, EIP-7954 code size, EIP-8024 DUPN/SWAPN/EXCHANGE (Amsterdam)

Item `geth`, batch `el-evm`. This was a public-page code reading only. Nothing was run against any network or node.

## 0. Method and limits (read first)

- **The shell was unavailable.** Every Bash command failed with `apply-seccomp: write /proc/self/setgroups ... Permission denied`, so I could not shallow-clone or run `grep -n`.
- **How the code was read.** All code came from `raw.githubusercontent.com` at the pinned hashes, and pins came from `api.github.com`, through a fetch tool. That tool hands the page to a helper model and returns its answer: the quoted code text plus its line numbers.
- **Line numbers may be off by one or two.** I re-asked for some locations, and twice the numbers came back slightly different:
  - `opDupN`: L1009, then L1008 on re-check.
  - The init-code check in `state_transition.go`: L676–678, then L678–680 on re-check (where I asked for that exact range verbatim).
  - In that case I cite the verbatim range read.
  - So every Geth, EELS and Nethermind `#L` below is accurate to about ±2 lines. Quoted code text is as returned.
- **Hive per-test results could not be read.** The per-test JSON was over 10 MB, the fetch limit.

## 1. Pins

| Repo | Branch | Commit (pinned via api.github.com/repos/…/commits/…) | Committer date | Head message |
|---|---|---|---|---|
| ethereum/go-ethereum | master | `8817f99f92852f8ac53e596de6202dd9e3494065` | 2026-10-27T03:32:47Z | "eth/protocols/eth: fix minimal gas after amsterdam (#36020)" |
| ethereum/execution-specs | forks/bogota (default) | `7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b` | 2026-10-27T17:40:55Z | "chore(spec-specs,tests): revert #3920 (heze-devnet-3 on bogota) (#3921)" |
| NethermindEth/nethermind | master | `d48833af88ec4224c86afadd1c596e8f619c406b` | 2026-10-27T12:00:20Z | "perf(ci): apply review feedback on migrated CI scripts (#15246)" |

Abbreviations: G = `https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/`, S = `https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/`, N = `https://raw.githubusercontent.com/NethermindEth/nethermind/d48833af88ec4224c86afadd1c596e8f619c406b/src/Nethermind/`.

EIP status on eips.ethereum.org on 2026-10-27: EIP-7843, EIP-7954 and EIP-8024 are all **Last Call**, with a deadline of 2026-11-01. None of them is live on mainnet, so the "details withheld" rule does not apply to anything here.

**The brief's opcode description differs from the current EIP-8024 text.** The brief lists "SWAPN 0xE6, DUPN 0xE7" with decoding "n+1; n+1; nibble+1". The current EIP-8024 (https://raw.githubusercontent.com/ethereum/EIPS/master/EIPS/eip-8024.md) has:

- `DUPN` = `0xe6`, `SWAPN` = `0xe7`, `EXCHANGE` = `0xe8`.
- Decoding through `decode_single`: `return (x + 145) % 256`, with immediates in `90 < x < 128` invalid.
- Decoding through `decode_pair`: `k = x ^ 143`, `q, r = divmod(k, 16)`, `if q < r: return q + 1, r + 1 else: return r + 1, 29 - q`, with immediates in `81 < x < 128` invalid.
- "JUMPDEST analysis unchanged" (immediates are *not* treated as data).

I checked Geth against the current EIP and EELS, not against the brief's older description. If Geth had followed the brief's description, it would have been wrong.

## 2. Candidates

**None.** I found no place where Geth's gas, state, block validity or encoding would differ from EELS or the EIP text for these three EIPs. Section 3 lists each rule checked. Section 4 lists the possible divergences I tried and ruled out. Per the brief I preferred no candidate to a weak one.

## 3. Rules checked and found correct

| # | Rule (spec source) | Geth at pin | EELS at pin | Nethermind at pin | Verdict |
|---|---|---|---|---|---|
| 1 | SLOTNUM is opcode `0x4b` (EIP-7843: "A new opcode `SLOTNUM` is introduced at `0x4b`") | G`core/vm/opcodes.go#L108` `SLOTNUM OpCode = 0x4b` | — | — | agrees |
| 2 | SLOTNUM gas 2 ("fixed fee of `2`") | G`core/vm/eips.go#L579-L586` `enable7843`: `constantGas: GasQuickStep`, `minStack(0, 1)`, `maxStack(0, 1)` | S`vm/gas.py#L221` `OPCODE_SLOTNUM ... = BASE`; S`vm/instructions/block.py#L264-L294` `charge_gas(evm, GasCosts.OPCODE_SLOTNUM)` | N`Nethermind.Evm/Instructions/EvmInstructions.Environment.cs#L961-L977` `UpdateGas<BaseGasCost>` | agrees (GasQuickStep = BASE = 2) |
| 3 | SLOTNUM pushes the header slot number as uint64 | G`core/vm/eips.go#L572-L576` `scope.Stack.get().SetUint64(evm.Context.SlotNum)`; G`core/evm.go#L66-L68,#L82` sets `SlotNum` from `*header.SlotNumber`; G`core/vm/evm.go#L69` `SlotNum uint64` | S`vm/instructions/block.py#L291` `push(evm.stack, U256(evm.block_env.slot_number))`; S`fork.py#L316` `slot_number=block.header.slot_number` | `stack.PushUInt64(slotNumber.Value)` (L974) | agrees |
| 4 | SLOTNUM overflow at 1024 | default dispatch checks `sp > operation.maxStack` before execute (G`core/vm/interpreter_gen.go`, `default:` case, about L818-L845) | `push` raises `StackOverflowError` if `len(stack) == 1024` (S`vm/stack.py#L128-L129`) | — | agrees |
| 5 | SLOTNUM, DUPN, SWAPN, EXCHANGE invalid before Amsterdam | Only `newAmsterdamInstructionSet` calls `enable7843`/`enable8024` (G`core/vm/jump_table.go#L106-L112`). `newOsakaInstructionSet` (L114-L118) adds only CLZ. The Amsterdam table is chosen by `case evm.chainRules.IsAmsterdam:` (G`core/vm/evm.go#L162`) | opcodes exist only in the amsterdam fork tree | `IsEip7843Enabled`, `IsEip8024Enabled` set in N`Nethermind.Specs/Forks/25_Amsterdam.cs#L19,#L23` | agrees |
| 6 | Header `slot_number: U64` is the last header field | G`core/types/block.go#L102-L106`: `BlockAccessListHash *common.Hash ... rlp:"optional"`, then `SlotNumber *uint64 ... rlp:"optional"` | S`blocks.py#L251` `block_access_list_hash: Hash32`, S`blocks.py#L263` `slot_number: U64` | — | agrees (same order, uint64 RLP) |
| 7 | Header field present iff Amsterdam | G`consensus/beacon/consensus.go#L271-L287`: `if header.SlotNumber == nil { return errors.New("header is missing slotNumber") }` / pre-fork `if header.SlotNumber != nil { return fmt.Errorf("invalid slotNumber: ...") }` | Amsterdam `Header` always has the field | N`Nethermind.Consensus/Validators/HeaderValidator.cs#L479-L495` `ValidateSlotNumber` (presence only) | agrees |
| 8 | Slot value: EL does not validate it against anything | Geth checks presence only (row 7). Value comes from the engine payload: G`beacon/engine/types.go#L374` `SlotNumber: data.SlotNumber,` | S`fork.py`: per the fetch, `validate_header` has no `slot_number` check | presence only | agrees (no EL-side value rule in the EIP or EELS) |
| 9 | Engine API V4/V5 field gating (EIP-7843: `PayloadAttributesV4`, `engine_newPayloadV5`, `engine_forkchoiceUpdatedV4`) | G`eth/catalyst/api.go`: about L219 `ForkchoiceUpdatedV4` `case params.SlotNumber == nil:` → "missing slot number"; about L838-L839 `NewPayloadV4` rejects `SlotNumber != nil`; about L867-L868 `NewPayloadV5` rejects `SlotNumber == nil`; about L387 `SlotNum: payloadAttributes.SlotNumber` | — | — | agrees |
| 10 | Built block uses the attribute's slot | G`miner/worker.go#L340-L343`: `if genParams.slotNum == nil { return nil, errors.New("no slot number set post-amsterdam") }` … `header.SlotNumber = genParams.slotNum` | — | — | agrees |
| 11 | First Amsterdam block's slot value | No rule in EIP-7843 or EELS beyond "the corresponding slot number for this block". Geth takes it from the CL (rows 8–10) | — | — | nothing to diverge from |
| 12 | MAX_CODE_SIZE 0x10000, MAX_INIT_CODE_SIZE 0x20000 (EIP-7954: "to 64KiB (`0x10000` bytes)", "to 128KiB (`0x20000` bytes)") | G`params/protocol_params.go#L161-L164`: `MaxCodeSizeAmsterdam = 65536`, `MaxInitCodeSizeAmsterdam = 2 * MaxCodeSizeAmsterdam` | S`vm/interpreter.py#L80-L81` `MAX_CODE_SIZE = 0x10000`, `MAX_INIT_CODE_SIZE = 2 * MAX_CODE_SIZE` | N`Nethermind.Core/CodeSizeConstants.cs#L9` `MaxCodeSizeEip7954 = 65_536`; `25_Amsterdam.cs#L22` | agrees |
| 13 | Exactly-at-limit size is allowed (`>` comparison) | G`core/vm/common.go#L28-L54`: `if size > params.MaxInitCodeSizeAmsterdam` / `if size > params.MaxCodeSizeAmsterdam`, gated on `rules.IsAmsterdam` first | S`vm/interpreter.py#L367` `if len(contract_code) > MAX_CODE_SIZE:` | — | agrees |
| 14 | Code-deposit order: 0xEF prefix check, then size check, then keccak word gas, then state gas | G`core/vm/evm.go#L651-L701` `initNewContract`: `ret[0] == 0xEF && IsLondon` → `ErrInvalidCode`; Amsterdam branch: `CheckMaxCodeSize`, then `toWordSize(len)*Keccak256WordGas`, then `len*CostPerStateByte` via `chargeState` | S`vm/interpreter.py#L363-L379`: `if contract_code[0] == 0xEF: raise InvalidContractPrefix`; `if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError`; `charge_gas(evm, code_hash_gas)`; `charge_state_gas(...)` | — | agrees; both errors are exceptional halts (G`core/vm/gascosts.go#L249-L264` `Exit`: any error other than `ErrExecutionReverted` → `ExitHalt`) |
| 15 | CREATE/CREATE2 init-code limit and word gas in Amsterdam | G`core/vm/gas_table.go` about L541-L564 `gasCreateEip8037` (`CheckMaxInitCodeSize`, `InitCodeWordGas * words`) and about L566-L592 `gasCreate2Eip8037` (`(InitCodeWordGas + Keccak256WordGas) * words`); wired in G`core/vm/eips.go#L590-L594` | S`vm/gas.py#L89` `CODE_INIT_PER_WORD = 2`; S`vm/gas.py` about L864-L883 `init_code_cost` | — | agrees (Amsterdam limit used through `rules.IsAmsterdam`) |
| 16 | Top-level create: init code over the limit makes the transaction invalid; word gas in intrinsic gas | G`core/state_transition.go#L678-L683` `if msg.To == nil { if err := vm.CheckMaxInitCodeSize(&rules, uint64(len(msg.Data))); ...` (unconditional within `preCheck`); intrinsic gas about L114-L119 `if isContractCreation && rules.IsShanghai { ... gas += lenWords * params.InitCodeWordGas` | per-word cost unchanged by EIP-7954 | — | agrees |
| 17 | Transaction pool uses the same helper (not consensus) | G`core/txpool/validation.go#L87-L89` `vm.CheckMaxInitCodeSize(&rules, uint64(len(tx.Data())))` | — | — | consistent |
| 18 | EIP-7702 delegation path | EIP-7954 has no delegation-specific rule. The 23-byte designator is not code deposit, and delegated code is not size-checked at call time in either Geth or EELS | — | — | nothing to diverge from |
| 19 | Opcodes `DUPN 0xe6`, `SWAPN 0xe7`, `EXCHANGE 0xe8` | G`core/vm/opcodes.go#L232-L234` | EIP-8024 | — | agrees with current EIP |
| 20 | Gas 3 each (EIP-8024: "Charge 3 gas.") | G`core/vm/eips.go#L339-L359` `constantGas: GasFastestStep` for all three | S`vm/gas.py#L227-L229` `= VERY_LOW` | N`EvmInstructions.Stack.cs#L1057,#L1074,#L1091` `VeryLowGasCost` | agrees |
| 21 | Immediate past end of code reads as 0 (EIP: "`code[pc + 1]` evaluates to `0` if beyond the end of the code") | G`core/vm/instructions.go` about L1009-L1017 (and the same in SwapN and Exchange): `var x byte; if i < uint64(len(code)) { x = code[i] }` | S`vm/instructions/stack.py#L232-L234` `buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0]` | N`EvmInstructions.Stack.cs#L1106-L1109` `programCounter < codeLength ? ... : (byte)0` | agrees (x=0 is valid: DUPN n=145, EXCHANGE: `0^143=143` → q=8, r=15, q<r → (n,m)=(9,16)) |
| 22 | Invalid ranges `90<x<128` (single) and `81<x<128` (pair) | G`instructions.go` about L1020 `if x > 90 && x < 128`, about L1048 (same, SwapN), about L1079 `if x > 81 && x < 128` | S`vm/stack.py#L47,#L79` | N`EvmInstructions.Stack.cs#L1100,#L1104` `(uint)(imm - 0x5B) > 0x24`, `(uint)(imm - 0x52) > 0x2D` | agrees (0x5B..0x7F = 91..127; 0x52..0x7F = 82..127) |
| 23 | `decode_single` = `(x+145)%256` | G`instructions.go` about L978-L986 `return (int(x) + 145) % 256` | S`vm/stack.py#L53` | N L1124 `(imm + 145) & 0xFF` | agrees |
| 24 | `decode_pair` | G`instructions.go` about L988-L1007: `k := int(x ^ 143)`; `q, r := k/16, k%16`; `if q < r { return q + 1, r + 1 }`; `return r + 1, 29 - q` | S`vm/stack.py#L86-L91` | N L1147-L1157 (returns 1-based positions, i.e. spec n+1, m+1) | agrees |
| 25 | DUPN: underflow if `n > len(stack)`; push `stack[top-n+1]` | G about L1027-L1032 `if scope.Stack.len() < n {...}`; `scope.Stack.push(scope.Stack.back(n - 1))` | S`vm/instructions/stack.py#L236-L239` | `stack.Dup(depth)` L1061 | agrees |
| 26 | DUPN overflow at 1024 | `maxStack: maxStack(0, 1)` (G`eips.go#L345`), enforced by `sp > operation.maxStack` before execute | `push` overflow (S`vm/stack.py#L128-L129`) | — | agrees |
| 27 | SWAPN: underflow if `n+1 > len(stack)`; swap `top` with `top-n` | G about L1055-L1062 `if scope.Stack.len() < n+1`; `top := scope.Stack.peek(); nth := scope.Stack.back(n)` swap | S`vm/instructions/stack.py#L269-L275` | `stack.Swap(depth + 1)` L1078 | agrees |
| 28 | EXCHANGE: underflow if `m+1 > len(stack)`; swap `top-n` with `top-m` | G about L1083-L1095 `need := max(n, m) + 1`; `back(n)` with `back(m)` | S`vm/instructions/stack.py#L303-L311` `depth = max(n, m) + U8(1)` | `stack.Exchange(n, m)` L1095 | agrees (m > n always, so max = m) |
| 29 | pc += 2 | handlers do `*pc += 1` and the dispatch loop does `pc++` (G`interpreter_gen.go` default case) | S `evm.pc += Uint(2)` | L1129, L1162 `programCounter++` plus the loop increment | agrees |
| 30 | JUMPDEST analysis unchanged (EIP: "JUMPDEST analysis: Unchanged"; a 0x5b immediate stays a valid jump target) | G`core/vm/analysis_legacy.go#L75-L118` `codeBitmapInternal` skips only PUSH1..PUSH32 data; 0xe6–0xe8 are not mentioned in the file | EELS: unchanged | — | agrees (immediate is **not** treated as data, which matches the current EIP, not the brief's wording) |
| 31 | The fast-path interpreter does not special-case the new opcodes | G`core/vm/interpreter_gen.go` (generated, "DO NOT EDIT"): no case for 0x4b/0xe6/0xe7/0xe8, which fall to `default:` → `table[op]` with minStack/maxStack/constantGas checks | — | — | consistent with the jump-table path |

## 4. Divergences considered and disproved

1. **Error ordering when several faults coincide.** Example: DUPN with a full stack of 1024 *and* an invalid immediate. Geth reports `ErrStackOverflow`, because the dispatch checks maxStack first. EELS charges gas, then raises `InvalidParameter`. With 1 stack item and an invalid SWAPN/EXCHANGE immediate, Geth reports underflow (minStack 2) and EELS reports `InvalidParameter`.
   - Both are exceptional halts. Geth's `Exit` (G`core/vm/gascosts.go#L249-L264`) maps every error except `ErrExecutionReverted` to `ExitHalt`, so gas, state and receipt status are identical.
   - Only the trace error string differs. That is cosmetic and below the bar for a candidate.
   - Out-of-gas versus stack faults likewise lead to the same halt.
2. **Code over the limit versus EIP-8037 state gas.** Geth checks size *before* charging gas (G`core/vm/evm.go#L672-L677`). EELS also checks size (L367) before `charge_gas`/`charge_state_gas` (L375, L379). Same order, so the state-gas/reservoir accounting is the same.
3. **Init-code check at fork transition.** `CheckMaxInitCodeSize` and `CheckMaxCodeSize` test `IsAmsterdam` before `IsShanghai`/`IsEIP158` and take `&evm.chainRules` (block rules), so the limit changes exactly at the first Amsterdam block. No off-by-one found.
4. **Optional-field RLP.** `SlotNumber` is the last `rlp:"optional"` field, after `BlockAccessListHash`. Both are mandatory in Amsterdam (consensus.go L273-L279), so no Amsterdam header can omit `BlockAccessListHash` while carrying `SlotNumber`. Encoding equals the EELS dataclass order.
5. **Pre-Amsterdam payload carrying `slotNumber`.** This is rejected in `NewPayloadV4` (`invalidStatus, paramsErr("slotNumber not supported pre-amsterdam")`) and again by `verifyHeader` L284-L286. Open PR #35502 changes this to a -32602 error code: that is an Engine API error-code detail, not block validity.
6. **Nethermind SLOTNUM.** It returns `BadInstruction` if `Header.SlotNumber` is null (N`EvmInstructions.Environment.cs#L970`). This is unreachable on valid Amsterdam blocks because its header validator requires the field. Not a Geth issue.

## 5. Known-check

Every result below came from the GitHub search API (`api.github.com/search/issues`, which covers both issues and pull requests, open and closed).

| Query (repo:ethereum/go-ethereum) | Hits | Relevant hits (state) |
|---|---|---|
| `8024` | 12 | #33095 implement EIP-8024 (closed PR); #33361 fix PC increment for EIP-8024 opcodes (closed PR); #33614 missing immediate treated as 0x00 (closed PR); #33869 branchless normalization, extend EXCHANGE (closed PR); #33928 enable 8024 in Amsterdam (closed PR); #34634 tighten eip-8024 min stack bounds (closed PR); #34635 include operand in invalid eip-8024 errors (closed PR); #33787, #33785 tests (closed PRs); #33661 Amsterdam Tracking (open issue) |
| `7843 OR slotnum OR slotnumber` | 33 (18 read) | #33589 implement eip-7843 SLOTNUM (closed PR); #35292 core/vm/runtime: propagate SlotNum to EVM block context (open draft PR; touches the `core/vm/runtime` harness, not block import); #35502 pre-fork field validation incl. slotNumber (open PR); #35464 genesis slot number parsing (closed PR); #34790/#34791/#34792 miner pending block slot number (closed PRs); #35469 graphql slotNumber (closed PR); #35546 RPC endpoints divergence (open issue) |
| `7954` | 4 | #33832 implement eip-7954 (closed PR); #35217 params: bump max code size as per EIP-7954 (closed PR); #33930 devnet 3 (closed PR); #31701 Fusaka planning (closed issue) |

- **Candidates against this list.** There are no candidates, so nothing is marked known. The past fixes above (#33361 PC increment, #33614 end-of-code immediate, #34634 min-stack bounds, #35217 size bump) are all reflected at the pin, as rows 21, 25–29 and 12 show.
- **execution-specs "Test Release Tracker".** 36 issues; I read #3217, "`tests@v21.0.0` (Glamsterdam Testnet)" (open). It lists EIP-8024, EIP-7843 and EIP-7954 test sections and notes the "simplification to keep JUMPDEST analysis unchanged". It reports no per-client failures.
- **Hive.** `https://hive.ethpandaops.io/glamsterdam/listing.jsonl` covered 2026-10-24 to 2026-10-26. Latest Geth runs, version `Geth/v1.17.11-unstable-d01e869d-20261026`:

  | Suite | Passes | Fails | Result file |
  |---|---|---|---|
  | eels/consume-rlp | 44159 | 2 | `1793013940-23946828090cec88b8a68ea052699e5e.json` |
  | eels/consume-engine | 44223 | 2 | `1793010480-d551c775c4d248e574860df4df37a25e.json` |
  | eels/consume-enginex | 83208 | 50 | — |
  | eels/execute | 173 | 0 | — |

  **The failing test names could not be read**: the result JSON is over the 10 MB fetch limit. So I cannot say whether those 2 or 50 failures touch these EIPs. No listing entry name mentions 8024, 7843 or 7954.

## 6. URLs read

- https://api.github.com/repos/ethereum/go-ethereum/commits/master
- https://api.github.com/repos/ethereum/execution-specs/commits/forks/bogota
- https://api.github.com/repos/NethermindEth/nethermind/commits/master
- https://eips.ethereum.org/EIPS/eip-7843
- https://eips.ethereum.org/EIPS/eip-7954
- https://eips.ethereum.org/EIPS/eip-8024
- https://raw.githubusercontent.com/ethereum/EIPS/master/EIPS/eip-8024.md
- G + `core/vm/eips.go`, `core/vm/instructions.go`, `core/vm/opcodes.go`, `core/vm/jump_table.go`, `core/vm/analysis_legacy.go`, `core/vm/interpreter_gen.go`, `core/vm/evm.go`, `core/vm/common.go`, `core/vm/gas_table.go`, `core/vm/gascosts.go`, `core/evm.go`, `core/state_transition.go`, `core/txpool/validation.go`, `core/types/block.go`, `consensus/beacon/consensus.go`, `beacon/engine/types.go`, `eth/catalyst/api.go`, `miner/worker.go`, `params/protocol_params.go`
- https://api.github.com/repos/ethereum/go-ethereum/contents/core/vm?ref=8817f99f92852f8ac53e596de6202dd9e3494065
- S + `blocks.py`, `fork.py`, `vm/instructions/block.py`, `vm/instructions/stack.py`, `vm/stack.py`, `vm/interpreter.py`, `vm/gas.py`
- N + `Nethermind.Evm/Instructions/EvmInstructions.Stack.cs`, `Nethermind.Evm/Instructions/EvmInstructions.Environment.cs`, `Nethermind.Core/Specs/IReleaseSpec.cs`, `Nethermind.Consensus/Validators/HeaderValidator.cs`, `Nethermind.Specs/Forks/25_Amsterdam.cs`, `Nethermind.Core/CodeSizeConstants.cs`, `Nethermind.Specs/ReleaseSpec.cs`
- https://api.github.com/search/issues?q=repo:ethereum/go-ethereum+8024
- https://api.github.com/search/issues?q=repo:ethereum/go-ethereum+7843+OR+slotnum+OR+slotnumber
- https://api.github.com/search/issues?q=repo:ethereum/go-ethereum+7954
- https://api.github.com/repos/ethereum/go-ethereum/pulls/35502
- https://api.github.com/repos/ethereum/go-ethereum/pulls/35292
- https://api.github.com/search/issues?q=repo:ethereum/execution-specs+%22Test+Release+Tracker%22
- https://api.github.com/repos/ethereum/execution-specs/issues/3217
- https://hive.ethpandaops.io/glamsterdam/listing.jsonl
- https://hive.ethpandaops.io/glamsterdam/results/1793010480-d551c775c4d248e574860df4df37a25e.json (not readable: over 10 MB)

**Not located:** where Nethermind derives its Amsterdam init-code limit. Its `IReleaseSpec.cs` and `ReleaseSpec.cs` do not contain `MaxInitCodeSize` per the fetch, so its 0x20000 init-code limit is unverified here.
