Skip to content

Compute the create address in the VM#1589

Open
chfast wants to merge 2 commits into
masterfrom
evmc/vm-computed-create-address
Open

Compute the create address in the VM#1589
chfast wants to merge 2 commits into
masterfrom
evmc/vm-computed-create-address

Conversation

@chfast

@chfast chfast commented Jul 13, 2026

Copy link
Copy Markdown
Member

The create address was computed host-side (Host::prepare_message), one
EVMC crossing too late: msg.recipient traveled down empty and was
filled midway, the EIP-2681 nonce-overflow light-fail lived in the host
while the depth and balance light-fails lived in the VM, the EIP-2929
warming happened host-side where EELS does it in the creating frame,
and the parent could learn what it created only from
evmc_result.create_address.

Compute the address in create_impl instead: read the sender's nonce via
get_nonce (unifying the EIP-2681 light-fail with depth/balance), derive
the CREATE/CREATE2 address, warm it in the creating frame,
and pass it down in msg.recipient - the same
VM-resolved-message pattern as code_address for EIP-7702 delegations.
This leaves evmc_result.create_address and evmc_message.create2_salt
without readers: drop both and bump EVMC_ABI_VERSION to 16.

Host::prepare_message dissolves. The creator-nonce bump stays in
Host::call before the state checkpoint: per the Yellow Paper it
survives a failed creation. At depth 0, build_message computes the
deployment address from tx.nonce.

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.

Pull request overview

This PR moves CREATE/CREATE2 address derivation into the VM (so msg.recipient is set before the evmc_call boundary), aligns EIP-2681/EIP-2929 handling with that new flow, and updates the EVMC interface by removing evmc_result.create_address and bumping the ABI version.

Changes:

  • Compute CREATE/CREATE2 addresses inside create_impl(), warm the created address in the creating frame, and pass it down via evmc_message::recipient.
  • Remove evmc_result.create_address / the corresponding C++ wrapper APIs and bump EVMC_ABI_VERSION to 16.
  • Update state tests, unit tests, and fuzz harness logic to use VM-computed created addresses.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/unittests/tracing_test.cpp Updates expected trace output to reflect VM-computed CREATE address.
test/unittests/evm_other_test.cpp Adjusts recorded-call expectations based on nonzero CREATE return value affecting later stack/memory behavior.
test/unittests/evm_eip3860_initcode_test.cpp Stops depending on host-supplied create_address; validates VM-produced nonzero return on success.
test/unittests/evm_calls_test.cpp Switches assertions from mocked call_result.create_address to compute_create*_address() helpers.
test/state/state.cpp Computes/warmups create-tx deployment address up front and adjusts code_address initialization.
test/state/host.hpp Re-exports compute_create*_address() from the new library header; removes local declarations.
test/state/host.cpp Removes prepare_message(), shifts nonce bumping into Host::call(), and relies on VM-populated msg.recipient for creates.
test/fuzzer/fuzzer.cpp Stops synthesizing result.create_address from output bytes.
lib/evmone/instructions_calls.cpp Computes create address in create_impl(), does EIP-2681 check in VM, warms created address (Berlin+), and pushes computed address on success.
lib/evmone/create_address.hpp Introduces header-only compute_create_address() / compute_create2_address() helpers.
lib/evmone/CMakeLists.txt Adds create_address.hpp to the library sources.
evmc/include/evmc/evmc.hpp Removes Result::create_address exposure and the “create-result” constructor overload.
evmc/include/evmc/evmc.h Bumps ABI version, clarifies CREATE recipient semantics, and removes evmc_result.create_address.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/state/host.cpp Outdated
Comment on lines +184 to +186
// The VM computes the created account's address (and warms it, EIP-2929) and
// performs the EIP-2681 nonce-overflow check before entering the create frame.
assert(msg.recipient != address{});
@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.40%. Comparing base (056dc2a) to head (d9241c7).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1589   +/-   ##
=======================================
  Coverage   97.39%   97.40%           
=======================================
  Files         164      164           
  Lines       14666    14655   -11     
  Branches     3390     3388    -2     
