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
15
16namespace bb::avm2::simulation {
17
18namespace {
19
20std::string to_string(const TreeSnapshots& snapshots)
21{
22 return format("PUBLIC_DATA_TREE: ",
23 snapshots.public_data_tree,
24 "\nNULLIFIER_TREE: ",
25 snapshots.nullifier_tree,
26 "\nNOTE_HASH_TREE: ",
27 snapshots.note_hash_tree,
28 "\nL1_TO_L2_MESSAGE_TREE: ",
29 snapshots.l1_to_l2_message_tree);
30}
31
32std::string get_tree_name(world_state::MerkleTreeId tree_id)
33{
34 switch (tree_id) {
36 return "PUBLIC_DATA_TREE";
38 return "NULLIFIER_TREE";
40 return "NOTE_HASH_TREE";
42 return "L1_TO_L2_MESSAGE_TREE";
44 return "ARCHIVE";
45 }
46
47 return "UNKNOWN"; // To make GCC happy.
48}
49
50} // namespace
51
52// HintedRawContractDB starts.
54{
55 BB_BENCH_NAME("HintedRawContractDB::HintedRawContractDB");
56
57 vinfo("Initializing HintedRawContractDB with...",
58 "\n * contract_instances: ",
59 hints.contract_instances.size(),
60 "\n * contract_classes: ",
61 hints.contract_classes.size(),
62 "\n * bytecode_commitments: ",
63 hints.bytecode_commitments.size(),
64 "\n * debug_function_names: ",
65 hints.debug_function_names.size());
66
67 for (const auto& contract_instance_hint : hints.contract_instances) {
68 contract_instances[std::make_tuple(contract_instance_hint.hint_key, contract_instance_hint.address)] =
69 contract_instance_hint;
70 }
71
72 for (const auto& contract_class_hint : hints.contract_classes) {
73 contract_classes[std::make_tuple(contract_class_hint.hint_key, contract_class_hint.class_id)] =
74 contract_class_hint;
75 }
76
77 for (const auto& bytecode_commitment_hint : hints.bytecode_commitments) {
78 bytecode_commitments[std::make_tuple(bytecode_commitment_hint.hint_key, bytecode_commitment_hint.class_id)] =
79 bytecode_commitment_hint.commitment;
80 }
81
82 for (const auto& debug_function_name_hint : hints.debug_function_names) {
83 debug_function_names[std::make_pair(debug_function_name_hint.address, debug_function_name_hint.selector)] =
84 debug_function_name_hint.name;
85 }
86
87 for (const auto& hint : hints.contract_db_create_checkpoint_hints) {
88 create_checkpoint_hints[hint.action_counter] = hint;
89 }
90 for (const auto& hint : hints.contract_db_commit_checkpoint_hints) {
91 commit_checkpoint_hints[hint.action_counter] = hint;
92 }
93 for (const auto& hint : hints.contract_db_revert_checkpoint_hints) {
94 revert_checkpoint_hints[hint.action_counter] = hint;
95 }
96}
97
99{
100 uint32_t hint_key = action_counter;
101 auto key = std::make_tuple(hint_key, address);
102 auto it = contract_instances.find(key);
103 if (it == contract_instances.end()) {
104 vinfo("Contract instance not found for key (", hint_key, ", ", address, ")");
105 return std::nullopt;
106 }
107 const auto& contract_instance_hint = it->second;
108
110 .salt = contract_instance_hint.salt,
111 .deployer = contract_instance_hint.deployer,
112 .current_contract_class_id = contract_instance_hint.current_contract_class_id,
113 .original_contract_class_id = contract_instance_hint.original_contract_class_id,
114 .initialization_hash = contract_instance_hint.initialization_hash,
115 .public_keys =
117 .nullifier_key = contract_instance_hint.public_keys.master_nullifier_public_key,
118 .incoming_viewing_key = contract_instance_hint.public_keys.master_incoming_viewing_public_key,
119 .outgoing_viewing_key = contract_instance_hint.public_keys.master_outgoing_viewing_public_key,
120 .tagging_key = contract_instance_hint.public_keys.master_tagging_public_key,
121 },
122 });
123}
124
126{
127 uint32_t hint_key = action_counter;
128 auto key = std::make_tuple(hint_key, class_id);
129 auto it = contract_classes.find(key);
130 if (it == contract_classes.end()) {
131 vinfo("Contract class not found for key (", hint_key, ", ", class_id, ")");
132 return std::nullopt;
133 }
134 const auto& contract_class_hint = it->second;
135
137 .id = class_id,
138 .artifact_hash = contract_class_hint.artifact_hash,
139 .private_functions_root = contract_class_hint.private_functions_root,
140 .packed_bytecode = contract_class_hint.packed_bytecode,
141 });
142}
143
145{
146 uint32_t hint_key = action_counter;
147 auto key = std::make_tuple(hint_key, class_id);
148 auto it = bytecode_commitments.find(key);
149 if (it == bytecode_commitments.end()) {
150 vinfo("Bytecode commitment not found for key (", hint_key, ", ", class_id, ")");
151 return std::nullopt;
152 }
153 return it->second;
154}
155
157 const FunctionSelector& selector) const
158{
159 auto it = debug_function_names.find(std::make_pair(address, selector));
160 if (it != debug_function_names.end()) {
161 return it->second;
162 }
163 return std::nullopt;
164}
165
166void HintedRawContractDB::add_contracts([[maybe_unused]] const ContractDeploymentData& contract_deployment_data)
167{
168 debug("add_contracts called (no-op in hinted mode)");
169}
170
172{
173 auto hint_it = create_checkpoint_hints.find(action_counter);
174 assert(hint_it != create_checkpoint_hints.end());
175
176 const auto& hint = hint_it->second;
177 assert(hint.old_checkpoint_id == checkpoint_stack.top());
178
179 checkpoint_stack.push(hint.new_checkpoint_id);
181}
182
184{
185 auto hint_it = commit_checkpoint_hints.find(action_counter);
186 assert(hint_it != commit_checkpoint_hints.end());
187
188 const auto& hint = hint_it->second;
189 assert(hint.old_checkpoint_id == checkpoint_stack.top());
190
191 checkpoint_stack.pop();
192 assert(hint.new_checkpoint_id == checkpoint_stack.top());
194 (void)hint;
195}
196
198{
199 auto hint_it = revert_checkpoint_hints.find(action_counter);
200 assert(hint_it != revert_checkpoint_hints.end());
201
202 const auto& hint = hint_it->second;
203 assert(hint.old_checkpoint_id == checkpoint_stack.top());
204
205 checkpoint_stack.pop();
206 assert(hint.new_checkpoint_id == checkpoint_stack.top());
208 (void)hint;
209}
210
212{
213 return checkpoint_stack.top();
214}
215
216// Hinted MerkleDB starts.
218 : tree_roots(hints.starting_tree_roots)
219{
220 BB_BENCH_NAME("HintedRawMerkleDB::HintedRawMerkleDB");
221
222 vinfo("Initializing HintedRawMerkleDB with...",
223 "\n * get_sibling_path_hints: ",
224 hints.get_sibling_path_hints.size(),
225 "\n * get_previous_value_index_hints: ",
227 "\n * get_leaf_preimage_hints_public_data_tree: ",
229 "\n * get_leaf_preimage_hints_nullifier_tree: ",
231 "\n * get_leaf_value_hints: ",
232 hints.get_leaf_value_hints.size(),
233 "\n * sequential_insert_hints_public_data_tree: ",
235 "\n * sequential_insert_hints_nullifier_tree: ",
237 "\n * append_leaves_hints: ",
238 hints.append_leaves_hints.size(),
239 "\n * create_checkpoint_hints: ",
240 hints.create_checkpoint_hints.size(),
241 "\n * commit_checkpoint_hints: ",
242 hints.commit_checkpoint_hints.size(),
243 "\n * revert_checkpoint_hints: ",
244 hints.revert_checkpoint_hints.size());
245 debug("Initializing HintedRawMerkleDB with snapshots...\n", to_string(tree_roots));
246
247 for (const auto& get_sibling_path_hint : hints.get_sibling_path_hints) {
248 GetSiblingPathKey key = { get_sibling_path_hint.hint_key,
249 get_sibling_path_hint.tree_id,
250 get_sibling_path_hint.index };
251 get_sibling_path_hints[key] = get_sibling_path_hint.path;
252 }
253
254 for (const auto& get_previous_value_index_hint : hints.get_previous_value_index_hints) {
255 GetPreviousValueIndexKey key = { get_previous_value_index_hint.hint_key,
256 get_previous_value_index_hint.tree_id,
257 get_previous_value_index_hint.value };
259 get_previous_value_index_hint.already_present,
260 get_previous_value_index_hint.index,
261 };
262 }
263
264 for (const auto& get_leaf_preimage_hint : hints.get_leaf_preimage_hints_public_data_tree) {
265 GetLeafPreimageKey key = { get_leaf_preimage_hint.hint_key, get_leaf_preimage_hint.index };
266 get_leaf_preimage_hints_public_data_tree[key] = get_leaf_preimage_hint.leaf_preimage;
267 }
268
269 for (const auto& get_leaf_preimage_hint : hints.get_leaf_preimage_hints_nullifier_tree) {
270 GetLeafPreimageKey key = { get_leaf_preimage_hint.hint_key, get_leaf_preimage_hint.index };
271 get_leaf_preimage_hints_nullifier_tree[key] = get_leaf_preimage_hint.leaf_preimage;
272 }
273
274 for (const auto& get_leaf_value_hint : hints.get_leaf_value_hints) {
275 GetLeafValueKey key = { get_leaf_value_hint.hint_key, get_leaf_value_hint.tree_id, get_leaf_value_hint.index };
276 get_leaf_value_hints[key] = get_leaf_value_hint.value;
277 }
278
279 for (const auto& sequential_insert_hint : hints.sequential_insert_hints_public_data_tree) {
280 SequentialInsertHintPublicDataTreeKey key = { sequential_insert_hint.hint_key,
281 sequential_insert_hint.tree_id,
282 sequential_insert_hint.leaf };
283 sequential_insert_hints_public_data_tree[key] = sequential_insert_hint;
284 }
285
286 for (const auto& sequential_insert_hint : hints.sequential_insert_hints_nullifier_tree) {
287 SequentialInsertHintNullifierTreeKey key = { sequential_insert_hint.hint_key,
288 sequential_insert_hint.tree_id,
289 sequential_insert_hint.leaf };
290 sequential_insert_hints_nullifier_tree[key] = sequential_insert_hint;
291 }
292
293 for (const auto& append_leaves_hint : hints.append_leaves_hints) {
294 // Convert the span from the hint to a vector for the key
295 AppendLeavesHintKey key = { append_leaves_hint.hint_key,
296 append_leaves_hint.tree_id,
297 append_leaves_hint.leaves };
298 append_leaves_hints[key] = append_leaves_hint.state_after;
299 }
300
301 for (const auto& create_checkpoint_hint : hints.create_checkpoint_hints) {
302 create_checkpoint_hints[create_checkpoint_hint.action_counter] = create_checkpoint_hint;
303 }
304
305 for (const auto& commit_checkpoint_hint : hints.commit_checkpoint_hints) {
306 commit_checkpoint_hints[commit_checkpoint_hint.action_counter] = commit_checkpoint_hint;
307 }
308
309 for (const auto& revert_checkpoint_hint : hints.revert_checkpoint_hints) {
310 revert_checkpoint_hints[revert_checkpoint_hint.action_counter] = revert_checkpoint_hint;
311 }
312}
313
318
323
325{
326 auto tree_info = get_tree_info(tree_id);
327 GetSiblingPathKey key = { tree_info, tree_id, leaf_index };
328 auto it = get_sibling_path_hints.find(key);
329 if (it == get_sibling_path_hints.end()) {
330 throw std::runtime_error(format("Sibling path not found for key (root: ",
331 tree_info.root,
332 ", size: ",
333 tree_info.next_available_leaf_index,
334 ", tree: ",
335 get_tree_name(tree_id),
336 ", leaf_index: ",
337 leaf_index,
338 ")"));
339 }
340 return it->second;
341}
342
344 const FF& value) const
345{
346 auto tree_info = get_tree_info(tree_id);
347 GetPreviousValueIndexKey key = { tree_info, tree_id, value };
348 auto it = get_previous_value_index_hints.find(key);
349 if (it == get_previous_value_index_hints.end()) {
350 throw std::runtime_error(format("Low indexed leaf not found for key (root: ",
351 tree_info.root,
352 ", size: ",
353 tree_info.next_available_leaf_index,
354 ", tree: ",
355 get_tree_name(tree_id),
356 ", value: ",
357 value,
358 ")"));
359 }
360 return it->second;
361}
362
364{
365 auto tree_info = get_tree_info(tree_id);
366 GetLeafValueKey key = { tree_info, tree_id, leaf_index };
367 auto it = get_leaf_value_hints.find(key);
368 if (it == get_leaf_value_hints.end()) {
369 throw std::runtime_error(format("Leaf value not found for key (root: ",
370 tree_info.root,
371 ", size: ",
372 tree_info.next_available_leaf_index,
373 ", tree: ",
374 get_tree_name(tree_id),
375 ", leaf_index: ",
376 leaf_index,
377 ")"));
378 }
379 return it->second;
380}
381
383{
385 GetLeafPreimageKey key = { tree_info, leaf_index };
388 throw std::runtime_error(format("Leaf preimage (PUBLIC_DATA_TREE) not found for key (root: ",
389 tree_info.root,
390 ", size: ",
391 tree_info.next_available_leaf_index,
392 ", leaf_index: ",
393 leaf_index,
394 ")"));
395 }
396 return it->second;
397}
398
400{
402 GetLeafPreimageKey key = { tree_info, leaf_index };
405 throw std::runtime_error(format("Leaf preimage (NULLIFIER_TREE) not found for key (root: ",
406 tree_info.root,
407 ", size: ",
408 tree_info.next_available_leaf_index,
409 ", leaf_index: ",
410 leaf_index,
411 ")"));
412 }
413 return it->second;
414}
415
417 const PublicDataLeafValue& leaf_value)
418{
423 throw std::runtime_error(format("Sequential insert hint (PUBLIC_DATA_TREE) not found for key (root: ",
424 tree_info.root,
425 ", size: ",
426 tree_info.next_available_leaf_index,
427 ", leaf_value: ",
428 leaf_value,
429 ")"));
430 }
431 const auto& hint = it->second;
432
434
435 // Convert low leaves witness data
436 result.low_leaf_witness_data.emplace_back(
437 hint.low_leaves_witness_data.leaf, hint.low_leaves_witness_data.index, hint.low_leaves_witness_data.path);
438
439 // Convert insertion witness data
440 result.insertion_witness_data.emplace_back(
441 hint.insertion_witness_data.leaf, hint.insertion_witness_data.index, hint.insertion_witness_data.path);
442
443 // Evolve state.
444 tree_roots.public_data_tree = hint.state_after;
445
446 debug("Evolved state of PUBLIC_DATA_TREE: ",
448 " (size: ",
450 ")");
451
452 return result;
453}
454
456 const NullifierLeafValue& leaf_value)
457{
462 throw std::runtime_error(format("Sequential insert hint (NULLIFIER_TREE) not found for key (root: ",
463 tree_info.root,
464 ", size: ",
465 tree_info.next_available_leaf_index,
466 ", leaf_value: ",
467 leaf_value,
468 ")"));
469 }
470 const auto& hint = it->second;
471
473
474 // Convert low leaves witness data
475 result.low_leaf_witness_data.emplace_back(
476 hint.low_leaves_witness_data.leaf, hint.low_leaves_witness_data.index, hint.low_leaves_witness_data.path);
477
478 // Convert insertion witness data
479 result.insertion_witness_data.emplace_back(
480 hint.insertion_witness_data.leaf, hint.insertion_witness_data.index, hint.insertion_witness_data.path);
481
482 // Evolve state.
483 tree_roots.nullifier_tree = hint.state_after;
484
485 debug("Evolved state of NULLIFIER_TREE: ",
487 " (size: ",
489 ")");
490
491 return result;
492}
493
495{
497 if (it == create_checkpoint_hints.end()) {
498 throw std::runtime_error(
499 format("[create_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
500 }
501 const auto& hint = it->second;
502
503 // Sanity check.
504 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
505 throw std::runtime_error(format("[create_checkpoint@",
507 "] Old checkpoint id does not match the current checkpoint id: ",
508 hint.old_checkpoint_id,
509 " != ",
510 checkpoint_stack.top()));
511 }
512
513 debug("[create_checkpoint@",
515 "] Checkpoint evolved ",
516 hint.old_checkpoint_id,
517 " -> ",
518 hint.new_checkpoint_id);
519
520 checkpoint_stack.push(hint.new_checkpoint_id);
522}
523
525{
527 if (it == commit_checkpoint_hints.end()) {
528 throw std::runtime_error(
529 format("[commit_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
530 }
531 const auto& hint = it->second;
532
533 // Sanity check.
534 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
535 throw std::runtime_error(format("[commit_checkpoint@",
537 "] Old checkpoint id does not match the current checkpoint id: ",
538 hint.old_checkpoint_id,
539 " != ",
540 checkpoint_stack.top()));
541 }
542
543 checkpoint_stack.pop();
544
545 // Sanity check.
546 if (hint.new_checkpoint_id != checkpoint_stack.top()) {
547 throw std::runtime_error(format("[commit_checkpoint@",
549 "] New checkpoint id does not match the current checkpoint id: ",
550 hint.new_checkpoint_id,
551 " != ",
552 checkpoint_stack.top()));
553 }
554
555 debug("[commit_checkpoint@",
557 "] Checkpoint evolved ",
558 hint.old_checkpoint_id,
559 " -> ",
560 hint.new_checkpoint_id);
561
563}
564
566{
568 if (it == revert_checkpoint_hints.end()) {
569 throw std::runtime_error(
570 format("[revert_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
571 }
572 const auto& hint = it->second;
573
574 // Sanity check of checkpoint stack.
575 if (hint.old_checkpoint_id != checkpoint_stack.top()) {
576 throw std::runtime_error(format("[revert_checkpoint@",
578 "] Old checkpoint id does not match the current checkpoint id: ",
579 hint.old_checkpoint_id,
580 " != ",
581 checkpoint_stack.top()));
582 }
583
584 // Sanity check of tree snapshots.
585 if (hint.state_before != tree_roots) {
586 vinfo("Hint tree snapshots: ", to_string(hint.state_before));
587 vinfo("Current tree roots: ", to_string(tree_roots));
588 throw std::runtime_error(format("[revert_checkpoint@",
590 "] Hint tree snapshots do not match the current tree roots."));
591 }
592
593 checkpoint_stack.pop();
594
595 // Sanity check.
596 if (hint.new_checkpoint_id != checkpoint_stack.top()) {
597 throw std::runtime_error(format("[revert_checkpoint@",
599 "] New checkpoint id does not match the current checkpoint id: ",
600 hint.new_checkpoint_id,
601 " != ",
602 checkpoint_stack.top()));
603 }
604
605 // Evolve trees.
606 tree_roots = hint.state_after;
607
608 debug("[revert_checkpoint@",
610 "] Checkpoint evolved ",
611 hint.old_checkpoint_id,
612 " -> ",
613 hint.new_checkpoint_id);
614
616}
617
619 std::span<const FF> leaves)
620{
622 results.reserve(leaves.size());
623
624 // We need to process each leaf individually because we need the sibling path after insertion, to be able to
625 // constraint the insertion.
626 // TODO(https://github.com/AztecProtocol/aztec-packages/issues/13380): This can be changed if the world state
627 // appendLeaves returns the sibling paths.
628 for (const auto& leaf : leaves) {
629 results.push_back(appendLeafInternal(tree_id, leaf));
630 }
631
632 return results;
633}
634
636{
637 auto& tree_info = get_tree_info(tree_id);
638 auto size_before = tree_info.next_available_leaf_index;
639 (void)size_before; // To please the compiler.
640 tree_info.next_available_leaf_index += num_leaves;
641
642 debug("Padded tree ",
643 get_tree_name(tree_id),
644 " from size ",
645 size_before,
646 " to ",
647 tree_info.next_available_leaf_index);
648}
649
651{
652 auto tree_info = get_tree_info(tree_id);
653 AppendLeavesHintKey key = { tree_info, tree_id, { leaf } };
654 auto it = append_leaves_hints.find(key);
655 if (it == append_leaves_hints.end()) {
656 throw std::runtime_error(format("Append leaves hint not found for key (root: ",
657 tree_info.root,
658 ", size: ",
659 tree_info.next_available_leaf_index,
660 ", tree: ",
661 get_tree_name(tree_id),
662 ", leaf: ",
663 leaf,
664 ")"));
665 }
666 const auto& state_after = it->second;
667
668 // Update the tree state based on the hint.
669 switch (tree_id) {
671 tree_roots.note_hash_tree = state_after;
672 debug("Evolved state of NOTE_HASH_TREE: ",
674 " (size: ",
676 ")");
677 break;
679 tree_roots.l1_to_l2_message_tree = state_after;
680 debug("Evolved state of L1_TO_L2_MESSAGE_TREE: ",
682 " (size: ",
684 ")");
685 break;
686 default:
687 throw std::runtime_error("append_leaves is only supported for NOTE_HASH_TREE and L1_TO_L2_MESSAGE_TREE");
688 }
689
690 // Get the sibling path for the newly inserted leaf.
691 return { .root = tree_info.root, .path = get_sibling_path(tree_id, tree_info.next_available_leaf_index) };
692}
693
695{
696 return checkpoint_stack.top();
697}
698
699// PureRawMerkleDB starts.
701{
702 auto l1_to_l2_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
703 auto note_hash_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::NOTE_HASH_TREE);
704 auto nullifier_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::NULLIFIER_TREE);
705 auto public_data_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::PUBLIC_DATA_TREE);
706
707 return TreeSnapshots{
708 .l1_to_l2_message_tree = AppendOnlyTreeSnapshot{ .root = l1_to_l2_info.meta.root,
709 .next_available_leaf_index = l1_to_l2_info.meta.size },
710 .note_hash_tree = AppendOnlyTreeSnapshot{ .root = note_hash_info.meta.root,
711 .next_available_leaf_index = note_hash_info.meta.size },
712 .nullifier_tree = AppendOnlyTreeSnapshot{ .root = nullifier_info.meta.root,
713 .next_available_leaf_index = nullifier_info.meta.size },
714 .public_data_tree = AppendOnlyTreeSnapshot{ .root = public_data_info.meta.root,
715 .next_available_leaf_index = public_data_info.meta.size },
716 };
717}
718
720{
721 return ws_instance.get_sibling_path(ws_revision, tree_id, leaf_index);
722}
723
728
730{
731 std::optional<FF> res = ws_instance.get_leaf<FF>(ws_revision, tree_id, leaf_index);
732 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
733 if (!res.has_value()) {
734 throw std::runtime_error(
735 format("Invalid get_leaf_value request", static_cast<uint64_t>(tree_id), " for index ", leaf_index));
736 }
737 return res.value();
738}
739
741{
743 ws_instance.get_indexed_leaf<PublicDataLeafValue>(ws_revision, MerkleTreeId::PUBLIC_DATA_TREE, leaf_index);
744 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
745 if (!res.has_value()) {
746 throw std::runtime_error(format("Invalid get_leaf_preimage_public_data_tree request for index ", leaf_index));
747 }
748 return res.value();
749}
750
752{
754 ws_instance.get_indexed_leaf<NullifierLeafValue>(ws_revision, MerkleTreeId::NULLIFIER_TREE, leaf_index);
755 // If the optional is not set, we assume something is wrong (e.g. leaf index out of bounds)
756 if (!res.has_value()) {
757 throw std::runtime_error(format("Invalid get_leaf_preimage_nullifier_tree request for index ", leaf_index));
758 }
759 return res.value();
760}
761
762// State modification methods.
764 const PublicDataLeafValue& leaf_value)
765{
767 MerkleTreeId::PUBLIC_DATA_TREE, { leaf_value }, ws_revision.forkId);
768 return result;
769}
770
772 const NullifierLeafValue& leaf_value)
773{
775 MerkleTreeId::NULLIFIER_TREE, { leaf_value }, ws_revision.forkId);
776 return result;
777}
778
779// This method currently returns a vector of intermediate roots and sibling paths, but in practice we might only
780// need or care about the last one for simulation, this would simplify how we append in this function.
781// todo(ilyas): Given this function says append, perhaps we just want to restrict to NoteHash?
783{
784 std::vector<FF> leaves_vec(leaves.begin(), leaves.end());
785
786 // If we wanted intermediate roots and paths, we would need to call append_leaves one by one
787 ws_instance.append_leaves(tree_id, leaves_vec, ws_revision.forkId);
788
789 auto tree_info = ws_instance.get_tree_info(ws_revision, MerkleTreeId::NOTE_HASH_TREE);
790 return { AppendLeafResult{ .root = tree_info.meta.root,
791 .path = get_sibling_path(tree_id, tree_info.meta.size - 1) } };
792}
793
794void PureRawMerkleDB::pad_tree(MerkleTreeId tree_id, size_t num_leaves)
795{
796 // The only trees that should be padded are NULLIFIER_TREE and NOTE_HASH_TREE
797 switch (tree_id) {
798 case MerkleTreeId::NULLIFIER_TREE: {
801 MerkleTreeId::NULLIFIER_TREE, padding_leaves, NULLIFIER_SUBTREE_HEIGHT, ws_revision.forkId);
802 break;
803 }
804 case MerkleTreeId::NOTE_HASH_TREE: {
805 std::vector<FF> padding_leaves(num_leaves, FF(0));
806 ws_instance.append_leaves(MerkleTreeId::NOTE_HASH_TREE, padding_leaves, ws_revision.forkId);
807 break;
808 }
809 default:
810 throw std::runtime_error("Padding not supported for tree " + std::to_string(static_cast<uint64_t>(tree_id)));
811 }
812}
813
815{
817 // Since the world state checkpoint stack is opaque, we track our own checkpoint ids.
818 uint32_t current_id = checkpoint_stack.top();
819 checkpoint_stack.push(current_id + 1);
820}
821
827
833
835{
836 return checkpoint_stack.top();
837}
838
839} // namespace bb::avm2::simulation
#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
std::vector< AppendLeafResult > append_leaves(MerkleTreeId tree_id, std::span< const FF > leaves) override
AppendLeafResult appendLeafInternal(MerkleTreeId tree_id, const FF &leaf)
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
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
world_state::WorldState & ws_instance
IndexedLeaf< NullifierLeafValue > get_leaf_preimage_nullifier_tree(index_t leaf_index) const override
std::vector< AppendLeafResult > append_leaves(MerkleTreeId tree_id, std::span< const FF > leaves) override
GetLowIndexedLeafResponse get_low_indexed_leaf(MerkleTreeId tree_id, const FF &value) const override
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:22
#define vinfo(...)
Definition log.hpp:80
#define debug(...)
Definition log.hpp:62
auto & get_tree_info_helper(world_state::MerkleTreeId tree_id, auto &tree_roots)
Definition db_types.hpp:71
::bb::crypto::merkle_tree::fr_sibling_path SiblingPath
Definition db.hpp:36
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, index_t > GetSiblingPathKey
Definition db_types.hpp:15
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, index_t > GetLeafValueKey
Definition db_types.hpp:18
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, NullifierLeafValue > SequentialInsertHintNullifierTreeKey
Definition db_types.hpp:20
std::tuple< AppendOnlyTreeSnapshot, index_t > GetLeafPreimageKey
Definition db_types.hpp:17
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, PublicDataLeafValue > SequentialInsertHintPublicDataTreeKey
Definition db_types.hpp:19
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, FF > GetPreviousValueIndexKey
Definition db_types.hpp:16
std::tuple< AppendOnlyTreeSnapshot, MerkleTreeId, std::vector< FF > > AppendLeavesHintKey
Definition db_types.hpp:21
::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:29
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