mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-12 18:53:11 +00:00
207 lines
6.4 KiB
NASM
207 lines
6.4 KiB
NASM
// TODO: Receipt trie leaves are variable-length, so we need to be careful not
|
|
// to permit buffer over-reads.
|
|
|
|
// Load all partial trie data from prover inputs.
|
|
global load_all_mpts:
|
|
// stack: retdest
|
|
// First set @GLOBAL_METADATA_TRIE_DATA_SIZE = 1.
|
|
// We don't want it to start at 0, as we use 0 as a null pointer.
|
|
PUSH 1
|
|
%set_trie_data_size
|
|
|
|
%load_mpt %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT)
|
|
%load_mpt %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT)
|
|
%load_mpt %mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_ROOT)
|
|
|
|
PROVER_INPUT(mpt)
|
|
// stack: num_storage_tries, retdest
|
|
DUP1 %mstore_global_metadata(@GLOBAL_METADATA_NUM_STORAGE_TRIES)
|
|
// stack: num_storage_tries, retdest
|
|
PUSH 0 // i = 0
|
|
// stack: i, num_storage_tries, retdest
|
|
storage_trie_loop:
|
|
DUP2 DUP2 EQ
|
|
// stack: i == num_storage_tries, i, num_storage_tries, retdest
|
|
%jumpi(storage_trie_loop_end)
|
|
// stack: i, num_storage_tries, retdest
|
|
PROVER_INPUT(mpt)
|
|
// stack: storage_trie_addr, i, num_storage_tries, retdest
|
|
DUP2
|
|
// stack: i, storage_trie_addr, i, num_storage_tries, retdest
|
|
%mstore_kernel(@SEGMENT_STORAGE_TRIE_ADDRS)
|
|
// stack: i, num_storage_tries, retdest
|
|
%load_mpt
|
|
// stack: root_ptr, i, num_storage_tries, retdest
|
|
DUP2
|
|
// stack: i, root_ptr, i, num_storage_tries, retdest
|
|
%mstore_kernel(@SEGMENT_STORAGE_TRIE_PTRS)
|
|
// stack: i, num_storage_tries, retdest
|
|
%jump(storage_trie_loop)
|
|
storage_trie_loop_end:
|
|
// stack: i, num_storage_tries, retdest
|
|
%pop2
|
|
// stack: retdest
|
|
JUMP
|
|
|
|
// Load an MPT from prover inputs.
|
|
// Pre stack: retdest
|
|
// Post stack: node_ptr
|
|
load_mpt:
|
|
// stack: retdest
|
|
PROVER_INPUT(mpt)
|
|
// stack: node_type, retdest
|
|
|
|
DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(load_mpt_empty)
|
|
DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(load_mpt_branch)
|
|
DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(load_mpt_extension)
|
|
DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(load_mpt_leaf)
|
|
DUP1 %eq_const(@MPT_NODE_HASH) %jumpi(load_mpt_digest)
|
|
PANIC // Invalid node type
|
|
|
|
load_mpt_empty:
|
|
// TRIE_DATA[0] = 0, and an empty node has type 0, so we can simply return the null pointer.
|
|
%stack (node_type, retdest) -> (retdest, 0)
|
|
JUMP
|
|
|
|
load_mpt_branch:
|
|
// stack: node_type, retdest
|
|
%get_trie_data_size
|
|
// stack: node_ptr, node_type, retdest
|
|
SWAP1 %append_to_trie_data
|
|
// stack: node_ptr, retdest
|
|
// Save the offset of our 16 child pointers so we can write them later.
|
|
// Then advance out current trie pointer beyond them, so we can load the
|
|
// value and have it placed after our child pointers.
|
|
%get_trie_data_size
|
|
// stack: children_ptr, node_ptr, retdest
|
|
DUP1 %add_const(17) // Skip over 16 children plus the value pointer
|
|
// stack: value_ptr, children_ptr, node_ptr, retdest
|
|
%set_trie_data_size
|
|
// stack: children_ptr, node_ptr, retdest
|
|
%load_value
|
|
// stack: children_ptr, value_ptr, node_ptr, retdest
|
|
SWAP1
|
|
|
|
// Load the 16 children.
|
|
%rep 16
|
|
%load_mpt
|
|
// stack: child_ptr, next_child_ptr_ptr, value_ptr, node_ptr, retdest
|
|
DUP2
|
|
// stack: next_child_ptr_ptr, child_ptr, next_child_ptr_ptr, value_ptr, node_ptr, retdest
|
|
%mstore_trie_data
|
|
// stack: next_child_ptr_ptr, value_ptr, node_ptr, retdest
|
|
%increment
|
|
// stack: next_child_ptr_ptr, value_ptr, node_ptr, retdest
|
|
%endrep
|
|
|
|
// stack: value_ptr_ptr, value_ptr, node_ptr, retdest
|
|
%mstore_trie_data
|
|
// stack: node_ptr, retdest
|
|
SWAP1
|
|
JUMP
|
|
|
|
load_mpt_extension:
|
|
// stack: node_type, retdest
|
|
%get_trie_data_size
|
|
// stack: node_ptr, node_type, retdest
|
|
SWAP1 %append_to_trie_data
|
|
// stack: node_ptr, retdest
|
|
PROVER_INPUT(mpt) // read num_nibbles
|
|
%append_to_trie_data
|
|
PROVER_INPUT(mpt) // read packed_nibbles
|
|
%append_to_trie_data
|
|
// stack: node_ptr, retdest
|
|
|
|
%get_trie_data_size
|
|
// stack: child_ptr_ptr, node_ptr, retdest
|
|
// Increment trie_data_size, to leave room for child_ptr_ptr, before we load our child.
|
|
DUP1 %increment %set_trie_data_size
|
|
// stack: child_ptr_ptr, node_ptr, retdest
|
|
|
|
%load_mpt
|
|
// stack: child_ptr, child_ptr_ptr, node_ptr, retdest
|
|
SWAP1
|
|
%mstore_trie_data
|
|
// stack: node_ptr, retdest
|
|
SWAP1
|
|
JUMP
|
|
|
|
load_mpt_leaf:
|
|
// stack: node_type, retdest
|
|
%get_trie_data_size
|
|
// stack: node_ptr, node_type, retdest
|
|
SWAP1 %append_to_trie_data
|
|
// stack: node_ptr, retdest
|
|
PROVER_INPUT(mpt) // read num_nibbles
|
|
%append_to_trie_data
|
|
PROVER_INPUT(mpt) // read packed_nibbles
|
|
%append_to_trie_data
|
|
// stack: node_ptr, retdest
|
|
// We save value_ptr_ptr = get_trie_data_size, then increment trie_data_size
|
|
// to skip over the slot for value_ptr. We will write value_ptr after the
|
|
// load_value call.
|
|
%get_trie_data_size
|
|
// stack: value_ptr_ptr, node_ptr, retdest
|
|
DUP1 %increment %set_trie_data_size
|
|
// stack: value_ptr_ptr, node_ptr, retdest
|
|
%load_value
|
|
// stack: value_ptr, value_ptr_ptr, node_ptr, retdest
|
|
SWAP1 %mstore_trie_data
|
|
// stack: node_ptr, retdest
|
|
SWAP1
|
|
JUMP
|
|
|
|
load_mpt_digest:
|
|
// stack: node_type, retdest
|
|
%get_trie_data_size
|
|
// stack: node_ptr, node_type, retdest
|
|
SWAP1 %append_to_trie_data
|
|
// stack: node_ptr, retdest
|
|
PROVER_INPUT(mpt) // read digest
|
|
%append_to_trie_data
|
|
// stack: node_ptr, retdest
|
|
SWAP1
|
|
JUMP
|
|
|
|
// Convenience macro to call load_mpt and return where we left off.
|
|
%macro load_mpt
|
|
PUSH %%after
|
|
%jump(load_mpt)
|
|
%%after:
|
|
%endmacro
|
|
|
|
// Load a leaf from prover input, append it to trie data, and return a pointer to it.
|
|
%macro load_value
|
|
// stack: (empty)
|
|
PROVER_INPUT(mpt)
|
|
// stack: value_len
|
|
DUP1 ISZERO
|
|
%jumpi(%%return_null)
|
|
// stack: value_len
|
|
%get_trie_data_size
|
|
SWAP1
|
|
// stack: value_len, value_ptr
|
|
DUP1 %append_to_trie_data
|
|
// stack: value_len, value_ptr
|
|
%%loop:
|
|
DUP1 ISZERO
|
|
// stack: value_len == 0, value_len, value_ptr
|
|
%jumpi(%%finish_loop)
|
|
// stack: value_len, value_ptr
|
|
PROVER_INPUT(mpt)
|
|
// stack: leaf_part, value_len, value_ptr
|
|
%append_to_trie_data
|
|
// stack: value_len, value_ptr
|
|
%decrement
|
|
// stack: value_len', value_ptr
|
|
%jump(%%loop)
|
|
%%finish_loop:
|
|
// stack: value_len, value_ptr
|
|
POP
|
|
// stack: value_ptr
|
|
%jump(%%end)
|
|
%%return_null:
|
|
%stack (value_len) -> (0)
|
|
%%end:
|
|
%endmacro
|