Skip to content

fix(tests): enhance & un-skip Amsterdam ported static tests (Pt. 1) - #3215

Merged
spencer-tb merged 18 commits into
ethereum:forks/amsterdamfrom
marioevz:ported-static-enhance-skill
Jul 29, 2026
Merged

fix(tests): enhance & un-skip Amsterdam ported static tests (Pt. 1)#3215
spencer-tb merged 18 commits into
ethereum:forks/amsterdamfrom
marioevz:ported-static-enhance-skill

Conversation

@marioevz

Copy link
Copy Markdown
Member

Description

Amsterdam's EIP-8037 two-dimensional (regular vs. state) gas model broke a large batch of machine-ported tests/ported_static/ tests, which were temporarily parked in amsterdam_skip_list.txt. These fillers encode gas the wrong way for a fork that reprices: hardcoded absolute GAS snapshots, tight OOG gas budgets, and per-opcode gas constants baked into expectations. When EIP-8037 moved account creation / storage writes into the state dimension (and EIP-2780 dropped the intrinsic tx cost 21000 → 15000), every one of those pinned numbers shifted and the tests failed on Amsterdam.

This PR (Part 1) rewrites a first tranche of them to be fork-robust — they now express gas through framework constructs that track the live schedule (CodeGasMeasure, bytecode.gas_cost(fork) / .regular_cost(fork) / .state_cost(fork), opcode metadata) rather than magic numbers — so a future fork that re-prices gas no longer silently breaks them. Each enhanced test is verified across its full valid_from range and on Amsterdam, and its skip-list entry removed.

Result: the Amsterdam ported-static skip list drops from 258 → 153 entries (105 un-skipped). Along the way ~40 near-identical sibling fillers are consolidated into a handful of parametrized tests (56 files changed: +1067 / −4621), and most tests gain much wider fork coverage (the ported valid_from was almost always an over-tight Cancun; many now run from Frontier / Berlin / SpuriousDragon onward).

The remaining 153 skipped cases — dominated by OOG-boundary, revert-depth, refund, and collision families — are left for a follow-up PR (Part 2).

Highlights

  • MCOPY copy-cost (55 cases, largest single win). The filler probed MCOPY cost via a razor-thin OOG boundary whose instrumentation SSTORE is repriced into ~97920 state gas on Amsterdam, so every case OOG'd. Reframed to measure the copy cost directly with CodeGasMeasure over pre-expanded memory, asserting mcopy.gas_cost(fork).
  • RawCall*GasAsk (10 → 1). Verifies the EIP-150 "all but one 64th" gas-forwarding rule. An outer call caps the caller frame at a known budget so the forwarded amount is deterministic (independent of the tx gas limit), the callee returns its observed GAS up to the top frame (avoiding a lower-frame state-gas trap), and the expectation is derived as all_but_one_64th(caller_gas − call.gas_cost(fork)) + stipend − GAS.
  • RawCreate*Gas (6 → 1). One parametrize over value / memory / failure; confirms an EIP-8037 behavior — a balance-failure CREATE charges regular gas only (regular_cost(fork)), never state gas.
  • Empty-contract & behavior families. CREATE/CALL gas via CodeGasMeasure; gas-independent behavior tests freed of tight gas_limits; subcall gas operands left to default (Op.GAS) instead of hardcoded constants; dynamic addresses throughout; protected=fork.supports_protected_txs() to keep the fork floor at the behavior's real EIP rather than masking a signature floor.

Methodology / tooling

  • Adds the enhance-ported-test Claude Code skill (.claude/commands/enhance-ported-test.md) and wires it into CLAUDE.md — an ordered, empirically-validated methodology for turning a ported filler into idiomatic, fork-robust Python (max out gas, dynamic addresses, CodeGasMeasure, consolidation, valid_from floors, re-pinning discipline). This is the playbook Part 2 will follow.

Related Issues or PRs

N/A.

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

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

marioevz added 17 commits July 23, 2026 11:58
Enhance and un-skip 10 Amsterdam skip-list entries (234 -> 224):

- test_create_empty_contract: CREATE gas via CodeGasMeasure; merge
  with_balance as a parametrize.
- test_create_empty_contract_and_call_it (new): merge 0wei/1wei; CALL gas
  via CodeGasMeasure with a runtime SLOAD address.
- test_copy_offset (new): merge CODECOPY/CALLDATACOPY OOB-offset; drop the
  delivery CALL.
