diff --git a/evm_arithmetization/src/cpu/kernel/aggregator.rs b/evm_arithmetization/src/cpu/kernel/aggregator.rs index d24e856fa..9ba350242 100644 --- a/evm_arithmetization/src/cpu/kernel/aggregator.rs +++ b/evm_arithmetization/src/cpu/kernel/aggregator.rs @@ -140,8 +140,8 @@ pub static KERNEL_FILES: [&str; NUMBER_KERNEL_FILES] = [ include_str!("asm/mpt/insert/insert_leaf.asm"), include_str!("asm/mpt/insert/insert_trie_specific.asm"), include_str!("asm/mpt/linked_list/linked_list.asm"), - include_str!("asm/mpt/linked_list/initial_tries.asm"), include_str!("asm/mpt/linked_list/final_tries.asm"), + include_str!("asm/mpt/linked_list/initial_tries.asm"), include_str!("asm/mpt/read.asm"), include_str!("asm/mpt/storage/storage_read.asm"), include_str!("asm/mpt/storage/storage_write.asm"), diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 6f20938af..e72c20ee6 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -215,14 +215,16 @@ global check_state_trie: // `GLOBAL_METADATA_TRIE_DATA_SIZE` is correct. %get_trie_data_size // stack: trie_data_len - PROVER_INPUT(trie_ptr::state) + PROVER_INPUT(trie_ptr::initial_state) %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) PROVER_INPUT(trie_ptr::trie_data_size) %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) - %set_initial_tries + // stack: trie_data_len + %set_initial_state_trie + // stack: trie_data_len PUSH @INITIAL_RLP_ADDR // stack: rlp_start, trie_data_len @@ -233,7 +235,7 @@ global check_state_trie: %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) %assert_eq // Check that the stored trie data length is correct. - %mload_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) + %mload_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) %assert_eq // We set a dummy value as an initial trie data length, diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm index 82b14865c..37f9fc670 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -29,12 +29,12 @@ mpt_hash_hash_if_rlp: mpt_hash_hash_rlp: // stack: result, result_len, new_len, retdest %stack (result, result_len, new_len) - -> (@SEGMENT_RLP_RAW, result, result_len, mpt_hash_hash_rlp_after_unpacking, result_len, new_len) + -> (@INITIAL_RLP_ADDR, result, result_len, mpt_hash_hash_rlp_after_unpacking, result_len, new_len) // stack: addr, result, result_len, mpt_hash_hash_rlp_after_unpacking, result_len, new_len %jump(mstore_unpacking) mpt_hash_hash_rlp_after_unpacking: // stack: result_addr, result_len, new_len, retdest - POP PUSH @SEGMENT_RLP_RAW // ctx == virt == 0 + POP PUSH @INITIAL_RLP_ADDR // ctx == 0, virt == 1 // stack: result_addr, result_len, new_len, retdest KECCAK_GENERAL // stack: hash, new_len, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 9db07083d..53093f4f4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -209,21 +209,17 @@ after_mpt_delete_slot: global set_final_tries: PUSH set_final_tries_after - PUSH @SEGMENT_STORAGE_LINKED_LIST - %add_const(@STORAGE_LINKED_LISTS_NODE_SIZE) // Skip the first node. + %first_initial_slot // Skip the first node. %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - %add_const(@ACCOUNTS_LINKED_LISTS_NODE_SIZE) // Skip the first node. + %first_initial_account // Skip the first node. %jump(delete_removed_accounts) set_final_tries_after: // stack: new_state_root PUSH set_final_tries_after_after SWAP1 // stack: new_state_root, set_final_tries_after_after - PUSH @SEGMENT_STORAGE_LINKED_LIST - %next_slot + %first_slot SWAP1 - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - %next_account + %first_account %jump(insert_all_accounts) set_final_tries_after_after: //stack: new_state_root diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index 12d463b58..df4762a51 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -1,306 +1,129 @@ -// Set the payload pointers of the leaves in the trie with root at `node_ptr` -// 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 initial accounts and linked lists. -// Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest -// Post stack: account_ptr_ptr, storage_ptr_ptr -global mpt_set_payload: - // stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - DUP1 %mload_trie_data - // stack: node_type, node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - // Increment node_ptr, so it points to the node payload instead of its type. - SWAP1 %increment SWAP1 - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(skip) - 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: - // The following 2-lines block is the inlined version of - // %stack (node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest) -> - // (retdest, account_ptr_ptr, storage_ptr_ptr) - POP POP SWAP3 POP - SWAP3 SWAP1 POP - - JUMP - -%macro mpt_set_payload - %stack (node_ptr, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles) -> - (node_ptr, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, %%after) - %jump(mpt_set_payload) -%%after: -%endmacro - -%macro set_initial_tries - PUSH %%after - PUSH 0 // empty nibbles - PUSH 0 // num nibbles - PUSH @SEGMENT_STORAGE_LINKED_LIST - %add_const(8) // The first node is the special node, of size 5, so the first value is at position 5 + 3. - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - %add_const(6) // The first node is the special node, of size 4, so the first payload is at position 4 + 2. +global set_initial_state_trie: + // stack: retdest + PUSH set_initial_state_trie_after + %first_initial_slot // Skip the first node. %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - %jump(mpt_set_payload) -%%after: - // We store account_ptr_ptr - 2, i.e. a pointer to the first node not in the initial state. - %sub_const(2) - %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) - // We store storage_ptr_ptr - 3, i.e. a pointer to the first node not in the initial state. - %sub_const(3) - %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) -%endmacro - -// Pre stack: node_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest -// Post stack: storage_ptr_ptr -global mpt_set_storage_payload: - // stack: node_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - DUP1 %mload_trie_data - // stack: node_type, node_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - // Increment node_ptr, so it points to the node payload instead of its type. - SWAP1 %increment SWAP1 - // stack: node_type, after_node_type, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - - DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(storage_skip) - DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_storage_branch) - DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_storage_extension) - DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_storage_leaf) - -storage_skip: - // stack: node_type, after_node_type, storage_ptr_ptr, num_nibbles, packedـnibbles, retdest - %stack (node_type, after_node_type, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest) -> (retdest, storage_ptr_ptr) + %first_initial_account // Skip the first node. + %jump(insert_all_initial_accounts) +set_initial_state_trie_after: + //stack: new_state_root + %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) JUMP -%macro mpt_set_storage_payload - %stack(node_ptr, storage_ptr_ptr, num_nibbles, nibbles) -> (node_ptr, storage_ptr_ptr, num_nibbles, nibbles, %%after) - %jump(mpt_set_storage_payload) +%macro set_initial_state_trie + // stack: (empty) + PUSH %%after + %jump(set_initial_state_trie) %%after: %endmacro -set_payload_branch: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - POP - - PUSH 0 // child counter - // Call mpt_set_payload on each child - %rep 16 - // The following 4-lines block is the inlined version of - // %stack (i, child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles) -> - // (num_nibbles, packed_nibbles, 1, i, child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, i, num_nibbles, packed_nibbles, child_ptr_ptr) - SWAP2 DUP2 DUP4 - PUSH 1 - DUP9 DUP9 SWAP8 - SWAP6 SWAP10 SWAP9 - - // We do not check the stored nibbles here, as the current value is not written yet. - %merge_nibbles - // stack: num_merged_nibbles, merged_nibbles, child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, i, num_nibbles, packed_nibbles, child_ptr_ptr - - // The following line is the inlined version of - // %stack (num_merged_nibbles, merged_nibbles, child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> - // (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, num_merged_nibbles, merged_nibbles) - SWAP3 SWAP1 SWAP4 SWAP2 - - // stack: child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, num_merged_nibbles, merged_nibbles, i, num_nibbles, packed_nibbles, child_ptr_ptr, retdest - %mload_trie_data - // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, num_merged_nibbles, merged_nibbles, i, num_nibbles, packed_nibbles, child_ptr_ptr, retdest - %mpt_set_payload - // stack: account_ptr_ptr', storage_ptr_ptr', i, num_nibbles, packed_nibbles, child_ptr_ptr, retdest - - // The following line is the inlined version of - // %stack (account_ptr_ptr_p, storage_ptr_ptr_p, i, num_nibbles, packed_nibbles, child_ptr_ptr) -> - // (child_ptr_ptr, i, account_ptr_ptr_p, storage_ptr_ptr_p, num_nibbles, packed_nibbles) - SWAP2 SWAP1 SWAP3 SWAP4 SWAP5 - - // stack: (child_ptr_ptr, i, account_ptr_ptr_p, storage_ptr_ptr_p, num_nibbles, packed_nibbles, retdest) - %increment - SWAP1 - %increment - %endrep - // stack: i, child_ptr_ptr', account_ptr_ptr', storage_ptr_ptr', num_nibbles, packed_nibbles, retdest - POP - %stack (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest) -> - (retdest, account_ptr_ptr, storage_ptr_ptr) - JUMP - -set_payload_storage_branch: - // stack: node_type, child_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - POP - - // Child counter - PUSH 0 - // Call mpt_set_storage_payload on each child - %rep 16 - // The following 3-lines block is the inlined version of - // %stack (i, child_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles) -> - // (num_nibbles, packed_nibbles, 1, i, child_ptr_ptr, storage_ptr_ptr, i, num_nibbles, packed_nibbles, child_ptr_ptr) - SWAP1 SWAP4 SWAP3 - SWAP2 DUP5 DUP3 - PUSH 1 DUP7 DUP7 - - %merge_nibbles - // stack: num_merged_nibbles, merged_nibbles, child_ptr_ptr, storage_ptr_ptr, i, num_nibbles, packed_nibbles, child_ptr_ptr, retdest - %stack (num_merged_nibbles, merged_nibbles, child_ptr_ptr, storage_ptr_ptr) -> - (child_ptr_ptr, storage_ptr_ptr, num_merged_nibbles, merged_nibbles) - %mload_trie_data - // stack: child_ptr, storage_ptr_ptr, num_merged_nibbles, merged_nibbles, i, num_nibbles, packed_nibbles, child_ptr_ptr, retdest - %mpt_set_storage_payload - // stack: storage_ptr_ptr', i, num_nibbles, packed_nibbles, child_ptr_ptr, retdest - %stack (storage_ptr_ptr_p, i, num_nibbles, packed_nibbles, child_ptr_ptr) -> - (child_ptr_ptr, i, storage_ptr_ptr_p, num_nibbles, packed_nibbles) - %increment - SWAP1 - %increment - %endrep - // stack: i, child_ptr_ptr', storage_ptr_ptr', num_nibbles, packed_nibbles, retdest - %stack (i, child_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest) -> (retdest, storage_ptr_ptr) - JUMP - -set_payload_extension: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - POP - // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - DUP1 %mload_trie_data // num_nibbles - DUP2 %increment %mload_trie_data // nibbles - SWAP2 - %add_const(2) %mload_trie_data - // stack: child_ptr, loaded_num_nibbles, loaded_nibbles, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - - // The following 2-lines block is the inlined version of - // %stack (child_ptr, loaded_num_nibbles, loaded_nibbles, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles) -> - // (num_nibbles, packed_nibbles, loaded_num_nibbles, loaded_nibbles, child_ptr, account_ptr_ptr, storage_ptr_ptr) - SWAP4 SWAP6 SWAP1 - SWAP2 SWAP3 SWAP5 - - %merge_nibbles - // stack: merged_num_nibbles, merged_nibbles, child_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %stack (merged_num_nibbles, merged_nibbles, child_ptr, account_ptr_ptr, storage_ptr_ptr) -> - (child_ptr, account_ptr_ptr, storage_ptr_ptr, merged_num_nibbles, merged_nibbles) - %jump(mpt_set_payload) - -set_payload_storage_extension: - // stack: node_type, after_node_type, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - POP - // stack: after_node_type, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - DUP1 %mload_trie_data // num_nibbles - DUP2 %increment %mload_trie_data // nibbles +// Given a pointer `root_ptr` to the root of a trie, insert all the initial accounts in +// the accounts_linked_list starting at `account_ptr_ptr` as well as the +// respective initial storage slots in `storage_ptr_ptr`. +// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest +// Post stack: new_root_ptr. // The value of new_root_ptr shouldn't change +global insert_all_initial_accounts: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest SWAP2 - // stack: after_node_type, loaded_num_nibbles, loaded_packed_nibbles, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - %add_const(2) %mload_trie_data - // stack: child_ptr, loaded_num_nibbles, loaded_packed_nibbles, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - - // The following 2-lines block is the inlined version of - // %stack (child_ptr, loaded_num_nibbles, loaded_packed_nibbles, storage_ptr_ptr, num_nibbles, packed_nibbles) -> - // (num_nibbles, packed_nibbles, loaded_num_nibbles, loaded_packed_nibbles, child_ptr, storage_ptr_ptr) - SWAP1 SWAP2 SWAP3 - SWAP5 SWAP1 SWAP4 - - %merge_nibbles - %stack (merged_num_nibbles, merged_nibbles, child_ptr, storage_ptr_ptr) -> - (child_ptr, storage_ptr_ptr, merged_num_nibbles, merged_nibbles) - %jump(mpt_set_storage_payload) - -set_payload_leaf: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - POP - DUP1 %increment %mload_trie_data - DUP2 %mload_trie_data - - // The following 2-lines block is the inlined version of - // %stack (loaded_num_nibbles, loaded_packed_nibbles, after_node_type, account_ptr_ptr, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest) -> - // (num_nibbles, packed_nibbles, loaded_num_nibbles, loaded_packed_nibbles, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) - SWAP2 SWAP4 SWAP6 - SWAP1 SWAP3 SWAP5 - - %merge_nibbles - // stack: merged_len, merged_nibbles, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - PUSH 64 %assert_eq - DUP3 %sub_const(2) MLOAD_GENERAL - // stack: addr_key, merged_nibbles, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - %assert_eq - // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - %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 - %mload_trie_data - // stack: account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %add_const(2) - %mload_trie_data // storage_root_ptr = account[2] - - // stack: storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - - // The following 4-lines block is the inlined version of - // %stack (storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> - // (storage_root_ptr, storage_ptr_ptr, 0, 0, after_set_storage_payload, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) - PUSH 0 PUSH 0 - DUP3 SWAP4 SWAP5 SWAP6 - PUSH after_set_storage_payload - SWAP4 - - %jump(mpt_set_storage_payload) -after_set_storage_payload: - // stack: storage_ptr_ptr', storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, retdest + DUP3 + MLOAD_GENERAL + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest DUP4 - MLOAD_GENERAL // load the next payload pointer in the linked list - DUP1 %add_const(2) // new_storage_root_ptr_ptr = payload_ptr[2] - // stack: new_storage_root_ptr_ptr, new_payload_ptr, storage_root_ptr, storage_ptr_ptr', payload_ptr_ptr, account_ptr_ptr, retdest - // Load also the old "dynamic" payload for storing the storage_root_ptr - DUP6 %decrement + %mload_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) + EQ + %jumpi(no_more_accounts) + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + PUSH after_mpt_read + DUP2 + PUSH 64 + DUP6 + // stack: root_ptr, nibbles, key, after_mpt_read, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %jump(mpt_read) +after_mpt_read: + //stack: trie_account_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + DUP1 + %mload_trie_data + %add_const(2) + %mload_trie_data + // stack: trie_storage_root, trie_account_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + SWAP1 + // stack: trie_account_ptr_ptr, trie_storage_root, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + DUP6 + %add_const(2) // intial account_ptr = account_ptr_ptr + 2 MLOAD_GENERAL - %add_const(2) // dyn_storage_root_ptr_ptr = dyn_paylod_ptr[2] + // stack: account_ptr, trie_account_ptr_ptr, trie_storage_root, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + DUP1 SWAP2 + // stack: trie_account_ptr_ptr, account_ptr, account_ptr, trie_storage_root, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %mstore_trie_data // The trie's account points to the linked list initial account + // stack: account_ptr, trie_storage_root, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %add_const(2) + // stack: storage_root_ptr_ptr, trie_storage_root, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest - // The following 3-lines block is the inlined version of - // %stack (dyn_storage_root_ptr_ptr, new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> - // (new_storage_root_ptr_ptr, storage_root_ptr, dyn_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) - DUP5 - SWAP3 SWAP5 SWAP1 SWAP4 - SWAP7 SWAP6 SWAP4 SWAP2 + %stack + (storage_root_ptr_ptr, trie_storage_root, key, storage_ptr_ptr) -> + (key, storage_ptr_ptr, trie_storage_root, after_insert_all_initial_slots, storage_root_ptr_ptr) + %jump(insert_all_initial_slots) - %mstore_trie_data // The initial account pointer in the linked list has no storage root so we need to manually set it. - %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(@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 +after_insert_all_initial_slots: + // stack: storage_ptr_ptr', trie_storage_root_ptr', storage_root_ptr_ptr, root_ptr, account_ptr_ptr, retdest SWAP2 + %mstore_trie_data + // stack: storage_ptr_ptr', root_ptr, account_ptr_ptr, retdest + SWAP2 + %next_initial_account + // stack: account_ptr_ptr', root_ptr, storage_ptr_ptr', retdest + %jump(insert_all_initial_accounts) + +no_more_accounts: + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %stack (key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest) ->(retdest, root_ptr) JUMP -set_payload_storage_leaf: - // stack: node_type, after_node_type, storage_ptr_ptr, num_nibbles, packed_nibbles, retdest - POP - DUP1 %increment %mload_trie_data - DUP2 %mload_trie_data - %stack (loaded_num_nibbles, loaded_nibbles, after_node_type, storage_ptr_ptr, num_nibbles, packed_nibbles) -> - (num_nibbles, packed_nibbles, loaded_num_nibbles, loaded_nibbles, after_node_type, storage_ptr_ptr) - %merge_nibbles - // stack: merged_num_nibbles, merged_nibbles, after_node_type, storage_ptr_ptr, retdest - PUSH 64 %assert_eq - // stack: merged_nibbles, after_node_type, storage_ptr_ptr, retdest - DUP3 %sub_const(2) MLOAD_GENERAL - // stack: slot_key, merged_nibbles, after_node_type, storage_ptr_ptr, retdest - %assert_eq - // stack: after_node_type, storage_ptr_ptr, retdest - %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. - // stack: value_ptr_ptr, storage_ptr_ptr, retdest - DUP2 MLOAD_GENERAL - // stack: value, value_ptr_ptr, storage_ptr_ptr, retdest - // If value == 0, then value_ptr = 0, and we don't need to append the value to the `TrieData` segment. - DUP1 ISZERO %jumpi(set_payload_storage_leaf_end) - %get_trie_data_size - // stack: value_ptr, value, value_ptr_ptr, storage_ptr_ptr, retdest - SWAP1 - %append_to_trie_data -set_payload_storage_leaf_end: - // stack: value_ptr, value_ptr_ptr, storage_ptr_ptr, retdest +// Insert all slots before the account key changes +// Pre stack: addr, storage_ptr_ptr, root_ptr, retdest +// Post stack: storage_ptr_ptr', root_ptr' +global insert_all_initial_slots: + DUP2 + MLOAD_GENERAL + DUP2 + EQ // Check that the node address is the same as `addr` + DUP3 + %mload_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) + SUB + MUL + %jumpi(insert_next_slot) + // The addr has changed, meaning that we've inserted all slots for addr, + // or we reached the end of the initial storage linked list. + // stack: addr, storage_ptr_ptr, root_ptr, retdest + %stack (addr, storage_ptr_ptr, root_ptr, retdest) -> (retdest, storage_ptr_ptr, root_ptr) + JUMP +insert_next_slot: + // stack: addr, storage_ptr_ptr, root_ptr, retdest + DUP2 + %increment + MLOAD_GENERAL + // stack: key, addr, storage_ptr_ptr, root_ptr, retdest + DUP3 + %add_const(3) // inital value is at position 3 + MLOAD_GENERAL + // stack: value, key, addr, storage_ptr_ptr, root_ptr, retdest + // If the value is 0, then payload_ptr = 0, and we don't need to insert a value in the `TrieData` segment. + DUP1 ISZERO %jumpi(insert_with_payload_ptr) + %get_trie_data_size // payload_ptr SWAP1 + %append_to_trie_data // append the value to the trie data segment +insert_with_payload_ptr: + %stack + (payload_ptr, key, addr, storage_ptr_ptr, root_ptr) -> + (root_ptr, 64, key, after_insert_slot, payload_ptr, storage_ptr_ptr, addr, root_ptr) + %jump(mpt_read) +after_insert_slot: + // stack: slot_ptr_ptr, payload_ptr, storage_ptr_ptr, addr, root_ptr, retdest %mstore_trie_data - // stack: storage_ptr_ptr, retdest - %add_const(@STORAGE_LINKED_LISTS_NODE_SIZE) // The next pointer is at distance `STORAGE_LINKED_LISTS_NODE_SIZE` - // stack: storage_ptr_ptr', retdest + // stack: storage_ptr_ptr, addr, root_ptr, retdest + %next_initial_slot + // stack: storage_ptr_ptr', addr, root_ptr, retdest SWAP1 - JUMP + %jump(insert_all_initial_slots) + diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 39e4604d3..650d69db2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -38,6 +38,11 @@ /// 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`. +/// It also checks that the next node address is current address + 4 +/// and that all keys are strictly increasing. +/// NOTE: It may be more efficient to check that the next node addres != U256_MAX +/// (i.e. node was not deleted) and ensure that no node with repeated key +/// is ever read. global store_initial_accounts: // stack: retdest PUSH @ACCOUNTS_LINKED_LISTS_NODE_SIZE @@ -45,15 +50,24 @@ global store_initial_accounts: ADD // stack: cur_len, retdest PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + // stack: current_node_ptr, cur_len, retdest + DUP1 + MLOAD_GENERAL + // stack: current_addr_key, current_node_ptr, cur_len', retdest + %assert_eq_const(@U256_MAX) + DUP1 %next_account + // stack: next_node_ptr, current_node_ptr, cur_len', retdest + DUP1 + SWAP2 + %next_initial_account + %assert_eq(store_initial_accounts_end) // next_node_ptr == current_node_ptr + node_size + // stack: next_node_ptr, cur_len', retdest + loop_store_initial_accounts: // stack: current_node_ptr, cur_len, retdest %get_trie_data_size - DUP2 - MLOAD_GENERAL - // stack: current_addr_key, cpy_ptr, current_node_ptr, cur_len, retdest - %eq_const(@U256_MAX) - %jumpi(store_initial_accounts_end) + // stack: cpy_ptr, current_node_ptr, cur_len, retdest DUP2 %increment MLOAD_GENERAL @@ -84,13 +98,35 @@ loop_store_initial_accounts: SWAP1 PUSH @ACCOUNTS_LINKED_LISTS_NODE_SIZE ADD SWAP1 - // stack: current_node_ptr, cur_len', retdest + // Check next node ptr validity and strict keys monotonicity + DUP1 + MLOAD_GENERAL + // stack: current_addr_key, current_node_ptr, cur_len', retdest + SWAP1 + DUP1 %next_account + // stack: next_node_ptr, current_node_ptr, current_addr_key, cur_len', retdest + DUP1 + SWAP2 + %next_initial_account + %assert_eq(store_initial_accounts_end_pop_key) // next_node_ptr == current_node_ptr + node_size + // stack: next_node_ptr, current_addr_key, cur_len', retdest + SWAP1 + DUP2 + MLOAD_GENERAL + %assert_gt // next_addr_key > current_addr_key + // stack: next_node_ptr, cur_len', retdest %jump(loop_store_initial_accounts) +store_initial_accounts_end_pop_key: + // stack: next_node_ptr, current_addr_key, cur_len', retdest + SWAP1 POP store_initial_accounts_end: - %pop2 + // stack: next_node_ptr, cur_len', retdest + %assert_eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) // stack: cur_len, retdest + DUP1 + %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE) JUMP @@ -324,6 +360,11 @@ global remove_account: /// 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`. +/// It also checks that the next node address is current address + 5 +/// and that all keys are strictly increasing. +/// NOTE: It may be more efficient to check that the next node addres != U256_MAX +/// (i.e. node was not deleted) and ensure that no node with repeated key +/// is ever read. global store_initial_slots: // stack: retdest PUSH @STORAGE_LINKED_LISTS_NODE_SIZE @@ -331,15 +372,23 @@ global store_initial_slots: ADD // stack: cur_len, retdest PUSH @SEGMENT_STORAGE_LINKED_LIST - %next_slot - -loop_store_initial_slots: - // stack: current_node_ptr, cur_len, retdest DUP1 MLOAD_GENERAL // stack: current_addr_key, current_node_ptr, cur_len, retdest - %eq_const(@U256_MAX) - %jumpi(store_initial_slots_end) + %assert_eq_const(@U256_MAX) + + // stack: current_node_ptr, cur_len', retdest + DUP1 + %next_slot + // stack: next_node_ptr, current_node_ptr, cur_len, retdest + DUP1 + SWAP2 + %next_initial_slot + %assert_eq(store_initial_slots_end) // next_node_ptr == current_node_ptr + node_size + // stack: next_node_ptr, cur_len', retdest + +loop_store_initial_slots: + // stack: current_node_ptr, cur_len, retdest DUP1 %add_const(2) MLOAD_GENERAL @@ -353,13 +402,65 @@ loop_store_initial_slots: SWAP1 PUSH @STORAGE_LINKED_LISTS_NODE_SIZE ADD SWAP1 - // stack: current_node_ptr, cur_len', retdest + // Check correctness of next node ptr and strict key monotonicity. + DUP1 + MLOAD_GENERAL + // stack: current_addr_key, current_node_ptr, cur_len', retdest + SWAP1 + DUP1 + %increment + MLOAD_GENERAL + // stack: current_slot_key, current_node_ptr, current_addr_key, cur_len', retdest + SWAP1 + DUP1 %next_slot + // stack: next_node_ptr, current_node_ptr, current_slot_key, current_addr_key, cur_len', retdest + DUP1 + SWAP2 + %next_initial_slot + %assert_eq(store_initial_slots_end_pop_keys) // next_node_ptr == current_node_ptr + node_size + // stack: next_node_ptr, current_slot_key, current_addr_key, cur_len', retdest + DUP1 + DUP1 + %increment + MLOAD_GENERAL + // stack: next_node_slot_key, next_node_ptr, next_node_ptr, current_slot_key, current_addr_key, cur_len', retdest + SWAP1 + MLOAD_GENERAL + // stack: next_node_addr_key, next_node_slot_key, next_node_ptr, current_slot_key, current_addr_key, cur_len', retdest + SWAP3 + LT + // stack: current_slot_key > next_node_slot_key, next_node_ptr, next_node_addr_key, current_addr_key, cur_len', retdest + SWAP2 + SWAP1 + SWAP3 + // stack: current_addr_key, next_node_addr_key, current_slot_key > next_node_slot_key, next_node_ptr, cur_len', retdest + DUP2 + DUP2 + EQ + // stack: current_addr_key == next_node_addr_key, current_addr_key, next_node_addr_key, current_slot_key > next_node_slot_key, next_node_ptr, cur_len', retdest + SWAP1 + SWAP3 + MUL // AND + // stack current_slot_key > next_node_slot_key AND current_addr_key == next_node_addr_key, next_node_addr_key, current_addr_key, next_node_ptr, cur_len', retdest + SWAP2 + LT + ADD // OR + %assert_nonzero %jump(loop_store_initial_slots) +store_initial_slots_end_pop_keys: + // stack: next_node_ptr, current_slot_key, current_addr_key, cur_len', retdest + SWAP2 + %pop2 + store_initial_slots_end: - POP + // stack: next_node_ptr, cur_len', retdest + %assert_eq_const(@SEGMENT_STORAGE_LINKED_LIST) + // stack: cur_len, retdest + DUP1 + %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE) JUMP @@ -894,6 +995,12 @@ remove_all_slots_end: %next_account %endmacro +%macro first_initial_account + // stack: empty + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + %next_initial_account +%endmacro + %macro next_account // stack: node_ptr %add_const(@ACCOUNTS_NEXT_NODE_PTR) @@ -901,15 +1008,49 @@ remove_all_slots_end: // stack: next_node_ptr %endmacro +%macro next_initial_account + // stack: node_ptr + %add_const(@ACCOUNTS_LINKED_LISTS_NODE_SIZE) + // stack: next_node_ptr +%endmacro + %macro first_slot // stack: empty PUSH @SEGMENT_STORAGE_LINKED_LIST %next_slot %endmacro +%macro first_initial_slot + // stack: empty + PUSH @SEGMENT_STORAGE_LINKED_LIST + %next_initial_slot +%endmacro + %macro next_slot // stack: node_ptr %add_const(@STORAGE_NEXT_NODE_PTR) MLOAD_GENERAL // stack: next_node_ptr %endmacro + +%macro next_initial_slot + // stack: node_ptr + %add_const(@STORAGE_LINKED_LISTS_NODE_SIZE) + // stack: next_node_ptr +%endmacro + +%macro next_hash_node + // stack: hash_node_ptr + %add_const(4) + // stack: next_hash_node_ptr +%endmacro + +// Skip over the the first three words (number of nibbles and keys) +// and load the hash from memory. +%macro get_hash + // stack: hash_node_ptr + %add_const(3) + // stack: next_ptr + MLOAD_GENERAL + // stack: hash +%endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 148a7897d..303377c04 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -24,7 +24,8 @@ global mpt_read_state_trie: // - the key, as a U256 // - return destination // -// This function returns a pointer to the value, or 0 if the key is not found. +// This function returns a pointer to the value, or 0 if the key is not found. If the key +// is a leaf, it returns a pointer to a pointer. global mpt_read: // stack: node_ptr, num_nibbles, key, retdest DUP1 @@ -145,7 +146,6 @@ global mpt_read_leaf_found: // stack: node_payload_ptr, retdest %add_const(2) // The value pointer is located after num_nibbles and the key. // stack: value_ptr_ptr, retdest - %mload_trie_data - // stack: value_ptr, retdest SWAP1 + // For leaves, we return the pointer JUMP diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index ff4dba48e..b290b8403 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -197,36 +197,30 @@ pub(crate) fn prepare_interpreter( interpreter.stack() ); - // Set initial tries. + // Now, set the payload. interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push(0.into()) // Initial nibbles - .expect("The stack should not overflow"); - interpreter - .push(0.into()) // Initial number of nibbles - .expect("The stack should not overflow"); - interpreter - .push((Segment::StorageLinkedList as usize + 8).into()) - .expect("The stack should not overflow"); - interpreter - .push((Segment::AccountsLinkedList as usize + 6).into()) + .push((Segment::StorageLinkedList as usize + 5).into()) .expect("The stack should not overflow"); interpreter .push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)) + .unwrap(); + interpreter + .push((Segment::AccountsLinkedList as usize + 4).into()) .expect("The stack should not overflow"); // Now, set the payload. interpreter.generation_state.registers.program_counter = - KERNEL.global_labels["mpt_set_payload"]; + KERNEL.global_labels["insert_all_initial_accounts"]; interpreter.run()?; - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; - interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); - interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + assert_eq!(interpreter.stack_len(), 1); + + let state_root = interpreter.pop().expect("The stack should not be empty"); + interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_root); // Now, execute `mpt_hash_state_trie`. state_trie.insert(k, rlp::encode(account).to_vec())?; @@ -417,43 +411,30 @@ fn prepare_interpreter_all_accounts( KERNEL.global_labels["store_initial_slots"]; interpreter.run()?; - // Set the pointers to the initial payloads. + // Now, set the payload. interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push(0.into()) // Initial nibbles - .expect("The stack should not overflow"); - interpreter - .push(0.into()) // Initial number of nibbles - .expect("The stack should not overflow"); - interpreter - .push((Segment::StorageLinkedList as usize + 8).into()) - .expect("The stack should not overflow"); - interpreter - .push((Segment::AccountsLinkedList as usize + 6).into()) + .push((Segment::StorageLinkedList as usize + 5).into()) .expect("The stack should not overflow"); interpreter .push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)) + .unwrap(); + interpreter + .push((Segment::AccountsLinkedList as usize + 4).into()) .expect("The stack should not overflow"); - // Now, set the payloads in the state trie leaves. + // Now, set the payload. interpreter.generation_state.registers.program_counter = - KERNEL.global_labels["mpt_set_payload"]; + KERNEL.global_labels["insert_all_initial_accounts"]; interpreter.run()?; - assert_eq!( - interpreter.stack().len(), - 2, - "Expected 2 items on stack after setting the initial trie payloads, found {:?}", - interpreter.stack() - ); + assert_eq!(interpreter.stack_len(), 1); - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; - interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); - interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + let state_root = interpreter.pop().expect("The stack should not be empty"); + interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_root); // Switch context and initialize memory with the data we need for the tests. interpreter.generation_state.registers.program_counter = 0; diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs index ca3de5163..72edba94f 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs @@ -121,33 +121,25 @@ fn test_state_trie( .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push(0.into()) // Initial nibbles - .expect("The stack should not overflow"); - interpreter - .push(0.into()) // Initial number of nibbles - .expect("The stack should not overflow"); - interpreter - .push((Segment::StorageLinkedList as usize + 8).into()) - .expect("The stack should not overflow"); - interpreter - .push((Segment::AccountsLinkedList as usize + 6).into()) + .push((Segment::StorageLinkedList as usize + 5).into()) .expect("The stack should not overflow"); interpreter .push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)) .unwrap(); + interpreter + .push((Segment::AccountsLinkedList as usize + 4).into()) + .expect("The stack should not overflow"); // Now, set the payload. interpreter.generation_state.registers.program_counter = - KERNEL.global_labels["mpt_set_payload"]; + KERNEL.global_labels["insert_all_initial_accounts"]; interpreter.run()?; - assert_eq!(interpreter.stack_len(), 2); + assert_eq!(interpreter.stack_len(), 1); - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; - interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); - interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + let state_root = interpreter.pop().expect("The stack should not be empty"); + interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_root); // Next, execute mpt_insert_state_trie. interpreter.generation_state.registers.program_counter = mpt_insert_state_trie; diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs index ccf576a4f..7428044d1 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs @@ -190,36 +190,29 @@ fn test_state_trie( interpreter.generation_state.registers.program_counter = KERNEL.global_labels["store_initial"]; interpreter.run()?; - // Set initial tries. interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push(0.into()) // Initial nibbles - .expect("The stack should not overflow"); - interpreter - .push(0.into()) // Initial number of nibbles - .expect("The stack should not overflow"); - interpreter - .push((Segment::StorageLinkedList as usize + 8).into()) - .expect("The stack should not overflow"); - interpreter - .push((Segment::AccountsLinkedList as usize + 6).into()) + .push((Segment::StorageLinkedList as usize + 5).into()) .expect("The stack should not overflow"); interpreter .push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)) .unwrap(); + interpreter + .push((Segment::AccountsLinkedList as usize + 4).into()) + .expect("The stack should not overflow"); // Now, set the payload. interpreter.generation_state.registers.program_counter = - KERNEL.global_labels["mpt_set_payload"]; + KERNEL.global_labels["insert_all_initial_accounts"]; interpreter.run()?; - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; - interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); - interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + assert_eq!(interpreter.stack_len(), 1); + + let state_root = interpreter.pop().expect("The stack should not be empty"); + interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_root); // Next, execute mpt_insert_state_trie. interpreter.generation_state.registers.program_counter = mpt_insert_state_trie; @@ -267,10 +260,6 @@ fn test_state_trie( ); interpreter.generation_state.registers.program_counter = check_state_trie; - interpreter - .halt_offsets - .push(KERNEL.global_labels["check_txn_trie"]); - interpreter .push(interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)) // Initial trie data segment size, unused. .expect("The stack should not overflow"); diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs index 571b45c38..8390c6a59 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs @@ -42,7 +42,9 @@ fn mpt_read() -> Result<()> { interpreter.run()?; assert_eq!(interpreter.stack().len(), 1); - let result_ptr = interpreter.stack()[0].as_usize(); + // mpt_read returns a pointer to the accounts pointer + let result_ptr_ptr = interpreter.stack()[0].as_usize(); + let result_ptr = interpreter.get_trie_data()[result_ptr_ptr..][..4][0].as_usize(); let result = &interpreter.get_trie_data()[result_ptr..][..4]; assert_eq!(result[0], test_account_1().nonce); assert_eq!(result[1], test_account_1().balance); diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 16c1e5310..366b75a35 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -93,7 +93,7 @@ impl GenerationState { fn run_trie_ptr(&mut self, input_fn: &ProverInputFn) -> Result { let trie = input_fn.0[1].as_str(); match trie { - "state" => self + "initial_state" => self .trie_root_ptrs .state_root_ptr .map_or_else( diff --git a/scripts/prove_stdio.sh b/scripts/prove_stdio.sh index f54969930..7249dce92 100755 --- a/scripts/prove_stdio.sh +++ b/scripts/prove_stdio.sh @@ -53,8 +53,8 @@ if ! [[ $TEST_ONLY == "test_only" ]]; then # These sizes are configured specifically for block 19807080. Don't use this in other scenarios echo "Using specific circuit sizes for witness_b19807080.json" export ARITHMETIC_CIRCUIT_SIZE="16..18" - export BYTE_PACKING_CIRCUIT_SIZE="10..15" - export CPU_CIRCUIT_SIZE="16..20" + export BYTE_PACKING_CIRCUIT_SIZE="9..15" + export CPU_CIRCUIT_SIZE="15..20" export KECCAK_CIRCUIT_SIZE="12..18" export KECCAK_SPONGE_CIRCUIT_SIZE="8..14" export LOGIC_CIRCUIT_SIZE="8..17"