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
6
7namespace bb::avm2::simulation {
8
13
15 const WrittenPublicDataSlotsTreeLeafPreimage& low_leaf_preimage, const FF& leaf_slot)
16{
17 if (!field_gt.ff_gt(leaf_slot, low_leaf_preimage.leaf.slot)) {
18 throw std::runtime_error("Low leaf slot is GTE leaf slot");
19 }
20 if (low_leaf_preimage.nextKey != 0 && !field_gt.ff_gt(low_leaf_preimage.nextKey, leaf_slot)) {
21 throw std::runtime_error("Leaf slot is GTE low leaf next slot");
22 }
23}
24
26{
28
29 const auto& tree = written_public_data_slots_tree_stack.top();
30 const auto snapshot = tree.get_snapshot();
31 auto [exists, low_leaf_index] = tree.get_low_indexed_leaf(leaf_slot);
32 auto sibling_path = tree.get_sibling_path(low_leaf_index);
33 auto low_leaf_preimage = tree.get_leaf_preimage(low_leaf_index);
34
35 // Low leaf membership
36 FF low_leaf_hash = poseidon2.hash(low_leaf_preimage.get_hash_inputs());
37 merkle_check.assert_membership(low_leaf_hash, low_leaf_index, sibling_path, snapshot.root);
38
39 if (exists) {
40 if (low_leaf_preimage.leaf.slot != leaf_slot) {
41 throw std::runtime_error("Slot membership check failed");
42 }
43 } else {
44 validate_low_leaf_jumps_over_slot(low_leaf_preimage, leaf_slot);
45 }
46
49 .slot = slot,
50 .leaf_slot = leaf_slot,
51 .prev_snapshot = snapshot,
52 .next_snapshot = snapshot,
53 .low_leaf_preimage = low_leaf_preimage,
54 .low_leaf_hash = low_leaf_hash,
55 .low_leaf_index = low_leaf_index,
56 });
57
58 return exists;
59}
60
62{
64
65 auto& tree = written_public_data_slots_tree_stack.top();
66 AppendOnlyTreeSnapshot prev_snapshot = tree.get_snapshot();
67 auto insertion_result = tree.insert_indexed_leaves({ { WrittenPublicDataSlotLeafValue(leaf_slot) } });
68 auto& [low_leaf_preimage, low_leaf_index, low_leaf_sibling_path] = insertion_result.low_leaf_witness_data.at(0);
69 std::span<FF> insertion_sibling_path = insertion_result.insertion_witness_data.at(0).path;
70
71 bool exists = leaf_slot == low_leaf_preimage.leaf.slot;
72
73 AppendOnlyTreeSnapshot next_snapshot = prev_snapshot;
75
76 FF low_leaf_hash = poseidon2.hash(low_leaf_preimage.get_hash_inputs());
77 if (exists) {
78 merkle_check.assert_membership(low_leaf_hash, low_leaf_index, low_leaf_sibling_path, prev_snapshot.root);
79 } else {
80 validate_low_leaf_jumps_over_slot(low_leaf_preimage, leaf_slot);
81 // Low leaf update
82 WrittenPublicDataSlotsTreeLeafPreimage updated_low_leaf_preimage = low_leaf_preimage;
83 updated_low_leaf_preimage.nextIndex = prev_snapshot.next_available_leaf_index;
84 updated_low_leaf_preimage.nextKey = leaf_slot;
85
86 FF updated_low_leaf_hash = poseidon2.hash(updated_low_leaf_preimage.get_hash_inputs());
87
88 FF intermediate_root = merkle_check.write(
89 low_leaf_hash, updated_low_leaf_hash, low_leaf_index, low_leaf_sibling_path, prev_snapshot.root);
90
92 WrittenPublicDataSlotLeafValue(leaf_slot), low_leaf_preimage.nextIndex, low_leaf_preimage.nextKey);
93
94 FF new_leaf_hash = poseidon2.hash(new_leaf_preimage.get_hash_inputs());
95
96 FF write_root = merkle_check.write(
97 FF(0), new_leaf_hash, prev_snapshot.next_available_leaf_index, insertion_sibling_path, intermediate_root);
98
99 next_snapshot = AppendOnlyTreeSnapshot{
100 .root = write_root,
101 .next_available_leaf_index = prev_snapshot.next_available_leaf_index + 1,
102 };
103 // This will throw an unexpected exception if it fails.
104 BB_ASSERT_EQ(next_snapshot, tree.get_snapshot(), "Next snapshot mismatch");
105 append_data = SlotAppendData{
106 .updated_low_leaf_hash = updated_low_leaf_hash,
107 .new_leaf_hash = new_leaf_hash,
108 .intermediate_root = intermediate_root,
109 };
110 }
111
114 .slot = slot,
115 .leaf_slot = leaf_slot,
116 .prev_snapshot = prev_snapshot,
117 .next_snapshot = next_snapshot,
118 .low_leaf_preimage = low_leaf_preimage,
119 .low_leaf_hash = low_leaf_hash,
120 .low_leaf_index = low_leaf_index,
121 .write = true,
122 .append_data = append_data,
123 });
124}
125
130
132{
133 // -1 Since the tree has a prefill leaf at index 0.
134 return static_cast<uint32_t>(written_public_data_slots_tree_stack.top().get_snapshot().next_available_leaf_index) -
135 1;
136}
137
143
145{
146 // Commit the current top of the stack down one level.
150}
151
156
157} // namespace bb::avm2::simulation
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:93
#define DOM_SEP__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