Skip to content

fix(spec-specs, tests): EIP-8037 strict block-gas inclusion rule#2892

Open
chfast wants to merge 1 commit into
ethereum:devnets/bal/7from
chfast:feat/eip-8037-block-gas-inclusion-strict
Open

fix(spec-specs, tests): EIP-8037 strict block-gas inclusion rule#2892
chfast wants to merge 1 commit into
ethereum:devnets/bal/7from
chfast:feat/eip-8037-block-gas-inclusion-strict

Conversation

@chfast
Copy link
Copy Markdown
Member

@chfast chfast commented May 21, 2026

🗒️ Description

EIP-8037 specifies the per-dimension inclusion check at block start as:

min(TX_MAX_GAS_LIMIT, tx.gas) <= regular_gas_available
tx.gas <= state_gas_available

EELS Amsterdam was subtracting intrinsic.state / intrinsic.regular from tx.gas in each dimension, which let a transaction with non-zero state intrinsic (CREATE, EIP-7702 set_code) be included when tx.gas exceeded block.gas_limit by up to intrinsic.regular (state-dim) or intrinsic.state (regular-dim). evmone, revm, and erigon enforce the EIP literally and reject; pre-bump geth rejects too.

Add a parametrized test under EIP-8037 covering the boundary across all post-EIP-7702 tx types and contract-creation kinds, at two block-gas-limit values to avoid hard-coded-cap false-positives.

🔗 Related Issues or PRs

N/A.

✅ 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).
  • Tests: Ran mkdocs serve locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.
  • Tests: For PRs implementing a missed test case, update the post-mortem document to add an entry the list.
  • Ported Tests: All converted JSON/YML tests from ethereum/tests or tests/static have been assigned @ported_from marker.

EIP-8037 specifies the per-dimension inclusion check at block start as:

    min(TX_MAX_GAS_LIMIT, tx.gas) <= regular_gas_available
    tx.gas <= state_gas_available

EELS Amsterdam was subtracting intrinsic.state / intrinsic.regular from
tx.gas in each dimension, which let a transaction with non-zero state
intrinsic (CREATE, EIP-7702 set_code) be included when tx.gas exceeded
block.gas_limit by up to intrinsic.regular (state-dim) or intrinsic.state
(regular-dim). evmone, revm, and erigon enforce the EIP literally and
reject; pre-bump geth rejects too.

Add a parametrized test under EIP-8037 covering the boundary across all
post-EIP-7702 tx types and contract-creation kinds, at two block-gas-limit
values to avoid hard-coded-cap false-positives.
@marioevz
Copy link
Copy Markdown
Member

We are in the process of merging EIP-8037 to forks/amsterdam via this PR: #2901

Once the PR is merged we can point this to the forks/amsterdam branch and then merge.

chfast added a commit to ipsilon/evmone that referenced this pull request Jun 2, 2026
EIP-8037 §"Transaction validation" rule 2 requires a per-tx inclusion
check against the per-dimension remaining budget:

    min(TX_MAX_GAS_LIMIT, tx.gas) <= regular_gas_available
    tx.gas <= state_gas_available

Add `state_block_gas_left` parameter to `validate_transaction` and
enforce both checks for Amsterdam+; default to 0 in the header for
pre-Amsterdam call sites that ignore state-gas. Errors are
`GAS_LIMIT_REACHED` (mapped to `TransactionException.GAS_ALLOWANCE_EXCEEDED`
by EEST).

Also flip the existing Amsterdam intrinsic-cap check from
`GAS_LIMIT_EXCEEDS_MAXIMUM` to `INTRINSIC_GAS_TOO_LOW`: EELS raises
`InsufficientTransactionGasError` here ("the tx can't pay its
intrinsic within the reservoir bound"), not the EIP-7825 absolute-cap
exception.

Note on EELS divergence: amsterdam/fork.py:561-583 currently subtracts
intrinsic.state / intrinsic.regular from tx.gas in each dimension
(`min(TX_MAX_GAS_LIMIT, tx.gas - intrinsic.state)` etc.), which is
more permissive than the EIP. ethereum/execution-specs#2892 aligns
EELS back with the EIP literal. This implementation follows the EIP
text directly — same as revm/erigon/pre-bump-geth.

`test::transition` (the TestState wrapper used by state-transition
unit tests and state tests) passes `block_gas_left` as both budgets,
since those tests run a single tx in a fresh block.

evmone-unittests: 1116 / 1116 pass.
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