Skip to content

feat(spec-specs): EIP-8037 - check static context upfront in CREATE opcodes - #12

Open
spencer-tb wants to merge 54 commits into
forks/amsterdamfrom
fix/create-static-check-upfront
Open

feat(spec-specs): EIP-8037 - check static context upfront in CREATE opcodes#12
spencer-tb wants to merge 54 commits into
forks/amsterdamfrom
fix/create-static-check-upfront

Conversation

@spencer-tb

@spencer-tb spencer-tb commented Jun 11, 2026

Copy link
Copy Markdown
Owner

🗒️ Description

Restores the upfront static-context check in CREATE/CREATE2, reverted during ethereum#2901 review (thread).

Before EIP-8037 the check position didn't matter, the static violation burns all the frame's gas either way. With EIP-8037 it does:

  • CREATE/CREATE2 charges NEW_ACCOUNT state gas before the static check.
  • If the frame's reservoir can't cover it, the rest is taken from gas_left.
  • The static check then halts the frame, and the caller gets all charged state gas back as reservoir, including the part paid from gas_left.
  • The caller now has more reservoir than it sent, so it can pay for state it otherwise couldn't → different state root.

Already pushed to devnets/bal/7 as cd19a9addc, and re-tagged v7.3.1.

🔗 Related Issues or PRs

Reverts part of ethereum@ac39618.

✅ Checklist

  • All: Ran fast static checks to avoid unnecessary CI fails, see also Code Standards and Enabling Pre-commit Checks:
    just static
  • All: PR title adheres to the repo standard - it will be used as the squash commit message and should start type(scope):.
  • All: Considered updating the online docs in the ./docs/ directory.
  • All: Set appropriate labels for the changes (only maintainers can apply labels).

Cute Animal Picture

Put a link to a cute animal picture inside the parenthesis-->

jsign and others added 30 commits May 19, 2026 14:36
…reum#2877)

* feat: devnet script optimization to avoid merge conflicts

* feat: mario feedback

* refactor: 8037+7981 harmonization, add zero-valued access list token scaffolding

* fix: add comment

