From 02965b06dcafb9f5ef0be1d693550d6a989e0be8 Mon Sep 17 00:00:00 2001 From: SDartayet Date: Mon, 7 Jul 2025 12:20:26 -0300 Subject: [PATCH 1/4] Added reusable buffer --- crates/common/trie/node.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/common/trie/node.rs b/crates/common/trie/node.rs index 8818c54f8a..03a5d29fde 100644 --- a/crates/common/trie/node.rs +++ b/crates/common/trie/node.rs @@ -51,23 +51,28 @@ impl NodeRef { } } - pub fn commit(&mut self, acc: &mut Vec<(NodeHash, Vec)>) -> NodeHash { + pub fn commit( + &mut self, + acc: &mut Vec<(NodeHash, Vec)>, + encoding_buffer: &mut Vec, + ) -> NodeHash { match *self { NodeRef::Node(ref mut node, ref mut hash) => { match Arc::make_mut(node) { Node::Branch(node) => { for node in &mut node.choices { - node.commit(acc); + node.commit(acc, encoding_buffer); } } Node::Extension(node) => { - node.child.commit(acc); + node.child.commit(acc, encoding_buffer); } Node::Leaf(_) => {} } let hash = hash.get_or_init(|| node.compute_hash()); - acc.push((*hash, node.encode_to_vec())); + node.encode(encoding_buffer); + acc.push((*hash, encoding_buffer.drain(..).as_slice().to_vec())); let hash = *hash; *self = hash.into(); From c7c81f858a759fe6e073a8563e48fe46642a9379 Mon Sep 17 00:00:00 2001 From: SDartayet Date: Mon, 7 Jul 2025 12:59:53 -0300 Subject: [PATCH 2/4] Minor fixes --- crates/common/trie/trie.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/common/trie/trie.rs b/crates/common/trie/trie.rs index 7011a3d144..dc299a3282 100644 --- a/crates/common/trie/trie.rs +++ b/crates/common/trie/trie.rs @@ -176,7 +176,8 @@ impl Trie { pub fn commit(&mut self) -> Result<(), TrieError> { if self.root.is_valid() { let mut acc = Vec::new(); - self.root.commit(&mut acc); + let mut encoding_buffer = Vec::new(); + self.root.commit(&mut acc, &mut encoding_buffer); self.db.put_batch(acc)?; // we'll try to avoid calling this for every commit } @@ -188,7 +189,8 @@ impl Trie { pub fn commit_without_storing(&mut self) -> Vec { let mut acc = Vec::new(); if self.root.is_valid() { - self.root.commit(&mut acc); + let mut encoding_buffer = Vec::new(); + self.root.commit(&mut acc, &mut encoding_buffer); } acc From d9de39c9c75fd493d6e2cc2c98005807e6a45c39 Mon Sep 17 00:00:00 2001 From: SDartayet Date: Mon, 7 Jul 2025 18:33:15 -0300 Subject: [PATCH 3/4] Changed way buffer is reused --- crates/common/trie/node.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/common/trie/node.rs b/crates/common/trie/node.rs index 03a5d29fde..edf82b1602 100644 --- a/crates/common/trie/node.rs +++ b/crates/common/trie/node.rs @@ -51,10 +51,10 @@ impl NodeRef { } } - pub fn commit( + pub fn commit<'a>( &mut self, - acc: &mut Vec<(NodeHash, Vec)>, - encoding_buffer: &mut Vec, + acc: &mut Vec<(NodeHash, (usize, usize))>, + encoding_buffer: &'a mut Vec, ) -> NodeHash { match *self { NodeRef::Node(ref mut node, ref mut hash) => { @@ -71,8 +71,10 @@ impl NodeRef { } let hash = hash.get_or_init(|| node.compute_hash()); + let new_encode_start = encoding_buffer.len(); node.encode(encoding_buffer); - acc.push((*hash, encoding_buffer.drain(..).as_slice().to_vec())); + let new_encode_end = encoding_buffer.len(); + acc.push((*hash, (new_encode_start, new_encode_end))); let hash = *hash; *self = hash.into(); From 278236979ce68bb7c1353002b45aa13078373f17 Mon Sep 17 00:00:00 2001 From: SDartayet Date: Thu, 10 Jul 2025 15:25:05 -0300 Subject: [PATCH 4/4] Tried new approach --- crates/common/trie/node.rs | 19 ++++++++++--------- crates/common/trie/trie.rs | 20 ++++++++++++++------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/crates/common/trie/node.rs b/crates/common/trie/node.rs index edf82b1602..183a6bd463 100644 --- a/crates/common/trie/node.rs +++ b/crates/common/trie/node.rs @@ -4,6 +4,7 @@ mod leaf; use std::{ array, + collections::btree_map::Range, sync::{Arc, OnceLock}, }; @@ -51,30 +52,30 @@ impl NodeRef { } } - pub fn commit<'a>( + pub fn commit( &mut self, - acc: &mut Vec<(NodeHash, (usize, usize))>, - encoding_buffer: &'a mut Vec, + buffer: &mut Vec, + acc: &mut Vec<(NodeHash, std::ops::Range)>, ) -> NodeHash { match *self { NodeRef::Node(ref mut node, ref mut hash) => { match Arc::make_mut(node) { Node::Branch(node) => { for node in &mut node.choices { - node.commit(acc, encoding_buffer); + node.commit(buffer, acc); } } Node::Extension(node) => { - node.child.commit(acc, encoding_buffer); + node.child.commit(buffer, acc); } Node::Leaf(_) => {} } let hash = hash.get_or_init(|| node.compute_hash()); - let new_encode_start = encoding_buffer.len(); - node.encode(encoding_buffer); - let new_encode_end = encoding_buffer.len(); - acc.push((*hash, (new_encode_start, new_encode_end))); + let first = buffer.len(); + node.encode(buffer); + let last = buffer.len(); + acc.push((*hash, (first..last))); let hash = *hash; *self = hash.into(); diff --git a/crates/common/trie/trie.rs b/crates/common/trie/trie.rs index dc299a3282..27e3e28f3d 100644 --- a/crates/common/trie/trie.rs +++ b/crates/common/trie/trie.rs @@ -176,9 +176,13 @@ impl Trie { pub fn commit(&mut self) -> Result<(), TrieError> { if self.root.is_valid() { let mut acc = Vec::new(); - let mut encoding_buffer = Vec::new(); - self.root.commit(&mut acc, &mut encoding_buffer); - self.db.put_batch(acc)?; // we'll try to avoid calling this for every commit + let mut buffer = Vec::new(); + self.root.commit(&mut buffer, &mut acc); + let updates: Vec<(NodeHash, Vec)> = acc + .iter() + .map(|(hash, range)| (*hash, buffer[range.clone()].to_vec())) + .collect(); + self.db.put_batch(updates)?; // we'll try to avoid calling this for every commit } Ok(()) @@ -188,12 +192,16 @@ impl Trie { /// Nodes are given with their hash pre-calculated. pub fn commit_without_storing(&mut self) -> Vec { let mut acc = Vec::new(); + let mut buffer = Vec::new(); if self.root.is_valid() { - let mut encoding_buffer = Vec::new(); - self.root.commit(&mut acc, &mut encoding_buffer); + self.root.commit(&mut buffer, &mut acc); } - acc + let updates: Vec<(NodeHash, Vec)> = acc + .iter() + .map(|(hash, range)| (*hash, buffer[range.clone()].to_vec())) + .collect(); + updates } /// Obtain a merkle proof for the given path.