@@ -3,6 +3,7 @@ include "calldata.pil";
33include "precomputed.pil";
44include "constants_gen.pil";
55include "range_check.pil";
6+ include "context.pil";
67
78/** This trace handles CALLDATACOPY and RETURNDATACOPY
89 * The data_copy gadget handles CALLDATACOPY (both enqueued and nested) and RETURNDATACOPY
@@ -21,22 +22,42 @@ include "range_check.pil";
2122 * padding rows are constrained to have the value = 0.
2223 *
2324 * It is memory aware and so is expected to call the memory subtrace directly
24- * Example: Lookup to execution trace
25- * execution.sel_data_copy {
26- * clk, context_id,
27- * context_id, parent_id
28- * reg1, mem_tag1, reg2, mem_tag2, rop3
29- * parent_callsrc_data_size, parent_calloffset,
30- * gadget_id
31- * }
32- * in
33- * sel_data_copy {
34- * clk, context_id,
35- * src_context_id, dst_context_id,
36- * copy_size, copy_size_mem_tag, offset, offset_mem_tag, dst_address
37- * src_data_size, src_addr,
38- * operation_id
39- * }
25+ *
26+ * Note that there are two ways that this subtrace is invoked from the execution trace: CD_COPY or RD_COPY
27+ * This requires two permutations because they operate on different execution trace cols (parent vs child)
28+ * CD COPY
29+ * execution.sel_calldata_copy {
30+ * clk,
31+ * parent_id, context_id,
32+ * reg[0], reg[1], rop[2],
33+ * parent_calldata_addr, parent_calldata_size,
34+ * sel_calldata_copy, sel_opcode_error
35+ * }
36+ * in
37+ * sel_start {
38+ * clk,
39+ * src_context_id, dst_context_id,
40+ * copy_size, offset, dst_addr,
41+ * src_addr, src_data_size,
42+ * sel_cd_copy, err
43+ * }
44+ *
45+ * RD COPY
46+ * execution.sel_returndata_copy {
47+ * clk,
48+ * last_child_id, context_id,
49+ * reg[0], reg[1], rop[2],
50+ * last_child_returndata_addr, last_child_returndata_size,
51+ * sel_returndata_copy, sel_opcode_error
52+ * }
53+ * is
54+ * sel_rd_copy_start {
55+ * clk,
56+ * src_context_id, dst_context_id,
57+ * copy_size, offset, dst_addr,
58+ * src_addr, src_data_size,
59+ * sel_rd_copy, err
60+ * };
4061 *
4162 * Reading from calldata column
4263 * Calldata Trace
@@ -47,12 +68,12 @@ include "range_check.pil";
4768 * | 1 | 200 | 2 | 1 |
4869 * | 1 | 300 | 3 | 1 |
4970 * +-----+-------+-------+------------+
50- * Execution Trace (cd_size) (cd_offset)
51- * +-----+-----+------------+-----------+------------+------------+
52- * | clk | sel | context_id | parent_id | register_1 | register_2 |
53- * +-----+-----+------------+-----------+------------+------------+
54- * | 1 | 1 | 1 | 0 | 3 | 0 |
55- * +-----+-----+------------+-----------+------------+------------+
71+ * Execution Trace (dst_addr) (cd_size) (cd_offset)
72+ * +-----+-----+------------+-----------+---------------+------------ +------------+
73+ * | clk | sel | context_id | parent_id | resolved_op_2 | register_0 | register_1 |
74+ * +-----+-----+------------+-----------+---------------+------------ +------------+
75+ * | 1 | 1 | 1 | 0 | 0 | 3 | 0 |
76+ * +-----+-----+------------+-----------+---------------+------------ +------------+
5677 * DataCopy Trace
5778 * +-------------+------------+------------+-----------+------------------+----------+-------+------------+
5879 * | sel_cd_copy | src_ctx_id | dst_ctx_id | copy_size | cd_copy_col_read | cd_index | value | dst_addr |
@@ -61,7 +82,7 @@ include "range_check.pil";
6182 * | 1 | 0 | 1 | 2 | 1 | 2 | 200 | 6 |
6283 * | 1 | 0 | 1 | 1 | 1 | 3 | 300 | 7 |
6384 * +-------------+------------+------------+-----------+------------------+----------+-------+------------+
64- */
85+ */
6586
6687namespace data_copy;
6788
@@ -77,11 +98,6 @@ namespace data_copy;
7798 pol commit sel_rd_copy;
7899 sel_rd_copy * (1 - sel_rd_copy) = 0;
79100
80- // Gadget ID is supplied by the execution trace, if non-zero it can be 1 or 2 (instruction spec constrained)
81- // depending on if the operation is calldatacopy or returndatacopy respectively
82- pol commit operation_id;
83- // Bitwise decomposition
84- operation_id = sel_cd_copy + (2 ** 1) * sel_rd_copy;
85101 // Two varieties depending of if we gate by error
86102 pol SEL_NO_ERR = SEL * (1 - err);
87103
@@ -171,7 +187,7 @@ namespace data_copy;
171187 // Memory Out of Range: If reading or writing would access an address outside of the AVM memory range
172188 // If there is an error, no data copy operation is performed
173189
174- // Memory Out of Range, this section checks that the maximum number of reads ans writes do not
190+ // Memory Out of Range, this section checks that the maximum number of reads ans writes do not
175191 // If top level, we trivially succeed since there is no mem read i.e. we cannot have a src_out_of_range_err
176192 pol MAX_READ_ADDR = (src_addr + MAX_READ_INDEX) * (1 - is_top_level);
177193 pol commit abs_read_diff;
@@ -189,13 +205,13 @@ namespace data_copy;
189205 sel_start { abs_write_diff, thirty_two } in range_check.sel { range_check.value, range_check.rng_chk_bits };
190206
191207 //////////////////////////////
192- // Control flow management
208+ // Control flow management
193209 //////////////////////////////
194210 pol commit sel_start_no_err;
195211 sel_start_no_err * (1 - sel_start_no_err) = 0;
196212 sel_start_no_err = sel_start * (1 - err);
197213
198- // An active row succeeding sel_end has to be a sel_start
214+ // An active row succeeding sel_end has to be a sel_start
199215 #[START_AFTER_END]
200216 (sel_cd_copy' + sel_rd_copy') * sel_end * (sel_start' - 1) = 0;
201217
@@ -224,7 +240,7 @@ namespace data_copy;
224240
225241 // If sel_offset_gt_max_read = 1 (i.e. when offset > MAX_READ_INDEX, reads_left = 0)
226242 // otherwise, reads_left = MAX_READ_INDEX - offset
227- #[INIT_READS_LEFT]
243+ #[INIT_READS_LEFT]
228244 SEL * sel_start_no_err * (reads_left - OFFSET_LTE_MAX_READ * (1 - sel_offset_gt_max_read)) = 0;
229245
230246 //////////////////////////////
@@ -254,7 +270,7 @@ namespace data_copy;
254270 #[INCR_READ_ADDR]
255271 SEL * (1 - padding) * (1 - sel_end) * (read_addr' - read_addr - 1) = 0;
256272
257- // Read count decrements
273+ // Read count decrements
258274 #[DECR_READ_COUNT]
259275 SEL * (1 - padding) * (1 - sel_end) * (reads_left' - reads_left + 1) = 0;
260276 pol commit padding; // Padding = 1 if reads_left = 0
@@ -289,3 +305,48 @@ namespace data_copy;
289305 in
290306 calldata.sel { calldata.value, calldata.context_id, calldata.index };
291307
308+ ////////////////////////////////////////////////
309+ // Dispatch Permutation
310+ ////////////////////////////////////////////////
311+ // Since these are permutations, we need to distinguish between the start
312+ // of a cd_copy and rd_copy.
313+ // Note that the value of sel_cd_copy and sel_rd_copy are constrained by their
314+ // inclusion inside the permutation.
315+
316+ pol commit sel_cd_copy_start;
317+ sel_cd_copy_start = sel_start * sel_cd_copy;
318+ #[DISPATCH_CD_COPY]
319+ execution.sel_execute_calldata_copy {
320+ precomputed.clk,
321+ execution.parent_id, execution.context_id,
322+ execution.register[0], execution.register[1], execution.rop[2],
323+ execution.parent_calldata_addr, execution.parent_calldata_size,
324+ execution.sel_execute_calldata_copy/*=1*/, execution.sel_opcode_error
325+ }
326+ is
327+ sel_cd_copy_start {
328+ clk,
329+ src_context_id, dst_context_id,
330+ copy_size, offset, dst_addr,
331+ src_addr, src_data_size,
332+ sel_cd_copy, err
333+ };
334+
335+ pol commit sel_rd_copy_start;
336+ sel_rd_copy_start = sel_start * sel_rd_copy;
337+ #[DISPATCH_RD_COPY]
338+ execution.sel_execute_returndata_copy {
339+ precomputed.clk,
340+ execution.last_child_id, execution.context_id,
341+ execution.register[0], execution.register[1], execution.rop[2],
342+ execution.last_child_returndata_addr, execution.last_child_returndata_size,
343+ execution.sel_execute_returndata_copy/*=1*/, execution.sel_opcode_error
344+ }
345+ is
346+ sel_rd_copy_start {
347+ clk,
348+ src_context_id, dst_context_id,
349+ copy_size, offset, dst_addr,
350+ src_addr, src_data_size,
351+ sel_rd_copy, err
352+ };
0 commit comments