mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 00:33:06 +00:00
Rework MPT hashing to support inlining <32 byte children
This commit is contained in:
parent
7ccc673368
commit
0c9847abf3
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
global mload_packing:
|
global mload_packing:
|
||||||
// stack: context, segment, offset, len, retdest
|
// stack: context, segment, offset, len, retdest
|
||||||
// TODO
|
PANIC // TODO
|
||||||
// stack: value
|
// stack: value
|
||||||
|
|
||||||
// Pre stack: context, segment, offset, value, len, retdest
|
// Pre stack: context, segment, offset, value, len, retdest
|
||||||
|
|||||||
@ -1,82 +1,155 @@
|
|||||||
// Computes the Merkle root of the given trie node.
|
// Computes the Merkle root of the given trie node.
|
||||||
//
|
//
|
||||||
// The encode_value function should take as input
|
// encode_value is a function which should take as input
|
||||||
// - the position withing @SEGMENT_RLP_RAW to write to,
|
// - the position withing @SEGMENT_RLP_RAW to write to,
|
||||||
// - the offset of a value within @SEGMENT_TRIE_DATA, and
|
// - the offset of a value within @SEGMENT_TRIE_DATA, and
|
||||||
// - a return address.
|
// - a return address.
|
||||||
// It should serialize the value, write it to @SEGMENT_RLP_RAW starting at the
|
// It should serialize the value, write it to @SEGMENT_RLP_RAW starting at the
|
||||||
// given position, and return an updated position (the next unused offset).
|
// given position, and return an updated position (the next unused offset).
|
||||||
%macro mpt_hash(encode_value)
|
//
|
||||||
// stack: node_ptr, retdest
|
// Pre stack: node_ptr, encode_value, retdest
|
||||||
DUP1
|
// Post stack: hash
|
||||||
%mload_trie_data
|
global mpt_hash:
|
||||||
// stack: node_type, node_ptr, retdest
|
// stack: node_ptr, encode_value, retdest
|
||||||
// Increment node_ptr, so it points to the node payload instead of its type.
|
%stack (node_ptr, encode_value) -> (node_ptr, encode_value, mpt_hash_hash_if_rlp)
|
||||||
SWAP1 %add_const(1) SWAP1
|
%jump(encode_or_hash_node)
|
||||||
// stack: node_type, node_payload_ptr, retdest
|
mpt_hash_hash_if_rlp:
|
||||||
|
// stack: result, result_len, retdest
|
||||||
DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(mpt_hash_empty)
|
// If result_len < 32, then we have an RLP blob, and we need to hash it.
|
||||||
DUP1 %eq_const(@MPT_NODE_HASH) %jumpi(mpt_hash_hash)
|
DUP2 %lt_const(32) %jumpi(mpt_hash_hash_rlp)
|
||||||
DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(%%mpt_hash_branch)
|
// Otherwise, we already have a hash, so just return it.
|
||||||
DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(%%mpt_hash_extension)
|
// stack: result, result_len, retdest
|
||||||
DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(%%mpt_hash_leaf)
|
%stack (result, result_len, retdest) -> (retdest, result)
|
||||||
PANIC // Invalid node type? Shouldn't get here.
|
JUMP
|
||||||
|
mpt_hash_hash_rlp:
|
||||||
%%mpt_hash_branch:
|
// stack: result, result_len, retdest
|
||||||
// stack: node_type, node_payload_ptr, retdest
|
%stack (result, result_len)
|
||||||
POP
|
// context, segment, offset, value, len, retdest
|
||||||
// stack: node_payload_ptr, retdest
|
-> (0, @SEGMENT_RLP_RAW, 0, result, result_len, mpt_hash_hash_rlp_after_unpacking)
|
||||||
PANIC // TODO
|
%jump(mstore_unpacking)
|
||||||
|
mpt_hash_hash_rlp_after_unpacking:
|
||||||
%%mpt_hash_extension:
|
// stack: result_len, retdest
|
||||||
// stack: node_type, node_payload_ptr, retdest
|
PUSH 0 // offset
|
||||||
POP
|
PUSH @SEGMENT_RLP_RAW // segment
|
||||||
// stack: node_payload_ptr, retdest
|
PUSH 0 // context
|
||||||
PANIC // TODO
|
// stack: result_addr: 3, result_len, retdest
|
||||||
|
|
||||||
%%mpt_hash_leaf:
|
|
||||||
// stack: node_type, node_payload_ptr, retdest
|
|
||||||
POP
|
|
||||||
// stack: node_payload_ptr, retdest
|
|
||||||
PUSH %%mpt_hash_leaf_after_hex_prefix // retdest
|
|
||||||
PUSH 1 // terminated
|
|
||||||
// stack: terminated, %%mpt_hash_leaf_after_hex_prefix, node_payload_ptr, retdest
|
|
||||||
DUP3 %add_const(1) %mload_trie_data // Load the packed_nibbles field, which is at index 1.
|
|
||||||
// stack: packed_nibbles, terminated, %%mpt_hash_leaf_after_hex_prefix, node_payload_ptr, retdest
|
|
||||||
DUP4 %mload_trie_data // Load the num_nibbles field, which is at index 0.
|
|
||||||
// stack: num_nibbles, packed_nibbles, terminated, %%mpt_hash_leaf_after_hex_prefix, node_payload_ptr, retdest
|
|
||||||
PUSH 9 // We start at 9 to leave room to prepend the largest possible RLP list header.
|
|
||||||
// stack: rlp_start, num_nibbles, packed_nibbles, terminated, %%mpt_hash_leaf_after_hex_prefix, node_payload_ptr, retdest
|
|
||||||
%jump(hex_prefix_rlp)
|
|
||||||
%%mpt_hash_leaf_after_hex_prefix:
|
|
||||||
// stack: rlp_pos, node_payload_ptr, retdest
|
|
||||||
SWAP1
|
|
||||||
%add_const(2) // The value starts at index 2.
|
|
||||||
%stack (value_ptr, rlp_pos, retdest)
|
|
||||||
-> (rlp_pos, value_ptr, %%mpt_hash_leaf_after_encode_value, retdest)
|
|
||||||
%jump($encode_value)
|
|
||||||
%%mpt_hash_leaf_after_encode_value:
|
|
||||||
// stack: rlp_end_pos, retdest
|
|
||||||
%prepend_rlp_list_prefix
|
|
||||||
// stack: rlp_start_pos, rlp_len, retdest
|
|
||||||
PUSH @SEGMENT_RLP_RAW
|
|
||||||
PUSH 0 // kernel context
|
|
||||||
// stack: rlp_start_addr: 3, rlp_len, retdest
|
|
||||||
KECCAK_GENERAL
|
KECCAK_GENERAL
|
||||||
// stack: hash, retdest
|
// stack: hash, retdest
|
||||||
SWAP1
|
SWAP1
|
||||||
JUMP
|
JUMP
|
||||||
%endmacro
|
|
||||||
|
|
||||||
global mpt_hash_empty:
|
// Given a trie node, return its RLP encoding if it is is less than 32 bytes,
|
||||||
%stack (node_type, node_payload_ptr, retdest) -> (retdest, @EMPTY_NODE_HASH)
|
// otherwise return the Keccak256 hash of its RLP encoding.
|
||||||
|
//
|
||||||
|
// The result is given as a (value, length) pair, where the length is given
|
||||||
|
// in bytes.
|
||||||
|
//
|
||||||
|
// Pre stack: node_ptr, encode_value, retdest
|
||||||
|
// Post stack: result, result_len
|
||||||
|
global encode_or_hash_node:
|
||||||
|
%stack (node_ptr, encode_value) -> (node_ptr, encode_value, maybe_hash_node)
|
||||||
|
%jump(encode_node)
|
||||||
|
maybe_hash_node:
|
||||||
|
// stack: result_ptr, result_len, retdest
|
||||||
|
DUP2 %lt_const(32)
|
||||||
|
%jumpi(pack_small_rlp)
|
||||||
|
|
||||||
|
// result_len >= 32, so we hash the result.
|
||||||
|
// stack: result_ptr, result_len, retdest
|
||||||
|
PUSH @SEGMENT_RLP_RAW // segment
|
||||||
|
PUSH 0 // context
|
||||||
|
// stack: result_addr: 3, result_len, retdest
|
||||||
|
KECCAK_GENERAL
|
||||||
|
%stack (hash, retdest) -> (retdest, hash, 32)
|
||||||
|
JUMP
|
||||||
|
pack_small_rlp:
|
||||||
|
// stack: result_ptr, result_len, retdest
|
||||||
|
PANIC // TODO: Return packed RLP
|
||||||
|
|
||||||
|
// RLP encode the given trie node, and return an (pointer, length) pair
|
||||||
|
// indicating where the data lives within @SEGMENT_RLP_RAW.
|
||||||
|
//
|
||||||
|
// Pre stack: node_ptr, encode_value, retdest
|
||||||
|
// Post stack: result_ptr, result_len
|
||||||
|
global encode_node:
|
||||||
|
// stack: node_ptr, encode_value, retdest
|
||||||
|
DUP1 %mload_trie_data
|
||||||
|
// stack: node_type, node_ptr, encode_value, retdest
|
||||||
|
// Increment node_ptr, so it points to the node payload instead of its type.
|
||||||
|
SWAP1 %add_const(1) SWAP1
|
||||||
|
// stack: node_type, node_payload_ptr, encode_value, retdest
|
||||||
|
|
||||||
|
DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(encode_node_empty)
|
||||||
|
DUP1 %eq_const(@MPT_NODE_HASH) %jumpi(encode_node_hash)
|
||||||
|
DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(encode_node_branch)
|
||||||
|
DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(encode_node_extension)
|
||||||
|
DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(encode_node_leaf)
|
||||||
|
PANIC // Invalid node type? Shouldn't get here.
|
||||||
|
|
||||||
|
global encode_node_empty:
|
||||||
|
// stack: node_type, node_payload_ptr, encode_value, retdest
|
||||||
|
%pop3
|
||||||
|
// stack: retdest
|
||||||
|
// An empty node is encoded as a single byte, 0x80, which is the RLP
|
||||||
|
// encoding of the empty string. Write this byte to RLP[0] and return
|
||||||
|
// (0, 1).
|
||||||
|
PUSH 0x80
|
||||||
|
PUSH 0
|
||||||
|
%mstore_rlp
|
||||||
|
%stack (retdest) -> (retdest, 0, 1)
|
||||||
JUMP
|
JUMP
|
||||||
|
|
||||||
global mpt_hash_hash:
|
global encode_node_hash:
|
||||||
// stack: node_type, node_payload_ptr, retdest
|
// stack: node_type, node_payload_ptr, encode_value, retdest
|
||||||
POP
|
POP
|
||||||
// stack: node_payload_ptr, retdest
|
// stack: node_payload_ptr, encode_value, retdest
|
||||||
%mload_trie_data
|
%mload_trie_data
|
||||||
// stack: hash, retdest
|
%stack (hash, encode_value, retdest) -> (retdest, hash, 32)
|
||||||
SWAP1
|
JUMP
|
||||||
|
|
||||||
|
encode_node_branch:
|
||||||
|
// stack: node_type, node_payload_ptr, encode_value, retdest
|
||||||
|
POP
|
||||||
|
// stack: node_payload_ptr, encode_value, retdest
|
||||||
|
PUSH 9 // rlp_pos; we start at 9 to leave room to prepend a list prefix
|
||||||
|
%rep 16
|
||||||
|
// stack: rlp_pos, node_child_ptr, encode_value, retdest
|
||||||
|
// TODO: Append encode_or_hash_node(child) to our RLP. Do all encode_or_hash_node calls first to avoid clobbering.
|
||||||
|
SWAP1 %increment SWAP1 // node_child_ptr += 1
|
||||||
|
%endrep
|
||||||
|
// stack: node_value_ptr, encode_value, retdest
|
||||||
|
PANIC // TODO
|
||||||
|
|
||||||
|
encode_node_extension:
|
||||||
|
// stack: node_type, node_payload_ptr, encode_value, retdest
|
||||||
|
POP
|
||||||
|
// stack: node_payload_ptr, encode_value, retdest
|
||||||
|
PANIC // TODO
|
||||||
|
|
||||||
|
encode_node_leaf:
|
||||||
|
// stack: node_type, node_payload_ptr, encode_value, retdest
|
||||||
|
POP
|
||||||
|
// stack: node_payload_ptr, encode_value, retdest
|
||||||
|
PUSH encode_node_leaf_after_hex_prefix // retdest
|
||||||
|
PUSH 1 // terminated
|
||||||
|
// stack: terminated, encode_node_leaf_after_hex_prefix, node_payload_ptr, encode_value, retdest
|
||||||
|
DUP3 %add_const(1) %mload_trie_data // Load the packed_nibbles field, which is at index 1.
|
||||||
|
// stack: packed_nibbles, terminated, encode_node_leaf_after_hex_prefix, node_payload_ptr, encode_value, retdest
|
||||||
|
DUP4 %mload_trie_data // Load the num_nibbles field, which is at index 0.
|
||||||
|
// stack: num_nibbles, packed_nibbles, terminated, encode_node_leaf_after_hex_prefix, node_payload_ptr, encode_value, retdest
|
||||||
|
PUSH 9 // We start at 9 to leave room to prepend the largest possible RLP list header.
|
||||||
|
// stack: rlp_start, num_nibbles, packed_nibbles, terminated, encode_node_leaf_after_hex_prefix, node_payload_ptr, encode_value, retdest
|
||||||
|
%jump(hex_prefix_rlp)
|
||||||
|
encode_node_leaf_after_hex_prefix:
|
||||||
|
// stack: rlp_pos, node_payload_ptr, encode_value, retdest
|
||||||
|
SWAP1
|
||||||
|
%add_const(2) // The value starts at index 2.
|
||||||
|
// stack: value_ptr, rlp_pos, encode_value, retdest
|
||||||
|
%stack (value_ptr, rlp_pos, encode_value, retdest)
|
||||||
|
-> (encode_value, rlp_pos, value_ptr, encode_node_leaf_after_encode_value, retdest)
|
||||||
|
JUMP
|
||||||
|
encode_node_leaf_after_encode_value:
|
||||||
|
// stack: rlp_end_pos, retdest
|
||||||
|
%prepend_rlp_list_prefix
|
||||||
|
%stack (rlp_start_pos, rlp_len, retdest) -> (retdest, rlp_start_pos, rlp_len)
|
||||||
JUMP
|
JUMP
|
||||||
|
|||||||
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
global mpt_hash_state_trie:
|
global mpt_hash_state_trie:
|
||||||
// stack: retdest
|
// stack: retdest
|
||||||
|
PUSH encode_account
|
||||||
%mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT)
|
%mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT)
|
||||||
// stack: node_ptr, retdest
|
// stack: node_ptr, encode_account, retdest
|
||||||
%mpt_hash(encode_account)
|
%jump(mpt_hash)
|
||||||
|
|
||||||
%macro mpt_hash_state_trie
|
%macro mpt_hash_state_trie
|
||||||
PUSH %%after
|
PUSH %%after
|
||||||
@ -14,9 +15,10 @@ global mpt_hash_state_trie:
|
|||||||
|
|
||||||
global mpt_hash_txn_trie:
|
global mpt_hash_txn_trie:
|
||||||
// stack: retdest
|
// stack: retdest
|
||||||
|
PUSH encode_txn
|
||||||
%mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT)
|
%mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT)
|
||||||
// stack: node_ptr, retdest
|
// stack: node_ptr, encode_txn, retdest
|
||||||
%mpt_hash(encode_txn)
|
%jump(mpt_hash)
|
||||||
|
|
||||||
%macro mpt_hash_txn_trie
|
%macro mpt_hash_txn_trie
|
||||||
PUSH %%after
|
PUSH %%after
|
||||||
@ -26,9 +28,10 @@ global mpt_hash_txn_trie:
|
|||||||
|
|
||||||
global mpt_hash_receipt_trie:
|
global mpt_hash_receipt_trie:
|
||||||
// stack: retdest
|
// stack: retdest
|
||||||
|
PUSH encode_receipt
|
||||||
%mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_ROOT)
|
%mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_ROOT)
|
||||||
// stack: node_ptr, retdest
|
// stack: node_ptr, encode_receipt, retdest
|
||||||
%mpt_hash(encode_receipt)
|
%jump(mpt_hash)
|
||||||
|
|
||||||
%macro mpt_hash_receipt_trie
|
%macro mpt_hash_receipt_trie
|
||||||
PUSH %%after
|
PUSH %%after
|
||||||
|
|||||||
@ -159,6 +159,7 @@ load_mpt_digest:
|
|||||||
|
|
||||||
// Load a leaf from prover input, and append it to trie data.
|
// Load a leaf from prover input, and append it to trie data.
|
||||||
%macro load_leaf_value
|
%macro load_leaf_value
|
||||||
|
// TODO: Need to store leaf len, or at least a has_leaf flag for branch nodes.
|
||||||
// stack: (empty)
|
// stack: (empty)
|
||||||
PROVER_INPUT(mpt)
|
PROVER_INPUT(mpt)
|
||||||
// stack: leaf_len
|
// stack: leaf_len
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user