feat(tests): EIP-8037 additional state gas coverage#2718
Merged
spencer-tb merged 11 commits intoethereum:eips/amsterdam/eip-8037from Apr 20, 2026
Conversation
cc2cd47 to
44c4c15
Compare
9d29dcf to
25e2a3e
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## eips/amsterdam/eip-8037 #2718 +/- ##
==========================================================
Coverage ? 86.27%
==========================================================
Files ? 599
Lines ? 37156
Branches ? 3803
==========================================================
Hits ? 32058
Misses ? 4530
Partials ? 568
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
44c4c15 to
de5bf67
Compare
656ca32 to
b9b80f8
Compare
kclowes
approved these changes
Apr 20, 2026
Contributor
kclowes
left a comment
There was a problem hiding this comment.
This LGTM!
There are a few related edge cases that I will put up in another PR, but nothing major or that should be blocking at all. Nice work!
fselmo
approved these changes
Apr 20, 2026
Contributor
fselmo
left a comment
There was a problem hiding this comment.
lgtm. Just minor readability nit we can always clean up later. 🚢
82374fe to
4dca651
Compare
f5da8ef
into
ethereum:eips/amsterdam/eip-8037
17 checks passed
spencer-tb
added a commit
to spencer-tb/execution-specs
that referenced
this pull request
Apr 21, 2026
spencer-tb
added a commit
to spencer-tb/execution-specs
that referenced
this pull request
Apr 21, 2026
spencer-tb
added a commit
that referenced
this pull request
Apr 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🗒️ Description
Revives the state gas test coverage from the closed PR #2639 and closes gaps surfaced by the evmone mutation testing report on that same PR from @chfast.
Most of the tests originated during bal-devnet-3 client testing, Maria's state gas accounting review, and spec reviews. They live on
feat/eip-8037-tests-devnet3andfeat/eip-8037-additional-testsand were bundled into #2639 but never landed. The seven spec PRs that did merge since (#2689, #2698, #2703, #2704, #2707, #2711, plus PR #2646 and PR #2725) invalidated some of the originals (inverted premises, duplicates) and left a coverage gap for the rest, which this PR closes.Devnet-3 client bug regressions
Two client bugs were discovered during bal-devnet-3 testing. Regression tests:
f4c8b36, cc @daniellehrner @jochem-brouwer). When a child frame spilled state gas intogas_left, then failed, then the parent hit an exception halt at the top level, Besu was incorrectly consuming the restored reservoir instead of refunding it to the sender.test_top_level_halt_preserves_restored_reservoirports the regression withchild_termination * reservoir_deltaparametrization.test_inner_create_state_gas_persists_on_failureasserted the parentsGAS_NEW_ACCOUNTcharge for an inner CREATE must NOT be refunded on child failure. PR feat(spec-specs, tests): EIP-8037 - CREATE failure refunds state gas to reservoir #2704 subsequently changed the spec to do exactly what geth was doing (refund on failure), inverting the original test's premise. PR feat(spec-specs, tests): EIP-8037 - CREATE failure refunds state gas to reservoir #2704's own refund tests cover the non-creation-factory case,test_inner_create_fail_refunds_in_creation_txfills the creation tx gap.Access list gas classification
test_access_list_gas_is_regular_not_state(EIP-2930 access list intrinsic must stay on the regular dimension, parametrized over list size and keys per entry), andtest_access_list_warm_savings_stay_regular(warm-access savings must stay on regular, catches clients crediting the cold to warm delta to state gas). cc @MariusVanDerWijdenBlock 2D gas accounting edge cases
test_tx_rejected_when_regular_gas_exceeds_block_limit_small(tight boundary case complementing PR feat(spec-specs, tests): EIP-8037 - per-dimension block gas limit check at tx inclusion #2703 tests, cc @kclowes),test_block_2d_gas_tx_gas_limit_exceeds_regular_remaining(the inclusion check usesmin(TX_MAX_GAS_LIMIT, tx.gas - intrinsic.state)not the rawtx.gas_limit, cc @jwasinger),test_receipt_cumulative_differs_from_header_gas_used(2Dheader.gas_usedcan diverge from 1D receiptcumulative_gas_usedwhen state dominates),test_failed_create_tx_state_gas_dominates(creation tx with tight gas and REVERT/halt initcode where state dominates the header).Initcode size validation ordering
Ports the initcode size before state gas ordering regression. cc @chfast
test_oversized_initcode_tx_no_state_gas(creation tx path)test_oversized_initcode_opcode_no_state_gas(CREATE/CREATE2 opcode path)Reservoir preservation and CALLCODE edge cases
test_top_level_halt_preserves_restored_reservoir(the Besu bug regression above),test_callcode_value_no_new_account_state_gas(CALLCODE transfers value to self, never creates a new account),test_create_oog_during_state_gas_charge(inner CREATE OOGs on the state gas charge itself; parent reservoir is restored and subsequent SSTORE still succeeds).Creation-tx compositions
test_selfdestruct_in_create_tx_initcode(creation-tx initcode SELFDESTRUCTs to a new beneficiary; the same-tx refund cancels itsGAS_NEW_ACCOUNTcharge),test_inner_create_succeeds_code_deposit_state_gas(creation tx with an inner CREATE that succeeds and deploys code; parametrized overouter_outcome × create_opcode).Nested CREATE fail and deep-recursion
test_nested_create_fail_parent_revert_state_gas(two-layer refund: caller to factory to inner CREATE failure to factory REVERTs or STOPs, parametrized overchild_failure * parent_reverts * create_opcode),test_create_stack_depth_state_gas_consumed(deep-recursion robustness; CALLs self until gas exhausts, EIP-150 63/64 caps effective depth well below the stack limit; outermost SSTORE probe verifies the reservoir threaded through),test_inner_create_fail_refunds_in_creation_tx(geth bug regression, rewritten for the post PR feat(spec-specs, tests): EIP-8037 - CREATE failure refunds state gas to reservoir #2704 spec change).Mutation testing regression tests
Four from @chfast's evmone mutation testing report on the closed PR, plus one from a local mutation scan against the current spec:
test_call_new_account_no_regular_account_creation_cost(pre-Amsterdam25_000regularACCOUNT_CREATION_COSTremoval for CALL-to-new-account)test_selfdestruct_new_beneficiary_no_regular_account_creation_cost(same 25k regular charge removal, SELFDESTRUCT variant)test_child_failure_refunds_state_gas_to_reservoir_not_gas_left(incorporate_child_on_errorrestores tostate_gas_left, notgas_left)test_create_collision_burned_gas_counted_in_block_regular(collision-burnedcreate_message_gasmust count towardblock_regular_gas_used)test_create_selfdestruct_code_deposit_refund_header_check(same-tx CREATE+SELFDESTRUCT refund includes the code-length term; the existing test only asserts the account is gone, not that the refund landed at the block level)Each was validated by injecting the target mutation into the spec and confirming the test fails under the bug.
Closed PR tests not ported and why
Six tests from the closed PRs original set are intentionally dropped:
test_failed_create_opcode_state_gas_dominatestest_create_child_{revert,halt}_refunds_state_gas+test_create_code_deposit_oog_refunds_state_gas. Premise also inverted by PR #2704's refund.test_inner_create_state_gas_persists_on_failuretest_inner_create_fail_refunds_in_creation_tx.test_create_nonce_overflow_state_gas_consumedtest_create_silent_failure_refunds_state_gas[nonce_overflow]. Premise also inverted.test_create2_collision_state_gas_block_accountingtest_create_collision_refunds_state_gas. Premise inverted.test_create_selfdestruct_same_tx_no_state_gas_refundtest_call_value_to_selfdestructed_same_tx_account(test_state_gas_selfdestruct.pyvariant)🔗 Related Issues or PRs
Closed PR whose test set that this PR revives: #2639.
✅ Checklist
just statictype(scope):.