Skip to content

eip-8037: refund execution state gas on top-level failure#2609

Open
qu0b wants to merge 21 commits intoethereum:eips/amsterdam/eip-8037from
qu0b:qu0b/eip8037-refund-state-gas-top-level
Open

eip-8037: refund execution state gas on top-level failure#2609
qu0b wants to merge 21 commits intoethereum:eips/amsterdam/eip-8037from
qu0b:qu0b/eip8037-refund-state-gas-top-level

Conversation

@qu0b
Copy link
Copy Markdown
Contributor

@qu0b qu0b commented Apr 1, 2026

Summary

Note this is a consideration for bal-devnet-4 and requires more discussion async based on EIPs#11476.

The opposite of #2595. Where #2595 tests that state gas IS counted at the top level on failure (#11468), this PR tests that state gas is NOT counted (#11476) — the parent frame refunds state gas just like child frames do.

Changes

fork.py: On top-level error, move state_gas_used back into state_gas_left and reset to zero — mirroring incorporate_child_on_error.

test_top_level_state_gas_refund.py: 2-tx blockchain test at 100M:

  • TX1: deploys 14 KiB contract → state gas becomes the binding dimension
  • TX2: failing CREATE whose initcode does CALL to new account then returns oversized code

The execution state gas from TX2 (GAS_NEW_ACCOUNT = 112 * cpsb = 131,488) is the delta between the two spec interpretations:

Spec change: ethereum/EIPs#11476

Fill results

  • EELS fill: PASS (4/4)
  • Fixtures differ from unpatched EELS by exactly GAS_NEW_ACCOUNT (131,488)

🤖 Generated with Claude Code

spencer-tb and others added 20 commits March 17, 2026 11:07
…se (ethereum#2363)

* feat(spec-specs): update EIP-8037 to match latest spec revision

* feat(tests): add EIP-8037 state creation gas cost increase tests
Co-authored-by: Ben Adams <thundercat@illyriad.co.uk>
Add sstore_state_gas(), code_deposit_state_gas(), and create_state_gas()
calculator methods to Fork. Replace Spec constants and manual gas
arithmetic across all EIP-8037 tests with dynamic fork method calls.
Remove redundant Op.STOP, hardcoded numbers from docstrings, and add
fork: Fork parameter to all test functions that use fork methods.
Test CREATE with max initcode size using proper regular/state gas
split via the reservoir. Verifies gas boundary behavior with EIP-8037
two-dimensional metering.
Align EIP-8037 gas constant references with upstream renames:
- GAS_STORAGE_UPDATE → GAS_COLD_STORAGE_WRITE
- GAS_COLD_SLOAD → GAS_COLD_STORAGE_ACCESS
- GAS_WARM_ACCOUNT_ACCESS → GAS_WARM_ACCESS

Bump gas_limit on tests added to upstream after EIP-8037 branched,
which now need extra gas for EIP-8037 state gas costs.
… format runs in withdrawal request contract tests (ethereum#2532)

* fix(tests): prevent tx_gas_limit double-accumulation across fixture format runs in withdrawal request contract tests

* fix: mypy

* fix: ruff

* fix: ruff

* chore(tests): refactor fix to fork-aware transactions to prevent mutation

* chore(test): add a warning to all tests that could mutate vars; address in later PR

Add a lightweight repr-based snapshot hook to the filler plugin that warns whenever
any ``pytest.param`` value is mutated during a test run.

A subsequent PR could address this by returning values instead of mutating, then
flipping the hook to a hard failure.

---------

Co-authored-by: fselmo <fselmo2@gmail.com>
… gas validity test (ethereum#2583)

Co-authored-by: Stefan <22667037+qu0b@users.noreply.github.com>
…terdam/eip-8037

# Conflicts:
#	packages/testing/src/execution_testing/forks/base_fork.py
#	packages/testing/src/execution_testing/forks/forks/forks.py
#	src/ethereum/forks/amsterdam/fork.py
#	src/ethereum/forks/amsterdam/transactions.py
#	tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py
#	tests/prague/eip7702_set_code_tx/test_set_code_txs.py
Conditionally increase tx gas_limit (and env gas_limit where needed)
when fork >= Amsterdam to account for EIP-8037 state creation gas costs.

137 files, 9 with env gas_limit bumps. Headroom: 2,000,000.
Move MAX_CODE_SIZE check before gas charges, charge keccak hash
cost (regular gas) before code deposit state gas, and add tests
for over-max code size and reservoir preservation after OOG.
On CREATE/CREATE2 address collision the 63/64 gas allocation is
burned but was not added to regular_gas_used, leaving it invisible
to 2D block gas accounting. Per EIP-684 collision behaves as an
immediate exceptional halt, so the burned gas belongs in the regular
dimension.
…and subcall pattern

Co-authored-by: Mario Vega <marioevz@gmail.com>
The static test skip list and conftest were a temporary workaround for
EIP-8037 gas failures. The ported static tests in tests/ported_static/
replace this approach; failures are tracked in ethereum#2601.
@qu0b qu0b force-pushed the qu0b/eip8037-refund-state-gas-top-level branch 4 times, most recently from 110c250 to 278b35c Compare April 1, 2026 16:33
EELS patch: on top-level revert or exceptional halt, restore all
execution state gas to the reservoir and reset state_gas_used to
zero. Mirrors incorporate_child_on_error for child frames.

Test: 2-tx blockchain test at 100M where state gas is the binding
dimension. TX1 deploys 14 KiB contract (high state gas). TX2 is a
failing CREATE whose initcode state gas (GAS_NEW_ACCOUNT) is the
observable delta in header.gas_used.

This is the opposite of ethereum#2595 which tests that state gas IS counted
at the top level (#11468). This test verifies state gas is NOT
counted at the top level (#11476).

Spec change: ethereum/EIPs#11476

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@qu0b qu0b force-pushed the qu0b/eip8037-refund-state-gas-top-level branch from 278b35c to 9a45ae4 Compare April 1, 2026 16:35
@marioevz marioevz force-pushed the eips/amsterdam/eip-8037 branch 2 times, most recently from 629b34b to 9755dba Compare April 10, 2026 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants