Skip to content

Glamsterdam devnet 6 eips#12117

Merged
LukaszRozmej merged 9 commits into
masterfrom
glamsterdam-devnet-6-eips
Jul 10, 2026
Merged

Glamsterdam devnet 6 eips#12117
LukaszRozmej merged 9 commits into
masterfrom
glamsterdam-devnet-6-eips

Conversation

@Marchhill

@Marchhill Marchhill commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Merge without squashing

Changes

Implements glamsterdam devnet-6. Constituent PRs (already reviewed and merged into this branch):

Also updates the EF fixture pins (tests-glamsterdam-devnet@v6.1.1, tests-zkevm@v0.5.0) and merges latest master + fixes.

Types of changes

What types of changes does your code introduce?

  • New feature (a non-breaking change that adds functionality)
  • Bugfix (a non-breaking change that fixes an issue)

Testing

Requires testing

  • Yes

If yes, did you write tests?

  • Yes

Notes on testing

Covered by the EF tests-glamsterdam-devnet v6.1.1 fixtures (state/blockchain/engine) and unit tests; stateless execution covered by the tests-zkevm v0.5.0 fixtures.

Documentation

Requires documentation update

  • No

Requires explanation in Release Notes

  • No

References

@github-actions github-actions Bot added the test label Jun 24, 2026
@claude

claude Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Marchhill's task in 1m 14s —— View job


Review

  • Gather context and understand the change
  • Analyze CI status
  • Post review

The change is a straightforward two-line constant update, bumping the pyspec test fixture reference from bal@v7.2.0 to glamsterdam-devnet@v6.0.0. The logic in LoadPyspecTestsStrategy.cs that consumes these constants is correct and unchanged — no issues there.


Medium — Three test CI failures on the June 22 commit

The previous CI run (triggered on June 22 before the upstream merge) shows three failures:

Workflow Result
Nethermind/Ethereum tests ❌ failure
Nethermind extra test variants ❌ failure
Nethermind tests (Flat DB) ❌ failure

These are exactly the suites that exercise pyspec/EF tests. The June 24 re-run (triggered when the PR was opened after merging upstream/master) has all three queued but not yet complete. Please confirm the current CI run passes, or add a brief note if failures are expected (e.g., incomplete EIP implementations in this devnet branch).


Low — PR description is unfilled

The PR body is the blank template. Even a one-liner ("Updates pyspec fixture constants to glamsterdam-devnet v6.0.0") would help reviewers and the changelog.


