@@ -12,7 +12,8 @@ use reth_tasks::pool::BlockingTaskPool;
12
12
use reth_trie:: {
13
13
hashed_cursor:: { HashedCursorFactory , HashedPostStateCursorFactory } ,
14
14
node_iter:: { TrieElement , TrieNodeIter } ,
15
- trie_cursor:: TrieCursorFactory ,
15
+ prefix_set:: TriePrefixSets ,
16
+ trie_cursor:: { InMemoryTrieCursorFactory , TrieCursorFactory } ,
16
17
updates:: TrieUpdates ,
17
18
walker:: TrieWalker ,
18
19
HashBuilder , HashedPostState , Nibbles , StorageRoot , TrieAccount ,
@@ -41,8 +42,12 @@ pub struct AsyncStateRoot<Factory> {
41
42
view : ConsistentDbView < Factory > ,
42
43
/// Blocking task pool.
43
44
blocking_pool : BlockingTaskPool ,
45
+ /// Cached trie nodes.
46
+ trie_nodes : TrieUpdates ,
44
47
/// Changed hashed state.
45
48
hashed_state : HashedPostState ,
49
+ /// A set of prefix sets that have changed.
50
+ prefix_sets : TriePrefixSets ,
46
51
/// Parallel state root metrics.
47
52
#[ cfg( feature = "metrics" ) ]
48
53
metrics : ParallelStateRootMetrics ,
@@ -53,12 +58,16 @@ impl<Factory> AsyncStateRoot<Factory> {
53
58
pub fn new (
54
59
view : ConsistentDbView < Factory > ,
55
60
blocking_pool : BlockingTaskPool ,
61
+ trie_nodes : TrieUpdates ,
56
62
hashed_state : HashedPostState ,
63
+ prefix_sets : TriePrefixSets ,
57
64
) -> Self {
58
65
Self {
59
66
view,
60
67
blocking_pool,
68
+ trie_nodes,
61
69
hashed_state,
70
+ prefix_sets,
62
71
#[ cfg( feature = "metrics" ) ]
63
72
metrics : ParallelStateRootMetrics :: default ( ) ,
64
73
}
@@ -86,12 +95,15 @@ where
86
95
retain_updates : bool ,
87
96
) -> Result < ( B256 , TrieUpdates ) , AsyncStateRootError > {
88
97
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 ( ) ) ;
90
100
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 ,
93
106
) ;
94
- let hashed_state_sorted = Arc :: new ( self . hashed_state . into_sorted ( ) ) ;
95
107
96
108
// Pre-calculate storage roots async for accounts which were changed.
97
109
tracker. set_precomputed_storage_roots ( storage_root_targets. len ( ) as u64 ) ;
@@ -102,14 +114,18 @@ where
102
114
{
103
115
let view = self . view . clone ( ) ;
104
116
let hashed_state_sorted = hashed_state_sorted. clone ( ) ;
117
+ let trie_nodes_sorted = trie_nodes_sorted. clone ( ) ;
105
118
#[ cfg( feature = "metrics" ) ]
106
119
let metrics = self . metrics . storage_trie . clone ( ) ;
107
120
let handle =
108
121
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
+ ) ;
111
127
let hashed_state = HashedPostStateCursorFactory :: new (
112
- DatabaseHashedCursorFactory :: new ( provider . tx_ref ( ) ) ,
128
+ DatabaseHashedCursorFactory :: new ( provider_ro . tx_ref ( ) ) ,
113
129
& hashed_state_sorted,
114
130
) ;
115
131
Ok ( StorageRoot :: new_hashed (
@@ -129,16 +145,18 @@ where
129
145
let mut trie_updates = TrieUpdates :: default ( ) ;
130
146
131
147
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
+ ) ;
134
152
let hashed_cursor_factory = HashedPostStateCursorFactory :: new (
135
- DatabaseHashedCursorFactory :: new ( tx ) ,
153
+ DatabaseHashedCursorFactory :: new ( provider_ro . tx_ref ( ) ) ,
136
154
& hashed_state_sorted,
137
155
) ;
138
156
139
157
let walker = TrieWalker :: new (
140
158
trie_cursor_factory. account_trie_cursor ( ) . map_err ( ProviderError :: Database ) ?,
141
- prefix_sets. account_prefix_set ,
159
+ self . prefix_sets . account_prefix_set ,
142
160
)
143
161
. with_deletions_retained ( retain_updates) ;
144
162
let mut account_node_iter = TrieNodeIter :: new (
@@ -190,7 +208,7 @@ where
190
208
trie_updates. finalize (
191
209
account_node_iter. walker ,
192
210
hash_builder,
193
- prefix_sets. destroyed_accounts ,
211
+ self . prefix_sets . destroyed_accounts ,
194
212
) ;
195
213
196
214
let stats = tracker. finish ( ) ;
@@ -290,7 +308,9 @@ mod tests {
290
308
AsyncStateRoot :: new(
291
309
consistent_view. clone( ) ,
292
310
blocking_pool. clone( ) ,
293
- HashedPostState :: default ( )
311
+ Default :: default ( ) ,
312
+ HashedPostState :: default ( ) ,
313
+ Default :: default ( ) ,
294
314
)
295
315
. incremental_root( )
296
316
. await
@@ -323,11 +343,18 @@ mod tests {
323
343
}
324
344
}
325
345
346
+ let prefix_sets = hashed_state. construct_prefix_sets ( ) ;
326
347
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( ) ,
331
358
test_utils:: state_root( state)
332
359
) ;
333
360
}
0 commit comments