mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-09 09:13:09 +00:00
Remove some CPU cycles (#1469)
* Amortize mload_packing * Reduce stack overhead * Amortize mstore_unpacking * Speed-up stack operation in hash.asm * Misc * Small tweaks * Misc small optims * Fix comments * Fix main access to withdrawals * Fix stack description * minor: rename label * Comments --------- Co-authored-by: Linda Guiga <lindaguiga3@gmail.com>
This commit is contained in:
parent
30b4799826
commit
990eb34d96
@ -2,13 +2,13 @@ global sys_extcodehash:
|
||||
// stack: kexit_info, address
|
||||
SWAP1 %u256_to_addr
|
||||
// stack: address, kexit_info
|
||||
DUP1 %insert_accessed_addresses
|
||||
// stack: cold_access, address, kexit_info
|
||||
SWAP1
|
||||
DUP2 %insert_accessed_addresses
|
||||
// stack: cold_access, kexit_info, address
|
||||
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
|
||||
|
||||
@ -57,13 +57,13 @@ global sys_extcodesize:
|
||||
// stack: kexit_info, address
|
||||
SWAP1 %u256_to_addr
|
||||
// stack: address, kexit_info
|
||||
DUP1 %insert_accessed_addresses
|
||||
// stack: cold_access, address, kexit_info
|
||||
SWAP1
|
||||
DUP2 %insert_accessed_addresses
|
||||
// stack: cold_access, kexit_info, address
|
||||
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
|
||||
|
||||
|
||||
@ -2,13 +2,13 @@ global sys_balance:
|
||||
// stack: kexit_info, address
|
||||
SWAP1 %u256_to_addr
|
||||
// stack: address, kexit_info
|
||||
DUP1 %insert_accessed_addresses
|
||||
// stack: cold_access, address, kexit_info
|
||||
SWAP1
|
||||
DUP2 %insert_accessed_addresses
|
||||
// stack: cold_access, kexit_info, address
|
||||
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
|
||||
|
||||
|
||||
@ -38,20 +38,17 @@ global get_create_address:
|
||||
global get_create2_address:
|
||||
// stack: sender, code_hash, salt, retdest
|
||||
PUSH 0xff PUSH 0 %mstore_kernel_general
|
||||
%stack (sender, code_hash, salt, retdest) -> (@SEGMENT_KERNEL_GENERAL, 1, sender, 20, get_create2_address_contd, salt, code_hash, retdest)
|
||||
%stack (sender, code_hash, salt, retdest) -> (@SEGMENT_KERNEL_GENERAL, 1, sender, salt, code_hash, retdest)
|
||||
ADD
|
||||
%jump(mstore_unpacking)
|
||||
get_create2_address_contd:
|
||||
MSTORE_32BYTES_20
|
||||
POP
|
||||
%stack (salt, code_hash, retdest) -> (@SEGMENT_KERNEL_GENERAL, 21, salt, 32, get_create2_address_contd2, code_hash, retdest)
|
||||
%stack (salt, code_hash, retdest) -> (@SEGMENT_KERNEL_GENERAL, 21, salt, code_hash, retdest)
|
||||
ADD
|
||||
%jump(mstore_unpacking)
|
||||
get_create2_address_contd2:
|
||||
MSTORE_32BYTES_32
|
||||
POP
|
||||
%stack (code_hash, retdest) -> (@SEGMENT_KERNEL_GENERAL, 53, code_hash, 32, get_create2_address_finish, retdest)
|
||||
%stack (code_hash, retdest) -> (@SEGMENT_KERNEL_GENERAL, 53, code_hash, retdest)
|
||||
ADD
|
||||
%jump(mstore_unpacking)
|
||||
get_create2_address_finish:
|
||||
MSTORE_32BYTES_32
|
||||
POP
|
||||
%stack (retdest) -> (@SEGMENT_KERNEL_GENERAL, 85, retdest) // offset == context == 0
|
||||
// addr, len, retdest
|
||||
|
||||
@ -42,7 +42,7 @@ continue:
|
||||
proof_ok:
|
||||
// stack: i, ctx, final_pos, retdest
|
||||
// We already know final_pos is a jumpdest
|
||||
%stack (i, ctx, final_pos) -> (ctx, @SEGMENT_JUMPDEST_BITS, i)
|
||||
%stack (i, ctx, final_pos) -> (ctx, @SEGMENT_JUMPDEST_BITS, final_pos)
|
||||
%build_address
|
||||
PUSH 1
|
||||
MSTORE_GENERAL
|
||||
@ -145,7 +145,7 @@ global write_table_if_jumpdest:
|
||||
(proof_prefix_addr, ctx) ->
|
||||
(ctx, proof_prefix_addr, 32, proof_prefix_addr, ctx)
|
||||
ADD // combine context and offset to make an address (SEGMENT_CODE == 0)
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// packed_opcodes, proof_prefix_addr, ctx, jumpdest, retdest
|
||||
DUP1 %shl_const(1)
|
||||
DUP2 %shl_const(2)
|
||||
|
||||
@ -105,7 +105,7 @@ global precompile_blake2_f:
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 4, h_0..h_7, m_0..m_15, t_0, t_1, flag, blake2_f_contd, kexit_info
|
||||
%build_address_no_offset
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: rounds, h_0..h_7, m_0..m_15, t_0, t_1, flag, blake2_f_contd, kexit_info
|
||||
|
||||
DUP1
|
||||
|
||||
@ -14,32 +14,32 @@ global precompile_bn_add:
|
||||
|
||||
%charge_gas_const(@BN_ADD_GAS)
|
||||
|
||||
// Load x0, y0, x1, y1 from the call data using `mload_packing`.
|
||||
// Load x0, y0, x1, y1 from the call data using `MLOAD_32BYTES`.
|
||||
PUSH bn_add_return
|
||||
// stack: bn_add_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 96, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 96, 32, bn_add_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: y1, bn_add_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 64, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 64, 32, y1, bn_add_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: x1, y1, bn_add_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 32, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 32, 32, x1, y1, bn_add_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: y0, x1, y1, bn_add_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 32, y0, x1, y1, bn_add_return, kexit_info
|
||||
%build_address_no_offset
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: x0, y0, x1, y1, bn_add_return, kexit_info
|
||||
%jump(bn_add)
|
||||
bn_add_return:
|
||||
@ -53,11 +53,11 @@ bn_add_return:
|
||||
// Store the result (x, y) to the parent's return data using `mstore_unpacking`.
|
||||
%mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 64)
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
|
||||
%stack (parent_ctx, x, y) -> (parent_ctx, @SEGMENT_RETURNDATA, x, 32, bn_add_contd6, parent_ctx, y)
|
||||
%stack (parent_ctx, x, y) -> (parent_ctx, @SEGMENT_RETURNDATA, x, parent_ctx, y)
|
||||
%build_address_no_offset
|
||||
%jump(mstore_unpacking)
|
||||
bn_add_contd6:
|
||||
MSTORE_32BYTES_32
|
||||
POP
|
||||
%stack (parent_ctx, y) -> (parent_ctx, @SEGMENT_RETURNDATA, 32, y, 32, pop_and_return_success)
|
||||
%stack (parent_ctx, y) -> (parent_ctx, @SEGMENT_RETURNDATA, 32, y)
|
||||
%build_address
|
||||
%jump(mstore_unpacking)
|
||||
MSTORE_32BYTES_32
|
||||
%jump(pop_and_return_success)
|
||||
|
||||
@ -14,26 +14,26 @@ global precompile_bn_mul:
|
||||
|
||||
%charge_gas_const(@BN_MUL_GAS)
|
||||
|
||||
// Load x, y, n from the call data using `mload_packing`.
|
||||
// Load x, y, n from the call data using `MLOAD_32BYTES`.
|
||||
PUSH bn_mul_return
|
||||
// stack: bn_mul_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 64, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 64, 32, bn_mul_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: n, bn_mul_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 32, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 32, 32, n, bn_mul_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: y, n, bn_mul_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 32, y, n, bn_mul_return, kexit_info
|
||||
%build_address_no_offset
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: x, y, n, bn_mul_return, kexit_info
|
||||
%jump(bn_mul)
|
||||
bn_mul_return:
|
||||
@ -47,11 +47,12 @@ bn_mul_return:
|
||||
// Store the result (Px, Py) to the parent's return data using `mstore_unpacking`.
|
||||
%mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 64)
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
|
||||
%stack (parent_ctx, Px, Py) -> (parent_ctx, @SEGMENT_RETURNDATA, Px, 32, bn_mul_contd6, parent_ctx, Py)
|
||||
%stack (parent_ctx, Px, Py) -> (parent_ctx, @SEGMENT_RETURNDATA, Px, parent_ctx, Py)
|
||||
%build_address_no_offset
|
||||
%jump(mstore_unpacking)
|
||||
MSTORE_32BYTES_32
|
||||
bn_mul_contd6:
|
||||
POP
|
||||
%stack (parent_ctx, Py) -> (parent_ctx, @SEGMENT_RETURNDATA, 32, Py, 32, pop_and_return_success)
|
||||
%stack (parent_ctx, Py) -> (parent_ctx, @SEGMENT_RETURNDATA, 32, Py)
|
||||
%build_address
|
||||
%jump(mstore_unpacking)
|
||||
MSTORE_32BYTES_32
|
||||
%jump(pop_and_return_success)
|
||||
|
||||
@ -14,32 +14,32 @@ global precompile_ecrec:
|
||||
|
||||
%charge_gas_const(@ECREC_GAS)
|
||||
|
||||
// Load hash, v, r, s from the call data using `mload_packing`.
|
||||
// Load hash, v, r, s from the call data using `MLOAD_32BYTES`.
|
||||
PUSH ecrec_return
|
||||
// stack: ecrec_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 96, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 96, 32, ecrec_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: s, ecrec_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 64, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 64, 32, s, ecrec_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: r, s, ecrec_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 32, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 32, 32, r, s, ecrec_return, kexit_info
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: v, r, s, ecrec_return, kexit_info
|
||||
%stack () -> (@SEGMENT_CALLDATA, 32)
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 32, v, r, s, ecrec_return, kexit_info
|
||||
%build_address_no_offset
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: hash, v, r, s, ecrec_return, kexit_info
|
||||
%jump(ecrecover)
|
||||
ecrec_return:
|
||||
@ -49,9 +49,10 @@ ecrec_return:
|
||||
// Store the result address to the parent's return data using `mstore_unpacking`.
|
||||
%mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 32)
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
|
||||
%stack (parent_ctx, address) -> (parent_ctx, @SEGMENT_RETURNDATA, address, 32, pop_and_return_success)
|
||||
%stack (parent_ctx, address) -> (parent_ctx, @SEGMENT_RETURNDATA, address)
|
||||
%build_address_no_offset
|
||||
%jump(mstore_unpacking)
|
||||
MSTORE_32BYTES_32
|
||||
%jump(pop_and_return_success)
|
||||
|
||||
// On bad input, return empty return data but still return success.
|
||||
ecrec_bad_input:
|
||||
|
||||
@ -18,7 +18,7 @@ mload_bytes_as_limbs:
|
||||
// stack: min(16, num_bytes), addr, num_bytes, retdest, total_num_limbs, len, ..limbs
|
||||
DUP2
|
||||
// stack: addr, min(16, num_bytes), addr, num_bytes, retdest, total_num_limbs, len, ..limbs
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: new_limb, addr, num_bytes, retdest, total_num_limbs, len, ..limbs
|
||||
%stack (new, addr, numb, ret, tot, len) -> (numb, addr, ret, tot, len, new)
|
||||
// stack: num_bytes, addr, retdest, total_num_limbs, len, new_limb, ..limbs
|
||||
@ -113,7 +113,7 @@ calculate_l_E_prime:
|
||||
PUSH @SEGMENT_CALLDATA
|
||||
GET_CONTEXT
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: i[96 + l_B..128 + l_B], l_E, l_B, retdest
|
||||
%log2_floor
|
||||
// stack: log2(i[96 + l_B..128 + l_B]), l_E, l_B, retdest
|
||||
@ -144,7 +144,7 @@ case_le_32:
|
||||
PUSH @SEGMENT_CALLDATA
|
||||
GET_CONTEXT
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: E, retdest
|
||||
%log2_floor
|
||||
// stack: log2(E), retdest
|
||||
@ -172,21 +172,21 @@ global precompile_expmod:
|
||||
GET_CONTEXT
|
||||
// stack: ctx, @SEGMENT_CALLDATA, 32, kexit_info
|
||||
%build_address_no_offset
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: l_B, kexit_info
|
||||
|
||||
// Load l_E from i[32..64].
|
||||
%stack () -> (@SEGMENT_CALLDATA, 32, 32)
|
||||
GET_CONTEXT
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: l_E, l_B, kexit_info
|
||||
|
||||
// Load l_M from i[64..96].
|
||||
%stack () -> (@SEGMENT_CALLDATA, 64, 32)
|
||||
GET_CONTEXT
|
||||
%build_address
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: l_M, l_E, l_B, kexit_info
|
||||
DUP3 ISZERO DUP2 ISZERO
|
||||
MUL // AND
|
||||
|
||||
@ -44,6 +44,7 @@ rip160_contd:
|
||||
// Store the result hash to the parent's return data using `mstore_unpacking`.
|
||||
%mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 32)
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
|
||||
%stack (parent_ctx, hash) -> (parent_ctx, @SEGMENT_RETURNDATA, hash, 32, pop_and_return_success)
|
||||
%stack (parent_ctx, hash) -> (parent_ctx, @SEGMENT_RETURNDATA, hash)
|
||||
%build_address_no_offset
|
||||
%jump(mstore_unpacking)
|
||||
MSTORE_32BYTES_32
|
||||
%jump(pop_and_return_success)
|
||||
|
||||
@ -44,6 +44,7 @@ sha256_contd:
|
||||
// Store the result hash to the parent's return data using `mstore_unpacking`.
|
||||
%mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 32)
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
|
||||
%stack (parent_ctx, hash) -> (parent_ctx, @SEGMENT_RETURNDATA, hash, 32, pop_and_return_success)
|
||||
%stack (parent_ctx, hash) -> (parent_ctx, @SEGMENT_RETURNDATA, hash)
|
||||
%build_address_no_offset
|
||||
%jump(mstore_unpacking)
|
||||
MSTORE_32BYTES_32
|
||||
%jump(pop_and_return_success)
|
||||
|
||||
@ -30,47 +30,47 @@ loading_loop:
|
||||
DUP1 %mul_const(192)
|
||||
// stack: px, i, k, kexit_info
|
||||
GET_CONTEXT
|
||||
%stack (ctx, px) -> (ctx, @SEGMENT_CALLDATA, px, 32, loading_loop_contd, px)
|
||||
%stack (ctx, px) -> (ctx, @SEGMENT_CALLDATA, px, 32, px)
|
||||
%build_address
|
||||
%jump(mload_packing)
|
||||
MLOAD_32BYTES
|
||||
loading_loop_contd:
|
||||
// stack: x, px, i, k, kexit_info
|
||||
SWAP1 %add_const(32)
|
||||
GET_CONTEXT
|
||||
%stack (ctx, py) -> (ctx, @SEGMENT_CALLDATA, py, 32, loading_loop_contd2, py)
|
||||
%stack (ctx, py) -> (ctx, @SEGMENT_CALLDATA, py, 32, py)
|
||||
%build_address
|
||||
%jump(mload_packing)
|
||||
MLOAD_32BYTES
|
||||
loading_loop_contd2:
|
||||
// stack: y, py, x, i, k, kexit_info
|
||||
SWAP1 %add_const(32)
|
||||
GET_CONTEXT
|
||||
%stack (ctx, px_im) -> (ctx, @SEGMENT_CALLDATA, px_im, 32, loading_loop_contd3, px_im)
|
||||
%stack (ctx, px_im) -> (ctx, @SEGMENT_CALLDATA, px_im, 32, px_im)
|
||||
%build_address
|
||||
%jump(mload_packing)
|
||||
MLOAD_32BYTES
|
||||
loading_loop_contd3:
|
||||
// stack: x_im, px_im, y, x, i, k, kexit_info
|
||||
SWAP1 %add_const(32)
|
||||
// stack: px_re, x_im, y, x, i, k, kexit_info
|
||||
GET_CONTEXT
|
||||
%stack (ctx, px_re) -> (ctx, @SEGMENT_CALLDATA, px_re, 32, loading_loop_contd4, px_re)
|
||||
%stack (ctx, px_re) -> (ctx, @SEGMENT_CALLDATA, px_re, 32, px_re)
|
||||
%build_address
|
||||
%jump(mload_packing)
|
||||
MLOAD_32BYTES
|
||||
loading_loop_contd4:
|
||||
// stack: x_re, px_re, x_im, y, x, i, k, kexit_info
|
||||
SWAP1 %add_const(32)
|
||||
// stack: py_im, x_re, x_im, y, x, i, k, kexit_info
|
||||
GET_CONTEXT
|
||||
%stack (ctx, py_im) -> (ctx, @SEGMENT_CALLDATA, py_im, 32, loading_loop_contd5, py_im)
|
||||
%stack (ctx, py_im) -> (ctx, @SEGMENT_CALLDATA, py_im, 32, py_im)
|
||||
%build_address
|
||||
%jump(mload_packing)
|
||||
MLOAD_32BYTES
|
||||
loading_loop_contd5:
|
||||
// stack: y_im, py_im, x_re, x_im, y, x, i, k, kexit_info
|
||||
SWAP1 %add_const(32)
|
||||
// stack: py_re, y_im, x_re, x_im, y, x, i, k, kexit_info
|
||||
GET_CONTEXT
|
||||
%stack (ctx, py_re) -> (ctx, @SEGMENT_CALLDATA, py_re, 32, loading_loop_contd6)
|
||||
%stack (ctx, py_re) -> (ctx, @SEGMENT_CALLDATA, py_re, 32)
|
||||
%build_address
|
||||
%jump(mload_packing)
|
||||
MLOAD_32BYTES
|
||||
loading_loop_contd6:
|
||||
// stack: y_re, y_im, x_re, x_im, y, x, i, k, kexit_info
|
||||
SWAP1 // the EVM serializes the imaginary part first
|
||||
@ -124,6 +124,7 @@ got_result:
|
||||
// Store the result bool (repr. by a U256) to the parent's return data using `mstore_unpacking`.
|
||||
%mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 32)
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
|
||||
%stack (parent_ctx, address) -> (parent_ctx, @SEGMENT_RETURNDATA, address, 32, pop_and_return_success)
|
||||
%stack (parent_ctx, address) -> (parent_ctx, @SEGMENT_RETURNDATA, address)
|
||||
%build_address_no_offset
|
||||
%jump(mstore_unpacking)
|
||||
MSTORE_32BYTES_32
|
||||
%jump(pop_and_return_success)
|
||||
|
||||
@ -47,14 +47,15 @@ global start_txn:
|
||||
// is handled outside of the kernel.
|
||||
%mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_BEFORE)
|
||||
// stack: txn_nb
|
||||
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_BEFORE)
|
||||
// stack: init_used_gas, txn_nb
|
||||
DUP2 %scalar_to_rlp
|
||||
// stack: txn_counter, init_gas_used, txn_nb
|
||||
DUP1 %scalar_to_rlp
|
||||
// stack: txn_counter, txn_nb
|
||||
DUP1 %num_bytes %mul_const(2)
|
||||
// stack: num_nibbles, txn_counter, init_gas_used, txn_nb
|
||||
SWAP2
|
||||
// stack: init_gas_used, txn_counter, num_nibbles, txn_nb
|
||||
// stack: num_nibbles, txn_counter, txn_nb
|
||||
%increment_bounded_rlp
|
||||
// stack: txn_counter, num_nibbles, next_txn_counter, next_num_nibbles, txn_nb
|
||||
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_BEFORE)
|
||||
|
||||
// stack: init_gas_used, txn_counter, num_nibbles, next_txn_counter, next_num_nibbles, txn_nb
|
||||
|
||||
// If the prover has no txn for us to process, halt.
|
||||
PROVER_INPUT(no_txn)
|
||||
@ -62,9 +63,9 @@ global start_txn:
|
||||
|
||||
// Call route_txn. When we return, we will process the txn receipt.
|
||||
PUSH txn_after
|
||||
// stack: retdest, prev_gas_used, txn_counter, num_nibbles, txn_nb
|
||||
DUP4 DUP4 %increment_bounded_rlp
|
||||
%stack (next_txn_counter, next_num_nibbles, retdest, prev_gas_used, txn_counter, num_nibbles) -> (txn_counter, num_nibbles, retdest, prev_gas_used, txn_counter, num_nibbles, next_txn_counter, next_num_nibbles)
|
||||
// stack: retdest, prev_gas_used, txn_counter, num_nibbles, next_txn_counter, next_num_nibbles, txn_nb
|
||||
DUP4 DUP4
|
||||
|
||||
%jump(route_txn)
|
||||
|
||||
global txn_after:
|
||||
@ -72,10 +73,14 @@ global txn_after:
|
||||
%process_receipt
|
||||
// stack: new_cum_gas, txn_counter, num_nibbles, txn_nb
|
||||
SWAP3 %increment SWAP3
|
||||
%jump(execute_withdrawals_post_stack_op)
|
||||
|
||||
global execute_withdrawals:
|
||||
// stack: cum_gas, txn_counter, num_nibbles, txn_nb
|
||||
// stack: cum_gas, txn_counter, num_nibbles, next_txn_counter, next_num_nibbles, txn_nb
|
||||
%stack (cum_gas, txn_counter, num_nibbles, next_txn_counter, next_num_nibbles) -> (cum_gas, txn_counter, num_nibbles)
|
||||
execute_withdrawals_post_stack_op:
|
||||
%withdrawals
|
||||
|
||||
global hash_final_tries:
|
||||
// stack: cum_gas, txn_counter, num_nibbles, txn_nb
|
||||
// Check that we end up with the correct `cum_gas`, `txn_nb` and bloom filter.
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
// Load a big-endian u32, consisting of 4 bytes (c_3, c_2, c_1, c_0).
|
||||
%macro mload_u32
|
||||
// stack: addr
|
||||
%stack (addr) -> (addr, 4, %%after)
|
||||
%jump(mload_packing)
|
||||
%%after:
|
||||
%stack (addr) -> (addr, 4)
|
||||
MLOAD_32BYTES
|
||||
%endmacro
|
||||
|
||||
// Load a little-endian u32, consisting of 4 bytes (c_0, c_1, c_2, c_3).
|
||||
@ -51,17 +50,14 @@
|
||||
// Load a big-endian u256.
|
||||
%macro mload_u256
|
||||
// stack: addr
|
||||
%stack (addr) -> (addr, 32, %%after)
|
||||
%jump(mload_packing)
|
||||
%%after:
|
||||
%stack (addr) -> (addr, 32)
|
||||
MLOAD_32BYTES
|
||||
%endmacro
|
||||
|
||||
// Store a big-endian u32, consisting of 4 bytes (c_3, c_2, c_1, c_0).
|
||||
%macro mstore_u32
|
||||
// stack: addr, value
|
||||
%stack (addr, value) -> (addr, value, 4, %%after)
|
||||
%jump(mstore_unpacking)
|
||||
%%after:
|
||||
MSTORE_32BYTES_4
|
||||
// stack: offset
|
||||
POP
|
||||
%endmacro
|
||||
|
||||
@ -1,22 +1,5 @@
|
||||
// Methods for encoding integers as bytes in memory, as well as the reverse,
|
||||
// decoding bytes as integers. All big-endian.
|
||||
|
||||
// Given a pointer to some bytes in memory, pack them into a word. Assumes 0 < len <= 32.
|
||||
// Pre stack: addr, len, retdest
|
||||
// Post stack: packed_value
|
||||
global mload_packing:
|
||||
// stack: addr, len, retdest
|
||||
MLOAD_32BYTES
|
||||
// stack: packed_value, retdest
|
||||
SWAP1
|
||||
// stack: retdest, packed_value
|
||||
JUMP
|
||||
|
||||
%macro mload_packing
|
||||
%stack (addr, len) -> (addr, len, %%after)
|
||||
%jump(mload_packing)
|
||||
%%after:
|
||||
%endmacro
|
||||
// decoding bytes as integers. All big-endian unless specified.
|
||||
|
||||
global mload_packing_u64_LE:
|
||||
// stack: addr, retdest
|
||||
|
||||
@ -60,11 +60,11 @@ global sys_calldataload:
|
||||
%mload_context_metadata(@CTX_METADATA_CALLDATA_SIZE)
|
||||
%stack (calldata_size, kexit_info, i) -> (calldata_size, i, kexit_info, i)
|
||||
LT %jumpi(calldataload_large_offset)
|
||||
%stack (kexit_info, i) -> (@SEGMENT_CALLDATA, i, 32, sys_calldataload_after_mload_packing, kexit_info)
|
||||
%stack (kexit_info, i) -> (@SEGMENT_CALLDATA, i, 32, kexit_info)
|
||||
GET_CONTEXT
|
||||
%build_address
|
||||
// stack: addr, 32, sys_calldataload_after_mload_packing, kexit_info
|
||||
%jump(mload_packing)
|
||||
// stack: addr, 32, kexit_info
|
||||
MLOAD_32BYTES
|
||||
sys_calldataload_after_mload_packing:
|
||||
// stack: value, kexit_info
|
||||
SWAP1
|
||||
|
||||
@ -63,15 +63,16 @@ global encode_or_hash_node:
|
||||
// Load the hash and return (hash, 32).
|
||||
// stack: node_type, node_ptr, encode_value, cur_len, retdest
|
||||
POP
|
||||
// Update the length of the `TrieData` segment: there are only two
|
||||
// elements in a hash node.
|
||||
SWAP2 %add_const(2) SWAP2
|
||||
|
||||
// stack: node_ptr, encode_value, cur_len, retdest
|
||||
%increment // Skip over node type prefix
|
||||
// stack: hash_ptr, encode_value, cur_len, retdest
|
||||
%mload_trie_data
|
||||
// stack: hash, encode_value, cur_len, retdest
|
||||
%stack (hash, encode_value, cur_len, retdest) -> (retdest, hash, 32, cur_len)
|
||||
// Update the length of the `TrieData` segment: there are only two
|
||||
// elements in a hash node.
|
||||
SWAP2 %add_const(2)
|
||||
%stack (cur_len, encode_value, hash, retdest) -> (retdest, hash, 32, cur_len)
|
||||
JUMP
|
||||
encode_or_hash_concrete_node:
|
||||
%stack (node_type, node_ptr, encode_value, cur_len) -> (node_type, node_ptr, encode_value, cur_len, maybe_hash_node)
|
||||
@ -89,8 +90,8 @@ maybe_hash_node:
|
||||
pack_small_rlp:
|
||||
// stack: result_ptr, result_len, cur_len, retdest
|
||||
%stack (result_ptr, result_len, cur_len)
|
||||
-> (result_ptr, result_len, after_packed_small_rlp, result_len, cur_len)
|
||||
%jump(mload_packing)
|
||||
-> (result_ptr, result_len, result_len, cur_len)
|
||||
MLOAD_32BYTES
|
||||
after_packed_small_rlp:
|
||||
%stack (result, result_len, cur_len, retdest) -> (retdest, result, result_len, cur_len)
|
||||
JUMP
|
||||
@ -182,22 +183,21 @@ encode_node_branch_prepend_prefix:
|
||||
// stack: node_payload_ptr, encode_value, cur_len, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%add_const($i) %mload_trie_data
|
||||
// stack: child_i_ptr, encode_value, cur_len, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%stack
|
||||
(child_i_ptr, encode_value, cur_len, after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest) ->
|
||||
(child_i_ptr, encode_value, cur_len, after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest)
|
||||
%jump(encode_or_hash_node)
|
||||
%%after_encode:
|
||||
// stack: result, result_len, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest
|
||||
// stack: result, result_len, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, old_len, retdest
|
||||
// If result_len != 32, result is raw RLP, with an appropriate RLP prefix already.
|
||||
SWAP1 DUP1 %sub_const(32) %jumpi(%%unpack)
|
||||
SWAP1
|
||||
PUSH 32 DUP2 SUB
|
||||
%jumpi(%%unpack)
|
||||
// Otherwise, result is a hash, and we need to add the prefix 0x80 + 32 = 160.
|
||||
// stack: result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest
|
||||
// stack: result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, old_len, retdest
|
||||
DUP4 // rlp_pos
|
||||
PUSH 160
|
||||
MSTORE_GENERAL
|
||||
SWAP3 %increment SWAP3 // rlp_pos += 1
|
||||
%%unpack:
|
||||
%stack (result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest)
|
||||
%stack (result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, old_len, retdest)
|
||||
-> (rlp_pos, result, result_len, %%after_unpacking,
|
||||
rlp_start, node_payload_ptr, encode_value, cur_len, retdest)
|
||||
%jump(mstore_unpacking)
|
||||
@ -231,7 +231,8 @@ encode_node_extension_after_encode_child:
|
||||
encode_node_extension_after_hex_prefix:
|
||||
// stack: rlp_pos, rlp_start, result, result_len, node_payload_ptr, cur_len, retdest
|
||||
// If result_len != 32, result is raw RLP, with an appropriate RLP prefix already.
|
||||
DUP4 %sub_const(32) %jumpi(encode_node_extension_unpack)
|
||||
PUSH 32 DUP5 SUB
|
||||
%jumpi(encode_node_extension_unpack)
|
||||
// Otherwise, result is a hash, and we need to add the prefix 0x80 + 32 = 160.
|
||||
DUP1 // rlp_pos
|
||||
PUSH 160
|
||||
@ -250,11 +251,6 @@ encode_node_extension_after_unpacking:
|
||||
|
||||
global encode_node_leaf:
|
||||
// stack: node_type, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// `TrieData` holds the node type, the number of nibbles, the nibbles,
|
||||
// the pointer to the value and the value.
|
||||
// First, we add 4 for the node type, the number of nibbles, the nibbles
|
||||
// and the pointer to the value.
|
||||
SWAP3 %add_const(4) SWAP3
|
||||
POP
|
||||
// stack: node_payload_ptr, encode_value, cur_len, retdest
|
||||
%alloc_rlp_block
|
||||
@ -280,7 +276,12 @@ encode_node_leaf_after_hex_prefix:
|
||||
JUMP
|
||||
encode_node_leaf_after_encode_value:
|
||||
// stack: rlp_end_pos, cur_len, rlp_start, retdest
|
||||
%stack(rlp_end_pos, cur_len, rlp_start, retdest) -> (rlp_end_pos, rlp_start, cur_len, retdest)
|
||||
// `TrieData` holds the node type, the number of nibbles, the nibbles,
|
||||
// the pointer to the value and the value.
|
||||
// We add 4 for the node type, the number of nibbles, the nibbles
|
||||
// and the pointer to the value.
|
||||
SWAP1 %add_const(4)
|
||||
%stack(cur_len, rlp_end_pos, rlp_start, retdest) -> (rlp_end_pos, rlp_start, cur_len, retdest)
|
||||
%prepend_rlp_list_prefix
|
||||
%stack (rlp_prefix_start_pos, rlp_len, cur_len, retdest)
|
||||
-> (retdest, rlp_prefix_start_pos, rlp_len, cur_len)
|
||||
|
||||
@ -28,8 +28,8 @@ first_byte:
|
||||
// get the first nibble, if num_nibbles is odd, or zero otherwise
|
||||
SWAP2
|
||||
// stack: packed_nibbles, num_nibbles, rlp_addr, terminated, retdest
|
||||
DUP2 DUP1
|
||||
%mod_const(2)
|
||||
DUP2
|
||||
PUSH 2 DUP2 MOD
|
||||
// stack: parity, num_nibbles, packed_nibbles, num_nibbles, rlp_addr, terminated, retdest
|
||||
SWAP1 SUB
|
||||
%mul_const(4)
|
||||
@ -61,12 +61,12 @@ remaining_bytes:
|
||||
SWAP2
|
||||
PUSH @U256_MAX
|
||||
// stack: U256_MAX, packed_nibbles, num_nibbles, rlp_addr, ret_dest
|
||||
SWAP1 SWAP2 DUP1
|
||||
%mod_const(2)
|
||||
SWAP1 SWAP2
|
||||
PUSH 2 DUP2 MOD
|
||||
// stack: parity, num_nibbles, U256_MAX, packed_nibbles, rlp_addr, ret_dest
|
||||
SWAP1 SUB DUP1
|
||||
// stack: num_nibbles - parity, num_nibbles - parity, U256_MAX, packed_nibbles, rlp_addr, ret_dest
|
||||
%div_const(2)
|
||||
%div2
|
||||
// stack: rem_bytes, num_nibbles - parity, U256_MAX, packed_nibbles, rlp_addr, ret_dest
|
||||
SWAP2 SWAP1
|
||||
// stack: num_nibbles - parity, U256_MAX, rem_bytes, packed_nibbles, rlp_addr, ret_dest
|
||||
|
||||
@ -81,7 +81,7 @@ global scalar_to_rlp:
|
||||
DUP2 DUP2 SUB // len of the key
|
||||
// stack: len, addr', init_addr, retdest
|
||||
DUP3
|
||||
%mload_packing
|
||||
MLOAD_32BYTES
|
||||
// stack: packed_key, addr', init_addr, retdest
|
||||
SWAP2 %pop2
|
||||
// stack: key, retdest
|
||||
|
||||
@ -158,9 +158,9 @@
|
||||
DUP3 DUP6 MUL ISZERO %jumpi(%%return)
|
||||
|
||||
// first_nib_2 = (key_2 >> (bits_2 - 4)) & 0xF
|
||||
DUP6 DUP6 %sub_const(4) SHR %and_const(0xF)
|
||||
DUP6 PUSH 4 DUP7 SUB SHR %and_const(0xF)
|
||||
// first_nib_1 = (key_1 >> (bits_1 - 4)) & 0xF
|
||||
DUP5 DUP5 %sub_const(4) SHR %and_const(0xF)
|
||||
DUP5 PUSH 4 DUP6 SUB SHR %and_const(0xF)
|
||||
// stack: first_nib_1, first_nib_2, len_common, key_common, bits_1, key_1, bits_2, key_2
|
||||
|
||||
// if first_nib_1 != first_nib_2: break
|
||||
@ -204,8 +204,8 @@
|
||||
%pop2
|
||||
%%return:
|
||||
// stack: len_common, key_common, bits_1, key_1, bits_2, key_2
|
||||
SWAP2 %div_const(4) SWAP2 // bits_1 -> len_1 (in nibbles)
|
||||
SWAP4 %div_const(4) SWAP4 // bits_2 -> len_2 (in nibbles)
|
||||
SWAP2 %shr_const(2) SWAP2 // bits_1 -> len_1 (in nibbles)
|
||||
SWAP4 %shr_const(2) SWAP4 // bits_2 -> len_2 (in nibbles)
|
||||
// stack: len_common, key_common, len_1, key_1, len_2, key_2
|
||||
%endmacro
|
||||
|
||||
|
||||
@ -1,28 +1,20 @@
|
||||
// RLP-encode a fixed-length 160 bit (20 byte) string. Assumes string < 2^160.
|
||||
// Convenience macro to RLP-encode a fixed-length 160 bit (20 byte) string
|
||||
// and return where we left off. Assumes string < 2^160.
|
||||
// Pre stack: rlp_addr, string, retdest
|
||||
// Post stack: rlp_addr
|
||||
global encode_rlp_160:
|
||||
PUSH 20
|
||||
%jump(encode_rlp_fixed)
|
||||
|
||||
// Convenience macro to call encode_rlp_160 and return where we left off.
|
||||
%macro encode_rlp_160
|
||||
%stack (rlp_addr, string) -> (rlp_addr, string, %%after)
|
||||
%jump(encode_rlp_160)
|
||||
%stack (rlp_addr, string) -> (20, rlp_addr, string, %%after)
|
||||
%jump(encode_rlp_fixed)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
// RLP-encode a fixed-length 256 bit (32 byte) string.
|
||||
// Convenience macro to RLP-encode a fixed-length 256 bit (32 byte) string
|
||||
// and return where we left off.
|
||||
// Pre stack: rlp_addr, string, retdest
|
||||
// Post stack: rlp_addr
|
||||
global encode_rlp_256:
|
||||
PUSH 32
|
||||
%jump(encode_rlp_fixed)
|
||||
|
||||
// Convenience macro to call encode_rlp_256 and return where we left off.
|
||||
%macro encode_rlp_256
|
||||
%stack (rlp_addr, string) -> (rlp_addr, string, %%after)
|
||||
%jump(encode_rlp_256)
|
||||
%stack (rlp_addr, string) -> (32, rlp_addr, string, %%after)
|
||||
%jump(encode_rlp_fixed)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
// its number of nibbles when required. Shouldn't be
|
||||
// called with rlp_index > 0x82 ff ff
|
||||
global increment_bounded_rlp:
|
||||
// stack: rlp_index, num_nibbles, retdest
|
||||
DUP1
|
||||
// stack: num_nibbles, rlp_index, retdest
|
||||
DUP2
|
||||
%eq_const(0x80)
|
||||
%jumpi(case_0x80)
|
||||
DUP1
|
||||
@ -14,19 +14,19 @@ global increment_bounded_rlp:
|
||||
%jumpi(case_0x81ff)
|
||||
// If rlp_index != 0x80 and rlp_index != 0x7f and rlp_index != 0x81ff
|
||||
// we only need to add one and keep the number of nibbles
|
||||
%increment
|
||||
%stack (rlp_index, num_nibbles, retdest) -> (retdest, rlp_index, num_nibbles)
|
||||
DUP2 %increment DUP2
|
||||
%stack (next_num_nibbles, next_rlp_index, num_nibbles, rlp_index, retdest) -> (retdest, rlp_index, num_nibbles, next_rlp_index, next_num_nibbles)
|
||||
JUMP
|
||||
|
||||
case_0x80:
|
||||
%stack (rlp_index, num_nibbles, retdest) -> (retdest, 0x01, 2)
|
||||
%stack (num_nibbles, rlp_index, retdest) -> (retdest, 0x80, 2, 0x01, 2)
|
||||
JUMP
|
||||
case_0x7f:
|
||||
%stack (rlp_index, num_nibbles, retdest) -> (retdest, 0x8180, 4)
|
||||
%stack (num_nibbles, rlp_index, retdest) -> (retdest, 0x7f, 2, 0x8180, 4)
|
||||
JUMP
|
||||
|
||||
case_0x81ff:
|
||||
%stack (rlp_index, num_nibbles, retdest) -> (retdest, 0x820100, 6)
|
||||
%stack (num_nibbles, rlp_index, retdest) -> (retdest, 0x81ff, 4, 0x820100, 6)
|
||||
JUMP
|
||||
|
||||
|
||||
|
||||
@ -55,12 +55,10 @@ sys_keccak256_empty:
|
||||
// Since KECCAK_GENERAL takes its input from memory, we will first write
|
||||
// a's bytes to @SEGMENT_KERNEL_GENERAL[0..32], then b's bytes to
|
||||
// @SEGMENT_KERNEL_GENERAL[32..64].
|
||||
%stack (a) -> (@SEGMENT_KERNEL_GENERAL, a, 32, %%after_mstore_a)
|
||||
%jump(mstore_unpacking)
|
||||
%%after_mstore_a:
|
||||
%stack (addr, b) -> (addr, b, 32, %%after_mstore_b)
|
||||
%jump(mstore_unpacking)
|
||||
%%after_mstore_b:
|
||||
%stack (a) -> (@SEGMENT_KERNEL_GENERAL, a)
|
||||
MSTORE_32BYTES_32
|
||||
// stack: addr, b
|
||||
MSTORE_32BYTES_32
|
||||
%stack (addr) -> (addr, 64, 64) // reset the address offset
|
||||
SUB
|
||||
KECCAK_GENERAL
|
||||
|
||||
@ -5,60 +5,6 @@ use crate::cpu::kernel::aggregator::KERNEL;
|
||||
use crate::cpu::kernel::interpreter::Interpreter;
|
||||
use crate::memory::segments::Segment;
|
||||
|
||||
#[test]
|
||||
fn test_mload_packing_1_byte() -> Result<()> {
|
||||
let mload_packing = KERNEL.global_labels["mload_packing"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let len = 1.into();
|
||||
let addr = (Segment::RlpRaw as u64 + 2).into();
|
||||
let initial_stack = vec![retdest, len, addr];
|
||||
|
||||
let mut interpreter = Interpreter::new_with_kernel(mload_packing, initial_stack);
|
||||
interpreter.set_rlp_memory(vec![0, 0, 0xAB]);
|
||||
|
||||
interpreter.run()?;
|
||||
assert_eq!(interpreter.stack(), vec![0xAB.into()]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mload_packing_3_bytes() -> Result<()> {
|
||||
let mload_packing = KERNEL.global_labels["mload_packing"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let len = 3.into();
|
||||
let addr = (Segment::RlpRaw as u64 + 2).into();
|
||||
let initial_stack = vec![retdest, len, addr];
|
||||
|
||||
let mut interpreter = Interpreter::new_with_kernel(mload_packing, initial_stack);
|
||||
interpreter.set_rlp_memory(vec![0, 0, 0xAB, 0xCD, 0xEF]);
|
||||
|
||||
interpreter.run()?;
|
||||
assert_eq!(interpreter.stack(), vec![0xABCDEF.into()]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mload_packing_32_bytes() -> Result<()> {
|
||||
let mload_packing = KERNEL.global_labels["mload_packing"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let len = 32.into();
|
||||
let addr = (Segment::RlpRaw as u64).into();
|
||||
let initial_stack = vec![retdest, len, addr];
|
||||
|
||||
let mut interpreter = Interpreter::new_with_kernel(mload_packing, initial_stack);
|
||||
interpreter.set_rlp_memory(vec![0xFF; 32]);
|
||||
|
||||
interpreter.run()?;
|
||||
assert_eq!(interpreter.stack(), vec![U256::MAX]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mstore_unpacking() -> Result<()> {
|
||||
let mstore_unpacking = KERNEL.global_labels["mstore_unpacking"];
|
||||
|
||||
@ -45,13 +45,13 @@ fn test_encode_rlp_scalar_medium() -> Result<()> {
|
||||
|
||||
#[test]
|
||||
fn test_encode_rlp_160() -> Result<()> {
|
||||
let encode_rlp_160 = KERNEL.global_labels["encode_rlp_160"];
|
||||
let encode_rlp_fixed = KERNEL.global_labels["encode_rlp_fixed"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let string = 0x12345.into();
|
||||
let pos = U256::from(Segment::RlpRaw as usize);
|
||||
let initial_stack = vec![retdest, string, pos];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_160, initial_stack);
|
||||
let initial_stack = vec![retdest, string, pos, U256::from(20)];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_fixed, initial_stack);
|
||||
|
||||
interpreter.run()?;
|
||||
let expected_stack = vec![pos + U256::from(1 + 20)]; // pos'
|
||||
@ -65,13 +65,13 @@ fn test_encode_rlp_160() -> Result<()> {
|
||||
|
||||
#[test]
|
||||
fn test_encode_rlp_256() -> Result<()> {
|
||||
let encode_rlp_256 = KERNEL.global_labels["encode_rlp_256"];
|
||||
let encode_rlp_fixed = KERNEL.global_labels["encode_rlp_fixed"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let string = 0x12345.into();
|
||||
let pos = U256::from(Segment::RlpRaw as usize);
|
||||
let initial_stack = vec![retdest, string, pos];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_256, initial_stack);
|
||||
let initial_stack = vec![retdest, string, pos, U256::from(32)];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_fixed, initial_stack);
|
||||
|
||||
interpreter.run()?;
|
||||
let expected_stack = vec![pos + U256::from(1 + 32)]; // pos'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user