Skip to content

Commit

Permalink
Cherry pick what's left of Linked lists for the state trie (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nashtare committed Aug 6, 2024
1 parent fd0f7d5 commit 4a39a37
Show file tree
Hide file tree
Showing 15 changed files with 203 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -386,4 +386,4 @@ global remove_accessed_storage_keys:
// stack: next_next_ptr, next_ptr_ptr, addr, key, retdest
MSTORE_GENERAL
%pop2
JUMP
JUMP
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ revert_account_destroyed_contd:
// stack: address, prev_balance, retdest
%read_accounts_linked_list
// stack: account_payload_ptr, prev_balance, retdest
DUP1 %assert_nonzero
DUP1
%assert_nonzero
%increment
// stack: account_balance_payload_ptr, prev_balance, retdest
%mstore_trie_data
JUMP

Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ global revert_nonce_change:
%mstore_trie_data
// stack: retdest
JUMP

9 changes: 2 additions & 7 deletions evm_arithmetization/src/cpu/kernel/asm/main.asm
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,12 @@ global main:
// Encode constant nodes
%initialize_rlp_segment

// Initialize linked list and trie data constants.
// TODO: Validate them.
PROVER_INPUT(linked_list::accounts_linked_list_len)
%mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN)
PROVER_INPUT(linked_list::storage_linked_list_len)
%mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN)
// Initialize trie data size.
PROVER_INPUT(trie_ptr::trie_data_size)
%mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE)

global store_initial:
// Store the inital accounts and slots for hashing later
// Store the initial accounts and slots for hashing later
%store_initial_accounts
%store_initial_slots
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ global delete_account:
%jump(delete_account)
%%after:
// stack: (empty)
%endmacro
%endmacro
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,3 @@ global encode_storage_value:
// stack: rlp_addr', cur_len, retdest
%stack (rlp_addr, cur_len, retdest) -> (retdest, rlp_addr, cur_len)
JUMP

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ after_insert_slot:
%jump(insert_all_slots)

// Delete all the accounts, referenced by the respective nodes in the linked list starting at
// `account_ptr_ptr`, which where deleted from the intial state. Delete also all slots of non-deleted accounts
// `account_ptr_ptr`, which where deleted from the initial state. Delete also all slots of non-deleted accounts
// deleted from the storage trie.
// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest
// Post stack: new_root_ptr.
Expand All @@ -100,7 +100,7 @@ global delete_removed_accounts:
// We assume that the size of the initial accounts linked list, containing the accounts
// of the initial state, was stored at `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`.
%mload_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN)
// The inital accounts linked list was stored at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`.
// The initial accounts linked list was stored at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`.
// If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it
// suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`
EQ
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// to mem[payload_ptr_ptr] + step*i,
// for i =0..n_leaves. This is used to constraint the
// initial state and account tries payload pointers such that they are exactly
// those of the inital accounts and linked lists.
// those of the initial accounts and linked lists.
// Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
// Post stack: account_ptr_ptr, storage_ptr_ptr
global mpt_set_payload:
Expand All @@ -17,6 +17,8 @@ global mpt_set_payload:
DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_branch)
DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension)
DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf)
DUP1 %eq_const(@MPT_NODE_HASH) %jumpi(skip)
PANIC

skip:
// stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest
Expand Down Expand Up @@ -46,7 +48,7 @@ skip:
%mstore_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN)
%endmacro

// Pre stack: node_ptr, account_ptr_ptr, retdest
// Pre stack: node_ptr, storage_ptr_ptr, retdest
// Post stack: storage_ptr_ptr
global mpt_set_storage_payload:
// stack: node_ptr, storage_ptr_ptr, retdest
Expand Down Expand Up @@ -116,34 +118,33 @@ set_payload_storage_branch:
JUMP

set_payload_extension:
// stack: node_type, after_node_type, storage_ptr_ptr, retdest
// stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest
POP
// stack: after_node_type, storage_ptr_ptr, retdest
// stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest
%add_const(2) %mload_trie_data
// stack: child_ptr, after_node_type, storage_ptr_ptr, retdest
// stack: child_ptr, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest
%jump(mpt_set_payload)

set_payload_storage_extension:
// stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest
// stack: node_type, after_node_type, storage_ptr_ptr, retdest
POP
// stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest
// stack: after_node_type, storage_ptr_ptr, retdest
%add_const(2) %mload_trie_data
// stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
// stack: child_ptr, storage_ptr_ptr, retdest
%jump(mpt_set_storage_payload)

set_payload_leaf:
// stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest
POP
%add_const(2) // The payload pointer starts at index 3, after num_nibbles and packed_nibbles.
DUP1
// stack payload_ptr_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
// stack: payload_ptr_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
%mload_trie_data
// stack account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
// stack: account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
%add_const(2)
%mload_trie_data // storage_root_ptr = account[2]

