Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(trie): avoid update reallocation & track wiped #12929

Merged
merged 2 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions crates/trie/sparse/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ pub struct SparseStateTrie {
storages: HashMap<B256, SparseTrie>,
/// Collection of revealed account and storage keys.
revealed: HashMap<B256, HashSet<B256>>,
/// Collection of addresses that had their storage tries wiped.
wiped_storages: HashSet<B256>,
/// Flag indicating whether trie updates should be retained.
retain_updates: bool,
/// Reusable buffer for RLP encoding of trie accounts.
Expand All @@ -36,7 +34,6 @@ impl Default for SparseStateTrie {
state: Default::default(),
storages: Default::default(),
revealed: Default::default(),
wiped_storages: Default::default(),
retain_updates: false,
account_rlp_buf: Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE),
}
Expand Down Expand Up @@ -275,9 +272,10 @@ impl SparseStateTrie {

/// Wipe the storage trie at the provided address.
pub fn wipe_storage(&mut self, address: B256) -> SparseStateTrieResult<()> {
let Some(trie) = self.storages.get_mut(&address) else { return Ok(()) };
self.wiped_storages.insert(address);
trie.wipe().map_err(Into::into)
if let Some(trie) = self.storages.get_mut(&address) {
trie.wipe()?;
}
Ok(())
}

/// Calculates the hashes of the nodes below the provided level.
Expand All @@ -302,18 +300,18 @@ impl SparseStateTrie {
self.state.as_revealed_mut().map(|state| {
let updates = state.take_updates();
TrieUpdates {
account_nodes: HashMap::from_iter(updates.updated_nodes),
removed_nodes: HashSet::from_iter(updates.removed_nodes),
account_nodes: updates.updated_nodes,
removed_nodes: updates.removed_nodes,
storage_tries: self
.storages
.iter_mut()
.map(|(address, trie)| {
let trie = trie.as_revealed_mut().unwrap();
let updates = trie.take_updates();
let updates = StorageTrieUpdates {
is_deleted: self.wiped_storages.contains(address),
storage_nodes: HashMap::from_iter(updates.updated_nodes),
removed_nodes: HashSet::from_iter(updates.removed_nodes),
is_deleted: updates.wiped,
storage_nodes: updates.updated_nodes,
removed_nodes: updates.removed_nodes,
};
(*address, updates)
})
Expand Down
14 changes: 12 additions & 2 deletions crates/trie/sparse/src/trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ pub struct RevealedSparseTrie {
prefix_set: PrefixSetMut,
/// Reusable buffer for RLP encoding of nodes.
rlp_buf: Vec<u8>,
/// Retained trie updates.
updates: Option<SparseTrieUpdates>,
}

Expand Down Expand Up @@ -607,8 +608,10 @@ impl RevealedSparseTrie {

/// Wipe the trie, removing all values and nodes, and replacing the root with an empty node.
pub fn wipe(&mut self) {
let updates_retained = self.updates.is_some();
*self = Self::default();
self.prefix_set = PrefixSetMut::all();
self.updates = updates_retained.then(SparseTrieUpdates::wiped);
}

/// Return the root of the sparse trie.
Expand Down Expand Up @@ -1030,12 +1033,18 @@ impl RlpNodeBuffers {
pub struct SparseTrieUpdates {
pub(crate) updated_nodes: HashMap<Nibbles, BranchNodeCompact>,
pub(crate) removed_nodes: HashSet<Nibbles>,
pub(crate) wiped: bool,
}

impl SparseTrieUpdates {
/// Create new wiped sparse trie updates.
pub fn wiped() -> Self {
Self { wiped: true, ..Default::default() }
}
}

#[cfg(test)]
mod tests {
use std::collections::BTreeMap;

use super::*;
use alloy_primitives::{map::HashSet, U256};
use alloy_rlp::Encodable;
Expand All @@ -1057,6 +1066,7 @@ mod tests {
proof::{ProofNodes, ProofRetainer},
HashBuilder,
};
use std::collections::BTreeMap;

/// Pad nibbles to the length of a B256 hash with zeros on the left.
fn pad_nibbles_left(nibbles: Nibbles) -> Nibbles {
Expand Down
Loading