Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
public_data_tree_trace.cpp
Go to the documentation of this file.
2
9
10// This tracegen file will generate both the public data check trace and the public data squash trace from the same
11// events. These two traces are sorted in a different order, so we need to process them separately.
12namespace bb::avm2::tracegen {
13
15using simulation::PublicDataTreeReadWriteEvent;
16
17namespace {
18
19struct EventWithDiscard {
20 simulation::PublicDataTreeReadWriteEvent event;
21 bool discard;
22};
23
24void process_public_data_tree_check_trace(const std::vector<EventWithDiscard>& events_with_metadata,
25 const std::unordered_map<FF, uint32_t>& first_write_per_slot,
26 const std::unordered_map<FF, FF>& last_value_per_slot,
27 TraceContainer& trace)
28{
29 using C = Column;
30
31 // This is a shifted trace, so we start at 1
32 uint32_t row = 1;
33
35
36 for (size_t i = 0; i < events_with_metadata.size(); i++) {
37 bool end = i == events_with_metadata.size() - 1;
38 const auto& event = events_with_metadata[i].event;
39 const bool discard = events_with_metadata[i].discard;
40
41 bool exists = event.low_leaf_preimage.leaf.slot == event.leaf_slot;
42 FF slot_low_leaf_slot_diff_inv = exists ? 0 : (event.leaf_slot - event.low_leaf_preimage.leaf.slot).invert();
43
44 bool next_slot_is_nonzero = false;
45 FF next_slot_inv = 0;
46 if (!exists) {
47 next_slot_is_nonzero = event.low_leaf_preimage.nextKey != 0;
48 next_slot_inv = next_slot_is_nonzero ? event.low_leaf_preimage.nextKey.invert() : 0;
49 }
50
51 bool write = event.write_data.has_value();
52 bool should_insert = !exists && write;
53 bool nondiscarded_write = write && !discard;
54 bool should_write_to_public_inputs =
55 nondiscarded_write && first_write_per_slot.at(event.leaf_slot) == event.execution_id;
56 FF final_value = nondiscarded_write ? last_value_per_slot.at(event.leaf_slot) : 0;
57
58 FF intermediate_root = 0;
60 FF updated_low_leaf_hash = 0;
61 FF new_leaf_hash = 0;
62 AppendOnlyTreeSnapshot next_snapshot = event.prev_snapshot;
63
64 if (write) {
65 next_snapshot = event.write_data->next_snapshot;
66 intermediate_root = event.write_data->intermediate_root;
67 updated_low_leaf = event.write_data->updated_low_leaf_preimage;
68 updated_low_leaf_hash = event.write_data->updated_low_leaf_hash;
69 new_leaf_hash = event.write_data->new_leaf_hash;
70 }
71 uint32_t clk = event.execution_id;
72 uint32_t clk_diff = end ? 0 : events_with_metadata[i + 1].event.execution_id - clk;
73
74 uint32_t public_data_writes_length = write_idx -
76 static_cast<uint32_t>(should_write_to_public_inputs);
77
78 trace.set(row,
79 { {
80 { C::public_data_check_sel, 1 },
81 { C::public_data_check_not_end, !end },
82 { C::public_data_check_end, end },
83 { C::public_data_check_value, event.value },
84 { C::public_data_check_slot, event.slot },
85 { C::public_data_check_root, event.prev_snapshot.root },
86 { C::public_data_check_address, event.contract_address },
87 { C::public_data_check_write_root, next_snapshot.root },
88 { C::public_data_check_tree_size_before_write, event.prev_snapshot.nextAvailableLeafIndex },
89 { C::public_data_check_tree_size_after_write, next_snapshot.nextAvailableLeafIndex },
90 { C::public_data_check_write, write },
91 { C::public_data_check_clk, clk },
92 { C::public_data_check_discard, discard },
93 { C::public_data_check_low_leaf_slot, event.low_leaf_preimage.leaf.slot },
94 { C::public_data_check_low_leaf_value, event.low_leaf_preimage.leaf.value },
95 { C::public_data_check_low_leaf_next_index, event.low_leaf_preimage.nextIndex },
96 { C::public_data_check_low_leaf_next_slot, event.low_leaf_preimage.nextKey },
97 { C::public_data_check_updated_low_leaf_value, updated_low_leaf.leaf.value },
98 { C::public_data_check_updated_low_leaf_next_index, updated_low_leaf.nextIndex },
99 { C::public_data_check_updated_low_leaf_next_slot, updated_low_leaf.nextKey },
100 { C::public_data_check_low_leaf_index, event.low_leaf_index },
101 { C::public_data_check_clk_diff, clk_diff },
102 { C::public_data_check_constant_32, 32 },
103 { C::public_data_check_leaf_slot, event.leaf_slot },
104 { C::public_data_check_siloing_separator, GENERATOR_INDEX__PUBLIC_LEAF_INDEX },
105 { C::public_data_check_leaf_not_exists, !exists },
106 { C::public_data_check_leaf_slot_low_leaf_slot_diff_inv, slot_low_leaf_slot_diff_inv },
107 { C::public_data_check_next_slot_is_nonzero, next_slot_is_nonzero },
108 { C::public_data_check_next_slot_inv, next_slot_inv },
109 { C::public_data_check_low_leaf_hash, event.low_leaf_hash },
110 { C::public_data_check_intermediate_root, intermediate_root },
111 { C::public_data_check_tree_height, PUBLIC_DATA_TREE_HEIGHT },
112 { C::public_data_check_updated_low_leaf_hash, updated_low_leaf_hash },
113 { C::public_data_check_should_insert, should_insert },
114 { C::public_data_check_new_leaf_hash, new_leaf_hash },
115 { C::public_data_check_write_idx, write_idx },
116 { C::public_data_check_nondiscaded_write, nondiscarded_write },
117 { C::public_data_check_should_write_to_public_inputs, should_write_to_public_inputs },
118 { C::public_data_check_final_value, final_value },
119 { C::public_data_check_public_data_writes_length, public_data_writes_length },
120 { C::public_data_check_length_pi_idx,
122 } });
123 row++;
124 if (should_write_to_public_inputs) {
125 write_idx++;
126 }
127 }
128}
129
130void process_squashing_trace(const std::vector<PublicDataTreeReadWriteEvent>& nondiscarded_writes,
131 const std::unordered_map<FF, uint32_t>& first_write_per_slot,
132 const std::unordered_map<FF, FF>& last_value_per_slot,
133 TraceContainer& trace)
134{
135 using C = Column;
136
137 using C = Column;
138
139 // This is a shifted trace, so we start at 1
140 uint32_t row = 1;
141
142 for (size_t i = 0; i < nondiscarded_writes.size(); i++) {
143 bool end = i == nondiscarded_writes.size() - 1;
144 const auto& event = nondiscarded_writes[i];
145
146 uint32_t clk = event.execution_id;
147
148 bool leaf_slot_increase = false;
149 bool check_clock = false;
150 uint32_t clk_diff = 0;
151
152 if (!end) {
153 const auto& next_event = nondiscarded_writes[i + 1];
154
155 if (event.leaf_slot == next_event.leaf_slot) {
156 assert(event.execution_id < next_event.execution_id);
157 clk_diff = next_event.execution_id - event.execution_id;
158 check_clock = true;
159 } else {
160 assert(static_cast<uint256_t>(event.leaf_slot) < static_cast<uint256_t>(next_event.leaf_slot));
161 leaf_slot_increase = true;
162 }
163 }
164
165 bool should_write_to_public_inputs = first_write_per_slot.at(event.leaf_slot) == event.execution_id;
166 FF final_value = last_value_per_slot.at(event.leaf_slot);
167
168 trace.set(row,
169 { {
170 { C::public_data_squash_sel, 1 },
171 { C::public_data_squash_leaf_slot, event.leaf_slot },
172 { C::public_data_squash_value, event.value },
173 { C::public_data_squash_clk, clk },
174 { C::public_data_squash_write_to_public_inputs, should_write_to_public_inputs },
175 { C::public_data_squash_leaf_slot_increase, leaf_slot_increase },
176 { C::public_data_squash_check_clock, check_clock },
177 { C::public_data_squash_clk_diff, clk_diff },
178 { C::public_data_squash_constant_32, 32 },
179 { C::public_data_squash_final_value, final_value },
180 } });
181 row++;
182 }
183}
184
185} // namespace
186
190{
191
192 std::vector<EventWithDiscard> events_with_metadata;
193 std::unordered_map<FF, uint32_t> first_write_per_slot;
194 std::unordered_map<FF, FF> last_value_per_slot;
195
196 events_with_metadata.reserve(events.size());
198 events_with_metadata.push_back({ event, discard });
199 if (!discard && event.write_data.has_value()) {
200 if (!first_write_per_slot.contains(event.leaf_slot)) {
201 first_write_per_slot[event.leaf_slot] = event.execution_id;
202 }
203 last_value_per_slot[event.leaf_slot] = event.value;
204 }
205 });
206
207 // Sort by clk in ascending order (reads will have clk=0)
208 std::sort(events_with_metadata.begin(),
209 events_with_metadata.end(),
210 [](const EventWithDiscard& a, const EventWithDiscard& b) {
211 return a.event.execution_id < b.event.execution_id;
212 });
213
214 process_public_data_tree_check_trace(events_with_metadata, first_write_per_slot, last_value_per_slot, trace);
215
217 nondiscarded_writes.reserve(events_with_metadata.size());
218 // Retain only nondiscarded writes
219 for (const auto& event_with_metadata : events_with_metadata) {
220 if (event_with_metadata.event.write_data.has_value() && !event_with_metadata.discard) {
221 nondiscarded_writes.push_back(event_with_metadata.event);
222 }
223 }
224
225 // Sort by slot, and then by clk
226 std::sort(nondiscarded_writes.begin(),
227 nondiscarded_writes.end(),
228 [](const PublicDataTreeReadWriteEvent& a, const PublicDataTreeReadWriteEvent& b) {
229 if (a.leaf_slot == b.leaf_slot) {
230 return a.execution_id < b.execution_id;
231 }
232 return static_cast<uint256_t>(a.leaf_slot) < static_cast<uint256_t>(b.leaf_slot);
233 });
234
235 process_squashing_trace(nondiscarded_writes, first_write_per_slot, last_value_per_slot, trace);
236}
237
238const InteractionDefinition PublicDataTreeTraceBuilder::interactions =
239 InteractionDefinition()
240 // Public data read/write
241 .add<lookup_public_data_check_silo_poseidon2_settings, InteractionType::LookupGeneric>()
242 .add<lookup_public_data_check_low_leaf_slot_validation_settings, InteractionType::LookupGeneric>()
244 .add<lookup_public_data_check_low_leaf_poseidon2_0_settings, InteractionType::LookupGeneric>()
245 .add<lookup_public_data_check_low_leaf_poseidon2_1_settings, InteractionType::LookupGeneric>()
246 .add<lookup_public_data_check_updated_low_leaf_poseidon2_0_settings, InteractionType::LookupGeneric>()
248 .add<lookup_public_data_check_low_leaf_merkle_check_settings, InteractionType::LookupGeneric>()
249 .add<lookup_public_data_check_new_leaf_poseidon2_0_settings, InteractionType::LookupGeneric>()
250 .add<lookup_public_data_check_new_leaf_poseidon2_1_settings, InteractionType::LookupGeneric>()
251 .add<lookup_public_data_check_new_leaf_merkle_check_settings, InteractionType::LookupGeneric>()
252 .add<perm_public_data_check_squashing_settings, InteractionType::Permutation>()
254 InteractionType::LookupIntoIndexedByClk>()
255 // TODO: Disabled sorting lookups
256 // .add<lookup_public_data_squash_leaf_slot_increase_ff_gt_settings, InteractionType::LookupGeneric>()
257 // .add<lookup_public_data_squash_clk_diff_range_settings, InteractionType::LookupGeneric>()
258 // .add<lookup_public_data_check_clk_diff_range_settings, InteractionType::LookupGeneric>()
260 InteractionType::LookupIntoIndexedByClk>();
261
262} // namespace bb::avm2::tracegen
#define GENERATOR_INDEX__PUBLIC_LEAF_INDEX
#define AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_ARRAY_LENGTHS_PUBLIC_DATA_WRITES_ROW_IDX
#define AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_PUBLIC_DATA_WRITES_ROW_IDX
#define PUBLIC_DATA_TREE_HEIGHT
InteractionDefinition & add(auto &&... args)
void process(const simulation::EventEmitterInterface< simulation::PublicDataTreeCheckEvent >::Container &events, TraceContainer &trace)
void set(Column col, uint32_t row, const FF &value)
TestTraceContainer trace
FF a
FF b
IndexedLeaf< PublicDataLeafValue > PublicDataTreeLeafPreimage
void process_with_discard(const std::vector< std::variant< EventType, simulation::CheckPointEventType > > &events, ProcessEventFn &&process_event)
lookup_settings< lookup_public_data_check_low_leaf_next_slot_validation_settings_ > lookup_public_data_check_low_leaf_next_slot_validation_settings
lookup_settings< lookup_public_data_check_new_leaf_merkle_check_settings_ > lookup_public_data_check_new_leaf_merkle_check_settings
lookup_settings< lookup_public_data_check_updated_low_leaf_poseidon2_1_settings_ > lookup_public_data_check_updated_low_leaf_poseidon2_1_settings
lookup_settings< lookup_public_data_check_silo_poseidon2_settings_ > lookup_public_data_check_silo_poseidon2_settings
lookup_settings< lookup_public_data_check_write_writes_length_to_public_inputs_settings_ > lookup_public_data_check_write_writes_length_to_public_inputs_settings
lookup_settings< lookup_public_data_check_new_leaf_poseidon2_0_settings_ > lookup_public_data_check_new_leaf_poseidon2_0_settings
lookup_settings< lookup_public_data_check_write_public_data_to_public_inputs_settings_ > lookup_public_data_check_write_public_data_to_public_inputs_settings
lookup_settings< lookup_public_data_check_low_leaf_poseidon2_1_settings_ > lookup_public_data_check_low_leaf_poseidon2_1_settings
typename Flavor::FF FF
void write(B &buf, field2< base_field, Params > const &value)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
simulation::PublicDataTreeReadWriteEvent event
static IndexedLeaf< PublicDataLeafValue > empty()