DUP1 %mload_trie_data
POP
// stack storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
// stack: storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest
%stack
(storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) ->
(storage_root_ptr, storage_ptr_ptr, after_set_storage_payload, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr)
Expand All @@ -165,7 +166,7 @@ after_set_storage_payload:
%mstore_trie_data // The dynamic account pointer in the linked list has no storage root so we need to manually set it.
%mstore_trie_data // Set the leaf payload pointing to next account in the linked list.
// stack: account_ptr_ptr, storage_ptr_ptr', retdest
%add_const(@STORAGE_NEXT_NODE_PTR) // The next pointer is at distance `STORAGE_NEXT_NODE_PTR`
%add_const(@ACCOUNTS_LINKED_LISTS_NODE_SIZE) // The next pointer is at distance `ACCOUNTS_LINKED_LISTS_NODE_SIZE`
// stack: payload_ptr_ptr', storage_ptr_ptr', retdest
SWAP1
SWAP2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
/// The values at the respective positions are:
/// - 0: The account key
/// - 1: A ptr to the payload (the account values)
/// - 2: A ptr to the intial payload.
/// - 2: A ptr to the initial payload.
/// - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list.
/// Similarly, an empty storage linked list is written as
/// [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST.
Expand All @@ -34,51 +34,64 @@
%%after:
%endmacro

/// Iterates over the inital account linked list and shallow copies
/// Iterates over the initial account linked list and shallow copies
/// the accounts, storing a pointer to the copied account in the node.
/// Computes the length of `SEGMENT_ACCOUNTS_LINKED_LIST` and
/// stores it in `GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE`.
global store_initial_accounts:
// stack: retdest
PUSH @SEGMENT_ACCOUNTS_LINKED_LIST
PUSH @ACCOUNTS_LINKED_LISTS_NODE_SIZE
PUSH @SEGMENT_ACCOUNTS_LINKED_LIST
ADD
// stack: cur_len, retdest
PUSH @SEGMENT_ACCOUNTS_LINKED_LIST
%next_account
loop_store_initial_accounts:
// stack: current_node_ptr
// stack: current_node_ptr, cur_len, retdest
%get_trie_data_size
DUP2
MLOAD_GENERAL
// stack: current_addr_key, cpy_ptr, current_node_ptr, retdest
// stack: current_addr_key, cpy_ptr, current_node_ptr, cur_len, retdest
%eq_const(@U256_MAX)
%jumpi(store_initial_accounts_end)
DUP2
%increment
MLOAD_GENERAL
// stack: nonce_ptr, cpy_ptr, current_node_ptr, retdest
// stack: nonce_ptr, cpy_ptr, current_node_ptr, cur_len, retdest
DUP1
%mload_trie_data // nonce
%append_to_trie_data
%increment
// stack: balance_ptr, cpy_ptr, current_node_ptr, retdest
// stack: balance_ptr, cpy_ptr, current_node_ptr, cur_len, retdest
DUP1
%mload_trie_data // balance
%append_to_trie_data
%increment // The storage_root_ptr is not really necessary
// stack: storage_root_ptr_ptr, cpy_ptr, current_node_ptr, retdest
// stack: storage_root_ptr_ptr, cpy_ptr, current_node_ptr, cur_len, retdest
DUP1
%mload_trie_data // storage_root_ptr
%append_to_trie_data
%increment
// stack: code_hash_ptr, cpy_ptr, current_node_ptr, retdest
// stack: code_hash_ptr, cpy_ptr, current_node_ptr, cur_len, retdest
%mload_trie_data // code_hash
%append_to_trie_data
// stack: cpy_ptr, current_node_ptr, retdest
// stack: cpy_ptr, current_node_ptr, cur_len, retdest
DUP2
%add_const(2)
SWAP1
MSTORE_GENERAL // Store cpy_ptr
// stack: current_node_ptr, cur_len, retdest
SWAP1 PUSH @ACCOUNTS_LINKED_LISTS_NODE_SIZE
ADD
SWAP1
// stack: current_node_ptr, cur_len', retdest
%next_account
%jump(loop_store_initial_accounts)

store_initial_accounts_end:
%pop2
// stack: cur_len, retdest
%mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE)
JUMP

%macro insert_account_with_overwrite
Expand All @@ -88,7 +101,7 @@ store_initial_accounts_end:
%endmacro

// Multiplies the value at the top of the stack, denoted by ptr/4, by 4
// and aborts if ptr/4 <= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN]/4.
// and aborts if ptr/4 <= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE]/4.
// Also checks that ptr >= @SEGMENT_ACCOUNTS_LINKED_LIST.
// This way, 4*ptr/4 must be pointing to the beginning of a node.
// TODO: Maybe we should check here if the node has been deleted.
Expand All @@ -103,7 +116,7 @@ store_initial_accounts_end:
// stack: ptr/4
DUP1
PUSH 4
%mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN)
%mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE)
// By construction, both @SEGMENT_ACCOUNTS_LINKED_LIST and the unscaled list len
// must be multiples of 4
DIV
Expand Down Expand Up @@ -159,7 +172,7 @@ insert_new_account:
// get the value of the next address
%add_const(@ACCOUNTS_NEXT_NODE_PTR)
// stack: next_ptr_ptr, addr_key, payload_ptr, retdest
%mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN)
%mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE)
DUP2
MLOAD_GENERAL
// stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, payload_ptr, retdest
Expand Down Expand Up @@ -201,14 +214,14 @@ insert_new_account:
MSTORE_GENERAL
// stack: new_next_ptr, addr_key, payload_ptr, retdest
%increment
%mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN)
%mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE)
// stack: addr_key, payload_ptr, retdest
%pop2
JUMP


