From 4112fddfe8062f9fd35733f0bc9ceb2e98981064 Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:56:51 -0300 Subject: [PATCH] feat(l1): don't store trie nodes if they are already inlined on their parent (#1124) **Motivation** We are currently storing nodes on the DB even if they are already inlined in their parent node. This is not only storage-inefficient but it also needs special handling when verifying proofs or importing trie nodes from other clients (such as in snap sync) as inlined nodes will not be sent separately. This PR aims to solve this issue at `TrieState` level, so that the change is invisible to the main trie logic. The state will skip insertion for inlined node hashes and will decode them instead of fetching from the db upon lookups **Description** * `TrieState::insert` now skips node hashes that represent inlined nodes * `TrieState::get` now decoded the node if it is inlined instead of performing a db lookup Closes None, but is needed in order to validate and integrate output from snap sync requests #184 --- crates/storage/trie/node/branch.rs | 2 +- crates/storage/trie/state.rs | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/storage/trie/node/branch.rs b/crates/storage/trie/node/branch.rs index 15d2d4114..0b42455af 100644 --- a/crates/storage/trie/node/branch.rs +++ b/crates/storage/trie/node/branch.rs @@ -349,7 +349,7 @@ mod test { 1 => leaf { vec![0, 16] => vec![0x34, 0x56, 0x78, 0x9A] }, } }; - let path = Nibbles::from_hex(vec![2]); + let path = Nibbles::from_bytes(&[2]); let value = vec![0x3]; let node = node diff --git a/crates/storage/trie/state.rs b/crates/storage/trie/state.rs index d99bbf472..213e3716d 100644 --- a/crates/storage/trie/state.rs +++ b/crates/storage/trie/state.rs @@ -25,6 +25,10 @@ impl TrieState { /// Retrieves a node based on its hash pub fn get_node(&self, hash: NodeHash) -> Result, TrieError> { + // Decode the node if it is inlined + if let NodeHash::Inline(encoded) = hash { + return Ok(Some(Node::decode_raw(&encoded)?)); + } if let Some(node) = self.cache.get(&hash) { return Ok(Some(node.clone())); }; @@ -36,7 +40,10 @@ impl TrieState { /// Inserts a node pub fn insert_node(&mut self, node: Node, hash: NodeHash) { - self.cache.insert(hash, node); + // Don't insert the node if it is already inlined on the parent + if matches!(hash, NodeHash::Hashed(_)) { + self.cache.insert(hash, node); + } } /// Commits cache changes to DB and clears it