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

Effective gas implementation #290

Merged
merged 6 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions main/load-tx-rlp.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ vREADTx:
A :MSTORE(txV)
C + D => C :CALL(addBatchHashData)

;; read effective percentage
effectivePercentageTx:
Copy link

Choose a reason for hiding this comment

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

This label is never called. Is this just a documentation?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, it is there for clarity

1 => D :CALL(getTxBytes)
Copy link

Choose a reason for hiding this comment

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

The description of getTxBytes does not say what C is used for.

Copy link
Contributor

Choose a reason for hiding this comment

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

C description is at the very beginning of the rlp-processing: https://github.com/0xPolygonHermez/zkevm-rom/blob/main/main/load-tx-rlp.zkasm#L28

A :MSTORE(effectivePercentageRLP)
C + D => C :CALL(addBatchHashData)
;;;;;;;;;
;; D - Finish RLP parsing
;;;;;;;;;
Expand Down
20 changes: 15 additions & 5 deletions main/opcodes/stack-operations.zkasm
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
/**
* @link [https://www.evm.codes/#60?fork=berlin]
* @link [https://www.evm.codes/#5f?fork=shanghai]
* @zk-counters
* - 100 steps (stack) || 400 steps (calldata)
* - 1 binary (stack) || 0 binary (calldata)
* - 100 steps
* @process-opcode
* - stack input: none
* - stack output: [pushed_value]
* - stack output: [0]
*/

opPUSH0:
; checks zk-counters
%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep)

; check out-of-gas
GAS - %GAS_QUICK_STEP => GAS :JMPN(outOfGas)
; store stack output
0 :MSTORE(SP++); [0 => SP]
; check stack overflow
%CALLDATA_OFFSET - SP :JMPN(stackOverflow, readCode)

/**
* @link [https://www.evm.codes/#60?fork=berlin]
* @zk-counters
* - 100 steps (stack) || 400 steps (calldata)
* - 1 binary (stack) || 0 binary (calldata)
* @process-opcode
* - stack input: none
* - stack output: [pushed_value]
*/
opPUSH1:
; number of bytes to push to D
1 => D
Expand Down
30 changes: 28 additions & 2 deletions main/process-tx.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ processTx:
; Minimum of 100000 steps left to process a tx
%MAX_CNT_STEPS - STEP - 100000 :JMPN(outOfCountersStep)
%MAX_CNT_BINARY - CNT_BINARY - 100 :JMPN(outOfCountersBinary)
%MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith)

$ => A :MLOAD(txHash)
; Check the signature
$ => B :MLOAD(txR)
Expand Down Expand Up @@ -68,9 +70,33 @@ endCheckChainId:
:CALL(isColdAddress) ; add tx.origin to touched addresses
0 :MSTORE(depth) ; Initial depth is 0

;; Set gasPrice global var
;; Set gasPrice global var depending on effectivePercentage [0-255] -> txGasPrice = Floor((gasPrice * (effectivePercentage + 1)) / 256)
; gasPrice => A
$ => A :MLOAD(txGasPriceRLP)
A :MSTORE(txGasPrice)
; effectivePercentage => B
$ => B :MLOAD(effectivePercentageRLP)
; B -> [1, 256]
B + 1 => B
; A*B + C = D * 2**256 + op(E)
0 => C
; _effGasPriceShifted = gasPrice * (effectivePercentage + 1)
$${var _effGasPriceShifted = A * B}
; get value above 256 bits
${_effGasPriceShifted >> 256} => D
; compute ARITH
${_effGasPriceShifted} => E :ARITH
Copy link

Choose a reason for hiding this comment

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

Should we have out of arith counters check for this code?
(or any other counters (steps, binary?) given that this adds quite a bit of computation)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I agree we should add an arith checker at beginning of process-tx.zkasm


; txGasPrice = _effGasPriceShifted / 256
256 => B
; (_effGasPriceShifted / 256)(A) * 256(B) + (_effGasPriceShifted % 256)(C) = D * 2**256 + op(E)
${_effGasPriceShifted / 256} => A :MSTORE(txGasPrice)
${_effGasPriceShifted % 256} => C
; compute ARITH
E :ARITH
Copy link

Choose a reason for hiding this comment

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

Maybe I still don't quite understand how this works, so correct where if I'm wrong.

I believe the purpose of this ARITH is to contstrain the free calculations above (_effGasPriceShifted / 256 and _effGasPriceShifted % 256)

This ARITH line calculates AB + C and updates E and D.

What would stop malicious prover to return arbitrary value into A instead of _effGasPriceShifted / 256? This ARITH doesn't seem to constrain neither of registers values (unlike the first ARITH above?)
(for C it is more clear, it is at least checked for <256 afterwards)

Copy link

Choose a reason for hiding this comment

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

Actually I think I understand now: it takes into account previous values of E and D and checks result of ARITH against them, because this expression doesn't have an assignment to register.

; check divisor > remainder
C => A
Copy link

Choose a reason for hiding this comment

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

To confirm: LT treats arguments as unsigned. I.e. this will work in case C is "negative".

Copy link

Choose a reason for hiding this comment

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

Is the usage of LT covered by CNT_BINARY - 100?

Copy link
Contributor Author

@ignasirv ignasirv May 30, 2023

Choose a reason for hiding this comment

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

LT uses 1 binary, so yes.
LT treats arguments as unsigned, it compares two 256 bit scalars. To treat them as signed, we also have the registry SLT.
In case C is "negative" it will be treated as a Scalar

1 :LT

;;;;;;;;;;;;;;;;;;
;; D - Verify and increase nonce
;;;;;;;;;;;;;;;;;;
Expand Down
2 changes: 2 additions & 0 deletions main/utils.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,8 @@ handleError:
handleBatchError:
; restore init state root and finish batch
$ => SR :MLOAD(batchSR)
; if batch error is triggered while parsing the RLP, it jumps to 'invalidTxRLP'
; to fill the missing bytes to complete 'batchDataHash'
$ :MLOAD(isLoadingRLP),JMPNZ(invalidTxRLP)
$${eventLog(onFinishTx)}
$${eventLog(onFinishBatch)} :JMP(processTxsEnd)
Expand Down
1 change: 1 addition & 0 deletions main/vars.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ VAR CTX storageAddr ; address which the storage will be modified
VAR CTX txValue ; transaction parameter: 'value'
VAR CTX txNonce ; transaction parameter: nonce
VAR CTX txGasPriceRLP ; transaction parameter: 'gasPrice' decoded from the RLP
VAR CTX effectivePercentageRLP ; transaction parameter: 'effectivePercentage' decoded from the RLP
VAR CTX txChainId ; transaction parameter: 'chainId'
VAR CTX txS ; transaction parameter: ecdsa signature S
VAR CTX txR ; transaction parameter: ecdsa signature R
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
},
"devDependencies": {
"@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#3bc0368dd67caf92d38e3cbebe7b030e78c54e35",
"@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v1.2.0-rc.1-fork.5",
"@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v1.0.1-rc.3",
"@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#feature/effective-gas-price",
"@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#feature/effective-gas-price",
"chai": "^4.3.6",
"chalk": "^3.0.0",
"eslint": "^8.25.0",
Expand Down