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

read entire bytecode program at once #219

Merged
merged 1 commit into from
Jan 5, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 15 additions & 44 deletions main/opcodes/calldata-returndata-code.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -419,24 +419,29 @@ VAR GLOBAL tmpContractLength
opEXTCODECOPY:
; checks zk-counters
%MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 510 :JMPN(outOfCountersPoseidon)
%MAX_CNT_PADDING_PG - CNT_PADDING_PG - 11 :JMPN(outOfCountersPadding)
%MAX_CNT_PADDING_PG - CNT_PADDING_PG - 11 :JMPN(outOfCountersPadding)
%MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 2 :JMPN(outOfCountersMemalign)
%MAX_CNT_BINARY - CNT_BINARY - 32 :JMPN(outOfCountersBinary)
%MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep)

; check stack underflow
SP - 4 => SP :JMPN(stackUnderflow)
SP - 4 => SP :JMPN(stackUnderflow)
$ => A :MLOAD(SP+3), CALL(maskAddress); [address => A]; in: [A: address] out: [A: masked address]
:CALL(isColdAddress); in: [A: address] out: [D: 0 if warm, 1 if cold]

; check out-of-gas
GAS - %WARM_STORGE_READ_GAS - D * %COLD_ACCOUNT_ACCESS_COST_RED => GAS :JMPN(outOfGas)
:CALL(opEXTCODECOPYCheckHash)
:CALL(opEXTCODECOPYLoadBytecode)
$ => C :MLOAD(SP+2); [destOffset => C]
$ => D :MLOAD(SP+1); [offset => D]
$ => E :MLOAD(SP); [size => E]

; store lastMemOffset for memory expansion gas cost
C :MSTORE(lastMemOffset)

; store lastMemLength for memory expansion gas cost
E :MSTORE(lastMemLength)

; check out-of-gas
;${3*((E+31)/32)}
E+31 => A
Expand Down Expand Up @@ -471,7 +476,7 @@ opEXTCODECOPY2:
E :MSTORE(remainingBytes), JMP(opCODECOPYinit)

VAR GLOBAL tmpZkPCext
opEXTCODECOPYCheckHash:
opEXTCODECOPYLoadBytecode:
; set key for smt smart contract length query
%SMT_KEY_SC_LENGTH => B
0 => C
Expand All @@ -482,6 +487,7 @@ opEXTCODECOPYCheckHash:
0 => A
D => B
$ :EQ, JMPC(opEXTCODECOPYCheckHashEnd)

; check poseidon counters
; 56 is the value used by the prover to increment poseidon counters depending on the hash length
RR :MSTORE(tmpZkPCext)
Expand All @@ -492,56 +498,21 @@ opEXTCODECOPYCheckHash:
%MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 1 => A
$ :LT, JMPC(outOfCountersPoseidon)

E => A
; set key for smt smart contract code query
E => A
%SMT_KEY_SC_CODE => B
0 => C
$ => A :SLOAD

; get a new hashPId
$ => E :MLOAD(nextHashPId)
E :MSTORE(tmpContractHashId)
E + 1 :MSTORE(nextHashPId)

; set vars prior to loop
D => B
0 => HASHPOS :JMP(opEXTCODECOPYCheckHashLoop)

; @info bytes are inserted byte by byte
opEXTCODECOPYCheckHashLoop:
%MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep)
; finish reading bytecode
B :JMPZ(opEXTCODECOPYCheckHashLoopEnd)
; add bytes to hash contract bytecode
${getBytecode(A, HASHPOS, 1)} :HASHP1(E)
B - 1 => B :JMP(opEXTCODECOPYCheckHashLoop)

opEXTCODECOPYCheckHashLoopEnd:
HASHPOS :HASHPLEN(E)
$ => E :HASHPDIGEST(E)
; check hash computed matches hash in the smt leaf
E :ASSERT
; load contract bytecode
A :HASHPDIGEST(E)
opEXTCODECOPYCheckHashEnd:
:RETURN

opEXTCODECOPYinit:
; checks zk-counters
%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep)
C :JMPZ(readCode)
C - 32 :JMPN(opEXTCODECOPYfinal)
${getBytecode(A,B,32)} => D
; set bytesToStore with value to use in MSTORE
D :MSTORE(bytesToStore)
:CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset]
C - 32 => C
B + 32 => B :JMP(opEXTCODECOPYinit)

