6#include <unordered_map>
28using simulation::PublicDataTreeReadWriteEvent;
32struct EventWithDiscard {
33 simulation::PublicDataTreeReadWriteEvent
event;
49 const std::unordered_map<FF, uint32_t>& first_write_per_slot,
50 const std::unordered_map<FF, FF>& last_value_per_slot,
51 TraceContainer& trace)
60 for (
size_t i = 0; i < events_with_discard.size(); i++) {
61 bool end = i == events_with_discard.size() - 1;
62 const auto&
event = events_with_discard[i].event;
63 const bool discard = events_with_discard[i].discard;
65 bool exists =
event.low_leaf_preimage.leaf.slot ==
event.leaf_slot;
66 FF slot_low_leaf_slot_diff =
event.leaf_slot -
event.low_leaf_preimage.leaf.slot;
68 bool next_slot_is_nonzero =
false;
71 next_slot_is_nonzero =
event.low_leaf_preimage.nextKey != 0;
72 next_slot =
event.low_leaf_preimage.nextKey;
75 bool write =
event.write_data.has_value();
78 bool protocol_write =
event.execution_id == std::numeric_limits<uint32_t>::max();
81 bool sel_write_to_public_inputs =
82 nondiscarded_write && first_write_per_slot.at(
event.leaf_slot) ==
event.execution_id;
83 FF final_value = nondiscarded_write ? last_value_per_slot.at(
event.leaf_slot) : 0;
85 FF intermediate_root = 0;
87 FF updated_low_leaf_hash = 0;
89 AppendOnlyTreeSnapshot next_snapshot =
event.prev_snapshot;
92 next_snapshot =
event.write_data->next_snapshot;
93 intermediate_root =
event.write_data->intermediate_root;
94 updated_low_leaf =
event.write_data->updated_low_leaf_preimage;
95 updated_low_leaf_hash =
event.write_data->updated_low_leaf_hash;
96 new_leaf_hash =
event.write_data->new_leaf_hash;
98 uint32_t clk =
event.execution_id;
99 uint32_t clk_diff = end ? 0 : events_with_discard[i + 1].event.execution_id - clk;
101 uint32_t public_data_writes_length = write_idx -
103 static_cast<uint32_t
>(sel_write_to_public_inputs);
107 { C::public_data_check_sel, 1 },
108 { C::public_data_check_not_end, !end },
109 { C::public_data_check_end, end },
110 { C::public_data_check_value,
event.value },
111 { C::public_data_check_slot,
event.slot },
112 { C::public_data_check_root,
event.prev_snapshot.root },
113 { C::public_data_check_address,
event.contract_address },
114 { C::public_data_check_write_root, next_snapshot.root },
115 { C::public_data_check_tree_size_before_write,
event.prev_snapshot.next_available_leaf_index },
116 { C::public_data_check_tree_size_after_write, next_snapshot.next_available_leaf_index },
117 { C::public_data_check_write,
write },
118 { C::public_data_check_protocol_write, protocol_write },
119 { C::public_data_check_non_protocol_write,
write && !protocol_write },
120 { C::public_data_check_clk, clk },
121 { C::public_data_check_discard,
discard },
122 { C::public_data_check_low_leaf_slot,
event.low_leaf_preimage.leaf.slot },
123 { C::public_data_check_low_leaf_value,
event.low_leaf_preimage.leaf.value },
124 { C::public_data_check_low_leaf_next_index,
event.low_leaf_preimage.nextIndex },
125 { C::public_data_check_low_leaf_next_slot,
event.low_leaf_preimage.nextKey },
126 { C::public_data_check_updated_low_leaf_value, updated_low_leaf.leaf.value },
127 { C::public_data_check_updated_low_leaf_next_index, updated_low_leaf.nextIndex },
128 { C::public_data_check_updated_low_leaf_next_slot, updated_low_leaf.nextKey },
129 { C::public_data_check_low_leaf_index,
event.low_leaf_index },
130 { C::public_data_check_clk_diff_lo,
static_cast<uint16_t
>(clk_diff) },
131 { C::public_data_check_clk_diff_hi, clk_diff >> 16 },
132 { C::public_data_check_leaf_slot,
event.leaf_slot },
134 { C::public_data_check_leaf_not_exists, !
exists },
135 { C::public_data_check_leaf_slot_low_leaf_slot_diff_inv,
136 slot_low_leaf_slot_diff },
137 { C::public_data_check_next_slot_is_nonzero, next_slot_is_nonzero },
138 { C::public_data_check_next_slot_inv, next_slot },
139 { C::public_data_check_low_leaf_hash,
event.low_leaf_hash },
140 { C::public_data_check_intermediate_root, intermediate_root },
142 { C::public_data_check_const_three, 3 },
143 { C::public_data_check_const_four, 4 },
145 { C::public_data_check_updated_low_leaf_hash, updated_low_leaf_hash },
146 { C::public_data_check_should_insert, should_insert },
147 { C::public_data_check_new_leaf_hash, new_leaf_hash },
148 { C::public_data_check_write_idx, write_idx },
149 { C::public_data_check_non_discarded_write, nondiscarded_write },
150 { C::public_data_check_sel_write_to_public_inputs, sel_write_to_public_inputs },
151 { C::public_data_check_final_value, final_value },
152 { C::public_data_check_public_data_writes_length, public_data_writes_length },
153 { C::public_data_check_length_pi_idx,
157 if (sel_write_to_public_inputs) {
175 const std::unordered_map<FF, uint32_t>& first_write_per_slot,
176 const std::unordered_map<FF, FF>& last_value_per_slot,
177 TraceContainer& trace)
184 for (
size_t i = 0; i < nondiscarded_writes.size(); i++) {
185 bool end = i == nondiscarded_writes.size() - 1;
186 const auto&
event = nondiscarded_writes[i];
188 uint32_t clk =
event.execution_id;
190 bool leaf_slot_increase =
false;
191 bool check_clock =
false;
192 uint32_t clk_diff = 0;
195 const auto& next_event = nondiscarded_writes[i + 1];
197 if (
event.leaf_slot == next_event.leaf_slot) {
199 event.execution_id, next_event.execution_id,
"Execution id is not less than next execution id");
201 clk_diff = next_event.execution_id -
event.execution_id - 1;
205 static_cast<uint256_t>(next_event.leaf_slot),
206 "Leaf slot is not less than next leaf slot");
207 leaf_slot_increase =
true;
211 bool sel_write_to_public_inputs = first_write_per_slot.at(
event.leaf_slot) ==
event.execution_id;
212 FF final_value = last_value_per_slot.at(
event.leaf_slot);
216 { C::public_data_squash_sel, 1 },
217 { C::public_data_squash_leaf_slot,
event.leaf_slot },
218 { C::public_data_squash_value,
event.value },
219 { C::public_data_squash_clk, clk },
220 { C::public_data_squash_write_to_public_inputs, sel_write_to_public_inputs },
221 { C::public_data_squash_leaf_slot_increase, leaf_slot_increase },
222 { C::public_data_squash_check_clock, check_clock },
223 { C::public_data_squash_clk_diff_lo,
static_cast<uint16_t
>(clk_diff) },
224 { C::public_data_squash_clk_diff_hi, clk_diff >> 16 },
225 { C::public_data_squash_final_value, final_value },
247 std::unordered_map<FF, uint32_t> first_write_clk_per_slot;
248 std::unordered_map<FF, FF> last_write_value_per_slot;
250 events_with_discard.reserve(events.size());
255 if (!first_write_clk_per_slot.contains(event.leaf_slot)) {
256 first_write_clk_per_slot[event.leaf_slot] = event.execution_id;
258 last_write_value_per_slot[
event.leaf_slot] =
event.value;
263 std::ranges::sort(events_with_discard.begin(),
264 events_with_discard.end(),
265 [](
const EventWithDiscard&
a,
const EventWithDiscard&
b) {
266 return a.event.execution_id < b.event.execution_id;
269 process_public_data_tree_check_trace(
270 events_with_discard, first_write_clk_per_slot, last_write_value_per_slot, trace);
273 nondiscarded_writes.reserve(events_with_discard.size());
275 for (
const auto& event_with_discard : events_with_discard) {
276 if (event_with_discard.event.write_data.has_value() && !event_with_discard.discard) {
277 nondiscarded_writes.push_back(event_with_discard.event);
282 std::ranges::sort(nondiscarded_writes.begin(),
283 nondiscarded_writes.end(),
284 [](
const PublicDataTreeReadWriteEvent&
a,
const PublicDataTreeReadWriteEvent&
b) {
285 if (a.leaf_slot == b.leaf_slot) {
286 return a.execution_id < b.execution_id;
291 process_squashing_trace(nondiscarded_writes, first_write_clk_per_slot, last_write_value_per_slot, trace);
295 { { Column::public_data_check_leaf_slot_low_leaf_slot_diff_inv, Column::public_data_check_next_slot_inv } });
301 InteractionDefinition()
304 .add<InteractionType::LookupGeneric, lookup_public_data_check_low_leaf_slot_validation_settings>()
306 .add<InteractionType::LookupGeneric, lookup_public_data_check_low_leaf_poseidon2_0_settings>()
308 .add<InteractionType::LookupGeneric, lookup_public_data_check_updated_low_leaf_poseidon2_0_settings>()
310 .add<InteractionType::LookupGeneric, lookup_public_data_check_low_leaf_merkle_check_settings>()
312 .add<InteractionType::LookupGeneric, lookup_public_data_check_new_leaf_poseidon2_1_settings>()
314 .add<InteractionType::MultiPermutation, perm_sstore_storage_write_settings, perm_tx_balance_update_settings>(
315 Column::public_data_check_write)
317 .add<InteractionType::LookupIntoIndexedByRow,
320 .add<InteractionType::LookupIntoIndexedByRow, lookup_public_data_check_clk_diff_range_hi_settings>()
321 .
add<InteractionType::LookupIntoIndexedByRow,
324 .add<InteractionType::LookupGeneric, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>()
326 .add<InteractionType::LookupIntoIndexedByRow, lookup_public_data_squash_clk_diff_range_hi_settings>();
#define BB_ASSERT_LT(left, right,...)
#define AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_ARRAY_LENGTHS_PUBLIC_DATA_WRITES_ROW_IDX
#define DOM_SEP__PUBLIC_LEAF_SLOT
#define DOM_SEP__PUBLIC_DATA_MERKLE
#define AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_PUBLIC_DATA_WRITES_ROW_IDX
#define PUBLIC_DATA_TREE_HEIGHT
std::vector< Event > Container
InteractionDefinition & add(auto &&... args)
static const InteractionDefinition interactions
void process(const simulation::EventEmitterInterface< simulation::PublicDataTreeCheckEvent >::Container &events, TraceContainer &trace)
Process the public data tree check events and populate the relevant columns in the trace.
void invert_columns(std::span< const Column > cols)
void set(Column col, uint32_t row, const FF &value)
IndexedLeaf< PublicDataLeafValue > PublicDataTreeLeafPreimage
void process_with_discard(const std::vector< std::variant< EventType, simulation::CheckPointEventType > > &events, ProcessEventFn &&process_event)
Processes events from a stream, attaching a discard flag to indicate reverted checkpoints.
permutation_settings< perm_public_data_check_squashing_settings_ > perm_public_data_check_squashing_settings
lookup_settings< lookup_public_data_check_clk_diff_range_lo_settings_ > lookup_public_data_check_clk_diff_range_lo_settings
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_squash_clk_diff_range_lo_settings_ > lookup_public_data_squash_clk_diff_range_lo_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
void write(B &buf, field2< base_field, Params > const &value)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
simulation::PublicDataTreeReadWriteEvent event
static IndexedLeaf< PublicDataLeafValue > empty()