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 .immutables_hash = contract_instance_hint.immutables_hash,
117 .public_keys =
119 .nullifier_key_hash = contract_instance_hint.public_keys.npk_m_hash,
120 .incoming_viewing_key = contract_instance_hint.public_keys.ivpk_m,
121 .outgoing_viewing_key_hash = contract_instance_hint.public_keys.ovpk_m_hash,
122 .tagging_key_hash = contract_instance_hint.public_keys.tpk_m_hash,
123 .message_signing_key_hash = contract_instance_hint.public_keys.mspk_m_hash,
124 .fallback_key_hash = contract_instance_hint.public_keys.fbpk_m_hash,
125 },
126 });
127}
128
130{
131 uint32_t hint_key = action_counter;
132 auto key = std::make_tuple(hint_key, class_id);
133 auto it = contract_classes.find(key);
134 if (it == contract_classes.end()) {
135 vinfo("Contract class not found for key (", hint_key, ", ", class_id, ")");
136 return std::nullopt;
137 }
138 const auto& contract_class_hint = it->second;
139
141 .id = class_id,
142 .artifact_hash = contract_class_hint.artifact_hash,
143 .private_functions_root = contract_class_hint.private_functions_root,
144 .packed_bytecode = contract_class_hint.packed_bytecode,
145 });
146}
147
149{
150 uint32_t hint_key = action_counter;
151 auto key = std::make_tuple(hint_key, class_id);
152 auto it = bytecode_commitments.find(key);
153 if (it == bytecode_commitments.end()) {
154 vinfo("Bytecode commitment not found for key (", hint_key, ", ", class_id, ")");
155 return std::nullopt;
156 }
157 return it->second;
158}
159
161 const FunctionSelector& selector) const
162{
163 auto it = debug_function_names.find(std::make_pair(address, selector));
164 if (it != debug_function_names.end()) {
165 return it->second;
166 }
167 return std::nullopt;
168}
169
170void HintedRawContractDB::add_contracts([[maybe_unused]] const ContractDeploymentData& contract_deployment_data)
171{
172 debug("add_contracts called (no-op in hinted mode)");
173}
174
176{
177 auto hint_it = create_checkpoint_hints.find(action_counter);
178 BB_ASSERT(hint_it != create_checkpoint_hints.end(), "Hint not found for create checkpoint");
179
180 const auto& hint = hint_it->second;
182 hint.old_checkpoint_id, checkpoint_stack.top(), "Old checkpoint id does not match the current checkpoint id");
183
184 checkpoint_stack.push(hint.new_checkpoint_id);
186}
187
189{
190 auto hint_it = commit_checkpoint_hints.find(action_counter);
191 BB_ASSERT(hint_it != commit_checkpoint_hints.end(), "Hint not found for commit checkpoint");
192
193 const auto& hint = hint_it->second;
195 hint.old_checkpoint_id, checkpoint_stack.top(), "Old checkpoint id does not match the current checkpoint id");
196
197 checkpoint_stack.pop();
199 hint.new_checkpoint_id, checkpoint_stack.top(), "New checkpoint id does not match the current checkpoint id");
201}
202
204{
205 auto hint_it = revert_checkpoint_hints.find(action_counter);
206 BB_ASSERT(hint_it != revert_checkpoint_hints.end(), "Hint not found for revert checkpoint");
207
208 const auto& hint = hint_it->second;
210 hint.old_checkpoint_id, checkpoint_stack.top(), "Old checkpoint id does not match the current checkpoint id");
211
212 checkpoint_stack.pop();
214 hint.new_checkpoint_id, checkpoint_stack.top(), "New checkpoint id does not match the current checkpoint id");
216}
217
219{
220 return checkpoint_stack.top();
221}
222
223// Hinted MerkleDB starts.
225 : tree_roots(hints.starting_tree_roots)
226{
227 BB_BENCH_NAME("HintedRawMerkleDB::HintedRawMerkleDB");
228
229 vinfo("Initializing HintedRawMerkleDB with...",
230 "\n * get_sibling_path_hints: ",
231 hints.get_sibling_path_hints.size(),
232 "\n * get_previous_value_index_hints: ",
234 "\n * get_leaf_preimage_hints_public_data_tree: ",
236 "\n * get_leaf_preimage_hints_nullifier_tree: ",
238 "\n * get_leaf_value_hints: ",
239 hints.get_leaf_value_hints.size(),
240 "\n * sequential_insert_hints_public_data_tree: ",
242 "\n * sequential_insert_hints_nullifier_tree: ",
244 "\n * append_leaves_hints: ",
245 hints.append_leaves_hints.size(),
246 "\n * create_checkpoint_hints: ",
247 hints.create_checkpoint_hints.size(),
248 "\n * commit_checkpoint_hints: ",
249 hints.commit_checkpoint_hints.size(),
250 "\n * revert_checkpoint_hints: ",
251 hints.revert_checkpoint_hints.size());
252 debug("Initializing HintedRawMerkleDB with snapshots...\n", to_string(tree_roots));
253
254 for (const auto& get_sibling_path_hint : hints.get_sibling_path_hints) {
255 GetSiblingPathKey key = { get_sibling_path_hint.hint_key,
256 get_sibling_path_hint.tree_id,
257 get_sibling_path_hint.index };
258 get_sibling_path_hints[key] = get_sibling_path_hint.path;
259 }
260
261 for (const auto& get_previous_value_index_hint : hints.get_previous_value_index_hints) {
262 GetPreviousValueIndexKey key = { get_previous_value_index_hint.hint_key,
263 get_previous_value_index_hint.tree_id,
264 get_previous_value_index_hint.value };
266 get_previous_value_index_hint.already_present,
267 get_previous_value_index_hint.index,
268 };
269 }
270
271 for (const auto& get_leaf_preimage_hint : hints.get_leaf_preimage_hints_public_data_tree) {
272 GetLeafPreimageKey key = { get_leaf_preimage_hint.hint_key, get_leaf_preimage_hint.index };
273 get_leaf_preimage_hints_public_data_tree[key] = get_leaf_preimage_hint.leaf_preimage;
274 }
275
276 for (const auto& get_leaf_preimage_hint : hints.get_leaf_preimage_hints_nullifier_tree) {
277 GetLeafPreimageKey key = { get_leaf_preimage_hint.hint_key, get_leaf_preimage_hint.index };
278 get_leaf_preimage_hints_nullifier_tree[key] = get_leaf_preimage_hint.leaf_preimage;
279 }
280
281 for (const auto& get_leaf_value_hint : hints.get_leaf_value_hints) {
282 GetLeafValueKey key = { get_leaf_value_hint.hint_key, get_leaf_value_hint.tree_id, get_leaf_value_hint.index };
283 get_leaf_value_hints[key] = get_leaf_value_hint.value;
284 }
285
286 for (const auto& sequential_insert_hint : hints.sequential_insert_hints_public_data_tree) {
287 SequentialInsertHintPublicDataTreeKey key = { sequential_insert_hint.hint_key,
288 sequential_insert_hint.tree_id,
289 sequential_insert_hint.leaf };
290 sequential_insert_hints_public_data_tree[key] = sequential_insert_hint;
291 }
292
293 for (const auto& sequential_insert_hint : hints.sequential_insert_hints_nullifier_tree) {
294 SequentialInsertHintNullifierTreeKey key = { sequential_insert_hint.hint_key,
295 sequential_insert_hint.tree_id,
296 sequential_insert_hint.leaf };
297 sequential_insert_hints_nullifier_tree[key] = sequential_insert_hint;
298 }
299
300 for (const auto& append_leaves_hint : hints.append_leaves_hints) {
301 // Convert the span from the hint to a vector for the key
302 AppendLeavesHintKey key = { append_leaves_hint.hint_key,
303 append_leaves_hint.tree_id,
304 append_leaves_hint.leaves };
305 append_leaves_hints[key] = append_leaves_hint.state_after;
306 }
307
308 for (const auto& create_checkpoint_hint : hints.create_checkpoint_hints) {
309 create_checkpoint_hints[create_checkpoint_hint.action_counter] = create_checkpoint_hint;
310 }
311
312 for (const auto& commit_checkpoint_hint : hints.commit_checkpoint_hints) {
313 commit_checkpoint_hints[commit_checkpoint_hint.action_counter] = commit_checkpoint_hint;
314 }
315
316 for (const auto& revert_checkpoint_hint : hints.revert_checkpoint_hints) {
317 revert_checkpoint_hints[revert_checkpoint_hint.action_counter] = revert_checkpoint_hint;
318 }
319}
320
325
330
332{
333 auto tree_info = get_tree_info(tree_id);
334 GetSiblingPathKey key = { tree_info, tree_id, leaf_index };
335 auto it = get_sibling_path_hints.find(key);
336 if (it == get_sibling_path_hints.end()) {
337 throw std::runtime_error(format("Sibling path not found for key (root: ",
338 tree_info.root,
339 ", size: ",
340 tree_info.next_available_leaf_index,
341 ", tree: ",
342 get_tree_name(tree_id),
343 ", leaf_index: ",
344 leaf_index,
345 ")"));
346 }
347 return it->second;
348}
349
351 const FF& value) const
352{
353 auto tree_info = get_tree_info(tree_id);
354 GetPreviousValueIndexKey key = { tree_info, tree_id, value };
355 auto it = get_previous_value_index_hints.find(key);
356 if (it == get_previous_value_index_hints.end()) {
357 throw std::runtime_error(format("Low indexed leaf not found for key (root: ",
358 tree_info.root,
359 ", size: ",
360 tree_info.next_available_leaf_index,
361 ", tree: ",
362 get_tree_name(tree_id),
363 ", value: ",
364 value,
365 ")"));
366 }
367 return it->second;
368}
369
371{
372 auto tree_info = get_tree_info(tree_id);
373 GetLeafValueKey key = { tree_info, tree_id, leaf_index };
374 auto it = get_leaf_value_hints.find(key);
375 if (it == get_leaf_value_hints.end()) {
376 throw std::runtime_error(format("Leaf value not found for key (root: ",
377 tree_info.root,
378 ", size: ",
379 tree_info.next_available_leaf_index,
380 ", tree: ",
381 get_tree_name(tree_id),
382 ", leaf_index: ",
383 leaf_index,
384 ")"));
385 }
386 return it->second;
387}
388
390{
392 GetLeafPreimageKey key = { tree_info, leaf_index };
395 throw std::runtime_error(format("Leaf preimage (PUBLIC_DATA_TREE) not found for key (root: ",
396 tree_info.root,
397 ", size: ",
398 tree_info.next_available_leaf_index,
399 ", leaf_index: ",
400 leaf_index,
401 ")"));
402 }
403 return it->second;
404}
405
407{
409 GetLeafPreimageKey key = { tree_info, leaf_index };
412 throw std::runtime_error(format("Leaf preimage (NULLIFIER_TREE) not found for key (root: ",
413 tree_info.root,
414 ", size: ",
415 tree_info.next_available_leaf_index,
416 ", leaf_index: ",
417 leaf_index,
418 ")"));
419 }
420 return it->second;
421}
422
424 const PublicDataLeafValue& leaf_value)
425{
430 throw std::runtime_error(format("Sequential insert hint (PUBLIC_DATA_TREE) not found for key (root: ",
431 tree_info.root,
432 ", size: ",
433 tree_info.next_available_leaf_index,
434 ", leaf_value: ",
435 leaf_value,
436 ")"));
437 }
438 const auto& hint = it->second;
439
441
442 // Convert low leaves witness data
443 result.low_leaf_witness_data.emplace_back(
444 hint.low_leaves_witness_data.leaf, hint.low_leaves_witness_data.index, hint.low_leaves_witness_data.path);
445
446 // Convert insertion witness data
447 result.insertion_witness_data.emplace_back(
448 hint.insertion_witness_data.leaf, hint.insertion_witness_data.index, hint.insertion_witness_data.path);
449
450 // Evolve state.
451 tree_roots.public_data_tree = hint.state_after;
452
453 debug("Evolved state of PUBLIC_DATA_TREE: ",
455 " (size: ",
457 ")");
458
459 return result;
460}
461
463 const NullifierLeafValue& leaf_value)
464{
469 throw std::runtime_error(format("Sequential insert hint (NULLIFIER_TREE) not found for key (root: ",
470 tree_info.root,
471 ", size: ",
472 tree_info.next_available_leaf_index,
473 ", leaf_value: ",
474 leaf_value,
475 ")"));
476 }
477 const auto& hint = it->second;
478
480
481 // Convert low leaves witness data
482 result.low_leaf_witness_data.emplace_back(
483 hint.low_leaves_witness_data.leaf, hint.low_leaves_witness_data.index, hint.low_leaves_witness_data.path);
484
485 // Convert insertion witness data
486 result.insertion_witness_data.emplace_back(
487 hint.insertion_witness_data.leaf, hint.insertion_witness_data.index, hint.insertion_witness_data.path);
488
489 // Evolve state.
490 tree_roots.nullifier_tree = hint.state_after;
491
492 debug("Evolved state of NULLIFIER_TREE: ",
494 " (size: ",
496 ")");
497
498 return result;
499}
500
502{
504 if (it == create_checkpoint_hints.end()) {
505 throw std::runtime_error(
506 format("[create_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
507 }
508 const auto& hint = it->second;
509
510 // Sanity check.
511 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
512 throw std::runtime_error(format("[create_checkpoint@",
514 "] Old checkpoint id does not match the current checkpoint id: ",
515 hint.old_checkpoint_id,
516 " != ",
517 checkpoint_stack.top()));
518 }
519
520 debug("[create_checkpoint@",
522 "] Checkpoint evolved ",
523 hint.old_checkpoint_id,
524 " -> ",
525 hint.new_checkpoint_id);
526
527 checkpoint_stack.push(hint.new_checkpoint_id);
529}
530
532{
534 if (it == commit_checkpoint_hints.end()) {
535 throw std::runtime_error(
536 format("[commit_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
537 }
538 const auto& hint = it->second;
539
540 // Sanity check.
541 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
542 throw std::runtime_error(format("[commit_checkpoint@",
544 "] Old checkpoint id does not match the current checkpoint id: ",
545 hint.old_checkpoint_id,
546 " != ",
547 checkpoint_stack.top()));
548 }
549
550 checkpoint_stack.pop();
551
552 // Sanity check.
553 if (hint.new_checkpoint_id != checkpoint_stack.top()) {
554 throw std::runtime_error(format("[commit_checkpoint@",
556 "] New checkpoint id does not match the current checkpoint id: ",
557 hint.new_checkpoint_id,
558 " != ",
559 checkpoint_stack.top()));
560 }
561
562 debug("[commit_checkpoint@",
564 "] Checkpoint evolved ",
565 hint.old_checkpoint_id,
566 " -> ",
567 hint.new_checkpoint_id);
568
570}
571
573{
575 if (it == revert_checkpoint_hints.end()) {
576 throw std::runtime_error(
577 format("[revert_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
578 }
579 const auto& hint = it->second;
580
581 // Sanity check of checkpoint stack.
582 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
583 throw std::runtime_error(format("[revert_checkpoint@",
585 "] Old checkpoint id does not match the current checkpoint id: ",
586 hint.old_checkpoint_id,
587 " != ",
588 checkpoint_stack.top()));
589 }
590
591 // Sanity check of tree snapshots.
592 if (hint.state_before != tree_roots) {
593 vinfo("Hint tree snapshots: ", to_string(hint.state_before));
594 vinfo("Current tree roots: ", to_string(tree_roots));
595 throw std::runtime_error(format("[revert_checkpoint@",
597 "] Hint tree snapshots do not match the current tree roots."));
598 }
599
600 checkpoint_stack.pop();
601
602 // Sanity check.
603 if (hint.new_checkpoint_id != checkpoint_stack.top()) {
604 throw std::runtime_error(format("[revert_checkpoint@",
606 "] New checkpoint id does not match the current checkpoint id: ",
607 hint.new_checkpoint_id,
608 " != ",
609 checkpoint_stack.top()));
610 }
611
612 // Evolve trees.
613 tree_roots = hint.state_after;
614
615 debug("[revert_checkpoint@",
617 "] Checkpoint evolved ",
618 hint.old_checkpoint_id,
619 " -> ",
620 hint.new_checkpoint_id);
621
623}
624
626{
627 auto tree_info = get_tree_info(tree_id);
628 AppendLeavesHintKey key = { tree_info, tree_id, std::vector<FF>(leaves.begin(), leaves.end()) };
629 auto it = append_leaves_hints.find(key);
630 if (it == append_leaves_hints.end()) {
631 throw std::runtime_error(format("Append leaves hint not found for key (root: ",
632 tree_info.root,
633 ", size: ",
634 tree_info.next_available_leaf_index,
635 ", tree: ",
636 get_tree_name(tree_id),
637 ", leaves: ",
638 std::vector<FF>(leaves.begin(), leaves.end()),
639 ")"));
640 }
641 const AppendOnlyTreeSnapshot& snapshot_after = it->second;
642
643 // Update the tree state based on the hint.
644 switch (tree_id) {
646 tree_roots.note_hash_tree = snapshot_after;
647 debug("Evolved state of NOTE_HASH_TREE: ",
649 " (size: ",
651 ")");
652 break;
654 tree_roots.l1_to_l2_message_tree = snapshot_after;
655 debug("Evolved state of L1_TO_L2_MESSAGE_TREE: ",
657 " (size: ",
659 ")");
660 break;
661 default:
662 throw std::runtime_error("append_leaves is only supported for NOTE_HASH_TREE and L1_TO_L2_MESSAGE_TREE");
663 }
664}
665
667{
668 auto& tree_info = get_tree_info(tree_id);
669 auto size_before = tree_info.next_available_leaf_index;
670 (void)size_before; // To please the compiler.
671 tree_info.next_available_leaf_index += num_leaves;
672
673 debug("Padded tree ",
674 get_tree_name(tree_id),
675 " from size ",
676 size_before,
677 " to ",
678 tree_info.next_available_leaf_index);
679}
680
682{
683 return checkpoint_stack.top();
684}
685
686// PureRawMerkleDB starts.
688{
689 if (cached_tree_snapshots.has_value()) {
690 return cached_tree_snapshots.value();
691 }
692
693 auto l1_to_l2_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
694 auto note_hash_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::NOTE_HASH_TREE);
695 auto nullifier_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::NULLIFIER_TREE);
696 auto public_data_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::PUBLIC_DATA_TREE);
697
698 TreeSnapshots tree_snapshots = {
699 .l1_to_l2_message_tree = AppendOnlyTreeSnapshot{ .root = l1_to_l2_info.meta.root,
700 .next_available_leaf_index = l1_to_l2_info.meta.size },
701 .note_hash_tree = AppendOnlyTreeSnapshot{ .root = note_hash_info.meta.root,
702 .next_available_leaf_index = note_hash_info.meta.size },
703 .nullifier_tree = AppendOnlyTreeSnapshot{ .root = nullifier_info.meta.root,
704 .next_available_leaf_index = nullifier_info.meta.size },
705 .public_data_tree = AppendOnlyTreeSnapshot{ .root = public_data_info.meta.root,
706 .next_available_leaf_index = public_data_info.meta.size },
707 };
708
709 if (cache_tree_roots) {
710 cached_tree_snapshots = tree_snapshots;
711 }
712
713 return tree_snapshots;
714}
715
717{
718 return ws_instance.get_sibling_path(ws_revision, tree_id, leaf_index);
719}
720
725
727{
728 std::optional<FF> res = ws_instance.get_leaf<FF>(ws_revision, tree_id, leaf_index);
729 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
730 if (!res.has_value()) {
731 throw std::runtime_error(
732 format("Invalid get_leaf_value request", static_cast<uint64_t>(tree_id), " for index ", leaf_index));
733 }
734 return res.value();
735}
736
738{
740 ws_instance.get_indexed_leaf<PublicDataLeafValue>(ws_revision, MerkleTreeId::PUBLIC_DATA_TREE, leaf_index);
741 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
742 if (!res.has_value()) {
743 throw std::runtime_error(format("Invalid get_leaf_preimage_public_data_tree request for index ", leaf_index));
744 }
745 return res.value();
746}
747
749{
751 ws_instance.get_indexed_leaf<NullifierLeafValue>(ws_revision, MerkleTreeId::NULLIFIER_TREE, leaf_index);
752 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
753 if (!res.has_value()) {
754 throw std::runtime_error(format("Invalid get_leaf_preimage_nullifier_tree request for index ", leaf_index));
755 }
756 return res.value();
757}
758
759// State modification methods.
761 const PublicDataLeafValue& leaf_value)
762{
763 // Throws CancelledException if cancelled.
765
766 // Invalidate the cached tree roots.
768
770 MerkleTreeId::PUBLIC_DATA_TREE, { leaf_value }, ws_revision.forkId);
771 return result;
772}
773
775 const NullifierLeafValue& leaf_value)
776{
777 // Throws CancelledException if cancelled.
779
780 // Invalidate the cached tree roots.
782
784 MerkleTreeId::NULLIFIER_TREE, { leaf_value }, ws_revision.forkId);
785 return result;
786}
787
789{
790 // Throws CancelledException if cancelled.
792
793 // Invalidate the cached tree roots.
795
796 ws_instance.append_leaves(tree_id, std::vector<FF>(leaves.begin(), leaves.end()), ws_revision.forkId);
797}
798
799void PureRawMerkleDB::pad_tree(MerkleTreeId tree_id, size_t num_leaves)
800{
801 // Throws CancelledException if cancelled.
803
804 // Invalidate the cached tree roots.
806
807 // The only trees that should be padded are NULLIFIER_TREE and NOTE_HASH_TREE
808 switch (tree_id) {
809 case MerkleTreeId::NULLIFIER_TREE: {
812 MerkleTreeId::NULLIFIER_TREE, padding_leaves, NULLIFIER_SUBTREE_HEIGHT, ws_revision.forkId);
813 break;
814 }
815 case MerkleTreeId::NOTE_HASH_TREE: {
816 std::vector<FF> padding_leaves(num_leaves, FF(0));
817 ws_instance.append_leaves(MerkleTreeId::NOTE_HASH_TREE, padding_leaves, ws_revision.forkId);
818 break;
819 }
820 default:
821 throw std::runtime_error("Padding not supported for tree " + std::to_string(static_cast<uint64_t>(tree_id)));
822 }
823}
824
826{
828 // Since the world state checkpoint stack is opaque, we track our own checkpoint ids.
829 uint32_t current_id = checkpoint_stack.top();
830 checkpoint_stack.push(current_id + 1);
831}
832
838
840{
841 // Invalidate the cached tree roots.
843
845 checkpoint_stack.pop();
846}
847
849{
850 return checkpoint_stack.top();
851}
852
853} // namespace bb::avm2::simulation
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define NULLIFIER_SUBTREE_HEIGHT
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
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.
uint32_t checkpoint(const uint64_t &forkId)
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.
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:23
#define vinfo(...)
Definition log.hpp:94
#define debug(...)
Definition log.hpp:99
auto & get_tree_info_helper(world_state::MerkleTreeId tree_id, auto &tree_roots)
Definition db_types.hpp:72
AVM range check gadget for witness generation.
::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
AvmFlavorSettings::FF FF
Definition field.hpp:10
FF ContractClassId
FF FunctionSelector
@ L1_TO_L2_MESSAGE_TREE
Definition types.hpp:23
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:384
std::vector< GetSiblingPathHint > get_sibling_path_hints
Definition avm_io.hpp:375
std::vector< DebugFunctionNameHint > debug_function_names
Definition avm_io.hpp:369
std::vector< ContractDBCreateCheckpointHint > contract_db_create_checkpoint_hints
Definition avm_io.hpp:370
std::vector< ContractDBCommitCheckpointHint > contract_db_commit_checkpoint_hints
Definition avm_io.hpp:371
std::vector< CommitCheckpointHint > commit_checkpoint_hints
Definition avm_io.hpp:387
std::vector< SequentialInsertHint< crypto::merkle_tree::PublicDataLeafValue > > sequential_insert_hints_public_data_tree
Definition avm_io.hpp:383
std::vector< RevertCheckpointHint > revert_checkpoint_hints
Definition avm_io.hpp:388
std::vector< ContractDBRevertCheckpointHint > contract_db_revert_checkpoint_hints
Definition avm_io.hpp:372
std::vector< GetPreviousValueIndexHint > get_previous_value_index_hints
Definition avm_io.hpp:376
std::vector< GetLeafPreimageHint< crypto::merkle_tree::IndexedLeaf< crypto::merkle_tree::PublicDataLeafValue > > > get_leaf_preimage_hints_public_data_tree
Definition avm_io.hpp:378
std::vector< GetLeafPreimageHint< crypto::merkle_tree::IndexedLeaf< crypto::merkle_tree::NullifierLeafValue > > > get_leaf_preimage_hints_nullifier_tree
Definition avm_io.hpp:380
std::vector< CreateCheckpointHint > create_checkpoint_hints
Definition avm_io.hpp:386
std::vector< GetLeafValueHint > get_leaf_value_hints
Definition avm_io.hpp:381
std::vector< AppendLeavesHint > append_leaves_hints
Definition avm_io.hpp:385
std::vector< ContractInstanceHint > contract_instances
Definition avm_io.hpp:366
std::vector< ContractClassHint > contract_classes
Definition avm_io.hpp:367
std::vector< BytecodeCommitmentHint > bytecode_commitments
Definition avm_io.hpp:368
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