/// Searches the account addr in the linked list.
/// Returns `payload_ptr` if the account was not found, `original_ptr` if it was already present.
/// Returns 0 if the account was not found or `original_ptr` if it was already present.
global search_account:
// stack: addr_key, retdest
PROVER_INPUT(linked_list::insert_account)
Expand Down Expand Up @@ -307,11 +320,17 @@ global remove_account:
%endmacro


/// Iterates over the inital account linked list and shallow copies
/// Iterates over the initial account linked list and shallow copies
/// the accounts, storing a pointer to the copied account in the node.
/// Computes the length of `SEGMENT_STORAGE_LINKED_LIST` and
/// checks against `GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE`.
global store_initial_slots:
// stack: retdest
PUSH @SEGMENT_STORAGE_LINKED_LIST
PUSH @STORAGE_LINKED_LISTS_NODE_SIZE
PUSH @SEGMENT_STORAGE_LINKED_LIST
ADD
// stack: cur_len, retdest
PUSH @SEGMENT_STORAGE_LINKED_LIST
%next_slot

loop_store_initial_slots:
Expand Down Expand Up @@ -357,7 +376,7 @@ store_initial_slots_end:
%endmacro

// Multiplies the value at the top of the stack, denoted by ptr/5, by 5
// and aborts if ptr/5 >= (mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN] - @SEGMENT_STORAGE_LINKED_LIST)/5.
// and aborts if ptr/5 >= (mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE] - @SEGMENT_STORAGE_LINKED_LIST)/5.
// This way, @SEGMENT_STORAGE_LINKED_LIST + 5*ptr/5 must be pointing to the beginning of a node.
// TODO: Maybe we should check here if the node has been deleted.
%macro get_valid_slot_ptr
Expand All @@ -366,7 +385,7 @@ store_initial_slots_end:
PUSH 5
PUSH @SEGMENT_STORAGE_LINKED_LIST
// stack: segment, 5, ptr/5, ptr/5
%mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN)
%mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE)
SUB
// stack: accessed_strg_keys_len, 5, ptr/5, ptr/5
// By construction, the unscaled list len must be multiple of 5
Expand Down Expand Up @@ -430,7 +449,7 @@ insert_new_slot_with_value:
// get the value of the next address
%add_const(@STORAGE_NEXT_NODE_PTR)
// stack: next_ptr_ptr, addr_key, key, value, retdest
%mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN)
%mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE)
DUP2
MLOAD_GENERAL
// stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest
Expand Down Expand Up @@ -518,15 +537,14 @@ slot_found_write_value:
%stack (slot_key, addr_key, value) -> (addr_key, slot_key, value, %%after)
%jump(insert_slot_with_value)
%%after:
// stack: (empty)
%endmacro

%macro insert_slot_with_value_from_keys
// stack: addr_key, slot_key, value
%stack (addr_key, slot_key, value) -> (addr_key, slot_key, value, %%after)
%jump(insert_slot_with_value)
%%after:
// stack: value_ptr
POP
// stack: (empty)
%endmacro

Expand Down Expand Up @@ -598,7 +616,7 @@ insert_new_slot:
// get the value of the next address
%add_const(@STORAGE_NEXT_NODE_PTR)
// stack: next_ptr_ptr, addr_key, key, payload_ptr, retdest
%mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN)
%mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE)
DUP2
MLOAD_GENERAL
// stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest
Expand Down Expand Up @@ -669,7 +687,7 @@ next_node_ok:
MSTORE_GENERAL
// stack: new_next_ptr, addr_key, key, payload_ptr, retdest
%increment
%mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN)
%mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE)
// stack: addr_key, key, payload_ptr, retdest
%stack (addr_key, key, payload_ptr, retdest) -> (retdest, payload_ptr)
JUMP
Expand Down Expand Up @@ -737,6 +755,13 @@ slot_found_no_write:
%stack (orig_value, addr_key, key, payload_ptr, retdest) -> (retdest, orig_value)
JUMP

%macro search_slot
// stack: state_key, storage_key, ptr
%stack (state_key, storage_key, ptr) -> (state_key, storage_key, ptr, %%after)
%jump(search_slot)
%%after:
// stack: ptr
%endmacro

%macro remove_slot
%stack (key, addr_key) -> (addr_key, key, %%after)
Expand Down Expand Up @@ -864,14 +889,6 @@ remove_all_slots_end:
// stack: slot_ptr
%endmacro

%macro search_slot
// stack: state_key, storage_key, ptr
%stack (state_key, storage_key, ptr) -> (state_key, storage_key, ptr, %%after)
%jump(search_slot)
%%after:
// stack: ptr
%endmacro

%macro first_account
// stack: empty
PUSH @SEGMENT_ACCOUNTS_LINKED_LIST
Expand Down
Loading

0 comments on commit 4a39a37

Please sign in to comment.