- test_delegatecall_emptycontract, test_deleagate_call_after_value_transfer:
  gas forwarded via the default Op.GAS; the latter also restores its
  "after value transfer" intent with a non-zero tx value.
- test_static_call_value_inherit_from_call: STATICCALL sees CALLVALUE 0.
- test_make_money: value flow as a relationship; drop gas-noise balance.

Coverage widened from the ported Cancun-only down to each test's true fork
floor. Skill enhance-ported-test.md updated with the validated patterns
(CREATE metadata, omit subcall gas, protected=fork.supports_protected_txs,
absolute-vs-delta gas, degraded-port restoration).

Claude-Session: https://claude.ai/code/session_01FxUr7ixeLr8apwbNzBLgNo
Fold the six stEIP150singleCodeGasPrices RawCreate*Gas fillers (plain, memory,
value-transfer, value-transfer-memory, and two insufficient-balance failures)
into one CodeGasMeasure parametrize on (create_value, size, fails). Un-skips 6
Amsterdam entries (224 -> 218) and lowers the floor to SpuriousDragon.

Confirms the EIP-8037 error-path question: a balance-failure CREATE runs no
init code and creates no account, so it charges regular gas only. Success
asserts create_code.gas_cost(fork) (regular + state); failure asserts
create_code.regular_cost(fork) — one expression correct on every fork.

Skill updated: error-path regular_cost split (resolves a known gap), and a new
known gap for the 63/64 callee-side *_gas_ask shape.

Claude-Session: https://claude.ai/code/session_01FxUr7ixeLr8apwbNzBLgNo
The ported MCOPY_copy_cost filler probed the copy cost indirectly via a razor-
thin OOG gas boundary (gas_limit 55697): a flag SSTORE ran, then the MCOPY, and
slot 0 stayed set only if the whole thing fit. EIP-8037 reprices that flag
SSTORE (zero->non-zero) into ~97920 state gas, which alone exceeds the budget,
so every case OOGs on Amsterdam.

Reframe to measure the MCOPY copy cost directly with CodeGasMeasure: pre-expand
memory past the largest copy region so the measured MCOPY charges only its
base + per-word copy cost (never expansion), and assert the fork-derived
mcopy.gas_cost(fork). Parametrized over the same (src, size) matrix; a pure
execution-gas op, so it is fork-robust. Un-skips 55 Amsterdam entries
(218 -> 163).

Claude-Session: https://claude.ai/code/session_01FxUr7ixeLr8apwbNzBLgNo
Fold the ten stEIP150singleCodeGasPrices RawCall*GasAsk fillers (CALL / CALLCODE
/ DELEGATECALL x value-transfer x memory) into one parametrize that verifies the
EIP-150 "all but one 64th" gas-forwarding rule. Un-skips 10 Amsterdam entries
(163 -> 153).

The ported fillers pinned the forwarded gas as an absolute number tied to the tx
gas limit, which the EIP-2780 intrinsic change makes fork-fragile. Reframed
(approach by @marioevz): an outer call caps the caller frame at a known gas
budget so the forwarded amount is deterministic; the callee returns its observed
GAS up to the top frame (no lower-frame SSTORE state-gas trap); the expected
value is derived from the fork as all_but_one_64th(CALLER_GAS -
call.gas_cost(fork)) + stipend - GAS. Note: the cap is available -
available // 64, NOT available * 63 // 64 (they differ by 1 off a multiple).

Skill updated with the forwarded-gas / 63/64 pattern and the // 64 gotcha.

Claude-Session: https://claude.ai/code/session_01FxUr7ixeLr8apwbNzBLgNo
@marioevz
marioevz requested a review from spencer-tb July 23, 2026 09:01
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (forks/amsterdam@2282c75). Learn more about missing BASE report.
⚠️ Report is 26 commits behind head on forks/amsterdam.

Additional details and impacted files
@@                Coverage Diff                 @@
##             forks/amsterdam    #3215   +/-   ##
==================================================
  Coverage                   ?   93.42%           
==================================================
  Files                      ?      625           
  Lines                      ?    37032           
  Branches                   ?     3385           
==================================================
  Hits                       ?    34597           
  Misses                     ?     1666           
  Partials                   ?      769           
Flag Coverage Δ
unittests 93.42% <ø> (?)

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.

@spencer-tb

Copy link
Copy Markdown
Contributor

Added some extra tweaks here: marioevz#7

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

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.

2 participants