1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
30using simulation::EmitUnencryptedLogWriteEvent;
31using simulation::TrackedSideEffects;
32using testing::PublicInputsBuilder;
33using tracegen::EmitUnencryptedLogTraceBuilder;
34using tracegen::PublicInputsTraceBuilder;
35using tracegen::TestTraceContainer;
43 memory_values.reserve(fields.size());
44 for (
const FF&
field : fields) {
45 memory_values.push_back(MemoryValue::from<FF>(
field));
50TEST(EmitUnencryptedLogConstrainingTest, EmptyTrace)
55TEST(EmitUnencryptedLogConstrainingTest, Positive)
59 const std::vector<FF> log_fields = { 4, 5 };
60 uint32_t log_size =
static_cast<uint32_t
>(log_fields.size());
61 TrackedSideEffects side_effect_states = { .public_logs = {} };
62 TrackedSideEffects side_effect_states_after = { .public_logs = PublicLogs{ { { log_fields,
address } } } };
64 EmitUnencryptedLogWriteEvent
event = {
68 .log_address = log_address,
70 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
71 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
73 .values = to_memory_values(log_fields),
74 .error_memory_out_of_bounds =
false,
75 .error_too_many_log_fields =
false,
76 .error_tag_mismatch =
false,
79 TestTraceContainer
trace({
80 { { C::precomputed_first_row, 1 } },
83 EmitUnencryptedLogTraceBuilder trace_builder;
84 trace_builder.process({
event },
trace);
86 check_relation<emit_unencrypted_log>(trace);
89TEST(EmitUnencryptedLogConstrainingTest, PositiveEmptyLog)
94 const std::vector<FF> log_fields = {};
95 uint32_t log_size =
static_cast<uint32_t
>(log_fields.size());
96 TrackedSideEffects side_effect_states = { .public_logs = {} };
97 TrackedSideEffects side_effect_states_after = { .public_logs = PublicLogs{ { { log_fields,
address } } } };
99 EmitUnencryptedLogWriteEvent
event = {
103 .log_address = log_address,
104 .log_size = log_size,
105 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
106 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
108 .values = to_memory_values(log_fields),
109 .error_memory_out_of_bounds =
false,
110 .error_too_many_log_fields =
false,
111 .error_tag_mismatch =
false,
115 uint64_t end_log_address_upper_bound =
static_cast<uint64_t
>(log_address) +
static_cast<uint64_t
>(log_size);
117 simulation::GreaterThanEvent gt_event = {
118 .a = end_log_address_upper_bound,
123 TestTraceContainer
trace({
124 { { C::precomputed_first_row, 1 } },
127 EmitUnencryptedLogTraceBuilder trace_builder;
130 trace_builder.process({
event },
trace);
133 FF end_log_address_upper_bound_log_trace =
trace.
get(C::emit_unencrypted_log_end_log_address_upper_bound, 1);
134 FF end_log_address_upper_bound_gt_trace =
trace.
get(C::gt_input_a, 0);
135 EXPECT_EQ(end_log_address_upper_bound_log_trace, end_log_address_upper_bound_gt_trace);
137 check_relation<emit_unencrypted_log>(trace);
138 check_interaction<EmitUnencryptedLogTraceBuilder, lookup_emit_unencrypted_log_check_memory_out_of_bounds_settings>(
142TEST(EmitUnencryptedLogConstrainingTest, ErrorMemoryOutOfBounds)
146 uint32_t log_size = 2;
147 TrackedSideEffects side_effect_states = { .public_logs = PublicLogs{ { { { 4 },
address } } } };
148 const TrackedSideEffects& side_effect_states_after = side_effect_states;
150 EmitUnencryptedLogWriteEvent
event = {
154 .log_address = log_address,
155 .log_size = log_size,
156 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
157 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
160 .error_memory_out_of_bounds =
true,
161 .error_too_many_log_fields =
false,
162 .error_tag_mismatch =
false,
165 TestTraceContainer
trace({
166 { { C::precomputed_first_row, 1 } },
169 EmitUnencryptedLogTraceBuilder trace_builder;
170 trace_builder.process({
event },
trace);
172 check_relation<emit_unencrypted_log>(trace);
175TEST(EmitUnencryptedLogConstrainingTest, ErrorTooManyLogFields)
179 const std::vector<FF> log_fields = { 4, 5 };
180 uint32_t log_size =
static_cast<uint32_t
>(log_fields.size());
182 TrackedSideEffects side_effect_states = {
185 const TrackedSideEffects& side_effect_states_after = side_effect_states;
187 EmitUnencryptedLogWriteEvent
event = {
191 .log_address = log_address,
192 .log_size = log_size,
193 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
194 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
196 .values = to_memory_values(log_fields),
197 .error_memory_out_of_bounds =
false,
198 .error_too_many_log_fields =
true,
199 .error_tag_mismatch =
false,
202 TestTraceContainer
trace({
203 { { C::precomputed_first_row, 1 } },
206 EmitUnencryptedLogTraceBuilder trace_builder;
207 trace_builder.process({
event },
trace);
209 check_relation<emit_unencrypted_log>(trace);
212TEST(EmitUnencryptedLogConstrainingTest, ErrorTagMismatch)
217 uint32_t log_size =
static_cast<uint32_t
>(log_values.size());
218 TrackedSideEffects side_effect_states = { .public_logs = {} };
220 const TrackedSideEffects& side_effect_states_after = side_effect_states;
222 EmitUnencryptedLogWriteEvent
event = {
226 .log_address = log_address,
227 .log_size = log_size,
228 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
229 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
231 .values = log_values,
232 .error_memory_out_of_bounds =
false,
233 .error_too_many_log_fields =
false,
234 .error_tag_mismatch =
true,
237 TestTraceContainer
trace({
238 { { C::precomputed_first_row, 1 } },
241 EmitUnencryptedLogTraceBuilder trace_builder;
242 trace_builder.process({
event },
trace);
244 check_relation<emit_unencrypted_log>(trace);
247TEST(EmitUnencryptedLogConstrainingTest, ErrorStatic)
251 const std::vector<FF> log_fields = { 4, 5 };
252 uint32_t log_size =
static_cast<uint32_t
>(log_fields.size());
253 TrackedSideEffects side_effect_states = { .public_logs = PublicLogs{ { { { 4 },
address } } } };
254 const TrackedSideEffects& side_effect_states_after = side_effect_states;
256 EmitUnencryptedLogWriteEvent
event = {
260 .log_address = log_address,
261 .log_size = log_size,
262 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
263 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
265 .values = to_memory_values(log_fields),
266 .error_memory_out_of_bounds =
false,
267 .error_too_many_log_fields =
false,
268 .error_tag_mismatch =
false,
271 TestTraceContainer
trace({
272 { { C::precomputed_first_row, 1 } },
275 EmitUnencryptedLogTraceBuilder trace_builder;
276 trace_builder.process({
event },
trace);
279TEST(EmitUnencryptedLogConstrainingTest, Interactions)
283 const std::vector<FF> log_fields = { 4, 5 };
284 uint32_t log_size =
static_cast<uint32_t
>(log_fields.size());
285 TrackedSideEffects side_effect_states = { .public_logs = {} };
286 TrackedSideEffects side_effect_states_after = { .public_logs = PublicLogs{ { { log_fields,
address } } } };
287 AvmAccumulatedData accumulated_data = {};
288 accumulated_data.public_logs.add_log({
289 .fields = {
FF(4),
FF(5) },
292 auto public_inputs = PublicInputsBuilder().set_accumulated_data(accumulated_data).build();
296 EmitUnencryptedLogWriteEvent
event = {
300 .log_address = log_address,
301 .log_size = log_size,
302 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
303 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
306 .error_memory_out_of_bounds =
false,
307 .error_too_many_log_fields =
false,
308 .error_tag_mismatch =
false,
311 TestTraceContainer
trace = TestTraceContainer({
314 { C::precomputed_first_row, 1 },
317 { C::gt_input_a, side_effect_states_after.get_num_unencrypted_log_fields() },
323 { C::execution_sel, 1 },
324 { C::execution_sel_exec_dispatch_emit_unencrypted_log, 1 },
325 { C::execution_context_id, 57 },
326 { C::execution_rop_1_, log_address },
327 { C::execution_register_0_, log_size },
328 { C::execution_contract_address,
address },
329 { C::execution_prev_num_unencrypted_log_fields, side_effect_states.get_num_unencrypted_log_fields() },
330 { C::execution_num_unencrypted_log_fields, side_effect_states_after.get_num_unencrypted_log_fields() },
331 { C::execution_is_static,
false },
332 { C::execution_sel_opcode_error, 0 },
333 { C::execution_discard, 0 },
336 { C::gt_input_a, log_address + log_size },
343 for (uint32_t i = 0; i <
inputs.size(); ++i) {
345 trace.
set(C::memory_address, i + 1, log_address + i);
347 trace.
set(C::memory_tag, i + 1,
static_cast<uint32_t
>(
inputs[i].get_tag()));
351 trace.
set(C::memory_space_id, i + 1, 57);
361 EmitUnencryptedLogTraceBuilder trace_builder;
362 trace_builder.process({
event },
trace);
364 check_relation<emit_unencrypted_log>(trace);
365 check_all_interactions<EmitUnencryptedLogTraceBuilder>(trace);
368TEST(EmitUnencryptedLogConstrainingTest, NegativeStartAfterLatch)
370 TestTraceContainer
trace = TestTraceContainer({ {
371 { C::precomputed_first_row, 1 },
374 { C::emit_unencrypted_log_sel, 1 },
375 { C::emit_unencrypted_log_start, 1 },
376 { C::emit_unencrypted_log_end, 1 },
379 { C::emit_unencrypted_log_sel, 1 },
380 { C::emit_unencrypted_log_start, 1 },
385 trace.
set(C::emit_unencrypted_log_end, 1, 0);
388 "START_AFTER_LATCH");
390 trace.
set(C::emit_unencrypted_log_end, 1, 1);
391 trace.
set(C::precomputed_first_row, 0, 0);
394 "START_AFTER_LATCH");
397TEST(EmitUnencryptedLogConstrainingTest, NegativeSelectorOnStart)
399 TestTraceContainer
trace = TestTraceContainer({ {
400 { C::emit_unencrypted_log_sel, 1 },
401 { C::emit_unencrypted_log_start, 1 },
406 trace.
set(C::emit_unencrypted_log_sel, 0, 0);
409 "SELECTOR_ON_START");
412TEST(EmitUnencryptedLogConstrainingTest, NegativeSelectorConsistency)
414 TestTraceContainer
trace = TestTraceContainer({ {
415 { C::precomputed_first_row, 1 },
418 { C::emit_unencrypted_log_sel, 1 },
419 { C::emit_unencrypted_log_start, 1 },
420 { C::emit_unencrypted_log_end, 1 },
423 { C::emit_unencrypted_log_sel, 0 },
428 trace.
set(C::emit_unencrypted_log_end, 1, 0);
432 "SELECTOR_CONSISTENCY");
435TEST(EmitUnencryptedLogConstrainingTest, NegativeSelectorOnEnd)
437 TestTraceContainer
trace = TestTraceContainer({ {
438 { C::emit_unencrypted_log_sel, 1 },
439 { C::emit_unencrypted_log_end, 1 },
444 trace.
set(C::emit_unencrypted_log_sel, 0, 0);
450TEST(EmitUnencryptedLogConstrainingTest, NegativeRemainingRowsDecrement)
452 TestTraceContainer
trace = TestTraceContainer({ {
453 { C::emit_unencrypted_log_sel, 1 },
454 { C::emit_unencrypted_log_remaining_rows, 1 },
457 { C::emit_unencrypted_log_sel, 1 },
458 { C::emit_unencrypted_log_remaining_rows, 0 },
459 { C::emit_unencrypted_log_end, 1 },
464 trace.
set(C::emit_unencrypted_log_remaining_rows, 1, 1);
468 "REMAINING_ROWS_DECREMENT");
471TEST(EmitUnencryptedLogConstrainingTest, NegativeErrorOutOfBoundsConsistency)
473 TestTraceContainer
trace = TestTraceContainer({ {
474 { C::emit_unencrypted_log_sel, 1 },
475 { C::emit_unencrypted_log_error_out_of_bounds, 1 },
478 { C::emit_unencrypted_log_sel, 1 },
479 { C::emit_unencrypted_log_error_out_of_bounds, 1 },
480 { C::emit_unencrypted_log_end, 1 },
485 trace.
set(C::emit_unencrypted_log_error_out_of_bounds, 1, 0);
489 "ERROR_OUT_OF_BOUNDS_CONSISTENCY");
492TEST(EmitUnencryptedLogConstrainingTest, NegativeErrorTagMismatchConsistency)
494 TestTraceContainer
trace = TestTraceContainer({ {
495 { C::emit_unencrypted_log_sel, 1 },
496 { C::emit_unencrypted_log_error_tag_mismatch, 1 },
499 { C::emit_unencrypted_log_sel, 1 },
500 { C::emit_unencrypted_log_error_tag_mismatch, 1 },
501 { C::emit_unencrypted_log_end, 1 },
506 trace.
set(C::emit_unencrypted_log_error_tag_mismatch, 1, 0);
510 "ERROR_TAG_MISMATCH_CONSISTENCY");
513TEST(EmitUnencryptedLogConstrainingTest, NegativeWrongTagCheck)
515 TestTraceContainer
trace = TestTraceContainer({ {
516 { C::emit_unencrypted_log_sel, 1 },
517 { C::emit_unencrypted_log_seen_wrong_tag, 0 },
520 { C::emit_unencrypted_log_sel, 1 },
521 { C::emit_unencrypted_log_seen_wrong_tag, 1 },
522 { C::emit_unencrypted_log_correct_tag, 0 },
523 { C::emit_unencrypted_log_end, 1 },
528 trace.
set(C::emit_unencrypted_log_seen_wrong_tag, 1, 0);
534TEST(EmitUnencryptedLogConstrainingTest, NegativeSelectorShouldWriteToPublicInputsConsistency)
536 TestTraceContainer
trace =
537 TestTraceContainer({ {
538 { C::emit_unencrypted_log_sel, 1 },
539 { C::emit_unencrypted_log_sel_should_write_to_public_inputs, 1 },
542 { C::emit_unencrypted_log_sel, 1 },
543 { C::emit_unencrypted_log_sel_should_write_to_public_inputs, 1 },
544 { C::emit_unencrypted_log_end, 1 },
549 trace.
set(C::emit_unencrypted_log_sel_should_write_to_public_inputs, 1, 0);
553 "SEL_SHOULD_WRITE_TO_PUBLIC_INPUTS_CONSISTENCY");
556TEST(EmitUnencryptedLogConstrainingTest, NegativeLogOffsetIncrement)
558 TestTraceContainer
trace = TestTraceContainer({ {
559 { C::emit_unencrypted_log_sel, 1 },
560 { C::emit_unencrypted_log_is_write_memory_value, 1 },
561 { C::emit_unencrypted_log_log_address, 10 },
564 { C::emit_unencrypted_log_sel, 1 },
565 { C::emit_unencrypted_log_is_write_memory_value, 1 },
566 { C::emit_unencrypted_log_log_address, 11 },
567 { C::emit_unencrypted_log_end, 1 },
572 trace.
set(C::emit_unencrypted_log_log_address, 1, 9);
576 "LOG_ADDRESS_INCREMENT");
579TEST(EmitUnencryptedLogConstrainingTest, NegativeExecutionClkConsistency)
581 TestTraceContainer
trace = TestTraceContainer({ {
582 { C::emit_unencrypted_log_sel, 1 },
583 { C::emit_unencrypted_log_execution_clk, 1 },
586 { C::emit_unencrypted_log_sel, 1 },
587 { C::emit_unencrypted_log_execution_clk, 1 },
588 { C::emit_unencrypted_log_end, 1 },
593 trace.
set(C::emit_unencrypted_log_execution_clk, 1, 0);
597 "EXEC_CLK_CONSISTENCY");
600TEST(EmitUnencryptedLogConstrainingTest, NegativeSpaceIdConsistency)
602 TestTraceContainer
trace = TestTraceContainer({ {
603 { C::emit_unencrypted_log_sel, 1 },
604 { C::emit_unencrypted_log_space_id, 17 },
607 { C::emit_unencrypted_log_sel, 1 },
608 { C::emit_unencrypted_log_space_id, 17 },
609 { C::emit_unencrypted_log_end, 1 },
614 trace.
set(C::emit_unencrypted_log_space_id, 1, 18);
618 "SPACE_ID_CONSISTENCY");
621TEST(EmitUnencryptedLogConstrainingTest, NegativeContractAddressConsistency)
623 TestTraceContainer
trace = TestTraceContainer({ {
624 { C::emit_unencrypted_log_sel, 1 },
625 { C::emit_unencrypted_log_contract_address, 42 },
628 { C::emit_unencrypted_log_sel, 1 },
629 { C::emit_unencrypted_log_contract_address, 42 },
630 { C::emit_unencrypted_log_end, 1 },
635 trace.
set(C::emit_unencrypted_log_contract_address, 1, 43);
639 "CONTRACT_ADDRESS_CONSISTENCY");
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
#define FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH
#define AVM_HIGHEST_MEM_ADDRESS
static constexpr size_t SR_SPACE_ID_CONSISTENCY
static constexpr size_t SR_SELECTOR_ON_END
static constexpr size_t SR_START_AFTER_LATCH
static constexpr size_t SR_LOG_ADDRESS_INCREMENT
static constexpr size_t SR_SEL_SHOULD_WRITE_TO_PUBLIC_INPUTS_CONSISTENCY
static constexpr size_t SR_ERROR_TAG_MISMATCH_CONSISTENCY
static constexpr size_t SR_SELECTOR_ON_START
static constexpr size_t SR_WRONG_TAG_CHECK
static constexpr size_t SR_REMAINING_ROWS_DECREMENT
static constexpr size_t SR_ERROR_OUT_OF_BOUNDS_CONSISTENCY
static constexpr size_t SR_EXEC_CLK_CONSISTENCY
static constexpr size_t SR_SELECTOR_CONSISTENCY
static constexpr size_t SR_CONTRACT_ADDRESS_CONSISTENCY
void process(const simulation::EventEmitterInterface< simulation::GreaterThanEvent >::Container &events, TraceContainer &trace)
void process_misc(TraceContainer &trace, const uint32_t num_rows=MAX_AVM_TRACE_SIZE)
const FF & get(Column col, uint32_t row) const
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value)
PrecomputedTraceBuilder precomputed_builder
GreaterThanTraceBuilder gt_builder
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
std::variant< EmitUnencryptedLogWriteEvent, CheckPointEventType > EmitUnencryptedLogEvent
TestTraceContainer empty_trace()
std::vector< FF > random_fields(size_t n)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
tracegen::PublicInputsTraceBuilder public_inputs_builder