@@ -1245,7 +1245,7 @@ TEST_F(AvmExecutionTests, msmOpCode)
1245
1245
}
1246
1246
1247
1247
// Positive test for Kernel Input opcodes
1248
- TEST_F (AvmExecutionTests, kernelInputOpcodes )
1248
+ TEST_F (AvmExecutionTests, getEnvOpcode )
1249
1249
{
1250
1250
std::string bytecode_hex =
1251
1251
to_hex (OpCode::GETENVVAR_16) + // opcode GETENVVAR_16
@@ -1497,6 +1497,32 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes)
1497
1497
validate_trace (std::move (trace), convert_public_inputs (public_inputs_vec), calldata, returndata);
1498
1498
}
1499
1499
1500
+ // TODO(9395): allow this intruction to raise error flag in main.pil
1501
+ // TEST_F(AvmExecutionTests, getEnvOpcodeBadEnum)
1502
+ // {
1503
+ // std::string bytecode_hex =
1504
+ // to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16
1505
+ // "00" // Indirect flag
1506
+ // + to_hex(static_cast<uint8_t>(EnvironmentVariable::MAX_ENV_VAR)) + // envvar ADDRESS
1507
+ // "0001"; // dst_offset
1508
+ //
1509
+ // auto bytecode = hex_to_bytes(bytecode_hex);
1510
+ // auto instructions = Deserialization::parse(bytecode);
1511
+ //
1512
+ // // Public inputs for the circuit
1513
+ // std::vector<FF> calldata;
1514
+ // std::vector<FF> returndata;
1515
+ // ExecutionHints execution_hints;
1516
+ // auto trace = gen_trace(bytecode, calldata, public_inputs_vec, returndata, execution_hints);
1517
+ //
1518
+ // // Bad enum should raise error flag
1519
+ // auto address_row =
1520
+ // std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_address == 1; });
1521
+ // EXPECT_EQ(address_row->main_op_err, FF(1));
1522
+ //
1523
+ // validate_trace(std::move(trace), convert_public_inputs(public_inputs_vec), calldata, returndata);
1524
+ // }
1525
+
1500
1526
// Positive test for L2GASLEFT opcode
1501
1527
TEST_F (AvmExecutionTests, l2GasLeft)
1502
1528
{
@@ -2110,43 +2136,10 @@ TEST_F(AvmExecutionTests, opCallOpcodes)
2110
2136
validate_trace (std::move (trace), public_inputs, calldata, returndata);
2111
2137
}
2112
2138
2113
- TEST_F (AvmExecutionTests, opGetContractInstanceOpcodes )
2139
+ TEST_F (AvmExecutionTests, opGetContractInstanceOpcode )
2114
2140
{
2115
- std::string bytecode_hex = to_hex (OpCode::SET_8) + // opcode SET
2116
- " 00" // Indirect flag
2117
- + to_hex (AvmMemoryTag::U32) +
2118
- " 00" // val
2119
- " 00" // dst_offset
2120
- + to_hex (OpCode::SET_8) + // opcode SET
2121
- " 00" // Indirect flag
2122
- + to_hex (AvmMemoryTag::U32) +
2123
- " 01" // val
2124
- " 01" +
2125
- to_hex (OpCode::CALLDATACOPY) + // opcode CALLDATACOPY for addr
2126
- " 00" // Indirect flag
2127
- " 0000" // cd_offset
2128
- " 0001" // copy_size
2129
- " 0001" // dst_offset, (i.e. where we store the addr)
2130
- + to_hex (OpCode::SET_8) + // opcode SET for the indirect dst offset
2131
- " 00" // Indirect flag
2132
- + to_hex (AvmMemoryTag::U32) +
2133
- " 03" // val i
2134
- " 02" + // dst_offset 2
2135
- to_hex (OpCode::GETCONTRACTINSTANCE) + // opcode CALL
2136
- " 02" // Indirect flag
2137
- " 00000001" // address offset
2138
- " 00000002" // dst offset
2139
- + to_hex (OpCode::RETURN) + // opcode RETURN
2140
- " 00" // Indirect flag
2141
- " 0003" // ret offset 3
2142
- " 0006" ; // ret size 6
2143
-
2144
- auto bytecode = hex_to_bytes (bytecode_hex);
2145
- auto instructions = Deserialization::parse (bytecode);
2146
-
2147
- FF address = 10 ;
2148
- std::vector<FF> calldata = { address };
2149
- std::vector<FF> returndata = {};
2141
+ const uint8_t address_byte = 0x42 ;
2142
+ const FF address (address_byte);
2150
2143
2151
2144
// Generate Hint for call operation
2152
2145
// Note: opcode does not write 'address' into memory
@@ -2158,14 +2151,96 @@ TEST_F(AvmExecutionTests, opGetContractInstanceOpcodes)
2158
2151
grumpkin::g1::affine_element::random_element (),
2159
2152
grumpkin::g1::affine_element::random_element (),
2160
2153
};
2161
- auto execution_hints =
2162
- ExecutionHints ().with_contract_instance_hints ({ { address, { address, 1 , 2 , 3 , 4 , 5 , public_keys_hints } } });
2154
+ const ContractInstanceHint instance = ContractInstanceHint{
2155
+ .address = address,
2156
+ .exists = true ,
2157
+ .salt = 2 ,
2158
+ .deployer_addr = 42 ,
2159
+ .contract_class_id = 66 ,
2160
+ .initialisation_hash = 99 ,
2161
+ .public_keys = public_keys_hints,
2162
+ };
2163
+ auto execution_hints = ExecutionHints ().with_contract_instance_hints ({ { address, instance } });
2164
+
2165
+ std::string bytecode_hex = to_hex (OpCode::SET_8) + // opcode SET
2166
+ " 00" // Indirect flag
2167
+ + to_hex (AvmMemoryTag::U8) + to_hex (address_byte) + // val
2168
+ " 01" // dst_offset 0
2169
+ + to_hex (OpCode::GETCONTRACTINSTANCE) + // opcode GETCONTRACTINSTANCE
2170
+ " 00" // Indirect flag
2171
+ + to_hex (static_cast <uint8_t >(ContractInstanceMember::DEPLOYER)) + // member enum
2172
+ " 0001" // address offset
2173
+ " 0010" // dst offset
2174
+ " 0011" // exists offset
2175
+ + to_hex (OpCode::GETCONTRACTINSTANCE) + // opcode GETCONTRACTINSTANCE
2176
+ " 00" // Indirect flag
2177
+ + to_hex (static_cast <uint8_t >(ContractInstanceMember::CLASS_ID)) + // member enum
2178
+ " 0001" // address offset
2179
+ " 0012" // dst offset
2180
+ " 0013" // exists offset
2181
+ + to_hex (OpCode::GETCONTRACTINSTANCE) + // opcode GETCONTRACTINSTANCE
2182
+ " 00" // Indirect flag
2183
+ + to_hex (static_cast <uint8_t >(ContractInstanceMember::INIT_HASH)) + // member enum
2184
+ " 0001" // address offset
2185
+ " 0014" // dst offset
2186
+ " 0015" // exists offset
2187
+ + to_hex (OpCode::RETURN) + // opcode RETURN
2188
+ " 00" // Indirect flag
2189
+ " 0010" // ret offset 1
2190
+ " 0006" ; // ret size 6 (dst & exists for all 3)
2191
+
2192
+ auto bytecode = hex_to_bytes (bytecode_hex);
2193
+ auto instructions = Deserialization::parse (bytecode);
2194
+
2195
+ ASSERT_THAT (instructions, SizeIs (5 ));
2196
+
2197
+ std::vector<FF> const calldata{};
2198
+ // alternating member value, exists bool
2199
+ std::vector<FF> const expected_returndata = {
2200
+ instance.deployer_addr , 1 , instance.contract_class_id , 1 , instance.initialisation_hash , 1 ,
2201
+ };
2163
2202
2203
+ std::vector<FF> returndata{};
2164
2204
auto trace = gen_trace (bytecode, calldata, public_inputs_vec, returndata, execution_hints);
2165
- EXPECT_EQ (returndata, std::vector<FF>({ 1 , 2 , 3 , 4 , 5 , returned_point.x })); // The first one represents true
2166
2205
2167
2206
validate_trace (std::move (trace), public_inputs, calldata, returndata);
2207
+
2208
+ // Validate returndata
2209
+ EXPECT_EQ (returndata, expected_returndata);
2168
2210
}
2211
+
2212
+ TEST_F (AvmExecutionTests, opGetContractInstanceOpcodeBadEnum)
2213
+ {
2214
+ const uint8_t address_byte = 0x42 ;
2215
+ const FF address (address_byte);
2216
+
2217
+ std::string bytecode_hex = to_hex (OpCode::SET_8) + // opcode SET
2218
+ " 00" // Indirect flag
2219
+ + to_hex (AvmMemoryTag::U8) + to_hex (address_byte) + // val
2220
+ " 01" // dst_offset 0
2221
+ + to_hex (OpCode::GETCONTRACTINSTANCE) + // opcode GETCONTRACTINSTANCE
2222
+ " 00" // Indirect flag
2223
+ + to_hex (static_cast <uint8_t >(ContractInstanceMember::MAX_MEMBER)) + // member enum
2224
+ " 0001" // address offset
2225
+ " 0010" // dst offset
2226
+ " 0011" ; // exists offset
2227
+
2228
+ auto bytecode = hex_to_bytes (bytecode_hex);
2229
+ auto instructions = Deserialization::parse (bytecode);
2230
+
2231
+ std::vector<FF> calldata;
2232
+ std::vector<FF> returndata;
2233
+ ExecutionHints execution_hints;
2234
+ auto trace = gen_trace (bytecode, calldata, public_inputs_vec, returndata, execution_hints);
2235
+
2236
+ // Bad enum should raise error flag
2237
+ auto address_row = std::ranges::find_if (
2238
+ trace.begin (), trace.end (), [](Row r) { return r.main_sel_op_get_contract_instance == 1 ; });
2239
+ EXPECT_EQ (address_row->main_op_err , FF (1 ));
2240
+
2241
+ validate_trace (std::move (trace), public_inputs, calldata, returndata);
2242
+ }
2243
+
2169
2244
// Negative test detecting an invalid opcode byte.
2170
2245
TEST_F (AvmExecutionTests, invalidOpcode)
2171
2246
{
0 commit comments