Skip to content
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

Merged
merged 6 commits into from
May 11, 2023
Merged

Feature/fix rlp push0 #286

merged 6 commits into from
May 11, 2023

Conversation

laisolizq
Copy link
Contributor

  • Add push0
  • Fix RLP data length

@cla-bot cla-bot bot added the cla-signed label May 5, 2023
@laisolizq laisolizq marked this pull request as draft May 5, 2023 16:05
main/utils.zkasm Outdated
@@ -872,10 +872,13 @@ SHLarithfinal:

; out of counters full tracer event trigger
outOfCountersStep:
$ :MLOAD(isLoadRLP),JMPNZ(handleOOCSatRLP)
Copy link
Contributor

@ignasirv ignasirv May 8, 2023

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

Copy link
Contributor

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
Copy link
Contributor

@ignasirv ignasirv May 8, 2023

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)
Copy link
Contributor

@ignasirv ignasirv May 8, 2023

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


opPUSH0:
; check out-of-gas
GAS - %GAS_QUICK_STEP => GAS :JMPN(outOfGas)
Copy link
Contributor

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)
Copy link
Contributor

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
Copy link
Contributor

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

Copy link
Contributor

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 the batchHashData
  • so we can save the auxLengthBytes variable

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@abdulmenan10
Copy link

Yes

@laisolizq laisolizq requested review from krlosMata and ignasirv May 11, 2023 07:51
Copy link
Contributor

@ignasirv ignasirv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@krlosMata krlosMata mentioned this pull request May 11, 2023
@laisolizq laisolizq marked this pull request as ready for review May 11, 2023 08:14
@laisolizq laisolizq requested a review from zkronos73 as a code owner May 11, 2023 08:14
Copy link
Contributor

@krlosMata krlosMata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😸

@krlosMata krlosMata merged commit adc6ccb into develop May 11, 2023
@@ -7,6 +7,15 @@
* - stack input: none
* - stack output: [pushed_value]
*/

opPUSH0:
Copy link

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.

Copy link
Contributor

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]
*/
Copy link

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.

Copy link
Contributor

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

Copy link

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}
Copy link

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

Copy link
Contributor

@krlosMata krlosMata May 29, 2023

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

Copy link

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.

Copy link

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 the p 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?

Copy link
Contributor

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.

exactly!

Copy link
Contributor

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 the p 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)
Copy link

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

Copy link

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?

Copy link
Contributor

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

@gumb0
Copy link

gumb0 commented May 29, 2023

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 utils that are called from RLP processing and should process counter errors differently.

I can see that this might be impractical if those utils are also called from many other places. Another less radical suggestion to consider could be: do the branching based on global isLoadingRLP only inside requried utils instead of lower-level handleBatchError. This way the fix would affect only some limited scope of functionality, comparing to affecting every batch error processing like now. And it would still be more explicit which utils depend on this global state.
(Downside of this approach could be if RLP processing changes to using some new utils, you have to remember to check isLoadingRLP in each one)

@krlosMata
Copy link
Contributor

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 utils that are called from RLP processing and should process counter errors differently.

I can see that this might be impractical if those utils are also called from many other places. Another less radical suggestion to consider could be: do the branching based on global isLoadingRLP only inside requried utils instead of lower-level handleBatchError. This way the fix would affect only some limited scope of functionality, comparing to affecting every batch error processing like now. And it would still be more explicit which utils depend on this global state. (Downside of this approach could be if RLP processing changes to using some new utils, you have to remember to check isLoadingRLP in each one)

We decided to go with the isLoadingRLP approach since it povides better security when adding new code to the RLP parsing since it is handled globally and it is not function specific. Also, RLP error where just removed and all zk-counters are handled via handleBatchError

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants