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