Glamsterdam devnet 6 eips#12117
Conversation
|
Claude finished @Marchhill's task in 1m 14s —— View job Review
The change is a straightforward two-line constant update, bumping the pyspec test fixture reference from Medium — Three test CI failures on the June 22 commitThe previous CI run (triggered on June 22 before the upstream merge) shows three failures:
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 unfilledThe 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 ( |
5ff5943 to
eb7d28d
Compare
EVM Opcode Benchmark DiffAggregated runs: base=3, pr=3 Regressions (2)
Improvements (2)
|
|
Claude finished @Marchhill's task in 11m 6s —— View job PR Review — Glamsterdam devnet-6 EIPs
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
Medium — Asymmetric clamp in
|
|
@claude will adress comments in follow up PR |
|
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:
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. |
ecdaffe to
2c6fd16
Compare
0c881cd to
148a794
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
…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.
148a794 to
86e1d28
Compare
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?
Testing
Requires testing
If yes, did you write tests?
Notes on testing
Covered by the EF
tests-glamsterdam-devnetv6.1.1 fixtures (state/blockchain/engine) and unit tests; stateless execution covered by thetests-zkevmv0.5.0 fixtures.Documentation
Requires documentation update
Requires explanation in Release Notes
References