Skip to content

Commit cb698c8

Browse files
Baltoliclaude
andcommitted
[vm] Extract FuzzerBackend abstraction from evmone types
Introduce a FuzzerBackend interface that abstracts state management and execution away from evmone-specific types. The fuzzer's core run loop now programs against this interface, with EvmoneBackend as the concrete implementation. This is step 1 of removing evmone as a dependency: the evmone state types (State, Account, StorageValue, Host, Transaction, BlockInfo, TestState, TestBlockHashes) are now confined to evmone_backend.cpp. The fuzzer core only sees FuzzerBackend, SortedStateView, and EVMC types. State comparison uses a sorted-view model with virtual cursors wrapped in move-only C++ input iterators, enabling std::views::zip for lockstep comparison of storage and transient storage across backends. New files: - fuzzer_backend.hpp: FuzzerBackend abstract class - fuzzer_view.hpp/cpp: SortedStateView, SortedStorageView, SortedTransientStorageView, Cursor<T>, CursorIterator<T>, assert_states_equal - evmone_backend.hpp/cpp: EvmoneBackend implementation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f5111a6 commit cb698c8

File tree

9 files changed

+860
-330
lines changed

9 files changed

+860
-330
lines changed

test/vm/fuzzer/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ target_sources(monad-compiler-fuzzer PRIVATE
1919
assertions.cpp
2020
assertions.hpp
2121
compiler_hook.hpp
22-
fuzzer.cpp)
22+
evmone_backend.hpp
23+
evmone_backend.cpp
24+
fuzzer.cpp
25+
fuzzer_backend.hpp
26+
fuzzer_backend.cpp
27+
fuzzer_view.hpp)
2328

2429
target_link_libraries(monad-compiler-fuzzer
2530
PRIVATE evmone::state

test/vm/fuzzer/assertions.cpp

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,66 +13,20 @@
1313
// You should have received a copy of the GNU General Public License
1414
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1515

16-
#include "account.hpp"
17-
#include "state.hpp"
16+
#include "assertions.hpp"
17+
#include "fuzzer_view.hpp"
1818

1919
#include <category/core/assert.h>
2020

2121
#include <evmc/evmc.h>
2222
#include <evmc/evmc.hpp>
2323

2424
#include <algorithm>
25+
#include <ranges>
2526
#include <span>
2627

27-
using namespace evmone::state;
28-
2928
namespace monad::vm::fuzzing
3029
{
31-
void assert_equal(StorageValue const &a, StorageValue const &b)
32-
{
33-
MONAD_ASSERT(a.current == b.current);
34-
MONAD_ASSERT(a.original == b.original);
35-
MONAD_ASSERT(a.access_status == b.access_status);
36-
}
37-
38-
void assert_equal(Account const &a, Account const &b)
39-
{
40-
MONAD_ASSERT(a.transient_storage.size() == b.transient_storage.size());
41-
for (auto const &[k, v] : a.transient_storage) {
42-
auto const found = b.transient_storage.find(k);
43-
MONAD_ASSERT(found != b.transient_storage.end());
44-
MONAD_ASSERT(found->second == v);
45-
}
46-
47-
MONAD_ASSERT(a.storage.size() == b.storage.size());
48-
for (auto const &[k, v] : a.storage) {
49-
auto const found = b.storage.find(k);
50-
MONAD_ASSERT(found != b.storage.end());
51-
assert_equal(v, found->second);
52-
}
53-
54-
MONAD_ASSERT(a.nonce == b.nonce);
55-
MONAD_ASSERT(a.balance == b.balance);
56-
MONAD_ASSERT(a.code_hash == b.code_hash);
57-
MONAD_ASSERT(a.destructed == b.destructed);
58-
MONAD_ASSERT(a.erase_if_empty == b.erase_if_empty);
59-
MONAD_ASSERT(a.just_created == b.just_created);
60-
MONAD_ASSERT(a.access_status == b.access_status);
61-
}
62-
63-
void assert_equal(State const &a, State const &b)
64-
{
65-
auto const &a_accs = a.get_modified_accounts();
66-
auto const &b_accs = b.get_modified_accounts();
67-
68-
MONAD_ASSERT(a_accs.size() == b_accs.size());
69-
for (auto const &[k, v] : a_accs) {
70-
auto const found = b_accs.find(k);
71-
MONAD_ASSERT(found != b_accs.end());
72-
assert_equal(v, found->second);
73-
}
74-
}
75-
7630
void assert_equal(
7731
evmc::Result const &evmone_result, evmc::Result const &compiler_result,
7832
bool const strict_out_of_gas)
@@ -118,4 +72,46 @@ namespace monad::vm::fuzzing
11872
}
11973
}
12074

