2023-03-19 20:17:30 -07:00
|
|
|
global sys_extcodehash:
|
|
|
|
|
// stack: kexit_info, address
|
2023-03-23 20:22:25 +01:00
|
|
|
SWAP1 %u256_to_addr
|
2023-03-19 20:17:30 -07:00
|
|
|
// stack: address, kexit_info
|
2023-03-23 20:22:25 +01:00
|
|
|
DUP1 %insert_accessed_addresses
|
|
|
|
|
// stack: cold_access, address, kexit_info
|
|
|
|
|
PUSH @GAS_COLDACCOUNTACCESS_MINUS_WARMACCESS
|
|
|
|
|
MUL
|
|
|
|
|
PUSH @GAS_WARMACCESS
|
|
|
|
|
ADD
|
|
|
|
|
%stack (gas, address, kexit_info) -> (gas, kexit_info, address)
|
|
|
|
|
%charge_gas
|
|
|
|
|
// stack: kexit_info, address
|
|
|
|
|
|
|
|
|
|
SWAP1
|
2023-03-19 20:17:30 -07:00
|
|
|
%extcodehash
|
|
|
|
|
// stack: hash, kexit_info
|
|
|
|
|
SWAP1
|
|
|
|
|
EXIT_KERNEL
|
2022-11-02 10:37:19 +01:00
|
|
|
|
|
|
|
|
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
|
2023-03-19 20:17:30 -07:00
|
|
|
retzero:
|
|
|
|
|
%stack (account_ptr, retdest) -> (retdest, 0)
|
|
|
|
|
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
|
2022-11-21 13:54:39 -08:00
|
|
|
%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
|
2023-03-23 20:22:25 +01:00
|
|
|
SWAP1 %u256_to_addr
|
|
|
|
|
// stack: address, kexit_info
|
|
|
|
|
DUP1 %insert_accessed_addresses
|
|
|
|
|
// stack: cold_access, address, kexit_info
|
|
|
|
|
PUSH @GAS_COLDACCOUNTACCESS_MINUS_WARMACCESS
|
|
|
|
|
MUL
|
|
|
|
|
PUSH @GAS_WARMACCESS
|
|
|
|
|
ADD
|
|
|
|
|
%stack (gas, address, kexit_info) -> (gas, kexit_info, address)
|
|
|
|
|
%charge_gas
|
|
|
|
|
// stack: kexit_info, address
|
|
|
|
|
|
2023-02-25 07:59:51 -08:00
|
|
|
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
|
|
|
|
2023-02-25 07:59:51 -08:00
|
|
|
%macro extcodecopy
|
|
|
|
|
// stack: address, dest_offset, offset, size
|
2023-03-21 20:15:30 +01:00
|
|
|
%stack (address, dest_offset, offset, size) -> (address, 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)
|
2023-03-30 06:46:26 +02:00
|
|
|
%u256_to_addr DUP1 %insert_accessed_addresses
|
|
|
|
|
// stack: cold_access, address, dest_offset, offset, size, kexit_info
|
|
|
|
|
PUSH @GAS_COLDACCOUNTACCESS_MINUS_WARMACCESS
|
|
|
|
|
MUL
|
|
|
|
|
PUSH @GAS_WARMACCESS
|
|
|
|
|
ADD
|
|
|
|
|
// stack: Gaccess, address, dest_offset, offset, size, kexit_info
|
|
|
|
|
|
|
|
|
|
DUP5
|
|
|
|
|
// stack: size, Gaccess, address, dest_offset, offset, size, kexit_info
|
|
|
|
|
ISZERO %jumpi(sys_extcodecopy_empty)
|
|
|
|
|
|
|
|
|
|
// stack: Gaccess, address, dest_offset, offset, size, kexit_info
|
|
|
|
|
DUP5 %num_bytes_to_num_words %mul_const(@GAS_COPY) ADD
|
|
|
|
|
%stack (gas, address, dest_offset, offset, size, kexit_info) -> (gas, kexit_info, address, dest_offset, offset, size)
|
|
|
|
|
%charge_gas
|
|
|
|
|
|
|
|
|
|
%stack (kexit_info, address, dest_offset, offset, size) -> (dest_offset, size, kexit_info, address, dest_offset, offset, size)
|
2023-04-13 18:49:18 +08:00
|
|
|
%add_or_fault
|
2023-03-30 06:46:26 +02:00
|
|
|
// stack: expanded_num_bytes, kexit_info, address, dest_offset, offset, size
|
|
|
|
|
DUP1 %ensure_reasonable_offset
|
|
|
|
|
%update_mem_bytes
|
|
|
|
|
|
|
|
|
|
%stack (kexit_info, address, dest_offset, offset, size) -> (address, dest_offset, offset, size, kexit_info)
|
2023-02-25 07:59:51 -08:00
|
|
|
%extcodecopy
|
|
|
|
|
// stack: kexit_info
|
|
|
|
|
EXIT_KERNEL
|
|
|
|
|
|
2023-03-30 06:46:26 +02:00
|
|
|
sys_extcodecopy_empty:
|
|
|
|
|
%stack (Gaccess, address, dest_offset, offset, size, kexit_info) -> (Gaccess, kexit_info)
|
|
|
|
|
%charge_gas
|
|
|
|
|
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
|
2022-11-21 13:54:39 -08:00
|
|
|
%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-04-05 06:24:26 +02:00
|
|
|
// stack: code_size, size, offset, dest_offset, retdest
|
|
|
|
|
DUP1 DUP4
|
|
|
|
|
// stack: offset, code_size, code_size, size, offset, dest_offset, retdest
|
|
|
|
|
GT %jumpi(extcodecopy_large_offset)
|
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`.
|
2022-11-21 13:54:39 -08:00
|
|
|
// 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
|
2023-05-18 13:50:34 +02:00
|
|
|
%mload_kernel(@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
|
2023-03-19 20:17:30 -07:00
|
|
|
%mstore_current(@SEGMENT_MAIN_MEMORY)
|
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
|
|
|
|
|
|
2023-04-05 06:24:26 +02:00
|
|
|
extcodecopy_large_offset:
|
|
|
|
|
// offset is larger than the code size. So we just have to write zeros.
|
|
|
|
|
// stack: code_size, size, offset, dest_offset, retdest
|
|
|
|
|
GET_CONTEXT
|
|
|
|
|
%stack (context, code_size, size, offset, dest_offset, retdest) -> (context, @SEGMENT_MAIN_MEMORY, dest_offset, 0, size, retdest)
|
|
|
|
|
%jump(memset)
|
2022-10-21 18:00:41 +02:00
|
|
|
|
2022-11-21 13:54:39 -08:00
|
|
|
// 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.
|
2022-11-21 13:54:39 -08:00
|
|
|
// 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:
|
2022-11-21 13:54:39 -08:00
|
|
|
%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:
|
2022-11-21 13:54:39 -08:00
|
|
|
// stack: codehash, ctx, segment, retdest
|
2023-03-21 20:15:30 +01:00
|
|
|
DUP1 ISZERO %jumpi(load_code_non_existent_account)
|
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
|
2022-11-21 13:54:39 -08:00
|
|
|
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
|
2023-03-21 20:15:30 +01:00
|
|
|
|
|
|
|
|
load_code_non_existent_account:
|
|
|
|
|
%stack (codehash, ctx, segment, retdest) -> (retdest, 0)
|
|
|
|
|
JUMP
|