Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
retrieved_bytecodes_tree_check.test.cpp
Go to the documentation of this file.
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
16
17namespace bb::avm2::simulation {
18
19using ::testing::_;
20using ::testing::ElementsAre;
21using ::testing::Return;
22using ::testing::StrictMock;
23
25
26namespace {
27
28TEST(AvmSimulationRetrievedBytecodesTreeCheck, ContainsNotExists)
29{
30 StrictMock<MockPoseidon2> poseidon2;
31 StrictMock<MockMerkleCheck> merkle_check;
32 StrictMock<MockFieldGreaterThan> field_gt;
33
34 EventEmitter<RetrievedBytecodesTreeCheckEvent> event_emitter;
35
36 FF class_id = 42;
38
39 // Prefill will point to our new leaf
40 ASSERT_EQ(initial_state.get_snapshot().nextAvailableLeafIndex, 1);
41 uint64_t low_leaf_index = 0;
42 RetrievedBytecodesTreeLeafPreimage low_leaf = initial_state.get_leaf_preimage(low_leaf_index);
43
45
46 auto sibling_path = initial_state.get_sibling_path(0);
47 auto snapshot = initial_state.get_snapshot();
48
49 RetrievedBytecodesTreeCheck retrieved_bytecodes_tree_check(
50 poseidon2, merkle_check, field_gt, initial_state, event_emitter);
51
52 EXPECT_CALL(poseidon2, hash(low_leaf.get_hash_inputs())).WillRepeatedly(Return(FF(low_leaf_hash)));
53 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
54 .WillRepeatedly(Return());
55 EXPECT_CALL(field_gt, ff_gt(class_id, low_leaf.leaf.class_id)).WillRepeatedly(Return(true));
56
57 EXPECT_FALSE(retrieved_bytecodes_tree_check.contains(class_id));
58
59 RetrievedBytecodesTreeCheckEvent expect_event = {
60 .class_id = class_id,
61 .prev_snapshot = snapshot,
62 .next_snapshot = snapshot,
63 .low_leaf_preimage = low_leaf,
64 .low_leaf_hash = low_leaf_hash,
65 .low_leaf_index = low_leaf_index,
66 };
67 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
68}
69
70TEST(AvmSimulationRetrievedBytecodesTree, ContainsExists)
71{
72 StrictMock<MockPoseidon2> poseidon2;
73 StrictMock<MockMerkleCheck> merkle_check;
74 StrictMock<MockFieldGreaterThan> field_gt;
75
76 EventEmitter<RetrievedBytecodesTreeCheckEvent> event_emitter;
78
79 FF class_id = 42;
80
81 uint64_t low_leaf_index = initial_state.get_snapshot().nextAvailableLeafIndex;
82 initial_state.insert_indexed_leaves({ { ClassIdLeafValue(class_id) } });
83
84 RetrievedBytecodesTreeLeafPreimage low_leaf = initial_state.get_leaf_preimage(low_leaf_index);
86 std::vector<FF> sibling_path = initial_state.get_sibling_path(low_leaf_index);
87 auto snapshot = initial_state.get_snapshot();
88
89 RetrievedBytecodesTreeCheck retrieved_bytecodes_tree_check(
90 poseidon2, merkle_check, field_gt, initial_state, event_emitter);
91
92 EXPECT_CALL(poseidon2, hash(low_leaf.get_hash_inputs())).WillRepeatedly(Return(FF(low_leaf_hash)));
93 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
94 .WillRepeatedly(Return());
95
96 EXPECT_TRUE(retrieved_bytecodes_tree_check.contains(class_id));
97
98 RetrievedBytecodesTreeCheckEvent expect_event = {
99 .class_id = class_id,
100 .prev_snapshot = snapshot,
101 .next_snapshot = snapshot,
102 .low_leaf_preimage = low_leaf,
103 .low_leaf_hash = low_leaf_hash,
104 .low_leaf_index = low_leaf_index,
105 };
106 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
107}
108
109TEST(AvmSimulationRetrievedBytecodesTree, ReadNotExistsLowPointsToAnotherLeaf)
110{
111 StrictMock<MockPoseidon2> poseidon2;
112 StrictMock<MockMerkleCheck> merkle_check;
113 StrictMock<MockFieldGreaterThan> field_gt;
114
115 EventEmitter<RetrievedBytecodesTreeCheckEvent> event_emitter;
116
118 // Prefill now points to leaf MAX
119 initial_state.insert_indexed_leaves({ { ClassIdLeafValue(FF::neg_one()) } });
120
121 FF class_id = 42;
122
123 auto low_leaf = initial_state.get_leaf_preimage(0);
124
126 uint64_t low_leaf_index = 0;
127 std::vector<FF> sibling_path = initial_state.get_sibling_path(low_leaf_index);
128 AppendOnlyTreeSnapshot snapshot = initial_state.get_snapshot();
129
130 RetrievedBytecodesTreeCheck retrieved_bytecodes_tree_check(
131 poseidon2, merkle_check, field_gt, initial_state, event_emitter);
132
133 EXPECT_CALL(poseidon2, hash(low_leaf.get_hash_inputs())).WillRepeatedly(Return(FF(low_leaf_hash)));
134 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
135 .WillRepeatedly(Return());
136 EXPECT_CALL(field_gt, ff_gt(class_id, low_leaf.leaf.class_id)).WillRepeatedly(Return(true));
137 EXPECT_CALL(field_gt, ff_gt(low_leaf.nextKey, class_id)).WillRepeatedly(Return(true));
138
140
141 RetrievedBytecodesTreeCheckEvent expect_event = {
142 .class_id = class_id,
143 .prev_snapshot = snapshot,
144 .next_snapshot = snapshot,
145 .low_leaf_preimage = low_leaf,
146 .low_leaf_hash = low_leaf_hash,
147 .low_leaf_index = low_leaf_index,
148 };
149 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
150}
151
152TEST(AvmSimulationRetrievedBytecodesTree, InsertExists)
153{
154 StrictMock<MockPoseidon2> poseidon2;
155 StrictMock<MockMerkleCheck> merkle_check;
156 StrictMock<MockFieldGreaterThan> field_gt;
157
158 EventEmitter<RetrievedBytecodesTreeCheckEvent> event_emitter;
159
160 FF class_id = 42;
161
163 uint64_t low_leaf_index = initial_state.get_snapshot().nextAvailableLeafIndex;
164 initial_state.insert_indexed_leaves({ { ClassIdLeafValue(class_id) } });
165
166 RetrievedBytecodesTreeLeafPreimage low_leaf = initial_state.get_leaf_preimage(low_leaf_index);
168 std::vector<FF> sibling_path = initial_state.get_sibling_path(low_leaf_index);
169 AppendOnlyTreeSnapshot snapshot = initial_state.get_snapshot();
170
171 RetrievedBytecodesTreeCheck retrieved_bytecodes_tree_check(
172 poseidon2, merkle_check, field_gt, initial_state, event_emitter);
173
174 EXPECT_CALL(poseidon2, hash(low_leaf.get_hash_inputs())).WillRepeatedly(Return(FF(low_leaf_hash)));
175 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
176 .WillRepeatedly(Return());
177
179
180 EXPECT_EQ(retrieved_bytecodes_tree_check.get_snapshot(), snapshot);
181
182 RetrievedBytecodesTreeCheckEvent expect_event = {
183 .class_id = class_id,
184 .prev_snapshot = snapshot,
185 .next_snapshot = snapshot,
186 .low_leaf_preimage = low_leaf,
187 .low_leaf_hash = low_leaf_hash,
188 .low_leaf_index = low_leaf_index,
189 .write = true,
190 };
191 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
192}
193
194TEST(AvmSimulationRetrievedBytecodesTree, InsertAppend)
195{
196 StrictMock<MockPoseidon2> poseidon2;
197 StrictMock<MockMerkleCheck> merkle_check;
198 StrictMock<MockFieldGreaterThan> field_gt;
199
200 EventEmitter<RetrievedBytecodesTreeCheckEvent> event_emitter;
201
202 FF class_id = 100;
203
205 // Prefill will point to our new leaf
206 ASSERT_EQ(initial_state.get_snapshot().nextAvailableLeafIndex, 1);
207 uint64_t low_leaf_index = 0;
208 uint64_t new_leaf_index = 1;
209 RetrievedBytecodesTreeLeafPreimage low_leaf = initial_state.get_leaf_preimage(low_leaf_index);
210
212 RetrievedBytecodesTree state_after_insert = initial_state;
213 state_after_insert.insert_indexed_leaves({ { ClassIdLeafValue(class_id) } });
214
215 std::vector<FF> low_leaf_sibling_path = initial_state.get_sibling_path(low_leaf_index);
216
218 updated_low_leaf.nextIndex = new_leaf_index;
219 updated_low_leaf.nextKey = class_id;
220 FF updated_low_leaf_hash = RawPoseidon2::hash(updated_low_leaf.get_hash_inputs());
221
222 FF intermediate_root = unconstrained_root_from_path(updated_low_leaf_hash, low_leaf_index, low_leaf_sibling_path);
223 std::vector<FF> insertion_sibling_path = state_after_insert.get_sibling_path(new_leaf_index);
224
227 FF new_leaf_hash = RawPoseidon2::hash(new_leaf.get_hash_inputs());
228
229 RetrievedBytecodesTreeCheck retrieved_bytecodes_tree_check(
230 poseidon2, merkle_check, field_gt, initial_state, event_emitter);
231
232 EXPECT_CALL(poseidon2, hash(_)).WillRepeatedly([](const std::vector<FF>& input) {
233 return RawPoseidon2::hash(input);
234 });
235 EXPECT_CALL(merkle_check,
236 write(low_leaf_hash, updated_low_leaf_hash, low_leaf_index, _, initial_state.get_snapshot().root))
237 .WillRepeatedly(Return(intermediate_root));
238 EXPECT_CALL(field_gt, ff_gt(class_id, low_leaf.leaf.class_id)).WillRepeatedly(Return(true));
239 EXPECT_CALL(field_gt, ff_gt(low_leaf.nextKey, class_id)).WillRepeatedly(Return(true));
240 EXPECT_CALL(merkle_check, write(FF(0), new_leaf_hash, new_leaf_index, _, intermediate_root))
241 .WillRepeatedly(Return(state_after_insert.get_snapshot().root));
242
244
245 EXPECT_EQ(retrieved_bytecodes_tree_check.get_snapshot(), state_after_insert.get_snapshot());
246
247 RetrievedBytecodesTreeCheckEvent expect_event = { .class_id = class_id,
248 .prev_snapshot = initial_state.get_snapshot(),
249 .next_snapshot = state_after_insert.get_snapshot(),
250 .low_leaf_preimage = low_leaf,
251 .low_leaf_hash = low_leaf_hash,
252 .low_leaf_index = low_leaf_index,
253 .write = true,
254 .append_data = RetrievedBytecodeAppendData{
255 .updated_low_leaf_hash = updated_low_leaf_hash,
256 .new_leaf_hash = new_leaf_hash,
257 .intermediate_root = intermediate_root,
258 } };
259
260 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
261}
262
263} // namespace
264
265} // namespace bb::avm2::simulation
StrictMock< MockRetrievedBytecodesTreeCheck > retrieved_bytecodes_tree_check
SequentialInsertionResult< LeafType > insert_indexed_leaves(std::span< const LeafType > leaves)
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
EventEmitter< DataCopyEvent > event_emitter
NullifierTreeLeafPreimage low_leaf
void hash(State &state) noexcept
crypto::Poseidon2< crypto::Poseidon2Bn254ScalarFieldParams > poseidon2
IndexedMemoryTree< ClassIdLeafValue, Poseidon2HashPolicy > RetrievedBytecodesTree
TEST(EmitUnencryptedLogTest, Basic)
IndexedLeaf< ClassIdLeafValue > RetrievedBytecodesTreeLeafPreimage
RetrievedBytecodesTree build_retrieved_bytecodes_tree()
FF unconstrained_root_from_path(const FF &leaf_value, const uint64_t leaf_index, std::span< const FF > path)
Definition merkle.cpp:12
AvmFlavorSettings::FF FF
Definition field.hpp:10
void write(std::vector< uint8_t > &buf, ClientIVC::VerificationKey const &vk)
typename Flavor::FF FF
FieldGreaterThan field_gt
std::vector< fr > get_hash_inputs() const