14DataCopyEvent create_cd_event(ContextInterface& context,
16 const uint32_t cd_copy_size,
19 const std::vector<FF>& calldata = {})
21 return DataCopyEvent{ .execution_clk = clk,
24 .write_context_id =
context.get_context_id(),
25 .read_context_id =
context.get_parent_id(),
26 .data_copy_size = cd_copy_size,
28 .data_addr =
context.get_parent_cd_addr(),
29 .data_size =
context.get_parent_cd_size(),
30 .is_nested =
context.has_parent(),
34DataCopyEvent create_rd_event(ContextInterface& context,
36 const uint32_t rd_copy_size,
37 const uint32_t rd_offset,
41 return DataCopyEvent{ .execution_clk = clk,
44 .write_context_id =
context.get_context_id(),
46 .read_context_id =
context.get_last_child_id(),
47 .data_copy_size = rd_copy_size,
48 .data_offset = rd_offset,
49 .data_addr =
context.get_last_rd_addr(),
50 .data_size =
context.get_last_rd_size(),
51 .is_nested =
context.has_parent(),
86 const uint32_t copy_size,
99 uint64_t max_read_index =
min(
static_cast<uint64_t
>(
offset) + copy_size,
context.get_parent_cd_size());
103 uint64_t max_read_addr = max_read_index +
context.get_parent_cd_addr();
104 uint64_t max_write_addr =
static_cast<uint64_t
>(
dst_addr) + copy_size;
110 if (read_out_of_range || write_out_of_range) {
111 throw std::runtime_error(
"Attempting to access out of bounds memory");
115 std::vector<FF> padded_calldata(copy_size, 0);
118 if (!
gt.gt(
static_cast<uint64_t
>(
offset), max_read_index)) {
122 for (uint32_t i = 0; i < copy_size; i++) {
123 memory.set(
dst_addr + i, MemoryValue::from<FF>(padded_calldata[i]));
127 }
catch (
const std::exception& e) {
128 debug(
"CD_COPY exception: ", e.what());
144 const uint32_t copy_size,
153 uint64_t max_read_index =
min(
static_cast<uint64_t
>(
offset) + copy_size,
context.get_last_rd_size());
155 uint64_t max_read_addr = max_read_index +
context.get_last_rd_addr();
156 uint64_t max_write_addr =
static_cast<uint64_t
>(
dst_addr) + copy_size;
162 if (read_out_of_range || write_out_of_range) {
163 throw std::runtime_error(
"Attempting to access out of bounds memory");
171 std::vector<FF> padded_returndata(copy_size, 0);
172 if (!
gt.gt(
static_cast<uint64_t
>(
offset), max_read_index)) {
173 padded_returndata =
context.get_returndata(
offset, copy_size);
176 for (uint32_t i = 0; i < copy_size; i++) {
177 memory.set(
dst_addr + i, MemoryValue::from<FF>(padded_returndata[i]));
182 }
catch (
const std::exception& e) {
183 debug(
"RD_COPY exception: ", e.what());
#define AVM_HIGHEST_MEM_ADDRESS
ExecutionIdGetterInterface & execution_id_manager
uint64_t min(uint64_t a, uint64_t b)
EventEmitterInterface< DataCopyEvent > & events
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,...
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.
virtual uint32_t get_execution_id() const =0
StrictMock< MockContext > context
std::vector< FF > calldata
std::vector< FF > returndata