@@ -2224,13 +2224,47 @@ where
2224
2224
2225
2225
let exec_time = Instant :: now ( ) ;
2226
2226
2227
- // TODO: create StateRootTask with the receiving end of a channel and
2228
- // pass the sending end of the channel to the state hook.
2229
- let noop_state_hook = |_state : & EvmState | { } ;
2227
+ let persistence_not_in_progress = !self . persistence_state . in_progress ( ) ;
2228
+
2229
+ // TODO: uncomment to use StateRootTask
2230
+
2231
+ // let (state_root_handle, state_hook) = if persistence_not_in_progress {
2232
+ // let consistent_view = ConsistentDbView::new_with_latest_tip(self.provider.clone())?;
2233
+ //
2234
+ // let state_root_config = StateRootConfig::new_from_input(
2235
+ // consistent_view.clone(),
2236
+ // self.compute_trie_input(consistent_view, block.header().parent_hash())
2237
+ // .map_err(ParallelStateRootError::into)?,
2238
+ // );
2239
+ //
2240
+ // let provider_ro = consistent_view.provider_ro()?;
2241
+ // let nodes_sorted = state_root_config.nodes_sorted.clone();
2242
+ // let state_sorted = state_root_config.state_sorted.clone();
2243
+ // let prefix_sets = state_root_config.prefix_sets.clone();
2244
+ // let blinded_provider_factory = ProofBlindedProviderFactory::new(
2245
+ // InMemoryTrieCursorFactory::new(
2246
+ // DatabaseTrieCursorFactory::new(provider_ro.tx_ref()),
2247
+ // &nodes_sorted,
2248
+ // ),
2249
+ // HashedPostStateCursorFactory::new(
2250
+ // DatabaseHashedCursorFactory::new(provider_ro.tx_ref()),
2251
+ // &state_sorted,
2252
+ // ),
2253
+ // prefix_sets,
2254
+ // );
2255
+ //
2256
+ // let state_root_task = StateRootTask::new(state_root_config,
2257
+ // blinded_provider_factory); let state_hook = state_root_task.state_hook();
2258
+ // (Some(state_root_task.spawn(scope)), Box::new(state_hook) as Box<dyn OnStateHook>)
2259
+ // } else {
2260
+ // (None, Box::new(|_state: &EvmState| {}) as Box<dyn OnStateHook>)
2261
+ // };
2262
+ let state_hook = Box :: new ( |_state : & EvmState | { } ) ;
2263
+
2230
2264
let output = self . metrics . executor . execute_metered (
2231
2265
executor,
2232
2266
( & block, U256 :: MAX ) . into ( ) ,
2233
- Box :: new ( noop_state_hook ) ,
2267
+ state_hook ,
2234
2268
) ?;
2235
2269
2236
2270
trace ! ( target: "engine::tree" , elapsed=?exec_time. elapsed( ) , ?block_number, "Executed block" ) ;
@@ -2253,33 +2287,47 @@ where
2253
2287
2254
2288
trace ! ( target: "engine::tree" , block=?sealed_block. num_hash( ) , "Calculating block state root" ) ;
2255
2289
let root_time = Instant :: now ( ) ;
2256
- let mut state_root_result = None ;
2257
-
2258
- // TODO: switch to calculate state root using `StateRootTask`.
2259
2290
2260
2291
// We attempt to compute state root in parallel if we are currently not persisting anything
2261
2292
// to database. This is safe, because the database state cannot change until we
2262
2293
// finish parallel computation. It is important that nothing is being persisted as
2263
2294
// we are computing in parallel, because we initialize a different database transaction
2264
2295
// per thread and it might end up with a different view of the database.
2265
- let persistence_in_progress = self . persistence_state . in_progress ( ) ;
2266
- if !persistence_in_progress {
2267
- state_root_result = match self
2268
- . compute_state_root_parallel ( block. header ( ) . parent_hash ( ) , & hashed_state)
2269
- {
2270
- Ok ( ( state_root, trie_output) ) => Some ( ( state_root, trie_output) ) ,
2296
+ let state_root_result = if persistence_not_in_progress {
2297
+ // TODO: uncomment to use StateRootTask
2298
+
2299
+ // if let Some(state_root_handle) = state_root_handle {
2300
+ // match state_root_handle.wait_for_result() {
2301
+ // Ok((task_state_root, task_trie_updates)) => {
2302
+ // info!(
2303
+ // target: "engine::tree",
2304
+ // block = ?sealed_block.num_hash(),
2305
+ // ?task_state_root,
2306
+ // "State root task finished"
2307
+ // );
2308
+ // }
2309
+ // Err(error) => {
2310
+ // info!(target: "engine::tree", ?error, "Failed to wait for state root task
2311
+ // result"); }
2312
+ // }
2313
+ // }
2314
+
2315
+ match self . compute_state_root_parallel ( block. header ( ) . parent_hash ( ) , & hashed_state) {
2316
+ Ok ( result) => Some ( result) ,
2271
2317
Err ( ParallelStateRootError :: Provider ( ProviderError :: ConsistentView ( error) ) ) => {
2272
2318
debug ! ( target: "engine" , %error, "Parallel state root computation failed consistency check, falling back" ) ;
2273
2319
None
2274
2320
}
2275
2321
Err ( error) => return Err ( InsertBlockErrorKindTwo :: Other ( Box :: new ( error) ) ) ,
2276
- } ;
2277
- }
2322
+ }
2323
+ } else {
2324
+ None
2325
+ } ;
2278
2326
2279
2327
let ( state_root, trie_output) = if let Some ( result) = state_root_result {
2280
2328
result
2281
2329
} else {
2282
- debug ! ( target: "engine::tree" , block=?sealed_block. num_hash( ) , persistence_in_progress , "Failed to compute state root in parallel" ) ;
2330
+ debug ! ( target: "engine::tree" , block=?sealed_block. num_hash( ) , ?persistence_not_in_progress , "Failed to compute state root in parallel" ) ;
2283
2331
state_provider. state_root_with_updates ( hashed_state. clone ( ) ) ?
2284
2332
} ;
2285
2333
@@ -2344,14 +2392,25 @@ where
2344
2392
parent_hash : B256 ,
2345
2393
hashed_state : & HashedPostState ,
2346
2394
) -> Result < ( B256 , TrieUpdates ) , ParallelStateRootError > {
2347
- // TODO: when we switch to calculate state root using `StateRootTask` this
2348
- // method can be still useful to calculate the required `TrieInput` to
2349
- // create the task.
2350
2395
let consistent_view = ConsistentDbView :: new_with_latest_tip ( self . provider . clone ( ) ) ?;
2396
+
2397
+ let mut input = self . compute_trie_input ( consistent_view. clone ( ) , parent_hash) ?;
2398
+ // Extend with block we are validating root for.
2399
+ input. append_ref ( hashed_state) ;
2400
+
2401
+ ParallelStateRoot :: new ( consistent_view, input) . incremental_root_with_updates ( )
2402
+ }
2403
+
2404
+ /// Computes the trie input at the provided parent hash.
2405
+ fn compute_trie_input (
2406
+ & self ,
2407
+ consistent_view : ConsistentDbView < P > ,
2408
+ parent_hash : B256 ,
2409
+ ) -> Result < TrieInput , ParallelStateRootError > {
2351
2410
let mut input = TrieInput :: default ( ) ;
2352
2411
2353
2412
if let Some ( ( historical, blocks) ) = self . state . tree_state . blocks_by_hash ( parent_hash) {
2354
- debug ! ( target: "engine::tree" , %parent_hash, %historical, "Calculating state root in parallel, parent found in memory" ) ;
2413
+ debug ! ( target: "engine::tree" , %parent_hash, %historical, "Parent found in memory" ) ;
2355
2414
// Retrieve revert state for historical block.
2356
2415
let revert_state = consistent_view. revert_state ( historical) ?;
2357
2416
input. append ( revert_state) ;
@@ -2362,15 +2421,12 @@ where
2362
2421
}
2363
2422
} else {
2364
2423
// The block attaches to canonical persisted parent.
2365
- debug ! ( target: "engine::tree" , %parent_hash, "Calculating state root in parallel, parent found in disk" ) ;
2424
+ debug ! ( target: "engine::tree" , %parent_hash, "Parent found on disk" ) ;
2366
2425
let revert_state = consistent_view. revert_state ( parent_hash) ?;
2367
2426
input. append ( revert_state) ;
2368
2427
}
2369
2428
2370
- // Extend with block we are validating root for.
2371
- input. append_ref ( hashed_state) ;
2372
-
2373
- ParallelStateRoot :: new ( consistent_view, input) . incremental_root_with_updates ( )
2429
+ Ok ( input)
2374
2430
}
2375
2431
2376
2432
/// Handles an error that occurred while inserting a block.
@@ -2648,7 +2704,7 @@ mod tests {
2648
2704
use reth_primitives:: { Block , BlockExt , EthPrimitives } ;
2649
2705
use reth_provider:: test_utils:: MockEthProvider ;
2650
2706
use reth_rpc_types_compat:: engine:: { block_to_payload_v1, payload:: block_to_payload_v3} ;
2651
- use reth_trie:: updates:: TrieUpdates ;
2707
+ use reth_trie:: { updates:: TrieUpdates , HashedPostState } ;
2652
2708
use std:: {
2653
2709
str:: FromStr ,
2654
2710
sync:: mpsc:: { channel, Sender } ,
0 commit comments