* feat(tests): adds EIP-7981 test and required framework changes (ethereum#2144)

* feat: adds 7981 src changes + tests

* fix: sam feedback

* fix: ethereum-spec-lint: 'the item .. has changed relative positions', do we really need this check

* feat: EIPs 11340 update implemented

* fix: sam feedback

* refactor(tests-eip-7981): Constrain tests to EIP inclusion

* fix: harmonize with 8037, correct access list token placement and remove docstring conflicts

* fix(specs,tests): EIP-7981 - Update implementation and specs (ethereum#2682)

* fix(specs,tests): EIP-7981 - Update implementation and specs

* fix: tooling+unused

* fix: ACCESS_LIST_ADDRESS_FLOOR_TOKENS and ACCESS_LIST_STORAGE_KEY_FLOOR_TOKENS are now populated

---------

Co-authored-by: Felix H <felix314159@users.noreply.github.com>

* chores: update refspec

* fix(tests): drop GAS_ prefix from gas_costs attribute references

Align the EIP-7981 mixin and tests with the GasCosts dataclass rename
on forks/amsterdam.

* chore: update refspec (both 706296e06bf9b700bf046cfaa80bd5c3ebbc89c3 and 71d3353c3f6776485539fe2ec526b7cc80780bfc would not change the fixtures we currently output, cosmetic only)

* chore: update refspec (cosmetic change, no action required)

* feat(tests): EIP-7981 zero-byte calldata floor cost rejection (ethereum#2869)

---------

Co-authored-by: marioevz <marioevz@gmail.com>
Co-authored-by: Toni Wahrstätter <51536394+nerolation@users.noreply.github.com>
Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
Co-authored-by: Paweł Bylica <pawel@hepcolgum.band>
call with insufficient balance shoudn't access delegation
…, EXCHANGE (ethereum#2881)

* feat: devnet script optimization to avoid merge conflicts

* feat: mario feedback

* feat(src): EIP-8024 tests added (ethereum#2021)

* feat(test): update EIP-8024 refspec and align on latest changes to EIP (ethereum#2095)

* feat(test): EIP-8024 update (ethereum#2301)

* feat: 8024 updates

* fix: handle data opcodes appropriately

* chore: fixes after rebase; gas constants were renamed

* chore: update refspec to latest

* feat(test): Add test vectors from EIP changes

* fix(src,test): correct EXCHANGE JUMPDEST range; add missing EIP-8024 test vectors

* nit: assert tests match EIP cases directly, for readability

* nit: `m, n` -> `n, m` for consistency with EIP

* refactor: simplify `encode_pair` assumption wrt `m`

- Changes related to latest updates: https://github.com/ethereum/EIPs/pull/11351/changes

---------

Co-authored-by: fselmo <fselmo2@gmail.com>

* refactor(tests): Condition EIP-8024 tests to EIP inclusion

* fix(tests-eip-8024): Fix cross-eip failures (EIP-8037) (ethereum#2656)

* fix: mypy

* fix(specs): align EIP-8024 DUPN/SWAPN/EXCHANGE gas references

Add OPCODE_DUPN, OPCODE_SWAPN, OPCODE_EXCHANGE constants (= VERY_LOW)
to the GasCosts class and use them in place of the retired module-level
GAS_VERY_LOW reference, matching the per-opcode naming convention used
by the rest of the stack instructions.

* fix(tests): rename GAS_VERY_LOW to VERY_LOW in EIP-8024 mixin

Align DUPN/SWAPN/EXCHANGE gas lookups with the GasCosts dataclass
attribute rename on forks/amsterdam.

* fix(tests): EIP-8037 workaround

* test(tests-eip-8024): end-of-code stack underflow regression (ethereum#2741)

Add regression coverage for the EIP-8024 consensus bug where DUPN/SWAPN/
EXCHANGE at end of code, with one fewer stack item than the zero-decoded
immediate requires, must halt with stack underflow rather than succeeding
via a graceful STOP.

Parametrized state test over DUPN (144 items), SWAPN (145), EXCHANGE (16)
asserting the pre-opcode marker is not persisted, which catches clients
that treat the missing immediate as an implicit STOP.

Bounty: https://github.com/ethereum-bounty/nethermind/issues/12
Fix:    NethermindEth/nethermind#11178

---------

Co-authored-by: felipe <fselmo2@gmail.com>
Co-authored-by: marioevz <marioevz@gmail.com>
Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
Co-authored-by: Bhargava Shastry <bhargava.shastry@ethereum.org>
…-balance sender (ethereum#2880)

EIP-7981 charges every access-list byte (20 per address, 32 per storage
key) at the floor token cost. A transaction whose `gas_limit` lies in
`[Amsterdam_floor_without_AL_term, Amsterdam_floor)` must reject at
pre-validate with `INTRINSIC_GAS_BELOW_FLOOR_GAS_COST`; an
implementation that omits the access-list-byte term from its floor
computes a smaller floor and accepts.

This test pins `gas_limit` at the midpoint of that uplift gap for
Type-1 and Type-2 transactions carrying 1000 / 2000 nonzero data bytes
plus a 1-address / 10-storage-key access list. The sender is funded
with exactly `gas_limit * gas_price`, so a buggy implementation cannot
fall back to a silent "accept and execute" — any acceptance produces
a divergent post-state.

Complements `test_insufficient_gas_for_access_list` and
`test_floor_cost_validation_with_access_list`, which exercise this
boundary at `gas_limit = floor - 1` with default sender funding.
…or gap (ethereum#2878)

* feat(tests): EIP-7976 reject in Prague/Amsterdam floor gap with exact-balance sender

EIP-7976 raises the per-byte calldata floor cost. A transaction whose
`gas_limit` lies in `[Prague_floor, Amsterdam_floor)` must reject at
pre-validate with `INTRINSIC_GAS_BELOW_FLOOR_GAS_COST`. This test pins
gas_limit at the midpoint of that gap for 100 and 1000 zero-byte
calldata transactions. Sender balance equals `gas_limit * gas_price`,
so an implementation that defaults to the Prague floor cannot fall
through to a silent "accept and execute" — any pre-validate divergence
produces a different post-state.

* refactor(tests): use `valid_at` marker and improve docstring consistency

---------

Co-authored-by: Felix H <felix314159@users.noreply.github.com>
* test(tests): extend BALs coverage for edge cases

* test(tests): closes ethereum#1910 - parametrize memory for call_opcode tests

* test(tests): expand BAL coverage for insufficient-funds boundaries

Add a combined outer-REVERT + inner-insufficient-funds test (CALL and CREATE), and layer EIP-7928-gated BAL expectations onto three existing cross-fork insufficient-funds tests (EIP-7708, EIP-2929 frontier CALL).

* feat(tests): add some more parallelization test scenarios for BALs

* chore(tests): add SSTORE to CREATE2 + SD + re-create as sanity check

* cleanups from comments on PR ethereum#2854

* feat(tests): add parallelization BAL tests for collision / OOG create chain

* chore: audit * update ``test_cases.md`` after suggestions and PR ethereum#2882

* fix(tests): update expected exception(s) for transition tests
ethereum#2883)

* feat(tests): EIP-7928 BAL withdrawal predeploy balance read across txs

Add a cross-tx test in eip7928_block_level_access_lists/test_block_access_lists_cross_index.py
that verifies a transaction observing the BAL balance change of the
WITHDRAWAL_REQUEST_PREDEPLOY recorded by a prior transaction within the
same block.

tx 0 pays the withdrawal fee (balance 0 -> fee, recorded as a BAL
balance_change at index 1). tx 1 calls a contract that performs
SSTORE(0, BALANCE(WITHDRAWAL_REQUEST_PREDEPLOY)); the assertion that
slot 0 equals fee exercises that tx 1's pre-state for the predeploy
includes tx 0's BAL prefix entry.

* chore: add entry to ``test_cases.md``

* chore: unrelated cleanup to use Spec instead of hard-coding

---------

Co-authored-by: fselmo <fselmo2@gmail.com>
…thereum#2893)

* feat(tests): EIP-7928 self destruct to system address with 0 value

* chore: some cleanup and add test case to ``tests_cases.md``

* chore: move test to more appropriate location

---------

Co-authored-by: fselmo <fselmo2@gmail.com>
…thereum#2896)

* tests/benchmark/compute/precompile/test_modexp.py: Add tests for modexp with random bit patterns and relevant lengths.
Add tests for modexp where the modulus is a power of 2.

* remove newline

* Fix typo

* refactor: comment and helper function

---------

Co-authored-by: LouisTsai <q1030176@gmail.com>
* 🧪 test: Extend create endowment

* 🧪 test: Extend tx boundary test

* feat(tests): 2D parametrize with (tx, withdrawal) for BAL gas limit test

---------

Co-authored-by: raxhvl <raxhvl@users.noreply.github.com>
Co-authored-by: fselmo <fselmo2@gmail.com>
* feat: fill-stateful pytest pluging implementation

* fix: test phase extraction; remove AI guesswork

* WIP: debug_setHead resets

* WIP: separate global setup step

* use withdrawal to fund; default gen seed key

* chore: cleanups related to stateful filling

* add --clean support; remove xdist logging

* chore: fix unit test for stateful fixture

* more refactoring

* refactor(test-cli): share live-network pytest plugin logic

* feat(test-cli): Use setup groups to optimize the setup + execution behavior

* refactor: some refactor and work on setup groups

* fix: address comments from PR ethereum#2637

* refactor: remove the setup groups; unnecessarily complex for small gain

* feat(tests-specs): added improvements and cleanup for stateful filling

* chore: fail loudly for parametrized stub tests missing stub file

* refactor: Use `PhaseManager` for fill-stateful

* fix: format selection

* fix: forks unit tests

* feat: fill-stateful hive support

* fix: hive flags

* fix: fill-stateful exclude from fill format

* refactor(fill): Get rid of PhaseManager, FormatSelector

* nit: comment update

* Louis' comments

Co-authored-by: 蔡佳誠 Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com>

* refactor: rename global_setup to block hash

---------

Co-authored-by: Mario Vega <marioevz@gmail.com>
Co-authored-by: LouisTsai <q1030176@gmail.com>
Co-authored-by: 蔡佳誠 Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com>
…#2294)

Type aliases such as Balance, Nonce, StorageKey, StorageValue, and
CodeData were pure documentation (TypeAlias offered no mypy
protection), inconsistent across forks, and forced readers to
navigate away from use sites to learn the underlying width. Inline
U256/U64/Bytes directly and keep only BlockAccessIndex, which names
a genuinely fork-specific concept, moved to fork_types.

Resolves ethereum#2260.

Co-authored-by: Guruprasad Kamath <guru241987@gmail.com>
…ms (ethereum#2907)

In test_valid_inputs and test_invalid_inputs:

- Convert tuple params to `pytest.param(..., id=...)` so each case's
  identifier lives next to its values; drop the parallel `ids=[...]`
  list in test_invalid_inputs.
- Move the per-case descriptions out of the function docstrings and
  into inline comments above the relevant pytest.param(s); shrink each
  docstring to a one-line summary.
- Replace the magic `0xC0 << 376` with the existing `INF_POINT`
  constant in Spec.kzg_to_versioned_hash() calls.
- Use idiomatic byte literals (`b""`, `b"\x00"`, `b"\x00" * 1023`)
  instead of `bytes()` / `bytes([0])` / `bytes([0] * 1023)`.

No fixture changes (t8n cache 100% hit on all 14 cases).
…um#2895)

* feat(test-consume): Validate RPC header fields

* fix(tests-rlp): Raise nice AssertionError
…2943)

* feat: nethermind state test added

* fix: i was lINTING again
pk910 and others added 23 commits June 2, 2026 14:24
… (EIP-7778) (ethereum#2949)

In test_multi_transaction_gas_accounting, a block whose included transaction
exceeds the remaining block gas was expected to fail only with the block-level
BlockException.GAS_USED_OVERFLOW. A client may legitimately report the same
condition at the transaction level: EELS raises GasUsedExceedsLimitError (an
InvalidTransaction subclass) when `tx.gas > gas_available`, and evmone reports
it as a rejected transaction (GAS_LIMIT_REACHED).

List both BlockException.GAS_USED_OVERFLOW and
TransactionException.GAS_ALLOWANCE_EXCEEDED as acceptable so either
categorization passes.
…wcase erigon statetest bug (ethereum#2951)

* feat: erigon support for 'consume direct'

* feat: add minimal test to showcase erigon statetest behavior differs from other clients
…b/) (ethereum#2962)

* chore: ignore local memory files (CLAUDE.local.md, .mb/, mb/)

These are local-only AI memory and notes files; ignore them so they do not show up as untracked in working trees.

* chore: exclude local memory files from codespell

Skip CLAUDE.local.md and the .mb/mb memory-bank dirs so codespell does not scan local-only AI memory and notes files (which may be present as symlinks).
Add a `FinalDecoratorHygiene` lint rule that flags any leaf dataclass (a
`@dataclass` or `@slotted_freezable` class never used as a base) that is
missing `@final`. Marking leaf dataclasses `@final` lets `mypyc` bypass
the vtable for method calls and property accessors.

The rule scans the whole specification once at the first fork position:
every fork's modules plus the shared modules such as `ethereum.state` and
`ethereum.trace`, including each package's `__init__.py`. Register the rule
in `vulture_whitelist.py` since lints are discovered dynamically.
…m#2901)

Co-authored-by: Ben Adams <thundercat@illyriad.co.uk>
Co-authored-by: felix <felix314159@users.noreply.github.com>
Co-authored-by: fselmo <fselmo2@gmail.com>
Co-authored-by: Stefan <22667037+qu0b@users.noreply.github.com>
Co-authored-by: Mario Vega <marioevz@gmail.com>
Co-authored-by: kclowes <kclowes@users.noreply.github.com>
Co-authored-by: carsons-eels <carson@ethereum.org>
Co-authored-by: Leo Lara <leolara@users.noreply.github.com>
Co-authored-by: danceratopz <danceratopz@gmail.com>
Co-authored-by: Paweł Bylica <pawel@hepcolgum.band>
Co-authored-by: Sam Wilson <57262657+SamWilsn@users.noreply.github.com>
Co-authored-by: marioevz <11726710+marioevz@users.noreply.github.com>
Co-authored-by: kclowes <6540608+kclowes@users.noreply.github.com>
…thereum#2970)

`build_refund_tx` iterated `set(fork.refund_types())`, whose order
depends on Python's per-process string-hash randomization (no
`PYTHONHASHSEED` is set in this repo). Different `fill` invocations
therefore appended the extra `PUSH0` from the
`AUTHORIZATION_EXISTING_AUTHORITY` branch either before or after the
`STORAGE_CLEAR` SSTOREs, producing two different bytecodes and — via
`contract_address_from_hash` — two different deployment addresses for
the same test, and hence two different pre-state allocations and
state roots.

Sort by enum-member name inside the iteration so the bytecode (and
therefore the contract address) is deterministic across runs.
* ✨ feat(test): selfdestruct a drity account

* nit

Co-authored-by: Mario Vega <marioevz@gmail.com>

* nit

Co-authored-by: Mario Vega <marioevz@gmail.com>

* nit

Co-authored-by: Mario Vega <marioevz@gmail.com>

* nit

Co-authored-by: Mario Vega <marioevz@gmail.com>

* nit

Co-authored-by: Mario Vega <marioevz@gmail.com>

* ✨ feat: Parameterise success / revert

* 🧹 chore: lint

* 🐞 fix: 8037 pricing change; forward all gas

---------

Co-authored-by: raxhvl <raxhvl@users.noreply.github.com>
Co-authored-by: Mario Vega <marioevz@gmail.com>
…tstrapped (ethereum#2944)

* feat(execute): skip the deterministic factory deploy (and dependent tests) when it can't be bootstrapped

The deterministic deployment proxy is bootstrapped in an autouse session
fixture via a keyless transaction with a fixed gas limit. On chains where the
contract-creation intrinsic gas exceeds that limit (so the keyless tx can never
be mined), the deploy aborted the entire execute session, blocking even tests
that never use the factory.

- Pre-flight the deploy with `eth_estimateGas`: if the network requires more
  gas for the creation than the keyless tx's fixed gas limit, raise instead of
  attempting it (no funding tx, no doomed send, no inclusion wait).
- Make the session fixture best-effort: warn instead of raising, so tests that
  don't need the factory still run.
- Skip a test that requests a deterministic deployment when the factory is
  unavailable.
- Add `EthRPC.estimate_gas` for the pre-flight.

* chore: update comment

---------

Co-authored-by: LouisTsai <q1030176@gmail.com>
@spencer-tb
spencer-tb force-pushed the fix/create-static-check-upfront branch 2 times, most recently from 0fade00 to cb8e10e Compare June 11, 2026 10:53
@spencer-tb spencer-tb changed the title fix(specs): check static context upfront in CREATE opcodes feat(spec-specs): EIP-8037 - check static context upfront in CREATE opcodes Jun 11, 2026
@spencer-tb
spencer-tb force-pushed the fix/create-static-check-upfront branch from cb8e10e to e981b8b Compare June 11, 2026 11:03
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.