1#include <gtest/gtest.h>
30 auto result = cpp_simulator.simulate(
bytecode, {});
31 return result.output.at(0);
36 auto add_instruction =
69 EXPECT_EQ(result, 10);
102 EXPECT_EQ(result, 0);
113 EXPECT_EQ(result, 0);
124 EXPECT_EQ(result, 0);
135 EXPECT_EQ(result, 7);
146 EXPECT_EQ(result, 7);
157 EXPECT_EQ(result, 20);
168 EXPECT_EQ(result, 1);
179 auto set_instruction_1 =
183 auto set_instruction_2 =
189 auto return_options =
196 auto result = cpp_simulator.simulate(
bytecode, {});
197 EXPECT_EQ(result.output.at(0), 2);
203 auto set_instruction =
207 auto not_instruction =
212 auto return_options =
219 auto result = cpp_simulator.simulate(
bytecode, {});
220 EXPECT_EQ(result.output.at(0), 255);
228 auto set_instruction_1 =
232 auto set_instruction_2 =
238 auto return_options =
245 auto result = cpp_simulator.simulate(
bytecode, {});
246 return result.output.at(0);
262 EXPECT_EQ(result, 7);
273 EXPECT_EQ(result, 3);
284 EXPECT_EQ(result, 10);
295 EXPECT_EQ(result, 2);
306 EXPECT_EQ(result, 0);
317 EXPECT_EQ(result, 0);
328 EXPECT_EQ(result, 0);
339 EXPECT_EQ(result, 0);
350 EXPECT_EQ(result, 7);
361 EXPECT_EQ(result, 7);
372 EXPECT_EQ(result, 20);
383 EXPECT_EQ(result, 1);
394 auto set_instruction_1 =
398 auto set_instruction_2 =
404 auto return_options =
411 auto result = cpp_simulator.simulate(
bytecode, {});
412 EXPECT_EQ(result.output.at(0), 2);
418 auto set_instruction =
427 auto return_options =
434 auto result = cpp_simulator.simulate(
bytecode, {});
435 EXPECT_EQ(result.output.at(0), 255);
458 auto return_options =
465 auto result = cpp_simulator.simulate(
bytecode, {});
466 EXPECT_EQ(result.output.at(0), 2);
487 auto return_options =
494 auto result = cpp_simulator.simulate(
bytecode, {});
495 EXPECT_EQ(result.output.at(0), 2);
503 const uint16_t test_value = 0xABCD;
504 auto set_instruction =
507 .value = test_value };
509 auto return_options =
516 auto result = cpp_simulator.simulate(
bytecode, {});
517 EXPECT_EQ(result.output.at(0), test_value);
522 const uint32_t test_value = 0x12345678UL;
523 auto set_instruction =
526 .value = test_value };
528 auto return_options =
535 auto result = cpp_simulator.simulate(
bytecode, {});
536 EXPECT_EQ(result.output.at(0), test_value);
542 const uint64_t test_value = 0xABCDEF0123456789ULL;
543 auto set_instruction =
546 .value = test_value };
548 auto return_options =
555 auto result = cpp_simulator.simulate(
bytecode, {});
556 EXPECT_EQ(result.output.at(0), test_value);
562 const uint64_t test_value_low = 0xFEDCBA9876543210ULL;
563 const uint64_t test_value_high = 0x123456789ABCDEF0ULL;
565 (
static_cast<uint128_t>(test_value_high) << 64) |
static_cast<uint128_t>(test_value_low);
566 auto set_instruction =
569 .value_low = test_value_low,
570 .value_high = test_value_high };
574 .return_value_offset_index = 0 };
580 auto result = cpp_simulator.simulate(
bytecode, {});
581 EXPECT_EQ(result.output.at(0), test_value);
588 auto set_instruction =
591 .value = test_value };
593 auto return_options =
600 auto result = cpp_simulator.simulate(
bytecode, {});
601 EXPECT_EQ(result.output.at(0), test_value);
607 const uint8_t test_value = 0x42;
608 const uint8_t test_value2 = 0x43;
609 auto set_instruction =
612 .value = test_value };
615 .value = test_value2 };
616 auto mov_instruction =
621 auto return_options =
628 auto result = cpp_simulator.simulate(
bytecode, {});
629 EXPECT_EQ(result.output.at(0), test_value);
635 const uint16_t test_value = 0xbabe;
636 const uint16_t test_value2 = 0xc0fe;
637 auto set_instruction =
640 .value = test_value };
641 auto set_instruction2 =
644 .value = test_value2 };
650 auto return_options =
657 auto result = cpp_simulator.simulate(
bytecode, {});
658 EXPECT_EQ(result.output.at(0), test_value);
679 auto return_options =
686 auto result = cpp_simulator.simulate(
bytecode, {});
687 EXPECT_EQ(result.output.at(0), 11);
709 auto instruction_blocks =
711 auto return_options =
719 auto result = cpp_simulator.simulate(
bytecode, {});
720 EXPECT_EQ(result.output.at(0), 12);
735 auto return_options =
742 auto result = cpp_simulator.simulate(
bytecode, {});
743 EXPECT_EQ(result.output.at(0), 10);
768 set_true_block, set_false_block, block2_instructions, block3_instructions
770 auto return_options =
776 .else_program_block_instruction_block_idx = 3,
777 .condition_offset_index = 1 });
778 auto bytecode_1 =
control_flow.build_bytecode(return_options);
779 auto control_flow2 =
ControlFlow(instruction_blocks);
783 .else_program_block_instruction_block_idx = 3,
784 .condition_offset_index = 1 });
785 auto bytecode_2 = control_flow2.build_bytecode(return_options);
787 auto result_1 = cpp_simulator.simulate(bytecode_1, {});
789 auto result_2 = cpp_simulator2.simulate(bytecode_2, {});
790 EXPECT_EQ(result_1.output.at(0), 11);
791 EXPECT_EQ(result_2.output.at(0), 12);
803 .value = first_boolean_value };
807 .value = second_boolean_value };
810 for (uint8_t i = 2; i < 5; i++) {
811 auto set_instruction =
815 instruction_blocks.push_back({ set_instruction });
817 auto return_options =
823 .else_program_block_instruction_block_idx = 4,
824 .condition_offset_index = 0 });
826 .else_program_block_instruction_block_idx = 3,
827 .condition_offset_index = 1 });
830 auto result = cpp_simulator.simulate(
bytecode, {});
831 return result.output.at(0);
847 auto set_instruction_block_1 =
850 .value = condition_value };
856 auto instruction_blocks =
858 auto return_options =
864 .else_program_block_instruction_block_idx = 2,
865 .condition_offset_index = 0 });
869 auto result = cpp_simulator.simulate(
bytecode, {});
870 return result.output.at(0);
897 .value = ff_value } };
900 const uint64_t u128_value_low = 0xFEDCBA9876543210ULL;
901 const uint64_t u128_value_high = 0x123456789ABCDEF0ULL;
905 .value_low = u128_value_low,
906 .value_high = u128_value_high } };
908 auto instruction_blocks =
918 .else_program_block_instruction_block_idx = 2,
919 .condition_offset_index = 0 });
932 auto control_flow_true =
ControlFlow(instruction_blocks);
935 .else_program_block_instruction_block_idx = 2,
936 .condition_offset_index = 0 });
944 auto bytecode_true = control_flow_true.build_bytecode(
ReturnOptions{
947 auto result_true = cpp_simulator_true.simulate(bytecode_true, {});
948 EXPECT_EQ(result_true.output.at(0), ff_value);
955 auto instruction_blocks_false =
958 auto control_flow_false =
ControlFlow(instruction_blocks_false);
961 .else_program_block_instruction_block_idx = 2,
962 .condition_offset_index = 0 });
971 (
static_cast<uint128_t>(u128_value_high) << 64) |
static_cast<uint128_t>(u128_value_low);
972 auto bytecode_false = control_flow_false.build_bytecode(
ReturnOptions{
975 auto result_false = cpp_simulator_false.simulate(bytecode_false, {});
976 EXPECT_EQ(result_false.output.at(0), expected_u128_value);
984 auto set_value_instruction =
995 auto sload_instruction =
1000 auto set_value_instruction2 =
1006 set_value_instruction, sstore_instruction, sload_instruction, set_value_instruction2
1013 .return_value_offset_index = 1 };
1018 auto result = cpp_simulator.simulate(
bytecode, {});
1019 EXPECT_EQ(result.output.at(0), 10);
1026 auto getenvvar_instruction =
1032 auto return_options =
1036 auto result = cpp_simulator.simulate(
bytecode, {});
1037 return result.output.at(0);
1060 auto set_field_instruction =
1073 { set_field_instruction, emit_nullifier_instruction, nullifier_exists_instruction }
1080 auto result = cpp_simulator.simulate(
bytecode, {});
1081 EXPECT_EQ(result.output.at(0), 1);
1084TEST(
fuzz, EmitNullifierThenNullifierExistsOverwritingPreviousNullifier)
1086 auto set_field_instruction =
1099 { set_field_instruction, emit_nullifier_instruction, nullifier_exists_instruction }
1106 auto result = cpp_simulator.simulate(
bytecode, {});
1107 EXPECT_EQ(result.output.at(0), 0);
1112 auto emit_note_hash_instruction =
1121 auto instruction_blocks =
1128 auto result = cpp_simulator.simulate(
bytecode, {});
1129 EXPECT_FALSE(result.reverted);
1130 EXPECT_EQ(result.output.at(0), 1);
1148 auto result = cpp_simulator.simulate(
bytecode, {
FF(1337) });
1149 EXPECT_EQ(result.output.at(0), 1337);
1155 auto set_field_instruction =
1159 auto set_field_instruction2 =
1164 auto instruction_blocks =
1168 control_flow.process_cfg_instruction(internal_call_instruction);
1172 auto result = cpp_simulator.simulate(
bytecode, {});
1173 EXPECT_EQ(result.output.at(0), 313373);
1182 auto set_field_instruction =
1186 auto set_boolean_instruction =
1191 auto instruction_blocks =
1195 control_flow.process_cfg_instruction(internal_call_instruction);
1204 auto result = cpp_simulator.simulate(
bytecode, {});
1205 EXPECT_EQ(result.output.at(0), 1337);
1213 auto set_field_instruction =
1217 auto set_field_instruction2 =
1221 auto set_field_instruction3 =
1228 { set_field_instruction, set_field_instruction2, set_field_instruction3 }
1232 control_flow.process_cfg_instruction(internal_call_instruction);
1233 control_flow.process_cfg_instruction(internal_call_instruction2);
1237 auto result = cpp_simulator.simulate(
bytecode, {});
1238 EXPECT_EQ(result.output.at(0), 313373);
1260 auto set_field_instruction0 =
1264 auto set_field_instruction1 =
1268 auto set_field_instruction2 =
1272 auto set_field_instruction3 =
1280 { set_field_instruction0, set_field_instruction1, set_field_instruction2, set_field_instruction3 }
1285 control_flow.process_cfg_instruction(internal_call_instruction);
1287 control_flow.process_cfg_instruction(internal_call_instruction2);
1299 control_flow.process_cfg_instruction(internal_call_instruction3);
1307 auto result = cpp_simulator.simulate(
bytecode, {});
1308 EXPECT_EQ(result.output.at(0), 313373);
1315 auto set_field_instruction =
1319 auto set_field_instruction2 =
1330 auto instruction_blocks =
1337 auto result = cpp_simulator.simulate(
bytecode, {});
1338 EXPECT_EQ(result.output.at(0), 30);
1343 auto set_field_instruction =
1347 auto set_field_instruction2 =
1351 auto add_instruction =
1354 .pointer_address = 100,
1360 auto instruction_blocks =
1367 auto result = cpp_simulator.simulate(
bytecode, {});
1368 EXPECT_EQ(result.output.at(0), 30);
1373 auto set_field_instruction =
1387 auto instruction_blocks =
1394 auto result = cpp_simulator.simulate(
bytecode, {});
1395 EXPECT_EQ(result.output.at(0), 400);
1400 auto set_field_instruction =
1417 auto instruction_blocks =
1424 auto result = cpp_simulator.simulate(
bytecode, {});
1425 EXPECT_EQ(result.output.at(0), 200);
::FuzzInstruction FuzzInstruction
SimulatorResult fuzz(const uint8_t *buffer, size_t size)
std::shared_ptr< Napi::ThreadSafeFunction > bytecode
uses barretenberg/vm2 to simulate the bytecode
FF get_result_of_instruction_16(FuzzInstruction instruction, bb::avm2::MemoryTag return_value_tag=bb::avm2::MemoryTag::U8)
FF get_result_of_instruction(FuzzInstruction instruction, bb::avm2::MemoryTag return_value_tag=bb::avm2::MemoryTag::U8)
TEST(fuzz, DirectWithIndirect)
TEST(fuzz, CopyCalldataThenReturnData)
TEST(fuzz, JumpToNewBlockSmoke)
FF simulate_jump_if_depth_2_helper(uint8_t first_boolean_value, uint8_t second_boolean_value)
FF simulate_jump_to_block_helper(uint8_t condition_value)
TEST(fuzz, GetEnvVarSmoke)
FF getenvvar_helper(uint8_t type, bb::avm2::MemoryTag return_value_tag=bb::avm2::MemoryTag::FF)
TEST(fuzz, InternalCalledBlockUsesInternalReturn)
TEST(fuzz, EmitNullifierThenNullifierExists)
TEST(fuzz, SstoreThenSload)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
unsigned __int128 uint128_t
mem[result_offset] = mem[a_address] + mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] + mem[b_address]
mem[result_offset] = mem[a_address] & mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] & mem[b_address]
CALLDATACOPY: M[dstOffset:dstOffset+M[copySizeOffset]] = calldata[M[cdStartOffset]:M[cdStartOffset]+M...
ResultAddressRef dst_address
CAST_16: cast mem[src_offset_index] to target_tag and store at dst_offset.
CAST_8: cast mem[src_offset_index] to target_tag and store at dst_offset.
mem[result_offset] = mem[a_address] / mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] / mem[b_address]
EMITNOTEHASH: M[note_hash_offset] = note_hash; emit note hash to the note hash tree.
ResultAddressRef note_hash_address
EMITNULIFIER: inserts new nullifier to the nullifier tree.
AddressRef nullifier_address
mem[result_offset] = mem[a_address] == mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] == mem[b_address]
finalizes the current block with Return and switches to the first non-terminated block
ReturnOptions return_options
GETENVVAR: M[result_offset] = getenvvar(type)
ResultAddressRef result_address
inserts INTERNALCALL instruction to the current block creates a new block and sets it as the current ...
uint16_t target_program_block_instruction_block_idx
insert instruction block to the current block
uint16_t instruction_block_idx
finalizes the current block with jump if, creates two new blocks, sets the first as the then block an...
uint16_t then_program_block_instruction_block_idx
finalizes the current block with a jump to the block, which does not create a loop in the graph (defi...
uint16_t target_block_idx
finalizes the current block with jump, creates a new block and sets it as the current block
uint16_t target_program_block_instruction_block_idx
mem[result_offset] = mem[a_address] < mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] < mem[b_address]
mem[result_offset] = mem[a_address] <= mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] <= mem[b_address]
MOV_16 instruction: mem[dst_offset] = mem[src_offset].
MOV_8 instruction: mem[dst_offset] = mem[src_offset].
mem[result_offset] = mem[a_address] * mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] * mem[b_address]
NOTEHASHEXISTS: M[result_offset] = NOTEHASHEXISTS(M[notehash_offset], M[leaf_index_offset]) len = len...
NULLIFIEREXISTS: checks if nullifier exists in the nullifier tree Gets contract's address by GETENVVA...
AddressRef nullifier_address
mem[result_offset] = mem[a_address] | mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] | mem[b_address]
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
mem[result_offset] = mem[a_address] << mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] << mem[b_address]
mem[result_offset] = mem[a_address] >> mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] >> mem[b_address]
SLOAD: M[slot_offset] = slot; M[result_offset] = S[M[slotOffset]].
SSTORE: M[slot_offset_index] = slot; S[M[slotOffset]] = M[srcOffset].
mem[result_offset] = mem[a_address] - mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] - mem[b_address]
mem[result_offset] = mem[a_address] ^ mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] ^ mem[b_address]