1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
23using simulation::EventEmitter;
24using simulation::FieldGreaterThan;
25using simulation::FieldGreaterThanEvent;
26using simulation::MockRangeCheck;
28using tracegen::ExecutionTraceBuilder;
29using tracegen::PublicInputsTraceBuilder;
30using tracegen::TestTraceContainer;
32using testing::PublicInputsBuilder;
33using tracegen::FieldGreaterThanTraceBuilder;
39TEST(SendL2ToL1MsgConstrainingTest, Positive)
41 uint64_t prev_num_l2_to_l1_msgs = MAX_L2_TO_L1_MSGS_PER_TX - 1;
42 TestTraceContainer
trace({ {
43 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
44 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
45 { C::execution_register_0_, 42 },
46 { C::execution_register_1_, 27 },
47 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
MemoryTag::FF) },
48 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
MemoryTag::FF) },
49 { C::execution_remaining_l2_to_l1_msgs_inv,
FF(MAX_L2_TO_L1_MSGS_PER_TX - prev_num_l2_to_l1_msgs).invert() },
50 { C::execution_sel_write_l2_to_l1_msg, 1 },
51 { C::execution_sel_opcode_error, 0 },
52 { C::execution_public_inputs_index,
53 AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX + prev_num_l2_to_l1_msgs },
54 { C::execution_prev_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs },
55 { C::execution_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs + 1 },
56 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_SENDL2TOL1MSG },
59 check_relation<send_l2_to_l1_msg>(trace);
62TEST(SendL2ToL1MsgConstrainingTest, LimitReached)
64 uint64_t prev_num_l2_to_l1_msgs = MAX_L2_TO_L1_MSGS_PER_TX;
65 TestTraceContainer
trace({ {
66 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
67 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
68 { C::execution_register_0_, 42 },
69 { C::execution_register_1_, 27 },
70 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
MemoryTag::FF) },
71 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
MemoryTag::FF) },
72 { C::execution_sel_l2_to_l1_msg_limit_error, 1 },
73 { C::execution_remaining_l2_to_l1_msgs_inv, 0 },
74 { C::execution_sel_write_l2_to_l1_msg, 0 },
75 { C::execution_sel_opcode_error, 1 },
76 { C::execution_public_inputs_index,
77 AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX + prev_num_l2_to_l1_msgs },
78 { C::execution_prev_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs },
79 { C::execution_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs },
80 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_SENDL2TOL1MSG },
82 check_relation<send_l2_to_l1_msg>(trace);
85 trace.
set(C::execution_sel_opcode_error, 0, 0);
88 trace.
set(C::execution_sel_opcode_error, 0, 1);
91 trace.
set(C::execution_num_l2_to_l1_messages, 0, prev_num_l2_to_l1_msgs + 1);
98TEST(SendL2ToL1MsgConstrainingTest, Discard)
100 uint64_t prev_num_l2_to_l1_msgs = 0;
101 TestTraceContainer
trace({ {
102 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
103 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
104 { C::execution_register_0_, 42 },
105 { C::execution_register_1_, 27 },
106 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
MemoryTag::FF) },
107 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
MemoryTag::FF) },
108 { C::execution_remaining_l2_to_l1_msgs_inv,
FF(MAX_L2_TO_L1_MSGS_PER_TX - prev_num_l2_to_l1_msgs).invert() },
109 { C::execution_sel_write_l2_to_l1_msg, 0 },
110 { C::execution_sel_opcode_error, 0 },
111 { C::execution_public_inputs_index,
112 AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX + prev_num_l2_to_l1_msgs },
113 { C::execution_discard, 1 },
114 { C::execution_prev_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs },
115 { C::execution_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs + 1 },
116 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_SENDL2TOL1MSG },
118 check_relation<send_l2_to_l1_msg>(trace);
121 trace.
set(C::execution_num_l2_to_l1_messages, 0, prev_num_l2_to_l1_msgs);
128TEST(SendL2ToL1MsgConstrainingTest, Interactions)
130 uint64_t prev_num_l2_to_l1_msgs = 0;
134 AvmAccumulatedData accumulated_data = {};
136 MockRangeCheck mock_range_check;
137 EventEmitter<FieldGreaterThanEvent> ff_gt_event_emitter;
138 FieldGreaterThan
field_gt(mock_range_check, ff_gt_event_emitter);
142 accumulated_data.l2_to_l1_msgs[0] = {
145 .recipient = recipient,
150 AvmAccumulatedDataArrayLengths array_lengths = { .l2_to_l1_msgs = 1 };
151 auto public_inputs = PublicInputsBuilder()
152 .set_accumulated_data(accumulated_data)
153 .set_accumulated_data_array_lengths(array_lengths)
156 TestTraceContainer
trace({ {
157 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
158 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
159 { C::execution_register_0_, recipient },
160 { C::execution_register_1_, content },
161 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
MemoryTag::FF) },
162 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
MemoryTag::FF) },
163 { C::execution_remaining_l2_to_l1_msgs_inv,
FF(MAX_L2_TO_L1_MSGS_PER_TX - prev_num_l2_to_l1_msgs).
invert() },
164 { C::execution_sel_write_l2_to_l1_msg, 1 },
165 { C::execution_sel_opcode_error, 0 },
166 { C::execution_public_inputs_index,
167 AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_L2_TO_L1_MSGS_ROW_IDX + prev_num_l2_to_l1_msgs },
168 { C::execution_contract_address,
address },
169 { C::execution_prev_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs },
170 { C::execution_num_l2_to_l1_messages, prev_num_l2_to_l1_msgs + 1 },
171 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_SENDL2TOL1MSG },
184 check_relation<send_l2_to_l1_msg>(trace);
190TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldErrorIfRecipientTooLarge)
192 TestTraceContainer
trace({ {
193 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
194 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
195 { C::execution_sel_too_large_recipient_error, 1 },
196 { C::execution_sel_l2_to_l1_msg_limit_error, 0 },
197 { C::execution_is_static, 0 },
198 { C::execution_sel_opcode_error, 1 },
203 trace.
set(C::execution_sel_opcode_error, 0, 0);
208TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldErrorIfStatic)
210 TestTraceContainer
trace({ {
211 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
212 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
213 { C::execution_sel_l2_to_l1_msg_limit_error, 0 },
214 { C::execution_is_static, 1 },
215 { C::execution_sel_opcode_error, 1 },
221 trace.
set(C::execution_sel_opcode_error, 0, 0);
226TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldNotWriteIfDiscard)
228 TestTraceContainer
trace({ {
229 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
230 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
231 { C::execution_sel_opcode_error, 0 },
232 { C::execution_discard, 1 },
233 { C::execution_sel_write_l2_to_l1_msg, 0 },
238 trace.
set(C::execution_sel_write_l2_to_l1_msg, 0, 1);
244TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldNumL2ToL1MessagesIncrease)
246 TestTraceContainer
trace({ {
247 { C::execution_sel_execute_send_l2_to_l1_msg, 1 },
248 { C::execution_max_eth_address_value,
FF(MAX_ETH_ADDRESS_VALUE) },
249 { C::execution_sel_opcode_error, 0 },
250 { C::execution_prev_num_l2_to_l1_messages, 0 },
251 { C::execution_num_l2_to_l1_messages, 1 },
253 check_relation<send_l2_to_l1_msg>(trace,
257 trace.
set(C::execution_prev_num_l2_to_l1_messages, 0, 1);
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
FieldGreaterThan field_gt
static constexpr size_t SR_OPCODE_ERROR
static constexpr size_t SR_EMIT_L2_TO_L1_MSG_NUM_L2_TO_L1_MSGS_EMITTED_INCREASE
static std::string get_subrelation_label(size_t index)
static constexpr size_t SR_SEND_L2_TO_L1_MSG_CONDITION
bool ff_gt(const FF &a, const FF &b) override
Computes the result of a > b (in a constrained way).
void process(const simulation::EventEmitterInterface< simulation::FieldGreaterThanEvent >::Container &events, TraceContainer &trace)
Processes FieldGreaterThanEvent events and generates trace rows for the ff_gt gadget.
void process_misc(TraceContainer &trace, const uint32_t num_rows=PRECOMPUTED_TRACE_SIZE)
Populate miscellaneous precomputed columns: first_row selector and idx (row index).
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value, bool use_atomic_limbs=false)
PrecomputedTraceBuilder precomputed_builder
FieldGreaterThanTraceBuilder field_gt_builder
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
lookup_settings< lookup_send_l2_to_l1_msg_recipient_check_settings_ > lookup_send_l2_to_l1_msg_recipient_check_settings
lookup_settings< lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_settings_ > lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_settings
constexpr field invert() const noexcept
tracegen::PublicInputsTraceBuilder public_inputs_builder