mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
Merge pull request #1190 from topos-protocol/mpt-remove-cow
Remove copy on write for mpt_insert and mpt_delete
This commit is contained in:
commit
f6f9fa3197
@ -3,7 +3,6 @@
|
||||
//
|
||||
// Pre stack: node_ptr, num_nibbles, key, retdest
|
||||
// Post stack: updated_node_ptr
|
||||
// TODO: Optimize this by removing the copy-on-write logic.
|
||||
global mpt_delete:
|
||||
// stack: node_ptr, num_nibbles, key, retdest
|
||||
DUP1 %mload_trie_data
|
||||
|
||||
@ -27,37 +27,16 @@ after_mpt_delete_branch:
|
||||
// If the updated child is empty, check if we need to normalize the branch node.
|
||||
DUP1 %mload_trie_data ISZERO %jumpi(maybe_normalize_branch)
|
||||
|
||||
// Make a copy of the branch node and set `branch[first_nibble] = updated_child_ptr`.
|
||||
// Set `branch[first_nibble] = updated_child_ptr`.
|
||||
update_branch:
|
||||
// stack: updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
%get_trie_data_size
|
||||
// stack: updated_branch_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
PUSH @MPT_NODE_BRANCH %append_to_trie_data
|
||||
// stack: updated_branch_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP4 %mload_trie_data %append_to_trie_data // Copy child[0]
|
||||
DUP4 %add_const(1) %mload_trie_data %append_to_trie_data // ...
|
||||
DUP4 %add_const(2) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(3) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(4) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(5) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(6) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(7) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(8) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(9) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(10) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(11) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(12) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(13) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(14) %mload_trie_data %append_to_trie_data
|
||||
DUP4 %add_const(15) %mload_trie_data %append_to_trie_data // Copy child[15]
|
||||
DUP4 %add_const(16) %mload_trie_data %append_to_trie_data // Copy value_ptr
|
||||
// stack: updated_branch_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
SWAP1
|
||||
// stack: updated_child_ptr, updated_branch_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP2 %increment DUP4 ADD
|
||||
// stack: updated_branch_ptr+first_nibble+1, updated_child_ptr, updated_branch_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP3 DUP3 ADD
|
||||
// stack: node_payload_ptr+first_nibble, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
%mstore_trie_data
|
||||
%stack (updated_branch_ptr, first_nibble, node_payload_ptr, retdest) -> (retdest, updated_branch_ptr)
|
||||
%stack (first_nibble, node_payload_ptr, retdest) -> (node_payload_ptr, 1, retdest)
|
||||
SUB
|
||||
// stack: node_ptr, retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
// The updated child is empty. Count how many non-empty children the branch node has.
|
||||
@ -121,31 +100,24 @@ maybe_normalize_branch_branch:
|
||||
|
||||
// The only child of the branch node is a leaf/extension node.
|
||||
// Transform the branch node into an leaf/extension node of length 1+len(child).
|
||||
// For that, return the modified child as the new node.
|
||||
maybe_normalize_branch_leafext:
|
||||
// stack: only_child_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP1 %mload_trie_data
|
||||
// stack: child_type, only_child_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP2 %increment %mload_trie_data
|
||||
// stack: child_len, child_type, only_child_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP3 %add_const(2) %mload_trie_data
|
||||
// stack: child_key, child_len, child_type, only_child_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
SWAP3 %add_const(3) %mload_trie_data
|
||||
// stack: child_value_ptr, child_len, child_type, child_key, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP1 %increment %mload_trie_data
|
||||
// stack: child_len, only_child_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
DUP2 %add_const(2) %mload_trie_data
|
||||
// stack: child_key, child_len, only_child_ptr, updated_child_ptr, first_nibble, node_payload_ptr, retdest
|
||||
%mload_kernel_general(1)
|
||||
%stack (i, child_value_ptr, child_len, child_type, child_key, updated_child_ptr, first_nibble, node_payload_ptr) ->
|
||||
(1, i, child_len, child_key, child_type, child_value_ptr)
|
||||
%stack (i, child_key, child_len, only_child_ptr, updated_child_ptr, first_nibble, node_payload_ptr) ->
|
||||
(1, i, child_len, child_key, only_child_ptr)
|
||||
%merge_nibbles
|
||||
// stack: len, key, child_type, value_ptr, retdest
|
||||
%get_trie_data_size // pointer to the leaf/extension node we're about to create
|
||||
// stack: node_ptr, len, key, child_type, value_ptr, retdest
|
||||
SWAP3
|
||||
// stack: child_type, len, key, node_ptr, value_ptr, retdest
|
||||
%append_to_trie_data // Append type to our node
|
||||
// stack: len, key, node_ptr, value_ptr, retdest
|
||||
%append_to_trie_data // Append len to our node
|
||||
// stack: key, node_ptr, value_ptr, retdest
|
||||
%append_to_trie_data // Append key to our node
|
||||
// stack: node_ptr, value_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append value_ptr to our node
|
||||
// stack: len, key, only_child_ptr,retdest
|
||||
DUP3
|
||||
// stack: node_ptr, len, key, only_child_ptr, retdest
|
||||
SWAP1 DUP2
|
||||
// stack: node_ptr, len, node_ptr, key, only_child_ptr, retdest
|
||||
%increment %mstore_trie_data // Change len in the child node
|
||||
// stack: node_ptr, key, only_child_ptr, retdest
|
||||
%add_const(2) %mstore_trie_data // Change key in the child node
|
||||
// stack: node_ptr, retdest
|
||||
SWAP1 JUMP
|
||||
|
||||
@ -18,15 +18,15 @@ global mpt_delete_extension:
|
||||
// stack: num_nibbles, key, node_payload_ptr, node_len, node_key, retdest
|
||||
SWAP2
|
||||
// stack: node_payload_ptr, key, num_nibbles, node_len, node_key, retdest
|
||||
%add_const(2) %mload_trie_data
|
||||
%stack (node_child_ptr, key, num_nibbles, node_len, node_key, retdest) ->
|
||||
(node_child_ptr, num_nibbles, key, after_mpt_delete_extension, node_len, node_key, retdest)
|
||||
DUP1 %add_const(2) %mload_trie_data
|
||||
%stack (node_child_ptr, node_payload_ptr, key, num_nibbles, node_len, node_key, retdest) ->
|
||||
(node_child_ptr, num_nibbles, key, after_mpt_delete_extension, node_payload_ptr, node_len, node_key, retdest)
|
||||
%jump(mpt_delete)
|
||||
|
||||
after_mpt_delete_extension:
|
||||
// stack: updated_child_node_ptr, node_len, node_key, retdest
|
||||
// stack: updated_child_node_ptr, node_payload_ptr, node_len, node_key, retdest
|
||||
DUP1 %mload_trie_data
|
||||
// stack: child_type, updated_child_node_ptr, node_len, node_key, retdest
|
||||
// stack: child_type, updated_child_node_ptr, node_payload_ptr, node_len, node_key, retdest
|
||||
DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(after_mpt_delete_extension_branch)
|
||||
DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(after_mpt_delete_extension_extension)
|
||||
DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(after_mpt_delete_extension_leaf)
|
||||
@ -34,66 +34,54 @@ after_mpt_delete_extension:
|
||||
PANIC
|
||||
|
||||
after_mpt_delete_extension_branch:
|
||||
// stack: child_type, updated_child_node_ptr, node_len, node_key, retdest
|
||||
// stack: child_type, updated_child_node_ptr, node_payload_ptr, node_len, node_key, retdest
|
||||
POP
|
||||
// stack: updated_child_node_ptr, node_len, node_key, retdest
|
||||
%get_trie_data_size // pointer to the extension node we're about to create
|
||||
// stack: updated_child_node_ptr, node_payload_ptr, node_len, node_key, retdest
|
||||
SWAP1
|
||||
// stack: extension_ptr, updated_child_node_ptr, node_len, node_key, retdest
|
||||
PUSH @MPT_NODE_EXTENSION %append_to_trie_data
|
||||
PUSH @MPT_NODE_EXTENSION DUP2 %mstore_trie_data
|
||||
// stack: extension_ptr, updated_child_node_ptr, node_len, node_key, retdest
|
||||
SWAP2 %append_to_trie_data // Append node_len to our node
|
||||
// stack: updated_child_node_ptr, extension_ptr, node_key, retdest
|
||||
SWAP2 %append_to_trie_data // Append node_key to our node
|
||||
// stack: extension_ptr, updated_child_node_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append updated_child_node_ptr to our node
|
||||
DUP3 DUP2 %mstore_trie_data // Append node_len to our node
|
||||
// stack: extension_ptr, updated_child_node_ptr, node_len, node_key, retdest
|
||||
DUP4 DUP2 %mstore_trie_data // Append node_key to our node
|
||||
// stack: extension_ptr, updated_child_node_ptr, node_len, node_key, retdest
|
||||
SWAP1 DUP2 %mstore_trie_data // Append updated_child_node_ptr to our node
|
||||
// stack: extension_ptr, node_len, node_key, retdest
|
||||
%stack (extension_ptr, node_len, node_key, retdest) -> (retdest, extension_ptr)
|
||||
// stack: extension_ptr, retdest
|
||||
SWAP1 JUMP
|
||||
JUMP
|
||||
|
||||
after_mpt_delete_extension_extension:
|
||||
// stack: child_type, updated_child_node_ptr, node_len, node_key, retdest
|
||||
POP
|
||||
// stack: child_type, updated_child_node_ptr, node_payload_ptr, node_len, node_key, retdest
|
||||
POP SWAP1 POP
|
||||
// stack: updated_child_node_ptr, node_len, node_key, retdest
|
||||
DUP1 %increment %mload_trie_data
|
||||
// stack: child_len, updated_child_node_ptr, node_len, node_key, retdest
|
||||
DUP2 %add_const(2) %mload_trie_data
|
||||
// stack: child_key, child_len, updated_child_node_ptr, node_len, node_key, retdest
|
||||
SWAP2 %add_const(3) %mload_trie_data
|
||||
%stack (grandchild_ptr, child_len, child_key, node_len, node_key) -> (node_len, node_key, child_len, child_key, grandchild_ptr)
|
||||
%stack (child_key, child_len, updated_child_node_ptr, node_len, node_key) -> (node_len, node_key, child_len, child_key, updated_child_node_ptr)
|
||||
%merge_nibbles
|
||||
// stack: len, key, grandchild_ptr, retdest
|
||||
%get_trie_data_size // pointer to the extension node we're about to create
|
||||
// stack: extension_ptr, len, key, grandchild_ptr, retdest
|
||||
PUSH @MPT_NODE_EXTENSION %append_to_trie_data
|
||||
// stack: extension_ptr, len, key, grandchild_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append len to our node
|
||||
// stack: extension_ptr, key, grandchild_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append key to our node
|
||||
// stack: extension_ptr, grandchild_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append grandchild_ptr to our node
|
||||
// stack: len, key, updated_child_node_ptr, retdest
|
||||
DUP3 %increment %mstore_trie_data // Change len
|
||||
// stack: key, updated_child_node_ptr, retdest
|
||||
DUP2 %add_const(2) %mstore_trie_data // Change key
|
||||
// stack: extension_ptr, retdest
|
||||
SWAP1 JUMP
|
||||
|
||||
// Essentially the same as `after_mpt_delete_extension_extension`. TODO: Could merge in a macro or common function.
|
||||
after_mpt_delete_extension_leaf:
|
||||
// stack: child_type, updated_child_node_ptr, node_len, node_key, retdest
|
||||
POP
|
||||
// stack: child_type, updated_child_node_ptr, node_payload_ptr, node_len, node_key, retdest
|
||||
POP SWAP1 POP
|
||||
// stack: updated_child_node_ptr, node_len, node_key, retdest
|
||||
DUP1 %increment %mload_trie_data
|
||||
// stack: child_len, updated_child_node_ptr, node_len, node_key, retdest
|
||||
DUP2 %add_const(2) %mload_trie_data
|
||||
// stack: child_key, child_len, updated_child_node_ptr, node_len, node_key, retdest
|
||||
SWAP2 %add_const(3) %mload_trie_data
|
||||
%stack (value_ptr, child_len, child_key, node_len, node_key) -> (node_len, node_key, child_len, child_key, value_ptr)
|
||||
%stack (child_key, child_len, updated_child_node_ptr, node_len, node_key) -> (node_len, node_key, child_len, child_key, updated_child_node_ptr)
|
||||
%merge_nibbles
|
||||
// stack: len, key, value_ptr, retdest
|
||||
%get_trie_data_size // pointer to the leaf node we're about to create
|
||||
// stack: leaf_ptr, len, key, value_ptr, retdest
|
||||
PUSH @MPT_NODE_LEAF %append_to_trie_data
|
||||
// stack: leaf_ptr, len, key, value_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append len to our node
|
||||
// stack: leaf_ptr, key, value_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append key to our node
|
||||
// stack: leaf_ptr, value_ptr, retdest
|
||||
SWAP1 %append_to_trie_data // Append value_ptr to our node
|
||||
// stack: leaf_ptr, retdest
|
||||
// stack: len, key, updated_child_node_ptr, retdest
|
||||
DUP3 %increment %mstore_trie_data // Change len
|
||||
// stack: key, updated_child_node_ptr, retdest
|
||||
DUP2 %add_const(2) %mstore_trie_data // Change key
|
||||
// stack: updated_child_node_ptr, retdest
|
||||
SWAP1 JUMP
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
//
|
||||
// Pre stack: node_ptr, num_nibbles, key, value_ptr, retdest
|
||||
// Post stack: updated_node_ptr
|
||||
// TODO: Optimize this by removing the copy-on-write logic.
|
||||
global mpt_insert:
|
||||
// stack: node_ptr, num_nibbles, key, value_ptr, retdest
|
||||
DUP1 %mload_trie_data
|
||||
@ -41,59 +40,40 @@ mpt_insert_empty:
|
||||
|
||||
mpt_insert_branch:
|
||||
// stack: node_type, node_payload_ptr, num_nibbles, key, value_ptr, retdest
|
||||
%get_trie_data_size
|
||||
// stack: updated_branch_ptr, node_type, node_payload_ptr, num_nibbles, key, value_ptr, retdest
|
||||
SWAP1
|
||||
%append_to_trie_data
|
||||
// stack: updated_branch_ptr, node_payload_ptr, num_nibbles, key, value_ptr, retdest
|
||||
SWAP1
|
||||
// stack: node_payload_ptr, updated_branch_ptr, num_nibbles, key, value_ptr, retdest
|
||||
POP
|
||||
|
||||
// Copy the original node's data to our updated node.
|
||||
DUP1 %mload_trie_data %append_to_trie_data // Copy child[0]
|
||||
DUP1 %add_const(1) %mload_trie_data %append_to_trie_data // ...
|
||||
DUP1 %add_const(2) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(3) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(4) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(5) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(6) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(7) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(8) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(9) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(10) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(11) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(12) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(13) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(14) %mload_trie_data %append_to_trie_data
|
||||
DUP1 %add_const(15) %mload_trie_data %append_to_trie_data // Copy child[15]
|
||||
%add_const(16) %mload_trie_data %append_to_trie_data // Copy value_ptr
|
||||
//stack: node_payload_ptr, num_nibbles, key, value_ptr, retdest
|
||||
|
||||
// At this point, we branch based on whether the key terminates with this branch node.
|
||||
// stack: updated_branch_ptr, num_nibbles, key, value_ptr, retdest
|
||||
// stack: node_payload_ptr, num_nibbles, key, value_ptr, retdest
|
||||
DUP2 %jumpi(mpt_insert_branch_nonterminal)
|
||||
|
||||
// The key terminates here, so the value will be placed right in our (updated) branch node.
|
||||
// stack: updated_branch_ptr, num_nibbles, key, value_ptr, retdest
|
||||
// stack: node_payload_ptr, num_nibbles, key, value_ptr, retdest
|
||||
SWAP3
|
||||
// stack: value_ptr, num_nibbles, key, updated_branch_ptr, retdest
|
||||
DUP4 %add_const(17)
|
||||
// stack: updated_branch_value_ptr_ptr, value_ptr, num_nibbles, key, updated_branch_ptr, retdest
|
||||
// stack: value_ptr, num_nibbles, key, node_payload_ptr, retdest
|
||||
DUP4 %add_const(16)
|
||||
// stack: branch_value_ptr_ptr, value_ptr, num_nibbles, key, node_payload_ptr, retdest
|
||||
%mstore_trie_data
|
||||
// stack: num_nibbles, key, updated_branch_ptr, retdest
|
||||
// stack: num_nibbles, key, node_payload_ptr, retdest
|
||||
%pop2
|
||||
// stack: updated_branch_ptr, retdest
|
||||
// stack: node_payload_ptr, retdest
|
||||
PUSH 1 SWAP1 SUB
|
||||
// stack: branch_ptr, retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
mpt_insert_branch_nonterminal:
|
||||
// The key continues, so we split off the first (most significant) nibble,
|
||||
// and recursively insert into the child associated with that nibble.
|
||||
// stack: updated_branch_ptr, num_nibbles, key, value_ptr, retdest
|
||||
%stack (updated_branch_ptr, num_nibbles, key) -> (num_nibbles, key, updated_branch_ptr)
|
||||
// stack: node_payload_ptr, num_nibbles, key, value_ptr, retdest
|
||||
%stack (node_payload_ptr, num_nibbles, key) -> (num_nibbles, key, node_payload_ptr)
|
||||
%split_first_nibble
|
||||
// stack: first_nibble, num_nibbles, key, updated_branch_ptr, value_ptr, retdest
|
||||
DUP4 %increment ADD
|
||||
// stack: child_ptr_ptr, num_nibbles, key, updated_branch_ptr, value_ptr, retdest
|
||||
// stack: first_nibble, num_nibbles, key, node_payload_ptr, value_ptr, retdest
|
||||
DUP4 ADD
|
||||
// stack: child_ptr_ptr, num_nibbles, key, node_payload_ptr, value_ptr, retdest
|
||||
// Replace node_payload_ptr with branch pointer
|
||||
SWAP3 PUSH 1 SWAP1 SUB SWAP3
|
||||
%stack (child_ptr_ptr, num_nibbles, key, updated_branch_ptr, value_ptr)
|
||||
-> (child_ptr_ptr, num_nibbles, key, value_ptr,
|
||||
mpt_insert_branch_nonterminal_after_recursion,
|
||||
|
||||
@ -177,17 +177,16 @@ insert_key_continues:
|
||||
%jump(maybe_add_extension_for_common_key)
|
||||
|
||||
keys_match:
|
||||
// The keys match exactly, so we simply create a new leaf node with the new value.xs
|
||||
// The keys match exactly, so we simply replace the leaf value with the new value.
|
||||
// stack: node_len, node_key, insert_len, insert_key, node_payload_ptr, insert_value_ptr, retdest
|
||||
%stack (node_len, node_key, insert_len, insert_key, node_payload_ptr, insert_value_ptr)
|
||||
-> (node_len, node_key, insert_value_ptr)
|
||||
// stack: common_len, common_key, insert_value_ptr, retdest
|
||||
%get_trie_data_size // pointer to the leaf node we're about to create
|
||||
// stack: updated_leaf_ptr, common_len, common_key, insert_value_ptr, retdest
|
||||
PUSH @MPT_NODE_LEAF %append_to_trie_data
|
||||
SWAP1 %append_to_trie_data // Append common_len to our leaf node
|
||||
SWAP1 %append_to_trie_data // Append common_key to our leaf node
|
||||
SWAP1 %append_to_trie_data // Append insert_value_ptr to our leaf node
|
||||
// stack: updated_leaf_ptr, retdestx
|
||||
-> (node_payload_ptr, node_len, node_key, insert_value_ptr)
|
||||
// stack: node_payload_ptr, common_len, common_key, insert_value_ptr, retdest
|
||||
DUP4 DUP2
|
||||
%add_const(2)
|
||||
%mstore_trie_data
|
||||
%stack (node_payload_ptr, common_len, common_key, insert_value_ptr, retdest) -> (node_payload_ptr, retdest)
|
||||
PUSH 1 SWAP1 SUB
|
||||
// stack: leaf_ptr, retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user