Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
written_public_data_slots_tree_check.cpp
Go to the documentation of this file.
2
5
6namespace bb::avm2::simulation {
7
12
14 const WrittenPublicDataSlotsTreeLeafPreimage& low_leaf_preimage, const FF& leaf_slot)
15{
16 if (!field_gt.ff_gt(leaf_slot, low_leaf_preimage.leaf.slot)) {
17 throw std::runtime_error("Low leaf slot is GTE leaf slot");
18 }
19 if (low_leaf_preimage.nextKey != 0 && !field_gt.ff_gt(low_leaf_preimage.nextKey, leaf_slot)) {
20 throw std::runtime_error("Leaf slot is GTE low leaf next slot");
21 }
22}
23
25{
27
28 const auto& tree = written_public_data_slots_tree_stack.top();
29 const auto snapshot = tree.get_snapshot();
30 auto [exists, low_leaf_index] = tree.get_low_indexed_leaf(leaf_slot);
31 auto sibling_path = tree.get_sibling_path(low_leaf_index);
32 auto low_leaf_preimage = tree.get_leaf_preimage(low_leaf_index);
33
34 // Low leaf membership
35 FF low_leaf_hash = poseidon2.hash(low_leaf_preimage.get_hash_inputs());
36 merkle_check.assert_membership(low_leaf_hash, low_leaf_index, sibling_path, snapshot.root);
37
38 if (exists) {
39 if (low_leaf_preimage.leaf.slot != leaf_slot) {
40 throw std::runtime_error("Slot membership check failed");
41 }
42 } else {
43 validate_low_leaf_jumps_over_slot(low_leaf_preimage, leaf_slot);
44 }
45
48 .slot = slot,
49 .leaf_slot = leaf_slot,
50 .prev_snapshot = snapshot,
51 .next_snapshot = snapshot,
52 .low_leaf_preimage = low_leaf_preimage,
53 .low_leaf_hash = low_leaf_hash,
54 .low_leaf_index = low_leaf_index,
55 });
56
57 return exists;
58}
59
61{
63
64 auto& tree = written_public_data_slots_tree_stack.top();
65 AppendOnlyTreeSnapshot prev_snapshot = tree.get_snapshot();
66 auto insertion_result = tree.insert_indexed_leaves({ { WrittenPublicDataSlotLeafValue(leaf_slot) } });
67 auto& [low_leaf_preimage, low_leaf_index, low_leaf_sibling_path] = insertion_result.low_leaf_witness_data.at(0);
68 std::span<FF> insertion_sibling_path = insertion_result.insertion_witness_data.at(0).path;
69
70 bool exists = leaf_slot == low_leaf_preimage.leaf.slot;
71
72 AppendOnlyTreeSnapshot next_snapshot = prev_snapshot;
74
75 FF low_leaf_hash = poseidon2.hash(low_leaf_preimage.get_hash_inputs());
76 if (exists) {
77 merkle_check.assert_membership(low_leaf_hash, low_leaf_index, low_leaf_sibling_path, prev_snapshot.root);
78 } else {
79 validate_low_leaf_jumps_over_slot(low_leaf_preimage, leaf_slot);
80 // Low leaf update
81 WrittenPublicDataSlotsTreeLeafPreimage updated_low_leaf_preimage = low_leaf_preimage;
82 updated_low_leaf_preimage.nextIndex = prev_snapshot.nextAvailableLeafIndex;
83 updated_low_leaf_preimage.nextKey = leaf_slot;
84
85 FF updated_low_leaf_hash = poseidon2.hash(updated_low_leaf_preimage.get_hash_inputs());
86
87 FF intermediate_root = merkle_check.write(
88 low_leaf_hash, updated_low_leaf_hash, low_leaf_index, low_leaf_sibling_path, prev_snapshot.root);
89
91 WrittenPublicDataSlotLeafValue(leaf_slot), low_leaf_preimage.nextIndex, low_leaf_preimage.nextKey);
92
93 FF new_leaf_hash = poseidon2.hash(new_leaf_preimage.get_hash_inputs());
94
95 FF write_root = merkle_check.write(
96 FF(0), new_leaf_hash, prev_snapshot.nextAvailableLeafIndex, insertion_sibling_path, intermediate_root);
97
98 next_snapshot = AppendOnlyTreeSnapshot{
99 .root = write_root,
100 .nextAvailableLeafIndex = prev_snapshot.nextAvailableLeafIndex + 1,
101 };
102 assert(next_snapshot == tree.get_snapshot());
103 append_data = SlotAppendData{
104 .updated_low_leaf_hash = updated_low_leaf_hash,
105 .new_leaf_hash = new_leaf_hash,
106 .intermediate_root = intermediate_root,
107 };
108 }
109
112 .slot = slot,
113 .leaf_slot = leaf_slot,
114 .prev_snapshot = prev_snapshot,
115 .next_snapshot = next_snapshot,
116 .low_leaf_preimage = low_leaf_preimage,
117 .low_leaf_hash = low_leaf_hash,
118 .low_leaf_index = low_leaf_index,
119 .write = true,
120 .append_data = append_data,
121 });
122}
123
128
130{
131 // -1 Since the tree has a prefill leaf at index 0.
132 return static_cast<uint32_t>(written_public_data_slots_tree_stack.top().get_snapshot().nextAvailableLeafIndex) - 1;
133}
134
139
141{
142 // Commit the current top of the stack down one level.
146}
147
152
153} // namespace bb::avm2::simulation
#define GENERATOR_INDEX__PUBLIC_LEAF_INDEX
virtual bool ff_gt(const FF &a, const FF &b)=0
bool contains(const AztecAddress &contract_address, const FF &slot) override
FF compute_leaf_slot(const AztecAddress &contract_address, const FF &slot)
void validate_low_leaf_jumps_over_slot(const WrittenPublicDataSlotsTreeLeafPreimage &low_leaf_preimage, const FF &leaf_slot)
void insert(const AztecAddress &contract_address, const FF &slot) override
EventEmitterInterface< WrittenPublicDataSlotsTreeCheckEvent > & events
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
IndexedLeaf< WrittenPublicDataSlotLeafValue > WrittenPublicDataSlotsTreeLeafPreimage
AvmFlavorSettings::FF FF
Definition field.hpp:10
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::vector< fr > get_hash_inputs() const