Skip to content

Commit ed13bfc

Browse files
committed
feat(trie): async root intermediate nodes
1 parent 1c20e0e commit ed13bfc

File tree

2 files changed

+54
-19
lines changed

2 files changed

+54
-19
lines changed

crates/trie/parallel/benches/root.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,15 @@ pub fn calculate_state_root(c: &mut Criterion) {
7777
// async root
7878
group.bench_function(BenchmarkId::new("async root", size), |b| {
7979
b.to_async(&runtime).iter_with_setup(
80-
|| AsyncStateRoot::new(view.clone(), blocking_pool.clone(), updated_state.clone()),
80+
|| {
81+
AsyncStateRoot::new(
82+
view.clone(),
83+
blocking_pool.clone(),
84+
Default::default(),
85+
updated_state.clone(),
86+
updated_state.construct_prefix_sets(),
87+
)
88+
},
8189
|calculator| calculator.incremental_root(),
8290
);
8391
});

crates/trie/parallel/src/async_root.rs

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use reth_tasks::pool::BlockingTaskPool;
1212
use reth_trie::{
1313
hashed_cursor::{HashedCursorFactory, HashedPostStateCursorFactory},
1414
node_iter::{TrieElement, TrieNodeIter},
15-
trie_cursor::TrieCursorFactory,
15+
prefix_set::TriePrefixSets,
16+
trie_cursor::{InMemoryTrieCursorFactory, TrieCursorFactory},
1617
updates::TrieUpdates,
1718
walker::TrieWalker,
1819
HashBuilder, HashedPostState, Nibbles, StorageRoot, TrieAccount,
@@ -41,8 +42,12 @@ pub struct AsyncStateRoot<Factory> {
4142
view: ConsistentDbView<Factory>,
4243
/// Blocking task pool.
4344
blocking_pool: BlockingTaskPool,
45+
/// Cached trie nodes.
46+
trie_nodes: TrieUpdates,
4447
/// Changed hashed state.
4548
hashed_state: HashedPostState,
49+
/// A set of prefix sets that have changed.
50+
prefix_sets: TriePrefixSets,
4651
/// Parallel state root metrics.
4752
#[cfg(feature = "metrics")]
4853
metrics: ParallelStateRootMetrics,
@@ -53,12 +58,16 @@ impl<Factory> AsyncStateRoot<Factory> {
5358
pub fn new(
5459
view: ConsistentDbView<Factory>,
5560
blocking_pool: BlockingTaskPool,
61+
trie_nodes: TrieUpdates,
5662
hashed_state: HashedPostState,
63+
prefix_sets: TriePrefixSets,
5764
) -> Self {
5865
Self {
5966
view,
6067
blocking_pool,
68+
trie_nodes,
6169
hashed_state,
70+
prefix_sets,
6271
#[cfg(feature = "metrics")]
6372
metrics: ParallelStateRootMetrics::default(),
6473
}
@@ -86,12 +95,15 @@ where
8695
retain_updates: bool,
8796
) -> Result<(B256, TrieUpdates), AsyncStateRootError> {
8897
let mut tracker = ParallelTrieTracker::default();
89-
let prefix_sets = self.hashed_state.construct_prefix_sets().freeze();
98+
let trie_nodes_sorted = Arc::new(self.trie_nodes.into_sorted());
99+
let hashed_state_sorted = Arc::new(self.hashed_state.into_sorted());
90100
let storage_root_targets = StorageRootTargets::new(
91-
self.hashed_state.accounts.keys().copied(),
92-
prefix_sets.storage_prefix_sets,
101+
self.prefix_sets
102+
.account_prefix_set
103+
.iter()
104+
.map(|nibbles| B256::from_slice(&nibbles.pack())),
105+
self.prefix_sets.storage_prefix_sets,
93106
);
94-
let hashed_state_sorted = Arc::new(self.hashed_state.into_sorted());
95107

96108
// Pre-calculate storage roots async for accounts which were changed.
97109
tracker.set_precomputed_storage_roots(storage_root_targets.len() as u64);
@@ -102,14 +114,18 @@ where
102114
{
103115
let view = self.view.clone();
104116
let hashed_state_sorted = hashed_state_sorted.clone();
117+
let trie_nodes_sorted = trie_nodes_sorted.clone();
105118
#[cfg(feature = "metrics")]
106119
let metrics = self.metrics.storage_trie.clone();
107120
let handle =
108121
self.blocking_pool.spawn_fifo(move || -> Result<_, AsyncStateRootError> {
109-
let provider = view.provider_ro()?;
110-
let trie_cursor_factory = DatabaseTrieCursorFactory::new(provider.tx_ref());
122+
let provider_ro = view.provider_ro()?;
123+
let trie_cursor_factory = InMemoryTrieCursorFactory::new(
124+
DatabaseTrieCursorFactory::new(provider_ro.tx_ref()),
125+
&trie_nodes_sorted,
126+
);
111127
let hashed_state = HashedPostStateCursorFactory::new(
112-
DatabaseHashedCursorFactory::new(provider.tx_ref()),
128+
DatabaseHashedCursorFactory::new(provider_ro.tx_ref()),
113129
&hashed_state_sorted,
114130
);
115131
Ok(StorageRoot::new_hashed(
@@ -129,16 +145,18 @@ where
129145
let mut trie_updates = TrieUpdates::default();
130146

131147
let provider_ro = self.view.provider_ro()?;
132-
let tx = provider_ro.tx_ref();
133-
let trie_cursor_factory = DatabaseTrieCursorFactory::new(tx);
148+
let trie_cursor_factory = InMemoryTrieCursorFactory::new(
149+
DatabaseTrieCursorFactory::new(provider_ro.tx_ref()),
150+
&trie_nodes_sorted,
151+
);
134152
let hashed_cursor_factory = HashedPostStateCursorFactory::new(
135-
DatabaseHashedCursorFactory::new(tx),
153+
DatabaseHashedCursorFactory::new(provider_ro.tx_ref()),
136154
&hashed_state_sorted,
137155
);
138156

139157
let walker = TrieWalker::new(
140158
trie_cursor_factory.account_trie_cursor().map_err(ProviderError::Database)?,
141-
prefix_sets.account_prefix_set,
159+
self.prefix_sets.account_prefix_set,
142160
)
143161
.with_deletions_retained(retain_updates);
144162
let mut account_node_iter = TrieNodeIter::new(
@@ -190,7 +208,7 @@ where
190208
trie_updates.finalize(
191209
account_node_iter.walker,
192210
hash_builder,
193-
prefix_sets.destroyed_accounts,
211+
self.prefix_sets.destroyed_accounts,
194212
);
195213

196214
let stats = tracker.finish();
@@ -290,7 +308,9 @@ mod tests {
290308
AsyncStateRoot::new(
291309
consistent_view.clone(),
292310
blocking_pool.clone(),
293-
HashedPostState::default()
311+
Default::default(),
312+
HashedPostState::default(),
313+
Default::default(),
294314
)
295315
.incremental_root()
296316
.await
@@ -323,11 +343,18 @@ mod tests {
323343
}
324344
}
325345

346+
let prefix_sets = hashed_state.construct_prefix_sets();
326347
assert_eq!(
327-
AsyncStateRoot::new(consistent_view.clone(), blocking_pool.clone(), hashed_state)
328-
.incremental_root()
329-
.await
330-
.unwrap(),
348+
AsyncStateRoot::new(
349+
consistent_view.clone(),
350+
blocking_pool.clone(),
351+
Default::default(),
352+
hashed_state,
353+
prefix_sets
354+
)
355+
.incremental_root()
356+
.await
357+
.unwrap(),
331358
test_utils::state_root(state)
332359
);
333360
}

0 commit comments

Comments
 (0)