Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
hinting_dbs.test.cpp
Go to the documentation of this file.
11
12#include <algorithm>
13#include <cstddef>
14#include <cstdlib>
15#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17#include <vector>
18
19namespace bb::avm2::simulation {
20namespace {
21
22class HintingDBsTest : public ::testing::Test {
23 protected:
24 HintingDBsTest(const AvmProvingInputs& inputs)
25 : inputs(inputs)
26 , base_contract_db(HintedRawContractDB(inputs.hints))
27 , base_merkle_db(HintedRawMerkleDB(inputs.hints))
28 {}
29
30 template <typename Hint>
31 void compare_hints(const std::vector<Hint>& input_hints, const std::vector<Hint>& collected_hints)
32 {
33 for (const Hint& input_hint : input_hints) {
34 EXPECT_FALSE(std::ranges::find(collected_hints.begin(), collected_hints.end(), input_hint) ==
35 collected_hints.end());
36 }
37
38 for (const Hint& collected_hint : collected_hints) {
39 EXPECT_FALSE(std::ranges::find(input_hints.begin(), input_hints.end(), collected_hint) ==
40 input_hints.end());
41 }
42 }
43
44 public:
45 AvmProvingInputs inputs;
46 HintedRawContractDB base_contract_db;
47 HintedRawMerkleDB base_merkle_db;
48 HintingContractsDB hinting_contract_db = HintingContractsDB(base_contract_db);
49 HintingRawDB hinting_merkle_db = HintingRawDB(base_merkle_db);
50};
51
52class HintingDBsMinimalTest : public HintingDBsTest {
53 protected:
54 HintingDBsMinimalTest()
55 : HintingDBsTest(AvmProvingInputs::from(read_file("../src/barretenberg/vm2/testing/minimal_tx.testdata.bin")))
56 {}
57};
58
59// A helper to reset the randomly generated values in avm_inputs.testdata.bin to avoid unrelated failures:
60AvmProvingInputs fix_hint_keys(AvmProvingInputs inputs)
61{
62 auto reset_action_counters = [&]<typename H>(std::vector<H>& hints) {
63 for (auto& hint : hints) {
64 hint.hint_key = 0;
65 }
66 };
67 auto reset_tree_id = [&]<typename H>(std::vector<H>& hints) {
68 for (auto& hint : hints) {
69 // The AVM handles treeIds 0 - 3:
70 hint.tree_id = MerkleTreeId(hint.tree_id % 4);
71 hint.hint_key = get_tree_info_helper(hint.tree_id, inputs.hints.starting_tree_roots);
72 }
73 };
74 reset_action_counters(inputs.hints.contract_instances);
75 reset_action_counters(inputs.hints.contract_classes);
76 reset_action_counters(inputs.hints.bytecode_commitments);
77 reset_tree_id(inputs.hints.get_sibling_path_hints);
78
79 return inputs;
80};
81
82class HintingDBsTestInputTest : public HintingDBsTest {
83 protected:
84 HintingDBsTestInputTest()
85 : HintingDBsTest(fix_hint_keys(
86 AvmProvingInputs::from(read_file("../src/barretenberg/vm2/testing/avm_inputs.testdata.bin"))))
87 {}
88};
89
90TEST_F(HintingDBsTestInputTest, GetContractInstance)
91{
92 for (const auto& instance_hint : inputs.hints.contract_instances) {
93 auto instance = hinting_contract_db.get_contract_instance(instance_hint.address);
94 EXPECT_TRUE(instance.has_value());
95 EXPECT_EQ(instance.value(), base_contract_db.get_contract_instance(instance_hint.address).value());
96 }
97
98 ExecutionHints collected_hints;
99 hinting_contract_db.dump_hints(collected_hints);
100 compare_hints(inputs.hints.contract_instances, collected_hints.contract_instances);
101}
102
103TEST_F(HintingDBsTestInputTest, GetContractClass)
104{
105 for (const auto& class_hint : inputs.hints.contract_classes) {
106 auto klass = hinting_contract_db.get_contract_class(class_hint.class_id);
107 EXPECT_TRUE(klass.has_value());
108 EXPECT_THAT(klass.value(), base_contract_db.get_contract_class(class_hint.class_id).value());
109 }
110
111 ExecutionHints collected_hints;
112 hinting_contract_db.dump_hints(collected_hints);
113 compare_hints(inputs.hints.contract_classes, collected_hints.contract_classes);
114}
115
116TEST_F(HintingDBsTestInputTest, GetBytecodeCommitment)
117{
118 for (const auto& hint : inputs.hints.bytecode_commitments) {
119 auto commitment = hinting_contract_db.get_bytecode_commitment(hint.class_id);
120 EXPECT_TRUE(commitment.has_value());
121 EXPECT_EQ(commitment.value(), base_contract_db.get_bytecode_commitment(hint.class_id).value());
122 }
123
124 ExecutionHints collected_hints;
125 hinting_contract_db.dump_hints(collected_hints);
126 compare_hints(inputs.hints.bytecode_commitments, collected_hints.bytecode_commitments);
127}
128
129TEST_F(HintingDBsTestInputTest, GetDebugFunctionName)
130{
131 for (const auto& hint : inputs.hints.debug_function_names) {
132 auto name = hinting_contract_db.get_debug_function_name(hint.address, hint.selector);
133 EXPECT_TRUE(name.has_value());
134 EXPECT_EQ(name.value(), base_contract_db.get_debug_function_name(hint.address, hint.selector).value());
135 }
136
137 ExecutionHints collected_hints;
138 hinting_contract_db.dump_hints(collected_hints);
139 compare_hints(inputs.hints.debug_function_names, collected_hints.debug_function_names);
140}
141
142TEST_F(HintingDBsMinimalTest, ContractDBCheckpoints)
143{
144 // The minimal tx has one create and one commit. The conditionals are in case the minimal tx ever changes, bricking
145 // this test:
147 // The hinting db will cause the underlying base db to push a checkpoint onto the stack and increment the action
148 // counter:
152 }
153 }
154 ExecutionHints collected_hints;
155 hinting_contract_db.dump_hints(collected_hints);
157 collected_hints.contract_db_create_checkpoint_hints);
159 collected_hints.contract_db_commit_checkpoint_hints);
160}
161
162TEST_F(HintingDBsTestInputTest, GetSiblingPath)
163{
164 for (const auto& hint : inputs.hints.get_sibling_path_hints) {
165 auto path = hinting_merkle_db.get_sibling_path(hint.tree_id, hint.index);
166 EXPECT_EQ(path, base_merkle_db.get_sibling_path(hint.tree_id, hint.index));
167 }
168
169 ExecutionHints collected_hints;
170 hinting_merkle_db.dump_hints(collected_hints);
171 compare_hints(inputs.hints.get_sibling_path_hints, collected_hints.get_sibling_path_hints);
172}
173
174TEST_F(HintingDBsMinimalTest, MerkleDBCheckpoints)
175{
176 // The minimal tx has one create and one commit. The conditionals are in case the minimal tx ever changes, bricking
177 // this test:
178 if (inputs.hints.create_checkpoint_hints.size() == 1) {
179 // The hinting db will cause the underlying base db to push a checkpoint onto the stack and increment the action
180 // counter:
182 if (inputs.hints.commit_checkpoint_hints.size() == 1) {
184 }
185 }
186 ExecutionHints collected_hints;
187 hinting_merkle_db.dump_hints(collected_hints);
188 compare_hints(inputs.hints.create_checkpoint_hints, collected_hints.create_checkpoint_hints);
189 compare_hints(inputs.hints.commit_checkpoint_hints, collected_hints.commit_checkpoint_hints);
190}
191
192class MockedHintingDBsTest : public ::testing::Test {
193 protected:
194 MockedHintingDBsTest() { ON_CALL(base_merkle_db, get_tree_roots).WillByDefault(testing::Return(mock_tree_info)); }
195 testing::StrictMock<MockContractDB> base_contract_db;
196 testing::StrictMock<MockLowLevelMerkleDB> base_merkle_db;
197 HintingContractsDB hinting_contract_db = HintingContractsDB(base_contract_db);
198 HintingRawDB hinting_merkle_db = HintingRawDB(base_merkle_db);
199
200 TreeSnapshots mock_tree_info = {
201 { 1, 2 },
202 { 3, 2 },
203 { 5, 5 },
204 { 7, 3 },
205 };
206};
207
208TEST_F(MockedHintingDBsTest, GetLowLeaf)
209{
210 // Mock some slots:
211 std::vector<FF> update_preimage_slots = { 1, 2, 4 };
212 // get_low_indexed_leaf will call get_tree_roots:
213 EXPECT_CALL(base_merkle_db, get_tree_roots).Times(static_cast<int>(update_preimage_slots.size()));
214 EXPECT_CALL(base_merkle_db, get_low_indexed_leaf(world_state::MerkleTreeId::PUBLIC_DATA_TREE, testing::_))
215 .WillRepeatedly([&](world_state::MerkleTreeId, const FF& leaf_slot) {
216 for (size_t i = 0; i < update_preimage_slots.size(); ++i) {
217 if (leaf_slot == update_preimage_slots[i]) {
218 return GetLowIndexedLeafResponse(true, static_cast<uint64_t>(i));
219 }
220 }
221 throw std::runtime_error("Leaf not found");
222 });
223
224 // Call the db:
225 for (const auto& update_preimage_slot : update_preimage_slots) {
227 }
228 ExecutionHints collected_hints;
229 hinting_merkle_db.dump_hints(collected_hints);
230
231 // Check the collected hints:
232 EXPECT_EQ(collected_hints.get_previous_value_index_hints.size(), update_preimage_slots.size());
233 EXPECT_THAT(
234 collected_hints.get_previous_value_index_hints,
235 testing::ElementsAreArray({ GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
236 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
237 .value = update_preimage_slots[0],
238 .index = 0,
239 .already_present = true },
240 GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
241 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
242 .value = update_preimage_slots[1],
243 .index = 1,
244 .already_present = true },
245 GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
246 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
247 .value = update_preimage_slots[2],
248 .index = 2,
249 .already_present = true } }));
250}
251
252TEST_F(MockedHintingDBsTest, GetLeafValue)
253{
254 // Mock some leaf values:
255 std::vector<FF> note_hash_leaf_values = { 11, 22, 44, 88 };
256 // get_leaf_value will call get_tree_roots:
257 EXPECT_CALL(base_merkle_db, get_tree_roots).Times(static_cast<int>(note_hash_leaf_values.size()));
258 EXPECT_CALL(base_merkle_db, get_leaf_value(world_state::MerkleTreeId::NOTE_HASH_TREE, testing::_))
259 .WillRepeatedly([&](world_state::MerkleTreeId, index_t index) {
260 if (index < note_hash_leaf_values.size()) {
261 return note_hash_leaf_values[index];
262 }
263 throw std::runtime_error("Leaf not found");
264 });
265
266 // Call the db:
267 for (index_t i = 0; i < note_hash_leaf_values.size(); i++) {
269 }
270 ExecutionHints collected_hints;
271 hinting_merkle_db.dump_hints(collected_hints);
272
273 // Check the collected hints:
274 EXPECT_EQ(collected_hints.get_leaf_value_hints.size(), note_hash_leaf_values.size());
275 EXPECT_THAT(collected_hints.get_leaf_value_hints,
276 testing::ElementsAreArray({
277 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
278 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
279 .index = 0,
280 .value = note_hash_leaf_values[0] },
281 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
282 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
283 .index = 1,
284 .value = note_hash_leaf_values[1] },
285 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
286 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
287 .index = 2,
288 .value = note_hash_leaf_values[2] },
289 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
290 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
291 .index = 3,
292 .value = note_hash_leaf_values[3] },
293 }));
294}
295
296TEST_F(MockedHintingDBsTest, GetLeafPreimagePublicDataTree)
297{
298 // Mock some leaf values:
299 std::vector<PublicDataLeafValue> public_leaf_values = { { 1, 3 }, { 2, 6 }, { 4, 7 } };
300 std::vector<IndexedLeaf<PublicDataLeafValue>> public_leaf_preimages = { { public_leaf_values[0], 1, 6 },
301 { public_leaf_values[1], 2, 4 },
302 { public_leaf_values[2], 0, 3 } };
303 // get_leaf_preimage_public_data_tree will call get_tree_roots:
304 EXPECT_CALL(base_merkle_db, get_tree_roots).Times(static_cast<int>(public_leaf_preimages.size()));
305 EXPECT_CALL(base_merkle_db, get_leaf_preimage_public_data_tree(testing::_)).WillRepeatedly([&](index_t index) {
306 if (index < public_leaf_preimages.size()) {
307 return public_leaf_preimages[index];
308 }
309 throw std::runtime_error("Leaf preimage not found");
310 });
311
312 // Call the db:
313 for (index_t i = 0; i < public_leaf_preimages.size(); i++) {
314 hinting_merkle_db.get_leaf_preimage_public_data_tree(i);
315 }
316 ExecutionHints collected_hints;
317 hinting_merkle_db.dump_hints(collected_hints);
318
319 // Check the collected hints:
320 EXPECT_EQ(collected_hints.get_leaf_preimage_hints_public_data_tree.size(), public_leaf_preimages.size());
321 EXPECT_THAT(
322 collected_hints.get_leaf_preimage_hints_public_data_tree,
323 testing::ElementsAreArray(
324 { GetLeafPreimageHint<PublicDataTreeLeafPreimage>{
325 .hint_key = mock_tree_info.public_data_tree, .index = 0, .leaf_preimage = public_leaf_preimages[0] },
326 GetLeafPreimageHint<PublicDataTreeLeafPreimage>{
327 .hint_key = mock_tree_info.public_data_tree, .index = 1, .leaf_preimage = public_leaf_preimages[1] },
328 GetLeafPreimageHint<PublicDataTreeLeafPreimage>{ .hint_key = mock_tree_info.public_data_tree,
329 .index = 2,
330 .leaf_preimage = public_leaf_preimages[2] } }));
331}
332
333TEST_F(MockedHintingDBsTest, GetLeafPreimageNullifierTree)
334{
335 // Mock some leaf values:
336 std::vector<NullifierLeafValue> nullifier_leaf_values = { { 1 }, { 2 }, { 4 } };
337 std::vector<IndexedLeaf<NullifierLeafValue>> nullifier_leaf_preimages = { { nullifier_leaf_values[0], 1, 6 },
338 { nullifier_leaf_values[1], 2, 4 },
339 { nullifier_leaf_values[2], 0, 3 } };
340 // get_leaf_preimage_nullifier_tree will call get_tree_roots:
341 EXPECT_CALL(base_merkle_db, get_tree_roots).Times(static_cast<int>(nullifier_leaf_preimages.size()));
342 EXPECT_CALL(base_merkle_db, get_leaf_preimage_nullifier_tree(testing::_)).WillRepeatedly([&](index_t index) {
343 if (index < nullifier_leaf_preimages.size()) {
344 return nullifier_leaf_preimages[index];
345 }
346 throw std::runtime_error("Leaf preimage not found");
347 });
348
349 // Call the db:
350 for (index_t i = 0; i < nullifier_leaf_preimages.size(); i++) {
351 hinting_merkle_db.get_leaf_preimage_nullifier_tree(i);
352 }
353 ExecutionHints collected_hints;
354 hinting_merkle_db.dump_hints(collected_hints);
355
356 // Check the collected hints:
357 EXPECT_EQ(collected_hints.get_leaf_preimage_hints_nullifier_tree.size(), nullifier_leaf_preimages.size());
358 EXPECT_THAT(
359 collected_hints.get_leaf_preimage_hints_nullifier_tree,
360 testing::ElementsAreArray(
361 { GetLeafPreimageHint<NullifierTreeLeafPreimage>{
362 .hint_key = mock_tree_info.nullifier_tree, .index = 0, .leaf_preimage = nullifier_leaf_preimages[0] },
363 GetLeafPreimageHint<NullifierTreeLeafPreimage>{
364 .hint_key = mock_tree_info.nullifier_tree, .index = 1, .leaf_preimage = nullifier_leaf_preimages[1] },
365 GetLeafPreimageHint<NullifierTreeLeafPreimage>{ .hint_key = mock_tree_info.nullifier_tree,
366 .index = 2,
367 .leaf_preimage = nullifier_leaf_preimages[2] } }));
368}
369
370TEST_F(MockedHintingDBsTest, InsertIndexedLeavesPublicDataTree)
371{
372 AppendOnlyTreeSnapshot state_before = mock_tree_info.public_data_tree;
373 // Mock the leaf values:
374 PublicDataLeafValue public_leaf_value = { 4, 7 };
375 PublicDataLeafValue low_leaf_value = { 2, 6 };
377 AppendOnlyTreeSnapshot mock_state_after = { mock_tree_info.public_data_tree.root++,
378 mock_tree_info.public_data_tree.next_available_leaf_index++ };
379 LeafUpdateWitnessData<PublicDataLeafValue> mock_low_witness_data =
380 LeafUpdateWitnessData<PublicDataLeafValue>{ { low_leaf_value, 0, 0 }, 0, mock_path };
381 // insert_indexed_leaves_public_data_tree will call get_tree_roots and get_tree_info (which itself will call
382 // get_tree_roots):
383 EXPECT_CALL(base_merkle_db, get_tree_roots).Times(2);
384 EXPECT_CALL(base_merkle_db, insert_indexed_leaves_public_data_tree(testing::_))
385 .WillOnce([&](PublicDataLeafValue value) {
386 SequentialInsertionResult<PublicDataLeafValue> result = {
387 .low_leaf_witness_data = { mock_low_witness_data },
388 .insertion_witness_data = { { { value, 1, 6 }, 1, mock_path } }
389 };
390 mock_tree_info.public_data_tree = mock_state_after;
391 return result;
392 });
393
394 // Call the db:
395 hinting_merkle_db.insert_indexed_leaves_public_data_tree(public_leaf_value);
396 ExecutionHints collected_hints;
397 hinting_merkle_db.dump_hints(collected_hints);
398
399 // Check the collected hints:
400 EXPECT_EQ(collected_hints.sequential_insert_hints_public_data_tree.size(), 1);
401 EXPECT_THAT(collected_hints.sequential_insert_hints_public_data_tree,
402 testing::ElementsAre(SequentialInsertHint<PublicDataLeafValue>{
403 .hint_key = state_before,
404 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
405 .leaf = public_leaf_value,
406 .low_leaves_witness_data = mock_low_witness_data,
407 .insertion_witness_data = { { public_leaf_value, 1, 6 }, 1, mock_path },
408 .state_after = mock_tree_info.public_data_tree }));
409}
410
411TEST_F(MockedHintingDBsTest, InsertIndexedLeavesNullifierTree)
412{
413 AppendOnlyTreeSnapshot state_before = mock_tree_info.nullifier_tree;
414 // Mock the leaf values:
416 NullifierLeafValue low_leaf_value = { 2 };
418 AppendOnlyTreeSnapshot mock_state_after = { mock_tree_info.nullifier_tree.root++,
419 mock_tree_info.nullifier_tree.next_available_leaf_index++ };
420 LeafUpdateWitnessData<NullifierLeafValue> mock_low_witness_data =
421 LeafUpdateWitnessData<NullifierLeafValue>{ { low_leaf_value, 0, 0 }, 0, mock_path };
422 // insert_indexed_leaves_nullifier_tree will call get_tree_roots and get_tree_info (which itself will call
423 // get_tree_roots):
424 EXPECT_CALL(base_merkle_db, get_tree_roots).Times(2);
425 EXPECT_CALL(base_merkle_db, insert_indexed_leaves_nullifier_tree(testing::_))
426 .WillOnce([&](NullifierLeafValue value) {
427 SequentialInsertionResult<NullifierLeafValue> result = { .low_leaf_witness_data = { mock_low_witness_data },
428 .insertion_witness_data = {
429 { { value, 1, 6 }, 1, mock_path } } };
430 mock_tree_info.nullifier_tree = mock_state_after;
431 return result;
432 });
433
434 // Call the db:
435 hinting_merkle_db.insert_indexed_leaves_nullifier_tree(nullifier);
436 ExecutionHints collected_hints;
437 hinting_merkle_db.dump_hints(collected_hints);
438
439 // Check the collected hints:
440 EXPECT_EQ(collected_hints.sequential_insert_hints_nullifier_tree.size(), 1);
441 EXPECT_THAT(collected_hints.sequential_insert_hints_nullifier_tree,
442 testing::ElementsAre(SequentialInsertHint<NullifierLeafValue>{
443 .hint_key = state_before,
444 .tree_id = world_state::MerkleTreeId::NULLIFIER_TREE,
445 .leaf = nullifier,
446 .low_leaves_witness_data = mock_low_witness_data,
447 .insertion_witness_data = { { nullifier, 1, 6 }, 1, mock_path },
448 .state_after = mock_tree_info.nullifier_tree }));
449}
450
451TEST_F(MockedHintingDBsTest, AppendLeaves)
452{
453 // Set initial state:
454 AppendOnlyTreeSnapshot initial_state = { 0, 0 };
455 mock_tree_info.note_hash_tree = initial_state;
456 // Mock the leaf values:
457 std::vector<FF> note_hash_leaf_values = { 11, 22, 44, 88 };
458 AppendOnlyTreeSnapshot expected_end_state = { 8, 4 };
459 TreeSnapshots expected_tree_info_after = mock_tree_info;
460 expected_tree_info_after.note_hash_tree = expected_end_state;
461 // append_leaves will call get_tree_info at the beginning and end of appending leaves:
462 EXPECT_CALL(base_merkle_db, get_tree_roots)
463 .WillOnce(testing::Return(mock_tree_info))
464 .WillOnce(testing::Return(expected_tree_info_after));
465 EXPECT_CALL(base_merkle_db, append_leaves(world_state::MerkleTreeId::NOTE_HASH_TREE, testing::_)).Times(1);
466
467 // Call the db:
468 hinting_merkle_db.append_leaves(world_state::MerkleTreeId::NOTE_HASH_TREE, note_hash_leaf_values);
469 ExecutionHints collected_hints;
470 hinting_merkle_db.dump_hints(collected_hints);
471
472 // Check the collected hints - one hint for all leaves:
473 EXPECT_EQ(collected_hints.append_leaves_hints.size(), 1);
474 EXPECT_THAT(collected_hints.append_leaves_hints,
475 testing::ElementsAre(AppendLeavesHint{ .hint_key = initial_state,
476 .state_after = expected_end_state,
477 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
478 .leaves = note_hash_leaf_values }));
479}
480
481TEST_F(MockedHintingDBsTest, MerkleDBCheckpoints)
482{
483 uint32_t mock_checkpoint_id = 0;
484 EXPECT_CALL(base_merkle_db, get_checkpoint_id)
485 .WillOnce(testing::Return(mock_checkpoint_id))
486 .WillOnce(testing::Return(++mock_checkpoint_id))
487 .WillOnce(testing::Return(mock_checkpoint_id))
488 .WillOnce(testing::Return(++mock_checkpoint_id));
489 ;
490 EXPECT_CALL(base_merkle_db, create_checkpoint).Times(2);
491 // Call the db:
492 hinting_merkle_db.create_checkpoint();
493 hinting_merkle_db.create_checkpoint();
494
495 EXPECT_CALL(base_merkle_db, get_checkpoint_id)
496 .WillOnce(testing::Return(mock_checkpoint_id))
497 .WillOnce(testing::Return(--mock_checkpoint_id));
498 EXPECT_CALL(base_merkle_db, commit_checkpoint).Times(1);
499 hinting_merkle_db.commit_checkpoint();
500
501 // revert_checkpoint will call get_tree_roots before and after calling the underlying db::
502 EXPECT_CALL(base_merkle_db, get_tree_roots).Times(2);
503
504 EXPECT_CALL(base_merkle_db, get_checkpoint_id)
505 .WillOnce(testing::Return(mock_checkpoint_id))
506 .WillOnce(testing::Return(--mock_checkpoint_id));
507 EXPECT_CALL(base_merkle_db, revert_checkpoint).Times(1);
508 hinting_merkle_db.revert_checkpoint();
509 ExecutionHints collected_hints;
510 hinting_merkle_db.dump_hints(collected_hints);
511
512 // Check the collected hints:
513 EXPECT_EQ(collected_hints.create_checkpoint_hints.size(), 2);
514 EXPECT_EQ(collected_hints.commit_checkpoint_hints.size(), 1);
515 EXPECT_EQ(collected_hints.revert_checkpoint_hints.size(), 1);
516 mock_checkpoint_id = 0;
517 uint32_t mock_action_counter = 0;
518 EXPECT_THAT(collected_hints.create_checkpoint_hints,
519 testing::ElementsAreArray({ CreateCheckpointHint{
520 .action_counter = mock_action_counter++,
521 .old_checkpoint_id = mock_checkpoint_id,
522 .new_checkpoint_id = ++mock_checkpoint_id,
523 },
524 CreateCheckpointHint{
525 .action_counter = mock_action_counter++,
526 .old_checkpoint_id = mock_checkpoint_id,
527 .new_checkpoint_id = ++mock_checkpoint_id,
528 } }));
529 EXPECT_THAT(collected_hints.commit_checkpoint_hints,
530 testing::ElementsAre(CommitCheckpointHint{
531 .action_counter = mock_action_counter++,
532 .old_checkpoint_id = mock_checkpoint_id,
533 .new_checkpoint_id = --mock_checkpoint_id,
534 }));
535 EXPECT_THAT(collected_hints.revert_checkpoint_hints,
536 testing::ElementsAre(RevertCheckpointHint{
537 .action_counter = mock_action_counter++,
538 .old_checkpoint_id = mock_checkpoint_id,
539 .new_checkpoint_id = --mock_checkpoint_id,
540 .state_before = mock_tree_info,
541 .state_after = mock_tree_info,
542 }));
543}
544
545} // namespace
546} // namespace bb::avm2::simulation
std::shared_ptr< Napi::ThreadSafeFunction > instance
std::shared_ptr< Napi::ThreadSafeFunction > revert_checkpoint
std::shared_ptr< Napi::ThreadSafeFunction > commit_checkpoint
std::shared_ptr< Napi::ThreadSafeFunction > create_checkpoint
#define NULLIFIER_TREE_HEIGHT
#define PUBLIC_DATA_TREE_HEIGHT
std::optional< ContractInstance > get_contract_instance(const AztecAddress &address) const override
std::optional< ContractClass > get_contract_class(const ContractClassId &class_id) const override
std::optional< std::string > get_debug_function_name(const AztecAddress &address, const FunctionSelector &selector) const override
std::optional< FF > get_bytecode_commitment(const ContractClassId &class_id) const override
SiblingPath get_sibling_path(MerkleTreeId tree_id, index_t leaf_index) const override
std::optional< std::string > get_debug_function_name(const AztecAddress &address, const FunctionSelector &selector) const override
std::optional< ContractClass > get_contract_class(const ContractClassId &class_id) const override
std::optional< FF > get_bytecode_commitment(const ContractClassId &class_id) const override
void dump_hints(ExecutionHints &hints)
std::optional< ContractInstance > get_contract_instance(const AztecAddress &address) const override
void dump_hints(ExecutionHints &hints)
SiblingPath get_sibling_path(MerkleTreeId tree_id, index_t leaf_index) const override
GetLowIndexedLeafResponse get_low_indexed_leaf(MerkleTreeId tree_id, const FF &value) const override
FF get_leaf_value(MerkleTreeId tree_id, index_t leaf_index) const override
auto & get_tree_info_helper(world_state::MerkleTreeId tree_id, auto &tree_roots)
Definition db_types.hpp:72
AvmProvingInputs inputs
HintingContractsDB hinting_contract_db
TreeSnapshots mock_tree_info
HintedRawMerkleDB base_merkle_db
HintingRawDB hinting_merkle_db
HintedRawContractDB base_contract_db
::bb::crypto::merkle_tree::fr_sibling_path SiblingPath
Definition db.hpp:36
::bb::world_state::MerkleTreeId MerkleTreeId
Definition db.hpp:35
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:185
std::vector< uint8_t > read_file(const std::string &filename, size_t bytes=0)
Definition file_io.hpp:30
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
TreeSnapshots starting_tree_roots
Definition avm_io.hpp:372
std::vector< GetSiblingPathHint > get_sibling_path_hints
Definition avm_io.hpp:373
std::vector< DebugFunctionNameHint > debug_function_names
Definition avm_io.hpp:367
std::vector< ContractDBCreateCheckpointHint > contract_db_create_checkpoint_hints
Definition avm_io.hpp:368
std::vector< ContractDBCommitCheckpointHint > contract_db_commit_checkpoint_hints
Definition avm_io.hpp:369
std::vector< CommitCheckpointHint > commit_checkpoint_hints
Definition avm_io.hpp:385
std::vector< CreateCheckpointHint > create_checkpoint_hints
Definition avm_io.hpp:384
std::vector< ContractInstanceHint > contract_instances
Definition avm_io.hpp:364
std::vector< ContractClassHint > contract_classes
Definition avm_io.hpp:365
std::vector< BytecodeCommitmentHint > bytecode_commitments
Definition avm_io.hpp:366