Skip to content

state: Replace State::find() with the nonexistent account flag - #1712

Merged
chfast merged 1 commit into
masterfrom
state/nonexistent-account-flag
Oct 7, 2026
Merged

chfast merged 1 commit into
masterfrom
state/nonexistent-account-flag

Conversation

@chfast

@chfast chfast commented Sep 14, 2026 •

Copy link
Copy Markdown
Member

State::find() returned nullptr for a missing account, so every
caller split into two cases and nothing could be recorded about an
account which does not exist. get() now always returns Account& and
the nonexistent flag answers "does this account exist?".

  • The miss is cached, so the initial state is queried once per address
    rather than once per access.
  • A cold access warms the account in place without creating it, so an
    address which never existed no longer reaches the StateDiff as a
    no-op deletion (part of state: build_diff() reports deletions for accounts that never existed #1718). The access_nonexistent test pins
    this.
  • get_or_create(), touch() and get_or_insert() create an account
    in place by clearing the flag. This replaces insert() and
    journal_new_account().
  • Reverting to nonexistent clears what a reverted CREATE left behind
    (nonce, code, just_created, code_changed), now reachable through
    the reference. Asserts pin that a nonexistent account holds no change
    and that the rollback restores the balance and the nonce before the
    flags entry un-creates the account.

No consensus change. Only the state diff changes: an address which is
only warmed no longer appears in it, neither as a no-op deletion of a
missing account nor as an unchanged existing precompile. On the CodSpeed
benchmarks the instruction count is slightly lower overall; precompile
calls get a few percent faster from the cached miss.

@codspeed

codspeed Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will regress 6 benchmarks

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 82 improved benchmarks
❌ 6 regressed benchmarks
✅ 811 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ test_calldatasize[fork_Osaka-blockchain_test-zero_data_True-calldata_size_32-benchmark-gas-value_1M] 16.9 ms 17.4 ms -2.9%
❌ test_msize[fork_Osaka-blockchain_test-mem_size_1-benchmark-gas-value_1M] 16.2 ms 16.4 ms -1.63%
❌ test_dup[fork_Osaka-blockchain_test-opcode_DUP5-benchmark-gas-value_1M] 12.3 ms 12.5 ms -1.55%
❌ test_msize[fork_Osaka-blockchain_test-mem_size_1000-benchmark-gas-value_1M] 15.9 ms 16.1 ms -1.45%
❌ test_dup[fork_Osaka-blockchain_test-opcode_DUP6-benchmark-gas-value_1M] 12.3 ms 12.5 ms -1.19%
❌ test_block_context_ops[fork_Osaka-blockchain_test-opcode_TIMESTAMP-benchmark-gas-value_1M] 20.6 ms 20.9 ms -1.09%
⚡ test_identity_fixed_size[fork_Osaka-blockchain_test-size_0-benchmark-gas-value_1M] 14.3 ms 13.5 ms +6.2%
⚡ test_identity_fixed_size[fork_Osaka-blockchain_test-size_32-benchmark-gas-value_1M] 14.5 ms 13.7 ms +6.02%
⚡ test_identity_fixed_size[fork_Osaka-blockchain_test-size_256-benchmark-gas-value_1M] 13.5 ms 12.8 ms +5.58%
⚡ test_blake2f_benchmark[fork_Osaka-blockchain_test-num_rounds_1-benchmark-gas-value_1M] 18.8 ms 17.8 ms +5.3%
⚡ test_identity_fixed_size[fork_Osaka-blockchain_test-size_1024-benchmark-gas-value_1M] 11.8 ms 11.3 ms +4.44%
⚡ test_blake2f_benchmark[fork_Osaka-blockchain_test-num_rounds_6-benchmark-gas-value_1M] 24.7 ms 23.8 ms +3.82%
⚡ test_ext_account_query_cold[fork_Osaka-blockchain_test-absent_accounts_True-opcode_BALANCE-benchmark-gas-value_1M] 3 ms 2.9 ms +3.69%
⚡ test_ext_account_query_warm[fork_Osaka-blockchain_test-initial_storage_False-initial_balance_False-empty_code_True-opcode_STATICCALL-benchmark-gas-value_1M] 14 ms 13.6 ms +3.36%
⚡ test_ext_account_query_warm[fork_Osaka-blockchain_test-initial_storage_False-initial_balance_True-empty_code_True-opcode_STATICCALL-benchmark-gas-value_1M] 14.1 ms 13.7 ms +3.25%
⚡ test_ext_account_query_warm[fork_Osaka-blockchain_test-initial_storage_True-initial_balance_False-empty_code_True-opcode_STATICCALL-benchmark-gas-value_1M] 14.1 ms 13.6 ms +3.2%
⚡ test_ext_account_query_warm[fork_Osaka-blockchain_test-initial_storage_False-initial_balance_False-empty_code_True-opcode_CALL-benchmark-gas-value_1M] 14.5 ms 14.1 ms +3.19%
⚡ test_ext_account_query_warm[fork_Osaka-blockchain_test-initial_storage_True-initial_balance_True-empty_code_True-opcode_STATICCALL-benchmark-gas-value_1M] 14.1 ms 13.6 ms +3.18%
⚡ test_ext_account_query_warm[fork_Osaka-blockchain_test-initial_storage_False-initial_balance_True-empty_code_True-opcode_CALL-benchmark-gas-value_1M] 14.6 ms 14.2 ms +3.16%
⚡ test_selfbalance[fork_Osaka-blockchain_test-contract_balance_0-benchmark-gas-value_1M] 41.2 ms 39.9 ms +3.08%
... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing state/nonexistent-account-flag (73ff6aa) with master (f282290)

Open in CodSpeed

@codecov

codecov Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.06%. Comparing base (f282290) to head (73ff6aa).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1712   +/-   ##
=======================================
  Coverage   98.06%   98.06%           
=======================================
  Files         183      183           
  Lines       16915    16940   +25     
  Branches     3879     3873    -6     
=======================================
+ Hits        16587    16613   +26     
  Misses        245      245           
+ Partials       83       82    -1     
Flag Coverage Δ
eest-develop-gmp 25.86% <83.33%> (+0.02%) ⬆️
eest-legacy 17.05% <74.44%> (-0.04%) ⬇️
eest-libsecp256k1 28.05% <83.33%> (+0.01%) ⬆️
eest-stable 83.88% <100.00%> (+0.02%) ⬆️
evmone-unittests 94.24% <98.88%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
core 96.25% <100.00%> (+0.02%) ⬆️
tooling 94.29% <ø> (ø)
tests 99.81% <100.00%> (+<0.01%) ⬆️
Files with missing lines Coverage Δ
test/state/account.hpp 100.00% <ø> (ø)
test/state/host.cpp 100.00% <100.00%> (+0.45%) ⬆️
test/state/state.cpp 99.11% <100.00%> (+0.02%) ⬆️
test/state/state.hpp 100.00% <ø> (ø)
test/unittests/state_transition_touch_test.cpp 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Base automatically changed from state/access-account-journal-order to master September 15, 2026 07:32
@chfast
chfast force-pushed the state/nonexistent-account-flag branch 4 times, most recently from cdfb329 to 0d4f740 Compare October 7, 2026 09:43
@chfast
chfast requested a balanced review from Copilot October 7, 2026 09:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Consensus-sensitive account creation and rollback changes need execution-spec validation and final human review.

Review effort: Balanced
Findings: None

What changed in this PR

Refactors account lookup to use cached records with a nonexistent flag instead of nullable pointers.

Changes:

  • Caches missing accounts and simplifies state and host lookups.
  • Keeps cold accesses to absent accounts out of state diffs, partially addressing #1718.
  • Clears reverted creation fields and adds invariant checks.
File Description
test/​unittests/​state_transition_touch_test.cpp Tests absent-account access without diff entries.
test/​state/​state.hpp Updates lookup and creation interfaces.
test/​state/​state.cpp Implements cached misses, in-place creation, and rollback cleanup.
test/​state/​host.cpp Uses reference-based lookups and warms absent accounts without creating them.
test/​state/​account.hpp Clarifies account flags and remaining rollback limitations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

find() returned nullptr for a missing account, so callers handled absence
separately and nothing could be recorded about an account which does not
exist. Return a reference always and let the nonexistent flag answer "does
this account exist?". The miss is then cached, a cold access warms the
account without creating it, and get_or_create(), touch() and
get_or_insert() create an account in place by clearing the flag; this
replaces insert() and journal_new_account(). Reverting to nonexistent also
clears what a reverted CREATE left behind, now reachable through the
reference.

Only the state diff changes: an address which is only warmed no longer
appears in it, neither as a no-op deletion of a missing account nor as an
unchanged existing precompile.
@chfast
chfast force-pushed the state/nonexistent-account-flag branch from 0d4f740 to 73ff6aa Compare October 7, 2026 11:08
@chfast
chfast requested a balanced review from Copilot October 7, 2026 11:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Consensus-sensitive account creation and rollback changes warrant final human verification.

Review effort: Balanced
Findings: None

@chfast
chfast merged commit 39425f3 into master Oct 7, 2026
30 of 31 checks passed
@chfast
chfast deleted the state/nonexistent-account-flag branch October 7, 2026 11:57
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