4#include <gmock/gmock.h>
5#include <gtest/gtest.h>
35using namespace simulation;
36using ::testing::Return;
37using ::testing::ReturnRef;
38using ::testing::StrictMock;
39using tracegen::DataCopyTraceBuilder;
40using tracegen::ExecutionTraceBuilder;
41using tracegen::TestTraceContainer;
47class DataCopyConstrainingBuilderTest :
public ::testing::Test {
49 DataCopyConstrainingBuilderTest() { EXPECT_CALL(context, get_memory()).WillRepeatedly(ReturnRef(mem)); }
53 RangeCheck
range_check = RangeCheck(range_check_event_emitter);
56 GreaterThan
gt = GreaterThan(mock_field_gt, range_check, gt_event_emitter);
58 DataCopy
copy_data = DataCopy(execution_id_manager, gt, event_emitter);
63 TestTraceContainer
trace = TestTraceContainer({
65 { C::precomputed_first_row, 1 },
71 MemoryValue::from<FF>(1), MemoryValue::from<FF>(2), MemoryValue::from<FF>(3), MemoryValue::from<FF>(4),
72 MemoryValue::from<FF>(5), MemoryValue::from<FF>(6), MemoryValue::from<FF>(7), MemoryValue::from<FF>(8),
76class NestedCdConstrainingBuilderTest :
public DataCopyConstrainingBuilderTest {
78 NestedCdConstrainingBuilderTest()
81 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
true));
82 EXPECT_CALL(context, get_parent_id).WillRepeatedly(Return(1));
83 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(2));
84 EXPECT_CALL(context, get_parent_cd_size).WillRepeatedly(Return(
data.size()));
85 EXPECT_CALL(context, get_parent_cd_addr).WillRepeatedly(Return(0));
89TEST_F(NestedCdConstrainingBuilderTest, CdZeroCopy)
96 tracegen::DataCopyTraceBuilder
builder;
102 check_relation<data_copy>(trace);
110TEST_F(NestedCdConstrainingBuilderTest, SimpleNestedCdCopy)
125 check_relation<data_copy>(trace);
136TEST_F(NestedCdConstrainingBuilderTest, SimpleNestedCdCopySizeOneNoPadding)
153 check_relation<data_copy>(trace);
161TEST_F(NestedCdConstrainingBuilderTest, SimpleNestedCdCopySizeOneWithPadding)
174 check_relation<data_copy>(trace);
182TEST_F(NestedCdConstrainingBuilderTest, NestedCdCopyPadded)
187 ASSERT_LT(result_cd.size(), 10);
188 result_cd.resize(10, MemoryValue::from<FF>(0));
189 uint32_t
copy_size =
static_cast<uint32_t
>(result_cd.size());
201 check_relation<data_copy>(trace);
209TEST_F(NestedCdConstrainingBuilderTest, NestedCdCopyPartial)
217 EXPECT_CALL(context, get_calldata(
offset, size)).WillOnce(Return(result_cd));
227 check_relation<data_copy>(trace);
235TEST_F(NestedCdConstrainingBuilderTest, ZeroCopySizeOffsetOOB)
237 uint32_t
offset =
static_cast<uint32_t
>(
data.size()) + 1;
251 check_relation<data_copy>(trace);
259TEST_F(NestedCdConstrainingBuilderTest, NonZeroCopySizeOffsetOOB)
261 uint32_t
offset =
static_cast<uint32_t
>(
data.size()) + 1;
275 check_relation<data_copy>(trace);
283TEST_F(NestedCdConstrainingBuilderTest, OutofRangeError)
290 "Attempting to access out of bounds memory");
298 check_relation<data_copy>(trace);
306TEST_F(NestedCdConstrainingBuilderTest, HighestMemoryAddressesWithPadding)
308 uint32_t
offset =
static_cast<uint32_t
>(
data.size() - 1);
316 EXPECT_CALL(context, get_calldata(
offset, size)).WillOnce(Return(result_cd));
326 check_relation<data_copy>(trace);
334TEST_F(NestedCdConstrainingBuilderTest, HighestMemoryAddressesNoPadding)
337 uint32_t size =
static_cast<uint32_t
>(
data.size()) - 2;
342 EXPECT_CALL(context, get_calldata(
offset, size)).WillOnce(Return(result_cd));
352 check_relation<data_copy>(trace);
360class HighCdAddressConstrainingBuilderTest :
public DataCopyConstrainingBuilderTest {
362 HighCdAddressConstrainingBuilderTest()
365 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
true));
366 EXPECT_CALL(context, get_parent_id).WillRepeatedly(Return(1));
367 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(2));
368 EXPECT_CALL(context, get_parent_cd_size).WillRepeatedly(Return(
data.size()));
373TEST_F(HighCdAddressConstrainingBuilderTest, HighestMemoryAddressesWithPadding)
375 uint32_t
offset =
static_cast<uint32_t
>(
data.size() - 1);
383 EXPECT_CALL(context, get_calldata(
offset, size)).WillOnce(Return(result_cd));
393 check_relation<data_copy>(trace);
401TEST_F(HighCdAddressConstrainingBuilderTest, HighestMemoryAddressesNoPadding)
404 uint32_t size =
static_cast<uint32_t
>(
data.size()) - 2;
409 EXPECT_CALL(context, get_calldata(
offset, size)).WillOnce(Return(result_cd));
419 check_relation<data_copy>(trace);
427class EnqueuedCdConstrainingBuilderTest :
public DataCopyConstrainingBuilderTest {
429 EnqueuedCdConstrainingBuilderTest()
432 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
false));
433 EXPECT_CALL(context, get_parent_id).WillRepeatedly(Return(0));
434 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(1));
435 EXPECT_CALL(context, get_parent_cd_size).WillRepeatedly(Return(
data.size()));
436 EXPECT_CALL(context, get_parent_cd_addr).WillRepeatedly(Return(0));
439 tracegen::CalldataTraceBuilder calldata_builder;
440 std::vector<FF> calldata_ff(
data.size());
441 std::ranges::transform(
444 CalldataEvent cd_event = {
446 .calldata = calldata_ff,
448 calldata_builder.process_retrieval({ cd_event },
trace);
452TEST_F(EnqueuedCdConstrainingBuilderTest, CdZeroCopy)
459 tracegen::DataCopyTraceBuilder
builder;
465 check_relation<data_copy>(trace);
466 check_all_interactions<DataCopyTraceBuilder>(trace);
469TEST_F(EnqueuedCdConstrainingBuilderTest, SimpleEnqueuedCdCopy)
484 check_relation<data_copy>(trace);
485 check_all_interactions<DataCopyTraceBuilder>(trace);
488TEST_F(EnqueuedCdConstrainingBuilderTest, EnqueuedCallCdCopyPadding)
492 ASSERT_LT(result_cd.size(), 10);
493 result_cd.resize(10, MemoryValue::from<FF>(0));
494 auto copy_size =
static_cast<uint32_t
>(result_cd.size());
506 check_relation<data_copy>(trace);
507 check_all_interactions<DataCopyTraceBuilder>(trace);
510TEST_F(EnqueuedCdConstrainingBuilderTest, EnqueuedCallCdCopyPartial)
518 EXPECT_CALL(context, get_calldata(
offset, size)).WillOnce(Return(result_cd));
528 check_relation<data_copy>(trace);
529 check_all_interactions<DataCopyTraceBuilder>(trace);
532class EnqueuedEmptyCdConstrainingBuilderTest :
public DataCopyConstrainingBuilderTest {
534 EnqueuedEmptyCdConstrainingBuilderTest()
537 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
false));
538 EXPECT_CALL(context, get_parent_id).WillRepeatedly(Return(0));
539 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(1));
540 EXPECT_CALL(context, get_parent_cd_size).WillRepeatedly(Return(0));
541 EXPECT_CALL(context, get_parent_cd_addr).WillRepeatedly(Return(0));
544 tracegen::CalldataTraceBuilder calldata_builder;
545 CalldataEvent cd_event = {
549 calldata_builder.process_retrieval({ cd_event },
trace);
553TEST_F(EnqueuedEmptyCdConstrainingBuilderTest, CdZeroCopy)
560 tracegen::DataCopyTraceBuilder
builder;
566 check_relation<data_copy>(trace);
567 check_all_interactions<DataCopyTraceBuilder>(trace);
570TEST_F(EnqueuedEmptyCdConstrainingBuilderTest, SimpleEnqueuedCdCopy)
583 check_relation<data_copy>(trace);
584 check_all_interactions<DataCopyTraceBuilder>(trace);
587TEST_F(EnqueuedEmptyCdConstrainingBuilderTest, EnqueuedCallCdCopyPadding)
590 std::vector<FF> result_cd = {};
591 result_cd.resize(10, 0);
592 auto copy_size =
static_cast<uint32_t
>(result_cd.size());
602 check_relation<data_copy>(trace);
603 check_all_interactions<DataCopyTraceBuilder>(trace);
610TEST(DataCopyWithExecutionPerm, CdCopy)
618 uint32_t parent_context_id = 99;
621 MemoryValue::from<FF>(8), MemoryValue::from<FF>(7), MemoryValue::from<FF>(6), MemoryValue::from<FF>(5),
622 MemoryValue::from<FF>(4), MemoryValue::from<FF>(3), MemoryValue::from<FF>(2), MemoryValue::from<FF>(1),
633 StrictMock<MockContext>
context;
634 EXPECT_CALL(context, get_memory()).WillRepeatedly(ReturnRef(
mem));
635 EXPECT_CALL(context, get_parent_cd_size).WillRepeatedly(Return(
data.size()));
636 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
true));
637 EXPECT_CALL(context, get_parent_cd_addr).WillRepeatedly(Return(
parent_cd_addr));
643 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(
context_id));
644 EXPECT_CALL(context, get_parent_id).WillRepeatedly(Return(parent_context_id));
651 TestTraceContainer
trace({
653 { C::precomputed_first_row, 1 },
654 { C::execution_sel, 1 },
656 { C::execution_parent_id, parent_context_id },
657 { C::execution_sel_exec_dispatch_calldata_copy, 1 },
661 { C::execution_sel_opcode_error, 0 },
663 { C::execution_parent_calldata_size,
static_cast<uint32_t
>(
data.size()) },
672 check_relation<data_copy>(trace);
678class NestedRdConstrainingBuilderTest :
public DataCopyConstrainingBuilderTest {
680 NestedRdConstrainingBuilderTest()
683 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
true));
684 EXPECT_CALL(context, get_last_child_id).WillRepeatedly(Return(2));
685 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(2));
686 EXPECT_CALL(context, get_last_rd_size).WillRepeatedly(Return(
data.size()));
687 EXPECT_CALL(context, get_last_rd_addr).WillRepeatedly(Return(0));
691TEST_F(NestedRdConstrainingBuilderTest, RdZeroCopy)
694 uint32_t rd_offset = 0;
698 tracegen::DataCopyTraceBuilder
builder;
704 check_relation<data_copy>(trace);
705 check_all_interactions<DataCopyTraceBuilder>(trace);
708TEST(DataCopyWithExecutionPerm, RdCopy)
712 uint32_t rd_offset = 3;
719 MemoryValue::from<FF>(1), MemoryValue::from<FF>(2), MemoryValue::from<FF>(3), MemoryValue::from<FF>(4),
720 MemoryValue::from<FF>(5), MemoryValue::from<FF>(6), MemoryValue::from<FF>(7), MemoryValue::from<FF>(8),
728 StrictMock<MockContext>
context;
729 EXPECT_CALL(context, get_memory()).WillRepeatedly(ReturnRef(
mem));
730 EXPECT_CALL(context, get_last_rd_size).WillRepeatedly(Return(
data.size()));
731 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
true));
732 EXPECT_CALL(context, get_last_rd_addr).WillRepeatedly(Return(
child_rd_addr));
733 EXPECT_CALL(context, get_returndata(rd_offset,
copy_size))
734 .WillRepeatedly(::testing::Invoke([&
data, rd_offset,
copy_size]() {
738 EXPECT_CALL(context, get_last_child_id).WillRepeatedly(Return(
child_context_id));
739 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(
context_id));
746 TestTraceContainer
trace({
748 { C::precomputed_first_row, 1 },
749 { C::execution_sel, 1 },
752 { C::execution_sel_exec_dispatch_returndata_copy, 1 },
754 { C::execution_register_1_, rd_offset },
756 { C::execution_sel_opcode_error, 0 },
758 { C::execution_last_child_returndata_size,
static_cast<uint32_t
>(
data.size()) },
767 check_relation<data_copy>(trace);
773TEST(DataCopyWithExecutionPerm, ErrorPropagation)
777 uint32_t rd_offset = 10;
784 uint32_t child_data_size = 10;
787 StrictMock<MockContext>
context;
788 EXPECT_CALL(context, get_memory()).WillRepeatedly(ReturnRef(
mem));
789 EXPECT_CALL(context, get_last_rd_size).WillRepeatedly(Return(child_data_size));
790 EXPECT_CALL(context, has_parent).WillRepeatedly(Return(
true));
791 EXPECT_CALL(context, get_last_rd_addr).WillRepeatedly(Return(
child_rd_addr));
792 EXPECT_CALL(context, get_context_id).WillRepeatedly(Return(
context_id));
793 EXPECT_CALL(context, get_last_child_id).WillRepeatedly(Return(
child_context_id));
803 TestTraceContainer
trace({
805 { C::precomputed_first_row, 1 },
806 { C::execution_sel, 1 },
809 { C::execution_sel_exec_dispatch_returndata_copy, 1 },
811 { C::execution_register_1_, rd_offset },
812 { C::execution_rop_2_, big_dst_addr },
813 { C::execution_sel_opcode_error, 1 },
815 { C::execution_last_child_returndata_size, child_data_size },
820 "Attempting to access out of bounds memory");
825 check_relation<data_copy>(trace);
#define AVM_HIGHEST_MEM_ADDRESS
void rd_copy(ContextInterface &context, uint32_t copy_size, uint32_t offset, MemoryAddress dst_addr) override
Copies returndata from the last executed context to the dst_addr.
void cd_copy(ContextInterface &context, uint32_t copy_size, uint32_t offset, MemoryAddress dst_addr) override
Writes calldata into dst_addr. There is slight difference in how enqueued and nested contexts are han...
void process(const simulation::EventEmitterInterface< simulation::AluEvent >::Container &events, TraceContainer &trace)
Process the ALU events and populate the ALU relevant columns in the trace.
void process(const simulation::EventEmitterInterface< simulation::GreaterThanEvent >::Container &events, TraceContainer &trace)
GreaterThanTraceBuilder gt_builder
EventEmitter< GreaterThanEvent > gt_event_emitter
ExecutionIdManager execution_id_manager
EventEmitter< RangeCheckEvent > range_check_event_emitter
StrictMock< MockFieldGreaterThan > mock_field_gt
EventEmitter< DataCopyEvent > event_emitter
const std::vector< MemoryValue > data
StrictMock< MockContext > context
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
TEST_F(AvmRecursiveTests, GoblinRecursion)
A test of the Goblinized AVM recursive verifier.
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(TxExecutionConstrainingTest, WriteTreeValue)
lookup_settings< lookup_data_copy_check_dst_addr_in_range_settings_ > lookup_data_copy_check_dst_addr_in_range_settings
permutation_settings< perm_execution_dispatch_to_cd_copy_settings_ > perm_execution_dispatch_to_cd_copy_settings
lookup_settings< lookup_data_copy_data_index_upper_bound_gt_offset_settings_ > lookup_data_copy_data_index_upper_bound_gt_offset_settings
lookup_settings< lookup_data_copy_offset_plus_size_is_gt_data_size_settings_ > lookup_data_copy_offset_plus_size_is_gt_data_size_settings
lookup_settings< lookup_data_copy_check_src_addr_in_range_settings_ > lookup_data_copy_check_src_addr_in_range_settings
permutation_settings< perm_execution_dispatch_to_rd_copy_settings_ > perm_execution_dispatch_to_rd_copy_settings
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
uint32_t child_context_id