Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
raw_data_dbs.cpp
Go to the documentation of this file.
2
3#include <cassert>
4#include <optional>
5#include <span>
6#include <stdexcept>
7#include <string>
8
16
17namespace bb::avm2::simulation {
18
19namespace {
20
21std::string to_string(const TreeSnapshots& snapshots)
22{
23 return format("PUBLIC_DATA_TREE: ",
24 snapshots.public_data_tree,
25 "\nNULLIFIER_TREE: ",
26 snapshots.nullifier_tree,
27 "\nNOTE_HASH_TREE: ",
28 snapshots.note_hash_tree,
29 "\nL1_TO_L2_MESSAGE_TREE: ",
30 snapshots.l1_to_l2_message_tree);
31}
32
33std::string get_tree_name(world_state::MerkleTreeId tree_id)
34{
35 switch (tree_id) {
37 return "PUBLIC_DATA_TREE";
39 return "NULLIFIER_TREE";
41 return "NOTE_HASH_TREE";
43 return "L1_TO_L2_MESSAGE_TREE";
45 return "ARCHIVE";
46 }
47
48 return "UNKNOWN"; // To make GCC happy.
49}
50
51} // namespace
52
53// HintedRawContractDB starts.
55{
56 BB_BENCH_NAME("HintedRawContractDB::HintedRawContractDB");
57
58 vinfo("Initializing HintedRawContractDB with...",
59 "\n * contract_instances: ",
60 hints.contract_instances.size(),
61 "\n * contract_classes: ",
62 hints.contract_classes.size(),
63 "\n * bytecode_commitments: ",
64 hints.bytecode_commitments.size(),
65 "\n * debug_function_names: ",
66 hints.debug_function_names.size());
67
68 for (const auto& contract_instance_hint : hints.contract_instances) {
69 contract_instances[std::make_tuple(contract_instance_hint.hint_key, contract_instance_hint.address)] =
70 contract_instance_hint;
71 }
72
73 for (const auto& contract_class_hint : hints.contract_classes) {
74 contract_classes[std::make_tuple(contract_class_hint.hint_key, contract_class_hint.class_id)] =
75 contract_class_hint;
76 }
77
78 for (const auto& bytecode_commitment_hint : hints.bytecode_commitments) {
79 bytecode_commitments[std::make_tuple(bytecode_commitment_hint.hint_key, bytecode_commitment_hint.class_id)] =
80 bytecode_commitment_hint.commitment;
81 }
82
83 for (const auto& debug_function_name_hint : hints.debug_function_names) {
84 debug_function_names[std::make_pair(debug_function_name_hint.address, debug_function_name_hint.selector)] =
85 debug_function_name_hint.name;
86 }
87
88 for (const auto& hint : hints.contract_db_create_checkpoint_hints) {
89 create_checkpoint_hints[hint.action_counter] = hint;
90 }
91 for (const auto& hint : hints.contract_db_commit_checkpoint_hints) {
92 commit_checkpoint_hints[hint.action_counter] = hint;
93 }
94 for (const auto& hint : hints.contract_db_revert_checkpoint_hints) {
95 revert_checkpoint_hints[hint.action_counter] = hint;
96 }
97}
98
100{
101 uint32_t hint_key = action_counter;
102 auto key = std::make_tuple(hint_key, address);
103 auto it = contract_instances.find(key);
104 if (it == contract_instances.end()) {
105 vinfo("Contract instance not found for key (", hint_key, ", ", address, ")");
106 return std::nullopt;
107 }
108 const auto& contract_instance_hint = it->second;
109
111 .salt = contract_instance_hint.salt,
112 .deployer = contract_instance_hint.deployer,
113 .current_contract_class_id = contract_instance_hint.current_contract_class_id,
114 .original_contract_class_id = contract_instance_hint.original_contract_class_id,
115 .initialization_hash = contract_instance_hint.initialization_hash,
116 .public_keys =
118 .nullifier_key = contract_instance_hint.public_keys.master_nullifier_public_key,
119 .incoming_viewing_key = contract_instance_hint.public_keys.master_incoming_viewing_public_key,
120 .outgoing_viewing_key = contract_instance_hint.public_keys.master_outgoing_viewing_public_key,
121 .tagging_key = contract_instance_hint.public_keys.master_tagging_public_key,
122 },
123 });
124}
125
127{
128 uint32_t hint_key = action_counter;
129 auto key = std::make_tuple(hint_key, class_id);
130 auto it = contract_classes.find(key);
131 if (it == contract_classes.end()) {
132 vinfo("Contract class not found for key (", hint_key, ", ", class_id, ")");
133 return std::nullopt;
134 }
135 const auto& contract_class_hint = it->second;
136
138 .id = class_id,
139 .artifact_hash = contract_class_hint.artifact_hash,
140 .private_functions_root = contract_class_hint.private_functions_root,
141 .packed_bytecode = contract_class_hint.packed_bytecode,
142 });
143}
144
146{
147 uint32_t hint_key = action_counter;
148 auto key = std::make_tuple(hint_key, class_id);
149 auto it = bytecode_commitments.find(key);
150 if (it == bytecode_commitments.end()) {
151 vinfo("Bytecode commitment not found for key (", hint_key, ", ", class_id, ")");
152 return std::nullopt;
153 }
154 return it->second;
155}
156
158 const FunctionSelector& selector) const
159{
160 auto it = debug_function_names.find(std::make_pair(address, selector));
161 if (it != debug_function_names.end()) {
162 return it->second;
163 }
164 return std::nullopt;
165}
166
167void HintedRawContractDB::add_contracts([[maybe_unused]] const ContractDeploymentData& contract_deployment_data)
168{
169 debug("add_contracts called (no-op in hinted mode)");
170}
171
173{
174 auto hint_it = create_checkpoint_hints.find(action_counter);
175 BB_ASSERT(hint_it != create_checkpoint_hints.end(), "Hint not found for create checkpoint");
176
177 const auto& hint = hint_it->second;
179 hint.old_checkpoint_id, checkpoint_stack.top(), "Old checkpoint id does not match the current checkpoint id");
180
181 checkpoint_stack.push(hint.new_checkpoint_id);
183}
184
186{
187 auto hint_it = commit_checkpoint_hints.find(action_counter);
188 BB_ASSERT(hint_it != commit_checkpoint_hints.end(), "Hint not found for commit checkpoint");
189
190 const auto& hint = hint_it->second;
192 hint.old_checkpoint_id, checkpoint_stack.top(), "Old checkpoint id does not match the current checkpoint id");
193
194 checkpoint_stack.pop();
196 hint.new_checkpoint_id, checkpoint_stack.top(), "New checkpoint id does not match the current checkpoint id");
198}
199
201{
202 auto hint_it = revert_checkpoint_hints.find(action_counter);
203 BB_ASSERT(hint_it != revert_checkpoint_hints.end(), "Hint not found for revert checkpoint");
204
205 const auto& hint = hint_it->second;
207 hint.old_checkpoint_id, checkpoint_stack.top(), "Old checkpoint id does not match the current checkpoint id");
208
209 checkpoint_stack.pop();
211 hint.new_checkpoint_id, checkpoint_stack.top(), "New checkpoint id does not match the current checkpoint id");
213}
214
216{
217 return checkpoint_stack.top();
218}
219
220// Hinted MerkleDB starts.
222 : tree_roots(hints.starting_tree_roots)
223{
224 BB_BENCH_NAME("HintedRawMerkleDB::HintedRawMerkleDB");
225
226 vinfo("Initializing HintedRawMerkleDB with...",
227 "\n * get_sibling_path_hints: ",
228 hints.get_sibling_path_hints.size(),
229 "\n * get_previous_value_index_hints: ",
231 "\n * get_leaf_preimage_hints_public_data_tree: ",
233 "\n * get_leaf_preimage_hints_nullifier_tree: ",
235 "\n * get_leaf_value_hints: ",
236 hints.get_leaf_value_hints.size(),
237 "\n * sequential_insert_hints_public_data_tree: ",
239 "\n * sequential_insert_hints_nullifier_tree: ",
241 "\n * append_leaves_hints: ",
242 hints.append_leaves_hints.size(),
243 "\n * create_checkpoint_hints: ",
244 hints.create_checkpoint_hints.size(),
245 "\n * commit_checkpoint_hints: ",
246 hints.commit_checkpoint_hints.size(),
247 "\n * revert_checkpoint_hints: ",
248 hints.revert_checkpoint_hints.size());
249 debug("Initializing HintedRawMerkleDB with snapshots...\n", to_string(tree_roots));
250
251 for (const auto& get_sibling_path_hint : hints.get_sibling_path_hints) {
252 GetSiblingPathKey key = { get_sibling_path_hint.hint_key,
253 get_sibling_path_hint.tree_id,
254 get_sibling_path_hint.index };
255 get_sibling_path_hints[key] = get_sibling_path_hint.path;
256 }
257
258 for (const auto& get_previous_value_index_hint : hints.get_previous_value_index_hints) {
259 GetPreviousValueIndexKey key = { get_previous_value_index_hint.hint_key,
260 get_previous_value_index_hint.tree_id,
261 get_previous_value_index_hint.value };
263 get_previous_value_index_hint.already_present,
264 get_previous_value_index_hint.index,
265 };
266 }
267
268 for (const auto& get_leaf_preimage_hint : hints.get_leaf_preimage_hints_public_data_tree) {
269 GetLeafPreimageKey key = { get_leaf_preimage_hint.hint_key, get_leaf_preimage_hint.index };
270 get_leaf_preimage_hints_public_data_tree[key] = get_leaf_preimage_hint.leaf_preimage;
271 }
272
273 for (const auto& get_leaf_preimage_hint : hints.get_leaf_preimage_hints_nullifier_tree) {
274 GetLeafPreimageKey key = { get_leaf_preimage_hint.hint_key, get_leaf_preimage_hint.index };
275 get_leaf_preimage_hints_nullifier_tree[key] = get_leaf_preimage_hint.leaf_preimage;
276 }
277
278 for (const auto& get_leaf_value_hint : hints.get_leaf_value_hints) {
279 GetLeafValueKey key = { get_leaf_value_hint.hint_key, get_leaf_value_hint.tree_id, get_leaf_value_hint.index };
280 get_leaf_value_hints[key] = get_leaf_value_hint.value;
281 }
282
283 for (const auto& sequential_insert_hint : hints.sequential_insert_hints_public_data_tree) {
284 SequentialInsertHintPublicDataTreeKey key = { sequential_insert_hint.hint_key,
285 sequential_insert_hint.tree_id,
286 sequential_insert_hint.leaf };
287 sequential_insert_hints_public_data_tree[key] = sequential_insert_hint;
288 }
289
290 for (const auto& sequential_insert_hint : hints.sequential_insert_hints_nullifier_tree) {
291 SequentialInsertHintNullifierTreeKey key = { sequential_insert_hint.hint_key,
292 sequential_insert_hint.tree_id,
293 sequential_insert_hint.leaf };
294 sequential_insert_hints_nullifier_tree[key] = sequential_insert_hint;
295 }
296
297 for (const auto& append_leaves_hint : hints.append_leaves_hints) {
298 // Convert the span from the hint to a vector for the key
299 AppendLeavesHintKey key = { append_leaves_hint.hint_key,
300 append_leaves_hint.tree_id,
301 append_leaves_hint.leaves };
302 append_leaves_hints[key] = append_leaves_hint.state_after;
303 }
304
305 for (const auto& create_checkpoint_hint : hints.create_checkpoint_hints) {
306 create_checkpoint_hints[create_checkpoint_hint.action_counter] = create_checkpoint_hint;
307 }
308
309 for (const auto& commit_checkpoint_hint : hints.commit_checkpoint_hints) {
310 commit_checkpoint_hints[commit_checkpoint_hint.action_counter] = commit_checkpoint_hint;
311 }
312
313 for (const auto& revert_checkpoint_hint : hints.revert_checkpoint_hints) {
314 revert_checkpoint_hints[revert_checkpoint_hint.action_counter] = revert_checkpoint_hint;
315 }
316}
317
322
327
329{
330 auto tree_info = get_tree_info(tree_id);
331 GetSiblingPathKey key = { tree_info, tree_id, leaf_index };
332 auto it = get_sibling_path_hints.find(key);
333 if (it == get_sibling_path_hints.end()) {
334 throw std::runtime_error(format("Sibling path not found for key (root: ",
335 tree_info.root,
336 ", size: ",
337 tree_info.next_available_leaf_index,
338 ", tree: ",
339 get_tree_name(tree_id),
340 ", leaf_index: ",
341 leaf_index,
342 ")"));
343 }
344 return it->second;
345}
346
348 const FF& value) const
349{
350 auto tree_info = get_tree_info(tree_id);
351 GetPreviousValueIndexKey key = { tree_info, tree_id, value };
352 auto it = get_previous_value_index_hints.find(key);
353 if (it == get_previous_value_index_hints.end()) {
354 throw std::runtime_error(format("Low indexed leaf not found for key (root: ",
355 tree_info.root,
356 ", size: ",
357 tree_info.next_available_leaf_index,
358 ", tree: ",
359 get_tree_name(tree_id),
360 ", value: ",
361 value,
362 ")"));
363 }
364 return it->second;
365}
366
368{
369 auto tree_info = get_tree_info(tree_id);
370 GetLeafValueKey key = { tree_info, tree_id, leaf_index };
371 auto it = get_leaf_value_hints.find(key);
372 if (it == get_leaf_value_hints.end()) {
373 throw std::runtime_error(format("Leaf value not found for key (root: ",
374 tree_info.root,
375 ", size: ",
376 tree_info.next_available_leaf_index,
377 ", tree: ",
378 get_tree_name(tree_id),
379 ", leaf_index: ",
380 leaf_index,
381 ")"));
382 }
383 return it->second;
384}
385
387{
389 GetLeafPreimageKey key = { tree_info, leaf_index };
392 throw std::runtime_error(format("Leaf preimage (PUBLIC_DATA_TREE) not found for key (root: ",
393 tree_info.root,
394 ", size: ",
395 tree_info.next_available_leaf_index,
396 ", leaf_index: ",
397 leaf_index,
398 ")"));
399 }
400 return it->second;
401}
402
404{
406 GetLeafPreimageKey key = { tree_info, leaf_index };
409 throw std::runtime_error(format("Leaf preimage (NULLIFIER_TREE) not found for key (root: ",
410 tree_info.root,
411 ", size: ",
412 tree_info.next_available_leaf_index,
413 ", leaf_index: ",
414 leaf_index,
415 ")"));
416 }
417 return it->second;
418}
419
421 const PublicDataLeafValue& leaf_value)
422{
427 throw std::runtime_error(format("Sequential insert hint (PUBLIC_DATA_TREE) not found for key (root: ",
428 tree_info.root,
429 ", size: ",
430 tree_info.next_available_leaf_index,
431 ", leaf_value: ",
432 leaf_value,
433 ")"));
434 }
435 const auto& hint = it->second;
436
438
439 // Convert low leaves witness data
440 result.low_leaf_witness_data.emplace_back(
441 hint.low_leaves_witness_data.leaf, hint.low_leaves_witness_data.index, hint.low_leaves_witness_data.path);
442
443 // Convert insertion witness data
444 result.insertion_witness_data.emplace_back(
445 hint.insertion_witness_data.leaf, hint.insertion_witness_data.index, hint.insertion_witness_data.path);
446
447 // Evolve state.
448 tree_roots.public_data_tree = hint.state_after;
449
450 debug("Evolved state of PUBLIC_DATA_TREE: ",
452 " (size: ",
454 ")");
455
456 return result;
457}
458
460 const NullifierLeafValue& leaf_value)
461{
466 throw std::runtime_error(format("Sequential insert hint (NULLIFIER_TREE) not found for key (root: ",
467 tree_info.root,
468 ", size: ",
469 tree_info.next_available_leaf_index,
470 ", leaf_value: ",
471 leaf_value,
472 ")"));
473 }
474 const auto& hint = it->second;
475
477
478 // Convert low leaves witness data
479 result.low_leaf_witness_data.emplace_back(
480 hint.low_leaves_witness_data.leaf, hint.low_leaves_witness_data.index, hint.low_leaves_witness_data.path);
481
482 // Convert insertion witness data
483 result.insertion_witness_data.emplace_back(
484 hint.insertion_witness_data.leaf, hint.insertion_witness_data.index, hint.insertion_witness_data.path);
485
486 // Evolve state.
487 tree_roots.nullifier_tree = hint.state_after;
488
489 debug("Evolved state of NULLIFIER_TREE: ",
491 " (size: ",
493 ")");
494
495 return result;
496}
497
499{
501 if (it == create_checkpoint_hints.end()) {
502 throw std::runtime_error(
503 format("[create_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
504 }
505 const auto& hint = it->second;
506
507 // Sanity check.
508 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
509 throw std::runtime_error(format("[create_checkpoint@",
511 "] Old checkpoint id does not match the current checkpoint id: ",
512 hint.old_checkpoint_id,
513 " != ",
514 checkpoint_stack.top()));
515 }
516
517 debug("[create_checkpoint@",
519 "] Checkpoint evolved ",
520 hint.old_checkpoint_id,
521 " -> ",
522 hint.new_checkpoint_id);
523
524 checkpoint_stack.push(hint.new_checkpoint_id);
526}
527
529{
531 if (it == commit_checkpoint_hints.end()) {
532 throw std::runtime_error(
533 format("[commit_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
534 }
535 const auto& hint = it->second;
536
537 // Sanity check.
538 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
539 throw std::runtime_error(format("[commit_checkpoint@",
541 "] Old checkpoint id does not match the current checkpoint id: ",
542 hint.old_checkpoint_id,
543 " != ",
544 checkpoint_stack.top()));
545 }
546
547 checkpoint_stack.pop();
548
549 // Sanity check.
550 if (hint.new_checkpoint_id != checkpoint_stack.top()) {
551 throw std::runtime_error(format("[commit_checkpoint@",
553 "] New checkpoint id does not match the current checkpoint id: ",
554 hint.new_checkpoint_id,
555 " != ",
556 checkpoint_stack.top()));
557 }
558
559 debug("[commit_checkpoint@",
561 "] Checkpoint evolved ",
562 hint.old_checkpoint_id,
563 " -> ",
564 hint.new_checkpoint_id);
565
567}
568
570{
572 if (it == revert_checkpoint_hints.end()) {
573 throw std::runtime_error(
574 format("[revert_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
575 }
576 const auto& hint = it->second;
577
578 // Sanity check of checkpoint stack.
579 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
580 throw std::runtime_error(format("[revert_checkpoint@",
582 "] Old checkpoint id does not match the current checkpoint id: ",
583 hint.old_checkpoint_id,
584 " != ",
585 checkpoint_stack.top()));
586 }
587
588 // Sanity check of tree snapshots.
589 if (hint.state_before != tree_roots) {
590 vinfo("Hint tree snapshots: ", to_string(hint.state_before));
591 vinfo("Current tree roots: ", to_string(tree_roots));
592 throw std::runtime_error(format("[revert_checkpoint@",
594 "] Hint tree snapshots do not match the current tree roots."));
595 }
596
597 checkpoint_stack.pop();
598
599 // Sanity check.
600 if (hint.new_checkpoint_id != checkpoint_stack.top()) {
601 throw std::runtime_error(format("[revert_checkpoint@",
603 "] New checkpoint id does not match the current checkpoint id: ",
604 hint.new_checkpoint_id,
605 " != ",
606 checkpoint_stack.top()));
607 }
608
609 // Evolve trees.
610 tree_roots = hint.state_after;
611
612 debug("[revert_checkpoint@",
614 "] Checkpoint evolved ",
615 hint.old_checkpoint_id,
616 " -> ",
617 hint.new_checkpoint_id);
618
620}
621
623{
624 auto tree_info = get_tree_info(tree_id);
625 AppendLeavesHintKey key = { tree_info, tree_id, std::vector<FF>(leaves.begin(), leaves.end()) };
626 auto it = append_leaves_hints.find(key);
627 if (it == append_leaves_hints.end()) {
628 throw std::runtime_error(format("Append leaves hint not found for key (root: ",
629 tree_info.root,
630 ", size: ",
631 tree_info.next_available_leaf_index,
632 ", tree: ",
633 get_tree_name(tree_id),
634 ", leaves: ",
635 std::vector<FF>(leaves.begin(), leaves.end()),
636 ")"));
637 }
638 const AppendOnlyTreeSnapshot& snapshot_after = it->second;
639
640 // Update the tree state based on the hint.
641 switch (tree_id) {
643 tree_roots.note_hash_tree = snapshot_after;
644 debug("Evolved state of NOTE_HASH_TREE: ",
646 " (size: ",
648 ")");
649 break;
651 tree_roots.l1_to_l2_message_tree = snapshot_after;
652 debug("Evolved state of L1_TO_L2_MESSAGE_TREE: ",
654 " (size: ",
656 ")");
657 break;
658 default:
659 throw std::runtime_error("append_leaves is only supported for NOTE_HASH_TREE and L1_TO_L2_MESSAGE_TREE");
660 }
661}
662
664{
665 auto& tree_info = get_tree_info(tree_id);
666 auto size_before = tree_info.next_available_leaf_index;
667 (void)size_before; // To please the compiler.
668 tree_info.next_available_leaf_index += num_leaves;
669
670 debug("Padded tree ",
671 get_tree_name(tree_id),
672 " from size ",
673 size_before,
674 " to ",
675 tree_info.next_available_leaf_index);
676}
677
679{
680 return checkpoint_stack.top();
681}
682
683// PureRawMerkleDB starts.
685{
686 if (cached_tree_snapshots.has_value()) {
687 return cached_tree_snapshots.value();
688 }
689
690 auto l1_to_l2_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
691 auto note_hash_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::NOTE_HASH_TREE);
692 auto nullifier_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::NULLIFIER_TREE);
693 auto public_data_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::PUBLIC_DATA_TREE);
694
695 TreeSnapshots tree_snapshots = {
696 .l1_to_l2_message_tree = AppendOnlyTreeSnapshot{ .root = l1_to_l2_info.meta.root,
697 .next_available_leaf_index = l1_to_l2_info.meta.size },
698 .note_hash_tree = AppendOnlyTreeSnapshot{ .root = note_hash_info.meta.root,
699 .next_available_leaf_index = note_hash_info.meta.size },
700 .nullifier_tree = AppendOnlyTreeSnapshot{ .root = nullifier_info.meta.root,
701 .next_available_leaf_index = nullifier_info.meta.size },
702 .public_data_tree = AppendOnlyTreeSnapshot{ .root = public_data_info.meta.root,
703 .next_available_leaf_index = public_data_info.meta.size },
704 };
705
706 if (cache_tree_roots) {
707 cached_tree_snapshots = tree_snapshots;
708 }
709
710 return tree_snapshots;
711}
712
714{
715 return ws_instance.get_sibling_path(ws_revision, tree_id, leaf_index);
716}
717
722
724{
725 std::optional<FF> res = ws_instance.get_leaf<FF>(ws_revision, tree_id, leaf_index);
726 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
727 if (!res.has_value()) {
728 throw std::runtime_error(
729 format("Invalid get_leaf_value request", static_cast<uint64_t>(tree_id), " for index ", leaf_index));
730 }
731 return res.value();
732}
733
735{
737 ws_instance.get_indexed_leaf<PublicDataLeafValue>(ws_revision, MerkleTreeId::PUBLIC_DATA_TREE, leaf_index);
738 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
739 if (!res.has_value()) {
740 throw std::runtime_error(format("Invalid get_leaf_preimage_public_data_tree request for index ", leaf_index));
741 }
742 return res.value();
743}
744
746{
748 ws_instance.get_indexed_leaf<NullifierLeafValue>(ws_revision, MerkleTreeId::NULLIFIER_TREE, leaf_index);
749 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
750 if (!res.has_value()) {
751 throw std::runtime_error(format("Invalid get_leaf_preimage_nullifier_tree request for index ", leaf_index));
752 }
753 return res.value();
754}
755
756// State modification methods.
758 const PublicDataLeafValue& leaf_value)
759{
760 // Throws CancelledException if cancelled.
762
763 // Invalidate the cached tree roots.
765
767 MerkleTreeId::PUBLIC_DATA_TREE, { leaf_value }, ws_revision.forkId);
768 return result;
769}
770
772 const NullifierLeafValue& leaf_value)
773{
774 // Throws CancelledException if cancelled.
776
777 // Invalidate the cached tree roots.
779
781 MerkleTreeId::NULLIFIER_TREE, { leaf_value }, ws_revision.forkId);
782 return result;
783}
784
786{
787 // Throws CancelledException if cancelled.
789
790 // Invalidate the cached tree roots.
792
793 ws_instance.append_leaves(tree_id, std::vector<FF>(leaves.begin(), leaves.end()), ws_revision.forkId);
794}
795
796void PureRawMerkleDB::pad_tree(MerkleTreeId tree_id, size_t num_leaves)
797{
798 // Throws CancelledException if cancelled.
800
801 // Invalidate the cached tree roots.
803
804 // The only trees that should be padded are NULLIFIER_TREE and NOTE_HASH_TREE
805 switch (tree_id) {
806 case MerkleTreeId::NULLIFIER_TREE: {
809 MerkleTreeId::NULLIFIER_TREE, padding_leaves, NULLIFIER_SUBTREE_HEIGHT, ws_revision.forkId);
810 break;
811 }
812 case MerkleTreeId::NOTE_HASH_TREE: {
813 std::vector<FF> padding_leaves(num_leaves, FF(0));
814 ws_instance.append_leaves(MerkleTreeId::NOTE_HASH_TREE, padding_leaves, ws_revision.forkId);
815 break;
816 }
817 default:
818 throw std::runtime_error("Padding not supported for tree " + std::to_string(static_cast<uint64_t>(tree_id)));
819 }
820}
821
823{
825 // Since the world state checkpoint stack is opaque, we track our own checkpoint ids.
826 uint32_t current_id = checkpoint_stack.top();
827 checkpoint_stack.push(current_id + 1);
828}
829
835
837{
838 // Invalidate the cached tree roots.
840
842 checkpoint_stack.pop();
843}
844
846{
847 return checkpoint_stack.top();
848}
849
850} // namespace bb::avm2::simulation
#define BB_ASSERT(expression,...)
Definition assert.hpp:80
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:93
#define NULLIFIER_SUBTREE_HEIGHT
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:219
HintedRawContractDB(const ExecutionHints &hints)
std::optional< ContractInstance > get_contract_instance(const AztecAddress &address) const override
unordered_flat_map< uint32_t, ContractDBRevertCheckpointHint > revert_checkpoint_hints
unordered_flat_map< GetBytecodeCommitmentKey, FF > bytecode_commitments
std::optional< ContractClass > get_contract_class(const ContractClassId &class_id) const override
unordered_flat_map< uint32_t, ContractDBCreateCheckpointHint > create_checkpoint_hints
unordered_flat_map< GetContractInstanceKey, ContractInstanceHint > contract_instances
void add_contracts(const ContractDeploymentData &contract_deployment_data) override
unordered_flat_map< uint32_t, ContractDBCommitCheckpointHint > commit_checkpoint_hints
unordered_flat_map< GetContractClassKey, ContractClassHint > contract_classes
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
unordered_flat_map< GetDebugFunctionNameKey, std::string > debug_function_names
unordered_flat_map< GetLeafValueKey, FF > get_leaf_value_hints
unordered_flat_map< uint32_t, RevertCheckpointHint > revert_checkpoint_hints
unordered_flat_map< SequentialInsertHintNullifierTreeKey, SequentialInsertHint< NullifierLeafValue > > sequential_insert_hints_nullifier_tree
GetLowIndexedLeafResponse get_low_indexed_leaf(MerkleTreeId tree_id, const FF &value) const override
unordered_flat_map< AppendLeavesHintKey, AppendOnlyTreeSnapshot > append_leaves_hints
SiblingPath get_sibling_path(MerkleTreeId tree_id, index_t leaf_index) const override
unordered_flat_map< uint32_t, CommitCheckpointHint > commit_checkpoint_hints
unordered_flat_map< GetSiblingPathKey, SiblingPath > get_sibling_path_hints
SequentialInsertionResult< NullifierLeafValue > insert_indexed_leaves_nullifier_tree(const NullifierLeafValue &leaf_value) override
unordered_flat_map< uint32_t, CreateCheckpointHint > create_checkpoint_hints
IndexedLeaf< PublicDataLeafValue > get_leaf_preimage_public_data_tree(index_t leaf_index) const override
IndexedLeaf< NullifierLeafValue > get_leaf_preimage_nullifier_tree(index_t leaf_index) const override
FF get_leaf_value(MerkleTreeId tree_id, index_t leaf_index) const override
unordered_flat_map< GetLeafPreimageKey, IndexedLeaf< NullifierLeafValue > > get_leaf_preimage_hints_nullifier_tree
unordered_flat_map< SequentialInsertHintPublicDataTreeKey, SequentialInsertHint< PublicDataLeafValue > > sequential_insert_hints_public_data_tree
HintedRawMerkleDB(const ExecutionHints &hints)
unordered_flat_map< GetLeafPreimageKey, IndexedLeaf< PublicDataLeafValue > > get_leaf_preimage_hints_public_data_tree
uint32_t get_checkpoint_id() const override
SequentialInsertionResult< PublicDataLeafValue > insert_indexed_leaves_public_data_tree(const PublicDataLeafValue &leaf_value) override
unordered_flat_map< GetPreviousValueIndexKey, GetLowIndexedLeafResponse > get_previous_value_index_hints
const AppendOnlyTreeSnapshot & get_tree_info(MerkleTreeId tree_id) const
void pad_tree(MerkleTreeId tree_id, size_t num_leaves) override
void append_leaves(MerkleTreeId tree_id, std::span< const FF > leaves) override
world_state::WorldStateRevision ws_revision
IndexedLeaf< PublicDataLeafValue > get_leaf_preimage_public_data_tree(index_t leaf_index) const override
SiblingPath get_sibling_path(MerkleTreeId tree_id, index_t leaf_index) const override
void append_leaves(MerkleTreeId tree_id, std::span< const FF > leaves) override
world_state::WorldState & ws_instance
IndexedLeaf< NullifierLeafValue > get_leaf_preimage_nullifier_tree(index_t leaf_index) const override
GetLowIndexedLeafResponse get_low_indexed_leaf(MerkleTreeId tree_id, const FF &value) const override
std::optional< TreeSnapshots > cached_tree_snapshots
std::stack< uint32_t > checkpoint_stack
TreeSnapshots get_tree_roots() const override
void pad_tree(MerkleTreeId tree_id, size_t num_leaves) override
SequentialInsertionResult< NullifierLeafValue > insert_indexed_leaves_nullifier_tree(const NullifierLeafValue &leaf_value) override
FF get_leaf_value(MerkleTreeId tree_id, index_t leaf_index) const override
SequentialInsertionResult< PublicDataLeafValue > insert_indexed_leaves_public_data_tree(const PublicDataLeafValue &leaf_value) override
uint32_t get_checkpoint_id() const override
BatchInsertionResult< T > batch_insert_indexed_leaves(MerkleTreeId tree_id, const std::vector< T > &leaves, uint32_t subtree_depth, Fork::Id fork_id=CANONICAL_FORK_ID)
Batch inserts a set of leaves into an indexed Merkle Tree.
void append_leaves(MerkleTreeId tree_id, const std::vector< T > &leaves, Fork::Id fork_id=CANONICAL_FORK_ID)
Appends a set of leaves to an existing Merkle Tree.
std::optional< crypto::merkle_tree::IndexedLeaf< T > > get_indexed_leaf(const WorldStateRevision &revision, MerkleTreeId tree_id, index_t leaf_index) const
Get the leaf preimage object.
void revert_checkpoint(const uint64_t &forkId)
crypto::merkle_tree::TreeMetaResponse get_tree_info(const WorldStateRevision &revision, MerkleTreeId tree_id) const
Get tree metadata for a particular tree.
SequentialInsertionResult< T > insert_indexed_leaves(MerkleTreeId tree_id, const std::vector< T > &leaves, Fork::Id fork_id=CANONICAL_FORK_ID)
Inserts a set of leaves sequentially into an indexed Merkle Tree.
void commit_checkpoint(const uint64_t &forkId)
crypto::merkle_tree::fr_sibling_path get_sibling_path(const WorldStateRevision &revision, MerkleTreeId tree_id, index_t leaf_index) const
Get the sibling path object for a leaf in a tree.
std::optional< T > get_leaf(const WorldStateRevision &revision, MerkleTreeId tree_id, index_t leaf_index) const
Gets the value of a leaf in a tree.
void checkpoint(const uint64_t &forkId)
crypto::merkle_tree::GetLowIndexedLeafResponse find_low_leaf_index(const WorldStateRevision &revision, MerkleTreeId tree_id, const bb::fr &leaf_key) const
Finds the leaf that would have its nextIdx/nextValue fields modified if the target leaf were to be in...
std::string format(Args... args)
Definition log.hpp:24
#define vinfo(...)
Definition log.hpp:94
#define debug(...)
Definition log.hpp:76
auto & get_tree_info_helper(world_state::MerkleTreeId tree_id, auto &tree_roots)
Definition db_types.hpp:72
::bb::crypto::merkle_tree::fr_sibling_path SiblingPath
Definition db.hpp:36
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, index_t > GetSiblingPathKey
Definition db_types.hpp:16
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, index_t > GetLeafValueKey
Definition db_types.hpp:19
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, NullifierLeafValue > SequentialInsertHintNullifierTreeKey
Definition db_types.hpp:21
std::tuple< AppendOnlyTreeSnapshot, index_t > GetLeafPreimageKey
Definition db_types.hpp:18
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, PublicDataLeafValue > SequentialInsertHintPublicDataTreeKey
Definition db_types.hpp:20
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, FF > GetPreviousValueIndexKey
Definition db_types.hpp:17
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, std::vector< FF > > AppendLeavesHintKey
Definition db_types.hpp:22
::bb::crypto::merkle_tree::index_t index_t
Definition db.hpp:37
std::string to_string(const std::array< FF, N > &arr)
Definition stringify.hpp:31
FF ContractClassId
FF FunctionSelector
AvmFlavorSettings::FF FF
Definition field.hpp:10
@ L1_TO_L2_MESSAGE_TREE
Definition types.hpp:22
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
std::vector< SequentialInsertHint< crypto::merkle_tree::NullifierLeafValue > > sequential_insert_hints_nullifier_tree
Definition avm_io.hpp:382
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< SequentialInsertHint< crypto::merkle_tree::PublicDataLeafValue > > sequential_insert_hints_public_data_tree
Definition avm_io.hpp:381
std::vector< RevertCheckpointHint > revert_checkpoint_hints
Definition avm_io.hpp:386
std::vector< ContractDBRevertCheckpointHint > contract_db_revert_checkpoint_hints
Definition avm_io.hpp:370
std::vector< GetPreviousValueIndexHint > get_previous_value_index_hints
Definition avm_io.hpp:374
std::vector< GetLeafPreimageHint< crypto::merkle_tree::IndexedLeaf< crypto::merkle_tree::PublicDataLeafValue > > > get_leaf_preimage_hints_public_data_tree
Definition avm_io.hpp:376
std::vector< GetLeafPreimageHint< crypto::merkle_tree::IndexedLeaf< crypto::merkle_tree::NullifierLeafValue > > > get_leaf_preimage_hints_nullifier_tree
Definition avm_io.hpp:378
std::vector< CreateCheckpointHint > create_checkpoint_hints
Definition avm_io.hpp:384
std::vector< GetLeafValueHint > get_leaf_value_hints
Definition avm_io.hpp:379
std::vector< AppendLeavesHint > append_leaves_hints
Definition avm_io.hpp:383
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
AffinePoint nullifier_key
AppendOnlyTreeSnapshot public_data_tree
AppendOnlyTreeSnapshot l1_to_l2_message_tree
AppendOnlyTreeSnapshot nullifier_tree
AppendOnlyTreeSnapshot note_hash_tree
std::vector< crypto::merkle_tree::LeafUpdateWitnessData< LeafValueType > > low_leaf_witness_data
std::vector< crypto::merkle_tree::LeafUpdateWitnessData< LeafValueType > > insertion_witness_data