feat(tests): pin the BAL for contract creation over a storage-only account - #3588
Draft
spencer-tb wants to merge 2 commits into
Draft
spencer-tb wants to merge 2 commits into
spencer-tb wants to merge 2 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## forks/amsterdam #3588 +/- ##
===================================================
+ Coverage 94.01% 94.44% +0.43%
===================================================
Files 624 624
Lines 36905 36990 +85
Branches 3326 3345 +19
===================================================
+ Hits 34695 34937 +242
+ Misses 1533 1450 -83
+ Partials 677 603 -74
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…count Diff storage writes that follow a same-transaction wipe against zero in the Amsterdam BAL builder, as it already does for a wipe by an earlier transaction, and add three BAL tests (38 cases) for a creation landing on an account with zero nonce, no code and non-empty storage.
spencer-tb
force-pushed
the
tests/amsterdam/bal-create-storage-only-target
branch
from
September 15, 2026 10:39
0af5725 to
41e5543
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Stacked on #3508: only the last commit is new, the first is #3508's. The new commit changes one function in the Amsterdam BAL builder and adds the tests.
What
Three BAL tests (38 cases) that pin what the block access list shows when a contract creation lands on an account with zero nonce, no code and non-empty storage, now that #3508 makes the creation wipe that storage:
test_bal_create_tx_storage_only_target(12 cases) andtest_bal_create_opcode_storage_only_target(24, CREATE and CREATE2). The init code leaves the wiped slots alone, reads one, rewrites one to its old value, writes a new value, reads then reverts, or selfdestructs; the target has balance 0 or 1.test_bal_cross_tx_create_storage_only_target_then_call(2 cases). Tx1 creates over the account, tx2 reads or rewrites a wiped slot.What they pin:
storage_read;storage_change, compared against the wiped value like a rewrite by a later transaction;storage_change;storage_change, since the block-level pre-tx value is 0 after the wipe.Spec change
_get_pre_tx_storagein the Amsterdam BAL builder now returns 0 for an address in the current transaction'sstorage_clears, as it already did (from #3508) for the block's. Before this, a slot wiped and then written in the same transaction was compared against the pre-block value, so restoring that value counted as a no-op while the same rewrite by a later transaction counted as a change. Where the wipe falls relative to a transaction boundary should not change the reference value. It is also what nethermind, reth and besu produce (table below), since their original-value snapshot is taken after the clear. No other Amsterdam expectation moves: the full EIP-7928 directory refills identically.Verification
tests/amsterdam/eip7928_block_level_access_lists/directory fills 2172/2172 on the branch.forks/amsterdamwithout fix(spec-specs): wipe pre-existing storage on contract creation from Cancun onward #3508 fails 26/38. Only the revert and selfdestruct arms pass, since their end state is identical under keep or wipe.just staticclean.Client survey
Read at today's master/main heads, not run (geth 94548a1, nethermind 0d43dbdf, reth c3f0746 with revm 43.0.2, besu 9c80643, erigon d6735e9, all 2026-09-15):
Each column is an arm: post-state slot 2 on every non-revert arm (wipe vs keep), the strict empty
storage_changeson the untouched arm (omission), therewrite_old_valuearm, and the cross-txread_wiped_slotcase.Expected client outcomes
By code reading:
Nethermind matches EELS, and every remaining failure is an inconsistency inside that client rather than a test convention: geth reuses the existing account object so the empty-storage start never happens, reth wipes in the EVM but persists and roots the old slots, besu clears the storage but its accumulator does not consult the cleared set when reading from the flat DB, and erigon's write normaliser still assumes a creation does not wipe pre-existing storage, a comment left over from before its 7610 removal.
Two caveats. Nethermind's parallel BAL-validation path treats the clear as a no-op, which could bite the read arms under engine validation; whether it falls back to sequential execution was not traced. And the current
glamsterdam-devnet-8hive images are older than these heads: besu's and erigon's still abort on EIP-7610 there, so a hive run today would show 0 / 38 for both until their images catch up with main.None of this is reachable on mainnet: it needs a create address colliding with one of the 28 storage-only accounts, and EIP-8253 gives those nonce 1. Whether these fixtures ship in a release is an ACDT call; as they stand they document the divergence.
Related Issues or PRs
Stacked on #3508. Related to #3417, #3425, ethereum/legacytests#18 and EIP-8253.
Checklist
just static<type>(<area>): <title>, where<type>and<area>come from an appropriateC-<type>, respectivelyA-<area>, label. The title should match the target squash commit message.