Skip to content

Commit 2d608ff

Browse files
authored
fix(avm)!: data_copy permutation (#16531)
Implements the permutations for cd_copy and rd_copy to the execution trace. It needs to be two different permutations (even though they lead to the same gadget) because they operate on different columns of execution (parent vs child). Hence, most instance of `DATACOPY` have been split into `CDCOPY` and `RDCOPY` There was also a range of bug fixes uncovered because of this. 1. Not including the parent calldata size at enqueued call contexts in execution. 2. Not serialized parent calldata information in the when entering a new call Calldata size needs to be properly handled at the tx trace level (in conjunction with calldata hashing). It's not solved here but tracked [here](#14666)
2 parents 708d702 + 76b8c1e commit 2d608ff

File tree

29 files changed

+756
-359
lines changed

29 files changed

+756
-359
lines changed

barretenberg/cpp/pil/vm2/constants_gen.pil

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ namespace constants;
4343
pol AVM_SUBTRACE_ID_TO_RADIX = 64;
4444
pol AVM_SUBTRACE_ID_ECC = 128;
4545
pol AVM_SUBTRACE_ID_KECCAKF1600 = 256;
46-
pol AVM_SUBTRACE_ID_DATA_COPY = 512;
46+
pol AVM_SUBTRACE_ID_CALLDATA_COPY = 512;
4747
pol AVM_SUBTRACE_ID_GETCONTRACTINSTANCE = 1024;
4848
pol AVM_SUBTRACE_ID_EMITUNENCRYPTEDLOG = 2048;
4949
pol AVM_SUBTRACE_ID_SHA256_COMPRESSION = 4096;
50+
pol AVM_SUBTRACE_ID_RETURNDATA_COPY = 8192;
5051
pol AVM_DYN_GAS_ID_CALLDATACOPY = 1;
5152
pol AVM_DYN_GAS_ID_RETURNDATACOPY = 2;
5253
pol AVM_DYN_GAS_ID_TORADIX = 4;

barretenberg/cpp/pil/vm2/context.pil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ namespace execution;
3737
pol commit parent_calldata_addr;
3838
pol commit parent_calldata_size;
3939

40+
pol commit last_child_id;
4041
pol commit last_child_returndata_addr;
4142
pol commit last_child_returndata_size;
4243
pol commit last_child_success; // Careful with this for now...

barretenberg/cpp/pil/vm2/data_copy.pil

Lines changed: 94 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ include "calldata.pil";
33
include "precomputed.pil";
44
include "constants_gen.pil";
55
include "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

6687
namespace 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+
};

barretenberg/cpp/pil/vm2/execution.pil

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ pol commit sel_execute_to_radix;
408408
pol commit sel_execute_poseidon2_perm;
409409
pol commit sel_execute_ecc_add;
410410
pol commit sel_execute_execution;
411-
pol commit sel_execute_data_copy;
411+
pol commit sel_execute_calldata_copy;
412+
pol commit sel_execute_returndata_copy;
412413
pol commit sel_execute_keccakf1600;
413414
pol commit sel_execute_get_contract_instance;
414415
pol commit sel_execute_emit_unencrypted_log;
@@ -421,7 +422,8 @@ sel_execute_to_radix * (1 - sel_execute_to_radix) = 0;
421422
sel_execute_poseidon2_perm * (1 - sel_execute_poseidon2_perm) = 0;
422423
sel_execute_ecc_add * (1 - sel_execute_ecc_add) = 0;
423424
sel_execute_execution * (1 - sel_execute_execution) = 0;
424-
sel_execute_data_copy * (1 - sel_execute_data_copy) = 0;
425+
sel_execute_calldata_copy * (1 - sel_execute_calldata_copy) = 0;
426+
sel_execute_returndata_copy * (1 - sel_execute_returndata_copy) = 0;
425427
sel_execute_keccakf1600 * (1 - sel_execute_keccakf1600) = 0;
426428
sel_execute_get_contract_instance * (1 - sel_execute_get_contract_instance) = 0;
427429
sel_execute_emit_unencrypted_log * (1 - sel_execute_emit_unencrypted_log) = 0;
@@ -437,10 +439,11 @@ sel_execute_poseidon2_perm * constants.AVM_SUBTRACE_ID_POSEIDON_PERM +
437439
sel_execute_to_radix * constants.AVM_SUBTRACE_ID_TO_RADIX +
438440
sel_execute_ecc_add * constants.AVM_SUBTRACE_ID_ECC +
439441
sel_execute_keccakf1600 * constants.AVM_SUBTRACE_ID_KECCAKF1600 +
440-
sel_execute_data_copy * constants.AVM_SUBTRACE_ID_DATA_COPY +
442+
sel_execute_calldata_copy * constants.AVM_SUBTRACE_ID_CALLDATA_COPY +
441443
sel_execute_get_contract_instance * constants.AVM_SUBTRACE_ID_GETCONTRACTINSTANCE +
442444
sel_execute_emit_unencrypted_log * constants.AVM_SUBTRACE_ID_EMITUNENCRYPTEDLOG +
443-
sel_execute_sha256_compression * constants.AVM_SUBTRACE_ID_SHA256_COMPRESSION
445+
sel_execute_sha256_compression * constants.AVM_SUBTRACE_ID_SHA256_COMPRESSION +
446+
sel_execute_returndata_copy * constants.AVM_SUBTRACE_ID_RETURNDATA_COPY
444447
// We force the selectors to be 0 if we are not executing an opcode.
445448
= sel_should_execute_opcode * subtrace_id;
446449

barretenberg/cpp/src/barretenberg/vm2/common/aztec_constants.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@
5353
#define AVM_SUBTRACE_ID_TO_RADIX 64
5454
#define AVM_SUBTRACE_ID_ECC 128
5555
#define AVM_SUBTRACE_ID_KECCAKF1600 256
56-
#define AVM_SUBTRACE_ID_DATA_COPY 512
56+
#define AVM_SUBTRACE_ID_CALLDATA_COPY 512
5757
#define AVM_SUBTRACE_ID_GETCONTRACTINSTANCE 1024
5858
#define AVM_SUBTRACE_ID_EMITUNENCRYPTEDLOG 2048
5959
#define AVM_SUBTRACE_ID_SHA256_COMPRESSION 4096
60+
#define AVM_SUBTRACE_ID_RETURNDATA_COPY 8192
6061
#define AVM_DYN_GAS_ID_CALLDATACOPY 1
6162
#define AVM_DYN_GAS_ID_RETURNDATACOPY 2
6263
#define AVM_DYN_GAS_ID_TORADIX 4

0 commit comments

Comments
 (0)