152 lines
5.9 KiB
NASM
Raw Normal View History

// Given an address, return a pointer to the associated account data, which
// consists of four words (nonce, balance, storage_root, code_hash), in the
// state trie. Returns null if the address is not found.
2022-10-02 11:14:07 -07:00
global mpt_read_state_trie:
// stack: addr, retdest
2022-10-17 11:31:08 -07:00
%addr_to_state_key
2022-10-02 11:14:07 -07:00
// stack: key, retdest
PUSH 64 // num_nibbles
%mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // node_ptr
// stack: node_ptr, num_nibbles, key, retdest
%jump(mpt_read)
2022-10-17 11:31:08 -07:00
// Convenience macro to call mpt_read_state_trie and return where we left off.
%macro mpt_read_state_trie
%stack (addr) -> (addr, %%after)
%jump(mpt_read_state_trie)
%%after:
%endmacro
// Read a value from a MPT.
//
// Arguments:
// - the virtual address of the trie to search in
2022-09-24 22:23:24 -07:00
// - the number of nibbles in the key (should start at 64)
2022-10-17 11:31:08 -07:00
// - the key, as a U256
2023-03-19 14:13:42 -07:00
// - return destination
//
// This function returns a pointer to the value, or 0 if the key is not found.
global mpt_read:
2022-09-24 22:23:24 -07:00
// stack: node_ptr, num_nibbles, key, retdest
DUP1
%mload_trie_data
2022-09-24 22:23:24 -07:00
// stack: node_type, node_ptr, num_nibbles, key, retdest
// Increment node_ptr, so it points to the node payload instead of its type.
SWAP1 %increment SWAP1
2022-09-24 22:23:24 -07:00
// stack: node_type, node_payload_ptr, num_nibbles, key, retdest
2022-09-22 20:09:48 -07:00
DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(mpt_read_empty)
DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(mpt_read_branch)
DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(mpt_read_extension)
2022-09-22 20:09:48 -07:00
DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(mpt_read_leaf)
2022-10-08 13:23:00 -07:00
// There's still the MPT_NODE_HASH case, but if we hit a hash node,
// it means the prover failed to provide necessary Merkle data, so panic.
PANIC
2023-03-19 14:13:42 -07:00
global mpt_read_empty:
// Return 0 to indicate that the value was not found.
2022-09-24 22:23:24 -07:00
%stack (node_type, node_payload_ptr, num_nibbles, key, retdest)
-> (retdest, 0)
JUMP
2023-03-19 14:13:42 -07:00
global mpt_read_branch:
2022-09-24 22:23:24 -07:00
// stack: node_type, node_payload_ptr, num_nibbles, key, retdest
POP
2022-09-24 22:23:24 -07:00
// stack: node_payload_ptr, num_nibbles, key, retdest
DUP2 // num_nibbles
ISZERO
2022-09-24 22:23:24 -07:00
// stack: num_nibbles == 0, node_payload_ptr, num_nibbles, key, retdest
%jumpi(mpt_read_branch_end_of_key)
// We have not reached the end of the key, so we descend to one of our children.
2022-09-24 22:23:24 -07:00
// stack: node_payload_ptr, num_nibbles, key, retdest
%stack (node_payload_ptr, num_nibbles, key)
-> (num_nibbles, key, node_payload_ptr)
// stack: num_nibbles, key, node_payload_ptr, retdest
%split_first_nibble
%stack (first_nibble, num_nibbles, key, node_payload_ptr)
-> (node_payload_ptr, first_nibble, num_nibbles, key)
// child_ptr = load(node_payload_ptr + first_nibble)
ADD %mload_trie_data
// stack: child_ptr, num_nibbles, key, retdest
%jump(mpt_read) // recurse
2023-03-19 14:13:42 -07:00
global mpt_read_branch_end_of_key:
2022-09-24 22:23:24 -07:00
%stack (node_payload_ptr, num_nibbles, key, retdest) -> (node_payload_ptr, retdest)
// stack: node_payload_ptr, retdest
%add_const(16) // skip over the 16 child nodes
2022-10-08 13:51:52 -07:00
// stack: value_ptr_ptr, retdest
%mload_trie_data
2022-10-05 20:31:36 -07:00
// stack: value_ptr, retdest
SWAP1
JUMP
2023-03-19 14:13:42 -07:00
global mpt_read_extension:
2022-09-24 22:23:24 -07:00
// stack: node_type, node_payload_ptr, num_nibbles, key, retdest
2022-09-27 10:49:13 -07:00
%stack (node_type, node_payload_ptr, num_nibbles, key)
-> (num_nibbles, key, node_payload_ptr)
// stack: num_nibbles, key, node_payload_ptr, retdest
DUP3 %mload_trie_data
// stack: node_num_nibbles, num_nibbles, key, node_payload_ptr, retdest
SWAP1
SUB
// stack: future_nibbles, key, node_payload_ptr, retdest
DUP2 DUP2
// stack: future_nibbles, key, future_nibbles, key, node_payload_ptr, retdest
%mul_const(4) SHR // key_part = key >> (future_nibbles * 4)
DUP1
// stack: key_part, key_part, future_nibbles, key, node_payload_ptr, retdest
DUP5 %increment %mload_trie_data
2022-09-27 10:49:13 -07:00
// stack: node_key, key_part, key_part, future_nibbles, key, node_payload_ptr, retdest
EQ // does the first part of our key match the node's key?
%jumpi(mpt_read_extension_found)
2023-03-19 14:13:42 -07:00
global mpt_read_extension_not_found:
2022-09-27 10:49:13 -07:00
// Not found; return 0.
2023-03-19 14:13:42 -07:00
%stack (key_part, future_nibbles, key, node_payload_ptr, retdest) -> (retdest, 0)
2022-09-27 10:49:13 -07:00
JUMP
mpt_read_extension_found:
// stack: key_part, future_nibbles, key, node_payload_ptr, retdest
DUP2 %mul_const(4) SHL // key_part_shifted = (key_part << (future_nibbles * 4))
// stack: key_part_shifted, future_nibbles, key, node_payload_ptr, retdest
%stack (key_part_shifted, future_nibbles, key)
-> (key, key_part_shifted, future_nibbles)
SUB // key -= key_part_shifted
// stack: key, future_nibbles, node_payload_ptr, retdest
SWAP2
// stack: node_payload_ptr, future_nibbles, key, retdest
%add_const(2) // child pointer is third field of extension node
%mload_trie_data
// stack: child_ptr, future_nibbles, key, retdest
%jump(mpt_read) // recurse
mpt_read_leaf:
2022-09-27 10:49:13 -07:00
// stack: node_type, node_payload_ptr, num_nibbles, key, retdest
POP
2022-09-27 10:49:13 -07:00
// stack: node_payload_ptr, num_nibbles, key, retdest
2022-09-24 22:23:24 -07:00
DUP1 %mload_trie_data
2022-09-27 10:49:13 -07:00
// stack: node_num_nibbles, node_payload_ptr, num_nibbles, key, retdest
DUP2 %increment %mload_trie_data
2022-09-27 10:49:13 -07:00
// stack: node_key, node_num_nibbles, node_payload_ptr, num_nibbles, key, retdest
SWAP3
// stack: num_nibbles, node_num_nibbles, node_payload_ptr, node_key, key, retdest
2022-09-24 22:23:24 -07:00
EQ
2022-09-27 10:49:13 -07:00
%stack (num_nibbles_match, node_payload_ptr, node_key, key)
2022-09-24 22:23:24 -07:00
-> (key, node_key, num_nibbles_match, node_payload_ptr)
EQ
AND
// stack: keys_match && num_nibbles_match, node_payload_ptr, retdest
%jumpi(mpt_read_leaf_found)
2023-03-19 14:13:42 -07:00
global mpt_read_leaf_not_found:
2022-09-27 10:49:13 -07:00
// Not found; return 0.
2022-09-24 22:23:24 -07:00
%stack (node_payload_ptr, retdest) -> (retdest, 0)
JUMP
mpt_read_leaf_found:
// stack: node_payload_ptr, retdest
2022-10-08 13:51:52 -07:00
%add_const(2) // The value pointer is located after num_nibbles and the key.
// stack: value_ptr_ptr, retdest
%mload_trie_data
2022-09-24 22:23:24 -07:00
// stack: value_ptr, retdest
SWAP1
JUMP