No code issues found with the change itself — the constant values follow the established naming pattern and the constructed download URL has the correct shape (https://github.com/ethereum/execution-specs/releases/download/tests-glamsterdam-devnet@v6.0.0/fixtures_glamsterdam-devnet.tar.gz).

@Marchhill
Marchhill force-pushed the glamsterdam-devnet-6-eips branch 2 times, most recently from 5ff5943 to eb7d28d Compare July 6, 2026 12:24
@github-actions github-actions Bot added evm and removed test labels Jul 6, 2026
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

EVM Opcode Benchmark Diff

Aggregated runs: base=3, pr=3
Noisy rerun opcodes: CREATE, EXTCODECOPY, EXTCODEHASH, MCOPY

Regressions (2)

Opcode Base Median (ns) PR Median (ns) Delta Abs Δ (ns) Base CV PR CV Threshold Uncertainty Effective
DIV 296.950 338.390 +13.96% 41.440 2.0% 1.8% ±5.0% ±2.8% ±5.0%
MULMOD 232.890 1049.460 +350.62% 816.570 2.3% 1.1% ±5.0% ±4.8% ±5.0%

Improvements (2)

Opcode Base Median (ns) PR Median (ns) Delta Abs Δ (ns) Base CV PR CV Threshold Uncertainty Effective
EXTCODECOPY 346.340 227.500 -34.31% 118.840 1.3% 3.4% ±5.0% ±2.5% ±6.8%
EXTCODEHASH 530.200 410.900 -22.50% 119.300 2.6% 1.4% ±5.0% ±2.5% ±5.2%

@claude

claude Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Marchhill's task in 11m 6s —— View job


PR Review — Glamsterdam devnet-6 EIPs

  • Gather context and review diff vs origin/master
  • Review EVM / gas-policy changes (EIP-8037/8038/2780)
  • Review execution requests & payload attributes (EIP-8282, targetGasLimit)
  • Review SELFDESTRUCT burn removal (EIP-8246)
  • Review spec wiring & stateless executor
  • Post review summary

Reviewed the devnet-6 EIP implementation across the EVM two-dimensional gas model (EIP-8037/8038), repricings (EIP-2780), SELFDESTRUCT burn removal (EIP-8246), builder execution requests (EIP-8282), and targetGasLimit plumbing. The constituent PRs were individually reviewed/merged and this branch is EEST-fixture-pinned (v6.1.1 / zkevm v0.5.0). Overall the change is coherent and internally consistent; findings below are concentrated in the state-gas "reservoir" accounting, which is the highest-residual-risk area.

Note: I couldn't compute a git merge-base for a precise diff on this shallow checkout, so this review is based on reading the changed files and their call sites directly.


Medium — Asymmetric clamp in RemoveStateGasRefundFromReservoir with a negative reservoir

src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs:399-409

long fromReservoir = Math.Min(amount, gas.StateReservoir);
gas.StateReservoir -= fromReservoir;
amount -= fromReservoir;
if (amount > 0) { gas.StateGasUsed -= Math.Min(amount, gas.StateGasUsed); }

amount is always positive (caller RemoveAdvancedStateGasRefund guards StateGasRefundAdvanced > 0), but gas.StateReservoir can legitimately be negative on a net-spill (set via ConsumeStateGas's Math.Min(0, reservoir) at :143, and propagated through Refund/RestoreChildStateGas). When the reservoir is negative, Math.Min(amount, negativeReservoir) returns the negative value, so:

  • gas.StateReservoir -= fromReservoir pushes the reservoir up toward 0 (spuriously reclaiming spilled state gas), and
  • amount -= fromReservoir increases the residual, over-deducting StateGasUsed by |reservoir|.

The sibling routine DiscardStateGas (:376) clamps its equivalent with Math.Max(0, …); this one does not. Both review passes independently landed on this asymmetry as the top concern.

Reachability is narrow: a sub-frame that both spilled state gas (reservoir negative) and advanced a speculative state-gas refund (CreditStateGasRefundAddStateGasRefundToReservoir), then reverts/exceptionally-halts. PopAndRestoreParentState (VirtualMachine.cs:646) → RemoveAdvancedStateGasRefund (:720-724) runs before RestoreChildStateGasOnHalt merges the child into the parent, so a corrupted StateReservoir/StateGasUsed would flow into the tx's committed block state gas — a consensus-relevant quantity feeding the 2D block-gas check (BlockAccessListManager.Validation.cs:84,89).

I could not fully confirm the intended semantics from the code alone (the reservoir model is intricate and this exact nesting may simply not arise), so treat this as plausible, needs confirmation rather than a proven break. Suggested action: add a targeted unit test for "sub-frame spills state gas + advances a refund + halts/reverts" and confirm the resulting block state gas matches the reference. If the current behavior is intentional, a one-line comment explaining why the clamp differs from DiscardStateGas would close the gap.

Fix this →


Low — SELFDESTRUCT new-account charge has no EIP-2780 branch (unlike CALL)

src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.ControlFlow.cs:244-254

The CALL path special-cases EIP-2780/8038 when deciding the dead-beneficiary NEW_ACCOUNT charge (EvmInstructions.Call.cs:174-180: spec.IsEip8038Enabled ? … : !spec.IsEip2780Enabled && (…)). The SELFDESTRUCT path computes chargesNewAccount purely from spec.ClearEmptyAccountWhenTouched with no 2780 branch. On the real glamsterdam fork EIP-8038 is co-activated (so SELFDESTRUCT takes the IsEip8038Enabled branch and the fixtures cover it), which is why this is Low — but a 2780-without-8038 spec configuration would charge a legacy NEW_ACCOUNT cost that CALL suppresses. Worth a confirming comment that the two paths are intended to diverge for that config, or aligning them.


Low — ConsumeStateGas doesn't set the OutOfGas flag on failure

src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs:137-141

On the spill path, a failed TryConsume returns false but (unlike UpdateGas/Consume) leaves gas.Value untouched and never sets gas.OutOfGas. Every current caller propagates the boolean into an explicit goto OutOfGas/SetOutOfGas, so no live path is affected, but a future caller that checks IsOutOfGas instead of the return value would mis-handle a state-gas OOG. Recommend either setting the flag defensively or documenting the return-value contract on the method.


Low — Release-mode silent underflow in CreateAvailableFromIntrinsic

src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs:550

Eip7825Constants.DefaultTxGasLimitCap - intrinsicGas.Value wraps (to a huge ulong) if intrinsic regular gas exceeds the 16 MiB cap; guarded only by a Debug.Assert plus the upstream EIP-7825 ExceedsCap inclusion check. Defense-in-depth, not a live bug — but a SaturatingSub here would match the saturating arithmetic used elsewhere in the file.


Low — Duplicated destroy-finalization blocks in TransactionProcessor

src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs:373-393 and :1381-1401

The deferred (EIP-8037+7708) and non-deferred destroy-finalization paths duplicate the DeleteAccountCreateAccount(addr, balance) delete/recreate logic under RemoveSelfdestructBurn, differing only in log type (CreateBurn vs CreateSelfDestruct). No behavioral bug (balance is 0 at finalization since the opcode subtracts first), but the duplication is a maintenance hazard — a fix to one block can silently miss the other. Consider extracting a shared helper.


Verified correct (no action)

  • EIP-8246 SELFDESTRUCT burn removal — self-target with RemoveSelfdestructBurn correctly goto Stop (no log, no SubtractFromBalance); the finalization delete+recreate preserves balance with no double-subtract/double-log (ControlFlow.cs:268-276).
  • The Fix state gas spill with negative reservoir #12338 negative-reservoir spill fix in ConsumeStateGas/CalculateStateGasSpill is internally consistent (reservoir + spill portions sum exactly to stateGasCost).
  • Eip8037BlockGasInclusionCheck.Validate early > blockGasLimit rejections and strict-> comparisons are correct.
  • EIP-8282 wiring: builder requests are dequeued after withdrawal/consolidation so the flat encoding stays in ascending type order (ExecutionRequestsProcessor.cs:103-113), MaxRequestsCount bumped to 5, builder predeploys added to IsSystemContract for BAL validation, and the stateless path correctly no-ops RecordRequests.
  • PayloadAttributes V4 targetGasLimit is included in the payload-id hash and field validation; TargetAdjustedGasLimitCalculator uses saturating arithmetic for the bound-divisor step.
  • Gas constant arithmetic (GasCostOf.cs, Eip803*Constants.cs) checks out with no long overflow for realistic inputs.

Recommendation: The Medium finding is plausible-but-unconfirmed and sits in a consensus-relevant hot path; I'd ask for either a targeted regression test proving the negative-reservoir + advanced-refund + halt path is handled, or an explicit acknowledgement that the asymmetry with DiscardStateGas is intentional, before merge. Everything else is Low.

@Marchhill

Copy link
Copy Markdown
Contributor Author

@claude will adress comments in follow up PR

@claude

claude Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Marchhill's task in 19s —— View job


Understood — noted that the review findings will be addressed in a follow-up PR.

For reference, the open items from the earlier review, in priority order:

  • Medium — Asymmetric clamp in RemoveStateGasRefundFromReservoir with a negative reservoir (EthereumGasPolicy.cs:399-409). The Math.Min(amount, gas.StateReservoir) goes wrong when StateReservoir is negative (net spill), unlike the Math.Max(0, …) clamp in the sibling DiscardStateGas. Worth a targeted regression test for "sub-frame spills state gas + advances a refund + halts/reverts" to confirm whether it reproduces.
  • Low — SELFDESTRUCT new-account charge has no EIP-2780 branch (unlike CALL) (EvmInstructions.ControlFlow.cs:244-254).
  • LowConsumeStateGas doesn't set the OutOfGas flag on failure (EthereumGasPolicy.cs:137-141).
  • Low — Release-mode silent underflow in CreateAvailableFromIntrinsic (EthereumGasPolicy.cs:550).
  • Low — Duplicated destroy-finalization blocks in TransactionProcessor (TransactionProcessor.cs:373-393 and :1381-1401).

This PR is already approved by @flcl42, so no action needed here from me — ping me on the follow-up PR if you'd like a re-review of the fixes.

@Marchhill
Marchhill force-pushed the glamsterdam-devnet-6-eips branch from ecdaffe to 2c6fd16 Compare July 9, 2026 16:49
@Marchhill
Marchhill force-pushed the glamsterdam-devnet-6-eips branch from 0c881cd to 148a794 Compare July 9, 2026 19:59
@Marchhill
Marchhill requested review from flcl42 and svlachakis July 9, 2026 20:10
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (1aae065) to head (148a794).
⚠️ Report is 9 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master   #12117       +/-   ##
===========================================
- Coverage   77.94%        0   -77.95%     
===========================================
  Files        2972        0     -2972     
  Lines      126482        0   -126482     
  Branches    19079        0    -19079     
===========================================
- Hits        98581        0    -98581     
+ Misses      24565        0    -24565     
+ Partials     3336        0     -3336     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Marchhill and others added 9 commits July 10, 2026 10:52
…VM v0.5.0

Point the default Pyspec fixture archive at tests-glamsterdam-devnet@v6.1.0
and the zkEVM stateless preview suite at tests-zkevm@v0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test: update pyspec fixtures to glamsterdam-devnet v6.0.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: ignore ZkEVM stateless suite (fixtures target bal-devnet-7)

The ZkEvmBlockchainTests stateless suite runs Nethermind.Stateless.Executor
against the pinned tests-zkevm@v0.4.1 archive, which is generated against
bal-devnet-7 (tests-bal@v7.2.0). Its EIP-7928 block-access-list semantics differ
from the devnet-6 (tests-glamsterdam-devnet@v6.0.0) rules this stack implements,
so stateless execution rejects every fixture block on a BAL mismatch
(StatelessValidationResult.IsSuccess=0) — the full Pyspec [Sequential]/engine
shards each failed only on the *_stateless_block_N cases.

Mark the suite [Ignore] until the client tracks bal-devnet-7 (or the archive is
repinned to devnet-6). No production code is affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump Glamsterdam devnet Pyspec fixtures to v6.1.0

Run the Ethereum.Blockchain.Pyspec.Test suite against the
tests-glamsterdam-devnet@v6.1.0 fixture release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: re-enable zkEVM stateless fixtures on tests-zkevm@v0.5.0

The zkVM stateless suite was disabled because the pinned archive
(tests-zkevm@v0.4.1) was generated against bal-devnet-7, whose EIP-7928
BAL semantics differ from the devnet-6 rules this stack implements.

tests-zkevm@v0.5.0 is generated against tests-glamsterdam-devnet@v6.1.0
(the devnet-6 fixtures this stack tracks), so the mismatch is resolved.
Bump the archive version and drop the [Ignore].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: update Pyspec fixtures to Glamsterdam devnet-6 (v6.1.0) and zkEVM v0.5.0

Point the default Pyspec fixture archive at tests-glamsterdam-devnet@v6.1.0
and the zkEVM stateless preview suite at tests-zkevm@v0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: implement EIP-8246 (Remove SELFDESTRUCT Burn)

Removes the residual ETH-burn cases left by EIP-6780:

- A self-targeting SELFDESTRUCT now moves no ETH and emits no log,
  regardless of whether the account was created in the same transaction.
- At transaction finalization, accounts marked for destruction keep their
  balance: storage and code are cleared and the nonce is reset to 0. A
  resulting zero-balance account is still removed as empty per EIP-161,
  matching the spec and keeping CREATE2 redeployment unblocked.

Wires a new IsEip8246Enabled flag through IReleaseSpec / ReleaseSpec /
decorators / chainspec (Eip8246TransitionTimestamp) and enables it in the
Amsterdam fork. Adds Eip8246Tests covering same-transaction self-destruct
to self/other, post-destruct funding, the zero-balance empty-account case,
and the unchanged not-in-same-tx no-op, each pinned with EIP on and off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: cover deferred finalization path; address review feedback

- Add an EIP-8037 + EIP-7708 fixture dimension so every EIP-8246 scenario
  also runs through the deferred FinalizeDestroyedAccount path (as in
  Amsterdam), covering the balance-preservation logic there.
- Add a CREATE2 redeployment test: a factory re-creates a self-destructed
  child at the same address across transactions, verifying the nonce reset
  keeps redeployment unblocked and the preserved balance accumulates.
- Report the destroy refund to the tracer in the deferred path, matching
  the inline path.
- Document the pre-existing Burn-vs-SelfDestruct log distinction between the
  post-fee and pre-fee finalization paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: do not enable EIP-8246 in Amsterdam fork

EIP-8246 is a Draft and is not part of the EEST `for_amsterdam` conformance
fixtures. Enabling it in the Amsterdam fork changed SELFDESTRUCT behaviour
for that fork, diverging from the reference post-states and failing the
Pyspec tests across all shards.

Keep the full implementation and spec/chainspec plumbing so the EIP can be
activated via the Eip8246Transition chainspec parameter once it is scheduled,
but leave it disabled in the named forks. Unit tests toggle the flag directly
via OverridableReleaseSpec, so coverage is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: assert storage clearing in EIP-8246 self-destruct tests

Address PR review comments:
- The self-destruct-to-self contract now writes storage slot 0 before
  SELFDESTRUCT so AssertBalanceOnly can verify storage is wiped on the
  surviving balance-only account.
- Clarify the self-targeting SELFDESTRUCT short-circuit comment to
  distinguish the EIP-6780 pure no-op case from the EIP-8246 burn-removal
  case (account in destroy list, finalization still clears code/storage).

Note: the deferred finalization path also gained a tracer.ReportRefund
call to match the inline path; that is an incidental tracer fix unrelated
to EIP-8246 semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: tidy EIP-8246 self-destruct test per review

- Rename the self-destruct-to-self fixtures to _sstoreThenSelfDestructToSelf
  so the name reflects the SSTORE-then-SELFDESTRUCT bytecode.
- Wrap AssertBalanceOnly in Assert.EnterMultipleScope so every mismatch is
  surfaced in one run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong DestroyRefund for tracer refund (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port EIP-8246 test BlockNumber override to ulong (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump EF fixtures to tests-glamsterdam-devnet@v6.1.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: map InvalidTxSignature to INVALID_SIGNATURE_VRS for v6.1.1 test_bad_v_r_s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: map InvalidTxChainId/EIP-155 sig failure to INVALID_CHAINID (v6.1.1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: decode invalid-tx state tests from txbytes (v6.1.1 expectException)

v6.1.1 state tests carry expectException plus the actual signed tx in txbytes.
The template tx is re-signed pre-EIP-155, which cannot reproduce signature-level
invalidity (test_invalid_chain_id executes as a valid tx and diverges from the
expected post state). Decode the fixture's raw tx for such entries so validation
rejects it; undecodable txbytes fall back to the template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables by spec instance, not on the spec object

The per-spec opcode tables were cached in IReleaseSpec.EvmInstructionsNoTrace/
Traced slots. OverridableReleaseSpec's getter fell back to the wrapped spec and
ReleaseSpecDecorator's setter wrote through to it, so wrappers with different
EVM flags (7708/8037/8246 test variants) shared one table with fork singletons —
first writer won, giving wrong opcode handlers (missing transfer logs, wrong
state-gas charges) depending on test order. Port master's fix (#12146): cache
tables in a ConcurrentDictionary keyed by spec instance (plain statics for the
single-fork zkEVM guest) and drop the IReleaseSpec slots.

Full Evm.Test suite: 10/10 clean (was ~5 of 6 runs failing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: tighten EIP-8246 comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: move the v6.1.1 pyspec fixes off the EIP-8246 branch

The fixture bump and its harness fixes (INVALID_SIGNATURE_VRS/INVALID_CHAINID
mappings, txbytes decode for expectException state tests) are unrelated to
EIP-8246; they move to fix/zkevm-stateless-v050-v2 where the fixture/format
alignment lives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: move the opcode-table cache fix to the stateless branch; group 8246 with Amsterdam EIPs

The spec-instance opcode-table keying is test-infrastructure hardening
unrelated to EIP-8246; it moves to fix/zkevm-stateless-v050-v2. IsEip8246Enabled
now sits with the other Amsterdam EIP flags in the spec surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: drop the Amsterdam EIP-8246 activation note

The flag is enabled one PR up (repricings, #12214) where the note is already gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: enable EIP-8246 in Amsterdam

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Marc Harvey-Hill <10379486+Marchhill@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* test: update pyspec fixtures to glamsterdam-devnet v6.0.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: ignore ZkEVM stateless suite (fixtures target bal-devnet-7)

The ZkEvmBlockchainTests stateless suite runs Nethermind.Stateless.Executor
against the pinned tests-zkevm@v0.4.1 archive, which is generated against
bal-devnet-7 (tests-bal@v7.2.0). Its EIP-7928 block-access-list semantics differ
from the devnet-6 (tests-glamsterdam-devnet@v6.0.0) rules this stack implements,
so stateless execution rejects every fixture block on a BAL mismatch
(StatelessValidationResult.IsSuccess=0) — the full Pyspec [Sequential]/engine
shards each failed only on the *_stateless_block_N cases.

Mark the suite [Ignore] until the client tracks bal-devnet-7 (or the archive is
repinned to devnet-6). No production code is affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump Glamsterdam devnet Pyspec fixtures to v6.1.0

Run the Ethereum.Blockchain.Pyspec.Test suite against the
tests-glamsterdam-devnet@v6.1.0 fixture release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: re-enable zkEVM stateless fixtures on tests-zkevm@v0.5.0

The zkVM stateless suite was disabled because the pinned archive
(tests-zkevm@v0.4.1) was generated against bal-devnet-7, whose EIP-7928
BAL semantics differ from the devnet-6 rules this stack implements.

tests-zkevm@v0.5.0 is generated against tests-glamsterdam-devnet@v6.1.0
(the devnet-6 fixtures this stack tracks), so the mismatch is resolved.
Bump the archive version and drop the [Ignore].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: update Pyspec fixtures to Glamsterdam devnet-6 (v6.1.0) and zkEVM v0.5.0

Point the default Pyspec fixture archive at tests-glamsterdam-devnet@v6.1.0
and the zkEVM stateless preview suite at tests-zkevm@v0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: implement EIP-8246 (Remove SELFDESTRUCT Burn)

Removes the residual ETH-burn cases left by EIP-6780:

- A self-targeting SELFDESTRUCT now moves no ETH and emits no log,
  regardless of whether the account was created in the same transaction.
- At transaction finalization, accounts marked for destruction keep their
  balance: storage and code are cleared and the nonce is reset to 0. A
  resulting zero-balance account is still removed as empty per EIP-161,
  matching the spec and keeping CREATE2 redeployment unblocked.

Wires a new IsEip8246Enabled flag through IReleaseSpec / ReleaseSpec /
decorators / chainspec (Eip8246TransitionTimestamp) and enables it in the
Amsterdam fork. Adds Eip8246Tests covering same-transaction self-destruct
to self/other, post-destruct funding, the zero-balance empty-account case,
and the unchanged not-in-same-tx no-op, each pinned with EIP on and off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: cover deferred finalization path; address review feedback

- Add an EIP-8037 + EIP-7708 fixture dimension so every EIP-8246 scenario
  also runs through the deferred FinalizeDestroyedAccount path (as in
  Amsterdam), covering the balance-preservation logic there.
- Add a CREATE2 redeployment test: a factory re-creates a self-destructed
  child at the same address across transactions, verifying the nonce reset
  keeps redeployment unblocked and the preserved balance accumulates.
- Report the destroy refund to the tracer in the deferred path, matching
  the inline path.
- Document the pre-existing Burn-vs-SelfDestruct log distinction between the
  post-fee and pre-fee finalization paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: do not enable EIP-8246 in Amsterdam fork

EIP-8246 is a Draft and is not part of the EEST `for_amsterdam` conformance
fixtures. Enabling it in the Amsterdam fork changed SELFDESTRUCT behaviour
for that fork, diverging from the reference post-states and failing the
Pyspec tests across all shards.

Keep the full implementation and spec/chainspec plumbing so the EIP can be
activated via the Eip8246Transition chainspec parameter once it is scheduled,
but leave it disabled in the named forks. Unit tests toggle the flag directly
via OverridableReleaseSpec, so coverage is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: assert storage clearing in EIP-8246 self-destruct tests

Address PR review comments:
- The self-destruct-to-self contract now writes storage slot 0 before
  SELFDESTRUCT so AssertBalanceOnly can verify storage is wiped on the
  surviving balance-only account.
- Clarify the self-targeting SELFDESTRUCT short-circuit comment to
  distinguish the EIP-6780 pure no-op case from the EIP-8246 burn-removal
  case (account in destroy list, finalization still clears code/storage).

Note: the deferred finalization path also gained a tracer.ReportRefund
call to match the inline path; that is an incidental tracer fix unrelated
to EIP-8246 semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: tidy EIP-8246 self-destruct test per review

- Rename the self-destruct-to-self fixtures to _sstoreThenSelfDestructToSelf
  so the name reflects the SSTORE-then-SELFDESTRUCT bytecode.
- Wrap AssertBalanceOnly in Assert.EnterMultipleScope so every mismatch is
  surfaced in one run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP repricings and existing-EIP updates (devnet-6)

Combined branch for the Glamsterdam devnet-6 repricing/update EIPs:
EIP-2780, EIP-8037, EIP-8038, plus existing-EIP (7702/7708/7928/7954/7981)
test and behavior updates. Folds in the EIP-8037 halt-gas-accounting fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* wip(test): begin ulong test-suite port for master #11937 (incomplete)

Partial long->ulong adaptation of the glamsterdam EIP test files to master's
type-unified gas API. Test projects do not yet build; tracked follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong DestroyRefund for tracer refund (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(8037): revert state-gas dimension to signed long

Master #11937 ("unify types with Geth") changed all gas from long to
ulong (uint64). This is correct for the regular gas dimension, but the
EIP-8037 state-gas dimension needs a *signed* reservoir: during nested
frame spill merges (RestoreChildStateGas / RestoreChildStateGasOnHalt /
RevertRefundToHalt) the StateReservoir goes transiently negative before
recovering. As ulong it underflowed to ~2^64, producing wrong spentGas
on halts (e.g. 12000 instead of 16777216) and 54 EIP-8037 spill/halt/
reservoir fixture failures.

Revert the state-gas dimension (StateReservoir, StateGasUsed,
StateGasSpill*, intrinsic/create/new-account/per-auth/code-deposit/
storage state costs, and their IGasPolicy signatures, VmState fields,
VirtualMachine refund locals, and TransactionProcessor halt/block-gas
locals) back to signed long. Regular gas Value/GetRemainingGas/
UpdateGas/Consume/TryConsume and GasConsumed stay ulong; cast at the
regular<->state boundary (all state values are non-negative there).

Fixes test_nested_failure_resets_to_tx_reservoir (was 54 failed -> 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port EIP-8246 test BlockNumber override to ulong (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump EF fixtures to tests-glamsterdam-devnet@v6.1.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: remove unnecessary using after SaturatingSub revert (IDE0005)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: map InvalidTxSignature to INVALID_SIGNATURE_VRS for v6.1.1 test_bad_v_r_s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* review fixes: assert 8037 gas invariants, restore getLogs depth test, fix stale docs

- Debug.Assert the EIP-8037 boundary invariants (state >= 0, remaining +
  reservoir <= gasLimit) at the halt/fail/collision read points and in
  RefundStateGas, replacing the saturating defense removed with the rework
- restore Eth_get_logs_enforces_max_block_depth (accidentally dropped in the
  master RPC reconciliation; the MaxBlockDepth guard is live)
- de-circularize the 7702 SpentGas expectation (constants instead of the
  production intrinsic calculator) and add an exact floor==standard tie case
  for EIP-7981
- refresh stale 4500-era totals/comments (TX_BASE is 12000), the 8038
  placeholder remark, and the 8037 inclusion-rule assertion message
- drop unused Eip8038IntrinsicRecipientGas params, redundant (ulong) casts on
  ulong constants, and the lazy BlockValidator ecdsa init

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: map InvalidTxChainId/EIP-155 sig failure to INVALID_CHAINID (v6.1.1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: decode invalid-tx state tests from txbytes (v6.1.1 expectException)

v6.1.1 state tests carry expectException plus the actual signed tx in txbytes.
The template tx is re-signed pre-EIP-155, which cannot reproduce signature-level
invalidity (test_invalid_chain_id executes as a valid tx and diverges from the
expected post state). Decode the fixture's raw tx for such entries so validation
rejects it; undecodable txbytes fall back to the template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: relax EIP-8037 debug asserts to the true signed invariants

The [checked] CI variant surfaced two over-strict asserts: the state reservoir
can legitimately end a tx negative (net child spill) with the ulong wrap still
producing the correct signed spentGas, and system calls can halt with
preRefundGas 0 while intrinsic state gas remains (their GasConsumed is
discarded). Assert the signed non-negative-spend invariant instead, and gate
the halt-path block-gas assert on non-system transactions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: drop end-of-tx gas assert that a parallel-test race trips flakily

A pre-existing Nethermind.Evm.Test parallel race (~1 in 6 full-suite runs)
intermittently violates the end-of-tx invariant from
Create2_redeploy_to_same_address_unblocked_after_self_destruct, SIGABRTing the
[checked] job. The halt/fail/collision asserts stay (validated clean across the
checked pyspec suite); a genuine wrap on this success path already fails
fixtures via receipts/state roots. Race tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables by spec instance, not on the spec object

The per-spec opcode tables were cached in IReleaseSpec.EvmInstructionsNoTrace/
Traced slots. OverridableReleaseSpec's getter fell back to the wrapped spec and
ReleaseSpecDecorator's setter wrote through to it, so wrappers with different
EVM flags (7708/8037/8246 test variants) shared one table with fork singletons —
first writer won, giving wrong opcode handlers (missing transfer logs, wrong
state-gas charges) depending on test order. Port master's fix (#12146): cache
tables in a ConcurrentDictionary keyed by spec instance (plain statics for the
single-fork zkEVM guest) and drop the IReleaseSpec slots.

Full Evm.Test suite: 10/10 clean (was ~5 of 6 runs failing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: restore the end-of-tx gas invariant assert

The parallel-test race that flakily violated it is fixed (opcode tables now
keyed by spec instance); 10/10 full checked Evm.Test runs clean with it live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: tighten EIP-8246 comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: move the v6.1.1 pyspec fixes off the EIP-8246 branch

The fixture bump and its harness fixes (INVALID_SIGNATURE_VRS/INVALID_CHAINID
mappings, txbytes decode for expectException state tests) are unrelated to
EIP-8246; they move to fix/zkevm-stateless-v050-v2 where the fixture/format
alignment lives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: move the opcode-table cache fix to the stateless branch; group 8246 with Amsterdam EIPs

The spec-instance opcode-table keying is test-infrastructure hardening
unrelated to EIP-8246; it moves to fix/zkevm-stateless-v050-v2. IsEip8246Enabled
now sits with the other Amsterdam EIP flags in the spec surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: drop the Amsterdam EIP-8246 activation note

The flag is enabled one PR up (repricings, #12214) where the note is already gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: enable EIP-8246 in Amsterdam

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reconcile glamsterdam gas policy with master's #12146 foundation

Keep devnet-6 semantics (signed state dimension, EELS block/halt gas, 2780/8038
repricings) while adopting master's structural changes: tagged-cost Consume,
policy-computed data-copy/create/SSTORE consumers (8038-aware where priced),
UpdateMemoryCost over EvmPooledMemory, parameterless state-cost getters,
TryReserveChildGas, CombineBlockGas, the system-tx-processor seam with the
parallel flag, and the popped-address cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style: expression-bodied state-cost test (IDE0022)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: aggressively inline the glamsterdam gas-policy interface defaults

Master's inlining guard test requires the attribute on every IGasPolicy
default/helper for no-dynamic-PGO regimes (NativeAOT zkEVM guest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: charge full requested gas for pre-EIP-150 child calls

The hand-ported TryReserveChildGas clamped the requested gas to the remaining
balance on the pre-63/64 branch; the spec charges the full request, so an
over-asking CALL exceptionally halts the caller (refundReset_Frontier/
Homestead and the early-fork pyspec chunks caught it). Now byte-identical to
master's implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: make EIP-2780 intrinsic gas state-independent

Per review agreement on #12118, the intrinsic must not read world state:
replace the draft's tiered recipient/value costs (dead-account, code,
access-list probes) with the spec's flat model, and drop the worldState
parameter from IntrinsicGasCalculator and IGasPolicy. Also compress
comments across the branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: remove unused usings after worldState removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: address re-review on repricings

- Enforce the EIP-2780 => EIP-7708 co-activation invariant in
  ChainSpecBasedSpecProvider (with regression test).
- Restore the MaxCallDepth capacity hint on the VM state stack.
- Route the inlined net-spill expressions through GetUnrefundedStateGasSpill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: trim comments and revert incidental type churn on repricings

Comments: drop devnet references and legacy gas values, compress
multi-line rationale to at most two lines, neutralise test names.
Tests: restore base-branch numeric types where the gas-policy port
changed them without need (Eip7928Tests, EthRpcModuleTests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: minimize the repricing diff against the base branch

Restore base-branch structure and spellings that the repricing did not
need: undo numeric-suffix and type churn in tests, keep the intrinsic-gas
helpers in IntrinsicGasCalculator (applying the EIP-2780/8038 changes
in place instead of duplicating them in IGasPolicy), restore the
ConsumeCreateGas/ConsumePrecompileGas policy hooks and the cached
IsTracingActions field, and drop dead members the PR introduced
(4-arg ConsumeDataCopyGas, ConsumeCodeDeposit, unused spill getters,
the unused GasValidationResult.IntrinsicGas field). Trim comments per
review guidance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop usings orphaned by the GasValidationResult field removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: strip gas-constant comments and EELS references

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: revert constant-context long-to-ulong churn in tests

C# 14 implicitly converts constant long expressions to ulong, so the
base branch's const spellings still compile against the ulong builders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove comments

* chore: trim restating comments in the transaction processor

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: decide BAL-overlay account existence on effective state

AccountExists short-circuited on the parent reader, missing same-block
deletions (an account drained to zero by an earlier selfdestruct), and
treated any recorded prior balance/nonce change as existence even when
the change was to zero. Evaluate EIP-161 non-emptiness of the effective
state instead, so a later same-block CREATE2 over the address does not
wrongly refund EIP-8037 create-state gas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: cascade long through the state-gas dimension per review

Retype the state-gas constants to long so the signed dimension needs no
casts at its call sites (C# 14 constant conversions keep them usable in
ulong contexts), cascade long through the intrinsic state path and the
delegation-refund counters, and centralize the regular/state boundary
subtraction in IGasPolicy.GetPreRefundGas. Also move the EIP-8038 clear
refund to RefundOf, name the per-auth cost components, note the
EIP-7778 dependency of before-refund block gas, saturate the system-tx
block-gas subtraction, gate the validator's sender-recovery fallback on
EIP-2780, and fold the selfdestruct new-account charge into one
expression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: drop casts made redundant by the long state-gas constants

Collapse the system-transaction reservoir round-trip and remove the
now-unneeded casts in the state-gas tests; where NUnit compares boxed
values, pin the long-typed constants with long expectations instead of
casting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: type the state-byte constants long at the source

The byte-count constants feed only the signed state dimension, so
declaring them long removes every initializer cast; C# 14 constant
conversions keep the few ulong-context uses working unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove unneeded check

* fix: refund NEW_ACCOUNT state gas on failed inline precompile calls

The ZK_EVM inline precompile path dropped the newAccountCharged flag, so
an EIP-8038 value CALL to a dead precompile that reverted or hard-failed
kept the up-front NEW_ACCOUNT state charge. Thread the flag through
InlinePrecompileCall and mirror the mainline refunds. Also trim comments
across the diff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: drop the 2780/7708 co-activation guard test

The guard itself was removed (EIP interdependencies are by convention
documented, not enforced in ChainSpecBasedSpecProvider); the XML remark
on IsEip2780Enabled keeps the dependency documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy chainspec test

---------

Co-authored-by: Marc Harvey-Hill <10379486+Marchhill@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* test: update pyspec fixtures to glamsterdam-devnet v6.0.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: ignore ZkEVM stateless suite (fixtures target bal-devnet-7)

The ZkEvmBlockchainTests stateless suite runs Nethermind.Stateless.Executor
against the pinned tests-zkevm@v0.4.1 archive, which is generated against
bal-devnet-7 (tests-bal@v7.2.0). Its EIP-7928 block-access-list semantics differ
from the devnet-6 (tests-glamsterdam-devnet@v6.0.0) rules this stack implements,
so stateless execution rejects every fixture block on a BAL mismatch
(StatelessValidationResult.IsSuccess=0) — the full Pyspec [Sequential]/engine
shards each failed only on the *_stateless_block_N cases.

Mark the suite [Ignore] until the client tracks bal-devnet-7 (or the archive is
repinned to devnet-6). No production code is affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump Glamsterdam devnet Pyspec fixtures to v6.1.0

Run the Ethereum.Blockchain.Pyspec.Test suite against the
tests-glamsterdam-devnet@v6.1.0 fixture release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: re-enable zkEVM stateless fixtures on tests-zkevm@v0.5.0

The zkVM stateless suite was disabled because the pinned archive
(tests-zkevm@v0.4.1) was generated against bal-devnet-7, whose EIP-7928
BAL semantics differ from the devnet-6 rules this stack implements.

tests-zkevm@v0.5.0 is generated against tests-glamsterdam-devnet@v6.1.0
(the devnet-6 fixtures this stack tracks), so the mismatch is resolved.
Bump the archive version and drop the [Ignore].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: update Pyspec fixtures to Glamsterdam devnet-6 (v6.1.0) and zkEVM v0.5.0

Point the default Pyspec fixture archive at tests-glamsterdam-devnet@v6.1.0
and the zkEVM stateless preview suite at tests-zkevm@v0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: implement EIP-8246 (Remove SELFDESTRUCT Burn)

Removes the residual ETH-burn cases left by EIP-6780:

- A self-targeting SELFDESTRUCT now moves no ETH and emits no log,
  regardless of whether the account was created in the same transaction.
- At transaction finalization, accounts marked for destruction keep their
  balance: storage and code are cleared and the nonce is reset to 0. A
  resulting zero-balance account is still removed as empty per EIP-161,
  matching the spec and keeping CREATE2 redeployment unblocked.

Wires a new IsEip8246Enabled flag through IReleaseSpec / ReleaseSpec /
decorators / chainspec (Eip8246TransitionTimestamp) and enables it in the
Amsterdam fork. Adds Eip8246Tests covering same-transaction self-destruct
to self/other, post-destruct funding, the zero-balance empty-account case,
and the unchanged not-in-same-tx no-op, each pinned with EIP on and off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: cover deferred finalization path; address review feedback

- Add an EIP-8037 + EIP-7708 fixture dimension so every EIP-8246 scenario
  also runs through the deferred FinalizeDestroyedAccount path (as in
  Amsterdam), covering the balance-preservation logic there.
- Add a CREATE2 redeployment test: a factory re-creates a self-destructed
  child at the same address across transactions, verifying the nonce reset
  keeps redeployment unblocked and the preserved balance accumulates.
- Report the destroy refund to the tracer in the deferred path, matching
  the inline path.
- Document the pre-existing Burn-vs-SelfDestruct log distinction between the
  post-fee and pre-fee finalization paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: do not enable EIP-8246 in Amsterdam fork

EIP-8246 is a Draft and is not part of the EEST `for_amsterdam` conformance
fixtures. Enabling it in the Amsterdam fork changed SELFDESTRUCT behaviour
for that fork, diverging from the reference post-states and failing the
Pyspec tests across all shards.

Keep the full implementation and spec/chainspec plumbing so the EIP can be
activated via the Eip8246Transition chainspec parameter once it is scheduled,
but leave it disabled in the named forks. Unit tests toggle the flag directly
via OverridableReleaseSpec, so coverage is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: assert storage clearing in EIP-8246 self-destruct tests

Address PR review comments:
- The self-destruct-to-self contract now writes storage slot 0 before
  SELFDESTRUCT so AssertBalanceOnly can verify storage is wiped on the
  surviving balance-only account.
- Clarify the self-targeting SELFDESTRUCT short-circuit comment to
  distinguish the EIP-6780 pure no-op case from the EIP-8246 burn-removal
  case (account in destroy list, finalization still clears code/storage).

Note: the deferred finalization path also gained a tracer.ReportRefund
call to match the inline path; that is an incidental tracer fix unrelated
to EIP-8246 semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: tidy EIP-8246 self-destruct test per review

- Rename the self-destruct-to-self fixtures to _sstoreThenSelfDestructToSelf
  so the name reflects the SSTORE-then-SELFDESTRUCT bytecode.
- Wrap AssertBalanceOnly in Assert.EnterMultipleScope so every mismatch is
  surfaced in one run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP repricings and existing-EIP updates (devnet-6)

Combined branch for the Glamsterdam devnet-6 repricing/update EIPs:
EIP-2780, EIP-8037, EIP-8038, plus existing-EIP (7702/7708/7928/7954/7981)
test and behavior updates. Folds in the EIP-8037 halt-gas-accounting fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP-8282 builder execution requests (devnet-6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* wip(test): begin ulong test-suite port for master #11937 (incomplete)

Partial long->ulong adaptation of the glamsterdam EIP test files to master's
type-unified gas API. Test projects do not yet build; tracked follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong DestroyRefund for tracer refund (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong 8282 predeploy nonce in TestBlockchain (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(8037): revert state-gas dimension to signed long

Master #11937 ("unify types with Geth") changed all gas from long to
ulong (uint64). This is correct for the regular gas dimension, but the
EIP-8037 state-gas dimension needs a *signed* reservoir: during nested
frame spill merges (RestoreChildStateGas / RestoreChildStateGasOnHalt /
RevertRefundToHalt) the StateReservoir goes transiently negative before
recovering. As ulong it underflowed to ~2^64, producing wrong spentGas
on halts (e.g. 12000 instead of 16777216) and 54 EIP-8037 spill/halt/
reservoir fixture failures.

Revert the state-gas dimension (StateReservoir, StateGasUsed,
StateGasSpill*, intrinsic/create/new-account/per-auth/code-deposit/
storage state costs, and their IGasPolicy signatures, VmState fields,
VirtualMachine refund locals, and TransactionProcessor halt/block-gas
locals) back to signed long. Regular gas Value/GetRemainingGas/
UpdateGas/Consume/TryConsume and GasConsumed stay ulong; cast at the
regular<->state boundary (all state values are non-negative there).

Fixes test_nested_failure_resets_to_tx_reservoir (was 54 failed -> 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port EIP-8246 test BlockNumber override to ulong (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump EF fixtures to tests-glamsterdam-devnet@v6.1.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: remove unnecessary using after SaturatingSub revert (IDE0005)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: map InvalidTxSignature to INVALID_SIGNATURE_VRS for v6.1.1 test_bad_v_r_s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* review fixes: assert 8037 gas invariants, restore getLogs depth test, fix stale docs

- Debug.Assert the EIP-8037 boundary invariants (state >= 0, remaining +
  reservoir <= gasLimit) at the halt/fail/collision read points and in
  RefundStateGas, replacing the saturating defense removed with the rework
- restore Eth_get_logs_enforces_max_block_depth (accidentally dropped in the
  master RPC reconciliation; the MaxBlockDepth guard is live)
- de-circularize the 7702 SpentGas expectation (constants instead of the
  production intrinsic calculator) and add an exact floor==standard tie case
  for EIP-7981
- refresh stale 4500-era totals/comments (TX_BASE is 12000), the 8038
  placeholder remark, and the 8037 inclusion-rule assertion message
- drop unused Eip8038IntrinsicRecipientGas params, redundant (ulong) casts on
  ulong constants, and the lazy BlockValidator ecdsa init

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* review fixes: extend request-type constants for EIP-8282, fail descriptively on builder-request decode

- MaxRequestsCount 3 -> 5 (deposit/withdrawal/consolidation + builder deposit/exit)
- GetFlatDecodedRequests throws a descriptive NotSupportedException for the
  EIP-8282 types the tests-zkevm v0.5.0 stateless input format cannot represent,
  instead of an opaque unknown-type error
- drop the stale length<=3 TODO

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: map InvalidTxChainId/EIP-155 sig failure to INVALID_CHAINID (v6.1.1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: decode invalid-tx state tests from txbytes (v6.1.1 expectException)

v6.1.1 state tests carry expectException plus the actual signed tx in txbytes.
The template tx is re-signed pre-EIP-155, which cannot reproduce signature-level
invalidity (test_invalid_chain_id executes as a valid tx and diverges from the
expected post state). Decode the fixture's raw tx for such entries so validation
rejects it; undecodable txbytes fall back to the template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: relax EIP-8037 debug asserts to the true signed invariants

The [checked] CI variant surfaced two over-strict asserts: the state reservoir
can legitimately end a tx negative (net child spill) with the ulong wrap still
producing the correct signed spentGas, and system calls can halt with
preRefundGas 0 while intrinsic state gas remains (their GasConsumed is
discarded). Assert the signed non-negative-spend invariant instead, and gate
the halt-path block-gas assert on non-system transactions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: drop end-of-tx gas assert that a parallel-test race trips flakily

A pre-existing Nethermind.Evm.Test parallel race (~1 in 6 full-suite runs)
intermittently violates the end-of-tx invariant from
Create2_redeploy_to_same_address_unblocked_after_self_destruct, SIGABRTing the
[checked] job. The halt/fail/collision asserts stay (validated clean across the
checked pyspec suite); a genuine wrap on this success path already fails
fixtures via receipts/state roots. Race tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables by spec instance, not on the spec object

The per-spec opcode tables were cached in IReleaseSpec.EvmInstructionsNoTrace/
Traced slots. OverridableReleaseSpec's getter fell back to the wrapped spec and
ReleaseSpecDecorator's setter wrote through to it, so wrappers with different
EVM flags (7708/8037/8246 test variants) shared one table with fork singletons —
first writer won, giving wrong opcode handlers (missing transfer logs, wrong
state-gas charges) depending on test order. Port master's fix (#12146): cache
tables in a ConcurrentDictionary keyed by spec instance (plain statics for the
single-fork zkEVM guest) and drop the IReleaseSpec slots.

Full Evm.Test suite: 10/10 clean (was ~5 of 6 runs failing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: restore the end-of-tx gas invariant assert

The parallel-test race that flakily violated it is fixed (opcode tables now
keyed by spec instance); 10/10 full checked Evm.Test runs clean with it live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: tighten EIP-8246 comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: move the v6.1.1 pyspec fixes off the EIP-8246 branch

The fixture bump and its harness fixes (INVALID_SIGNATURE_VRS/INVALID_CHAINID
mappings, txbytes decode for expectException state tests) are unrelated to
EIP-8246; they move to fix/zkevm-stateless-v050-v2 where the fixture/format
alignment lives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: move the opcode-table cache fix to the stateless branch; group 8246 with Amsterdam EIPs

The spec-instance opcode-table keying is test-infrastructure hardening
unrelated to EIP-8246; it moves to fix/zkevm-stateless-v050-v2. IsEip8246Enabled
now sits with the other Amsterdam EIP flags in the spec surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: drop the Amsterdam EIP-8246 activation note

The flag is enabled one PR up (repricings, #12214) where the note is already gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: enable EIP-8246 in Amsterdam

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reconcile glamsterdam gas policy with master's #12146 foundation

Keep devnet-6 semantics (signed state dimension, EELS block/halt gas, 2780/8038
repricings) while adopting master's structural changes: tagged-cost Consume,
policy-computed data-copy/create/SSTORE consumers (8038-aware where priced),
UpdateMemoryCost over EvmPooledMemory, parameterless state-cost getters,
TryReserveChildGas, CombineBlockGas, the system-tx-processor seam with the
parallel flag, and the popped-address cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style: expression-bodied state-cost test (IDE0022)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: aggressively inline the glamsterdam gas-policy interface defaults

Master's inlining guard test requires the attribute on every IGasPolicy
default/helper for no-dynamic-PGO regimes (NativeAOT zkEVM guest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: charge full requested gas for pre-EIP-150 child calls

The hand-ported TryReserveChildGas clamped the requested gas to the remaining
balance on the pre-63/64 branch; the spec charges the full request, so an
over-asking CALL exceptionally halts the caller (refundReset_Frontier/
Homestead and the early-fork pyspec chunks caught it). Now byte-identical to
master's implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: make EIP-2780 intrinsic gas state-independent

Per review agreement on #12118, the intrinsic must not read world state:
replace the draft's tiered recipient/value costs (dead-account, code,
access-list probes) with the spec's flat model, and drop the worldState
parameter from IntrinsicGasCalculator and IGasPolicy. Also compress
comments across the branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: remove unused usings after worldState removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: address re-review on repricings

- Enforce the EIP-2780 => EIP-7708 co-activation invariant in
  ChainSpecBasedSpecProvider (with regression test).
- Restore the MaxCallDepth capacity hint on the VM state stack.
- Route the inlined net-spill expressions through GetUnrefundedStateGasSpill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: trim comments and revert incidental type churn on repricings

Comments: drop devnet references and legacy gas values, compress
multi-line rationale to at most two lines, neutralise test names.
Tests: restore base-branch numeric types where the gas-policy port
changed them without need (Eip7928Tests, EthRpcModuleTests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: minimize the repricing diff against the base branch

Restore base-branch structure and spellings that the repricing did not
need: undo numeric-suffix and type churn in tests, keep the intrinsic-gas
helpers in IntrinsicGasCalculator (applying the EIP-2780/8038 changes
in place instead of duplicating them in IGasPolicy), restore the
ConsumeCreateGas/ConsumePrecompileGas policy hooks and the cached
IsTracingActions field, and drop dead members the PR introduced
(4-arg ConsumeDataCopyGas, ConsumeCodeDeposit, unused spill getters,
the unused GasValidationResult.IntrinsicGas field). Trim comments per
review guidance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop usings orphaned by the GasValidationResult field removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: align the BAL boundary tests with the base branch's ulong gas limits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: strip gas-constant comments and EELS references

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: revert constant-context long-to-ulong churn in tests

C# 14 implicitly converts constant long expressions to ulong, so the
base branch's const spellings still compile against the ulong builders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove comments

* chore: trim restating comments in the transaction processor

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy

* chore: minimize EIP-8282 diff vs base

Match existing SystemCall initializer style (drop UInt256.Zero and the
Nethermind.Int256 usings), align Eip8282TestConstants.Nonce with the
sibling test-constant files (ulong, no casts), and trim comments to the
why-only essentials.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: decide BAL-overlay account existence on effective state

AccountExists short-circuited on the parent reader, missing same-block
deletions (an account drained to zero by an earlier selfdestruct), and
treated any recorded prior balance/nonce change as existence even when
the change was to zero. Evaluate EIP-161 non-emptiness of the effective
state instead, so a later same-block CREATE2 over the address does not
wrongly refund EIP-8037 create-state gas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: name the stateless flat-encoded request-type count

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: cascade long through the state-gas dimension per review

Retype the state-gas constants to long so the signed dimension needs no
casts at its call sites (C# 14 constant conversions keep them usable in
ulong contexts), cascade long through the intrinsic state path and the
delegation-refund counters, and centralize the regular/state boundary
subtraction in IGasPolicy.GetPreRefundGas. Also move the EIP-8038 clear
refund to RefundOf, name the per-auth cost components, note the
EIP-7778 dependency of before-refund block gas, saturate the system-tx
block-gas subtraction, gate the validator's sender-recovery fallback on
EIP-2780, and fold the selfdestruct new-account charge into one
expression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: drop casts made redundant by the long state-gas constants

Collapse the system-transaction reservoir round-trip and remove the
now-unneeded casts in the state-gas tests; where NUnit compares boxed
values, pin the long-typed constants with long expectations instead of
casting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: type the state-byte constants long at the source

The byte-count constants feed only the signed state dimension, so
declaring them long removes every initializer cast; C# 14 constant
conversions keep the few ulong-context uses working unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove unneeded check

* fix: refund NEW_ACCOUNT state gas on failed inline precompile calls

The ZK_EVM inline precompile path dropped the newAccountCharged flag, so
an EIP-8038 value CALL to a dead precompile that reverted or hard-failed
kept the up-front NEW_ACCOUNT state charge. Thread the flag through
InlinePrecompileCall and mirror the mainline refunds. Also trim comments
across the diff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: drop the 2780/7708 co-activation guard test

The guard itself was removed (EIP interdependencies are by convention
documented, not enforced in ChainSpecBasedSpecProvider); the XML remark
on IsEip2780Enabled keeps the dependency documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy chainspec test

---------

Co-authored-by: Marc Harvey-Hill <10379486+Marchhill@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* test: update pyspec fixtures to glamsterdam-devnet v6.0.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: ignore ZkEVM stateless suite (fixtures target bal-devnet-7)

The ZkEvmBlockchainTests stateless suite runs Nethermind.Stateless.Executor
against the pinned tests-zkevm@v0.4.1 archive, which is generated against
bal-devnet-7 (tests-bal@v7.2.0). Its EIP-7928 block-access-list semantics differ
from the devnet-6 (tests-glamsterdam-devnet@v6.0.0) rules this stack implements,
so stateless execution rejects every fixture block on a BAL mismatch
(StatelessValidationResult.IsSuccess=0) — the full Pyspec [Sequential]/engine
shards each failed only on the *_stateless_block_N cases.

Mark the suite [Ignore] until the client tracks bal-devnet-7 (or the archive is
repinned to devnet-6). No production code is affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump Glamsterdam devnet Pyspec fixtures to v6.1.0

Run the Ethereum.Blockchain.Pyspec.Test suite against the
tests-glamsterdam-devnet@v6.1.0 fixture release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: re-enable zkEVM stateless fixtures on tests-zkevm@v0.5.0

The zkVM stateless suite was disabled because the pinned archive
(tests-zkevm@v0.4.1) was generated against bal-devnet-7, whose EIP-7928
BAL semantics differ from the devnet-6 rules this stack implements.

tests-zkevm@v0.5.0 is generated against tests-glamsterdam-devnet@v6.1.0
(the devnet-6 fixtures this stack tracks), so the mismatch is resolved.
Bump the archive version and drop the [Ignore].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: update Pyspec fixtures to Glamsterdam devnet-6 (v6.1.0) and zkEVM v0.5.0

Point the default Pyspec fixture archive at tests-glamsterdam-devnet@v6.1.0
and the zkEVM stateless preview suite at tests-zkevm@v0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: implement EIP-8246 (Remove SELFDESTRUCT Burn)

Removes the residual ETH-burn cases left by EIP-6780:

- A self-targeting SELFDESTRUCT now moves no ETH and emits no log,
  regardless of whether the account was created in the same transaction.
- At transaction finalization, accounts marked for destruction keep their
  balance: storage and code are cleared and the nonce is reset to 0. A
  resulting zero-balance account is still removed as empty per EIP-161,
  matching the spec and keeping CREATE2 redeployment unblocked.

Wires a new IsEip8246Enabled flag through IReleaseSpec / ReleaseSpec /
decorators / chainspec (Eip8246TransitionTimestamp) and enables it in the
Amsterdam fork. Adds Eip8246Tests covering same-transaction self-destruct
to self/other, post-destruct funding, the zero-balance empty-account case,
and the unchanged not-in-same-tx no-op, each pinned with EIP on and off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: cover deferred finalization path; address review feedback

- Add an EIP-8037 + EIP-7708 fixture dimension so every EIP-8246 scenario
  also runs through the deferred FinalizeDestroyedAccount path (as in
  Amsterdam), covering the balance-preservation logic there.
- Add a CREATE2 redeployment test: a factory re-creates a self-destructed
  child at the same address across transactions, verifying the nonce reset
  keeps redeployment unblocked and the preserved balance accumulates.
- Report the destroy refund to the tracer in the deferred path, matching
  the inline path.
- Document the pre-existing Burn-vs-SelfDestruct log distinction between the
  post-fee and pre-fee finalization paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: do not enable EIP-8246 in Amsterdam fork

EIP-8246 is a Draft and is not part of the EEST `for_amsterdam` conformance
fixtures. Enabling it in the Amsterdam fork changed SELFDESTRUCT behaviour
for that fork, diverging from the reference post-states and failing the
Pyspec tests across all shards.

Keep the full implementation and spec/chainspec plumbing so the EIP can be
activated via the Eip8246Transition chainspec parameter once it is scheduled,
but leave it disabled in the named forks. Unit tests toggle the flag directly
via OverridableReleaseSpec, so coverage is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: assert storage clearing in EIP-8246 self-destruct tests

Address PR review comments:
- The self-destruct-to-self contract now writes storage slot 0 before
  SELFDESTRUCT so AssertBalanceOnly can verify storage is wiped on the
  surviving balance-only account.
- Clarify the self-targeting SELFDESTRUCT short-circuit comment to
  distinguish the EIP-6780 pure no-op case from the EIP-8246 burn-removal
  case (account in destroy list, finalization still clears code/storage).

Note: the deferred finalization path also gained a tracer.ReportRefund
call to match the inline path; that is an incidental tracer fix unrelated
to EIP-8246 semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: tidy EIP-8246 self-destruct test per review

- Rename the self-destruct-to-self fixtures to _sstoreThenSelfDestructToSelf
  so the name reflects the SSTORE-then-SELFDESTRUCT bytecode.
- Wrap AssertBalanceOnly in Assert.EnterMultipleScope so every mismatch is
  surfaced in one run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP repricings and existing-EIP updates (devnet-6)

Combined branch for the Glamsterdam devnet-6 repricing/update EIPs:
EIP-2780, EIP-8037, EIP-8038, plus existing-EIP (7702/7708/7928/7954/7981)
test and behavior updates. Folds in the EIP-8037 halt-gas-accounting fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP-8282 builder execution requests (devnet-6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: targetGasLimit support in PayloadAttributesV4 (devnet-6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: align stateless executor with tests-zkevm@v0.5.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* wip(test): begin ulong test-suite port for master #11937 (incomplete)

Partial long->ulong adaptation of the glamsterdam EIP test files to master's
type-unified gas API. Test projects do not yet build; tracked follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong DestroyRefund for tracer refund (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong 8282 predeploy nonce in TestBlockchain (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(8037): revert state-gas dimension to signed long

Master #11937 ("unify types with Geth") changed all gas from long to
ulong (uint64). This is correct for the regular gas dimension, but the
EIP-8037 state-gas dimension needs a *signed* reservoir: during nested
frame spill merges (RestoreChildStateGas / RestoreChildStateGasOnHalt /
RevertRefundToHalt) the StateReservoir goes transiently negative before
recovering. As ulong it underflowed to ~2^64, producing wrong spentGas
on halts (e.g. 12000 instead of 16777216) and 54 EIP-8037 spill/halt/
reservoir fixture failures.

Revert the state-gas dimension (StateReservoir, StateGasUsed,
StateGasSpill*, intrinsic/create/new-account/per-auth/code-deposit/
storage state costs, and their IGasPolicy signatures, VmState fields,
VirtualMachine refund locals, and TransactionProcessor halt/block-gas
locals) back to signed long. Regular gas Value/GetRemainingGas/
UpdateGas/Consume/TryConsume and GasConsumed stay ulong; cast at the
regular<->state boundary (all state values are non-negative there).

Fixes test_nested_failure_resets_to_tx_reservoir (was 54 failed -> 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port target-gas-layer gas-limit/Engine tests to ulong API

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port EIP-8246 test BlockNumber override to ulong (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump EF fixtures to tests-glamsterdam-devnet@v6.1.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: remove unnecessary using after SaturatingSub revert (IDE0005)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: map InvalidTxSignature to INVALID_SIGNATURE_VRS for v6.1.1 test_bad_v_r_s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* review fixes: assert 8037 gas invariants, restore getLogs depth test, fix stale docs

- Debug.Assert the EIP-8037 boundary invariants (state >= 0, remaining +
  reservoir <= gasLimit) at the halt/fail/collision read points and in
  RefundStateGas, replacing the saturating defense removed with the rework
- restore Eth_get_logs_enforces_max_block_depth (accidentally dropped in the
  master RPC reconciliation; the MaxBlockDepth guard is live)
- de-circularize the 7702 SpentGas expectation (constants instead of the
  production intrinsic calculator) and add an exact floor==standard tie case
  for EIP-7981
- refresh stale 4500-era totals/comments (TX_BASE is 12000), the 8038
  placeholder remark, and the 8037 inclusion-rule assertion message
- drop unused Eip8038IntrinsicRecipientGas params, redundant (ulong) casts on
  ulong constants, and the lazy BlockValidator ecdsa init

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* review fixes: extend request-type constants for EIP-8282, fail descriptively on builder-request decode

- MaxRequestsCount 3 -> 5 (deposit/withdrawal/consolidation + builder deposit/exit)
- GetFlatDecodedRequests throws a descriptive NotSupportedException for the
  EIP-8282 types the tests-zkevm v0.5.0 stateless input format cannot represent,
  instead of an opaque unknown-type error
- drop the stale length<=3 TODO

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* review fixes: keep AuRa contract gas limit validation strict

- revert the IsGasLimitValid parent-delta acceptance: the check only runs on the
  pre-merge AuRa path where no targetGasLimit exists, so loosening it widened
  legacy block acceptance for no benefit
- drop the redundant single-arg GetGasLimit stub in TestingRpcModuleTests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: map InvalidTxChainId/EIP-155 sig failure to INVALID_CHAINID (v6.1.1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: decode invalid-tx state tests from txbytes (v6.1.1 expectException)

v6.1.1 state tests carry expectException plus the actual signed tx in txbytes.
The template tx is re-signed pre-EIP-155, which cannot reproduce signature-level
invalidity (test_invalid_chain_id executes as a valid tx and diverges from the
expected post state). Decode the fixture's raw tx for such entries so validation
rejects it; undecodable txbytes fall back to the template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: relax EIP-8037 debug asserts to the true signed invariants

The [checked] CI variant surfaced two over-strict asserts: the state reservoir
can legitimately end a tx negative (net child spill) with the ulong wrap still
producing the correct signed spentGas, and system calls can halt with
preRefundGas 0 while intrinsic state gas remains (their GasConsumed is
discarded). Assert the signed non-negative-spend invariant instead, and gate
the halt-path block-gas assert on non-system transactions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: drop end-of-tx gas assert that a parallel-test race trips flakily

A pre-existing Nethermind.Evm.Test parallel race (~1 in 6 full-suite runs)
intermittently violates the end-of-tx invariant from
Create2_redeploy_to_same_address_unblocked_after_self_destruct, SIGABRTing the
[checked] job. The halt/fail/collision asserts stay (validated clean across the
checked pyspec suite); a genuine wrap on this success path already fails
fixtures via receipts/state roots. Race tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables by spec instance, not on the spec object

The per-spec opcode tables were cached in IReleaseSpec.EvmInstructionsNoTrace/
Traced slots. OverridableReleaseSpec's getter fell back to the wrapped spec and
ReleaseSpecDecorator's setter wrote through to it, so wrappers with different
EVM flags (7708/8037/8246 test variants) shared one table with fork singletons —
first writer won, giving wrong opcode handlers (missing transfer logs, wrong
state-gas charges) depending on test order. Port master's fix (#12146): cache
tables in a ConcurrentDictionary keyed by spec instance (plain statics for the
single-fork zkEVM guest) and drop the IReleaseSpec slots.

Full Evm.Test suite: 10/10 clean (was ~5 of 6 runs failing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: restore the end-of-tx gas invariant assert

The parallel-test race that flakily violated it is fixed (opcode tables now
keyed by spec instance); 10/10 full checked Evm.Test runs clean with it live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: tighten EIP-8246 comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: move the v6.1.1 pyspec fixes off the EIP-8246 branch

The fixture bump and its harness fixes (INVALID_SIGNATURE_VRS/INVALID_CHAINID
mappings, txbytes decode for expectException state tests) are unrelated to
EIP-8246; they move to fix/zkevm-stateless-v050-v2 where the fixture/format
alignment lives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: pin EF fixtures v6.1.1 and align the harness with its new tests

Relocated from the EIP-8246 branch: the tests-glamsterdam-devnet@v6.1.1 bump,
the INVALID_SIGNATURE_VRS/INVALID_CHAINID error mappings for test_bad_v_r_s and
test_invalid_chain_id, and decoding expectException state-test txbytes so
signature-level invalidity survives conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: move the opcode-table cache fix to the stateless branch; group 8246 with Amsterdam EIPs

The spec-instance opcode-table keying is test-infrastructure hardening
unrelated to EIP-8246; it moves to fix/zkevm-stateless-v050-v2. IsEip8246Enabled
now sits with the other Amsterdam EIP flags in the spec surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables weakly by spec instance

Relocated from the EIP-8246 branch and reworked per review: the per-spec-slot
cache let OverridableReleaseSpec fall back to (and ReleaseSpecDecorator write
through to) the wrapped fork singleton's table, so spec wrappers with different
EVM flags shared one first-writer-wins dispatch table (flaky wrong handlers in
parallel test runs). Tables are now keyed by spec instance in a
ConditionalWeakTable — unlike a strong-keyed map, entries for the per-request
decorator specs built by simulate/state-override RPC paths (WithoutEip3607/
WithoutEip158/ForSystemTransaction) are collected instead of retained forever.
The single-fork zkEVM guest caches in plain statics; the IReleaseSpec slots are
gone.

Full Evm.Test suite 8/8 clean (the pre-fix race flaked ~5 of 6 runs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: drop the Amsterdam EIP-8246 activation note

The flag is enabled one PR up (repricings, #12214) where the note is already gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: enable EIP-8246 in Amsterdam

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reconcile glamsterdam gas policy with master's #12146 foundation

Keep devnet-6 semantics (signed state dimension, EELS block/halt gas, 2780/8038
repricings) while adopting master's structural changes: tagged-cost Consume,
policy-computed data-copy/create/SSTORE consumers (8038-aware where priced),
UpdateMemoryCost over EvmPooledMemory, parameterless state-cost getters,
TryReserveChildGas, CombineBlockGas, the system-tx-processor seam with the
parallel flag, and the popped-address cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: restore witnessMode plumbing dropped by the master merge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style: expression-bodied state-cost test (IDE0022)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: aggressively inline the glamsterdam gas-policy interface defaults

Master's inlining guard test requires the attribute on every IGasPolicy
default/helper for no-dynamic-PGO regimes (NativeAOT zkEVM guest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: supply TargetGasLimit in the witness-capture FCUv4 payload build

PayloadAttributesV4 requires it as of the targetGasLimit change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: charge full requested gas for pre-EIP-150 child calls

The hand-ported TryReserveChildGas clamped the requested gas to the remaining
balance on the pre-63/64 branch; the spec charges the full request, so an
over-asking CALL exceptionally halts the caller (refundReset_Frontier/
Homestead and the early-fork pyspec chunks caught it). Now byte-identical to
master's implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: make EIP-2780 intrinsic gas state-independent

Per review agreement on #12118, the intrinsic must not read world state:
replace the draft's tiered recipient/value costs (dead-account, code,
access-list probes) with the spec's flat model, and drop the worldState
parameter from IntrinsicGasCalculator and IGasPolicy. Also compress
comments across the branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: remove unused usings after worldState removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: address re-review on repricings

- Enforce the EIP-2780 => EIP-7708 co-activation invariant in
  ChainSpecBasedSpecProvider (with regression test).
- Restore the MaxCallDepth capacity hint on the VM state stack.
- Route the inlined net-spill expressions through GetUnrefundedStateGasSpill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: trim comments and revert incidental type churn on repricings

Comments: drop devnet references and legacy gas values, compress
multi-line rationale to at most two lines, neutralise test names.
Tests: restore base-branch numeric types where the gas-policy port
changed them without need (Eip7928Tests, EthRpcModuleTests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: minimize the repricing diff against the base branch

Restore base-branch structure and spellings that the repricing did not
need: undo numeric-suffix and type churn in tests, keep the intrinsic-gas
helpers in IntrinsicGasCalculator (applying the EIP-2780/8038 changes
in place instead of duplicating them in IGasPolicy), restore the
ConsumeCreateGas/ConsumePrecompileGas policy hooks and the cached
IsTracingActions field, and drop dead members the PR introduced
(4-arg ConsumeDataCopyGas, ConsumeCodeDeposit, unused spill getters,
the unused GasValidationResult.IntrinsicGas field). Trim comments per
review guidance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop usings orphaned by the GasValidationResult field removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: align the BAL boundary tests with the base branch's ulong gas limits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: strip gas-constant comments and EELS references

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: revert constant-context long-to-ulong churn in tests

C# 14 implicitly converts constant long expressions to ulong, so the
base branch's const spellings still compile against the ulong builders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove comments

* chore: trim restating comments in the transaction processor

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy

* chore: minimize EIP-8282 diff vs base

Match existing SystemCall initializer style (drop UInt256.Zero and the
Nethermind.Int256 usings), align Eip8282TestConstants.Nonce with the
sibling test-constant files (ulong, no casts), and trim comments to the
why-only essentials.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: decide BAL-overlay account existence on effective state

AccountExists short-circuited on the parent reader, missing same-block
deletions (an account drained to zero by an earlier selfdestruct), and
treated any recorded prior balance/nonce change as existence even when
the change was to zero. Evaluate EIP-161 non-emptiness of the effective
state instead, so a later same-block CREATE2 over the address does not
wrongly refund EIP-8037 create-state gas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: name the stateless flat-encoded request-type count

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: cascade long through the state-gas dimension per review

Retype the state-gas constants to long so the signed dimension needs no
casts at its call sites (C# 14 constant conversions keep them usable in
ulong contexts), cascade long through the intrinsic state path and the
delegation-refund counters, and centralize the regular/state boundary
subtraction in IGasPolicy.GetPreRefundGas. Also move the EIP-8038 clear
refund to RefundOf, name the per-auth cost components, note the
EIP-7778 dependency of before-refund block gas, saturate the system-tx
block-gas subtraction, gate the validator's sender-recovery fallback on
EIP-2780, and fold the selfdestruct new-account charge into one
expression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: drop casts made redundant by the long state-gas constants

Collapse the system-transaction reservoir round-trip and remove the
now-unneeded casts in the state-gas tests; where NUnit compares boxed
values, pin the long-typed constants with long expectations instead of
casting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: type the state-byte constants long at the source

The byte-count constants feed only the signed state dimension, so
declaring them long removes every initializer cast; C# 14 constant
conversions keep the few ulong-context uses working unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove unneeded check

* test: pin the PayloadAttributesV4 SSZ field offsets to the spec order

A round-trip test cannot detect a reordered container; assert the
slot_number and target_gas_limit byte positions from the execution-apis
layout directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: inject execution-requests processor factory instead of witnessMode flag

Per review on #12217: BlockAccessListManager no longer knows about witness
mode; StatelessBlockProcessingEnv injects the stateless factory directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: refund NEW_ACCOUNT state gas on failed inline precompile calls

The ZK_EVM inline precompile path dropped the newAccountCharged flag, so
an EIP-8038 value CALL to a dead precompile that reverted or hard-failed
kept the up-front NEW_ACCOUNT state charge. Thread the flag through
InlinePrecompileCall and mirror the mainline refunds. Also trim comments
across the diff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: drop the 2780/7708 co-activation guard test

The guard itself was removed (EIP interdependencies are by convention
documented, not enforced in ChainSpecBasedSpecProvider); the XML remark
on IsEip2780Enabled keeps the dependency documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy chainspec test

* Update src/Nethermind/Nethermind.Consensus.AuRa/AuRaContractGasLimitOverride.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

* Update src/Nethermind/Nethermind.Consensus.Test/PayloadAttributesValidateTests.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

* Update src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszCodecTests.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

---------

Co-authored-by: Marc Harvey-Hill <10379486+Marchhill@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
…pec fixtures (#12312)

* test: update pyspec fixtures to glamsterdam-devnet v6.0.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: ignore ZkEVM stateless suite (fixtures target bal-devnet-7)

The ZkEvmBlockchainTests stateless suite runs Nethermind.Stateless.Executor
against the pinned tests-zkevm@v0.4.1 archive, which is generated against
bal-devnet-7 (tests-bal@v7.2.0). Its EIP-7928 block-access-list semantics differ
from the devnet-6 (tests-glamsterdam-devnet@v6.0.0) rules this stack implements,
so stateless execution rejects every fixture block on a BAL mismatch
(StatelessValidationResult.IsSuccess=0) — the full Pyspec [Sequential]/engine
shards each failed only on the *_stateless_block_N cases.

Mark the suite [Ignore] until the client tracks bal-devnet-7 (or the archive is
repinned to devnet-6). No production code is affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump Glamsterdam devnet Pyspec fixtures to v6.1.0

Run the Ethereum.Blockchain.Pyspec.Test suite against the
tests-glamsterdam-devnet@v6.1.0 fixture release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: re-enable zkEVM stateless fixtures on tests-zkevm@v0.5.0

The zkVM stateless suite was disabled because the pinned archive
(tests-zkevm@v0.4.1) was generated against bal-devnet-7, whose EIP-7928
BAL semantics differ from the devnet-6 rules this stack implements.

tests-zkevm@v0.5.0 is generated against tests-glamsterdam-devnet@v6.1.0
(the devnet-6 fixtures this stack tracks), so the mismatch is resolved.
Bump the archive version and drop the [Ignore].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: update Pyspec fixtures to Glamsterdam devnet-6 (v6.1.0) and zkEVM v0.5.0

Point the default Pyspec fixture archive at tests-glamsterdam-devnet@v6.1.0
and the zkEVM stateless preview suite at tests-zkevm@v0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: implement EIP-8246 (Remove SELFDESTRUCT Burn)

Removes the residual ETH-burn cases left by EIP-6780:

- A self-targeting SELFDESTRUCT now moves no ETH and emits no log,
  regardless of whether the account was created in the same transaction.
- At transaction finalization, accounts marked for destruction keep their
  balance: storage and code are cleared and the nonce is reset to 0. A
  resulting zero-balance account is still removed as empty per EIP-161,
  matching the spec and keeping CREATE2 redeployment unblocked.

Wires a new IsEip8246Enabled flag through IReleaseSpec / ReleaseSpec /
decorators / chainspec (Eip8246TransitionTimestamp) and enables it in the
Amsterdam fork. Adds Eip8246Tests covering same-transaction self-destruct
to self/other, post-destruct funding, the zero-balance empty-account case,
and the unchanged not-in-same-tx no-op, each pinned with EIP on and off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: cover deferred finalization path; address review feedback

- Add an EIP-8037 + EIP-7708 fixture dimension so every EIP-8246 scenario
  also runs through the deferred FinalizeDestroyedAccount path (as in
  Amsterdam), covering the balance-preservation logic there.
- Add a CREATE2 redeployment test: a factory re-creates a self-destructed
  child at the same address across transactions, verifying the nonce reset
  keeps redeployment unblocked and the preserved balance accumulates.
- Report the destroy refund to the tracer in the deferred path, matching
  the inline path.
- Document the pre-existing Burn-vs-SelfDestruct log distinction between the
  post-fee and pre-fee finalization paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: do not enable EIP-8246 in Amsterdam fork

EIP-8246 is a Draft and is not part of the EEST `for_amsterdam` conformance
fixtures. Enabling it in the Amsterdam fork changed SELFDESTRUCT behaviour
for that fork, diverging from the reference post-states and failing the
Pyspec tests across all shards.

Keep the full implementation and spec/chainspec plumbing so the EIP can be
activated via the Eip8246Transition chainspec parameter once it is scheduled,
but leave it disabled in the named forks. Unit tests toggle the flag directly
via OverridableReleaseSpec, so coverage is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: assert storage clearing in EIP-8246 self-destruct tests

Address PR review comments:
- The self-destruct-to-self contract now writes storage slot 0 before
  SELFDESTRUCT so AssertBalanceOnly can verify storage is wiped on the
  surviving balance-only account.
- Clarify the self-targeting SELFDESTRUCT short-circuit comment to
  distinguish the EIP-6780 pure no-op case from the EIP-8246 burn-removal
  case (account in destroy list, finalization still clears code/storage).

Note: the deferred finalization path also gained a tracer.ReportRefund
call to match the inline path; that is an incidental tracer fix unrelated
to EIP-8246 semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: tidy EIP-8246 self-destruct test per review

- Rename the self-destruct-to-self fixtures to _sstoreThenSelfDestructToSelf
  so the name reflects the SSTORE-then-SELFDESTRUCT bytecode.
- Wrap AssertBalanceOnly in Assert.EnterMultipleScope so every mismatch is
  surfaced in one run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP repricings and existing-EIP updates (devnet-6)

Combined branch for the Glamsterdam devnet-6 repricing/update EIPs:
EIP-2780, EIP-8037, EIP-8038, plus existing-EIP (7702/7708/7928/7954/7981)
test and behavior updates. Folds in the EIP-8037 halt-gas-accounting fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP-8282 builder execution requests (devnet-6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: targetGasLimit support in PayloadAttributesV4 (devnet-6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: align stateless executor with tests-zkevm@v0.5.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* wip(test): begin ulong test-suite port for master #11937 (incomplete)

Partial long->ulong adaptation of the glamsterdam EIP test files to master's
type-unified gas API. Test projects do not yet build; tracked follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong DestroyRefund for tracer refund (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong 8282 predeploy nonce in TestBlockchain (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(8037): revert state-gas dimension to signed long

Master #11937 ("unify types with Geth") changed all gas from long to
ulong (uint64). This is correct for the regular gas dimension, but the
EIP-8037 state-gas dimension needs a *signed* reservoir: during nested
frame spill merges (RestoreChildStateGas / RestoreChildStateGasOnHalt /
RevertRefundToHalt) the StateReservoir goes transiently negative before
recovering. As ulong it underflowed to ~2^64, producing wrong spentGas
on halts (e.g. 12000 instead of 16777216) and 54 EIP-8037 spill/halt/
reservoir fixture failures.

Revert the state-gas dimension (StateReservoir, StateGasUsed,
StateGasSpill*, intrinsic/create/new-account/per-auth/code-deposit/
storage state costs, and their IGasPolicy signatures, VmState fields,
VirtualMachine refund locals, and TransactionProcessor halt/block-gas
locals) back to signed long. Regular gas Value/GetRemainingGas/
UpdateGas/Consume/TryConsume and GasConsumed stay ulong; cast at the
regular<->state boundary (all state values are non-negative there).

Fixes test_nested_failure_resets_to_tx_reservoir (was 54 failed -> 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port target-gas-layer gas-limit/Engine tests to ulong API

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port EIP-8246 test BlockNumber override to ulong (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump EF fixtures to tests-glamsterdam-devnet@v6.1.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: remove unnecessary using after SaturatingSub revert (IDE0005)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: map InvalidTxSignature to INVALID_SIGNATURE_VRS for v6.1.1 test_bad_v_r_s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* review fixes: assert 8037 gas invariants, restore getLogs depth test, fix stale docs

- Debug.Assert the EIP-8037 boundary invariants (state >= 0, remaining +
  reservoir <= gasLimit) at the halt/fail/collision read points and in
  RefundStateGas, replacing the saturating defense removed with the rework
- restore Eth_get_logs_enforces_max_block_depth (accidentally dropped in the
  master RPC reconciliation; the MaxBlockDepth guard is live)
- de-circularize the 7702 SpentGas expectation (constants instead of the
  production intrinsic calculator) and add an exact floor==standard tie case
  for EIP-7981
- refresh stale 4500-era totals/comments (TX_BASE is 12000), the 8038
  placeholder remark, and the 8037 inclusion-rule assertion message
- drop unused Eip8038IntrinsicRecipientGas params, redundant (ulong) casts on
  ulong constants, and the lazy BlockValidator ecdsa init

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* review fixes: extend request-type constants for EIP-8282, fail descriptively on builder-request decode

- MaxRequestsCount 3 -> 5 (deposit/withdrawal/consolidation + builder deposit/exit)
- GetFlatDecodedRequests throws a descriptive NotSupportedException for the
  EIP-8282 types the tests-zkevm v0.5.0 stateless input format cannot represent,
  instead of an opaque unknown-type error
- drop the stale length<=3 TODO

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* review fixes: keep AuRa contract gas limit validation strict

- revert the IsGasLimitValid parent-delta acceptance: the check only runs on the
  pre-merge AuRa path where no targetGasLimit exists, so loosening it widened
  legacy block acceptance for no benefit
- drop the redundant single-arg GetGasLimit stub in TestingRpcModuleTests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: map InvalidTxChainId/EIP-155 sig failure to INVALID_CHAINID (v6.1.1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: decode invalid-tx state tests from txbytes (v6.1.1 expectException)

v6.1.1 state tests carry expectException plus the actual signed tx in txbytes.
The template tx is re-signed pre-EIP-155, which cannot reproduce signature-level
invalidity (test_invalid_chain_id executes as a valid tx and diverges from the
expected post state). Decode the fixture's raw tx for such entries so validation
rejects it; undecodable txbytes fall back to the template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: relax EIP-8037 debug asserts to the true signed invariants

The [checked] CI variant surfaced two over-strict asserts: the state reservoir
can legitimately end a tx negative (net child spill) with the ulong wrap still
producing the correct signed spentGas, and system calls can halt with
preRefundGas 0 while intrinsic state gas remains (their GasConsumed is
discarded). Assert the signed non-negative-spend invariant instead, and gate
the halt-path block-gas assert on non-system transactions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: drop end-of-tx gas assert that a parallel-test race trips flakily

A pre-existing Nethermind.Evm.Test parallel race (~1 in 6 full-suite runs)
intermittently violates the end-of-tx invariant from
Create2_redeploy_to_same_address_unblocked_after_self_destruct, SIGABRTing the
[checked] job. The halt/fail/collision asserts stay (validated clean across the
checked pyspec suite); a genuine wrap on this success path already fails
fixtures via receipts/state roots. Race tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables by spec instance, not on the spec object

The per-spec opcode tables were cached in IReleaseSpec.EvmInstructionsNoTrace/
Traced slots. OverridableReleaseSpec's getter fell back to the wrapped spec and
ReleaseSpecDecorator's setter wrote through to it, so wrappers with different
EVM flags (7708/8037/8246 test variants) shared one table with fork singletons —
first writer won, giving wrong opcode handlers (missing transfer logs, wrong
state-gas charges) depending on test order. Port master's fix (#12146): cache
tables in a ConcurrentDictionary keyed by spec instance (plain statics for the
single-fork zkEVM guest) and drop the IReleaseSpec slots.

Full Evm.Test suite: 10/10 clean (was ~5 of 6 runs failing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: restore the end-of-tx gas invariant assert

The parallel-test race that flakily violated it is fixed (opcode tables now
keyed by spec instance); 10/10 full checked Evm.Test runs clean with it live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: tighten EIP-8246 comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: move the v6.1.1 pyspec fixes off the EIP-8246 branch

The fixture bump and its harness fixes (INVALID_SIGNATURE_VRS/INVALID_CHAINID
mappings, txbytes decode for expectException state tests) are unrelated to
EIP-8246; they move to fix/zkevm-stateless-v050-v2 where the fixture/format
alignment lives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: pin EF fixtures v6.1.1 and align the harness with its new tests

Relocated from the EIP-8246 branch: the tests-glamsterdam-devnet@v6.1.1 bump,
the INVALID_SIGNATURE_VRS/INVALID_CHAINID error mappings for test_bad_v_r_s and
test_invalid_chain_id, and decoding expectException state-test txbytes so
signature-level invalidity survives conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: move the opcode-table cache fix to the stateless branch; group 8246 with Amsterdam EIPs

The spec-instance opcode-table keying is test-infrastructure hardening
unrelated to EIP-8246; it moves to fix/zkevm-stateless-v050-v2. IsEip8246Enabled
now sits with the other Amsterdam EIP flags in the spec surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables weakly by spec instance

Relocated from the EIP-8246 branch and reworked per review: the per-spec-slot
cache let OverridableReleaseSpec fall back to (and ReleaseSpecDecorator write
through to) the wrapped fork singleton's table, so spec wrappers with different
EVM flags shared one first-writer-wins dispatch table (flaky wrong handlers in
parallel test runs). Tables are now keyed by spec instance in a
ConditionalWeakTable — unlike a strong-keyed map, entries for the per-request
decorator specs built by simulate/state-override RPC paths (WithoutEip3607/
WithoutEip158/ForSystemTransaction) are collected instead of retained forever.
The single-fork zkEVM guest caches in plain statics; the IReleaseSpec slots are
gone.

Full Evm.Test suite 8/8 clean (the pre-fix race flaked ~5 of 6 runs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: drop the Amsterdam EIP-8246 activation note

The flag is enabled one PR up (repricings, #12214) where the note is already gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: enable EIP-8246 in Amsterdam

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reconcile glamsterdam gas policy with master's #12146 foundation

Keep devnet-6 semantics (signed state dimension, EELS block/halt gas, 2780/8038
repricings) while adopting master's structural changes: tagged-cost Consume,
policy-computed data-copy/create/SSTORE consumers (8038-aware where priced),
UpdateMemoryCost over EvmPooledMemory, parameterless state-cost getters,
TryReserveChildGas, CombineBlockGas, the system-tx-processor seam with the
parallel flag, and the popped-address cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: restore witnessMode plumbing dropped by the master merge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style: expression-bodied state-cost test (IDE0022)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: aggressively inline the glamsterdam gas-policy interface defaults

Master's inlining guard test requires the attribute on every IGasPolicy
default/helper for no-dynamic-PGO regimes (NativeAOT zkEVM guest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: supply TargetGasLimit in the witness-capture FCUv4 payload build

PayloadAttributesV4 requires it as of the targetGasLimit change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: charge full requested gas for pre-EIP-150 child calls

The hand-ported TryReserveChildGas clamped the requested gas to the remaining
balance on the pre-63/64 branch; the spec charges the full request, so an
over-asking CALL exceptionally halts the caller (refundReset_Frontier/
Homestead and the early-fork pyspec chunks caught it). Now byte-identical to
master's implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: make EIP-2780 intrinsic gas state-independent

Per review agreement on #12118, the intrinsic must not read world state:
replace the draft's tiered recipient/value costs (dead-account, code,
access-list probes) with the spec's flat model, and drop the worldState
parameter from IntrinsicGasCalculator and IGasPolicy. Also compress
comments across the branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: remove unused usings after worldState removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: address re-review on repricings

- Enforce the EIP-2780 => EIP-7708 co-activation invariant in
  ChainSpecBasedSpecProvider (with regression test).
- Restore the MaxCallDepth capacity hint on the VM state stack.
- Route the inlined net-spill expressions through GetUnrefundedStateGasSpill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: trim comments and revert incidental type churn on repricings

Comments: drop devnet references and legacy gas values, compress
multi-line rationale to at most two lines, neutralise test names.
Tests: restore base-branch numeric types where the gas-policy port
changed them without need (Eip7928Tests, EthRpcModuleTests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: minimize the repricing diff against the base branch

Restore base-branch structure and spellings that the repricing did not
need: undo numeric-suffix and type churn in tests, keep the intrinsic-gas
helpers in IntrinsicGasCalculator (applying the EIP-2780/8038 changes
in place instead of duplicating them in IGasPolicy), restore the
ConsumeCreateGas/ConsumePrecompileGas policy hooks and the cached
IsTracingActions field, and drop dead members the PR introduced
(4-arg ConsumeDataCopyGas, ConsumeCodeDeposit, unused spill getters,
the unused GasValidationResult.IntrinsicGas field). Trim comments per
review guidance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop usings orphaned by the GasValidationResult field removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: align the BAL boundary tests with the base branch's ulong gas limits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: strip gas-constant comments and EELS references

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: revert constant-context long-to-ulong churn in tests

C# 14 implicitly converts constant long expressions to ulong, so the
base branch's const spellings still compile against the ulong builders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove comments

* chore: trim restating comments in the transaction processor

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy

* chore: minimize EIP-8282 diff vs base

Match existing SystemCall initializer style (drop UInt256.Zero and the
Nethermind.Int256 usings), align Eip8282TestConstants.Nonce with the
sibling test-constant files (ulong, no casts), and trim comments to the
why-only essentials.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: decide BAL-overlay account existence on effective state

AccountExists short-circuited on the parent reader, missing same-block
deletions (an account drained to zero by an earlier selfdestruct), and
treated any recorded prior balance/nonce change as existence even when
the change was to zero. Evaluate EIP-161 non-emptiness of the effective
state instead, so a later same-block CREATE2 over the address does not
wrongly refund EIP-8037 create-state gas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: name the stateless flat-encoded request-type count

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: cascade long through the state-gas dimension per review

Retype the state-gas constants to long so the signed dimension needs no
casts at its call sites (C# 14 constant conversions keep them usable in
ulong contexts), cascade long through the intrinsic state path and the
delegation-refund counters, and centralize the regular/state boundary
subtraction in IGasPolicy.GetPreRefundGas. Also move the EIP-8038 clear
refund to RefundOf, name the per-auth cost components, note the
EIP-7778 dependency of before-refund block gas, saturate the system-tx
block-gas subtraction, gate the validator's sender-recovery fallback on
EIP-2780, and fold the selfdestruct new-account charge into one
expression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: drop casts made redundant by the long state-gas constants

Collapse the system-transaction reservoir round-trip and remove the
now-unneeded casts in the state-gas tests; where NUnit compares boxed
values, pin the long-typed constants with long expectations instead of
casting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: type the state-byte constants long at the source

The byte-count constants feed only the signed state dimension, so
declaring them long removes every initializer cast; C# 14 constant
conversions keep the few ulong-context uses working unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove unneeded check

* fix(specs): BPO3 inherits BPO2, not Amsterdam

BPO forks are blob-parameter-only forks chained off BPO2, parallel to
Amsterdam (matching execution-spec-tests fork lineage). Inheriting
Amsterdam wrongly enabled EIP-7928 (and the rest of Amsterdam) on
BPO3/BPO4/BPO5, so BPO2->BPO3 transition blocks demanded a BAL hash
(MissingBlockLevelAccessListHash).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(pyspec): load BPO2->BPO3 and BPO3->BPO4 transition fixtures

tests-glamsterdam-devnet@v6.1.1 ships for_bpo2tobpo3attime15k and
for_bpo3tobpo4attime15k under both blockchain_tests and
blockchain_tests_engine, but Tests.cs stopped at Bpo2ToAmsterdam, so
these transition fixtures were never run in CI - which is how the BPO3
fork-lineage bug went unnoticed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(pyspec): load TangerineWhistle and SpuriousDragon fixtures

tests-glamsterdam-devnet ships for_tangerinewhistle and
for_spuriousdragon under blockchain_tests and state_tests, but Tests.cs
had no fixture classes for them, so they never ran. Completes the
class-per-directory mapping: every for_* dir in the archive now has a
matching fixture class across all five fixture trees.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: pin the PayloadAttributesV4 SSZ field offsets to the spec order

A round-trip test cannot detect a reordered container; assert the
slot_number and target_gas_limit byte positions from the execution-apis
layout directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: inject execution-requests processor factory instead of witnessMode flag

Per review on #12217: BlockAccessListManager no longer knows about witness
mode; StatelessBlockProcessingEnv injects the stateless factory directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: refund NEW_ACCOUNT state gas on failed inline precompile calls

The ZK_EVM inline precompile path dropped the newAccountCharged flag, so
an EIP-8038 value CALL to a dead precompile that reverted or hard-failed
kept the up-front NEW_ACCOUNT state charge. Thread the flag through
InlinePrecompileCall and mirror the mainline refunds. Also trim comments
across the diff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: drop the 2780/7708 co-activation guard test

The guard itself was removed (EIP interdependencies are by convention
documented, not enforced in ChainSpecBasedSpecProvider); the XML remark
on IsEip2780Enabled keeps the dependency documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy chainspec test

* Update src/Nethermind/Nethermind.Consensus.AuRa/AuRaContractGasLimitOverride.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

* Update src/Nethermind/Nethermind.Consensus.Test/PayloadAttributesValidateTests.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

* Update src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszCodecTests.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

---------

Co-authored-by: Marc Harvey-Hill <10379486+Marchhill@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
* test: update pyspec fixtures to glamsterdam-devnet v6.0.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: ignore ZkEVM stateless suite (fixtures target bal-devnet-7)

The ZkEvmBlockchainTests stateless suite runs Nethermind.Stateless.Executor
against the pinned tests-zkevm@v0.4.1 archive, which is generated against
bal-devnet-7 (tests-bal@v7.2.0). Its EIP-7928 block-access-list semantics differ
from the devnet-6 (tests-glamsterdam-devnet@v6.0.0) rules this stack implements,
so stateless execution rejects every fixture block on a BAL mismatch
(StatelessValidationResult.IsSuccess=0) — the full Pyspec [Sequential]/engine
shards each failed only on the *_stateless_block_N cases.

Mark the suite [Ignore] until the client tracks bal-devnet-7 (or the archive is
repinned to devnet-6). No production code is affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump Glamsterdam devnet Pyspec fixtures to v6.1.0

Run the Ethereum.Blockchain.Pyspec.Test suite against the
tests-glamsterdam-devnet@v6.1.0 fixture release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: re-enable zkEVM stateless fixtures on tests-zkevm@v0.5.0

The zkVM stateless suite was disabled because the pinned archive
(tests-zkevm@v0.4.1) was generated against bal-devnet-7, whose EIP-7928
BAL semantics differ from the devnet-6 rules this stack implements.

tests-zkevm@v0.5.0 is generated against tests-glamsterdam-devnet@v6.1.0
(the devnet-6 fixtures this stack tracks), so the mismatch is resolved.
Bump the archive version and drop the [Ignore].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: update Pyspec fixtures to Glamsterdam devnet-6 (v6.1.0) and zkEVM v0.5.0

Point the default Pyspec fixture archive at tests-glamsterdam-devnet@v6.1.0
and the zkEVM stateless preview suite at tests-zkevm@v0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: implement EIP-8246 (Remove SELFDESTRUCT Burn)

Removes the residual ETH-burn cases left by EIP-6780:

- A self-targeting SELFDESTRUCT now moves no ETH and emits no log,
  regardless of whether the account was created in the same transaction.
- At transaction finalization, accounts marked for destruction keep their
  balance: storage and code are cleared and the nonce is reset to 0. A
  resulting zero-balance account is still removed as empty per EIP-161,
  matching the spec and keeping CREATE2 redeployment unblocked.

Wires a new IsEip8246Enabled flag through IReleaseSpec / ReleaseSpec /
decorators / chainspec (Eip8246TransitionTimestamp) and enables it in the
Amsterdam fork. Adds Eip8246Tests covering same-transaction self-destruct
to self/other, post-destruct funding, the zero-balance empty-account case,
and the unchanged not-in-same-tx no-op, each pinned with EIP on and off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: cover deferred finalization path; address review feedback

- Add an EIP-8037 + EIP-7708 fixture dimension so every EIP-8246 scenario
  also runs through the deferred FinalizeDestroyedAccount path (as in
  Amsterdam), covering the balance-preservation logic there.
- Add a CREATE2 redeployment test: a factory re-creates a self-destructed
  child at the same address across transactions, verifying the nonce reset
  keeps redeployment unblocked and the preserved balance accumulates.
- Report the destroy refund to the tracer in the deferred path, matching
  the inline path.
- Document the pre-existing Burn-vs-SelfDestruct log distinction between the
  post-fee and pre-fee finalization paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: do not enable EIP-8246 in Amsterdam fork

EIP-8246 is a Draft and is not part of the EEST `for_amsterdam` conformance
fixtures. Enabling it in the Amsterdam fork changed SELFDESTRUCT behaviour
for that fork, diverging from the reference post-states and failing the
Pyspec tests across all shards.

Keep the full implementation and spec/chainspec plumbing so the EIP can be
activated via the Eip8246Transition chainspec parameter once it is scheduled,
but leave it disabled in the named forks. Unit tests toggle the flag directly
via OverridableReleaseSpec, so coverage is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: assert storage clearing in EIP-8246 self-destruct tests

Address PR review comments:
- The self-destruct-to-self contract now writes storage slot 0 before
  SELFDESTRUCT so AssertBalanceOnly can verify storage is wiped on the
  surviving balance-only account.
- Clarify the self-targeting SELFDESTRUCT short-circuit comment to
  distinguish the EIP-6780 pure no-op case from the EIP-8246 burn-removal
  case (account in destroy list, finalization still clears code/storage).

Note: the deferred finalization path also gained a tracer.ReportRefund
call to match the inline path; that is an incidental tracer fix unrelated
to EIP-8246 semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: tidy EIP-8246 self-destruct test per review

- Rename the self-destruct-to-self fixtures to _sstoreThenSelfDestructToSelf
  so the name reflects the SSTORE-then-SELFDESTRUCT bytecode.
- Wrap AssertBalanceOnly in Assert.EnterMultipleScope so every mismatch is
  surfaced in one run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP repricings and existing-EIP updates (devnet-6)

Combined branch for the Glamsterdam devnet-6 repricing/update EIPs:
EIP-2780, EIP-8037, EIP-8038, plus existing-EIP (7702/7708/7928/7954/7981)
test and behavior updates. Folds in the EIP-8037 halt-gas-accounting fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: EIP-8282 builder execution requests (devnet-6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: targetGasLimit support in PayloadAttributesV4 (devnet-6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: align stateless executor with tests-zkevm@v0.5.0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* wip(test): begin ulong test-suite port for master #11937 (incomplete)

Partial long->ulong adaptation of the glamsterdam EIP test files to master's
type-unified gas API. Test projects do not yet build; tracked follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong DestroyRefund for tracer refund (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test-build): cast ulong 8282 predeploy nonce in TestBlockchain (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(8037): revert state-gas dimension to signed long

Master #11937 ("unify types with Geth") changed all gas from long to
ulong (uint64). This is correct for the regular gas dimension, but the
EIP-8037 state-gas dimension needs a *signed* reservoir: during nested
frame spill merges (RestoreChildStateGas / RestoreChildStateGasOnHalt /
RevertRefundToHalt) the StateReservoir goes transiently negative before
recovering. As ulong it underflowed to ~2^64, producing wrong spentGas
on halts (e.g. 12000 instead of 16777216) and 54 EIP-8037 spill/halt/
reservoir fixture failures.

Revert the state-gas dimension (StateReservoir, StateGasUsed,
StateGasSpill*, intrinsic/create/new-account/per-auth/code-deposit/
storage state costs, and their IGasPolicy signatures, VmState fields,
VirtualMachine refund locals, and TransactionProcessor halt/block-gas
locals) back to signed long. Regular gas Value/GetRemainingGas/
UpdateGas/Consume/TryConsume and GasConsumed stay ulong; cast at the
regular<->state boundary (all state values are non-negative there).

Fixes test_nested_failure_resets_to_tx_reservoir (was 54 failed -> 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port unit tests to master #11937 ulong gas API

Master #11937 unified the gas API from long to ulong (regular gas) while
the glamsterdam state-gas dimension stays signed long. This ports the
test suite to compile and pass against the merged API:

- Evm.Test EIP test files (8037/8038/2780/7928/7981/7954/8246, intrinsic,
  block-gas-inclusion): gas locals/consts/tuples to ulong; state-gas
  values kept long with (long) casts on the shared ulong GasCostOf.*
  constants at the state-dimension boundary; FromLong -> FromULong;
  ConstantsTestCases + expected results to ulong.
- TestAllTracerWithOutput.ActionTrace.Gas long -> ulong (ReportAction gas).
- JsonRpc.Test EthRpcModule/EstimateGas: RpcConfig.GasCap and Header.GasLimit
  are ulong(?) now; floor-cost locals to ulong; ToTransaction gasCap and
  WithNonce/WithGasLimit args cast to ulong(?).
- Blockchain.Test (block-gas integration, 7702, simple-transfer, block
  validator): WithGasLimit/gas locals to ulong; count*cost casts.
- Merge.Plugin.Test: PayloadAttributes.TargetGasLimit + GetGasLimit(ulong?).
- GetNonce() returns ulong: Is.EqualTo(UInt256.Zero/One) -> 0UL/1UL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: adopt master's RPC behavior for JsonRpc tests

The master merge (#11937 + RPC hardening) changed RPC behavior that the
glamsterdam test files (kept --ours during the merge) still asserted the
old way. Reconcile to master's behavior:

- Filter-log IDs are now parsed as strict hex: leading zeros are rejected
  ("0x05"/"0x01" -> "0x5"/"0x1"; UInt256.ToString("X") padded overflow id
  needs TrimStart('0')). Otherwise the id fails hex parsing (-32602)
  before reaching the not-found path.
- eth_getBlockAccessListByNumber takes a hex block-parameter string, not a
  bare int (3 -> "0x3", 100 -> "0x64"). The by_number expected BAL keeps
  the glamsterdam EIP-8282 predeploy entries (…0f008282/…d9008282) which
  master's bal-devnet-6 lacks.
- Error message text: "Invalid," -> "transaction invalid,";
  "InsufficientFunds" -> TxErrorMessages.InsufficientFundsForGas text;
  estimateGas transfer "insufficient sender balance" -> "insufficient funds".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port target-gas-layer gas-limit/Engine tests to ulong API

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: port EIP-8246 test BlockNumber override to ulong (master #11937)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: bump EF fixtures to tests-glamsterdam-devnet@v6.1.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: remove unnecessary using after SaturatingSub revert (IDE0005)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: map InvalidTxSignature to INVALID_SIGNATURE_VRS for v6.1.1 test_bad_v_r_s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* review fixes: assert 8037 gas invariants, restore getLogs depth test, fix stale docs

- Debug.Assert the EIP-8037 boundary invariants (state >= 0, remaining +
  reservoir <= gasLimit) at the halt/fail/collision read points and in
  RefundStateGas, replacing the saturating defense removed with the rework
- restore Eth_get_logs_enforces_max_block_depth (accidentally dropped in the
  master RPC reconciliation; the MaxBlockDepth guard is live)
- de-circularize the 7702 SpentGas expectation (constants instead of the
  production intrinsic calculator) and add an exact floor==standard tie case
  for EIP-7981
- refresh stale 4500-era totals/comments (TX_BASE is 12000), the 8038
  placeholder remark, and the 8037 inclusion-rule assertion message
- drop unused Eip8038IntrinsicRecipientGas params, redundant (ulong) casts on
  ulong constants, and the lazy BlockValidator ecdsa init

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* review fixes: extend request-type constants for EIP-8282, fail descriptively on builder-request decode

- MaxRequestsCount 3 -> 5 (deposit/withdrawal/consolidation + builder deposit/exit)
- GetFlatDecodedRequests throws a descriptive NotSupportedException for the
  EIP-8282 types the tests-zkevm v0.5.0 stateless input format cannot represent,
  instead of an opaque unknown-type error
- drop the stale length<=3 TODO

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* review fixes: keep AuRa contract gas limit validation strict

- revert the IsGasLimitValid parent-delta acceptance: the check only runs on the
  pre-merge AuRa path where no targetGasLimit exists, so loosening it widened
  legacy block acceptance for no benefit
- drop the redundant single-arg GetGasLimit stub in TestingRpcModuleTests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: map InvalidTxChainId/EIP-155 sig failure to INVALID_CHAINID (v6.1.1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: decode invalid-tx state tests from txbytes (v6.1.1 expectException)

v6.1.1 state tests carry expectException plus the actual signed tx in txbytes.
The template tx is re-signed pre-EIP-155, which cannot reproduce signature-level
invalidity (test_invalid_chain_id executes as a valid tx and diverges from the
expected post state). Decode the fixture's raw tx for such entries so validation
rejects it; undecodable txbytes fall back to the template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: relax EIP-8037 debug asserts to the true signed invariants

The [checked] CI variant surfaced two over-strict asserts: the state reservoir
can legitimately end a tx negative (net child spill) with the ulong wrap still
producing the correct signed spentGas, and system calls can halt with
preRefundGas 0 while intrinsic state gas remains (their GasConsumed is
discarded). Assert the signed non-negative-spend invariant instead, and gate
the halt-path block-gas assert on non-system transactions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: drop end-of-tx gas assert that a parallel-test race trips flakily

A pre-existing Nethermind.Evm.Test parallel race (~1 in 6 full-suite runs)
intermittently violates the end-of-tx invariant from
Create2_redeploy_to_same_address_unblocked_after_self_destruct, SIGABRTing the
[checked] job. The halt/fail/collision asserts stay (validated clean across the
checked pyspec suite); a genuine wrap on this success path already fails
fixtures via receipts/state roots. Race tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables by spec instance, not on the spec object

The per-spec opcode tables were cached in IReleaseSpec.EvmInstructionsNoTrace/
Traced slots. OverridableReleaseSpec's getter fell back to the wrapped spec and
ReleaseSpecDecorator's setter wrote through to it, so wrappers with different
EVM flags (7708/8037/8246 test variants) shared one table with fork singletons —
first writer won, giving wrong opcode handlers (missing transfer logs, wrong
state-gas charges) depending on test order. Port master's fix (#12146): cache
tables in a ConcurrentDictionary keyed by spec instance (plain statics for the
single-fork zkEVM guest) and drop the IReleaseSpec slots.

Full Evm.Test suite: 10/10 clean (was ~5 of 6 runs failing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: restore the end-of-tx gas invariant assert

The parallel-test race that flakily violated it is fixed (opcode tables now
keyed by spec instance); 10/10 full checked Evm.Test runs clean with it live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: tighten EIP-8246 comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: move the v6.1.1 pyspec fixes off the EIP-8246 branch

The fixture bump and its harness fixes (INVALID_SIGNATURE_VRS/INVALID_CHAINID
mappings, txbytes decode for expectException state tests) are unrelated to
EIP-8246; they move to fix/zkevm-stateless-v050-v2 where the fixture/format
alignment lives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: pin EF fixtures v6.1.1 and align the harness with its new tests

Relocated from the EIP-8246 branch: the tests-glamsterdam-devnet@v6.1.1 bump,
the INVALID_SIGNATURE_VRS/INVALID_CHAINID error mappings for test_bad_v_r_s and
test_invalid_chain_id, and decoding expectException state-test txbytes so
signature-level invalidity survives conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: move the opcode-table cache fix to the stateless branch; group 8246 with Amsterdam EIPs

The spec-instance opcode-table keying is test-infrastructure hardening
unrelated to EIP-8246; it moves to fix/zkevm-stateless-v050-v2. IsEip8246Enabled
now sits with the other Amsterdam EIP flags in the spec surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: key opcode dispatch tables weakly by spec instance

Relocated from the EIP-8246 branch and reworked per review: the per-spec-slot
cache let OverridableReleaseSpec fall back to (and ReleaseSpecDecorator write
through to) the wrapped fork singleton's table, so spec wrappers with different
EVM flags shared one first-writer-wins dispatch table (flaky wrong handlers in
parallel test runs). Tables are now keyed by spec instance in a
ConditionalWeakTable — unlike a strong-keyed map, entries for the per-request
decorator specs built by simulate/state-override RPC paths (WithoutEip3607/
WithoutEip158/ForSystemTransaction) are collected instead of retained forever.
The single-fork zkEVM guest caches in plain statics; the IReleaseSpec slots are
gone.

Full Evm.Test suite 8/8 clean (the pre-fix race flaked ~5 of 6 runs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: drop the Amsterdam EIP-8246 activation note

The flag is enabled one PR up (repricings, #12214) where the note is already gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: enable EIP-8246 in Amsterdam

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: reconcile glamsterdam gas policy with master's #12146 foundation

Keep devnet-6 semantics (signed state dimension, EELS block/halt gas, 2780/8038
repricings) while adopting master's structural changes: tagged-cost Consume,
policy-computed data-copy/create/SSTORE consumers (8038-aware where priced),
UpdateMemoryCost over EvmPooledMemory, parameterless state-cost getters,
TryReserveChildGas, CombineBlockGas, the system-tx-processor seam with the
parallel flag, and the popped-address cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: restore witnessMode plumbing dropped by the master merge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style: expression-bodied state-cost test (IDE0022)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: aggressively inline the glamsterdam gas-policy interface defaults

Master's inlining guard test requires the attribute on every IGasPolicy
default/helper for no-dynamic-PGO regimes (NativeAOT zkEVM guest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: supply TargetGasLimit in the witness-capture FCUv4 payload build

PayloadAttributesV4 requires it as of the targetGasLimit change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: charge full requested gas for pre-EIP-150 child calls

The hand-ported TryReserveChildGas clamped the requested gas to the remaining
balance on the pre-63/64 branch; the spec charges the full request, so an
over-asking CALL exceptionally halts the caller (refundReset_Frontier/
Homestead and the early-fork pyspec chunks caught it). Now byte-identical to
master's implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: make EIP-2780 intrinsic gas state-independent

Per review agreement on #12118, the intrinsic must not read world state:
replace the draft's tiered recipient/value costs (dead-account, code,
access-list probes) with the spec's flat model, and drop the worldState
parameter from IntrinsicGasCalculator and IGasPolicy. Also compress
comments across the branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: remove unused usings after worldState removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: address re-review on repricings

- Enforce the EIP-2780 => EIP-7708 co-activation invariant in
  ChainSpecBasedSpecProvider (with regression test).
- Restore the MaxCallDepth capacity hint on the VM state stack.
- Route the inlined net-spill expressions through GetUnrefundedStateGasSpill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: trim comments and revert incidental type churn on repricings

Comments: drop devnet references and legacy gas values, compress
multi-line rationale to at most two lines, neutralise test names.
Tests: restore base-branch numeric types where the gas-policy port
changed them without need (Eip7928Tests, EthRpcModuleTests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: minimize the repricing diff against the base branch

Restore base-branch structure and spellings that the repricing did not
need: undo numeric-suffix and type churn in tests, keep the intrinsic-gas
helpers in IntrinsicGasCalculator (applying the EIP-2780/8038 changes
in place instead of duplicating them in IGasPolicy), restore the
ConsumeCreateGas/ConsumePrecompileGas policy hooks and the cached
IsTracingActions field, and drop dead members the PR introduced
(4-arg ConsumeDataCopyGas, ConsumeCodeDeposit, unused spill getters,
the unused GasValidationResult.IntrinsicGas field). Trim comments per
review guidance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop usings orphaned by the GasValidationResult field removal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: align the BAL boundary tests with the base branch's ulong gas limits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: strip gas-constant comments and EELS references

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: revert constant-context long-to-ulong churn in tests

C# 14 implicitly converts constant long expressions to ulong, so the
base branch's const spellings still compile against the ulong builders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove comments

* chore: trim restating comments in the transaction processor

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy

* chore: minimize EIP-8282 diff vs base

Match existing SystemCall initializer style (drop UInt256.Zero and the
Nethermind.Int256 usings), align Eip8282TestConstants.Nonce with the
sibling test-constant files (ulong, no casts), and trim comments to the
why-only essentials.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: decide BAL-overlay account existence on effective state

AccountExists short-circuited on the parent reader, missing same-block
deletions (an account drained to zero by an earlier selfdestruct), and
treated any recorded prior balance/nonce change as existence even when
the change was to zero. Evaluate EIP-161 non-emptiness of the effective
state instead, so a later same-block CREATE2 over the address does not
wrongly refund EIP-8037 create-state gas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: name the stateless flat-encoded request-type count

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: cascade long through the state-gas dimension per review

Retype the state-gas constants to long so the signed dimension needs no
casts at its call sites (C# 14 constant conversions keep them usable in
ulong contexts), cascade long through the intrinsic state path and the
delegation-refund counters, and centralize the regular/state boundary
subtraction in IGasPolicy.GetPreRefundGas. Also move the EIP-8038 clear
refund to RefundOf, name the per-auth cost components, note the
EIP-7778 dependency of before-refund block gas, saturate the system-tx
block-gas subtraction, gate the validator's sender-recovery fallback on
EIP-2780, and fold the selfdestruct new-account charge into one
expression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: drop casts made redundant by the long state-gas constants

Collapse the system-transaction reservoir round-trip and remove the
now-unneeded casts in the state-gas tests; where NUnit compares boxed
values, pin the long-typed constants with long expectations instead of
casting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: type the state-byte constants long at the source

The byte-count constants feed only the signed state dimension, so
declaring them long removes every initializer cast; C# 14 constant
conversions keep the few ulong-context uses working unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* remove unneeded check

* fix(specs): BPO3 inherits BPO2, not Amsterdam

BPO forks are blob-parameter-only forks chained off BPO2, parallel to
Amsterdam (matching execution-spec-tests fork lineage). Inheriting
Amsterdam wrongly enabled EIP-7928 (and the rest of Amsterdam) on
BPO3/BPO4/BPO5, so BPO2->BPO3 transition blocks demanded a BAL hash
(MissingBlockLevelAccessListHash).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(pyspec): load BPO2->BPO3 and BPO3->BPO4 transition fixtures

tests-glamsterdam-devnet@v6.1.1 ships for_bpo2tobpo3attime15k and
for_bpo3tobpo4attime15k under both blockchain_tests and
blockchain_tests_engine, but Tests.cs stopped at Bpo2ToAmsterdam, so
these transition fixtures were never run in CI - which is how the BPO3
fork-lineage bug went unnoticed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(pyspec): load TangerineWhistle and SpuriousDragon fixtures

tests-glamsterdam-devnet ships for_tangerinewhistle and
for_spuriousdragon under blockchain_tests and state_tests, but Tests.cs
had no fixture classes for them, so they never ran. Completes the
class-per-directory mapping: every for_* dir in the archive now has a
matching fixture class across all five fixture trees.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop comments

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: pin the PayloadAttributesV4 SSZ field offsets to the spec order

A round-trip test cannot detect a reordered container; assert the
slot_number and target_gas_limit byte positions from the execution-apis
layout directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: inject execution-requests processor factory instead of witnessMode flag

Per review on #12217: BlockAccessListManager no longer knows about witness
mode; StatelessBlockProcessingEnv injects the stateless factory directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: refund NEW_ACCOUNT state gas on failed inline precompile calls

The ZK_EVM inline precompile path dropped the newAccountCharged flag, so
an EIP-8038 value CALL to a dead precompile that reverted or hard-failed
kept the up-front NEW_ACCOUNT state charge. Thread the flag through
InlinePrecompileCall and mirror the mainline refunds. Also trim comments
across the diff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: drop the 2780/7708 co-activation guard test

The guard itself was removed (EIP interdependencies are by convention
documented, not enforced in ChainSpecBasedSpecProvider); the XML remark
on IsEip2780Enabled keeps the dependency documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tidy chainspec test

* Fix state gas spill with negative reservoir

* Update src/Nethermind/Nethermind.Consensus.AuRa/AuRaContractGasLimitOverride.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

* Update src/Nethermind/Nethermind.Consensus.Test/PayloadAttributesValidateTests.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

* Update src/Nethermind/Nethermind.Merge.Plugin.Test/SszRest/SszCodecTests.cs

Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>

---------

Co-authored-by: Marc Harvey-Hill <10379486+Marchhill@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Marc <Marchhill@users.noreply.github.com>
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
Pins the pyspec/EEST fixtures (tests-glamsterdam-devnet@v6.1.1,
tests-zkevm@v0.5.0) across the NUnit constants and the nethtest
workflow, adds state-test progress reporting and watchdog thread-stack
diagnostics, and warms up Rlp's static initializer to prevent a
class-init deadlock in the parallel state-test parse phase.
@Marchhill
Marchhill force-pushed the glamsterdam-devnet-6-eips branch from 148a794 to 86e1d28 Compare July 10, 2026 09:55
@LukaszRozmej
LukaszRozmej merged commit 96ed40d into master Jul 10, 2026
504 checks passed
@LukaszRozmej
LukaszRozmej deleted the glamsterdam-devnet-6-eips branch July 10, 2026 10:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants