Copy Circuit#194
Conversation
357e49e to
6415046
Compare
888d073 to
e22a654
Compare
|
@icemelon You will need to edit this PR from "draft" to "open" |
ed255
left a comment
There was a problem hiding this comment.
Overall looks very good!
I've added a few notes here and there but they are mainly topics for discussion and some small suggestions.
|
|
||
| def __init__(self) -> None: | ||
| self.rows = [] | ||
| self.pad_rows = [CopyCircuitRow(*[FQ(0)] * 18)] * 2 |
There was a problem hiding this comment.
This is an example of how padding rows work right? Not padding in the sense that a 0 is read after the src end; but in the sense that the circuit has a fixed number of rows and maybe not all of them are used.
If that's the case, could you add a line in the markdown doc saying that padding rows are set to all 0s, and that these values always pass the constraints?
Thanks for the suggestions. They all make sense and I'll update the PR soon :) |
| # bytes_left == 1 for last step | ||
| cs.constrain_zero(rows[1].is_last * (1 - rows[0].bytes_left)) | ||
| # bytes_left == bytes_left_next + 1 for non-last step | ||
| cs.constrain_zero((1 - rows[1].is_last) * (rows[0].bytes_left - rows[2].bytes_left - 1)) |
There was a problem hiding this comment.
not sure why use rows[2].bytes_left , refer to last step second row?
There was a problem hiding this comment.
If rows[0] is the read step (given that condition rows[0].q_step) then we want to constrain:
rows[0].bytes_left == rows[2].bytes_left + 1 as rows[2] is the next read step if rows[1] was not the last step.
|
just have a quick look ,one point to discuss: seems to me maybe there is possible duplicated constraint between copy circuit and state circuit. for example, read value constrain to be equal to writing value at the same address. in the state circuit should constrain this (even though not implemented yet sort of) by design, but it is not big problem from my side. |
roynalnaruto
left a comment
There was a problem hiding this comment.
Small question WRT some removed checks
Are you referring to the constraint that the value in the write row is the same as the value in the read row (of the same copy step)? If that's the case, I don't see how it's redundant as the CopyCircuit is copying between two different places. Could you elaborate on this duplicate constraint between Copy Circuit and State Circuit; and point to the exact constraint in the python spec? Thanks! |
| src_id: FQ | ||
| src_type: FQ | ||
| dst_id: FQ | ||
| dst_type: FQ | ||
| src_addr: FQ | ||
| src_addr_end: FQ | ||
| dst_addr: FQ | ||
| length: FQ | ||
| rw_counter: FQ | ||
| rwc_inc: FQ | ||
| log_id: FQ = field(default=FQ(0)) |
There was a problem hiding this comment.
| src_id: FQ | |
| src_type: FQ | |
| dst_id: FQ | |
| dst_type: FQ | |
| src_addr: FQ | |
| src_addr_end: FQ | |
| dst_addr: FQ | |
| length: FQ | |
| rw_counter: FQ | |
| rwc_inc: FQ | |
| log_id: FQ = field(default=FQ(0)) | |
| src_id: FQ # Copy source type-specific id. The id for each type is: {Bytecode: code_hash, Memory: call_id, TxCallData: tx_id, TxLog: tx_id} | |
| src_type: FQ # Copy source type from `CopyDataTypeTag` | |
| dst_id: FQ # Copy destination type-specific id | |
| dst_type: FQ # Copy destination type from `CopyDataTypeTag` | |
| src_addr: FQ # Copy source start address / index | |
| src_addr_end: FQ # Size of the Copy source. When source address equals this value or higher, the read value is `0`. | |
| dst_addr: FQ # Copy destination start address / index | |
| length: FQ # Copy length: number of bytes written into destination | |
| rw_counter: FQ # Rw counter value at the beginning of the copy | |
| rwc_inc: FQ # How much will the rw_counter increase after the copy is complete | |
| log_id: FQ = field(default=FQ(0)) |
Field description suggestions.
NOTE: I later realized that this fields are properly described in tables.md, so maybe these comments are redundant.
3eb2dc3 to
50b77d2
Compare
I check current state circuit don't constrain value read/write consistency for now, so it not problem ! |
| - **is_last**: a boolean value to indicate the last row in a copy event. | ||
| - **ID**: could be `$txID`, `$callID`, `$codeHash` (RLC encoded). | ||
| - **Type**: indicates the type of data source, including `Memory`, `Bytecode`, `TxCalldata`, `TxLog`. | ||
| - **Address**: indicates the address in the source data, could be memory address, byte index in the bytecode, tx call data, and tx log data. When the data type is `TxLog`, the address is the combination of byte index, `TxLogFieldTag.Data` tag, and `LogID`. |
There was a problem hiding this comment.
after #214 merged, Address for TxLog change to log_id + field_tag + index now. maybe need update accordingly . thanks !
There was a problem hiding this comment.
Yes, I already updated the txlog lookup in the latest commit. could you help take a look?
But that's just because it's a TODO rigth? The spec has de read consistency constraint: https://github.com/privacy-scaling-explorations/zkevm-specs/blob/34eafad5f5c1031834d48adc2499a0f94bc3ae3e/src/zkevm_specs/state.py#L490-L496 Once the read consistency constraint is added to the state circuit, do you think there will be redundancy of constraints with the copy circuit? |
|
@lispc in case you haven't reviewed this yet; could you take a look please? So that we reach 2 approvals :) |
b200a05 to
bed19e2
Compare
|
@ed255 @roynalnaruto OK! I missed it! i will have a review now |
|
great job! current codes seems much more elegant! |
|
@icemelon feel free to merge this PR whenever you like :) (as you submitted it originally) |
@ed255 sorry for the delay, yes, I think so , current state circuit don't implement yet. we can keep an eye when it starts implementation . |
This PR brings the copy circuit that eliminates the multi-slot opcodes such as CALLDATACOPY, CODECOPY, and LOG.