Skip to content

refactor: move EIP-161 state clear into journal finalize#3444

Merged
rakita merged 3 commits intobluealloy:mainfrom
decofe:klkvr/remove-state-clear-flag
Feb 26, 2026
Merged

refactor: move EIP-161 state clear into journal finalize#3444
rakita merged 3 commits intobluealloy:mainfrom
decofe:klkvr/remove-state-clear-flag

Conversation

@decofe
Copy link
Copy Markdown
Collaborator

@decofe decofe commented Feb 25, 2026

Summary

Move has_state_clear / set_state_clear_flag out of the database layer (CacheState / State<DB>) and into JournalInner::finalize(), where the SpecId is already available.

Motivation

set_state_clear_flag couples the database layer to chainspec knowledge. Block executors need extra chainspec-aware setup before each block just to handle a deprecated pre-Spurious Dragon behavior. This prevents executors from working with arbitrary Database implementations without that setup.

Changes

  • JournalInner::finalize(): normalize pre-EIP-161 empty touched accounts before returning EvmState
    • LoadedAsNotExistingmark_created() (materialize)
    • Already existing → unmark_touch() (preserve)
  • CacheState: remove has_state_clear field, set_state_clear_flag(), and pre-EIP-161 branch in apply_account_state() — always uses post-EIP-161 semantics
  • State<DB>: remove set_state_clear_flag()
  • StateBuilder: remove with_state_clear field and without_state_clear()
  • revme statetest runner: remove set_state_clear_flag calls

Zero perf impact for post-Spurious Dragon blocks (the finalize() iteration is gated behind !spec.is_enabled_in(SPURIOUS_DRAGON)).

Prompted by: arsenii

Remove `has_state_clear` flag from `CacheState` and `set_state_clear_flag`
from `State<DB>`. The database layer now always applies post-EIP-161
commit semantics (empty touched accounts are destroyed).

Pre-EIP-161 behavior is handled in `JournalInner::finalize()` which
normalizes accounts before they reach the database:
- Empty touched accounts that didn't exist: marked as Created
  (materialized)
- Empty touched existing accounts: touch flag cleared (preserved)

This eliminates the need for callers to configure state_clear per-block,
making block executors work with any database without chainspec-aware
setup.

Co-authored-by: Arsenii Kulikov <klkvr@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019c969c-8b41-7096-a8f0-54662b4776bf
Co-authored-by: Amp <amp@ampcode.com>
@decofe decofe force-pushed the klkvr/remove-state-clear-flag branch from 0e68f89 to c014ffe Compare February 25, 2026 22:12
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Feb 25, 2026

Merging this PR will improve performance by 4.72%

⚡ 2 improved benchmarks
✅ 174 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
MSTORE_50 19 µs 18.1 µs +4.72%
MSTORE_COLD_50 23.1 µs 22.4 µs +3.34%

Comparing decofe:klkvr/remove-state-clear-flag (4c40bae) with main (6ef1006)

Open in CodSpeed

Copy link
Copy Markdown
Member

@rakita rakita left a comment

Choose a reason for hiding this comment

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

good change!

@rakita rakita merged commit f06cdd8 into bluealloy:main Feb 26, 2026
31 checks passed
@github-actions github-actions bot mentioned this pull request Feb 26, 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