Skip to content

feat(tests): add EIP-7954 jumpdest test past the old code-size limit - #2993

Merged
danceratopz merged 3 commits into
ethereum:forks/amsterdamfrom
danceratopz:7954-high-jump-dest-test-case
Jun 17, 2026
Merged

feat(tests): add EIP-7954 jumpdest test past the old code-size limit#2993
danceratopz merged 3 commits into
ethereum:forks/amsterdamfrom
danceratopz:7954-high-jump-dest-test-case

Conversation

@danceratopz

@danceratopz danceratopz commented Jun 16, 2026

Copy link
Copy Markdown
Member

🗒️ Description

EIP-7954 raises MAX_CODE_SIZE to 64 KiB and the initcode limit to 128 KiB. Before this fork, deployed runtime code could never exceed 24 KiB, so no existing test ever executes a contract at a program counter past the old limit. The EIP-7954 max-size contracts are either deploy-only or run a short prefix that STOPs before their JUMPDEST padding, and EXTCODECOPY/CODECOPY only read the code rather than run it.

A client whose jumpdest analysis or code execution is still bounded by the old limit would pass the existing suite yet break on a real 64 KiB contract.

test_max_code_size_high_jumpdest deploys a MAX_CODE_SIZE contract and jumps near the new limit, far beyond the old 24 KiB code and 48 KiB initcode limits:

  • Valid JUMPDEST: The jump succeeds and the code runs at the high offset, storing a sentinel.
  • Non-JUMPDEST byte: The jump is rejected and nothing is stored.

The contract is called through a caller that records the call result, so a correct client is told apart from one that truncated its jumpdest analysis (the valid jump fails) or accepts any high offset (the invalid jump wrongly succeeds).

Final version

image image

🔗 Related Issues or PRs

✅ 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

cute animal

EIP-7954 raises `MAX_CODE_SIZE` to 64 KiB and the initcode limit to
128 KiB. Before this fork, deployed runtime code could never exceed
24 KiB, so no existing test ever executes a contract at a program
counter past the old limit. The EIP-7954 max-size contracts are either
deploy-only or run a short prefix that `STOP`s before their `JUMPDEST`
padding, and `EXTCODECOPY`/`CODECOPY` only read the code rather than
run it.

A client whose jumpdest analysis or code execution is still bounded by
the old limit would pass the existing suite yet break on a real 64 KiB
contract.

`test_max_code_size_high_jumpdest` deploys a `MAX_CODE_SIZE` contract
and jumps near the new limit, far beyond the old 24 KiB code and 48 KiB
initcode limits:

- Valid `JUMPDEST`: The jump succeeds and the code runs at the high
  offset, storing a sentinel.
- Non-`JUMPDEST` byte: The jump is rejected and nothing is stored.

The contract is called through a caller that records the call result,
so a correct client is told apart from one that truncated its jumpdest
analysis (the valid jump fails) or accepts any high offset (the invalid
jump wrongly succeeds).
@danceratopz danceratopz added C-feat Category: an improvement or new feature A-tests Area: Consensus tests. labels Jun 16, 2026
@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.20%. Comparing base (e35d103) to head (a9b7ed7).
⚠️ Report is 5 commits behind head on forks/amsterdam.

Additional details and impacted files
@@                 Coverage Diff                  @@
##           forks/amsterdam    #2993       +/-   ##
====================================================
+ Coverage            81.28%   93.20%   +11.92%     
====================================================
  Files                  620      620               
  Lines                36641    38759     +2118     
  Branches              3311     3341       +30     
====================================================
+ Hits                 29784    36127     +6343     
+ Misses                6335     1773     -4562     
- Partials               522      859      +337     
Flag Coverage Δ
unittests 93.20% <ø> (+11.92%) ⬆️

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 left a comment

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.

Looks good, just a couple of suggestions, feel free to apply.

Comment thread tests/amsterdam/eip7954_increase_max_contract_size/test_max_code_size.py Outdated
Comment thread tests/amsterdam/eip7954_increase_max_contract_size/test_max_code_size.py Outdated
Comment thread tests/amsterdam/eip7954_increase_max_contract_size/test_max_code_size.py Outdated

@LouisTsai-Csie LouisTsai-Csie 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.

Good points from Mario, LGTM once those are addressed. No other comments from my side.

Follow-up PR idea on JUMPDEST analysis: clients run it to ensure a jump target doesn't land on an immediate byte. We could add a scenario where the jump targets a 0x5b immediate byte of a PUSH, SWAPN, DUPN, or EXCHANGE instruction, asserting it's rejected as an invalid jump destination. The contract size should be at the new max code size, so the analysis is done well past the increase.

danceratopz and others added 2 commits June 17, 2026 11:39
The high jumpdest test is not gas sensitive, so drop the explicit
`gas_limit=fork.transaction_gas_limit_cap()` and let the framework fill
the transaction gas limit automatically.

Co-authored-by: marioevz <11726710+marioevz@users.noreply.github.com>
Store the sentinel in the prefix, before the `JUMP`, so the jump target
is a bare `JUMPDEST` (valid) or `STOP` (invalid) with no trailing code:

- Valid: The jump completes, the frame returns, and the store is kept.
- Invalid: The jump is rejected, the frame reverts, and the store is
  discarded.

Also fix the stale comment: with a bare `STOP` target, a client that
wrongly accepts the jump halts normally and keeps the prefix store, so
it stores `1`, not `2`.

Co-authored-by: marioevz <11726710+marioevz@users.noreply.github.com>
@danceratopz
danceratopz merged commit c00006f into ethereum:forks/amsterdam Jun 17, 2026
18 checks passed
@danceratopz

Copy link
Copy Markdown
Member Author

Follow-up PR idea on JUMPDEST analysis: clients run it to ensure a jump target doesn't land on an immediate byte. We could add a scenario where the jump targets a 0x5b immediate byte of a PUSH, SWAPN, DUPN, or EXCHANGE instruction, asserting it's rejected as an invalid jump destination. The contract size should be at the new max code size, so the analysis is done well past the increase.

Thanks for the review @LouisTsai-Csie! About the idea above, I think it has low additional value, but happy to add if you disagree. I think it would only catch a client that had hard-coded the wrong contract sizes in EIP-8024 context?

Behavior (the jump target byte) Whose rule Already tested in forks/amsterdam?
0x5B buried in PUSH data → rejected classic JUMPDEST analysis (pre-EIP) Rule: runtime.py#L62-L67. No dedicated test in the 8024/7954 suites (ancient behavior).
0x5B after DUPNaccepted EIP-8024 test_dupn_jump_to_immediate_byte_0x5b_succeeds
0x5B after SWAPNaccepted EIP-8024 test_swapn_jump_to_immediate_byte_0x5b_succeeds
0x5B after EXCHANGEaccepted EIP-8024 test_exchange_jump_to_immediate_byte (immediate sweep, incl. 0x5B)
valid immediate skipped → jump fails EIP-8024 test_dupn_jump_to_valid_immediate_fails, test_swapn_jump_to_valid_immediate_fails
any of the above at 64 KiB (MAX_CODE_SIZE) EIP-7954 (size only) ❌ Not covered. The 8024 tests above use tiny contracts; the basic max-size jump case is in #2993.

@danceratopz

Copy link
Copy Markdown
Member Author

@LouisTsai-Csie I added the test case here #2998

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-tests Area: Consensus tests. C-feat Category: an improvement or new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants