Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
written_public_data_slots_tree_check.test.cpp
Go to the documentation of this file.
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
10
11namespace bb::avm2::simulation {
12
13using ::testing::_;
14using ::testing::Return;
15using ::testing::StrictMock;
16
18
19namespace {
20
21const IndexedTreeSiloingParameters SLOT_SILOING_PARAMS = {
22 .address = AztecAddress(27),
23 .siloing_separator = DOM_SEP__PUBLIC_LEAF_SLOT,
24};
25const std::optional<IndexedTreeSiloingParameters> OPT_SLOT_SILOING_PARAMS = SLOT_SILOING_PARAMS;
26
27TEST(AvmSimulationWrittenPublicDataSlotsTreeCheck, ContainsNotExists)
28{
29 StrictMock<MockIndexedTreeCheck> mock_indexed_tree_check;
31
32 FF slot = 42;
33 AztecAddress address = SLOT_SILOING_PARAMS.address;
35
36 auto snapshot = tree.get_snapshot();
37 auto [exists, low_leaf_index] = tree.get_low_indexed_leaf(leaf_slot);
38 auto low_leaf = tree.get_leaf_preimage(low_leaf_index);
39 ASSERT_FALSE(exists);
40
41 IndexedTreeLeafData expected_leaf_data = {
42 .value = low_leaf.leaf.slot,
43 .next_value = low_leaf.nextKey,
44 .next_index = low_leaf.nextIndex,
45 };
46
47 EXPECT_CALL(mock_indexed_tree_check,
48 assert_read(slot, OPT_SLOT_SILOING_PARAMS, false, expected_leaf_data, low_leaf_index, _, snapshot));
49
50 WrittenPublicDataSlotsTreeCheck slots_check(mock_indexed_tree_check, tree);
51 EXPECT_FALSE(slots_check.contains(address, slot));
52}
53
54TEST(AvmSimulationWrittenPublicDataSlotsTreeCheck, ContainsExists)
55{
56 StrictMock<MockIndexedTreeCheck> mock_indexed_tree_check;
58
59 FF slot = 42;
60 AztecAddress address = SLOT_SILOING_PARAMS.address;
62 tree.insert_indexed_leaves({ { WrittenPublicDataSlotLeafValue(leaf_slot) } });
63
64 auto snapshot = tree.get_snapshot();
65 auto [exists, low_leaf_index] = tree.get_low_indexed_leaf(leaf_slot);
66 auto low_leaf = tree.get_leaf_preimage(low_leaf_index);
67 ASSERT_TRUE(exists);
68
69 IndexedTreeLeafData expected_leaf_data = {
70 .value = low_leaf.leaf.slot,
71 .next_value = low_leaf.nextKey,
72 .next_index = low_leaf.nextIndex,
73 };
74
75 EXPECT_CALL(mock_indexed_tree_check,
76 assert_read(slot, OPT_SLOT_SILOING_PARAMS, true, expected_leaf_data, low_leaf_index, _, snapshot));
77
78 WrittenPublicDataSlotsTreeCheck slots_check(mock_indexed_tree_check, tree);
79 EXPECT_TRUE(slots_check.contains(address, slot));
80}
81
82TEST(AvmSimulationWrittenPublicDataSlotsTreeCheck, InsertExists)
83{
84 StrictMock<MockIndexedTreeCheck> mock_indexed_tree_check;
86
87 FF slot = 42;
88 AztecAddress address = SLOT_SILOING_PARAMS.address;
90 tree.insert_indexed_leaves({ { WrittenPublicDataSlotLeafValue(leaf_slot) } });
91
92 auto snapshot = tree.get_snapshot();
93
94 EXPECT_CALL(mock_indexed_tree_check,
95 write(slot, OPT_SLOT_SILOING_PARAMS, NO_PUBLIC_INPUTS_INDEX, _, _, _, snapshot, _))
96 .WillOnce(Return(snapshot));
97
98 WrittenPublicDataSlotsTreeCheck slots_check(mock_indexed_tree_check, tree);
99 slots_check.insert(address, slot);
100 EXPECT_EQ(slots_check.get_snapshot(), snapshot);
101}
102
103TEST(AvmSimulationWrittenPublicDataSlotsTreeCheck, InsertAppend)
104{
105 StrictMock<MockIndexedTreeCheck> mock_indexed_tree_check;
107
108 FF slot = 100;
109 AztecAddress address = SLOT_SILOING_PARAMS.address;
111 auto prev_snapshot = tree.get_snapshot();
112
113 // Compute expected post-insert state.
114 WrittenPublicDataSlotsTree tree_after = tree;
115 tree_after.insert_indexed_leaves({ { WrittenPublicDataSlotLeafValue(leaf_slot) } });
116 auto next_snapshot = tree_after.get_snapshot();
117
118 EXPECT_CALL(mock_indexed_tree_check,
119 write(slot, OPT_SLOT_SILOING_PARAMS, NO_PUBLIC_INPUTS_INDEX, _, _, _, prev_snapshot, _))
120 .WillOnce(Return(next_snapshot));
121
122 WrittenPublicDataSlotsTreeCheck slots_check(mock_indexed_tree_check, tree);
123 slots_check.insert(address, slot);
124 EXPECT_EQ(slots_check.get_snapshot(), next_snapshot);
125}
126
127TEST(AvmSimulationWrittenPublicDataSlotsTreeCheck, CheckpointBehavior)
128{
129 // Use NiceMock since checkpoint behavior exercises multiple contains/inserts and
130 // we don't want to specify exact expectations for every internal call.
131 testing::NiceMock<MockIndexedTreeCheck> mock_indexed_tree_check;
133
134 // Track inserts in a parallel tree so the write mock returns correct snapshots.
135 WrittenPublicDataSlotsTree parallel_tree = tree;
136 ON_CALL(mock_indexed_tree_check, write)
137 .WillByDefault([&parallel_tree](const FF& slot,
140 const IndexedTreeLeafData&,
141 uint64_t,
143 const AppendOnlyTreeSnapshot&,
144 std::optional<std::span<const FF>> insertion_path) -> AppendOnlyTreeSnapshot {
145 if (insertion_path.has_value()) {
146 FF leaf_slot = unconstrained_compute_leaf_slot(siloing_params.value().address, slot);
147 parallel_tree.insert_indexed_leaves({ { WrittenPublicDataSlotLeafValue(leaf_slot) } });
148 }
149 return parallel_tree.get_snapshot();
150 });
151
152 WrittenPublicDataSlotsTreeCheck slots_check(mock_indexed_tree_check, tree);
153
154 EXPECT_EQ(slots_check.size(), 0);
155 slots_check.create_checkpoint();
156
157 AztecAddress address1 = AztecAddress(1);
158 slots_check.insert(address1, 1);
159 EXPECT_TRUE(slots_check.contains(address1, 1));
160 EXPECT_EQ(slots_check.size(), 1);
161
162 // Commit the checkpoint.
163 slots_check.commit_checkpoint();
164 EXPECT_TRUE(slots_check.contains(address1, 1));
165 EXPECT_EQ(slots_check.size(), 1);
166
167 // Create another checkpoint.
168 slots_check.create_checkpoint();
169
170 // Insert another slot.
171 AztecAddress address2 = AztecAddress(2);
172 slots_check.insert(address2, 2);
173 EXPECT_TRUE(slots_check.contains(address2, 2));
174 EXPECT_EQ(slots_check.size(), 2);
175
176 // Revert the checkpoint.
177 slots_check.revert_checkpoint();
178 EXPECT_TRUE(slots_check.contains(address1, 1));
179 EXPECT_EQ(slots_check.size(), 1);
180}
181
182} // namespace
183
184} // namespace bb::avm2::simulation
#define DOM_SEP__PUBLIC_LEAF_SLOT
IndexedTreeLeafData low_leaf
AVM range check gadget for witness generation.
const std::optional< uint64_t > NO_PUBLIC_INPUTS_INDEX
WrittenPublicDataSlotsTree build_public_data_slots_tree()
FF unconstrained_compute_leaf_slot(const AztecAddress &contract_address, const FF &slot)
Definition merkle.cpp:26
IndexedMemoryTree< WrittenPublicDataSlotLeafValue, Poseidon2HashPolicy > WrittenPublicDataSlotsTree
void write(B &buf, field2< base_field, Params > const &value)
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13