1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
7#include "barretenberg/aztec/aztec_constants.hpp"
32using tracegen::TestTraceContainer;
33using tracegen::TxTraceBuilder;
39TEST(TxExecutionConstrainingTest, NegativeEmptyTrace)
45TEST(TxExecutionConstrainingTest, NegativeEarlyEnd)
47 TestTraceContainer
trace({
50 { C::precomputed_first_row, 1 },
61TEST(TxExecutionConstrainingTest, NegativeNoExtraneousRows)
63 TestTraceContainer
trace({
66 { C::precomputed_first_row, 1 },
81class TxExecutionConstrainingTestHelper :
public ::testing::Test {
85 static void set_initial_columns(TestTraceContainer& trace,
91 trace.set(row++, { { { C::execution_clk, 0 }, { C::precomputed_first_row, 1 } } });
97 { C::tx_start_tx, 1 },
99 { C::tx_is_padded, 1 },
100 { C::tx_is_tree_insert_phase, 1 },
101 { C::tx_sel_append_nullifier, 1 },
103 { C::tx_read_pi_start_offset,
104 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_NULLIFIERS_ROW_IDX },
105 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_NULLIFIERS_ROW_IDX },
106 { C::tx_sel_read_phase_length, 1 },
107 { C::tx_read_pi_length_offset,
108 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NULLIFIERS_ROW_IDX },
110 { C::tx_start_phase, 1 },
111 { C::tx_end_phase, 1 },
112 { C::tx_next_context_id, 1 },
118 { C::tx_is_padded, 1 },
119 { C::tx_is_tree_insert_phase, 1 },
120 { C::tx_sel_append_note_hash, 1 },
121 { C::tx_read_pi_start_offset,
122 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_NOTE_HASHES_ROW_IDX },
123 { C::tx_read_pi_offset,
124 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_NOTE_HASHES_ROW_IDX },
125 { C::tx_sel_read_phase_length, 1 },
126 { C::tx_read_pi_length_offset,
127 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NOTE_HASHES_ROW_IDX },
128 { C::tx_start_phase, 1 },
129 { C::tx_end_phase, 1 },
130 { C::tx_next_context_id, 1 },
137 { C::tx_is_padded, 1 },
138 { C::tx_sel_append_l2_l1_msg, 1 },
140 { C::tx_read_pi_start_offset,
141 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
142 { C::tx_read_pi_offset,
143 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
144 { C::tx_sel_read_phase_length, 1 },
145 { C::tx_read_pi_length_offset,
146 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_L2_TO_L1_MSGS_ROW_IDX },
147 { C::tx_write_pi_offset, AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
149 { C::tx_start_phase, 1 },
150 { C::tx_end_phase, 1 },
151 { C::tx_next_context_id, 1 },
154 auto calls_remaining = setup_call_requests.size();
155 auto read_pi_offset = AVM_PUBLIC_INPUTS_PUBLIC_SETUP_CALL_REQUESTS_ROW_IDX;
156 for (
auto setup_call : setup_call_requests) {
157 bool is_first_call = calls_remaining == setup_call_requests.size();
162 { C::tx_start_phase, is_first_call ? 1 : 0 },
163 { C::tx_end_phase, calls_remaining == 1 ? 1 : 0 },
164 { C::tx_sel_read_phase_length, is_first_call ? 1 : 0 },
166 { C::tx_is_public_call_request, 1 },
167 { C::tx_sel_process_call_request, 1 },
168 { C::tx_read_pi_start_offset, AVM_PUBLIC_INPUTS_PUBLIC_SETUP_CALL_REQUESTS_ROW_IDX },
169 { C::tx_read_pi_offset, read_pi_offset },
170 { C::tx_read_pi_length_offset,
171 AVM_PUBLIC_INPUTS_PUBLIC_CALL_REQUEST_ARRAY_LENGTHS_SETUP_CALLS_ROW_IDX },
172 { C::tx_remaining_phase_counter, calls_remaining },
173 { C::tx_remaining_phase_inv,
FF(calls_remaining).invert() },
174 { C::tx_remaining_phase_minus_one_inv,
175 calls_remaining == 1 ? 0 :
FF(calls_remaining - 1).invert() },
177 { C::tx_msg_sender, setup_call.msg_sender },
178 { C::tx_contract_addr, setup_call.contract_address },
179 { C::tx_is_static, setup_call.is_static_call },
180 { C::tx_calldata_hash, setup_call.calldata_hash },
191 { C::tx_is_padded, 1 },
192 { C::tx_is_tree_insert_phase, 1 },
193 { C::tx_sel_append_nullifier, 1 },
194 { C::tx_is_revertible, 1 },
195 { C::tx_read_pi_start_offset,
196 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_NULLIFIERS_ROW_IDX },
197 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_NULLIFIERS_ROW_IDX },
198 { C::tx_sel_read_phase_length, 1 },
199 { C::tx_read_pi_length_offset,
200 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NULLIFIERS_ROW_IDX },
202 { C::tx_start_phase, 1 },
203 { C::tx_end_phase, 1 },
210 { C::tx_is_padded, 1 },
211 { C::tx_is_tree_insert_phase, 1 },
212 { C::tx_sel_append_note_hash, 1 },
213 { C::tx_is_revertible, 1 },
214 { C::tx_read_pi_start_offset,
215 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_NOTE_HASHES_ROW_IDX },
216 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_NOTE_HASHES_ROW_IDX },
217 { C::tx_sel_read_phase_length, 1 },
218 { C::tx_read_pi_length_offset,
219 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NOTE_HASHES_ROW_IDX },
221 { C::tx_start_phase, 1 },
222 { C::tx_end_phase, 1 },
229 { C::tx_is_padded, 1 },
230 { C::tx_sel_append_l2_l1_msg, 1 },
231 { C::tx_is_revertible, 1 },
232 { C::tx_read_pi_start_offset,
233 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
234 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
235 { C::tx_sel_read_phase_length, 1 },
236 { C::tx_read_pi_length_offset,
237 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_L2_TO_L1_MSGS_ROW_IDX },
238 { C::tx_write_pi_offset, AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
240 { C::tx_start_phase, 1 },
241 { C::tx_end_phase, 1 },
244 calls_remaining = app_logic_call_requests.size();
245 read_pi_offset = AVM_PUBLIC_INPUTS_PUBLIC_APP_LOGIC_CALL_REQUESTS_ROW_IDX;
246 for (
auto app_logic_call : app_logic_call_requests) {
247 bool is_first_call = calls_remaining == app_logic_call_requests.size();
252 { C::tx_start_phase, is_first_call ? 1 : 0 },
253 { C::tx_end_phase, calls_remaining == 1 ? 1 : 0 },
254 { C::tx_sel_read_phase_length, is_first_call ? 1 : 0 },
256 { C::tx_is_public_call_request, 1 },
257 { C::tx_sel_process_call_request, 1 },
258 { C::tx_read_pi_start_offset, AVM_PUBLIC_INPUTS_PUBLIC_APP_LOGIC_CALL_REQUESTS_ROW_IDX },
259 { C::tx_read_pi_offset, read_pi_offset },
260 { C::tx_read_pi_length_offset,
261 AVM_PUBLIC_INPUTS_PUBLIC_CALL_REQUEST_ARRAY_LENGTHS_APP_LOGIC_CALLS_ROW_IDX },
262 { C::tx_remaining_phase_counter, calls_remaining },
263 { C::tx_remaining_phase_inv,
FF(calls_remaining).invert() },
264 { C::tx_remaining_phase_minus_one_inv,
265 calls_remaining == 1 ? 0 :
FF(calls_remaining - 1).invert() },
266 { C::tx_is_revertible, 1 },
269 { C::tx_msg_sender, app_logic_call.msg_sender },
270 { C::tx_contract_addr, app_logic_call.contract_address },
271 { C::tx_is_static, app_logic_call.is_static_call },
272 { C::tx_calldata_hash, app_logic_call.calldata_hash },
282 { C::tx_is_teardown, 1 },
283 { C::tx_sel_read_phase_length, 1 },
284 { C::tx_read_pi_start_offset, AVM_PUBLIC_INPUTS_PUBLIC_TEARDOWN_CALL_REQUEST_ROW_IDX },
285 { C::tx_read_pi_length_offset,
286 AVM_PUBLIC_INPUTS_PUBLIC_CALL_REQUEST_ARRAY_LENGTHS_TEARDOWN_CALL_ROW_IDX },
287 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PUBLIC_TEARDOWN_CALL_REQUEST_ROW_IDX },
288 { C::tx_is_public_call_request, 1 },
289 { C::tx_is_revertible, 1 },
291 { C::tx_start_phase, 1 },
292 { C::tx_end_phase, 1 },
299 { C::tx_remaining_phase_counter, 1 },
300 { C::tx_remaining_phase_inv, 1 },
301 { C::tx_is_collect_fee, 1 },
302 { C::tx_read_pi_start_offset, AVM_PUBLIC_INPUTS_EFFECTIVE_GAS_FEES_ROW_IDX },
303 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_EFFECTIVE_GAS_FEES_ROW_IDX },
304 { C::tx_write_pi_offset, AVM_PUBLIC_INPUTS_TRANSACTION_FEE_ROW_IDX },
305 { C::tx_fee_juice_contract_address, FEE_JUICE_ADDRESS },
306 { C::tx_fee_juice_balances_slot_constant, FEE_JUICE_BALANCES_SLOT },
307 { C::tx_dom_sep_public_storage_map_slot, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT },
308 { C::tx_fee_payer_pi_offset, AVM_PUBLIC_INPUTS_FEE_PAYER_ROW_IDX },
309 { C::tx_const_three, 3 },
310 { C::tx_start_phase, 1 },
311 { C::tx_end_phase, 1 },
312 { C::tx_uint32_max, 0xffffffff },
319 { C::tx_start_phase, 1 },
320 { C::tx_end_phase, 1 },
321 { C::tx_is_tree_padding, 1 },
322 { C::tx_remaining_phase_counter, 1 },
323 { C::tx_remaining_phase_inv, 1 },
324 { C::tx_next_note_hash_tree_size, MAX_NOTE_HASHES_PER_TX },
325 { C::tx_next_nullifier_tree_size, MAX_NULLIFIERS_PER_TX },
332 { C::tx_start_phase, 1 },
333 { C::tx_end_phase, 1 },
334 { C::tx_is_cleanup, 1 },
335 { C::tx_remaining_phase_counter, 1 },
336 { C::tx_remaining_phase_inv, 1 },
341TEST_F(TxExecutionConstrainingTestHelper, SimpleControlFlowRead)
343 auto test_public_inputs = testing::PublicInputsBuilder()
344 .rand_public_setup_call_requests(2)
345 .rand_public_app_logic_call_requests(1)
348 auto first_setup_call_request = test_public_inputs.public_setup_call_requests[0];
349 auto second_setup_call_request = test_public_inputs.public_setup_call_requests[1];
350 auto app_logic_call_request = test_public_inputs.public_app_logic_call_requests[0];
352 TestTraceContainer
trace;
353 set_initial_columns(trace, { first_setup_call_request, second_setup_call_request }, { app_logic_call_request });
358 { C::tx_is_padded, 1 },
367 check_relation<tx>(trace);
374TEST_F(TxExecutionConstrainingTestHelper, SimpleHandleRevert)
376 auto test_public_inputs = testing::PublicInputsBuilder()
377 .rand_public_setup_call_requests(2)
378 .rand_public_app_logic_call_requests(2)
382 auto first_setup_call_request = test_public_inputs.public_setup_call_requests[0];
383 auto second_setup_call_request = test_public_inputs.public_setup_call_requests[1];
384 auto first_app_logic_call_request = test_public_inputs.public_app_logic_call_requests[0];
385 auto second_app_logic_call_request = test_public_inputs.public_app_logic_call_requests[1];
387 TestTraceContainer
trace;
388 set_initial_columns(trace,
389 { first_setup_call_request, second_setup_call_request },
390 { first_app_logic_call_request, second_app_logic_call_request });
393 trace.
set(11, { { { C::tx_is_padded, 1 } } });
396 trace.
set(10, { { { C::tx_reverted, 1 } } });
399 trace.
set(1, { { { C::tx_start_tx, 1 } } });
400 for (uint32_t i = 10; i < 15; i++) {
401 trace.
set(i, { { { C::tx_tx_reverted, 1 } } });
403 trace.
set(14, { { { C::tx_reverted_pi_offset, AVM_PUBLIC_INPUTS_REVERTED_ROW_IDX } } });
411 check_relation<tx>(trace);
412 check_relation<tx_context>(
414 check_interaction<TxTraceBuilder, lookup_tx_context_public_inputs_read_reverted_settings>(trace);
417TEST_F(TxExecutionConstrainingTestHelper, JumpOnRevert)
419 TestTraceContainer
trace;
422 { PublicCallRequest{ .msg_sender = 0, .contract_address = 0, .is_static_call =
false, .calldata_hash = 0 } },
428 { C::tx_is_padded, 0 },
429 { C::tx_sel_append_l2_l1_msg, 0 },
430 { C::tx_remaining_phase_counter, 1 },
431 { C::tx_remaining_phase_inv, 1 },
432 { C::tx_is_revertible, 1 },
433 { C::tx_reverted, 1 },
436 trace.
set(8, { { { C::tx_is_padded, 1 } } });
441 check_relation<tx>(trace);
446TEST(TxExecutionConstrainingTest, WriteTreeValue)
450 auto pub_inputs_col = test_public_inputs.
to_columns();
453 { { C::execution_clk, 0 }, { C::precomputed_first_row, 1 } },
458 { C::tx_start_phase, 1 },
460 { C::tx_read_pi_length_offset,
461 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NULLIFIERS_ROW_IDX },
462 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_NULLIFIERS_ROW_IDX },
464 { C::tx_is_tree_insert_phase, 1 },
465 { C::tx_leaf_value, test_public_inputs.previous_non_revertible_accumulated_data.nullifiers[0] },
466 { C::tx_prev_num_nullifiers_emitted, 0 },
467 { C::tx_next_num_nullifiers_emitted, 1 },
468 { C::tx_end_phase, 1 } },
473 { C::tx_start_phase, 1 },
475 { C::tx_read_pi_length_offset,
476 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NOTE_HASHES_ROW_IDX },
477 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_NOTE_HASHES_ROW_IDX },
479 { C::tx_is_tree_insert_phase, 1 },
480 { C::tx_leaf_value, test_public_inputs.previous_non_revertible_accumulated_data.note_hashes[0] },
481 { C::tx_prev_num_note_hashes_emitted, 0 },
482 { C::tx_next_num_note_hashes_emitted, 1 },
483 { C::tx_end_phase, 1 } },
488 { C::tx_start_phase, 1 },
489 { C::tx_read_pi_length_offset,
490 AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_L2_TO_L1_MSGS_ROW_IDX },
491 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
492 { C::tx_write_pi_offset, AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
494 { C::tx_sel_append_l2_l1_msg, 1 },
495 { C::tx_l2_l1_msg_content,
496 test_public_inputs.previous_non_revertible_accumulated_data.l2_to_l1_msgs[0].message.content },
497 { C::tx_l2_l1_msg_recipient,
498 test_public_inputs.previous_non_revertible_accumulated_data.l2_to_l1_msgs[0].message.recipient },
499 { C::tx_l2_l1_msg_contract_address,
500 test_public_inputs.previous_non_revertible_accumulated_data.l2_to_l1_msgs[0].contract_address },
501 { C::tx_end_phase, 1 } },
507 { C::tx_start_phase, 1 },
508 { C::tx_is_padded, 1 },
509 { C::tx_read_pi_length_offset, AVM_PUBLIC_INPUTS_PUBLIC_CALL_REQUEST_ARRAY_LENGTHS_SETUP_CALLS_ROW_IDX },
510 { C::tx_end_phase, 1 } },
515 { C::tx_start_phase, 1 },
517 { C::tx_read_pi_length_offset,
518 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NULLIFIERS_ROW_IDX },
519 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_NULLIFIERS_ROW_IDX },
521 { C::tx_is_tree_insert_phase, 1 },
522 { C::tx_leaf_value, test_public_inputs.previous_revertible_accumulated_data.nullifiers[0] },
523 { C::tx_prev_num_nullifiers_emitted, 1 },
524 { C::tx_next_num_nullifiers_emitted, 2 },
525 { C::tx_end_phase, 1 } },
530 { C::tx_start_phase, 1 },
532 { C::tx_read_pi_length_offset,
533 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NOTE_HASHES_ROW_IDX },
534 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_NOTE_HASHES_ROW_IDX },
536 { C::tx_is_tree_insert_phase, 1 },
537 { C::tx_leaf_value, test_public_inputs.previous_revertible_accumulated_data.note_hashes[0] },
538 { C::tx_prev_num_note_hashes_emitted, 1 },
539 { C::tx_next_num_note_hashes_emitted, 2 },
540 { C::tx_end_phase, 1 } },
545 { C::tx_start_phase, 1 },
547 { C::tx_read_pi_length_offset,
548 AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_L2_TO_L1_MSGS_ROW_IDX },
549 { C::tx_read_pi_offset, AVM_PUBLIC_INPUTS_PREVIOUS_REVERTIBLE_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX },
550 { C::tx_write_pi_offset, AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX + 1 },
552 { C::tx_sel_append_l2_l1_msg, 1 },
553 { C::tx_l2_l1_msg_content,
554 test_public_inputs.previous_revertible_accumulated_data.l2_to_l1_msgs[0].message.content },
555 { C::tx_l2_l1_msg_recipient,
556 test_public_inputs.previous_revertible_accumulated_data.l2_to_l1_msgs[0].message.recipient },
557 { C::tx_l2_l1_msg_contract_address,
558 test_public_inputs.previous_revertible_accumulated_data.l2_to_l1_msgs[0].contract_address },
559 { C::tx_end_phase, 1 } },
565 { C::tx_start_phase, 1 },
566 { C::tx_is_padded, 1 },
567 { C::tx_read_pi_length_offset, AVM_PUBLIC_INPUTS_PUBLIC_CALL_REQUEST_ARRAY_LENGTHS_APP_LOGIC_CALLS_ROW_IDX },
568 { C::tx_end_phase, 1 } },
573 { C::tx_read_pi_length_offset, AVM_PUBLIC_INPUTS_PUBLIC_CALL_REQUEST_ARRAY_LENGTHS_TEARDOWN_CALL_ROW_IDX },
574 { C::tx_is_padded, 1 },
575 { C::tx_start_phase, 1 },
576 { C::tx_end_phase, 1 } },
586 check_interaction<TxTraceBuilder, lookup_tx_read_tree_insert_value_settings>(
trace);
587 check_interaction<TxTraceBuilder, lookup_tx_read_l2_l1_msg_settings>(
trace);
588 check_interaction<TxTraceBuilder, lookup_tx_write_l2_l1_msg_settings>(
trace);
591TEST_F(TxExecutionConstrainingTestHelper, CollectFees)
595 .rand_public_app_logic_call_requests(1)
596 .rand_public_teardown_call_request()
600 auto second_setup_call_request = test_public_inputs.public_setup_call_requests[1];
601 auto app_logic_call_request = test_public_inputs.public_app_logic_call_requests[0];
602 auto teardown_call_request = test_public_inputs.public_teardown_call_request;
605 set_initial_columns(
trace, { first_setup_call_request, second_setup_call_request }, { app_logic_call_request });
608 for (uint32_t i = 1; i < 4; i++) {
611 { C::tx_prev_da_gas_used, 1 },
612 { C::tx_prev_l2_gas_used, 100 },
613 { C::tx_next_da_gas_used, 1 },
614 { C::tx_next_l2_gas_used, 100 },
620 { C::tx_prev_da_gas_used, 1 },
621 { C::tx_prev_l2_gas_used, 100 },
622 { C::tx_prev_da_gas_used_sent_to_enqueued_call, 1 },
623 { C::tx_prev_l2_gas_used_sent_to_enqueued_call, 100 },
624 { C::tx_next_da_gas_used, 2 },
625 { C::tx_next_l2_gas_used, 200 },
626 { C::tx_next_da_gas_used_sent_to_enqueued_call, 2 },
627 { C::tx_next_l2_gas_used_sent_to_enqueued_call, 200 },
632 { C::tx_prev_da_gas_used, 2 },
633 { C::tx_prev_l2_gas_used, 200 },
634 { C::tx_prev_da_gas_used_sent_to_enqueued_call, 2 },
635 { C::tx_prev_l2_gas_used_sent_to_enqueued_call, 200 },
636 { C::tx_next_da_gas_used, 3 },
637 { C::tx_next_l2_gas_used, 300 },
638 { C::tx_next_da_gas_used_sent_to_enqueued_call, 3 },
639 { C::tx_next_l2_gas_used_sent_to_enqueued_call, 300 },
642 for (uint32_t i = 6; i < 9; i++) {
645 { C::tx_prev_da_gas_used, 3 },
646 { C::tx_prev_l2_gas_used, 300 },
647 { C::tx_next_da_gas_used, 3 },
648 { C::tx_next_l2_gas_used, 300 },
654 { C::tx_prev_da_gas_used, 3 },
655 { C::tx_prev_l2_gas_used, 300 },
656 { C::tx_prev_da_gas_used_sent_to_enqueued_call, 3 },
657 { C::tx_prev_l2_gas_used_sent_to_enqueued_call, 300 },
658 { C::tx_next_da_gas_used, 4 },
659 { C::tx_next_l2_gas_used, 400 },
660 { C::tx_next_da_gas_used_sent_to_enqueued_call, 4 },
661 { C::tx_next_l2_gas_used_sent_to_enqueued_call, 400 },
666 { C::tx_sel_process_call_request, 1 },
667 { C::tx_remaining_phase_counter, 1 },
668 { C::tx_remaining_phase_inv, 1 },
670 { C::tx_msg_sender, teardown_call_request.msg_sender },
671 { C::tx_contract_addr, teardown_call_request.contract_address },
672 { C::tx_is_static, teardown_call_request.is_static_call },
673 { C::tx_calldata_hash, teardown_call_request.calldata_hash },
674 { C::tx_prev_da_gas_used, 4 },
675 { C::tx_prev_l2_gas_used, 400 },
676 { C::tx_prev_da_gas_used_sent_to_enqueued_call, 0 },
677 { C::tx_prev_l2_gas_used_sent_to_enqueued_call, 0 },
678 { C::tx_next_da_gas_used, 4 },
679 { C::tx_next_l2_gas_used, 400 },
680 { C::tx_next_da_gas_used_sent_to_enqueued_call, 13213 },
681 { C::tx_next_l2_gas_used_sent_to_enqueued_call, 456789 },
686 { C::tx_prev_da_gas_used, 4 },
687 { C::tx_prev_l2_gas_used, 400 },
688 { C::tx_next_da_gas_used, 4 },
689 { C::tx_next_l2_gas_used, 400 },
698 check_relation<tx>(
trace);
699 check_interaction<TxTraceBuilder, lookup_tx_read_phase_spec_settings>(
trace);
700 check_interaction<TxTraceBuilder, lookup_tx_read_phase_length_settings>(
trace);
701 check_interaction<TxTraceBuilder, lookup_tx_read_public_call_request_phase_settings>(
trace);
702 check_interaction<TxTraceBuilder, lookup_tx_read_effective_fee_public_inputs_settings>(
trace);
703 check_interaction<TxTraceBuilder, lookup_tx_read_fee_payer_public_inputs_settings>(
trace);
706TEST(TxExecutionConstrainingTest, NegativeTreePaddingChecks)
711 { C::precomputed_first_row, 1 },
716 { C::tx_is_tree_padding, 1 },
717 { C::tx_prev_note_hash_tree_root, 42 },
718 { C::tx_next_note_hash_tree_root, 42 },
719 { C::tx_prev_note_hash_tree_size, 5 },
720 { C::tx_next_note_hash_tree_size, MAX_NOTE_HASHES_PER_TX },
721 { C::tx_prev_num_note_hashes_emitted, 5 },
722 { C::tx_next_num_note_hashes_emitted, 5 },
723 { C::tx_prev_nullifier_tree_root, 43 },
724 { C::tx_next_nullifier_tree_root, 43 },
725 { C::tx_prev_nullifier_tree_size, 7 },
726 { C::tx_next_nullifier_tree_size, MAX_NULLIFIERS_PER_TX },
727 { C::tx_prev_num_nullifiers_emitted, 7 },
728 { C::tx_next_num_nullifiers_emitted, 7 },
733 check_relation<tx_context>(
trace,
742 trace.
set(C::tx_next_note_hash_tree_root, 1, 999);
747 trace.
set(C::tx_next_num_note_hashes_emitted, 1, 999);
752 trace.
set(C::tx_next_nullifier_tree_root, 1, 999);
757 trace.
set(C::tx_next_num_nullifiers_emitted, 1, 999);
762 trace.
set(C::tx_next_note_hash_tree_size, 1, MAX_NOTE_HASHES_PER_TX - 1);
767 trace.
set(C::tx_next_nullifier_tree_size, 1, MAX_NULLIFIERS_PER_TX - 1);
778 ::testing::StrictMock<simulation::MockGreaterThan>
mock_gt;
791 .rand_public_app_logic_call_requests(2)
794 std::vector<FF> dummy_setup_calldata = { 1, 2 };
795 std::vector<FF> dummy_setup_calldata_preimage = dummy_setup_calldata;
796 dummy_setup_calldata_preimage.insert(dummy_setup_calldata_preimage.begin(), DOM_SEP__PUBLIC_CALLDATA);
797 FF dummy_setup_calldata_hash =
poseidon2.
hash(dummy_setup_calldata_preimage);
798 test_public_inputs.public_setup_call_requests[0].calldata_hash = dummy_setup_calldata_hash;
800 std::vector<FF> non_empty_calldata = { 2, 3, 4 };
801 std::vector<FF> non_empty_calldata_preimage = non_empty_calldata;
802 non_empty_calldata_preimage.insert(non_empty_calldata_preimage.begin(), DOM_SEP__PUBLIC_CALLDATA);
803 FF non_empty_calldata_hash =
poseidon2.
hash(non_empty_calldata_preimage);
804 test_public_inputs.public_app_logic_call_requests[0].calldata_hash = non_empty_calldata_hash;
807 test_public_inputs.public_app_logic_call_requests[1].calldata_hash = empty_calldata_hash;
810 { .context_id = 1, .calldata = dummy_setup_calldata, .calldata_hash = dummy_setup_calldata_hash },
811 { .context_id = 5, .calldata = non_empty_calldata, .calldata_hash = non_empty_calldata_hash },
812 { .context_id = 6, .calldata = {}, .calldata_hash = empty_calldata_hash },
815 auto setup_call_request = test_public_inputs.public_setup_call_requests[0];
816 auto non_empty_calldata_app_logic_call_request = test_public_inputs.public_app_logic_call_requests[0];
817 auto empty_calldata_app_logic_call_request = test_public_inputs.public_app_logic_call_requests[1];
821 set_initial_columns(
trace,
822 { setup_call_request },
823 { non_empty_calldata_app_logic_call_request, empty_calldata_app_logic_call_request });
826 trace.
set(4, { { { C::tx_calldata_size, 2 }, { C::tx_next_context_id, 1 } } });
829 trace.
set(8, { { { C::tx_calldata_size, 3 }, { C::tx_next_context_id, 5 } } });
832 trace.
set(9, { { { C::tx_calldata_size, 0 }, { C::tx_next_context_id, 6 } } });
835 trace.
set(10, { { { C::tx_is_padded, 1 } } });
848 check_relation<tx>(
trace);
854 check_relation<bb::avm2::calldata_hashing<FF>>(
trace);
855 check_all_interactions<tracegen::CalldataTraceBuilder>(
trace);
860TEST(TxExecutionConstrainingTest, NegativeNullifierStateIncrementIsUnconditional)
870 { C::precomputed_first_row, 1 },
875 { C::tx_sel_nullifier_append, 1 },
876 { C::tx_reverted, 1 },
877 { C::tx_prev_nullifier_tree_size, 5 },
878 { C::tx_next_nullifier_tree_size, 5 },
879 { C::tx_prev_num_nullifiers_emitted, 3 },
880 { C::tx_next_num_nullifiers_emitted, 3 },
888 trace.
set(C::tx_next_nullifier_tree_size, 1, 6);
892 trace.
set(C::tx_next_num_nullifiers_emitted, 1, 4);
898TEST(TxExecutionConstrainingTest, MaxNullifierWritesReachedForcesReverted)
908 { C::precomputed_first_row, 1 },
912 { C::tx_sel_try_nullifier_append, 1 },
913 { C::tx_prev_num_nullifiers_emitted, MAX_NULLIFIERS_PER_TX },
914 { C::tx_reverted, 1 },
929TEST(TxExecutionConstrainingTest, NegativeCannotRevertWhenNullifierWritesAvailable)
933 constexpr uint32_t prev_emitted = 3;
934 constexpr uint32_t remaining = MAX_NULLIFIERS_PER_TX - prev_emitted;
935 static_assert(remaining > 0);
940 { C::precomputed_first_row, 1 },
944 { C::tx_sel_try_nullifier_append, 1 },
945 { C::tx_prev_num_nullifiers_emitted, prev_emitted },
946 { C::tx_reverted, 0 },
947 { C::tx_remaining_side_effects_inv,
FF(remaining).invert() },
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
StrictMock< MockGreaterThan > mock_gt
EventEmitter< Poseidon2PermutationMemoryEvent > perm_mem_event_emitter
EventEmitter< Poseidon2PermutationEvent > perm_event_emitter
EventEmitter< Poseidon2HashEvent > hash_event_emitter
Poseidon2TraceBuilder poseidon2_builder
StrictMock< MockExecutionIdManager > mock_execution_id_manager
simulation::EventEmitter< simulation::Poseidon2HashEvent > hash_event_emitter
::testing::StrictMock< simulation::MockGreaterThan > mock_gt
simulation::EventEmitter< simulation::Poseidon2PermutationEvent > perm_event_emitter
tracegen::Poseidon2TraceBuilder poseidon2_builder
::testing::StrictMock< simulation::MockExecutionIdManager > mock_execution_id_manager
simulation::EventEmitter< simulation::Poseidon2PermutationMemoryEvent > perm_mem_event_emitter
tracegen::CalldataTraceBuilder calldata_builder
void process_hash(const simulation::EventEmitterInterface< simulation::Poseidon2HashEvent >::Container &hash_events, TraceContainer &trace)
Processes the hash events for the Poseidon2 hash function. It populates the columns for the poseidon2...
void process_misc(TraceContainer &trace, const uint32_t num_rows=PRECOMPUTED_TRACE_SIZE)
Populate miscellaneous precomputed columns: first_row selector and idx (row index).
void process_phase_table(TraceContainer &trace)
Populate the transaction phase specification table.
void set(Column col, uint32_t row, const FF &value, bool use_atomic_limbs=false)
static constexpr size_t SR_NULLIFIER_SIZE_IMMUTABILITY
static constexpr size_t SR_INIT_TX_REVERTED
static constexpr size_t SR_NULLIFIER_COUNT_IMMUTABILITY
static std::string get_subrelation_label(size_t index)
static constexpr size_t SR_NOTE_HASH_ROOT_IMMUTABILITY
static constexpr size_t SR_NOTE_HASH_SIZE_IMMUTABILITY
static constexpr size_t SR_NULLIFIER_ROOT_IMMUTABILITY
static constexpr size_t SR_NOTE_HASH_COUNT_IMMUTABILITY
static constexpr size_t SR_TX_REVERTED_CONTINUITY
static constexpr size_t SR_SET_TX_REVERTED
static constexpr size_t SR_NO_EARLY_END
static std::string get_subrelation_label(size_t index)
static constexpr size_t SR_NULLIFIER_EMITTED_COUNT_INCREMENT
static constexpr size_t SR_MAX_NULLIFIER_WRITES_REACHED
static constexpr size_t SR_PAD_NOTE_HASH_TREE
static constexpr size_t SR_NULLIFIER_TREE_SIZE_INCREMENT
static constexpr size_t SR_TRACE_CONTINUITY
static constexpr size_t SR_PAD_NULLIFIER_TREE
static constexpr size_t SR_START_WITH_SEL
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
PrecomputedTraceBuilder precomputed_builder
TEST_F(AvmRecursiveTests, TwoLayerAvmRecursion)
A test of the Two Layer AVM recursive verifier.
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
TestTraceContainer empty_trace()
lookup_settings< lookup_tx_read_phase_spec_settings_ > lookup_tx_read_phase_spec_settings
permutation_settings< perm_tx_read_calldata_hash_settings_ > perm_tx_read_calldata_hash_settings
lookup_settings< lookup_tx_read_public_call_request_phase_settings_ > lookup_tx_read_public_call_request_phase_settings
lookup_settings< lookup_tx_read_phase_length_settings_ > lookup_tx_read_phase_length_settings
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
EventEmitter< CalldataEvent > calldata_events
Settings to be passed ot GenericLookupRelationImpl.
tracegen::PublicInputsTraceBuilder public_inputs_builder