Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
data_copy.test.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4#include <gmock/gmock.h>
5#include <gtest/gtest.h>
6
16
17namespace bb::avm2::simulation {
18namespace {
19
20using ::testing::ElementsAre;
21using ::testing::Return;
22using ::testing::ReturnRef;
23using ::testing::StrictMock;
24
25class DataCopySimulationTest : public ::testing::Test {
26 protected:
27 DataCopySimulationTest()
28 {
29 ON_CALL(context, get_memory).WillByDefault(ReturnRef(mem));
30
31 // Standard EventEmitter Expectations
32 EXPECT_CALL(context, get_memory());
33 EXPECT_CALL(execution_id_manager, get_execution_id());
34 EXPECT_CALL(context, get_context_id());
35 }
36
38 StrictMock<MockExecutionIdManager> execution_id_manager;
39 PureGreaterThan gt;
40 StrictMock<MockContext> context;
41 EventEmitter<DataCopyEvent> event_emitter;
42 DataCopy data_copy = DataCopy(execution_id_manager, gt, event_emitter);
43
44 uint32_t dst_addr = 0; // Destination address in memory for the copied returndata.
45};
46
47class NestedCdCopySimulationTest : public DataCopySimulationTest {
48 protected:
49 NestedCdCopySimulationTest()
50 {
51 // Load up parent context
52 for (uint32_t i = 0; i < parent_cd_size; ++i) {
54 }
55 EXPECT_CALL(context, get_parent_cd_addr()).WillRepeatedly(Return(parent_cd_addr));
56 EXPECT_CALL(context, get_parent_cd_size()).WillRepeatedly(Return(parent_cd_size));
57 EXPECT_CALL(context, get_parent_id());
58 EXPECT_CALL(context, has_parent()).WillRepeatedly(Return(true));
59 }
60
61 std::vector<FF> calldata = { 1, 2, 3, 4, 5, 6, 7, 8 };
62 uint32_t parent_cd_addr = 100; // Address where the parent calldata is stored.
63 uint32_t parent_cd_size = static_cast<uint32_t>(calldata.size());
64 uint32_t cd_offset = 0;
65};
66
67TEST_F(NestedCdCopySimulationTest, CdZero)
68{
69 // Copy zero calldata from the parent context to memory
70 uint32_t cd_copy_size = 0;
71 uint32_t cd_offset = 0;
72
73 EXPECT_CALL(context, get_calldata(cd_offset, cd_copy_size))
74 .WillOnce(Return(std::vector<FF>{})); // Should return empty vector
75
76 data_copy.cd_copy(context, cd_copy_size, cd_offset, dst_addr);
77
78 auto c = mem.get(dst_addr);
79 EXPECT_TRUE(c.as_ff().is_zero());
80}
81
82TEST_F(NestedCdCopySimulationTest, CdCopyAll)
83{
84 // Copy all calldata from the parent context to memory
85 uint32_t cd_copy_size = static_cast<uint32_t>(calldata.size());
86
87 EXPECT_CALL(context, get_calldata(cd_offset, cd_copy_size)).WillOnce(Return(calldata));
88
89 uint32_t dst_addr = 0;
90 data_copy.cd_copy(context, cd_copy_size, cd_offset, dst_addr);
91
92 // This should write all the calldata values
93 std::vector<FF> calldata_in_memory;
94 for (uint32_t i = 0; i < cd_copy_size; ++i) {
95 auto c = mem.get(dst_addr + i);
96 calldata_in_memory.emplace_back(c.as_ff());
97 }
98 EXPECT_THAT(calldata_in_memory, ElementsAre(1, 2, 3, 4, 5, 6, 7, 8));
99}
100
101TEST_F(NestedCdCopySimulationTest, CdCopyPartial)
102{
103 // Copy come calldata from the parent context to memory
104 uint32_t cd_copy_size = 2;
105
106 EXPECT_CALL(context, get_calldata(cd_offset, cd_copy_size))
107 .WillOnce(Return(std::vector<FF>{ 1, 2 })); // Only copy first two values
108
109 data_copy.cd_copy(context, cd_copy_size, cd_offset, dst_addr);
110
111 // This should write all the calldata values
112 std::vector<FF> calldata_in_memory;
113 for (uint32_t i = 0; i < cd_copy_size; ++i) {
114 auto c = mem.get(dst_addr + i);
115 calldata_in_memory.emplace_back(c.as_ff());
116 }
117 EXPECT_THAT(calldata_in_memory, ElementsAre(1, 2));
118}
119
120TEST_F(NestedCdCopySimulationTest, CdFullWithPadding)
121{
122 // Copy some calldata from the parent context to memory, but with padding
123 uint32_t cd_copy_size = 10; // Request more than available
124
125 std::vector<FF> expected_calldata = { 1, 2, 3, 4, 5, 6, 7, 8, 0, 0 }; // Should pad with zeros
126 EXPECT_CALL(context, get_calldata(cd_offset, cd_copy_size)).WillOnce(Return(expected_calldata));
127
128 data_copy.cd_copy(context, cd_copy_size, cd_offset, dst_addr);
129
130 // This should write all the calldata values and pad the rest with zeros
131 std::vector<FF> calldata_in_memory;
132 for (uint32_t i = 0; i < cd_copy_size; ++i) {
133 auto c = mem.get(dst_addr + i);
134 calldata_in_memory.emplace_back(c.as_ff());
135 }
136 EXPECT_THAT(calldata_in_memory, ElementsAre(1, 2, 3, 4, 5, 6, 7, 8, 0, 0));
137}
138
139TEST_F(NestedCdCopySimulationTest, CdPartialWithPadding)
140{
141 // Copy some calldata from the parent context to memory, but with padding
142 uint32_t cd_copy_size = 4; // Request more than available
143 uint32_t cd_offset = 6; // Offset into calldata
144
145 std::vector<FF> expected_calldata = { 7, 8, 0, 0 }; // Should pad with zeros
146
147 EXPECT_CALL(context, get_calldata(cd_offset, cd_copy_size)).WillOnce(Return(expected_calldata));
148
149 data_copy.cd_copy(context, cd_copy_size, cd_offset, dst_addr);
150
151 // This should write all the calldata values and pad the rest with zeros
152 std::vector<FF> calldata_in_memory;
153 for (uint32_t i = 0; i < cd_copy_size; ++i) {
154 auto c = mem.get(dst_addr + i);
155 calldata_in_memory.emplace_back(c.as_ff());
156 }
157 EXPECT_THAT(calldata_in_memory, ElementsAre(7, 8, 0, 0));
158}
159
160class RdCopySimulationTest : public DataCopySimulationTest {
161 protected:
162 RdCopySimulationTest()
163 {
164 // Set up the parent context address
165 EXPECT_CALL(context, get_last_rd_addr()).WillRepeatedly(Return(child_rd_addr));
166 EXPECT_CALL(context, get_last_rd_size()).WillRepeatedly(Return(child_rd_size));
167 EXPECT_CALL(context, get_last_child_id()).WillRepeatedly(Return(child_context_id));
168 EXPECT_CALL(context, has_parent()).WillRepeatedly(Return(true));
169 EXPECT_CALL(context, get_last_child_id()).WillRepeatedly(Return(2));
170 }
171 std::vector<FF> returndata = { 9, 10, 11, 12 }; // Example returndata to be copied.
172 uint32_t child_rd_size = static_cast<uint32_t>(returndata.size());
173 uint32_t child_rd_addr = 200; // Address where the parent returndata is stored.
174 uint32_t child_context_id = 2;
175};
176
177TEST_F(RdCopySimulationTest, RdZero)
178{
179 // Copy zero returndata from the last executed context to memory
180 uint32_t rd_copy_size = 0;
181 uint32_t rd_offset = 0;
182
183 EXPECT_CALL(context, get_returndata(rd_offset, rd_copy_size))
184 .WillOnce(Return(std::vector<FF>{})); // Should return empty vector
185
186 data_copy.rd_copy(context, rd_copy_size, rd_offset, dst_addr);
187
188 auto c = mem.get(dst_addr);
189 EXPECT_TRUE(c.as_ff().is_zero());
190}
191
192TEST_F(RdCopySimulationTest, RdCopyAll)
193{
194 // Copy all returndata from the last executed context to memory
195 uint32_t rd_copy_size = static_cast<uint32_t>(returndata.size());
196 uint32_t rd_offset = 0;
197
198 EXPECT_CALL(context, get_returndata(rd_offset, rd_copy_size)).WillOnce(Return(returndata));
199
200 data_copy.rd_copy(context, rd_copy_size, rd_offset, dst_addr);
201
202 // This should write all the returndata values
203 std::vector<FF> returndata_in_memory;
204 for (uint32_t i = 0; i < rd_copy_size; ++i) {
205 auto c = mem.get(dst_addr + i);
206 returndata_in_memory.emplace_back(c.as_ff());
207 }
208 EXPECT_THAT(returndata_in_memory, ElementsAre(9, 10, 11, 12));
209}
210
211TEST_F(RdCopySimulationTest, RdCopyPartial)
212{
213 // Copy some returndata from the last executed context to memory
214 uint32_t rd_copy_size = 2;
215 uint32_t rd_offset = 1; // Start copying from second element
216
217 EXPECT_CALL(context, get_returndata(rd_offset, rd_copy_size))
218 .WillOnce(Return(std::vector<FF>{ 10, 11 })); // Only copy second and third values
219
220 data_copy.rd_copy(context, rd_copy_size, rd_offset, dst_addr);
221
222 // This should write the selected returndata values
223 std::vector<FF> returndata_in_memory;
224 for (uint32_t i = 0; i < rd_copy_size; ++i) {
225 auto c = mem.get(dst_addr + i);
226 returndata_in_memory.emplace_back(c.as_ff());
227 }
228 EXPECT_THAT(returndata_in_memory, ElementsAre(10, 11));
229}
230
231TEST_F(RdCopySimulationTest, RdFullWithPadding)
232{
233 // Copy some returndata from the last executed context to memory, but with padding
234 uint32_t rd_copy_size = 10; // Request more than available
235 uint32_t rd_offset = 0; // Start copying from first element
236
237 std::vector<FF> expected_returndata = { 9, 10, 11, 12, 0, 0, 0, 0, 0, 0 }; // Should pad with zeros
238 EXPECT_CALL(context, get_returndata(rd_offset, rd_copy_size)).WillOnce(Return(expected_returndata));
239
240 data_copy.rd_copy(context, rd_copy_size, rd_offset, dst_addr);
241
242 // This should write all the returndata values and pad the rest with zeros
243 std::vector<FF> returndata_in_memory;
244 for (uint32_t i = 0; i < rd_copy_size; ++i) {
245 auto c = mem.get(dst_addr + i);
246 returndata_in_memory.emplace_back(c.as_ff());
247 }
248 EXPECT_THAT(returndata_in_memory, ElementsAre(9, 10, 11, 12, 0, 0, 0, 0, 0, 0));
249}
250
251TEST_F(RdCopySimulationTest, RdPartialWithPadding)
252{
253 // Copy some returndata from the last executed context to memory, but with padding
254 uint32_t rd_copy_size = 4; // Request more than available
255 uint32_t rd_offset = 2; // Start copying from third element
256
257 std::vector<FF> expected_returndata = { 11, 12, 0, 0 }; // Should pad with zeros
258
259 EXPECT_CALL(context, get_returndata(rd_offset, rd_copy_size)).WillOnce(Return(expected_returndata));
260
261 data_copy.rd_copy(context, rd_copy_size, rd_offset, dst_addr);
262
263 // This should write all the returndata values and pad the rest with zeros
264 std::vector<FF> returndata_in_memory;
265 for (uint32_t i = 0; i < rd_copy_size; ++i) {
266 auto c = mem.get(dst_addr + i);
267 returndata_in_memory.emplace_back(c.as_ff());
268 }
269 EXPECT_THAT(returndata_in_memory, ElementsAre(11, 12, 0, 0));
270}
271
272} // namespace
273} // namespace bb::avm2::simulation
static TaggedValue from(T value)
void cd_copy(ContextInterface &context, const uint32_t cd_copy_size, const uint32_t cd_offset, const MemoryAddress dst_addr) override
Writes calldata into dst_addr. There is slight difference in how enqueued and nested contexts,...
Definition data_copy.cpp:85
void rd_copy(ContextInterface &context, const uint32_t rd_copy_size, const uint32_t rd_offset, const MemoryAddress dst_addr) override
Copies returndata from the last executed context to the dst_addr.
const MemoryValue & get(MemoryAddress index) const override
ExecutionIdManager execution_id_manager
MemoryStore mem
EventEmitter< DataCopyEvent > event_emitter
uint32_t dst_addr
GreaterThan gt
StrictMock< MockContext > context
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:188
std::vector< FF > calldata
uint32_t child_rd_addr
uint32_t parent_cd_addr
uint32_t child_context_id
uint32_t child_rd_size
DataCopy data_copy
uint32_t parent_cd_size
std::vector< FF > returndata
uint32_t cd_offset