Skip to content

feat(spec-specs,test-forks,tests): charge EIP-8250 keyed nonce access in intrinsic gas and the calldata floor - #3756

Merged
spencer-tb merged 2 commits into
ethereum:eips/bogota/eip-8250from
lambdaclass:frames-1/eip8250-keyed-nonce-access-cost
Oct 12, 2026
Merged

spencer-tb merged 2 commits into
ethereum:eips/bogota/eip-8250from
lambdaclass:frames-1/eip8250-keyed-nonce-access-cost

Conversation

@ilitteri

@ilitteri ilitteri commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

Implements ethereum/EIPs#12457 for EIP-8250: every non-zero nonce key pays KEYED_NONCE_ACCESS_COST (EIP-8038's COLD_STORAGE_ACCESS + STORAGE_WRITE, 12,100 gas) for the cold read and the write of its nonce manager slot, in both frame_tx_intrinsic_gas and calldata_floor_gas. The legacy key set pays nothing. In the spec it is a new GasCosts.KEYED_NONCE_ACCESS term in the frame transaction's intrinsic base, which the intrinsic cost and the calldata floor share. The framework prices it through a _frame_transaction_nonce_access_cost hook that EIP8250 overrides, so the existing EIP-8250 tests, which price gas through the fork calculators, pick it up.

The new test_keyed_nonce_access_cost builds its expected gas from the EIP's constant rather than from the calculators, for the legacy key set and for fresh, used, two and sixteen keys, with the standard cost binding and with the calldata floor binding. test_block_access_list now also requires the written slots to be absent from storage_reads, with one and two keys, as the EIP's new block access list section states. The spec already recorded them that way.

Filling the EIP-8250 tests without the spec change fails 77 fixtures, all 24 keyed test_keyed_nonce_access_cost cases among them. The filled fixtures pass against a client implementing #12457 (ethrex), and 31 fixture files fail against the same client without it.

This changes frames-devnet-1 consensus: tests-frames-devnet@v1.0.0 pins EIP-8250 at 17669e9, before #12457, so it is meant for the next v1 minor release.

Related Issues or PRs

Checklist

  • Ran fast static checks to avoid CI fails, see Code Standards & Verifying Changes: just static
  • PR title has the form <type>(<area>): <title>, where <type> and <area> come from an appropriate C-<type>, respectively A-<area>, label. The title should match the target squash commit message.

Cute Animal Picture

… in intrinsic gas and the calldata floor

Implements ethereum/EIPs#12457: every non-zero nonce key pays
KEYED_NONCE_ACCESS_COST (EIP-8038's COLD_STORAGE_ACCESS + STORAGE_WRITE,
12,100 gas) for the cold read and the write of its nonce manager slot, in
both frame_tx_intrinsic_gas and calldata_floor_gas. The legacy key set pays
nothing. The framework's frame intrinsic and floor calculators price it
through a nonce access hook that EIP-8250 overrides.

test_keyed_nonce_access_cost builds its expected gas from the EIP's
constant, independently of the calculators, for the legacy key set and for
fresh, used, two and sixteen keys, with the standard cost and with the
calldata floor binding. test_block_access_list now also requires the
written slots to be absent from storage_reads, with one and two keys, as
the EIP's block access list section states.

The reference spec pin moves to the merged EIP text.
@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (eips/bogota/eip-8250@61ba0fb). Learn more about missing BASE report.

Additional details and impacted files
@@                   Coverage Diff                   @@
##             eips/bogota/eip-8250    #3756   +/-   ##
=======================================================
  Coverage                        ?   94.95%           
=======================================================
  Files                           ?      677           
  Lines                           ?    41945           
  Branches                        ?     3961           
=======================================================
  Hits                            ?    39830           
  Misses                          ?     1464           
  Partials                        ?      651           
Flag Coverage Δ
unittests 94.95% <100.00%> (?)

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.

if floor_bound:
worker = pre.deploy_contract(code=Op.STOP)
worker_gas = fork.frame_entry_gas_calculator()(target_warm=False)
worker_data = FLOOR_PADDING

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Having a constant data padding is suboptimal because: (a) it might break the test in the future unknowingly, and (b) we would not be able to catch a potential off-by-one bug in a client. If possible, consider doing a binary search to find the minimum amount of bytes that bind the floor.

If you consider it out of scope for this PR (since this constant already existed and it's used by other tests) please open a tracking issue and assign to the original author of this file. cc @spencer-tb

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 208aa47, for both tests in this file that used the constant. The constant also wasn't what bound the floor: with a no-op worker, the signature and nonce bytes priced at the floor rate already put it above the standard cost, so the 30,000 bytes only widened the margin. Both tests now run a worker whose cold reads keep the standard cost above the floor and binary-search the fewest bytes of frame data that bind it, and test_keyed_nonce_access_cost gains a below_floor case one byte short of that. Making the spec count one byte too many in the floor fails floor and below_floor; one byte too few fails floor.

test_gas_settlement.py on eips/bogota/eip-8141 has the same 30,000-byte padding (FLOOR_PADDING_DATA); happy to give it the same treatment in a separate PR against that branch, or open an issue if you prefer.

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.

Thanks!

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.

Will update these in some follow ups!

…m padding

FLOOR_PADDING lifted the floor with a fixed 30,000 bytes, a margin no
one-byte miscount of the charged data could cross, and it was not what made
the floor bind: the frames' signature and nonce bytes, priced at the floor
rate, already outweighed the stand-in worker's gas.

Both floor tests now run a worker whose cold reads keep the standard cost
above the floor, and a binary search over the worker's frame data finds the
fewest bytes that bind the floor. test_keyed_nonce_access_cost adds a
below_floor case one byte short of that, where the standard cost binds
again. A spec that counts the floor's data one byte too many fails the
below_floor and floor cases; one that counts one byte too few fails floor.
@ilitteri
ilitteri requested a review from marioevz October 12, 2026 18:34

@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!

@spencer-tb
spencer-tb merged commit afa31f3 into ethereum:eips/bogota/eip-8250 Oct 12, 2026
27 checks passed
spencer-tb pushed a commit that referenced this pull request Oct 13, 2026
gurukamath pushed a commit that referenced this pull request Oct 13, 2026
gurukamath pushed a commit that referenced this pull request Oct 13, 2026
gurukamath pushed a commit that referenced this pull request Oct 15, 2026
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