From 7f366cdace01e7f86fc7489c5ccf56155f66457e Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 16 Oct 2022 10:11:45 -0700 Subject: [PATCH] Treat storage tries as sub-tries of the state trie I.e. have leaves in the state trie point to the root of a storage trie --- evm/Cargo.toml | 2 +- evm/src/cpu/kernel/aggregator.rs | 1 + evm/src/cpu/kernel/asm/mpt/hash.asm | 44 ++-- .../cpu/kernel/asm/mpt/hash_trie_specific.asm | 12 +- evm/src/cpu/kernel/asm/mpt/load.asm | 206 ++++++++---------- .../cpu/kernel/asm/mpt/load_trie_specific.asm | 40 ++++ .../cpu/kernel/constants/context_metadata.rs | 2 +- .../cpu/kernel/constants/global_metadata.rs | 7 +- evm/src/cpu/kernel/tests/mpt/hash.rs | 78 ++++--- evm/src/cpu/kernel/tests/mpt/insert.rs | 46 ++-- evm/src/cpu/kernel/tests/mpt/load.rs | 62 ++++-- evm/src/cpu/kernel/tests/mpt/read.rs | 25 +-- evm/src/generation/mpt.rs | 138 +++++++++--- evm/src/memory/segments.rs | 24 +- 14 files changed, 396 insertions(+), 291 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/mpt/load_trie_specific.asm diff --git a/evm/Cargo.toml b/evm/Cargo.toml index bcbc5cd9..7c179318 100644 --- a/evm/Cargo.toml +++ b/evm/Cargo.toml @@ -14,7 +14,7 @@ ethereum-types = "0.14.0" hex = { version = "0.4.3", optional = true } hex-literal = "0.3.4" itertools = "0.10.3" -keccak-hash = "0.9.0" +keccak-hash = "0.10.0" log = "0.4.14" num = "0.4.0" maybe_rayon = { path = "../maybe_rayon" } diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 032338b7..afed6a31 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -48,6 +48,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/mpt/insert_leaf.asm"), include_str!("asm/mpt/insert_trie_specific.asm"), include_str!("asm/mpt/load.asm"), + include_str!("asm/mpt/load_trie_specific.asm"), include_str!("asm/mpt/read.asm"), include_str!("asm/mpt/storage_read.asm"), include_str!("asm/mpt/storage_write.asm"), diff --git a/evm/src/cpu/kernel/asm/mpt/hash.asm b/evm/src/cpu/kernel/asm/mpt/hash.asm index ee8b5ca3..9fe0edef 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash.asm @@ -47,7 +47,29 @@ mpt_hash_hash_rlp_after_unpacking: // 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) + // stack: node_ptr, encode_value, retdest + DUP1 %mload_trie_data + + // Check if we're dealing with a concrete node, i.e. not a hash node. + // stack: node_type, node_ptr, encode_value, retdest + DUP1 + PUSH @MPT_NODE_HASH + SUB + %jumpi(encode_or_hash_concrete_node) + + // If we got here, node_type == @MPT_NODE_HASH. + // Load the hash and return (hash, 32). + // stack: node_type, node_ptr, encode_value, retdest + POP + // stack: node_ptr, encode_value, retdest + %increment // Skip over node type prefix + // stack: hash_ptr, encode_value, retdest + %mload_trie_data + // stack: hash, encode_value, retdest + %stack (hash, encode_value, retdest) -> (retdest, hash, 32) + JUMP +encode_or_hash_concrete_node: + %stack (node_type, node_ptr, encode_value) -> (node_type, node_ptr, encode_value, maybe_hash_node) %jump(encode_node) maybe_hash_node: // stack: result_ptr, result_len, retdest @@ -75,22 +97,22 @@ after_packed_small_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 +// Pre stack: node_type, node_ptr, encode_value, retdest // Post stack: result_ptr, result_len -global encode_node: - // stack: node_ptr, encode_value, retdest - DUP1 %mload_trie_data +encode_node: // stack: node_type, node_ptr, encode_value, retdest // Increment node_ptr, so it points to the node payload instead of its type. SWAP1 %increment 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. + + // If we got here, node_type is either @MPT_NODE_HASH, which should have + // been handled earlier in encode_or_hash_node, or something invalid. + PANIC global encode_node_empty: // stack: node_type, node_payload_ptr, encode_value, retdest @@ -105,14 +127,6 @@ global encode_node_empty: %stack (retdest) -> (retdest, 0, 1) JUMP -global encode_node_hash: - // stack: node_type, node_payload_ptr, encode_value, retdest - POP - // stack: node_payload_ptr, encode_value, retdest - %mload_trie_data - %stack (hash, encode_value, retdest) -> (retdest, hash, 32) - JUMP - encode_node_branch: // stack: node_type, node_payload_ptr, encode_value, retdest POP diff --git a/evm/src/cpu/kernel/asm/mpt/hash_trie_specific.asm b/evm/src/cpu/kernel/asm/mpt/hash_trie_specific.asm index bf2c46f0..4f9b58b4 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash_trie_specific.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash_trie_specific.asm @@ -72,8 +72,13 @@ global encode_account: // stack: balance, rlp_pos_4, value_ptr, retdest SWAP1 %encode_rlp_scalar // stack: rlp_pos_5, value_ptr, retdest - DUP2 %add_const(2) %mload_trie_data // storage_root = value[2] - // stack: storage_root, rlp_pos_5, value_ptr, retdest + PUSH encode_account_after_hash_storage_trie + PUSH encode_storage_value + DUP4 %add_const(2) %mload_trie_data // storage_root_ptr = value[2] + // stack: storage_root_ptr, encode_storage_value, encode_account_after_hash_storage_trie, rlp_pos_5, value_ptr, retdest + %jump(mpt_hash) +encode_account_after_hash_storage_trie: + // stack: storage_root_digest, rlp_pos_5, value_ptr, retdest SWAP1 %encode_rlp_256 // stack: rlp_pos_6, value_ptr, retdest SWAP1 %add_const(3) %mload_trie_data // code_hash = value[3] @@ -88,3 +93,6 @@ encode_txn: encode_receipt: PANIC // TODO + +encode_storage_value: + PANIC // TODO diff --git a/evm/src/cpu/kernel/asm/mpt/load.asm b/evm/src/cpu/kernel/asm/mpt/load.asm index 49258a31..d787074b 100644 --- a/evm/src/cpu/kernel/asm/mpt/load.asm +++ b/evm/src/cpu/kernel/asm/mpt/load.asm @@ -1,6 +1,3 @@ -// TODO: Receipt trie leaves are variable-length, so we need to be careful not -// to permit buffer over-reads. - // Load all partial trie data from prover inputs. global load_all_mpts: // stack: retdest @@ -9,47 +6,20 @@ global load_all_mpts: PUSH 1 %set_trie_data_size - %load_mpt %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - %load_mpt %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT) - %load_mpt %mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_ROOT) + %load_mpt(mpt_load_state_trie_value) %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + %load_mpt(mpt_load_txn_trie_value) %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT) + %load_mpt(mpt_load_receipt_trie_value) %mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_ROOT) - PROVER_INPUT(mpt) - // stack: num_storage_tries, retdest - DUP1 %mstore_global_metadata(@GLOBAL_METADATA_NUM_STORAGE_TRIES) - // stack: num_storage_tries, retdest - PUSH 0 // i = 0 - // stack: i, num_storage_tries, retdest -storage_trie_loop: - DUP2 DUP2 EQ - // stack: i == num_storage_tries, i, num_storage_tries, retdest - %jumpi(storage_trie_loop_end) - // stack: i, num_storage_tries, retdest - PROVER_INPUT(mpt) - // stack: storage_trie_addr, i, num_storage_tries, retdest - DUP2 - // stack: i, storage_trie_addr, i, num_storage_tries, retdest - %mstore_kernel(@SEGMENT_STORAGE_TRIE_ADDRS) - // stack: i, num_storage_tries, retdest - %load_mpt - // stack: root_ptr, i, num_storage_tries, retdest - DUP2 - // stack: i, root_ptr, i, num_storage_tries, retdest - %mstore_kernel(@SEGMENT_STORAGE_TRIE_PTRS) - // stack: i, num_storage_tries, retdest - %jump(storage_trie_loop) -storage_trie_loop_end: - // stack: i, num_storage_tries, retdest - %pop2 // stack: retdest JUMP // Load an MPT from prover inputs. -// Pre stack: retdest +// Pre stack: load_value, retdest // Post stack: node_ptr -load_mpt: - // stack: retdest +global load_mpt: + // stack: load_value, retdest PROVER_INPUT(mpt) - // stack: node_type, retdest + // stack: node_type, load_value, retdest DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(load_mpt_empty) DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(load_mpt_branch) @@ -60,146 +30,144 @@ load_mpt: load_mpt_empty: // TRIE_DATA[0] = 0, and an empty node has type 0, so we can simply return the null pointer. - %stack (node_type, retdest) -> (retdest, 0) + %stack (node_type, load_value, retdest) -> (retdest, 0) JUMP load_mpt_branch: - // stack: node_type, retdest + // stack: node_type, load_value, retdest %get_trie_data_size - // stack: node_ptr, node_type, retdest + // stack: node_ptr, node_type, load_value, retdest SWAP1 %append_to_trie_data - // stack: node_ptr, retdest + // stack: node_ptr, load_value, retdest // Save the offset of our 16 child pointers so we can write them later. // Then advance our current trie pointer beyond them, so we can load the // value and have it placed after our child pointers. %get_trie_data_size - // stack: children_ptr, node_ptr, retdest + // stack: children_ptr, node_ptr, load_value, retdest DUP1 %add_const(17) // Skip over 16 children plus the value pointer - // stack: value_ptr, children_ptr, node_ptr, retdest - %set_trie_data_size - // stack: children_ptr, node_ptr, retdest - %load_value + // stack: end_of_branch_ptr, children_ptr, node_ptr, load_value, retdest + DUP1 %set_trie_data_size + // Now the top of the stack points to where the branch node will end and the + // value will begin, if there is a value. But we need to ask the prover if a + // value is present, and point to null if not. + // stack: end_of_branch_ptr, children_ptr, node_ptr, load_value, retdest + PROVER_INPUT(mpt) + // stack: is_value_present, end_of_branch_ptr, children_ptr, node_ptr, load_value, retdest + %jumpi(load_mpt_branch_value_present) + // There is no value present, so value_ptr = null. + %stack (end_of_branch_ptr) -> (0) + // stack: value_ptr, children_ptr, node_ptr, load_value, retdest + %jump(load_mpt_branch_after_load_value) +load_mpt_branch_value_present: + // stack: value_ptr, children_ptr, node_ptr, load_value, retdest + PUSH load_mpt_branch_after_load_value + DUP5 // load_value + JUMP +load_mpt_branch_after_load_value: + // stack: value_ptr, children_ptr, node_ptr, load_value, retdest SWAP1 - // stack: children_ptr, value_ptr, node_ptr, retdest + // stack: children_ptr, value_ptr, node_ptr, load_value, retdest // Load the 16 children. %rep 16 + DUP4 // load_value %load_mpt - // stack: child_ptr, next_child_ptr_ptr, value_ptr, node_ptr, retdest + // stack: child_ptr, next_child_ptr_ptr, value_ptr, node_ptr, load_value, retdest DUP2 - // stack: next_child_ptr_ptr, child_ptr, next_child_ptr_ptr, value_ptr, node_ptr, retdest + // stack: next_child_ptr_ptr, child_ptr, next_child_ptr_ptr, value_ptr, node_ptr, load_value, retdest %mstore_trie_data - // stack: next_child_ptr_ptr, value_ptr, node_ptr, retdest + // stack: next_child_ptr_ptr, value_ptr, node_ptr, load_value, retdest %increment - // stack: next_child_ptr_ptr, value_ptr, node_ptr, retdest + // stack: next_child_ptr_ptr, value_ptr, node_ptr, load_value, retdest %endrep - // stack: value_ptr_ptr, value_ptr, node_ptr, retdest + // stack: value_ptr_ptr, value_ptr, node_ptr, load_value, retdest %mstore_trie_data - // stack: node_ptr, retdest - SWAP1 + %stack (node_ptr, load_value, retdest) -> (retdest, node_ptr) JUMP load_mpt_extension: - // stack: node_type, retdest + // stack: node_type, load_value, retdest %get_trie_data_size - // stack: node_ptr, node_type, retdest + // stack: node_ptr, node_type, load_value, retdest SWAP1 %append_to_trie_data - // stack: node_ptr, retdest + // stack: node_ptr, load_value, retdest PROVER_INPUT(mpt) // read num_nibbles %append_to_trie_data PROVER_INPUT(mpt) // read packed_nibbles %append_to_trie_data - // stack: node_ptr, retdest + // stack: node_ptr, load_value, retdest %get_trie_data_size - // stack: child_ptr_ptr, node_ptr, retdest + // stack: child_ptr_ptr, node_ptr, load_value, retdest // Increment trie_data_size, to leave room for child_ptr_ptr, before we load our child. DUP1 %increment %set_trie_data_size - // stack: child_ptr_ptr, node_ptr, retdest - - %load_mpt - // stack: child_ptr, child_ptr_ptr, node_ptr, retdest - SWAP1 - %mstore_trie_data - // stack: node_ptr, retdest - SWAP1 + %stack (child_ptr_ptr, node_ptr, load_value, retdest) + -> (load_value, load_mpt_extension_after_load_mpt, + child_ptr_ptr, retdest, node_ptr) + %jump(load_mpt) +load_mpt_extension_after_load_mpt: + // stack: child_ptr, child_ptr_ptr, retdest, node_ptr + SWAP1 %mstore_trie_data + // stack: retdest, node_ptr JUMP load_mpt_leaf: - // stack: node_type, retdest + // stack: node_type, load_value, retdest %get_trie_data_size - // stack: node_ptr, node_type, retdest + // stack: node_ptr, node_type, load_value, retdest SWAP1 %append_to_trie_data - // stack: node_ptr, retdest + // stack: node_ptr, load_value, retdest PROVER_INPUT(mpt) // read num_nibbles %append_to_trie_data PROVER_INPUT(mpt) // read packed_nibbles %append_to_trie_data - // stack: node_ptr, retdest + // stack: node_ptr, load_value, retdest // We save value_ptr_ptr = get_trie_data_size, then increment trie_data_size - // to skip over the slot for value_ptr. We will write value_ptr after the - // load_value call. + // to skip over the slot for value_ptr_ptr. We will write to value_ptr_ptr + // after the load_value call. %get_trie_data_size - // stack: value_ptr_ptr, node_ptr, retdest - DUP1 %increment %set_trie_data_size - // stack: value_ptr_ptr, node_ptr, retdest - %load_value - // stack: value_ptr, value_ptr_ptr, node_ptr, retdest - SWAP1 %mstore_trie_data - // stack: node_ptr, retdest - SWAP1 + // stack: value_ptr_ptr, node_ptr, load_value, retdest + DUP1 %increment + // stack: value_ptr, value_ptr_ptr, node_ptr, load_value, retdest + DUP1 %set_trie_data_size + // stack: value_ptr, value_ptr_ptr, node_ptr, load_value, retdest + %stack (value_ptr, value_ptr_ptr, node_ptr, load_value, retdest) + -> (load_value, load_mpt_leaf_after_load_value, + value_ptr_ptr, value_ptr, retdest, node_ptr) + JUMP +load_mpt_leaf_after_load_value: + // stack: value_ptr_ptr, value_ptr, retdest, node_ptr + %mstore_trie_data + // stack: retdest, node_ptr JUMP load_mpt_digest: - // stack: node_type, retdest + // stack: node_type, load_value, retdest %get_trie_data_size - // stack: node_ptr, node_type, retdest + // stack: node_ptr, node_type, load_value, retdest SWAP1 %append_to_trie_data - // stack: node_ptr, retdest + // stack: node_ptr, load_value, retdest PROVER_INPUT(mpt) // read digest %append_to_trie_data - // stack: node_ptr, retdest - SWAP1 + %stack (node_ptr, load_value, retdest) -> (retdest, node_ptr) JUMP // Convenience macro to call load_mpt and return where we left off. +// Pre stack: load_value +// Post stack: node_ptr %macro load_mpt - PUSH %%after + %stack (load_value) -> (load_value, %%after) %jump(load_mpt) %%after: %endmacro -// Load a value from prover input, append it to trie data, and return a pointer to it. -// Return null if the value is empty. -%macro load_value - // stack: (empty) - PROVER_INPUT(mpt) - // stack: value_len - DUP1 %jumpi(%%has_value) - %stack (value_len) -> (0) - %jump(%%end) -%%has_value: - // stack: value_len - %get_trie_data_size - // stack: value_ptr, value_len - SWAP1 - // stack: value_len, value_ptr -%%loop: - DUP1 ISZERO - // stack: value_len == 0, value_len, value_ptr - %jumpi(%%finish_loop) - // stack: value_len, value_ptr - PROVER_INPUT(mpt) - // stack: value_part, value_len, value_ptr - %append_to_trie_data - // stack: value_len, value_ptr - %decrement - // stack: value_len', value_ptr - %jump(%%loop) -%%finish_loop: - // stack: value_len, value_ptr - POP - // stack: value_ptr -%%end: +// Convenience macro to call load_mpt and return where we left off. +// Pre stack: (empty) +// Post stack: node_ptr +%macro load_mpt(load_value) + PUSH %%after + PUSH $load_value + %jump(load_mpt) +%%after: %endmacro diff --git a/evm/src/cpu/kernel/asm/mpt/load_trie_specific.asm b/evm/src/cpu/kernel/asm/mpt/load_trie_specific.asm new file mode 100644 index 00000000..b93b36e4 --- /dev/null +++ b/evm/src/cpu/kernel/asm/mpt/load_trie_specific.asm @@ -0,0 +1,40 @@ +global mpt_load_state_trie_value: + // stack: retdest + + // Load and append the nonce and balance. + PROVER_INPUT(mpt) %append_to_trie_data + PROVER_INPUT(mpt) %append_to_trie_data + + // Now increment the trie data size by 2, to leave room for our storage trie + // pointer and code hash fields, before calling load_mpt which will append + // our storage trie data. + %get_trie_data_size + // stack: storage_trie_ptr_ptr, retdest + DUP1 %add_const(2) + // stack: storage_trie_ptr, storage_trie_ptr_ptr, retdest + %set_trie_data_size + // stack: storage_trie_ptr_ptr, retdest + + %load_mpt(mpt_load_storage_trie_value) + // stack: storage_trie_ptr, storage_trie_ptr_ptr, retdest + DUP2 %mstore_trie_data + // stack: storage_trie_ptr_ptr, retdest + %increment + // stack: code_hash_ptr, retdest + PROVER_INPUT(mpt) + // stack: code_hash, code_hash_ptr, retdest + SWAP1 %mstore_trie_data + // stack: retdest + JUMP + +global mpt_load_txn_trie_value: + // stack: retdest + PANIC // TODO + +global mpt_load_receipt_trie_value: + // stack: retdest + PANIC // TODO + +global mpt_load_storage_trie_value: + // stack: retdest + PANIC // TODO diff --git a/evm/src/cpu/kernel/constants/context_metadata.rs b/evm/src/cpu/kernel/constants/context_metadata.rs index 17945d98..a2c460fc 100644 --- a/evm/src/cpu/kernel/constants/context_metadata.rs +++ b/evm/src/cpu/kernel/constants/context_metadata.rs @@ -21,7 +21,7 @@ pub(crate) enum ContextMetadata { /// prohibited. Static = 8, /// Pointer to the initial version of the state trie, at the creation of this context. Used when - /// we need to revert a context. See also `StorageTrieCheckpointPointers`. + /// we need to revert a context. StateTrieCheckpointPointer = 9, } diff --git a/evm/src/cpu/kernel/constants/global_metadata.rs b/evm/src/cpu/kernel/constants/global_metadata.rs index 295cdfd5..1fa62efe 100644 --- a/evm/src/cpu/kernel/constants/global_metadata.rs +++ b/evm/src/cpu/kernel/constants/global_metadata.rs @@ -18,9 +18,6 @@ pub(crate) enum GlobalMetadata { TransactionTrieRoot = 5, /// A pointer to the root of the receipt trie within the `TrieData` buffer. ReceiptTrieRoot = 6, - /// The number of storage tries involved in these transactions. I.e. the number of values in - /// `StorageTrieAddresses`, `StorageTriePointers` and `StorageTrieCheckpointPointers`. - NumStorageTries = 7, // The root digests of each Merkle trie before these transactions. StateTrieRootDigestBefore = 8, @@ -38,7 +35,7 @@ pub(crate) enum GlobalMetadata { } impl GlobalMetadata { - pub(crate) const COUNT: usize = 15; + pub(crate) const COUNT: usize = 14; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -49,7 +46,6 @@ impl GlobalMetadata { Self::StateTrieRoot, Self::TransactionTrieRoot, Self::ReceiptTrieRoot, - Self::NumStorageTries, Self::StateTrieRootDigestBefore, Self::TransactionTrieRootDigestBefore, Self::ReceiptTrieRootDigestBefore, @@ -70,7 +66,6 @@ impl GlobalMetadata { GlobalMetadata::StateTrieRoot => "GLOBAL_METADATA_STATE_TRIE_ROOT", GlobalMetadata::TransactionTrieRoot => "GLOBAL_METADATA_TXN_TRIE_ROOT", GlobalMetadata::ReceiptTrieRoot => "GLOBAL_METADATA_RECEIPT_TRIE_ROOT", - GlobalMetadata::NumStorageTries => "GLOBAL_METADATA_NUM_STORAGE_TRIES", GlobalMetadata::StateTrieRootDigestBefore => "GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE", GlobalMetadata::TransactionTrieRootDigestBefore => { "GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE" diff --git a/evm/src/cpu/kernel/tests/mpt/hash.rs b/evm/src/cpu/kernel/tests/mpt/hash.rs index de519797..19c38e91 100644 --- a/evm/src/cpu/kernel/tests/mpt/hash.rs +++ b/evm/src/cpu/kernel/tests/mpt/hash.rs @@ -1,12 +1,12 @@ use anyhow::Result; use eth_trie_utils::partial_trie::PartialTrie; -use ethereum_types::{BigEndianHash, H256, U256}; +use ethereum_types::{BigEndianHash, H256}; use super::nibbles; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::interpreter::Interpreter; -use crate::cpu::kernel::tests::mpt::extension_to_leaf; -use crate::generation::mpt::{all_mpt_prover_inputs_reversed, AccountRlp}; +use crate::cpu::kernel::tests::mpt::{extension_to_leaf, test_account_1_rlp, test_account_2_rlp}; +use crate::generation::mpt::all_mpt_prover_inputs_reversed; use crate::generation::TrieInputs; // TODO: Test with short leaf. Might need to be a storage trie. @@ -24,73 +24,69 @@ fn mpt_hash_empty() -> Result<()> { } #[test] -fn mpt_hash_leaf() -> Result<()> { - let account = AccountRlp { - nonce: U256::from(1111), - balance: U256::from(2222), - storage_root: H256::from_uint(&U256::from(3333)), - code_hash: H256::from_uint(&U256::from(4444)), +fn mpt_hash_empty_branch() -> Result<()> { + let children = std::array::from_fn(|_| PartialTrie::Empty.into()); + let state_trie = PartialTrie::Branch { + children, + value: vec![], }; - let account_rlp = rlp::encode(&account); - - let state_trie = PartialTrie::Leaf { - nibbles: nibbles(0xABC), - value: account_rlp.to_vec(), - }; - let trie_inputs = TrieInputs { state_trie, transactions_trie: Default::default(), receipts_trie: Default::default(), storage_tries: vec![], }; + test_state_trie(trie_inputs) +} +#[test] +fn mpt_hash_hash() -> Result<()> { + let hash = H256::random(); + let trie_inputs = TrieInputs { + state_trie: PartialTrie::Hash(hash), + transactions_trie: Default::default(), + receipts_trie: Default::default(), + storage_tries: vec![], + }; + + test_state_trie(trie_inputs) +} + +#[test] +fn mpt_hash_leaf() -> Result<()> { + let state_trie = PartialTrie::Leaf { + nibbles: nibbles(0xABC), + value: test_account_1_rlp(), + }; + let trie_inputs = TrieInputs { + state_trie, + transactions_trie: Default::default(), + receipts_trie: Default::default(), + storage_tries: vec![], + }; test_state_trie(trie_inputs) } #[test] fn mpt_hash_extension_to_leaf() -> Result<()> { - let account = AccountRlp { - nonce: U256::from(1111), - balance: U256::from(2222), - storage_root: H256::from_uint(&U256::from(3333)), - code_hash: H256::from_uint(&U256::from(4444)), - }; - let account_rlp = rlp::encode(&account); - - let state_trie = extension_to_leaf(account_rlp.to_vec()); - + let state_trie = extension_to_leaf(test_account_1_rlp()); let trie_inputs = TrieInputs { state_trie, transactions_trie: Default::default(), receipts_trie: Default::default(), storage_tries: vec![], }; - test_state_trie(trie_inputs) } #[test] fn mpt_hash_branch_to_leaf() -> Result<()> { - let account = AccountRlp { - nonce: U256::from(1111), - balance: U256::from(2222), - storage_root: H256::from_uint(&U256::from(3333)), - code_hash: H256::from_uint(&U256::from(4444)), - }; - let account_rlp = rlp::encode(&account); - let leaf = PartialTrie::Leaf { nibbles: nibbles(0xABC), - value: account_rlp.to_vec(), + value: test_account_2_rlp(), } .into(); let mut children = std::array::from_fn(|_| PartialTrie::Empty.into()); - children[5] = PartialTrie::Branch { - children: children.clone(), - value: vec![], - } - .into(); children[3] = leaf; let state_trie = PartialTrie::Branch { children, diff --git a/evm/src/cpu/kernel/tests/mpt/insert.rs b/evm/src/cpu/kernel/tests/mpt/insert.rs index 5310d431..3a52948d 100644 --- a/evm/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm/src/cpu/kernel/tests/mpt/insert.rs @@ -6,13 +6,13 @@ use super::nibbles; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; -use crate::cpu::kernel::tests::mpt::{test_account_1_rlp, test_account_2_rlp}; +use crate::cpu::kernel::tests::mpt::{test_account_1_rlp, test_account_2}; use crate::generation::mpt::{all_mpt_prover_inputs_reversed, AccountRlp}; use crate::generation::TrieInputs; #[test] fn mpt_insert_empty() -> Result<()> { - test_state_trie(Default::default(), nibbles(0xABC), test_account_2_rlp()) + test_state_trie(Default::default(), nibbles(0xABC), test_account_2()) } #[test] @@ -22,7 +22,7 @@ fn mpt_insert_leaf_identical_keys() -> Result<()> { nibbles: key, value: test_account_1_rlp(), }; - test_state_trie(state_trie, key, test_account_2_rlp()) + test_state_trie(state_trie, key, test_account_2()) } #[test] @@ -31,7 +31,7 @@ fn mpt_insert_leaf_nonoverlapping_keys() -> Result<()> { nibbles: nibbles(0xABC), value: test_account_1_rlp(), }; - test_state_trie(state_trie, nibbles(0x123), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0x123), test_account_2()) } #[test] @@ -40,7 +40,7 @@ fn mpt_insert_leaf_overlapping_keys() -> Result<()> { nibbles: nibbles(0xABC), value: test_account_1_rlp(), }; - test_state_trie(state_trie, nibbles(0xADE), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0xADE), test_account_2()) } #[test] @@ -49,7 +49,7 @@ fn mpt_insert_leaf_insert_key_extends_leaf_key() -> Result<()> { nibbles: nibbles(0xABC), value: test_account_1_rlp(), }; - test_state_trie(state_trie, nibbles(0xABCDE), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0xABCDE), test_account_2()) } #[test] @@ -58,7 +58,7 @@ fn mpt_insert_leaf_leaf_key_extends_insert_key() -> Result<()> { nibbles: nibbles(0xABCDE), value: test_account_1_rlp(), }; - test_state_trie(state_trie, nibbles(0xABC), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0xABC), test_account_2()) } #[test] @@ -69,10 +69,13 @@ fn mpt_insert_branch_replacing_empty_child() -> Result<()> { value: vec![], }; - test_state_trie(state_trie, nibbles(0xABC), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0xABC), test_account_2()) } #[test] +// TODO: Not a valid test because branches state trie cannot have branch values. +// We should change it to use a different trie. +#[ignore] fn mpt_insert_extension_nonoverlapping_keys() -> Result<()> { // Existing keys are 0xABC, 0xABCDEF; inserted key is 0x12345. let mut children = std::array::from_fn(|_| PartialTrie::Empty.into()); @@ -89,10 +92,13 @@ fn mpt_insert_extension_nonoverlapping_keys() -> Result<()> { } .into(), }; - test_state_trie(state_trie, nibbles(0x12345), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0x12345), test_account_2()) } #[test] +// TODO: Not a valid test because branches state trie cannot have branch values. +// We should change it to use a different trie. +#[ignore] fn mpt_insert_extension_insert_key_extends_node_key() -> Result<()> { // Existing keys are 0xA, 0xABCD; inserted key is 0xABCDEF. let mut children = std::array::from_fn(|_| PartialTrie::Empty.into()); @@ -109,7 +115,7 @@ fn mpt_insert_extension_insert_key_extends_node_key() -> Result<()> { } .into(), }; - test_state_trie(state_trie, nibbles(0xABCDEF), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0xABCDEF), test_account_2()) } #[test] @@ -126,10 +132,14 @@ fn mpt_insert_branch_to_leaf_same_key() -> Result<()> { value: vec![], }; - test_state_trie(state_trie, nibbles(0xABCD), test_account_2_rlp()) + test_state_trie(state_trie, nibbles(0xABCD), test_account_2()) } -fn test_state_trie(state_trie: PartialTrie, k: Nibbles, v: Vec) -> Result<()> { +/// Note: The account's storage_root is ignored, as we can't insert a new storage_root without the +/// accompanying trie data. An empty trie's storage_root is used instead. +fn test_state_trie(state_trie: PartialTrie, k: Nibbles, mut account: AccountRlp) -> Result<()> { + account.storage_root = PartialTrie::Empty.calc_hash(); + let trie_inputs = TrieInputs { state_trie: state_trie.clone(), transactions_trie: Default::default(), @@ -155,9 +165,13 @@ fn test_state_trie(state_trie: PartialTrie, k: Nibbles, v: Vec) -> Result<() trie_data.push(0.into()); } let value_ptr = trie_data.len(); - let account: AccountRlp = rlp::decode(&v).expect("Decoding failed"); - let account_data = account.to_vec(); - trie_data.extend(account_data); + trie_data.push(account.nonce); + trie_data.push(account.balance); + // In memory, storage_root gets interpreted as a pointer to a storage trie, + // so we have to ensure the pointer is valid. It's easiest to set it to 0, + // which works as an empty node, since trie_data[0] = 0 = MPT_TYPE_EMPTY. + trie_data.push(H256::zero().into_uint()); + trie_data.push(account.code_hash.into_uint()); let trie_data_len = trie_data.len().into(); interpreter.set_global_metadata_field(GlobalMetadata::TrieDataSize, trie_data_len); interpreter.push(0xDEADBEEFu32.into()); @@ -186,7 +200,7 @@ fn test_state_trie(state_trie: PartialTrie, k: Nibbles, v: Vec) -> Result<() ); let hash = H256::from_uint(&interpreter.stack()[0]); - let updated_trie = state_trie.insert(k, v); + let updated_trie = state_trie.insert(k, rlp::encode(&account).to_vec()); let expected_state_trie_hash = updated_trie.calc_hash(); assert_eq!(hash, expected_state_trie_hash); diff --git a/evm/src/cpu/kernel/tests/mpt/load.rs b/evm/src/cpu/kernel/tests/mpt/load.rs index b7b3b108..78129a1c 100644 --- a/evm/src/cpu/kernel/tests/mpt/load.rs +++ b/evm/src/cpu/kernel/tests/mpt/load.rs @@ -1,6 +1,6 @@ use anyhow::Result; use eth_trie_utils::partial_trie::PartialTrie; -use ethereum_types::{BigEndianHash, U256}; +use ethereum_types::{BigEndianHash, H256, U256}; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::constants::trie_type::PartialTrieType; @@ -42,11 +42,6 @@ fn load_all_mpts_empty() -> Result<()> { 0.into() ); - assert_eq!( - interpreter.get_global_metadata_field(GlobalMetadata::NumStorageTries), - trie_inputs.storage_tries.len().into() - ); - Ok(()) } @@ -81,8 +76,11 @@ fn load_all_mpts_leaf() -> Result<()> { 5.into(), // value ptr test_account_1().nonce, test_account_1().balance, - test_account_1().storage_root.into_uint(), + 9.into(), // pointer to storage trie root test_account_1().code_hash.into_uint(), + // These last two elements encode the storage trie, which is a hash node. + (PartialTrieType::Hash as u32).into(), + test_account_1().storage_root.into_uint(), ] ); @@ -95,9 +93,40 @@ fn load_all_mpts_leaf() -> Result<()> { 0.into() ); + Ok(()) +} + +#[test] +fn load_all_mpts_hash() -> Result<()> { + let hash = H256::random(); + let trie_inputs = TrieInputs { + state_trie: PartialTrie::Hash(hash), + transactions_trie: Default::default(), + receipts_trie: Default::default(), + storage_tries: vec![], + }; + + let load_all_mpts = KERNEL.global_labels["load_all_mpts"]; + + let initial_stack = vec![0xDEADBEEFu32.into()]; + let mut interpreter = Interpreter::new_with_kernel(load_all_mpts, initial_stack); + interpreter.generation_state.mpt_prover_inputs = all_mpt_prover_inputs_reversed(&trie_inputs); + interpreter.run()?; + assert_eq!(interpreter.stack(), vec![]); + + let type_hash = U256::from(PartialTrieType::Hash as u32); assert_eq!( - interpreter.get_global_metadata_field(GlobalMetadata::NumStorageTries), - trie_inputs.storage_tries.len().into() + interpreter.get_trie_data(), + vec![0.into(), type_hash, hash.into_uint(),] + ); + + assert_eq!( + interpreter.get_global_metadata_field(GlobalMetadata::TransactionTrieRoot), + 0.into() + ); + assert_eq!( + interpreter.get_global_metadata_field(GlobalMetadata::ReceiptTrieRoot), + 0.into() ); Ok(()) @@ -160,11 +189,6 @@ fn load_all_mpts_empty_branch() -> Result<()> { 0.into() ); - assert_eq!( - interpreter.get_global_metadata_field(GlobalMetadata::NumStorageTries), - trie_inputs.storage_tries.len().into() - ); - Ok(()) } @@ -201,15 +225,13 @@ fn load_all_mpts_ext_to_leaf() -> Result<()> { 9.into(), // value pointer test_account_1().nonce, test_account_1().balance, - test_account_1().storage_root.into_uint(), + 13.into(), // pointer to storage trie root test_account_1().code_hash.into_uint(), + // These last two elements encode the storage trie, which is a hash node. + (PartialTrieType::Hash as u32).into(), + test_account_1().storage_root.into_uint(), ] ); - assert_eq!( - interpreter.get_global_metadata_field(GlobalMetadata::NumStorageTries), - trie_inputs.storage_tries.len().into() - ); - Ok(()) } diff --git a/evm/src/cpu/kernel/tests/mpt/read.rs b/evm/src/cpu/kernel/tests/mpt/read.rs index c45a6b60..d8808e24 100644 --- a/evm/src/cpu/kernel/tests/mpt/read.rs +++ b/evm/src/cpu/kernel/tests/mpt/read.rs @@ -1,25 +1,17 @@ use anyhow::Result; -use ethereum_types::{BigEndianHash, H256, U256}; +use ethereum_types::BigEndianHash; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; -use crate::cpu::kernel::tests::mpt::extension_to_leaf; -use crate::generation::mpt::{all_mpt_prover_inputs_reversed, AccountRlp}; +use crate::cpu::kernel::tests::mpt::{extension_to_leaf, test_account_1, test_account_1_rlp}; +use crate::generation::mpt::all_mpt_prover_inputs_reversed; use crate::generation::TrieInputs; #[test] fn mpt_read() -> Result<()> { - let account = AccountRlp { - nonce: U256::from(1111), - balance: U256::from(2222), - storage_root: H256::from_uint(&U256::from(3333)), - code_hash: H256::from_uint(&U256::from(4444)), - }; - let account_rlp = rlp::encode(&account); - let trie_inputs = TrieInputs { - state_trie: extension_to_leaf(account_rlp.to_vec()), + state_trie: extension_to_leaf(test_account_1_rlp()), transactions_trie: Default::default(), receipts_trie: Default::default(), storage_tries: vec![], @@ -45,10 +37,11 @@ fn mpt_read() -> Result<()> { assert_eq!(interpreter.stack().len(), 1); let result_ptr = interpreter.stack()[0].as_usize(); let result = &interpreter.get_trie_data()[result_ptr..][..4]; - assert_eq!(result[0], account.nonce); - assert_eq!(result[1], account.balance); - assert_eq!(result[2], account.storage_root.into_uint()); - assert_eq!(result[3], account.code_hash.into_uint()); + assert_eq!(result[0], test_account_1().nonce); + assert_eq!(result[1], test_account_1().balance); + // result[2] is the storage root pointer. We won't check that it matches a + // particular address, since that seems like over-specifying. + assert_eq!(result[3], test_account_1().code_hash.into_uint()); Ok(()) } diff --git a/evm/src/generation/mpt.rs b/evm/src/generation/mpt.rs index e35364c6..8ceb195a 100644 --- a/evm/src/generation/mpt.rs +++ b/evm/src/generation/mpt.rs @@ -1,5 +1,8 @@ -use eth_trie_utils::partial_trie::PartialTrie; +use std::collections::HashMap; + +use eth_trie_utils::partial_trie::{Nibbles, PartialTrie}; use ethereum_types::{BigEndianHash, H256, U256}; +use keccak_hash::keccak; use rlp_derive::{RlpDecodable, RlpEncodable}; use crate::cpu::kernel::constants::trie_type::PartialTrieType; @@ -13,17 +16,6 @@ pub(crate) struct AccountRlp { pub(crate) code_hash: H256, } -impl AccountRlp { - pub(crate) fn to_vec(&self) -> Vec { - vec![ - self.nonce, - self.balance, - self.storage_root.into_uint(), - self.code_hash.into_uint(), - ] - } -} - pub(crate) fn all_mpt_prover_inputs_reversed(trie_inputs: &TrieInputs) -> Vec { let mut inputs = all_mpt_prover_inputs(trie_inputs); inputs.reverse(); @@ -34,10 +26,18 @@ pub(crate) fn all_mpt_prover_inputs_reversed(trie_inputs: &TrieInputs) -> Vec Vec { let mut prover_inputs = vec![]; - mpt_prover_inputs(&trie_inputs.state_trie, &mut prover_inputs, &|rlp| { - let account: AccountRlp = rlp::decode(rlp).expect("Decoding failed"); - account.to_vec() - }); + let storage_tries_by_state_key = trie_inputs + .storage_tries + .iter() + .map(|(address, storage_trie)| (Nibbles::from(keccak(address)), storage_trie)) + .collect(); + + mpt_prover_inputs_state_trie( + &trie_inputs.state_trie, + empty_nibbles(), + &mut prover_inputs, + &storage_tries_by_state_key, + ); mpt_prover_inputs(&trie_inputs.transactions_trie, &mut prover_inputs, &|rlp| { rlp::decode_list(rlp) @@ -48,14 +48,6 @@ pub(crate) fn all_mpt_prover_inputs(trie_inputs: &TrieInputs) -> Vec { vec![] }); - prover_inputs.push(trie_inputs.storage_tries.len().into()); - for (addr, storage_trie) in &trie_inputs.storage_tries { - prover_inputs.push(addr.0.as_ref().into()); - mpt_prover_inputs(storage_trie, &mut prover_inputs, &|leaf_be| { - vec![U256::from_big_endian(leaf_be)] - }); - } - prover_inputs } @@ -66,7 +58,7 @@ pub(crate) fn all_mpt_prover_inputs(trie_inputs: &TrieInputs) -> Vec { pub(crate) fn mpt_prover_inputs( trie: &PartialTrie, prover_inputs: &mut Vec, - parse_leaf: &F, + parse_value: &F, ) where F: Fn(&[u8]) -> Vec, { @@ -76,28 +68,108 @@ pub(crate) fn mpt_prover_inputs( PartialTrie::Hash(h) => prover_inputs.push(U256::from_big_endian(h.as_bytes())), PartialTrie::Branch { children, value } => { if value.is_empty() { - // There's no value, so length=0. + // There's no value, so value_len = 0. prover_inputs.push(U256::zero()); } else { - let leaf = parse_leaf(value); - prover_inputs.push(leaf.len().into()); - prover_inputs.extend(leaf); + let parsed_value = parse_value(value); + prover_inputs.push(parsed_value.len().into()); + prover_inputs.extend(parsed_value); } for child in children { - mpt_prover_inputs(child, prover_inputs, parse_leaf); + mpt_prover_inputs(child, prover_inputs, parse_value); } } PartialTrie::Extension { nibbles, child } => { prover_inputs.push(nibbles.count.into()); prover_inputs.push(nibbles.packed); - mpt_prover_inputs(child, prover_inputs, parse_leaf); + mpt_prover_inputs(child, prover_inputs, parse_value); } PartialTrie::Leaf { nibbles, value } => { prover_inputs.push(nibbles.count.into()); prover_inputs.push(nibbles.packed); - let leaf = parse_leaf(value); - prover_inputs.push(leaf.len().into()); + let leaf = parse_value(value); prover_inputs.extend(leaf); } } } + +/// Like `mpt_prover_inputs`, but for the state trie, which is a bit unique since each value +/// leads to a storage trie which we recursively traverse. +pub(crate) fn mpt_prover_inputs_state_trie( + trie: &PartialTrie, + key: Nibbles, + prover_inputs: &mut Vec, + storage_tries_by_state_key: &HashMap, +) { + prover_inputs.push((PartialTrieType::of(trie) as u32).into()); + match trie { + PartialTrie::Empty => {} + PartialTrie::Hash(h) => prover_inputs.push(U256::from_big_endian(h.as_bytes())), + PartialTrie::Branch { children, value } => { + assert!(value.is_empty(), "State trie should not have branch values"); + // There's no value, so value_len = 0. + prover_inputs.push(U256::zero()); + + for (i, child) in children.iter().enumerate() { + let extended_key = key.merge(&Nibbles { + count: 1, + packed: i.into(), + }); + mpt_prover_inputs_state_trie( + child, + extended_key, + prover_inputs, + storage_tries_by_state_key, + ); + } + } + PartialTrie::Extension { nibbles, child } => { + prover_inputs.push(nibbles.count.into()); + prover_inputs.push(nibbles.packed); + let extended_key = key.merge(nibbles); + mpt_prover_inputs_state_trie( + child, + extended_key, + prover_inputs, + storage_tries_by_state_key, + ); + } + PartialTrie::Leaf { nibbles, value } => { + let account: AccountRlp = rlp::decode(value).expect("Decoding failed"); + let AccountRlp { + nonce, + balance, + storage_root, + code_hash, + } = account; + + let storage_hash_only = PartialTrie::Hash(storage_root); + let storage_trie: &PartialTrie = storage_tries_by_state_key + .get(&key) + .copied() + .unwrap_or(&storage_hash_only); + + assert_eq!(storage_trie.calc_hash(), storage_root, + "In TrieInputs, an account's storage_root didn't match the associated storage trie hash"); + + prover_inputs.push(nibbles.count.into()); + prover_inputs.push(nibbles.packed); + prover_inputs.push(nonce); + prover_inputs.push(balance); + mpt_prover_inputs(storage_trie, prover_inputs, &parse_storage_value); + prover_inputs.push(code_hash.into_uint()); + } + } +} + +fn parse_storage_value(value_rlp: &[u8]) -> Vec { + let value: U256 = rlp::decode(value_rlp).expect("Decoding failed"); + vec![value] +} + +fn empty_nibbles() -> Nibbles { + Nibbles { + count: 0, + packed: U256::zero(), + } +} diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index b6254900..b8ba904f 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -29,23 +29,14 @@ pub(crate) enum Segment { /// Contains all trie data. Tries are stored as immutable, copy-on-write trees, so this is an /// append-only buffer. It is owned by the kernel, so it only lives on context 0. TrieData = 12, - /// The account address associated with the `i`th storage trie. Only lives on context 0. - StorageTrieAddresses = 13, - /// A pointer to the `i`th storage trie within the `TrieData` buffer. Only lives on context 0. - StorageTriePointers = 14, - /// Like `StorageTriePointers`, except that these pointers correspond to the version of each - /// trie at the creation of a given context. This lets us easily revert a context by replacing - /// `StorageTriePointers` with `StorageTrieCheckpointPointers`. - /// See also `StateTrieCheckpointPointer`. - StorageTrieCheckpointPointers = 15, /// A buffer used to store the encodings of a branch node's children. - TrieEncodedChild = 16, + TrieEncodedChild = 13, /// A buffer used to store the lengths of the encodings of a branch node's children. - TrieEncodedChildLen = 17, + TrieEncodedChildLen = 14, } impl Segment { - pub(crate) const COUNT: usize = 18; + pub(crate) const COUNT: usize = 15; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -62,9 +53,6 @@ impl Segment { Self::TxnData, Self::RlpRaw, Self::TrieData, - Self::StorageTrieAddresses, - Self::StorageTriePointers, - Self::StorageTrieCheckpointPointers, Self::TrieEncodedChild, Self::TrieEncodedChildLen, ] @@ -86,9 +74,6 @@ impl Segment { Segment::TxnData => "SEGMENT_TXN_DATA", Segment::RlpRaw => "SEGMENT_RLP_RAW", Segment::TrieData => "SEGMENT_TRIE_DATA", - Segment::StorageTrieAddresses => "SEGMENT_STORAGE_TRIE_ADDRS", - Segment::StorageTriePointers => "SEGMENT_STORAGE_TRIE_PTRS", - Segment::StorageTrieCheckpointPointers => "SEGMENT_STORAGE_TRIE_CHECKPOINT_PTRS", Segment::TrieEncodedChild => "SEGMENT_TRIE_ENCODED_CHILD", Segment::TrieEncodedChildLen => "SEGMENT_TRIE_ENCODED_CHILD_LEN", } @@ -110,9 +95,6 @@ impl Segment { Segment::TxnData => 256, Segment::RlpRaw => 8, Segment::TrieData => 256, - Segment::StorageTrieAddresses => 160, - Segment::StorageTriePointers => 32, - Segment::StorageTrieCheckpointPointers => 32, Segment::TrieEncodedChild => 256, Segment::TrieEncodedChildLen => 6, }