-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/fix rlp push0 #286
Conversation
laisolizq
commented
May 5, 2023
- Add push0
- Fix RLP data length
main/utils.zkasm
Outdated
@@ -872,10 +872,13 @@ SHLarithfinal: | |||
|
|||
; out of counters full tracer event trigger | |||
outOfCountersStep: | |||
$ :MLOAD(isLoadRLP),JMPNZ(handleOOCSatRLP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think adding this check only once at handleBatchError
function?
$ :MLOAD(isLoadRLP),JMPNZ(invalidTxRLP)
And remove the handleOOCXatRLP
from the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and add $ => SR :MLOAD(batchSR)
in invalidTxRLP
main/vars.zkasm
Outdated
VAR CTX initTouchedSR ; touched root once a new context begins | ||
VAR CTX isLoadRLP ; flag to determine if the function is called from RLP loop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to isLoadingRLP or isProcessingRLP.
Also, it should be Global. Now we are just setting the flag to 0 at the last context.
main/main.zkasm
Outdated
|
||
$ => A :MLOAD(batchL2DataLength) | ||
$ => C :MLOAD(batchL2DataParsed) | ||
C - A :JMPN(loadTx_rlp, endCheckRLP) | ||
endCheckRLP: | ||
; set flag isLoadRLP to 0 | ||
0 :MSTORE(isLoadRLP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The var now is of type CTX. We have to options:
- Set the flag to 0 before calling
loadTx_rlp
: this way, all the CTX are set to 0 - Make the var GLOBAL: in this case we should set it to 1 only once just before
txLoopRLP
The current situation is that we are only setting the flag to 0 for the last processed context
main/opcodes/stack-operations.zkasm
Outdated
|
||
opPUSH0: | ||
; check out-of-gas | ||
GAS - %GAS_QUICK_STEP => GAS :JMPN(outOfGas) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lint: align with following instructions
main/utils.zkasm
Outdated
@@ -872,10 +872,13 @@ SHLarithfinal: | |||
|
|||
; out of counters full tracer event trigger | |||
outOfCountersStep: | |||
$ :MLOAD(isLoadRLP),JMPNZ(handleOOCSatRLP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and add $ => SR :MLOAD(batchSR)
in invalidTxRLP
main/utils.zkasm
Outdated
@@ -1153,6 +1156,7 @@ finalPush: | |||
VAR GLOBAL tmpVarDaddB | |||
VAR GLOBAL tmpZkPCaddB | |||
VAR GLOBAL auxBytes | |||
VAR GLOBAL auxLengthBytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not only used in this function, so this global variable should be in vars.zkasm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can compute in invalidTxRLP
:
batchHashPos
-batchL2DataLength
to check how many bytes are missing to fill in the thebatchHashData
- so we can save the
auxLengthBytes
variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
Yes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😸
@@ -7,6 +7,15 @@ | |||
* - stack input: none | |||
* - stack output: [pushed_value] | |||
*/ | |||
|
|||
opPUSH0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it not consume any ZK counters? I would think that gas check at stack check do. Even POP requires 100 steps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we would add them
@@ -7,6 +7,15 @@ | |||
* - stack input: none | |||
* - stack output: [pushed_value] | |||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment applies to opPUSH1
and further, opPUSH0
should be above it and with its own comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree !! We will add specific comment for PUSH0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also you need a newer link https://www.evm.codes/#5f?fork=shanghai
invalidTxRLP: | ||
;; Append all missing 'batchL2Data' to 'batchDataHash' bytes | ||
$ => B :MLOAD(batchL2DataLength) | ||
$ => C :MLOAD(batchHashPos) | ||
$${p = C} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? Seems like it can change behaviour (of getTxs()
?) significantly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p
is the pointer to the read transactions bytes via getTxs()
.
While reading RLP, we add bytes to the batchHash
and perform some check afterwards, but the bytes are already added. So, if anything goes wrong we jump to invalidTxRLP
to load the remaining bytes. The remaining bytes where added starting at p
, where the p
was set during the RLP parsing. This was always true before, but if we perform the check before the bytes are added to the batchHash
, then it will not match the batchHash
.
The generic way to add the missing batchHash
bytes was to simply set the pointer p
to starting byte to add, which is stored in batchHashPos
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as I understand this error processing is now called from more places (utils
generating out-of-counters errors), including from the points where p
is not updated yet, so it is initialized explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining bytes where added starting at
p
, where thep
was set during the RLP parsing.
But for old cases, where this error processing is called after p
is already set, wouldn't this code here add more bytes than needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as I understand this error processing is now called from more places (
utils
generating out-of-counters errors), including from the points wherep
is not updated yet, so it is initialized explicitly.
exactly!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining bytes where added starting at
p
, where thep
was set during the RLP parsing.But for old cases, where this error processing is called after
p
is already set, wouldn't this code here add more bytes than needed?
for old cases, new code will just only set the p
where it was already read, so it will just only rewrite the p
with same value
@@ -928,6 +928,7 @@ handleError: | |||
handleBatchError: | |||
; restore init state root and finish batch | |||
$ => SR :MLOAD(batchSR) | |||
$ :MLOAD(isLoadingRLP),JMPNZ(invalidTxRLP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to have a comment why RLP error processing is different
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case isLoadingRLP
is 1
and you jump to invalidTxRLP
(and later to processTxsEnd
) the isLoadingRLP
remains 1
. May this cause any problems (e.g. infinite loops) or confusion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This flag is not used outside the zkevm-rom
so it could not cause any issue.
I would say the opposite, it could add information if the limit counters has been reached during the RLP
Some general thoughts about RLP fix, maybe missing the entire picture and all implications. In general it feels like fixing the problem of managing one global thing (ZK counters, behaving differently in different contexts), with adding more global data. Overall this increases complexity and potential implicit interdependencies and difficulty of reasoning about code. Ideally I think it would be better to make this dependency explicit by e.g. having an extra flag parameter to those I can see that this might be impractical if those |
We decided to go with the |