3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
47using ::testing::NiceMock;
48using ::testing::Return;
49using ::testing::ReturnRef;
50using ::testing::StrictMock;
51using ::testing::Throw;
54class TestingExecution :
public Execution {
56 using Execution::Execution;
58 void set_gas_tracker(GasTrackerInterface& gas_tracker) { this->testing_gas_tracker = &gas_tracker; }
60 GasTrackerInterface& get_gas_tracker()
override {
return *testing_gas_tracker; }
63 GasTrackerInterface* testing_gas_tracker;
66class ExecutionSimulationTest :
public ::testing::Test {
68 ExecutionSimulationTest()
70 ON_CALL(
context, get_memory).WillByDefault(ReturnRef(
memory));
71 ON_CALL(
context, get_bytecode_manager).WillByDefault(ReturnRef(bytecode_manager));
75 StrictMock<MockAlu> alu;
76 StrictMock<MockBitwise>
bitwise;
77 StrictMock<MockMemory>
memory;
78 StrictMock<MockExecutionComponentsProvider> execution_components;
79 StrictMock<MockContext>
context;
81 StrictMock<MockInternalCallStackManager> internal_call_stack_manager;
82 StrictMock<MockKeccakF1600> keccakf1600;
83 StrictMock<MockGetContractInstance> get_contract_instance;
84 EventEmitter<ExecutionEvent> execution_event_emitter;
85 EventEmitter<ContextStackEvent> context_stack_event_emitter;
89 StrictMock<MockGasTracker> gas_tracker;
90 StrictMock<MockHighLevelMerkleDB>
merkle_db;
93 StrictMock<MockEcc> ecc;
94 StrictMock<MockToRadix> to_radix;
95 StrictMock<MockEmitUnencryptedLog> emit_unencrypted_log;
96 StrictMock<MockBytecodeManager> bytecode_manager;
97 StrictMock<MockSha256>
sha256;
98 StrictMock<MockDebugLog> debug_log;
99 TestingExecution
execution = TestingExecution(alu,
106 execution_components,
110 execution_event_emitter,
111 context_stack_event_emitter,
114 get_contract_instance,
115 emit_unencrypted_log,
123TEST_F(ExecutionSimulationTest, Add)
128 EXPECT_CALL(context, get_memory);
129 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
130 EXPECT_CALL(alu, add(
a,
b)).WillOnce(Return(MemoryValue::from<uint32_t>(9)));
131 EXPECT_CALL(memory, set(6, MemoryValue::from<uint32_t>(9)));
132 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
137TEST_F(ExecutionSimulationTest, Sub)
142 EXPECT_CALL(context, get_memory);
143 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
144 EXPECT_CALL(alu, sub(
a,
b)).WillOnce(Return(MemoryValue::from<uint64_t>(2)));
145 EXPECT_CALL(memory, set(3, MemoryValue::from<uint64_t>(2)));
146 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
151TEST_F(ExecutionSimulationTest, Mul)
154 auto a = MemoryValue::from<uint128_t>(max);
155 auto b = MemoryValue::from<uint128_t>(max - 3);
157 EXPECT_CALL(context, get_memory);
158 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
159 EXPECT_CALL(alu, mul(
a,
b)).WillOnce(Return(MemoryValue::from<uint128_t>(4)));
160 EXPECT_CALL(memory, set(3, MemoryValue::from<uint128_t>(4)));
161 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
166TEST_F(ExecutionSimulationTest, Div)
168 auto a = MemoryValue::from<uint128_t>(6);
169 auto b = MemoryValue::from<uint128_t>(3);
171 EXPECT_CALL(context, get_memory);
172 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
173 EXPECT_CALL(alu, div(
a,
b)).WillOnce(Return(MemoryValue::from<uint128_t>(2)));
174 EXPECT_CALL(memory, set(3, MemoryValue::from<uint128_t>(2)));
175 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
180TEST_F(ExecutionSimulationTest, FDiv)
182 auto a = MemoryValue::from<FF>(FF::modulus - 4);
183 auto b = MemoryValue::from<FF>(2);
185 EXPECT_CALL(context, get_memory);
186 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
187 EXPECT_CALL(alu, fdiv(
a,
b)).WillOnce(Return(MemoryValue::from<FF>(FF::modulus - 2)));
188 EXPECT_CALL(memory, set(3, MemoryValue::from<FF>(FF::modulus - 2)));
189 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
194TEST_F(ExecutionSimulationTest, Shl)
196 auto a = MemoryValue::from<uint32_t>(64);
197 auto b = MemoryValue::from<uint32_t>(2);
199 EXPECT_CALL(context, get_memory);
200 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
201 EXPECT_CALL(alu,
shl(
a,
b)).WillOnce(Return(MemoryValue::from<uint32_t>(256)));
202 EXPECT_CALL(memory, set(3, MemoryValue::from<uint32_t>(256)));
203 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
208TEST_F(ExecutionSimulationTest, Shr)
210 auto a = MemoryValue::from<uint64_t>(64);
211 auto b = MemoryValue::from<uint64_t>(2);
213 EXPECT_CALL(context, get_memory);
214 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
215 EXPECT_CALL(alu,
shr(
a,
b)).WillOnce(Return(MemoryValue::from<uint64_t>(16)));
216 EXPECT_CALL(memory, set(3, MemoryValue::from<uint64_t>(16)));
217 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
224TEST_F(ExecutionSimulationTest, Call)
229 MemoryValue nested_address_value = MemoryValue::from<FF>(nested_address);
230 MemoryValue l2_gas_allocated = MemoryValue::from<uint32_t>(6);
231 MemoryValue da_gas_allocated = MemoryValue::from<uint32_t>(7);
232 MemoryValue cd_size = MemoryValue::from<uint32_t>(8);
233 AppendOnlyTreeSnapshot written_public_data_slots_tree_snapshot = AppendOnlyTreeSnapshot{
235 .nextAvailableLeafIndex = 10,
237 TreeStates tree_states = TreeStates {
241 .nextAvailableLeafIndex = 9,
248 .nextAvailableLeafIndex = 6,
252 .l1ToL2MessageTree = {
255 .nextAvailableLeafIndex = 3,
262 .nextAvailableLeafIndex = 1,
268 SideEffectStates side_effect_states = SideEffectStates{ .numUnencryptedLogFields = 1, .numL2ToL1Messages = 2 };
270 EXPECT_CALL(gas_tracker, compute_gas_limit_for_call(Gas{ 6, 7 })).WillOnce(Return(Gas{ 2, 3 }));
271 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
274 EXPECT_CALL(context, get_context_id);
275 EXPECT_CALL(context, get_parent_id);
276 EXPECT_CALL(context, get_bytecode_manager).WillOnce(ReturnRef(bytecode_manager));
277 EXPECT_CALL(bytecode_manager, get_retrieved_bytecode_id).WillOnce(Return(
FF(1)));
278 EXPECT_CALL(context, get_next_pc);
279 EXPECT_CALL(context, get_is_static).WillRepeatedly(Return(
false));
280 EXPECT_CALL(context, get_msg_sender).WillOnce(ReturnRef(parent_address));
281 EXPECT_CALL(context, get_transaction_fee).WillOnce(ReturnRef(zero));
282 EXPECT_CALL(context, get_parent_cd_addr);
283 EXPECT_CALL(context, get_parent_cd_size);
284 EXPECT_CALL(context, get_parent_gas_used);
285 EXPECT_CALL(context, get_parent_gas_limit);
286 EXPECT_CALL(context, get_written_public_data_slots_tree_snapshot)
287 .WillOnce(Return(written_public_data_slots_tree_snapshot));
288 EXPECT_CALL(context, get_side_effect_states).WillRepeatedly(ReturnRef(side_effect_states));
292 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_states));
294 EXPECT_CALL(context, get_memory);
295 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(parent_address));
296 EXPECT_CALL(memory,
get(1)).WillOnce(ReturnRef(l2_gas_allocated));
297 EXPECT_CALL(memory,
get(2)).WillOnce(ReturnRef(da_gas_allocated));
298 EXPECT_CALL(memory,
get(3)).WillOnce(ReturnRef(nested_address_value));
299 EXPECT_CALL(memory,
get(4)).WillOnce(ReturnRef(cd_size));
302 ON_CALL(*nested_context, halted())
303 .WillByDefault(Return(
true));
306 make_nested_context(nested_address,
316 .WillOnce(Return(
std::move(nested_context)));
327TEST_F(ExecutionSimulationTest, ExternalCallStaticnessPropagation)
333 MemoryValue nested_address_value = MemoryValue::from<FF>(nested_address);
334 MemoryValue l2_gas_allocated = MemoryValue::from<uint32_t>(6);
335 MemoryValue da_gas_allocated = MemoryValue::from<uint32_t>(7);
336 MemoryValue cd_size = MemoryValue::from<uint32_t>(8);
337 AppendOnlyTreeSnapshot written_public_data_slots_tree_snapshot = AppendOnlyTreeSnapshot{
339 .nextAvailableLeafIndex = 10,
341 TreeStates tree_states =
342 TreeStates{ .noteHashTree = { .tree = { .root = 10, .nextAvailableLeafIndex = 9 }, .counter = 8 },
343 .nullifierTree = { .tree = { .root = 7, .nextAvailableLeafIndex = 6 }, .counter = 5 },
344 .l1ToL2MessageTree = { .tree = { .root = 4, .nextAvailableLeafIndex = 3 }, .counter = 0 },
345 .publicDataTree = { .tree = { .root = 2, .nextAvailableLeafIndex = 1 }, .counter = 1 } };
346 SideEffectStates side_effect_states = SideEffectStates{ .numUnencryptedLogFields = 1, .numL2ToL1Messages = 2 };
348 auto setup_context_expectations = [&](
bool parent_is_static) {
349 EXPECT_CALL(gas_tracker, compute_gas_limit_for_call(Gas{ 6, 7 })).WillOnce(Return(Gas{ 2, 3 }));
350 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
351 EXPECT_CALL(context, get_context_id);
352 EXPECT_CALL(context, get_parent_id);
353 EXPECT_CALL(context, get_bytecode_manager).WillOnce(ReturnRef(bytecode_manager));
354 EXPECT_CALL(bytecode_manager, get_retrieved_bytecode_id).WillOnce(Return(
FF(1)));
355 EXPECT_CALL(context, get_next_pc);
356 EXPECT_CALL(context, get_is_static).WillRepeatedly(Return(parent_is_static));
357 EXPECT_CALL(context, get_msg_sender).WillOnce(ReturnRef(parent_address));
358 EXPECT_CALL(context, get_transaction_fee).WillOnce(ReturnRef(zero));
359 EXPECT_CALL(context, get_parent_cd_addr);
360 EXPECT_CALL(context, get_parent_cd_size);
361 EXPECT_CALL(context, get_parent_gas_used);
362 EXPECT_CALL(context, get_parent_gas_limit);
363 EXPECT_CALL(context, get_written_public_data_slots_tree_snapshot)
364 .WillOnce(Return(written_public_data_slots_tree_snapshot));
365 EXPECT_CALL(context, get_side_effect_states).WillRepeatedly(ReturnRef(side_effect_states));
367 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_states));
368 EXPECT_CALL(context, get_memory);
369 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(parent_address));
370 EXPECT_CALL(memory,
get(1)).WillOnce(ReturnRef(l2_gas_allocated));
371 EXPECT_CALL(memory,
get(2)).WillOnce(ReturnRef(da_gas_allocated));
372 EXPECT_CALL(memory,
get(3)).WillOnce(ReturnRef(nested_address_value));
373 EXPECT_CALL(memory,
get(4)).WillOnce(ReturnRef(cd_size));
376 auto create_nested_context = []() {
378 ON_CALL(*nested, halted()).WillByDefault(Return(
true));
383 setup_context_expectations(
false);
385 make_nested_context(nested_address,
395 .WillOnce(Return(create_nested_context()));
399 setup_context_expectations(
false);
401 make_nested_context(nested_address,
411 .WillOnce(Return(create_nested_context()));
412 execution.static_call(context, 1, 2, 3, 4, 5);
415 setup_context_expectations(
true);
417 make_nested_context(nested_address,
427 .WillOnce(Return(create_nested_context()));
431 setup_context_expectations(
true);
433 make_nested_context(nested_address,
443 .WillOnce(Return(create_nested_context()));
444 execution.static_call(context, 1, 2, 3, 4, 5);
447TEST_F(ExecutionSimulationTest, InternalCall)
449 uint32_t return_pc = 500;
450 uint32_t pc_loc = 11;
452 NiceMock<MockInternalCallStackManager> internal_call_stack_manager;
453 ON_CALL(context, get_internal_call_stack_manager).WillByDefault(ReturnRef(internal_call_stack_manager));
457 EXPECT_CALL(context, get_internal_call_stack_manager());
459 EXPECT_CALL(context, get_next_pc()).WillOnce(Return(return_pc));
460 EXPECT_CALL(internal_call_stack_manager, push(return_pc));
462 EXPECT_CALL(context, set_next_pc(pc_loc));
463 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
465 execution.internal_call(context, pc_loc);
469 EXPECT_CALL(context, get_internal_call_stack_manager());
471 EXPECT_CALL(internal_call_stack_manager, pop()).WillOnce(Return(return_pc));
473 EXPECT_CALL(context, set_next_pc(return_pc));
474 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
479TEST_F(ExecutionSimulationTest, GetEnvVarAddress)
482 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(addr));
483 EXPECT_CALL(context, get_memory);
484 EXPECT_CALL(memory, set(1, MemoryValue::from<FF>(addr)));
485 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
490TEST_F(ExecutionSimulationTest, GetEnvVarChainId)
492 GlobalVariables globals;
494 EXPECT_CALL(context, get_globals).WillOnce(ReturnRef(globals));
495 EXPECT_CALL(context, get_memory);
496 EXPECT_CALL(memory, set(1, MemoryValue::from<FF>(1)));
497 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
502TEST_F(ExecutionSimulationTest, GetEnvVarIsStaticCall)
504 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
505 EXPECT_CALL(context, get_memory);
506 EXPECT_CALL(memory, set(1, MemoryValue::from<uint1_t>(1)));
507 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
512TEST_F(ExecutionSimulationTest, GetEnvVarInvalidEnum)
514 EXPECT_CALL(context, get_memory);
515 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
517 EXPECT_THROW(
execution.get_env_var(context, 1, 255), std::runtime_error);
523TEST_F(ExecutionSimulationTest, Jump)
525 EXPECT_CALL(context, set_next_pc(120));
526 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
531TEST_F(ExecutionSimulationTest, SuccessCopyTrue)
533 EXPECT_CALL(context, get_memory);
534 EXPECT_CALL(context, get_last_success).WillOnce(Return(
true));
535 EXPECT_CALL(memory, set(10, MemoryValue::from<uint1_t>(1)));
536 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
541TEST_F(ExecutionSimulationTest, SuccessCopyFalse)
543 EXPECT_CALL(context, get_memory);
544 EXPECT_CALL(context, get_last_success).WillOnce(Return(
false));
545 EXPECT_CALL(memory, set(10, MemoryValue::from<uint1_t>(0)));
546 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
551TEST_F(ExecutionSimulationTest, RdSize)
553 EXPECT_CALL(context, get_memory);
554 EXPECT_CALL(context, get_last_rd_size).WillOnce(Return(42));
555 EXPECT_CALL(memory, set(10, MemoryValue::from<uint32_t>(42)));
556 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
561TEST_F(ExecutionSimulationTest, DebugLog)
568 uint16_t message_size = 5;
571 EXPECT_CALL(context, get_memory);
572 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(address));
573 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
574 EXPECT_CALL(debug_log,
575 debug_log(_, address, level_offset, message_offset, message_size, fields_offset, fields_size_offset));
577 execution.debug_log(context, level_offset, message_offset, fields_offset, fields_size_offset, message_size);
580TEST_F(ExecutionSimulationTest, Sload)
585 auto slot = MemoryValue::from<FF>(42);
587 EXPECT_CALL(context, get_memory);
589 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
590 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(address));
591 EXPECT_CALL(
merkle_db, storage_read(address,
slot.as<
FF>())).WillOnce(Return(7));
593 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<FF>(7)));
594 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
599TEST_F(ExecutionSimulationTest, SStore)
604 auto slot = MemoryValue::from<FF>(42);
605 auto value = MemoryValue::from<FF>(7);
606 TreeStates tree_state = {};
607 EXPECT_CALL(context, get_memory);
609 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
610 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
611 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
612 EXPECT_CALL(
merkle_db, was_storage_written(address,
slot.as<
FF>())).WillOnce(Return(
false));
613 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
614 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 1 }));
616 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
620 execution.sstore(context, value_addr, slot_addr);
623TEST_F(ExecutionSimulationTest, SStoreDuringStaticCall)
628 auto slot = MemoryValue::from<FF>(42);
629 auto value = MemoryValue::from<FF>(7);
630 EXPECT_CALL(context, get_memory);
632 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
633 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
634 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
635 EXPECT_CALL(
merkle_db, was_storage_written(address,
slot.as<
FF>())).WillOnce(Return(
false));
636 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 1 }));
638 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
640 "SSTORE: Cannot write to storage in static context");
643TEST_F(ExecutionSimulationTest, SStoreLimitReached)
648 auto slot = MemoryValue::from<FF>(42);
649 auto value = MemoryValue::from<FF>(7);
650 TreeStates tree_state = {};
652 EXPECT_CALL(context, get_memory);
654 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
655 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
656 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
657 EXPECT_CALL(
merkle_db, was_storage_written(address,
slot.as<
FF>())).WillOnce(Return(
false));
658 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
659 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 1 }));
661 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
664 "SSTORE: Maximum number of data writes reached");
667TEST_F(ExecutionSimulationTest, SStoreLimitReachedSquashed)
672 auto slot = MemoryValue::from<FF>(42);
673 auto value = MemoryValue::from<FF>(7);
674 TreeStates tree_state = {};
676 EXPECT_CALL(context, get_memory);
678 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
679 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
680 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
682 EXPECT_CALL(
merkle_db, was_storage_written(address,
slot.as<
FF>())).WillOnce(Return(
true));
683 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
685 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
689 execution.sstore(context, value_addr, slot_addr);
692TEST_F(ExecutionSimulationTest, NoteHashExists)
698 auto unique_note_hash = MemoryValue::from<FF>(42);
699 auto leaf_index = MemoryValue::from<uint64_t>(7);
701 EXPECT_CALL(context, get_memory);
702 EXPECT_CALL(memory,
get(unique_note_hash_addr)).WillOnce(ReturnRef(unique_note_hash));
703 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
705 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
709 EXPECT_CALL(
merkle_db, note_hash_exists(leaf_index.as<uint64_t>(), unique_note_hash.as<
FF>()))
710 .WillOnce(Return(
true));
712 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(1)));
714 execution.note_hash_exists(context, unique_note_hash_addr, leaf_index_addr,
dst_addr);
717TEST_F(ExecutionSimulationTest, NoteHashExistsOutOfRange)
723 auto unique_note_hash = MemoryValue::from<FF>(42);
726 EXPECT_CALL(context, get_memory);
727 EXPECT_CALL(memory,
get(unique_note_hash_addr)).WillOnce(ReturnRef(unique_note_hash));
728 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
730 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
734 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(0)));
736 execution.note_hash_exists(context, unique_note_hash_addr, leaf_index_addr,
dst_addr);
739TEST_F(ExecutionSimulationTest, EmitNoteHash)
743 auto note_hash = MemoryValue::from<FF>(42);
745 TreeStates tree_state = {};
747 EXPECT_CALL(context, get_memory);
748 EXPECT_CALL(memory,
get(note_hash_addr)).WillOnce(ReturnRef(note_hash));
749 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
751 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
753 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
754 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
755 EXPECT_CALL(
merkle_db, note_hash_write(address, note_hash.as<
FF>()));
757 execution.emit_note_hash(context, note_hash_addr);
760TEST_F(ExecutionSimulationTest, EmitNoteHashDuringStaticCall)
764 auto note_hash = MemoryValue::from<FF>(42);
767 EXPECT_CALL(context, get_memory);
768 EXPECT_CALL(memory,
get(note_hash_addr)).WillOnce(ReturnRef(note_hash));
769 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
771 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
773 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
775 "EMITNOTEHASH: Cannot emit note hash in static context");
778TEST_F(ExecutionSimulationTest, EmitNoteHashLimitReached)
782 auto note_hash = MemoryValue::from<FF>(42);
784 TreeStates tree_state = {};
787 EXPECT_CALL(context, get_memory);
788 EXPECT_CALL(memory,
get(note_hash_addr)).WillOnce(ReturnRef(note_hash));
789 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
791 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
793 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
794 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
797 "EMITNOTEHASH: Maximum number of note hashes reached");
800TEST_F(ExecutionSimulationTest, L1ToL2MessageExists)
806 auto msg_hash = MemoryValue::from<FF>(42);
807 auto leaf_index = MemoryValue::from<uint64_t>(7);
809 EXPECT_CALL(context, get_memory);
810 EXPECT_CALL(memory,
get(msg_hash_addr)).WillOnce(ReturnRef(msg_hash));
811 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
813 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
817 EXPECT_CALL(
merkle_db, l1_to_l2_msg_exists(leaf_index.as<uint64_t>(), msg_hash.as<
FF>())).WillOnce(Return(
true));
819 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(1)));
821 execution.l1_to_l2_message_exists(context, msg_hash_addr, leaf_index_addr,
dst_addr);
824TEST_F(ExecutionSimulationTest, L1ToL2MessageExistsOutOfRange)
830 auto msg_hash = MemoryValue::from<FF>(42);
833 EXPECT_CALL(context, get_memory);
834 EXPECT_CALL(memory,
get(msg_hash_addr)).WillOnce(ReturnRef(msg_hash));
835 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
837 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
841 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(0)));
843 execution.l1_to_l2_message_exists(context, msg_hash_addr, leaf_index_addr,
dst_addr);
846TEST_F(ExecutionSimulationTest, NullifierExists)
852 auto nullifier = MemoryValue::from<FF>(42);
853 auto address = MemoryValue::from<FF>(7);
855 EXPECT_CALL(context, get_memory);
856 EXPECT_CALL(memory,
get(nullifier_offset)).WillOnce(ReturnRef(
nullifier));
857 EXPECT_CALL(memory,
get(address_offset)).WillOnce(ReturnRef(address));
859 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
861 EXPECT_CALL(
merkle_db, nullifier_exists(address.as_ff(),
nullifier.as_ff())).WillOnce(Return(
true));
863 EXPECT_CALL(memory, set(exists_offset, MemoryValue::from<uint1_t>(1)));
865 execution.nullifier_exists(context, nullifier_offset, address_offset, exists_offset);
868TEST_F(ExecutionSimulationTest, EmitNullifier)
872 auto nullifier = MemoryValue::from<FF>(42);
874 TreeStates tree_state = {};
876 EXPECT_CALL(context, get_memory);
877 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
878 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
880 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
882 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
883 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
884 EXPECT_CALL(
merkle_db, nullifier_write(address,
nullifier.as_ff())).WillOnce(Return());
886 execution.emit_nullifier(context, nullifier_addr);
889TEST_F(ExecutionSimulationTest, EmitNullifierDuringStaticCall)
893 auto nullifier = MemoryValue::from<FF>(42);
896 EXPECT_CALL(context, get_memory);
897 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
898 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
900 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
902 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
904 "EMITNULLIFIER: Cannot emit nullifier in static context");
907TEST_F(ExecutionSimulationTest, EmitNullifierLimitReached)
911 auto nullifier = MemoryValue::from<FF>(42);
913 TreeStates tree_state = {};
916 EXPECT_CALL(context, get_memory);
917 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
918 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
920 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
922 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
923 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
926 "EMITNULLIFIER: Maximum number of nullifiers reached");
929TEST_F(ExecutionSimulationTest, EmitNullifierCollision)
933 auto nullifier = MemoryValue::from<FF>(42);
935 TreeStates tree_state = {};
937 EXPECT_CALL(context, get_memory);
938 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
939 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(address));
941 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
943 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
944 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
946 .WillOnce(Throw(NullifierCollisionException(
"Nullifier collision")));
951TEST_F(ExecutionSimulationTest, Set)
957 EXPECT_CALL(context, get_memory);
958 EXPECT_CALL(alu, truncate(
value,
static_cast<MemoryTag>(
dst_tag))).WillOnce(Return(MemoryValue::from<uint8_t>(7)));
959 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint8_t>(7)));
960 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
965TEST_F(ExecutionSimulationTest, Cast)
972 EXPECT_CALL(context, get_memory).WillOnce(ReturnRef(memory));
973 EXPECT_CALL(memory,
get(src_addr)).WillOnce(ReturnRef(
value));
976 .WillOnce(Return(MemoryValue::from<uint1_t>(1)));
977 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(1)));
978 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
988 EXPECT_CALL(context, get_memory);
989 EXPECT_CALL(gas_tracker, consume_gas);
990 EXPECT_CALL(
poseidon2, permutation(_, src_address, dst_address));
992 execution.poseidon2_permutation(context, src_address, dst_address);
995TEST_F(ExecutionSimulationTest, EccAdd)
1005 MemoryValue p_x = MemoryValue::from<FF>(
FF(
"0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"));
1006 MemoryValue p_y = MemoryValue::from<FF>(
FF(
"0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"));
1009 MemoryValue q_x = MemoryValue::from<FF>(
FF(
"0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"));
1010 MemoryValue q_y = MemoryValue::from<FF>(
FF(
"0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"));
1015 EXPECT_CALL(context, get_memory).WillRepeatedly(ReturnRef(memory));
1016 EXPECT_CALL(Const(memory),
get(p_x_addr)).WillOnce(ReturnRef(p_x));
1017 EXPECT_CALL(memory,
get(p_y_addr)).WillOnce(ReturnRef(p_y));
1018 EXPECT_CALL(memory,
get(p_is_inf_addr)).WillOnce(ReturnRef(zero));
1019 EXPECT_CALL(memory,
get(q_x_addr)).WillOnce(ReturnRef(q_x));
1020 EXPECT_CALL(memory,
get(q_y_addr)).WillOnce(ReturnRef(q_y));
1021 EXPECT_CALL(memory,
get(q_is_inf_addr)).WillOnce(ReturnRef(zero));
1023 EXPECT_CALL(gas_tracker, consume_gas);
1026 EXPECT_CALL(ecc, add(_, _, _,
dst_addr));
1029 execution.ecc_add(context, p_x_addr, p_y_addr, p_is_inf_addr, q_x_addr, q_y_addr, q_is_inf_addr,
dst_addr);
1032TEST_F(ExecutionSimulationTest, ToRadixBE)
1041 MemoryValue radix = MemoryValue::from<uint32_t>(16);
1043 MemoryValue::from<uint8_t>(0x55),
1044 MemoryValue::from<uint8_t>(0x00) };
1045 MemoryValue num_limbs = MemoryValue::from<uint32_t>(3);
1046 MemoryValue is_output_bits = MemoryValue::from<uint1_t>(
false);
1047 uint32_t num_p_limbs = 64;
1049 EXPECT_CALL(context, get_memory).WillOnce(ReturnRef(memory));
1050 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
1051 EXPECT_CALL(memory,
get(radix_addr)).WillOnce(ReturnRef(radix));
1052 EXPECT_CALL(memory,
get(num_limbs_addr)).WillOnce(ReturnRef(num_limbs));
1053 EXPECT_CALL(memory,
get(is_output_bits_addr)).WillOnce(ReturnRef(is_output_bits));
1055 EXPECT_CALL(greater_than,
gt(radix.as<uint32_t>(), 256)).WillOnce(Return(
false));
1056 EXPECT_CALL(greater_than,
gt(num_limbs.as<uint32_t>(), num_p_limbs)).WillOnce(Return(
false));
1058 EXPECT_CALL(gas_tracker, consume_gas);
1059 EXPECT_CALL(to_radix, to_be_radix);
1061 execution.to_radix_be(context, value_addr, radix_addr, num_limbs_addr, is_output_bits_addr,
dst_addr);
1064TEST_F(ExecutionSimulationTest, EmitUnencryptedLog)
1068 MemoryValue log_size = MemoryValue::from<uint32_t>(10);
1071 EXPECT_CALL(context, get_memory);
1072 EXPECT_CALL(memory,
get(log_size_offset)).WillOnce(ReturnRef(log_size));
1074 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(address));
1076 EXPECT_CALL(emit_unencrypted_log, emit_unencrypted_log(_, _, address, log_offset, log_size.as<uint32_t>()));
1078 EXPECT_CALL(gas_tracker, consume_gas(Gas{ log_size.as<uint32_t>(), log_size.as<uint32_t>() }));
1080 execution.emit_unencrypted_log(context, log_size_offset, log_offset);
1083TEST_F(ExecutionSimulationTest, SendL2ToL1Msg)
1088 auto recipient = MemoryValue::from<FF>(42);
1089 auto content = MemoryValue::from<FF>(27);
1091 SideEffectStates side_effects_states = {};
1093 SideEffectStates side_effects_states_after = side_effects_states;
1094 side_effects_states_after.numL2ToL1Messages++;
1096 EXPECT_CALL(context, get_memory);
1098 EXPECT_CALL(memory,
get(recipient_addr)).WillOnce(ReturnRef(recipient));
1099 EXPECT_CALL(memory,
get(content_addr)).WillOnce(ReturnRef(content));
1101 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1103 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
1105 EXPECT_CALL(context, get_side_effect_states).WillOnce(ReturnRef(side_effects_states));
1106 EXPECT_CALL(context, set_side_effect_states(side_effects_states_after));
1108 execution.send_l2_to_l1_msg(context, recipient_addr, content_addr);
1111TEST_F(ExecutionSimulationTest, SendL2ToL1MsgStaticCall)
1116 auto recipient = MemoryValue::from<FF>(42);
1117 auto content = MemoryValue::from<FF>(27);
1119 SideEffectStates side_effects_states = {};
1122 EXPECT_CALL(context, get_memory);
1124 EXPECT_CALL(memory,
get(recipient_addr)).WillOnce(ReturnRef(recipient));
1125 EXPECT_CALL(memory,
get(content_addr)).WillOnce(ReturnRef(content));
1127 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1129 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
1131 EXPECT_CALL(context, get_side_effect_states).WillOnce(ReturnRef(side_effects_states));
1134 "SENDL2TOL1MSG: Cannot send L2 to L1 message in static context");
1137TEST_F(ExecutionSimulationTest, SendL2ToL1MsgLimitReached)
1142 auto recipient = MemoryValue::from<FF>(42);
1143 auto content = MemoryValue::from<FF>(27);
1145 SideEffectStates side_effects_states = {};
1148 EXPECT_CALL(context, get_memory);
1150 EXPECT_CALL(memory,
get(recipient_addr)).WillOnce(ReturnRef(recipient));
1151 EXPECT_CALL(memory,
get(content_addr)).WillOnce(ReturnRef(content));
1153 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1155 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
1157 EXPECT_CALL(context, get_side_effect_states).WillOnce(ReturnRef(side_effects_states));
1160 "SENDL2TOL1MSG: Maximum number of L2 to L1 messages reached");
1163TEST_F(ExecutionSimulationTest, Sha256Compression)
1169 EXPECT_CALL(context, get_memory);
1170 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1171 EXPECT_CALL(sha256, compression(_, state_address, input_address, dst_address));
1173 execution.sha256_compression(context, dst_address, state_address, input_address);
#define NOTE_HASH_TREE_LEAF_COUNT
#define L1_TO_L2_MSG_TREE_LEAF_COUNT
#define MAX_L2_TO_L1_MSGS_PER_TX
#define MAX_NOTE_HASHES_PER_TX
#define MAX_NULLIFIERS_PER_TX
#define MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX
StrictMock< MockHighLevelMerkleDB > merkle_db
Applies the Poseidon2 permutation function from https://eprint.iacr.org/2023/323 ....
ExecutionIdManager execution_id_manager
StrictMock< MockContext > context
InstructionInfoDB instruction_info_db
testing::StrictMock< MockGreaterThan > greater_than
smt_circuit::STerm shr(smt_circuit::STerm v0, smt_circuit::STerm v1, smt_solver::Solver *solver)
Right shift operation.
smt_circuit::STerm shl(smt_circuit::STerm v0, smt_circuit::STerm v1, smt_solver::Solver *solver)
Left shift operation without truncation.
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
uint256_t get_tag_max_value(ValueTag tag)
Sha256Hash sha256(const ByteContainer &input)
TEST_F(IPATest, ChallengesAreZero)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
unsigned __int128 uint128_t
bb::crypto::Poseidon2< bb::crypto::Poseidon2Bn254ScalarFieldParams > poseidon2
NiceMock< MockContextProvider > context_provider
NiceMock< MockExecution > execution