Skip to content

[test/vm] Replace evmc::MockedHost with an in-tree mock host - #2561

Open
khordadi wants to merge 1 commit into
mainfrom
akhordadi/exe-161-replace-evmcmockedhost-with-an-in-tree-mock-host-for-vm-unit
Open

khordadi wants to merge 1 commit into
mainfrom
akhordadi/exe-161-replace-evmcmockedhost-with-an-in-tree-mock-host-for-vm-unit

Conversation

@khordadi

@khordadi khordadi commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Closes EXE-161, part of EXE-162. The VM unit tests no longer depend on evmc::MockedHost, so the vm::Host port (EXE-173) has one test host to move instead of two, and evmc::mocked_host leaves the test link line.

What changes. test/vm/utils/mocked_host.hpp replaces the test/vm/unit/runtime wrapper, which layered MIP-8 page tracking over evmc's mock. It implements vm::Host directly, including update_page, carries the page tracking over on the production compute_page_key, and keys its state on Address/bytes32_t; evmc types remain only where the vm::Host virtuals require them. It sits in monad-vm-test-utils so the fuzzer and benchmark targets can pick it up later without a new target.

Storage status. The EIP-2200 status is the one piece of logic rewritten rather than moved. mocked_host_tests.cpp checks the fifteen original -> current -> new transitions listed on evmc_storage_status; they partition the three values by zero-ness and pairwise equality, so the table is exhaustive. The runtime storage tests reach only the six clean-slot cases, and the spec comparison drives both VMs through the same mock, so neither would notice a wrong dirty-slot status.

Behaviour. No test-observable change. evm_fixture.hpp and monad_vm_interface_tests.cpp used evmc::MockedHost directly and now get the wrapper's semantics: access_storage warmth per page rather than per slot, and update_page from the page set rather than from the storage status. The only SSTORE either reaches runs under execute_and_compare, pinned to MONAD_EIGHT where MIP-8 is inactive.

Dropped, nothing uses them:

  • the 100/200 caps on recorded calls and account accesses
  • the copy of call input bytes behind recorded_calls (its pointer fields are nulled on record)
  • MockedAccount::nonce
  • the per-slot access flag the wrapper never returned
  • access_storage's side effect of creating the account and slot (account_exists after SLOAD on an absent account is now false)
  • the second recorded_account_accesses entry per SSTORE from the wrapper's extra get_storage
  • evmc's always-warm rule for 0x01..0x09 in access_account (production decides that per fork in EvmcHost; tests that need a warm address pre-warm it)

Verification.

vm-unit-tests main this PR
gcc-15 RelWithDebInfo 1291 passed / 34 skipped 1292 / 34
clang-19 ASAN+UBSAN, spec comparison on 1785 / 196 1786 / 196

The difference is the new test. monad-compiler-fuzzer, execution-benchmarks, vm-micro-benchmarks and mce build. clang-format-19 and clang-tidy-19 clean on the new files.

Review map: test/vm/utils/mocked_host.hpp (storage_status, then the virtuals) → test/vm/unit/mocked_host_tests.cpp → the five include/type swaps → the deleted wrapper.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings September 15, 2026 14:22

Copilot AI 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.

🟢 Approval recommended

No unresolved issues were identified, and all assessments indicate readiness.

Pull request overview

Replaces EVMC’s mocked host with an in-tree vm::Host implementation for VM tests.

Changes:

  • Adds page-aware storage and exhaustive EIP-2200 status tests.
  • Migrates fixtures and interface tests to the shared mock host.
  • Removes the obsolete wrapper and EVMC mock linkage.
File summaries
File Description
test/vm/utils/mocked_host.hpp Adds the in-tree mock host.
test/vm/utils/CMakeLists.txt Registers the shared mock header.
test/vm/unit/runtime/mocked_host.hpp Removes the obsolete wrapper.
test/vm/unit/runtime/fixture.hpp Uses the shared mock host.
test/vm/unit/runtime/fixture.cpp Updates account construction.
test/vm/unit/monad_vm_interface_tests.cpp Migrates interface tests.
test/vm/unit/mocked_host_tests.cpp Adds storage-status transition tests.
test/vm/unit/evm_fixture.hpp Uses the shared mock host.
test/vm/unit/CMakeLists.txt Adds tests and removes EVMC mock linkage.
Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 0
  • Review effort level: Lite

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

