3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
51using ::testing::NiceMock;
52using ::testing::Return;
53using ::testing::ReturnRef;
54using ::testing::StrictMock;
55using ::testing::Throw;
58class TestingExecution :
public Execution {
60 using Execution::Execution;
62 void set_gas_tracker(GasTrackerInterface& gas_tracker) { this->testing_gas_tracker = &gas_tracker; }
64 GasTrackerInterface& get_gas_tracker()
override {
return *testing_gas_tracker; }
67 GasTrackerInterface* testing_gas_tracker;
70class ExecutionSimulationTest :
public ::testing::Test {
72 ExecutionSimulationTest()
74 ON_CALL(
context, get_memory()).WillByDefault(ReturnRef(
memory));
75 ON_CALL(
context, get_bytecode_manager).WillByDefault(ReturnRef(bytecode_manager));
80 StrictMock<MockAlu> alu;
81 StrictMock<MockBitwise>
bitwise;
82 StrictMock<MockMemory>
memory;
83 StrictMock<MockExecutionComponentsProvider> execution_components;
84 StrictMock<MockContext>
context;
86 StrictMock<MockInternalCallStackManager> internal_call_stack_manager;
87 StrictMock<MockKeccakF1600> keccakf1600;
88 StrictMock<MockGetContractInstance> get_contract_instance;
89 EventEmitter<ExecutionEvent> execution_event_emitter;
90 EventEmitter<ContextStackEvent> context_stack_event_emitter;
94 StrictMock<MockGasTracker> gas_tracker;
95 StrictMock<MockHighLevelMerkleDB>
merkle_db;
98 StrictMock<MockEcc> ecc;
99 StrictMock<MockToRadix> to_radix;
100 StrictMock<MockEmitUnencryptedLog> emit_unencrypted_log;
101 StrictMock<MockBytecodeManager> bytecode_manager;
102 StrictMock<MockSha256>
sha256;
106 TestingExecution
execution = TestingExecution(alu,
113 execution_components,
117 execution_event_emitter,
118 context_stack_event_emitter,
121 get_contract_instance,
122 emit_unencrypted_log,
131TEST_F(ExecutionSimulationTest, Add)
136 EXPECT_CALL(context, get_memory());
137 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
138 EXPECT_CALL(alu, add(
a,
b)).WillOnce(Return(MemoryValue::from<uint32_t>(9)));
139 EXPECT_CALL(memory, set(6, MemoryValue::from<uint32_t>(9)));
140 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
145TEST_F(ExecutionSimulationTest, Sub)
150 EXPECT_CALL(context, get_memory());
151 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
152 EXPECT_CALL(alu, sub(
a,
b)).WillOnce(Return(MemoryValue::from<uint64_t>(2)));
153 EXPECT_CALL(memory, set(3, MemoryValue::from<uint64_t>(2)));
154 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
159TEST_F(ExecutionSimulationTest, Mul)
162 auto a = MemoryValue::from<uint128_t>(max);
163 auto b = MemoryValue::from<uint128_t>(max - 3);
165 EXPECT_CALL(context, get_memory());
166 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
167 EXPECT_CALL(alu, mul(
a,
b)).WillOnce(Return(MemoryValue::from<uint128_t>(4)));
168 EXPECT_CALL(memory, set(3, MemoryValue::from<uint128_t>(4)));
169 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
174TEST_F(ExecutionSimulationTest, Div)
176 auto a = MemoryValue::from<uint128_t>(6);
177 auto b = MemoryValue::from<uint128_t>(3);
179 EXPECT_CALL(context, get_memory());
180 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
181 EXPECT_CALL(alu, div(
a,
b)).WillOnce(Return(MemoryValue::from<uint128_t>(2)));
182 EXPECT_CALL(memory, set(3, MemoryValue::from<uint128_t>(2)));
183 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
188TEST_F(ExecutionSimulationTest, FDiv)
191 auto b = MemoryValue::from<FF>(2);
193 EXPECT_CALL(context, get_memory());
194 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
195 EXPECT_CALL(alu, fdiv(
a,
b)).WillOnce(Return(MemoryValue::from<FF>(
FF::modulus - 2)));
196 EXPECT_CALL(memory, set(3, MemoryValue::from<FF>(
FF::modulus - 2)));
197 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
202TEST_F(ExecutionSimulationTest, Shl)
204 auto a = MemoryValue::from<uint32_t>(64);
205 auto b = MemoryValue::from<uint32_t>(2);
207 EXPECT_CALL(context, get_memory());
208 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
209 EXPECT_CALL(alu,
shl(
a,
b)).WillOnce(Return(MemoryValue::from<uint32_t>(256)));
210 EXPECT_CALL(memory, set(3, MemoryValue::from<uint32_t>(256)));
211 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
216TEST_F(ExecutionSimulationTest, Shr)
218 auto a = MemoryValue::from<uint64_t>(64);
219 auto b = MemoryValue::from<uint64_t>(2);
221 EXPECT_CALL(context, get_memory());
222 EXPECT_CALL(memory, get).Times(2).WillOnce(ReturnRef(
a)).WillOnce(ReturnRef(
b));
223 EXPECT_CALL(alu,
shr(
a,
b)).WillOnce(Return(MemoryValue::from<uint64_t>(16)));
224 EXPECT_CALL(memory, set(3, MemoryValue::from<uint64_t>(16)));
225 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
232TEST_F(ExecutionSimulationTest, Call)
237 uint32_t parent_pc = 100;
238 MemoryValue nested_address_value = MemoryValue::from<FF>(nested_address);
239 MemoryValue l2_gas_allocated = MemoryValue::from<uint32_t>(6);
240 MemoryValue da_gas_allocated = MemoryValue::from<uint32_t>(7);
241 MemoryValue cd_size = MemoryValue::from<uint32_t>(8);
242 AppendOnlyTreeSnapshot written_public_data_slots_tree_snapshot = AppendOnlyTreeSnapshot{
244 .next_available_leaf_index = 10,
246 TreeStates tree_states = TreeStates {
250 .next_available_leaf_index = 9,
257 .next_available_leaf_index = 6,
261 .l1_to_l2_message_tree = {
264 .next_available_leaf_index = 3,
268 .public_data_tree = {
271 .next_available_leaf_index = 1,
276 TrackedSideEffects side_effect_states = {
277 .l2_to_l1_messages = { {
278 .message = { .recipient =
EthAddress(0x12345678), .content = 0x12345678 },
279 .contract_address = parent_address,
282 .message = { .recipient =
EthAddress(0x333333), .content = 0x12345678 },
283 .contract_address = parent_address,
285 .public_logs = PublicLogs{ { { { 4 }, parent_address } } },
288 EXPECT_CALL(gas_tracker, compute_gas_limit_for_call(Gas{ 6, 7 })).WillOnce(Return(Gas{ 2, 3 }));
289 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
292 EXPECT_CALL(context, get_pc).WillOnce(Return(parent_pc));
296 EXPECT_CALL(context, get_context_id);
297 EXPECT_CALL(context, get_parent_id);
298 EXPECT_CALL(context, get_bytecode_manager).WillOnce(ReturnRef(bytecode_manager));
299 EXPECT_CALL(bytecode_manager, get_retrieved_bytecode_id).WillOnce(Return(
FF(1)));
300 EXPECT_CALL(context, get_next_pc);
301 EXPECT_CALL(context, get_is_static).WillRepeatedly(Return(
false));
302 EXPECT_CALL(context, get_msg_sender).WillOnce(ReturnRef(parent_address));
303 EXPECT_CALL(context, get_transaction_fee).WillOnce(ReturnRef(zero));
304 EXPECT_CALL(context, get_parent_cd_addr);
305 EXPECT_CALL(context, get_parent_cd_size);
306 EXPECT_CALL(context, get_parent_gas_used);
307 EXPECT_CALL(context, get_parent_gas_limit);
308 EXPECT_CALL(context, get_written_public_data_slots_tree_snapshot)
309 .WillOnce(Return(written_public_data_slots_tree_snapshot));
310 EXPECT_CALL(context, get_side_effect_tracker);
311 EXPECT_CALL(
side_effect_tracker, get_side_effects()).WillRepeatedly(ReturnRef(side_effect_states));
315 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_states));
317 EXPECT_CALL(context, get_memory());
318 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(parent_address));
319 EXPECT_CALL(memory,
get(1)).WillOnce(ReturnRef(l2_gas_allocated));
320 EXPECT_CALL(memory,
get(2)).WillOnce(ReturnRef(da_gas_allocated));
321 EXPECT_CALL(memory,
get(3)).WillOnce(ReturnRef(nested_address_value));
322 EXPECT_CALL(memory,
get(4)).WillOnce(ReturnRef(cd_size));
325 ON_CALL(*nested_context, halted())
326 .WillByDefault(Return(
true));
328 EXPECT_CALL(*nested_context, get_address).WillOnce(ReturnRef(nested_address));
329 EXPECT_CALL(*nested_context, get_is_static).WillOnce(Return(
false));
330 EXPECT_CALL(*nested_context, get_gas_limit).WillOnce(Return(Gas{ 2, 3 }));
335 .WillOnce(Return(
std::move(nested_context)));
346TEST_F(ExecutionSimulationTest, ExternalCallStaticnessPropagation)
352 MemoryValue nested_address_value = MemoryValue::from<FF>(nested_address);
353 MemoryValue l2_gas_allocated = MemoryValue::from<uint32_t>(6);
354 MemoryValue da_gas_allocated = MemoryValue::from<uint32_t>(7);
355 MemoryValue cd_size = MemoryValue::from<uint32_t>(8);
356 AppendOnlyTreeSnapshot written_public_data_slots_tree_snapshot = AppendOnlyTreeSnapshot{
358 .next_available_leaf_index = 10,
360 TreeStates tree_states =
361 TreeStates{ .note_hash_tree = { .tree = { .root = 10, .next_available_leaf_index = 9 }, .counter = 8 },
362 .nullifier_tree = { .tree = { .root = 7, .next_available_leaf_index = 6 }, .counter = 5 },
363 .l1_to_l2_message_tree = { .tree = { .root = 4, .next_available_leaf_index = 3 }, .counter = 0 },
364 .public_data_tree = { .tree = { .root = 2, .next_available_leaf_index = 1 }, .counter = 1 } };
365 TrackedSideEffects side_effect_states = {
366 .l2_to_l1_messages = { {
367 .message = { .recipient =
EthAddress(0x12345678), .content = 0x12345678 },
368 .contract_address = parent_address,
371 .message = { .recipient =
EthAddress(0x333333), .content = 0x12345678 },
372 .contract_address = parent_address,
374 .public_logs = PublicLogs{ { { { 4 }, parent_address } } },
377 auto setup_context_expectations = [&](
bool parent_is_static) {
379 EXPECT_CALL(gas_tracker, compute_gas_limit_for_call(Gas{ 6, 7 })).WillOnce(Return(Gas{ 2, 3 }));
380 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
381 EXPECT_CALL(context, get_pc).WillOnce(Return(100));
382 EXPECT_CALL(context, get_context_id);
383 EXPECT_CALL(context, get_parent_id);
384 EXPECT_CALL(context, get_bytecode_manager).WillOnce(ReturnRef(bytecode_manager));
385 EXPECT_CALL(bytecode_manager, get_retrieved_bytecode_id).WillOnce(Return(
FF(1)));
386 EXPECT_CALL(context, get_next_pc);
387 EXPECT_CALL(context, get_is_static).WillRepeatedly(Return(parent_is_static));
388 EXPECT_CALL(context, get_msg_sender).WillOnce(ReturnRef(parent_address));
389 EXPECT_CALL(context, get_transaction_fee).WillOnce(ReturnRef(zero));
390 EXPECT_CALL(context, get_parent_cd_addr);
391 EXPECT_CALL(context, get_parent_cd_size);
392 EXPECT_CALL(context, get_parent_gas_used);
393 EXPECT_CALL(context, get_parent_gas_limit);
394 EXPECT_CALL(context, get_written_public_data_slots_tree_snapshot)
395 .WillOnce(Return(written_public_data_slots_tree_snapshot));
396 EXPECT_CALL(context, get_side_effect_tracker);
397 EXPECT_CALL(
side_effect_tracker, get_side_effects()).WillRepeatedly(ReturnRef(side_effect_states));
399 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_states));
400 EXPECT_CALL(context, get_memory());
401 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(parent_address));
402 EXPECT_CALL(memory,
get(1)).WillOnce(ReturnRef(l2_gas_allocated));
403 EXPECT_CALL(memory,
get(2)).WillOnce(ReturnRef(da_gas_allocated));
404 EXPECT_CALL(memory,
get(3)).WillOnce(ReturnRef(nested_address_value));
405 EXPECT_CALL(memory,
get(4)).WillOnce(ReturnRef(cd_size));
408 auto create_nested_context = [&]() {
410 ON_CALL(*nested, halted()).WillByDefault(Return(
true));
412 EXPECT_CALL(*nested, get_address).WillOnce(ReturnRef(nested_address));
413 EXPECT_CALL(*nested, get_is_static).WillOnce(Return(
false));
414 EXPECT_CALL(*nested, get_gas_limit).WillOnce(Return(Gas{ 2, 3 }));
419 setup_context_expectations(
false);
421 make_nested_context(nested_address,
430 .WillOnce(Return(create_nested_context()));
434 setup_context_expectations(
false);
436 make_nested_context(nested_address,
445 .WillOnce(Return(create_nested_context()));
446 execution.static_call(context, 1, 2, 3, 4, 5);
449 setup_context_expectations(
true);
451 make_nested_context(nested_address,
460 .WillOnce(Return(create_nested_context()));
464 setup_context_expectations(
true);
466 make_nested_context(nested_address,
475 .WillOnce(Return(create_nested_context()));
476 execution.static_call(context, 1, 2, 3, 4, 5);
479TEST_F(ExecutionSimulationTest, InternalCall)
482 uint32_t return_pc = 500;
483 uint32_t pc_loc = 11;
485 NiceMock<MockInternalCallStackManager> internal_call_stack_manager;
486 ON_CALL(context, get_internal_call_stack_manager).WillByDefault(ReturnRef(internal_call_stack_manager));
490 EXPECT_CALL(context, get_internal_call_stack_manager());
492 EXPECT_CALL(context, get_pc()).WillOnce(Return(pc));
493 EXPECT_CALL(context, get_next_pc()).WillOnce(Return(return_pc));
494 EXPECT_CALL(internal_call_stack_manager, push(pc, return_pc));
496 EXPECT_CALL(context, set_next_pc(pc_loc));
497 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
499 execution.internal_call(context, pc_loc);
503 EXPECT_CALL(context, get_internal_call_stack_manager());
505 EXPECT_CALL(internal_call_stack_manager, pop()).WillOnce(Return(return_pc));
507 EXPECT_CALL(context, set_next_pc(return_pc));
508 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
513TEST_F(ExecutionSimulationTest, GetEnvVarAddress)
516 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(addr));
517 EXPECT_CALL(context, get_memory());
518 EXPECT_CALL(memory, set(1, MemoryValue::from<FF>(addr)));
519 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
524TEST_F(ExecutionSimulationTest, GetEnvVarChainId)
526 GlobalVariables globals;
527 globals.chain_id = 1;
528 EXPECT_CALL(context, get_globals).WillOnce(ReturnRef(globals));
529 EXPECT_CALL(context, get_memory());
530 EXPECT_CALL(memory, set(1, MemoryValue::from<FF>(1)));
531 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
536TEST_F(ExecutionSimulationTest, GetEnvVarIsStaticCall)
538 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
539 EXPECT_CALL(context, get_memory());
540 EXPECT_CALL(memory, set(1, MemoryValue::from<uint1_t>(1)));
541 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
546TEST_F(ExecutionSimulationTest, GetEnvVarInvalidEnum)
548 EXPECT_CALL(context, get_memory());
549 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
551 EXPECT_THROW(
execution.get_env_var(context, 1, 255), std::runtime_error);
557TEST_F(ExecutionSimulationTest, Jump)
559 EXPECT_CALL(context, set_next_pc(120));
560 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
565TEST_F(ExecutionSimulationTest, SuccessCopyTrue)
567 EXPECT_CALL(context, get_memory());
568 EXPECT_CALL(context, get_last_success).WillOnce(Return(
true));
569 EXPECT_CALL(memory, set(10, MemoryValue::from<uint1_t>(1)));
570 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
575TEST_F(ExecutionSimulationTest, SuccessCopyFalse)
577 EXPECT_CALL(context, get_memory());
578 EXPECT_CALL(context, get_last_success).WillOnce(Return(
false));
579 EXPECT_CALL(memory, set(10, MemoryValue::from<uint1_t>(0)));
580 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
585TEST_F(ExecutionSimulationTest, RdSize)
587 EXPECT_CALL(context, get_memory());
588 EXPECT_CALL(context, get_last_rd_size).WillOnce(Return(42));
589 EXPECT_CALL(memory, set(10, MemoryValue::from<uint32_t>(42)));
590 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
595TEST_F(ExecutionSimulationTest, DebugLog)
602 uint16_t message_size = 5;
605 EXPECT_CALL(context, get_memory());
606 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(
address));
607 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
609 debug_log(_,
address, level_offset, message_offset, message_size, fields_offset, fields_size_offset));
611 execution.debug_log(context, level_offset, message_offset, fields_offset, fields_size_offset, message_size);
614TEST_F(ExecutionSimulationTest, Sload)
619 auto slot = MemoryValue::from<FF>(42);
621 EXPECT_CALL(context, get_memory());
623 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
624 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(
address));
627 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<FF>(7)));
628 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
633TEST_F(ExecutionSimulationTest, SStore)
638 auto slot = MemoryValue::from<FF>(42);
639 auto value = MemoryValue::from<FF>(7);
640 TreeStates tree_state = {};
641 EXPECT_CALL(context, get_memory());
643 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
644 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
645 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
647 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
648 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 1 }));
650 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
654 execution.sstore(context, value_addr, slot_addr);
657TEST_F(ExecutionSimulationTest, SStoreDuringStaticCall)
662 auto slot = MemoryValue::from<FF>(42);
663 auto value = MemoryValue::from<FF>(7);
664 EXPECT_CALL(context, get_memory());
666 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
667 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
668 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
670 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 1 }));
672 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
676TEST_F(ExecutionSimulationTest, SStoreLimitReached)
681 auto slot = MemoryValue::from<FF>(42);
682 auto value = MemoryValue::from<FF>(7);
683 TreeStates tree_state = {};
685 EXPECT_CALL(context, get_memory());
687 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
688 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
689 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
691 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
692 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 1 }));
694 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
697 "SSTORE: Maximum number of data writes reached");
700TEST_F(ExecutionSimulationTest, SStoreLimitReachedSquashed)
705 auto slot = MemoryValue::from<FF>(42);
706 auto value = MemoryValue::from<FF>(7);
707 TreeStates tree_state = {};
709 EXPECT_CALL(context, get_memory());
711 EXPECT_CALL(memory,
get(slot_addr)).WillOnce(ReturnRef(
slot));
712 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
713 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
716 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
718 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
722 execution.sstore(context, value_addr, slot_addr);
725TEST_F(ExecutionSimulationTest, NoteHashExists)
731 auto unique_note_hash = MemoryValue::from<FF>(42);
732 auto leaf_index = MemoryValue::from<uint64_t>(7);
734 EXPECT_CALL(context, get_memory());
735 EXPECT_CALL(memory,
get(unique_note_hash_addr)).WillOnce(ReturnRef(unique_note_hash));
736 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
738 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
742 EXPECT_CALL(
merkle_db, note_hash_exists(leaf_index.as<uint64_t>(), unique_note_hash.as<
FF>()))
743 .WillOnce(Return(
true));
745 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(1)));
747 execution.note_hash_exists(context, unique_note_hash_addr, leaf_index_addr,
dst_addr);
750TEST_F(ExecutionSimulationTest, NoteHashExistsOutOfRange)
756 auto unique_note_hash = MemoryValue::from<FF>(42);
759 EXPECT_CALL(context, get_memory());
760 EXPECT_CALL(memory,
get(unique_note_hash_addr)).WillOnce(ReturnRef(unique_note_hash));
761 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
763 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
767 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(0)));
769 execution.note_hash_exists(context, unique_note_hash_addr, leaf_index_addr,
dst_addr);
772TEST_F(ExecutionSimulationTest, EmitNoteHash)
776 auto note_hash = MemoryValue::from<FF>(42);
778 TreeStates tree_state = {};
780 EXPECT_CALL(context, get_memory());
781 EXPECT_CALL(memory,
get(note_hash_addr)).WillOnce(ReturnRef(
note_hash));
782 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
784 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
786 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
787 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
790 execution.emit_note_hash(context, note_hash_addr);
793TEST_F(ExecutionSimulationTest, EmitNoteHashDuringStaticCall)
797 auto note_hash = MemoryValue::from<FF>(42);
800 EXPECT_CALL(context, get_memory());
801 EXPECT_CALL(memory,
get(note_hash_addr)).WillOnce(ReturnRef(
note_hash));
802 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
804 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
806 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
810TEST_F(ExecutionSimulationTest, EmitNoteHashLimitReached)
814 auto note_hash = MemoryValue::from<FF>(42);
816 TreeStates tree_state = {};
819 EXPECT_CALL(context, get_memory());
820 EXPECT_CALL(memory,
get(note_hash_addr)).WillOnce(ReturnRef(
note_hash));
821 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
823 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
825 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
826 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
829 "EMITNOTEHASH: Maximum number of note hashes reached");
832TEST_F(ExecutionSimulationTest, L1ToL2MessageExists)
838 auto msg_hash = MemoryValue::from<FF>(42);
839 auto leaf_index = MemoryValue::from<uint64_t>(7);
841 EXPECT_CALL(context, get_memory());
842 EXPECT_CALL(memory,
get(msg_hash_addr)).WillOnce(ReturnRef(msg_hash));
843 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
845 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
849 EXPECT_CALL(
merkle_db, l1_to_l2_msg_exists(leaf_index.as<uint64_t>(), msg_hash.as<
FF>())).WillOnce(Return(
true));
851 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(1)));
853 execution.l1_to_l2_message_exists(context, msg_hash_addr, leaf_index_addr,
dst_addr);
856TEST_F(ExecutionSimulationTest, L1ToL2MessageExistsOutOfRange)
862 auto msg_hash = MemoryValue::from<FF>(42);
865 EXPECT_CALL(context, get_memory());
866 EXPECT_CALL(memory,
get(msg_hash_addr)).WillOnce(ReturnRef(msg_hash));
867 EXPECT_CALL(memory,
get(leaf_index_addr)).WillOnce(ReturnRef(leaf_index));
869 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
873 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(0)));
875 execution.l1_to_l2_message_exists(context, msg_hash_addr, leaf_index_addr,
dst_addr);
878TEST_F(ExecutionSimulationTest, NullifierExists)
884 auto nullifier = MemoryValue::from<FF>(42);
885 auto address = MemoryValue::from<FF>(7);
887 EXPECT_CALL(context, get_memory());
888 EXPECT_CALL(memory,
get(nullifier_offset)).WillOnce(ReturnRef(
nullifier));
889 EXPECT_CALL(memory,
get(address_offset)).WillOnce(ReturnRef(
address));
891 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
895 EXPECT_CALL(memory, set(exists_offset, MemoryValue::from<uint1_t>(1)));
897 execution.nullifier_exists(context, nullifier_offset, address_offset, exists_offset);
900TEST_F(ExecutionSimulationTest, EmitNullifier)
904 auto nullifier = MemoryValue::from<FF>(42);
906 TreeStates tree_state = {};
908 EXPECT_CALL(context, get_memory());
909 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
910 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
912 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
914 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
915 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
918 execution.emit_nullifier(context, nullifier_addr);
921TEST_F(ExecutionSimulationTest, EmitNullifierDuringStaticCall)
925 auto nullifier = MemoryValue::from<FF>(42);
928 EXPECT_CALL(context, get_memory());
929 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
930 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
932 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
934 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
938TEST_F(ExecutionSimulationTest, EmitNullifierLimitReached)
942 auto nullifier = MemoryValue::from<FF>(42);
944 TreeStates tree_state = {};
947 EXPECT_CALL(context, get_memory());
948 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
949 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
951 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
953 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
954 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
957 "EMITNULLIFIER: Maximum number of nullifiers reached");
960TEST_F(ExecutionSimulationTest, EmitNullifierCollision)
964 auto nullifier = MemoryValue::from<FF>(42);
966 TreeStates tree_state = {};
968 EXPECT_CALL(context, get_memory());
969 EXPECT_CALL(memory,
get(nullifier_addr)).WillOnce(ReturnRef(
nullifier));
970 EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(
address));
972 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
974 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
975 EXPECT_CALL(
merkle_db, get_tree_state).WillOnce(Return(tree_state));
977 .WillOnce(Throw(NullifierCollisionException(
"Nullifier collision")));
982TEST_F(ExecutionSimulationTest, Set)
988 EXPECT_CALL(context, get_memory());
989 EXPECT_CALL(alu, truncate(
value,
static_cast<MemoryTag>(
dst_tag))).WillOnce(Return(MemoryValue::from<uint8_t>(7)));
990 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint8_t>(7)));
991 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
996TEST_F(ExecutionSimulationTest, Cast)
1003 EXPECT_CALL(context, get_memory()).WillOnce(ReturnRef(memory));
1004 EXPECT_CALL(memory,
get(src_addr)).WillOnce(ReturnRef(
value));
1007 .WillOnce(Return(MemoryValue::from<uint1_t>(1)));
1008 EXPECT_CALL(memory, set(
dst_addr, MemoryValue::from<uint1_t>(1)));
1009 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1019 EXPECT_CALL(context, get_memory());
1020 EXPECT_CALL(gas_tracker, consume_gas);
1026TEST_F(ExecutionSimulationTest, EccAdd)
1036 MemoryValue p_x = MemoryValue::from<FF>(
FF(
"0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a"));
1037 MemoryValue p_y = MemoryValue::from<FF>(
FF(
"0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60"));
1040 MemoryValue q_x = MemoryValue::from<FF>(
FF(
"0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7"));
1041 MemoryValue q_y = MemoryValue::from<FF>(
FF(
"0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3"));
1046 EXPECT_CALL(context, get_memory()).WillRepeatedly(ReturnRef(memory));
1047 EXPECT_CALL(Const(memory),
get(p_x_addr)).WillOnce(ReturnRef(p_x));
1048 EXPECT_CALL(memory,
get(p_y_addr)).WillOnce(ReturnRef(p_y));
1049 EXPECT_CALL(memory,
get(p_is_inf_addr)).WillOnce(ReturnRef(zero));
1050 EXPECT_CALL(memory,
get(q_x_addr)).WillOnce(ReturnRef(q_x));
1051 EXPECT_CALL(memory,
get(q_y_addr)).WillOnce(ReturnRef(q_y));
1052 EXPECT_CALL(memory,
get(q_is_inf_addr)).WillOnce(ReturnRef(zero));
1054 EXPECT_CALL(gas_tracker, consume_gas);
1057 EXPECT_CALL(ecc, add(_, _, _,
dst_addr));
1060 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);
1063TEST_F(ExecutionSimulationTest, ToRadixBE)
1072 MemoryValue radix = MemoryValue::from<uint32_t>(16);
1074 MemoryValue::from<uint8_t>(0x55),
1075 MemoryValue::from<uint8_t>(0x00) };
1076 MemoryValue num_limbs = MemoryValue::from<uint32_t>(3);
1077 MemoryValue is_output_bits = MemoryValue::from<uint1_t>(
false);
1078 uint32_t num_p_limbs = 64;
1080 EXPECT_CALL(context, get_memory()).WillOnce(ReturnRef(memory));
1081 EXPECT_CALL(memory,
get(value_addr)).WillOnce(ReturnRef(
value));
1082 EXPECT_CALL(memory,
get(radix_addr)).WillOnce(ReturnRef(radix));
1083 EXPECT_CALL(memory,
get(num_limbs_addr)).WillOnce(ReturnRef(num_limbs));
1084 EXPECT_CALL(memory,
get(is_output_bits_addr)).WillOnce(ReturnRef(is_output_bits));
1086 EXPECT_CALL(greater_than,
gt(radix.as<uint32_t>(), 256)).WillOnce(Return(
false));
1087 EXPECT_CALL(greater_than,
gt(num_limbs.as<uint32_t>(), num_p_limbs)).WillOnce(Return(
false));
1089 EXPECT_CALL(gas_tracker, consume_gas);
1090 EXPECT_CALL(to_radix, to_be_radix);
1092 execution.to_radix_be(context, value_addr, radix_addr, num_limbs_addr, is_output_bits_addr,
dst_addr);
1095TEST_F(ExecutionSimulationTest, EmitUnencryptedLog)
1099 MemoryValue log_size = MemoryValue::from<uint32_t>(10);
1102 EXPECT_CALL(context, get_memory());
1103 EXPECT_CALL(memory,
get(log_size_offset)).WillOnce(ReturnRef(log_size));
1105 EXPECT_CALL(context, get_address).WillOnce(ReturnRef(
address));
1107 EXPECT_CALL(emit_unencrypted_log, emit_unencrypted_log(_, _,
address, log_offset, log_size.as<uint32_t>()));
1109 EXPECT_CALL(gas_tracker, consume_gas(Gas{ log_size.as<uint32_t>(), log_size.as<uint32_t>() }));
1111 execution.emit_unencrypted_log(context, log_size_offset, log_offset);
1114TEST_F(ExecutionSimulationTest, SendL2ToL1Msg)
1122 auto recipient = MemoryValue::from<FF>(recipient_address);
1123 auto content_value = MemoryValue::from<FF>(content);
1125 ScopedL2ToL1Message dummy_msg = { .message = { .recipient = recipient_address, .content = content },
1127 TrackedSideEffects side_effects_states;
1129 side_effects_states.l2_to_l1_messages.push_back(dummy_msg);
1131 TrackedSideEffects side_effects_states_after = side_effects_states;
1132 side_effects_states_after.l2_to_l1_messages.push_back(dummy_msg);
1134 EXPECT_CALL(context, get_memory());
1136 EXPECT_CALL(context, get_side_effect_tracker);
1138 EXPECT_CALL(memory,
get(recipient_addr)).WillOnce(ReturnRef(recipient));
1139 EXPECT_CALL(memory,
get(content_addr)).WillOnce(ReturnRef(content_value));
1141 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1143 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
1145 EXPECT_CALL(
side_effect_tracker, get_side_effects()).WillOnce(ReturnRef(side_effects_states));
1147 .WillOnce(Return());
1149 execution.send_l2_to_l1_msg(context, recipient_addr, content_addr);
1152TEST_F(ExecutionSimulationTest, SendL2ToL1MsgStaticCall)
1157 auto recipient = MemoryValue::from<FF>(42);
1158 auto content = MemoryValue::from<FF>(27);
1160 TrackedSideEffects side_effects_states;
1162 EXPECT_CALL(context, get_memory());
1164 EXPECT_CALL(memory,
get(recipient_addr)).WillOnce(ReturnRef(recipient));
1165 EXPECT_CALL(memory,
get(content_addr)).WillOnce(ReturnRef(content));
1167 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1169 EXPECT_CALL(context, get_is_static).WillOnce(Return(
true));
1172 "Static call cannot update the state");
1175TEST_F(ExecutionSimulationTest, SendL2ToL1MsgLimitReached)
1180 auto recipient = MemoryValue::from<FF>(42);
1181 auto content = MemoryValue::from<FF>(27);
1183 TrackedSideEffects side_effects_states;
1185 side_effects_states.l2_to_l1_messages.push_back(
1186 ScopedL2ToL1Message{ .message = { .recipient =
EthAddress(0x12345678), .content = 0x12345678 },
1187 .contract_address = 0x12345678 });
1190 EXPECT_CALL(context, get_memory());
1191 EXPECT_CALL(context, get_side_effect_tracker);
1193 EXPECT_CALL(memory,
get(recipient_addr)).WillOnce(ReturnRef(recipient));
1194 EXPECT_CALL(memory,
get(content_addr)).WillOnce(ReturnRef(content));
1196 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1198 EXPECT_CALL(context, get_is_static).WillOnce(Return(
false));
1200 EXPECT_CALL(
side_effect_tracker, get_side_effects()).WillOnce(ReturnRef(side_effects_states));
1203 "SENDL2TOL1MSG: Maximum number of L2 to L1 messages reached");
1206TEST_F(ExecutionSimulationTest, Sha256Compression)
1212 EXPECT_CALL(context, get_memory());
1213 EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 }));
1214 EXPECT_CALL(sha256, compression(_, state_address, input_address,
dst_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
AztecAddress contract_address
void debug_log(Args &&... args)
Compile-time debug logging helper.
InstructionInfoDB instruction_info_db
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)
SHA-256 hash function (FIPS 180-4)
TEST_F(IPATest, ChallengesAreZero)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
unsigned __int128 uint128_t
bb::crypto::Poseidon2< bb::crypto::Poseidon2Bn254ScalarFieldParams > poseidon2
static constexpr uint256_t modulus
SideEffectTracker side_effect_tracker
NiceMock< MockContextProvider > context_provider
NiceMock< MockExecution > execution
NoopCallStackMetadataCollector call_stack_metadata_collector