Skip to content

Commit 214d31c

Browse files
committed
12193: Add negative interaction tests for instr fetching
1 parent e404410 commit 214d31c

File tree

1 file changed

+108
-2
lines changed

1 file changed

+108
-2
lines changed

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/instr_fetching.test.cpp

+108-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace bb::avm2::constraining {
2222
namespace {
2323

2424
using tracegen::BytecodeTraceBuilder;
25+
using tracegen::PrecomputedTraceBuilder;
2526
using tracegen::TestTraceContainer;
2627
using FF = AvmFlavorSettings::FF;
2728
using C = Column;
@@ -138,7 +139,6 @@ TEST(InstrFetchingConstrainingTest, EachOpcodeWithTraceGen)
138139
// We perform this for a random instruction for opcodes: REVERT_16, CAST_8, TORADIXBE
139140
TEST(InstrFetchingConstrainingTest, NegativeWrongOperand)
140141
{
141-
TestTraceContainer trace;
142142
BytecodeTraceBuilder builder;
143143

144144
std::vector<WireOpCode> opcodes = { WireOpCode::REVERT_16, WireOpCode::CAST_8, WireOpCode::TORADIXBE };
@@ -155,6 +155,7 @@ TEST(InstrFetchingConstrainingTest, NegativeWrongOperand)
155155
};
156156

157157
for (const auto& opcode : opcodes) {
158+
TestTraceContainer trace;
158159
const auto instr = testing::random_instruction(opcode);
159160
builder.process_instruction_fetching({ simulation::InstructionFetchingEvent{
160161
.bytecode_id = 1,
@@ -186,7 +187,7 @@ TEST(InstrFetchingConstrainingTest, WireInstructionSpecInteractions)
186187
TestTraceContainer trace;
187188
BytecodeTraceBuilder bytecode_builder;
188189

189-
tracegen::PrecomputedTraceBuilder precomputed_builder;
190+
PrecomputedTraceBuilder precomputed_builder;
190191
precomputed_builder.process_wire_instruction_spec(trace);
191192
bytecode_builder.process_instruction_fetching(gen_instr_events_each_opcode(), trace);
192193
precomputed_builder.process_misc(trace, trace.get_num_rows()); // Limit to the number of rows we need.
@@ -221,5 +222,110 @@ TEST(InstrFetchingConstrainingTest, BcDecompositionInteractions)
221222
check_interaction<bc_decomposition_lookup>(trace);
222223
}
223224

225+
// Negative interaction test with some values not matching the instruction spec table.
226+
TEST(InstrFetchingConstrainingTest, NegativeWrongWireInstructionSpecInteractions)
227+
{
228+
using wire_instr_spec_lookup = lookup_instr_fetching_wire_instruction_info_relation<FF>;
229+
230+
BytecodeTraceBuilder bytecode_builder;
231+
PrecomputedTraceBuilder precomputed_builder;
232+
233+
// Some arbitrary chosen opcodes. We limit to one as this unit test is costly.
234+
// Test works if the following vector is extended to other opcodes though.
235+
std::vector<WireOpCode> opcodes = { WireOpCode::CALLDATACOPY };
236+
237+
for (const auto& opcode : opcodes) {
238+
TestTraceContainer trace;
239+
const auto instr = testing::random_instruction(opcode);
240+
bytecode_builder.process_instruction_fetching(
241+
{ simulation::InstructionFetchingEvent{ .bytecode_id = 1,
242+
.pc = 0,
243+
.instruction = instr,
244+
.bytecode =
245+
std::make_shared<std::vector<uint8_t>>(instr.encode()) } },
246+
trace);
247+
precomputed_builder.process_wire_instruction_spec(trace);
248+
precomputed_builder.process_misc(trace, trace.get_num_rows()); // Limit to the number of rows we need.
249+
250+
tracegen::LookupIntoIndexedByClk<wire_instr_spec_lookup::Settings>().process(trace);
251+
check_interaction<wire_instr_spec_lookup>(trace);
252+
253+
const std::vector<C> mutated_cols = {
254+
C::instr_fetching_exec_opcode, C::instr_fetching_instr_size_in_bytes, C::instr_fetching_sel_op_dc_0,
255+
C::instr_fetching_sel_op_dc_1, C::instr_fetching_sel_op_dc_2, C::instr_fetching_sel_op_dc_3,
256+
C::instr_fetching_sel_op_dc_4, C::instr_fetching_sel_op_dc_5, C::instr_fetching_sel_op_dc_6,
257+
C::instr_fetching_sel_op_dc_7, C::instr_fetching_sel_op_dc_8, C::instr_fetching_sel_op_dc_9,
258+
C::instr_fetching_sel_op_dc_10, C::instr_fetching_sel_op_dc_11, C::instr_fetching_sel_op_dc_12,
259+
C::instr_fetching_sel_op_dc_13, C::instr_fetching_sel_op_dc_14, C::instr_fetching_sel_op_dc_15,
260+
C::instr_fetching_sel_op_dc_16, C::instr_fetching_sel_op_dc_17,
261+
};
262+
263+
// Mutate execution opcode
264+
for (const auto& col : mutated_cols) {
265+
auto mutated_trace = trace;
266+
const FF mutated_value = trace.get(col, 0) + 1; // Mutate to value + 1
267+
mutated_trace.set(col, 0, mutated_value);
268+
EXPECT_THROW_WITH_MESSAGE(check_interaction<wire_instr_spec_lookup>(mutated_trace),
269+
"Relation.*WIRE_INSTRUCTION_INFO.* ACCUMULATION.* is non-zero");
270+
}
271+
}
272+
}
273+
274+
// Negative interaction test with some values not matching the bytecode decomposition table.
275+
TEST(InstrFetchingConstrainingTest, NegativeWrongBcDecompositionInteractions)
276+
{
277+
using bc_decomposition_lookup = lookup_instr_fetching_bytes_from_bc_dec_relation<FF>;
278+
279+
TestTraceContainer trace;
280+
BytecodeTraceBuilder bytecode_builder;
281+
282+
// Some arbitrary chosen opcodes. We limit to one as this unit test is costly.
283+
// Test works if the following vector is extended to other opcodes though.
284+
std::vector<WireOpCode> opcodes = { WireOpCode::STATICCALL };
285+
286+
for (const auto& opcode : opcodes) {
287+
TestTraceContainer trace;
288+
const auto instr = testing::random_instruction(opcode);
289+
auto bytecode_ptr = std::make_shared<std::vector<uint8_t>>(instr.encode());
290+
bytecode_builder.process_instruction_fetching({ simulation::InstructionFetchingEvent{
291+
.bytecode_id = 1,
292+
.pc = 0,
293+
.instruction = instr,
294+
.bytecode = bytecode_ptr,
295+
} },
296+
trace);
297+
bytecode_builder.process_decomposition({ simulation::BytecodeDecompositionEvent{
298+
.bytecode_id = 1,
299+
.bytecode = bytecode_ptr,
300+
} },
301+
trace);
302+
303+
tracegen::LookupIntoDynamicTableSequential<bc_decomposition_lookup::Settings>().process(trace);
304+
check_interaction<bc_decomposition_lookup>(trace);
305+
306+
const std::vector<C> mutated_cols = {
307+
C::instr_fetching_pc, C::instr_fetching_bytecode_id, C::instr_fetching_bd0, C::instr_fetching_bd1,
308+
C::instr_fetching_bd2, C::instr_fetching_bd3, C::instr_fetching_bd4, C::instr_fetching_bd5,
309+
C::instr_fetching_bd6, C::instr_fetching_bd7, C::instr_fetching_bd8, C::instr_fetching_bd9,
310+
C::instr_fetching_bd10, C::instr_fetching_bd11, C::instr_fetching_bd12, C::instr_fetching_bd13,
311+
C::instr_fetching_bd14, C::instr_fetching_bd15, C::instr_fetching_bd16, C::instr_fetching_bd17,
312+
C::instr_fetching_bd18, C::instr_fetching_bd19, C::instr_fetching_bd20, C::instr_fetching_bd21,
313+
C::instr_fetching_bd22, C::instr_fetching_bd23, C::instr_fetching_bd24, C::instr_fetching_bd25,
314+
C::instr_fetching_bd26, C::instr_fetching_bd27, C::instr_fetching_bd28, C::instr_fetching_bd29,
315+
C::instr_fetching_bd30, C::instr_fetching_bd31, C::instr_fetching_bd32, C::instr_fetching_bd33,
316+
C::instr_fetching_bd34, C::instr_fetching_bd35, C::instr_fetching_bd36,
317+
};
318+
319+
// Mutate execution opcode
320+
for (const auto& col : mutated_cols) {
321+
auto mutated_trace = trace;
322+
const FF mutated_value = trace.get(col, 0) + 1; // Mutate to value + 1
323+
mutated_trace.set(col, 0, mutated_value);
324+
EXPECT_THROW_WITH_MESSAGE(check_interaction<bc_decomposition_lookup>(mutated_trace),
325+
"Relation.*BYTES_FROM_BC_DEC.* ACCUMULATION.* is non-zero");
326+
}
327+
}
328+
}
329+
224330
} // namespace
225331
} // namespace bb::avm2::constraining

0 commit comments

Comments
 (0)