plonky2/evm/src/cpu/kernel/asm/account_code.asm

168 lines
5.7 KiB
NASM
Raw Normal View History

2022-11-02 10:37:19 +01:00
retzero:
%stack (account_ptr, retdest) -> (retdest, 0)
JUMP
global extcodehash:
// stack: address, retdest
2022-10-21 18:00:41 +02:00
%mpt_read_state_trie
2022-11-02 11:06:14 +01:00
// stack: account_ptr, retdest
2022-11-02 10:37:19 +01:00
DUP1 ISZERO %jumpi(retzero)
2022-10-21 18:00:41 +02:00
%add_const(3)
2022-11-02 11:06:14 +01:00
// stack: codehash_ptr, retdest
2022-10-21 18:00:41 +02:00
%mload_trie_data
2022-11-02 11:06:14 +01:00
// stack: codehash, retdest
SWAP1 JUMP
2022-10-21 18:00:41 +02:00
2023-01-14 21:18:58 -08:00
%macro extcodehash
%stack (address) -> (address, %%after)
%jump(extcodehash)
%%after:
%endmacro
%macro ext_code_empty
%extcodehash
%eq_const(@EMPTY_STRING_HASH)
%endmacro
2022-10-27 11:06:24 +02:00
2022-10-21 18:11:27 +02:00
%macro extcodesize
%stack (address) -> (address, 0, @SEGMENT_KERNEL_ACCOUNT_CODE, %%after)
2022-10-21 18:00:41 +02:00
%jump(load_code)
%%after:
%endmacro
2023-02-25 07:59:51 -08:00
global sys_extcodesize:
// stack: kexit_info, address
SWAP1
// stack: address, kexit_info
%extcodesize
// stack: code_size, kexit_info
SWAP1
EXIT_KERNEL
2022-10-24 13:06:53 +02:00
global extcodesize:
2022-10-27 09:32:29 +02:00
// stack: address, retdest
2022-10-24 13:06:53 +02:00
%extcodesize
2022-10-27 09:32:29 +02:00
// stack: extcodesize(address), retdest
SWAP1 JUMP
2022-10-24 13:06:53 +02:00
2022-10-21 18:11:27 +02:00
%macro codecopy
2023-02-25 07:59:51 -08:00
// stack: dest_offset, offset, size
2022-10-31 10:15:43 +01:00
%address
2023-02-25 07:59:51 -08:00
%extcodecopy
%endmacro
%macro extcodecopy
// stack: address, dest_offset, offset, size
%stack (dest_offset, offset, size) -> (dest_offset, offset, size, %%after)
2022-10-21 18:11:27 +02:00
%jump(extcodecopy)
2023-02-25 07:59:51 -08:00
%%after:
2022-10-21 18:11:27 +02:00
%endmacro
2023-02-25 07:59:51 -08:00
// Pre stack: kexit_info, address, dest_offset, offset, size
// Post stack: (empty)
global sys_extcodecopy:
%stack (kexit_info, address, dest_offset, offset, size)
-> (address, dest_offset, offset, size, kexit_info)
%extcodecopy
// stack: kexit_info
EXIT_KERNEL
2022-10-27 14:57:17 +02:00
// Pre stack: address, dest_offset, offset, size, retdest
// Post stack: (empty)
2022-10-21 18:00:41 +02:00
global extcodecopy:
// stack: address, dest_offset, offset, size, retdest
%stack (address, dest_offset, offset, size, retdest)
-> (address, 0, @SEGMENT_KERNEL_ACCOUNT_CODE, extcodecopy_contd, size, offset, dest_offset, retdest)
2022-10-21 18:00:41 +02:00
%jump(load_code)
2022-10-27 14:57:17 +02:00
2022-10-21 18:00:41 +02:00
extcodecopy_contd:
2023-03-06 21:57:51 -08:00
// stack: code_size, size, offset, dest_offset, retdest
2022-10-21 18:00:41 +02:00
SWAP1
2023-03-06 21:57:51 -08:00
// stack: size, code_size, offset, dest_offset, retdest
2022-10-21 18:00:41 +02:00
PUSH 0
2022-10-27 14:57:17 +02:00
// Loop copying the `code[offset]` to `memory[dest_offset]` until `i==size`.
// Each iteration increments `offset, dest_offset, i`.
// TODO: Consider implementing this with memcpy.
2022-10-21 18:00:41 +02:00
extcodecopy_loop:
2023-03-06 21:57:51 -08:00
// stack: i, size, code_size, offset, dest_offset, retdest
2022-10-21 18:00:41 +02:00
DUP2 DUP2 EQ
2023-03-06 21:57:51 -08:00
// stack: i == size, i, size, code_size, offset, dest_offset, retdest
2022-10-21 18:00:41 +02:00
%jumpi(extcodecopy_end)
2023-03-06 21:57:51 -08:00
%stack (i, size, code_size, offset, dest_offset, retdest)
-> (offset, code_size, offset, code_size, dest_offset, i, size, retdest)
2022-10-21 18:00:41 +02:00
LT
2023-03-06 21:57:51 -08:00
// stack: offset < code_size, offset, code_size, dest_offset, i, size, retdest
2022-10-21 18:00:41 +02:00
DUP2
2023-03-06 21:57:51 -08:00
// stack: offset, offset < code_size, offset, code_size, dest_offset, i, size, retdest
2022-10-21 18:00:41 +02:00
%mload_current(@SEGMENT_KERNEL_ACCOUNT_CODE)
2023-03-06 21:57:51 -08:00
// stack: opcode, offset < code_size, offset, code_size, dest_offset, i, size, retdest
%stack (opcode, offset_lt_code_size, offset, code_size, dest_offset, i, size, retdest)
-> (offset_lt_code_size, 0, opcode, offset, code_size, dest_offset, i, size, retdest)
// If `offset >= code_size`, use `opcode=0`. Necessary since `SEGMENT_KERNEL_ACCOUNT_CODE` might be clobbered from previous calls.
2022-10-21 18:00:41 +02:00
%select_bool
2023-03-06 21:57:51 -08:00
// stack: opcode, offset, code_size, dest_offset, i, size, retdest
2022-10-21 18:00:41 +02:00
DUP4
2023-03-06 21:57:51 -08:00
// stack: dest_offset, opcode, offset, code_size, dest_offset, i, size, retdest
2022-10-21 18:11:27 +02:00
%mstore_main
2023-03-06 21:57:51 -08:00
// stack: offset, code_size, dest_offset, i, size, retdest
2022-10-21 18:11:27 +02:00
%increment
2023-03-06 21:57:51 -08:00
// stack: offset+1, code_size, dest_offset, i, size, retdest
2022-10-21 18:11:27 +02:00
SWAP2
2023-03-06 21:57:51 -08:00
// stack: dest_offset, code_size, offset+1, i, size, retdest
2022-10-21 18:11:27 +02:00
%increment
2023-03-06 21:57:51 -08:00
// stack: dest_offset+1, code_size, offset+1, i, size, retdest
2022-10-21 18:11:27 +02:00
SWAP3
2023-03-06 21:57:51 -08:00
// stack: i, code_size, offset+1, dest_offset+1, size, retdest
2022-10-21 18:11:27 +02:00
%increment
2023-03-06 21:57:51 -08:00
// stack: i+1, code_size, offset+1, dest_offset+1, size, retdest
%stack (i, code_size, offset, dest_offset, size, retdest) -> (i, size, code_size, offset, dest_offset, retdest)
2022-10-21 18:11:27 +02:00
%jump(extcodecopy_loop)
2022-10-21 18:00:41 +02:00
extcodecopy_end:
2023-03-06 21:57:51 -08:00
%stack (i, size, code_size, offset, dest_offset, retdest) -> (retdest)
2022-10-21 18:00:41 +02:00
JUMP
// Loads the code at `address` into memory, at the given context and segment, starting at offset 0.
2022-10-27 11:06:24 +02:00
// Checks that the hash of the loaded code corresponds to the `codehash` in the state trie.
// Pre stack: address, ctx, segment, retdest
2023-03-06 21:57:51 -08:00
// Post stack: code_size
2022-11-20 12:46:15 -08:00
global load_code:
%stack (address, ctx, segment, retdest) -> (extcodehash, address, load_code_ctd, ctx, segment, retdest)
2022-11-02 10:37:19 +01:00
JUMP
load_code_ctd:
// stack: codehash, ctx, segment, retdest
2022-10-21 18:00:41 +02:00
PROVER_INPUT(account_code::length)
2023-03-06 21:57:51 -08:00
// stack: code_size, codehash, ctx, segment, retdest
2022-10-21 18:00:41 +02:00
PUSH 0
2022-10-27 14:57:17 +02:00
2023-03-06 21:57:51 -08:00
// Loop non-deterministically querying `code[i]` and storing it in `SEGMENT_KERNEL_ACCOUNT_CODE`
// at offset `i`, until `i==code_size`.
2022-10-21 18:00:41 +02:00
load_code_loop:
2023-03-06 21:57:51 -08:00
// stack: i, code_size, codehash, ctx, segment, retdest
2022-10-21 18:00:41 +02:00
DUP2 DUP2 EQ
2023-03-06 21:57:51 -08:00
// stack: i == code_size, i, code_size, codehash, ctx, segment, retdest
2022-10-21 18:00:41 +02:00
%jumpi(load_code_check)
PROVER_INPUT(account_code::get)
2023-03-06 21:57:51 -08:00
// stack: opcode, i, code_size, codehash, ctx, segment, retdest
2022-10-21 18:00:41 +02:00
DUP2
2023-03-06 21:57:51 -08:00
// stack: i, opcode, i, code_size, codehash, ctx, segment, retdest
DUP7 // segment
DUP7 // context
MSTORE_GENERAL
2023-03-06 21:57:51 -08:00
// stack: i, code_size, codehash, ctx, segment, retdest
2022-10-21 18:00:41 +02:00
%increment
2023-03-06 21:57:51 -08:00
// stack: i+1, code_size, codehash, ctx, segment, retdest
2022-10-21 18:00:41 +02:00
%jump(load_code_loop)
2022-10-27 14:57:17 +02:00
// Check that the hash of the loaded code equals `codehash`.
2022-10-21 18:00:41 +02:00
load_code_check:
2023-03-06 21:57:51 -08:00
// stack: i, code_size, codehash, ctx, segment, retdest
%stack (i, code_size, codehash, ctx, segment, retdest)
-> (ctx, segment, 0, code_size, codehash, retdest, code_size)
2022-10-21 18:00:41 +02:00
KECCAK_GENERAL
2023-03-06 21:57:51 -08:00
// stack: shouldbecodehash, codehash, retdest, code_size
2022-10-21 18:00:41 +02:00
%assert_eq
JUMP