4#include <gmock/gmock.h>
5#include <gtest/gtest.h>
32using ::testing::Return;
33using ::testing::SizeIs;
34using ::testing::StrictMock;
41class MockContractInstanceManager :
public ContractInstanceManagerInterface {
46class BytecodeManagerTest :
public ::testing::Test {
67TEST_F(BytecodeManagerTest, RetrievalAndDeduplication)
95 EXPECT_CALL(
contract_db, get_contract_class(instance1.current_contract_class_id))
97 EXPECT_CALL(
contract_db, get_bytecode_commitment(instance1.current_contract_class_id))
101 EXPECT_CALL(
poseidon2, hash(_)).WillOnce(Return(bytecode_commitment));
103 TreeStates tree_states = {};
104 EXPECT_CALL(
merkle_db, get_tree_state()).WillOnce(Return(tree_states));
107 BytecodeId result1 = tx_bytecode_manager.get_bytecode(address1);
108 EXPECT_EQ(result1, bytecode_commitment);
113 EXPECT_THAT(retrieval_events_dump, SizeIs(1));
114 EXPECT_EQ(retrieval_events_dump[0].
address, address1);
115 EXPECT_EQ(retrieval_events_dump[0].bytecode_id, bytecode_commitment);
116 EXPECT_TRUE(retrieval_events_dump[0].is_new_class);
117 EXPECT_FALSE(retrieval_events_dump[0].error.has_value());
120 EXPECT_THAT(hashing_events_dump, SizeIs(1));
121 EXPECT_EQ(hashing_events_dump[0].bytecode_id, bytecode_commitment);
124 EXPECT_THAT(decomposition_events_dump, SizeIs(1));
125 EXPECT_EQ(decomposition_events_dump[0].bytecode_id, bytecode_commitment);
136 EXPECT_CALL(
contract_db, get_contract_class(instance1.current_contract_class_id))
141 EXPECT_CALL(
merkle_db, get_tree_state()).WillOnce(Return(tree_states));
144 BytecodeId result2 = tx_bytecode_manager.get_bytecode(address1);
145 EXPECT_EQ(result2, bytecode_commitment);
149 EXPECT_THAT(retrieval_events_dump, SizeIs(1));
150 EXPECT_EQ(retrieval_events_dump[0].
address, address1);
151 EXPECT_EQ(retrieval_events_dump[0].bytecode_id, bytecode_commitment);
152 EXPECT_FALSE(retrieval_events_dump[0].is_new_class);
154 EXPECT_THAT(hashing_events_dump, SizeIs(0));
156 EXPECT_THAT(decomposition_events_dump, SizeIs(0));
161 instance2.current_contract_class_id = instance1.current_contract_class_id + 1;
171 EXPECT_CALL(
contract_db, get_contract_class(instance2.current_contract_class_id))
173 EXPECT_CALL(
contract_db, get_bytecode_commitment(instance2.current_contract_class_id))
176 EXPECT_CALL(
merkle_db, get_tree_state()).WillOnce(Return(tree_states));
179 BytecodeId result3 = tx_bytecode_manager.get_bytecode(address2);
180 EXPECT_EQ(result3, bytecode_commitment);
184 EXPECT_THAT(retrieval_events_dump, SizeIs(1));
185 EXPECT_EQ(retrieval_events_dump[0].
address, address2);
186 EXPECT_EQ(retrieval_events_dump[0].bytecode_id, bytecode_commitment);
187 EXPECT_FALSE(retrieval_events_dump[0].is_new_class);
189 EXPECT_THAT(hashing_events_dump, SizeIs(0));
191 EXPECT_THAT(decomposition_events_dump, SizeIs(0));
194TEST_F(BytecodeManagerTest, TooManyBytecodes)
211 EXPECT_CALL(
merkle_db, get_tree_state());
221 "Can't retrieve more than " +
225 EXPECT_THAT(retrieval_events_dump, SizeIs(1));
226 EXPECT_EQ(retrieval_events_dump[0].
address, address1);
227 EXPECT_EQ(retrieval_events_dump[0].bytecode_id, 0);
232TEST_F(BytecodeManagerTest, ContractAddressNullifierNotFoundError)
235 StrictMock<MockFieldGreaterThan>
field_gt;
236 ProtocolContracts protocol_contracts = {};
237 EventEmitter<ContractInstanceRetrievalEvent> contract_retrieval_events;
239 ContractInstanceManager real_contract_instance_manager(
246 real_contract_instance_manager,
257 EXPECT_CALL(
merkle_db, get_tree_state()).Times(2);
259 .WillOnce(Return(
false));
265 EXPECT_THAT(retrieval_events_dump, SizeIs(1));
267 EXPECT_EQ(retrieval_events_dump[0].bytecode_id, 0);
270 auto contract_retrieval_events_dump = contract_retrieval_events.dump_events();
271 EXPECT_THAT(contract_retrieval_events_dump, SizeIs(1));
273 EXPECT_FALSE(contract_retrieval_events_dump[0].
exists);
274 EXPECT_FALSE(contract_retrieval_events_dump[0].is_protocol_contract);
275 EXPECT_EQ(contract_retrieval_events_dump[0].deployment_nullifier,
address);
276 EXPECT_EQ(contract_retrieval_events_dump[0].contract_instance, ContractInstance{});
279TEST_F(BytecodeManagerTest, InstructionFetching)
294 .addressing_mode = 3,
295 .operands = { Operand::from<uint8_t>(0x34), Operand::from<uint8_t>(0x35), Operand::from<uint8_t>(0x36) },
298 std::vector<uint8_t>
bytecode = add_8_instruction.serialize();
305 Instruction result = tx_bytecode_manager.read_instruction(
310 EXPECT_EQ(result.addressing_mode, add_8_instruction.addressing_mode);
311 ASSERT_THAT(result.operands, SizeIs(3));
312 EXPECT_EQ(result.operands[0], add_8_instruction.operands[0]);
313 EXPECT_EQ(result.operands[1], add_8_instruction.operands[1]);
314 EXPECT_EQ(result.operands[2], add_8_instruction.operands[2]);
318 ASSERT_THAT(fetching_events_dump, SizeIs(1));
319 EXPECT_EQ(fetching_events_dump[0].bytecode_id, bytecode_commitment);
320 EXPECT_EQ(fetching_events_dump[0].pc, pc);
321 EXPECT_FALSE(fetching_events_dump[0].error.has_value());
329 "Instruction fetching error: .*");
337 "Instruction fetching error: .*");
341 bytecode[0] =
static_cast<uint8_t
>(add_8_instruction.opcode);
342 pc =
static_cast<PC>(
bytecode.size() - add_8_instruction.size_in_bytes() + 1);
346 "Instruction fetching error: .*");
353 .addressing_mode = 0,
354 .operands = { Operand::from<uint16_t>(0x1234),
356 Operand::from<uint16_t>(0x5678) },
360 bytecode = set_16_instruction.serialize();
364 "Instruction fetching error.*");
367 ASSERT_THAT(fetching_events_dump, SizeIs(4));
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
std::shared_ptr< Napi::ThreadSafeFunction > instance
std::shared_ptr< Napi::ThreadSafeFunction > bytecode
#define MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS
#define AVM_PC_SIZE_IN_BITS
#define MAX_PROTOCOL_CONTRACTS
#define CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS
FieldGreaterThan field_gt
RetrievedBytecodesTreeCheck retrieved_bytecodes_tree_check
BytecodeHasher bytecode_hasher
EventEmitter< BytecodeHashingEvent > hashing_events
EventEmitter< BytecodeDecompositionEvent > decomposition_events
StrictMock< MockHighLevelMerkleDB > merkle_db
EventEmitter< InstructionFetchingEvent > instruction_fetching_events
EventEmitter< BytecodeRetrievalEvent > retrieval_events
StrictMock< MockClassIdDerivation > class_id_derivation
StrictMock< MockContractDB > contract_db
StrictMock< MockContractInstanceManager > contract_instance_manager
Native Poseidon2 hash function implementation.
StrictMock< MockUpdateCheck > update_check
AVM range check gadget for witness generation.
@ INSTRUCTION_OUT_OF_RANGE
ContractClass random_contract_class(size_t bytecode_size)
ContractInstance random_contract_instance()
std::string field_to_string(const FF &ff)
TEST_F(IPATest, ChallengesAreZero)
Instruction
Enumeration of VM instructions that can be executed.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
static field random_element(numeric::RNG *engine=nullptr) noexcept