Comment thread test/vm/utils/mocked_host.hpp

@github-actions github-actions Bot 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.

Reviewed this replacement of evmc::MockedHost with the in-tree monad::vm::test::MockedHost.

What was verified:

  • The new storage_status implementation matches evmc's EIP-2200 logic exactly; the new MockedHost.StorageStatus test covers all 15 (original, current, value) transition classes and passes (verified by building and running it standalone).
  • access_account, selfdestruct, get_storage, set_storage, account_exists, get_balance, copy_code, transient storage, and block-hash recording all reproduce the vendored evmc::MockedHost semantics, including the EIP-2929 precompile warm range (0x01–0x09) and the record-then-check warmth behavior.
  • The page-based access_storage / update_page behavior (compute_page_key from storage_page.hpp, PAGE_KEY_SHIFT == 7) is identical to the deleted test/vm/unit/runtime/mocked_host.hpp wrapper, so the runtime fixture tests keep their previous semantics. The tests migrated off pure evmc::MockedHost (evm_fixture, monad_vm_interface_tests) don't exercise storage warmth, so no behavior-sensitive test is affected.
  • No remaining references to evmc/mocked_host.hpp anywhere in the tree, so dropping the evmc::mocked_host link from vm-unit-tests is safe. The new header compiles standalone, and the fixture.cpp designated initializer matches the new MockedAccount field order.

One non-blocking note posted inline: the dangling input_data/code pointers retained in recorded_calls (documented, but worth hardening).

Verdict: CORRECT

🤖 Generated with Claude Code

Comment thread test/vm/utils/mocked_host.hpp Outdated
@khordadi
khordadi force-pushed the akhordadi/exe-161-replace-evmcmockedhost-with-an-in-tree-mock-host-for-vm-unit branch from 748244a to fa5c51b Compare September 15, 2026 16:10
Closes EXE-161, part of EXE-162. The VM unit tests no longer depend on
evmc::MockedHost, so the vm::Host port (EXE-173) has one test host to move
instead of two, and evmc::mocked_host leaves the test link line.

test/vm/utils/mocked_host.hpp replaces the test/vm/unit/runtime wrapper,
which layered MIP-8 page tracking over evmc's mock. It implements vm::Host
directly, including update_page, carries the page tracking over on the
production compute_page_key, and keys its state on Address/bytes32_t; evmc
types remain only where the vm::Host virtuals require them. It sits in
monad-vm-test-utils so the fuzzer and benchmark targets can pick it up later
without a new target.

The EIP-2200 storage status is the one piece of logic rewritten rather than
moved. mocked_host_tests.cpp checks the fifteen original -> current -> new
transitions listed on evmc_storage_status; they partition the three values
by zero-ness and pairwise equality, so the table is exhaustive. The runtime
storage tests reach only the six clean-slot cases, and the spec comparison
drives both VMs through the same mock, so neither would notice a wrong
dirty-slot status.

No test-observable behaviour change. evm_fixture.hpp and
monad_vm_interface_tests.cpp used evmc::MockedHost directly and now get the
wrapper's semantics: access_storage warmth per page rather than per slot,
and update_page from the page set rather than from the storage status; the
only SSTORE either reaches runs under execute_and_compare, pinned to
MONAD_EIGHT where MIP-8 is inactive. Dropped because no test uses them: the
100/200 caps on recorded calls and account accesses, the copy of call input
bytes behind recorded_calls (its pointer fields are nulled on record),
MockedAccount::nonce, the per-slot access flag
the wrapper never returned, access_storage's side effect of creating the
account and slot (account_exists after SLOAD on an absent account is now
false), the second recorded_account_accesses entry per SSTORE from the
wrapper's extra get_storage, and evmc's always-warm rule for 0x01..0x09 in
access_account (production decides that per fork in EvmcHost; tests that
need a warm address pre-warm it).

vm-unit-tests: gcc 1292 passed / 34 skipped (main 1291 / 34); clang
ASAN+UBSAN with the spec comparison 1786 / 196 (main 1785 / 196). The
difference is the new test. monad-compiler-fuzzer, execution-benchmarks,
vm-micro-benchmarks and mce build.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@khordadi
khordadi force-pushed the akhordadi/exe-161-replace-evmcmockedhost-with-an-in-tree-mock-host-for-vm-unit branch from fa5c51b to 3fc0faa Compare September 15, 2026 18:07
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