perf(trie): avoid clearing already-cached sparse trie (#21702)

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Matthias Seitz
2026-02-02 14:03:07 +01:00
committed by GitHub
parent 1592e51d34
commit 102a6944ba
3 changed files with 8 additions and 51 deletions

View File

@@ -39,7 +39,7 @@ use reth_trie_parallel::{
proof_task::{ProofTaskCtx, ProofWorkerHandle},
root::ParallelStateRootError,
};
use reth_trie_sparse::{ClearedSparseStateTrie, RevealableSparseTrie, SparseStateTrie};
use reth_trie_sparse::{RevealableSparseTrie, SparseStateTrie};
use reth_trie_sparse_parallel::{ParallelSparseTrie, ParallelismThresholds};
use std::{
collections::BTreeMap,
@@ -552,11 +552,11 @@ where
sparse_state_trie,
))
} else {
SpawnedSparseTrieTask::Cached(SparseTrieCacheTask::new_with_cleared_trie(
SpawnedSparseTrieTask::Cached(SparseTrieCacheTask::new_with_trie(
from_multi_proof,
proof_worker_handle,
trie_metrics.clone(),
ClearedSparseStateTrie::from_state_trie(sparse_state_trie),
sparse_state_trie,
))
};

View File

@@ -26,8 +26,7 @@ use reth_trie_parallel::{
use reth_trie_sparse::{
errors::{SparseStateTrieResult, SparseTrieErrorKind},
provider::{TrieNodeProvider, TrieNodeProviderFactory},
ClearedSparseStateTrie, LeafUpdate, SerialSparseTrie, SparseStateTrie, SparseTrie,
SparseTrieExt,
LeafUpdate, SerialSparseTrie, SparseStateTrie, SparseTrie, SparseTrieExt,
};
use revm_primitives::{hash_map::Entry, B256Map};
use smallvec::SmallVec;
@@ -251,12 +250,12 @@ where
A: SparseTrieExt + Default,
S: SparseTrieExt + Default + Clone,
{
/// Creates a new sparse trie, pre-populating with a [`ClearedSparseStateTrie`].
pub(super) fn new_with_cleared_trie(
/// Creates a new sparse trie, pre-populating with an existing [`SparseStateTrie`].
pub(super) fn new_with_trie(
updates: CrossbeamReceiver<MultiProofMessage>,
proof_worker_handle: ProofWorkerHandle,
metrics: MultiProofTaskMetrics,
sparse_state_trie: ClearedSparseStateTrie<A, S>,
sparse_state_trie: SparseStateTrie<A, S>,
) -> Self {
let (proof_result_tx, proof_result_rx) = crossbeam_channel::unbounded();
Self {
@@ -264,7 +263,7 @@ where
proof_result_rx,
updates,
proof_worker_handle,
trie: sparse_state_trie.into_inner(),
trie: sparse_state_trie,
account_updates: Default::default(),
storage_updates: Default::default(),
pending_account_updates: Default::default(),

View File

@@ -23,48 +23,6 @@ use reth_trie_common::{
use tracing::debug;
use tracing::{instrument, trace};
/// Provides type-safe re-use of cleared [`SparseStateTrie`]s, which helps to save allocations
/// across payload runs.
#[derive(Debug)]
pub struct ClearedSparseStateTrie<
A = SerialSparseTrie, // Account trie implementation
S = SerialSparseTrie, // Storage trie implementation
>(SparseStateTrie<A, S>);
impl<A, S> ClearedSparseStateTrie<A, S>
where
A: SparseTrieTrait,
S: SparseTrieTrait,
{
/// Creates a [`ClearedSparseStateTrie`] by clearing all the existing internal state of a
/// [`SparseStateTrie`] and then storing that instance for later re-use.
pub fn from_state_trie(mut trie: SparseStateTrie<A, S>) -> Self {
trie.state.clear();
trie.revealed_account_paths.clear();
trie.storage.clear();
trie.account_rlp_buf.clear();
Self(trie)
}
/// Returns the cleared [`SparseStateTrie`], consuming this instance.
pub fn into_inner(self) -> SparseStateTrie<A, S> {
self.0
}
}
impl<A, S> ClearedSparseStateTrie<A, S>
where
A: SparseTrieTrait + SparseTrieExt + Default,
S: SparseTrieTrait + SparseTrieExt + Default + Clone,
{
/// Shrink the cleared sparse trie's capacity to the given node and value size.
///
/// Delegates to the inner `SparseStateTrie::shrink_to`.
pub fn shrink_to(&mut self, max_nodes: usize, max_values: usize) {
self.0.shrink_to(max_nodes, max_values);
}
}
#[derive(Debug)]
/// Sparse state trie representing lazy-loaded Ethereum state trie.
pub struct SparseStateTrie<