=======================================
- Hits        14284    14274   -10     
+ Misses        282      280    -2     
- Partials      100      101    +1     
Flag Coverage Δ
eest-develop 89.44% <100.00%> (-0.01%) ⬇️
eest-develop-gmp 26.06% <60.41%> (-0.05%) ⬇️
eest-legacy 17.48% <54.16%> (-0.05%) ⬇️
eest-libsecp256k1 27.69% <60.41%> (-0.05%) ⬇️
eest-stable 89.42% <100.00%> (-0.01%) ⬇️
evmone-unittests 92.63% <100.00%> (+<0.01%) ⬆️

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

Components Coverage Δ
core 95.94% <100.00%> (+0.01%) ⬆️
tooling 90.33% <ø> (ø)
tests 99.80% <100.00%> (ø)
Files with missing lines Coverage Δ
lib/evmone/instructions_calls.cpp 99.27% <100.00%> (+0.05%) ⬆️
test/state/host.cpp 99.52% <100.00%> (+0.40%) ⬆️
test/state/host.hpp 100.00% <ø> (ø)
test/state/state.cpp 99.68% <100.00%> (-0.01%) ⬇️
test/unittests/evm_calls_test.cpp 99.80% <100.00%> (ø)
test/unittests/evm_eip3860_initcode_test.cpp 100.00% <100.00%> (ø)
test/unittests/evm_other_test.cpp 100.00% <100.00%> (ø)
test/unittests/tracing_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.

chfast added a commit that referenced this pull request Jul 14, 2026
compute_create_address() and compute_create2_address() are defined in
the testing host (test/state/host.{hpp,cpp}) although they are not
Host-specific, and the VM itself will need them once it computes the
create address instead of the Host (#1589).

Move them to the new TU lib/evmone/create_address.{hpp,cpp} in the
evmone namespace. The implementations are unchanged except the
keccak256() host-utils wrapper being replaced by the direct
ethash::keccak256() call. The functions are marked EVMC_EXPORT so the
testing code can still reach them across the libevmone shared-library
boundary (same as get_delegate_address()).

Also rename state_new_account_address_test.cpp (and its test suite) to
create_address_test.cpp to match.

Claude-Session: https://claude.ai/code/session_01R8uyb9z8VwgRrEKRanDPP8
chfast added a commit that referenced this pull request Jul 14, 2026
compute_create_address() and compute_create2_address() are defined in
the testing host (test/state/host.{hpp,cpp}) although they are not
Host-specific, and the VM itself will need them once it computes the
create address instead of the Host (#1589).

Move them to the new TU lib/evmone/create_address.{hpp,cpp} in the
evmone namespace. The implementations are unchanged except the
keccak256() host-utils wrapper being replaced by the direct
ethash::keccak256() call. The functions are marked EVMC_EXPORT so the
testing code can still reach them across the libevmone shared-library
boundary.
@chfast chfast force-pushed the evmc/vm-computed-create-address branch from 6b36008 to 81b3ba9 Compare July 14, 2026 12:33
@chfast chfast requested a review from Copilot July 14, 2026 12:35

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.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

The create address was computed host-side (Host::prepare_message), one
EVMC crossing too late: msg.recipient traveled down empty and was
filled midway, the EIP-2681 nonce-overflow light-fail lived in the host
while the depth and balance light-fails lived in the VM, the EIP-2929
warming happened host-side where EELS does it in the creating frame,
and the parent could learn what it created only from
evmc_result.create_address.

Compute the address in create_impl instead: read the sender's nonce via
get_nonce (unifying the EIP-2681 light-fail with depth/balance), derive
the CREATE/CREATE2 address, warm it in the creating frame (EELS:
generic_create), and pass it down in msg.recipient - the same
VM-resolved-message pattern as code_address for EIP-7702 delegations.
This leaves evmc_result.create_address and evmc_message.create2_salt
without readers: drop both and bump EVMC_ABI_VERSION to 16.

Host::prepare_message dissolves. The creator-nonce bump stays in
Host::call before the state checkpoint: per the Yellow Paper it
survives a failed creation. At depth 0, build_message computes the
deployment address from tx.nonce.

Behavior-identical: the EEST glamsterdam-devnet@v7.2.0 state-test
failure set is bit-identical to master's.

Claude-Session: https://claude.ai/code/session_01R8uyb9z8VwgRrEKRanDPP8
@chfast chfast force-pushed the evmc/vm-computed-create-address branch from 767d513 to 1258466 Compare July 14, 2026 15:30

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.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

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