75+
void assert_states_equal(SortedStateView const &a, SortedStateView const &b)
76+
{
77+
MONAD_ASSERT(a.size() == b.size());
78+
79+
for (auto const &[a_acc, b_acc] : std::views::zip(a, b)) {
80+
MONAD_ASSERT(a_acc.addr == b_acc.addr);
81+
MONAD_ASSERT(a_acc.nonce == b_acc.nonce);
82+
MONAD_ASSERT(a_acc.balance == b_acc.balance);
83+
MONAD_ASSERT(a_acc.code_hash == b_acc.code_hash);
84+
MONAD_ASSERT(std::ranges::equal(a_acc.code, b_acc.code));
85+
86+
auto const a_st = a.storage(a_acc.addr);
87+
auto const b_st = b.storage(b_acc.addr);
88+
89+
MONAD_ASSERT(a_st->size() == b_st->size());
90+
91+
for (auto const &[a_se, b_se] : std::views::zip(*a_st, *b_st)) {
92+
MONAD_ASSERT(a_se.key == b_se.key);
93+
MONAD_ASSERT(a_se.current == b_se.current);
94+
MONAD_ASSERT(a_se.original == b_se.original);
95+
MONAD_ASSERT(a_se.access_status == b_se.access_status);
96+
}
97+
98+
auto const a_ts = a.transient_storage(a_acc.addr);
99+
auto const b_ts = b.transient_storage(b_acc.addr);
100+
101+
MONAD_ASSERT(a_ts->size() == b_ts->size());
102+
103+
for (auto const &[a_te, b_te] : std::views::zip(*a_ts, *b_ts)) {
104+
MONAD_ASSERT(a_te.key == b_te.key);
105+
MONAD_ASSERT(a_te.value == b_te.value);
106+
}
107+
}
108+
}
109+
110+
void
111+
assert_backend_states_equal(FuzzerBackend const &a, FuzzerBackend const &b)
112+
{
113+
auto const a_view = a.sorted_view();
114+
auto const b_view = b.sorted_view();
115+
assert_states_equal(*a_view, *b_view);
116+
}
121117
}

test/vm/fuzzer/assertions.hpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,25 @@
1313
// You should have received a copy of the GNU General Public License
1414
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1515

16-
#include "account.hpp"
17-
#include "state.hpp"
16+
#pragma once
17+
18+
#include "fuzzer_backend.hpp"
19+
#include "fuzzer_view.hpp"
1820

1921
#include <evmc/evmc.hpp>
2022

2123
namespace monad::vm::fuzzing
2224
{
2325
void assert_equal(
24-
evmone::state::StorageValue const &a,
25-
evmone::state::StorageValue const &b);
26-
27-
void assert_equal(
28-
evmone::state::Account const &a, evmone::state::Account const &b);
26+
evmc::Result const &evmone_result, evmc::Result const &compiler_result,
27+
bool strict_out_of_gas);
2928

29+
/// Walk two state views in lockstep and assert all accounts and storage
30+
/// slots are equal. Aborts on the first mismatch.
3031
void
31-
assert_equal(evmone::state::State const &a, evmone::state::State const &b);
32+
assert_states_equal(SortedStateView const &a, SortedStateView const &b);
3233

33-
void assert_equal(
34-
evmc::Result const &evmone_result, evmc::Result const &compiler_result,
35-
bool strict_out_of_gas);
34+
/// Convenience: construct sorted views from two backends and compare.
35+
void
36+
assert_backend_states_equal(FuzzerBackend const &a, FuzzerBackend const &b);
3637
}

0 commit comments

Comments
 (0)