opEXTCODECOPYfinal:
; copy last bytes
${getBytecode(A,B,C)} => A
32 - C => D :CALL(SHLarith); in: [A: value, D: #bytes to left shift] out: [A: shifted result]
; set bytesToStore with value to use in MSTORE
A :MSTORE(bytesToStore), CALL(MSTOREX); in: [bytesToStore, E: offset, C: length] out: [E: new offset]
:JMP(readCode)
:RETURN

/**
* @link [https://www.evm.codes/#3D?fork=berlin]
Expand Down
22 changes: 4 additions & 18 deletions main/process-tx.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ readDeployBytecodeCreateDefault:

;;;;;;;;;;;;;;;;;;
;; F.1 - Call contract
;; - Check bytecode to process against state-tree hash bytecode
;; - Load bytecode from its state-tree hash
;; - Process bytecode
;; - End deploy: add state-tree hash bytecode and bytecode length
;;;;;;;;;;;;;;;;;;
Expand Down Expand Up @@ -399,32 +399,18 @@ callContract:
%MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 1 => A
$ :LT, JMPC(outOfCountersPoseidon)

$ => A :MLOAD(txDestAddr)
; get hash contract
$ => A :MLOAD(txDestAddr)
%SMT_KEY_SC_CODE => B
$ => A :SLOAD
A :MSTORE(hashContractTxDestAddr)
0 => HASHPOS
$ => B :MLOAD(bytecodeLength)

; get a new hashPId
$ => E :MLOAD(nextHashPId)
E :MSTORE(contractHashId)
E+1 :MSTORE(nextHashPId)

; check steps used by REPEAT
%MAX_CNT_STEPS - STEP - B - 4 :JMPN(outOfCountersStep)

; set repeat itarations: RCX register + 1
B - 1 => RCX :JMPN(checkHashBytecodeEnd)
${getBytecode(A, HASHPOS, 1)} :HASHP1(E), REPEAT(RCX) ; hash contract bytecode

checkHashBytecodeEnd:
HASHPOS :HASHPLEN(E)
$ => E :HASHPDIGEST(E)
; check hash computed matches hash in the smt leaf
$ => A :MLOAD(hashContractTxDestAddr)
E :ASSERT, JMP(readCode)
; load contract bytecode
A :HASHPDIGEST(E)

readByteCode:
$ => E :MLOAD(contractHashId) ; hash index
Expand Down
2 changes: 2 additions & 0 deletions main/touched.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ checkWarmed:
; set address to warm and return 0
markWarmAddress:
1 => D
$${eventLog(onTouchedAddress(A))}
$ => SR :SSTORE
; address is cold. D = 1, set before

Expand Down Expand Up @@ -95,6 +96,7 @@ isColdSlot:
; set address to warm and return 0
markWarmSlot:
1 => D
$${eventLog(onTouchedSlot(A, C))}
$ => SR :SSTORE
; slot is cold. A = 1
1 => A
Expand Down
1 change: 0 additions & 1 deletion main/utils.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,6 @@ hashPoseidonEnd:
$ => E :MLOAD(tmpContractHashId)
HASHPOS :HASHPLEN(E)
$ => D :HASHPDIGEST(E)
$${saveContractBytecode(E)}

hashPoseidonReturn:
$ => RR :MLOAD(tmpZkPChashP)
Expand Down
1 change: 0 additions & 1 deletion main/vars.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ VAR GLOBAL txCount ; Current transaction count
VAR GLOBAL touchedSR ; touched tree root
VAR GLOBAL numTopics ; number of topics depending on LOG opcode call
VAR GLOBAL SPw ; aux variable to store Stack poimnter 'SP'
VAR GLOBAL hashContractTxDestAddr ; state-tree hash bytecode leaf value of the 'to' address
VAR GLOBAL auxSR ; auxiliaty variable. Temporary state root
VAR GLOBAL txRLPLength ; transaction RLP list length
VAR GLOBAL txDataRead ; aux varible to check transaction 'data' left that needs to be read
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"yargs": "^17.5.1"
},
"devDependencies": {
"@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#v0.6.0.0",
"@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/last-changes",
"@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v0.6.0.0",
"chai": "^4.3.6",
"chalk": "^3.0.0",
Expand Down