Skip to content

feat(tests): EIP-8037 unmask intrinsic-cap transaction-validity checks#2956

Merged
spencer-tb merged 1 commit into
ethereum:forks/amsterdamfrom
bshastry:bshastry/eip8037-intrinsic-cap-bal7
Jun 10, 2026
Merged

feat(tests): EIP-8037 unmask intrinsic-cap transaction-validity checks#2956
spencer-tb merged 1 commit into
ethereum:forks/amsterdamfrom
bshastry:bshastry/eip8037-intrinsic-cap-bal7

Conversation

@bshastry

@bshastry bshastry commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

🗒️ Description

The EIP-8037 "transaction validity" tests assert requirement 1,
max(intrinsic_regular, calldata_floor) <= TX_MAX_GAS_LIMIT. That cap
check runs after the sufficiency check
max(intrinsic_total, calldata_floor) <= tx.gas. The three existing
cap-rejection tests were each tripped by the sufficiency check first, so
none of them ever exercised the cap — a client with the sufficiency gate
but no max(regular, floor) > cap gate passes all three:

test how it was masked
test_intrinsic_regular_gas_exceeds_cap non-zero calldata at gas_limit = cap*2 made floor > tx.gas (sufficiency)
test_intrinsic_regular_gas_exceeds_cap_with_floor_below_cap EIP-7702 auths coupled state gas so intrinsic_total > tx.gas (sufficiency)
test_calldata_floor_exceeding_tx_gas_limit_cap[exceeds_cap] gas_limit = cap while floor > cap, so floor > tx.gas (sufficiency)

Differential fuzzing on bal-devnet-7 found a client with exactly that gap:
besu 26.6-develop-e8c2195 executes a floor-over-cap transaction that
geth, nethermind, revm, and the EELS reference all reject. The masked
tests would not have caught it.

This PR re-levers each test so the cap is the only check that can
reject
, and adds the accepting positive control:

  • Regular-dimension tests use a large access list (regular intrinsic
    only, no state gas) with gas_limit above the total intrinsic, and
    assert max(regular, floor) > cap, regular + state <= tx.gas, and —
    for the _with_floor_below_cap variant — floor < cap.
  • The floor test funds the floor in full (gas_limit = floor + 1_000_000)
    and asserts floor > cap and regular < cap.
  • New test_intrinsic_within_cap_gas_limit_above_cap accepts a tx whose
    gas_limit exceeds the cap while both operands stay below it.

All operands are derived from the fork gas calculators so the tests stay
correct as Amsterdam pricing evolves.

Verification (re-filled under EELS, fixtures replayed against the
bal-devnet-7 client binaries):

test geth nethermind revm EELS besu e8c2195
regular > cap (floor < cap) reject reject reject reject execute
regular > cap, floor below cap reject reject reject reject execute
floor > cap reject reject reject reject execute
within cap, gas_limit > cap accept accept accept accept accept

besu's gap covers both operands of max(regular, floor), not just the
floor. (Amsterdam / EIP-8037 is not live on mainnet; this is devnet
test-hardening, not a mainnet-exposing disclosure.)

This targets devnets/bal/7, the branch the nightly bal hive fixtures are
filled from and where the EIP-8037 transaction-validity tests live.

🔗 Related Issues or PRs

Re-levers the cap tests added in #2870 and the surrounding EIP-8037
state-gas test work.

✅ 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.

Cute Animal Picture

Cute capybara

@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.53%. Comparing base (84e39e1) to head (721002a).
⚠️ Report is 2 commits behind head on forks/amsterdam.

Additional details and impacted files
@@               Coverage Diff                @@
##           forks/amsterdam    #2956   +/-   ##
================================================
  Coverage            90.53%   90.53%           
================================================
  Files                  535      535           
  Lines                32897    32893    -4     
  Branches              3021     3021           
================================================
- Hits                 29782    29780    -2     
+ Misses                2596     2595    -1     
+ Partials               519      518    -1     
Flag Coverage Δ
unittests 90.53% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@marioevz

marioevz commented Jun 9, 2026

Copy link
Copy Markdown
Member

Potentially a duplicate of #2898.

Also needs a rebase and base change to forks/amsterdam.

The three EIP-8037 transaction-validity tests that assert
`max(intrinsic_regular, calldata_floor) <= TX_MAX_GAS_LIMIT` were each
satisfied by the *sufficiency* check (`max(intrinsic_total, floor) <=
tx.gas`) that runs before the cap check, so none of them exercised the
cap itself:

* `test_intrinsic_regular_gas_exceeds_cap` pushed both dimensions over the
  cap with non-zero calldata at `gas_limit = cap * 2`; the calldata floor
  exceeded `tx.gas`, so sufficiency rejected it first.
* `test_intrinsic_regular_gas_exceeds_cap_with_floor_below_cap` inflated
  the regular dimension with EIP-7702 authorizations, whose coupled state
  gas pushed the total intrinsic far above `tx.gas` (sufficiency).
* `test_calldata_floor_exceeding_tx_gas_limit_cap[exceeds_cap]` set
  `gas_limit = cap` while the floor exceeded the cap, so `floor > tx.gas`
  tripped sufficiency.

A client with the sufficiency gate but no `max(regular, floor) > cap`
gate passes all three. Differential fuzzing on bal-devnet-7 caught
exactly such a client: besu (26.6-develop-e8c2195) executes a
floor-over-cap transaction that geth, nethermind, revm, and the EELS
reference all reject.

Re-lever each test so the cap is the only check that can reject:

* The regular-dimension tests use a large access list (regular intrinsic
  only, no state gas) with `gas_limit` above the total intrinsic, and
  assert `max(regular, floor) > cap`, `regular + state <= tx.gas`, and
  (for the floor-below-cap variant) `floor < cap`.
* The floor test funds the floor in full (`gas_limit = floor + 1_000_000`)
  and asserts `floor > cap` and `regular < cap`.
* Add `test_intrinsic_within_cap_gas_limit_above_cap` as the accepting
  positive control (`gas_limit` above the cap, both operands below it).

All operands are derived from the fork gas calculators so the tests stay
correct as Amsterdam pricing evolves. Verified by re-filling under EELS
(rejects) and replaying the fixtures against the bal-devnet-7 clients:
geth, nethermind, revm, and EELS reject; besu e8c2195 executes (consensus
divergence); the positive control is accepted by all.
@bshastry bshastry force-pushed the bshastry/eip8037-intrinsic-cap-bal7 branch from 1a4570f to 721002a Compare June 10, 2026 09:30
@bshastry bshastry changed the base branch from devnets/bal/7 to forks/amsterdam June 10, 2026 09:30
@bshastry

Copy link
Copy Markdown
Contributor Author

Potentially a duplicate of #2898.

Also needs a rebase and base change to forks/amsterdam.

Done, feel free to close it if it is a dup.

@spencer-tb spencer-tb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I think we can keep both PRs for now.

@spencer-tb spencer-tb closed this Jun 10, 2026
@spencer-tb spencer-tb reopened this Jun 10, 2026
@spencer-tb

Copy link
Copy Markdown
Contributor

Close and reopen to trigger CI!

@spencer-tb spencer-tb changed the title fix(tests): EIP-8037 unmask intrinsic-cap transaction-validity checks feat(tests): EIP-8037 unmask intrinsic-cap transaction-validity checks Jun 10, 2026
@spencer-tb spencer-tb merged commit 55ee6b1 into ethereum:forks/amsterdam Jun 10, 2026
18 checks passed
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