Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
exec_op_id.test.cpp
Go to the documentation of this file.
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
4#include <cstdint>
5
21
22namespace bb::avm2::constraining {
23namespace {
24
25using simulation::ExecutionEvent;
26using testing::InstructionBuilder;
27using tracegen::ExecutionTraceBuilder;
28using tracegen::PrecomputedTraceBuilder;
31
32using tracegen::TestTraceContainer;
34using C = Column;
36
37constexpr std::array<WireOpCode, 23> WIRE_OPCODES = {
44};
45
46constexpr std::array<uint32_t, 23> OPERATION_IDS = {
70};
71
72constexpr std::array<C, 23> SELECTOR_COLUMNS = {
73 C::execution_sel_execute_get_env_var,
74 C::execution_sel_execute_mov,
75 C::execution_sel_execute_mov,
76 C::execution_sel_execute_jump,
77 C::execution_sel_execute_jumpi,
78 C::execution_sel_execute_call,
79 C::execution_sel_execute_internal_call,
80 C::execution_sel_execute_internal_return,
81 C::execution_sel_execute_return,
82 C::execution_sel_execute_success_copy,
83 C::execution_sel_execute_static_call,
84 C::execution_sel_execute_revert,
85 C::execution_sel_execute_revert,
86 C::execution_sel_execute_returndata_size,
87 C::execution_sel_execute_debug_log,
88 C::execution_sel_execute_sload,
89 C::execution_sel_execute_sstore,
90 C::execution_sel_execute_notehash_exists,
91 C::execution_sel_execute_emit_notehash,
92 C::execution_sel_execute_l1_to_l2_message_exists,
93 C::execution_sel_execute_nullifier_exists,
94 C::execution_sel_execute_emit_nullifier,
95 C::execution_sel_execute_send_l2_to_l1_msg,
96};
97
98// Ensure that WIRE_OPCODES contains all wire opcodes which have an execution opcode belonging
99// to the execution subtrace.
100TEST(ExecOpIdConstrainingTest, WireOpcodeListCompleteness)
101{
102 for (uint8_t opcode = 0; opcode < static_cast<uint8_t>(WireOpCode::LAST_OPCODE_SENTINEL); opcode++) {
103 const auto wire_opcode = static_cast<WireOpCode>(opcode);
104 const auto& exec_opcode = WIRE_INSTRUCTION_SPEC.at(wire_opcode).exec_opcode;
105
106 if (SUBTRACE_INFO_MAP.contains(exec_opcode)) {
107 const auto& subtrace_info = SUBTRACE_INFO_MAP.at(exec_opcode);
108 if (subtrace_info.subtrace_selector == SubtraceSel::EXECUTION) {
109 EXPECT_TRUE(std::find(WIRE_OPCODES.begin(), WIRE_OPCODES.end(), wire_opcode) != WIRE_OPCODES.end());
110 }
111 }
112 }
113}
114
115// Magic constant ensuring that for any index i, the index i + INCREMENT_FOR_NEGATIVE_TEST modulo
116// WIRE_OPCODES.size() has a different value in OPERATION_IDS and SELECTOR_COLUMNS. 6 corresponds to the
117// number of SET wire opcodes. This is the execution opcode with the largest number of wire opcodes.
118constexpr size_t INCREMENT_FOR_NEGATIVE_TEST = 6;
119
120// TODO(fcarreiro): enable.
121TEST(ExecOpIdConstrainingTest, DISABLED_Decomposition)
122{
123 for (size_t i = 0; i < WIRE_OPCODES.size(); i++) {
124 TestTraceContainer trace({
125 {
126 { C::execution_sel_execute_execution, 1 },
127 { C::execution_subtrace_operation_id, OPERATION_IDS.at(i) },
128 { SELECTOR_COLUMNS.at(i), 1 },
129 },
130 });
131
132 check_relation<execution>(trace, execution::SR_EXEC_OP_ID_DECOMPOSITION);
133
134 // Negative test: untoggle the selector
135 trace.set(SELECTOR_COLUMNS.at(i), 0, 0);
137 "EXEC_OP_ID_DECOMPOSITION");
138
139 // Negative test: toggle another selector
140 trace.set(SELECTOR_COLUMNS.at((i + INCREMENT_FOR_NEGATIVE_TEST) % WIRE_OPCODES.size()), 0, 1);
142 "EXEC_OP_ID_DECOMPOSITION");
143 }
144}
145
146// TODO(fcarreiro): enable.
147// Show that the precomputed trace contains the correct execution operation id
148// which maps to the correct opcode selectors.
149// Show also that execution relations are satisfied.
150TEST(ExecOpIdConstrainingTest, DISABLED_InteractionWithExecInstructionSpec)
151{
152 PrecomputedTraceBuilder precomputed_builder;
153
155 events.reserve(WIRE_OPCODES.size());
156 for (const auto& wire_opcode : WIRE_OPCODES) {
157 events.push_back({
158 .wire_instruction = InstructionBuilder(wire_opcode).build(),
159 });
160 }
161
162 TestTraceContainer trace;
163 ExecutionTraceBuilder exec_builder;
164 uint32_t row = 1;
165
166 for (const auto& event : events) {
167 exec_builder.process_execution_spec(event, trace, row);
168 row++;
169 }
170
171 // Check that the operation ids and relevant selectors are toggled.
172 for (size_t i = 0; i < WIRE_OPCODES.size(); i++) {
173 ASSERT_EQ(trace.get(C::execution_subtrace_operation_id, static_cast<uint32_t>(i + 1)), OPERATION_IDS.at(i));
174 ASSERT_EQ(trace.get(C::execution_subtrace_id, static_cast<uint32_t>(i + 1)), AVM_SUBTRACE_ID_EXECUTION);
175 ASSERT_EQ(trace.get(C::execution_sel_execute_execution, static_cast<uint32_t>(i + 1)), 1);
176 }
177
178 // Activate the lookup selector execution_sel_instruction_fetching_success for each row.
179 // Activate the execution selector execution_sel for each row.
180 // Set the execution opcode for each row.
181 for (size_t i = 0; i < WIRE_OPCODES.size(); i++) {
182 trace.set(C::execution_sel_instruction_fetching_success, static_cast<uint32_t>(i + 1), 1);
183 trace.set(C::execution_sel, static_cast<uint32_t>(i + 1), 1);
184 trace.set(C::execution_ex_opcode,
185 static_cast<uint32_t>(i + 1),
186 static_cast<uint8_t>(events.at(i).wire_instruction.get_exec_opcode()));
187 }
188
189 precomputed_builder.process_misc(
190 trace, 256); // number of clk set to 256 to ensure it covers all the rows of exec instruction spec
191 precomputed_builder.process_exec_instruction_spec(trace);
192
193 check_relation<execution>(trace, execution::SR_EXEC_OP_ID_DECOMPOSITION);
194 check_interaction<ExecutionTraceBuilder, lookup_execution_exec_spec_read_settings>(trace);
195
196 // Negative test: copy a wrong operation id
197 for (size_t i = 0; i < WIRE_OPCODES.size(); i++) {
198 auto mutated_trace = trace;
199 mutated_trace.set(C::execution_subtrace_operation_id,
200 static_cast<uint32_t>(i + 1),
201 OPERATION_IDS.at((i + INCREMENT_FOR_NEGATIVE_TEST) % WIRE_OPCODES.size()));
203 (check_interaction<ExecutionTraceBuilder, lookup_execution_exec_spec_read_settings>(mutated_trace)),
204 "Failed.*LOOKUP_EXECUTION_EXEC_SPEC_READ.*Could not find tuple in destination.");
205 }
206}
207
208} // namespace
209} // namespace bb::avm2::constraining
#define AVM_EXEC_OP_ID_SUCCESSCOPY
#define AVM_EXEC_OP_ID_NULLIFIER_EXISTS
#define AVM_EXEC_OP_ID_SSTORE
#define AVM_EXEC_OP_ID_EMIT_NULLIFIER
#define AVM_EXEC_OP_ID_NOTEHASH_EXISTS
#define AVM_EXEC_OP_ID_SLOAD
#define AVM_EXEC_OP_ID_RETURN
#define AVM_EXEC_OP_ID_INTERNALCALL
#define AVM_EXEC_OP_ID_STATICCALL
#define AVM_EXEC_OP_ID_JUMP
#define AVM_EXEC_OP_ID_DEBUGLOG
#define AVM_EXEC_OP_ID_EMIT_NOTEHASH
#define AVM_EXEC_OP_ID_REVERT
#define AVM_EXEC_OP_ID_MOV
#define AVM_EXEC_OP_ID_SENDL2TOL1MSG
#define AVM_EXEC_OP_ID_RETURNDATASIZE
#define AVM_EXEC_OP_ID_CALL
#define AVM_EXEC_OP_ID_JUMPI
#define AVM_EXEC_OP_ID_L1_TO_L2_MESSAGE_EXISTS
#define AVM_EXEC_OP_ID_GETENVVAR
#define AVM_EXEC_OP_ID_INTERNALRETURN
#define AVM_SUBTRACE_ID_EXECUTION
static constexpr size_t SR_EXEC_OP_ID_DECOMPOSITION
const FF & get(Column col, uint32_t row) const
void set(Column col, uint32_t row, const FF &value)
PrecomputedTraceBuilder precomputed_builder
Definition alu.test.cpp:119
TestTraceContainer trace
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
Definition macros.hpp:7
TEST(TxExecutionConstrainingTest, WriteTreeValue)
Definition tx.test.cpp:508
const std::unordered_map< ExecutionOpCode, SubtraceInfo > SUBTRACE_INFO_MAP
const std::unordered_map< WireOpCode, WireInstructionSpec > WIRE_INSTRUCTION_SPEC
typename Flavor::FF FF
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
simulation::PublicDataTreeReadWriteEvent event
NiceMock< MockExecution > execution