1
1
//! State root task related functionality.
2
2
3
- use alloy_primitives:: map:: HashSet ;
3
+ use alloy_primitives:: { map:: HashSet , Address } ;
4
4
use derive_more:: derive:: Deref ;
5
5
use rayon:: iter:: { ParallelBridge , ParallelIterator } ;
6
- use reth_errors:: ProviderError ;
6
+ use reth_errors:: { ProviderError , ProviderResult } ;
7
7
use reth_evm:: system_calls:: OnStateHook ;
8
8
use reth_provider:: {
9
9
providers:: ConsistentDbView , BlockReader , DBProvider , DatabaseProviderFactory ,
@@ -108,6 +108,8 @@ impl<Factory> StateRootConfig<Factory> {
108
108
#[ derive( Debug ) ]
109
109
#[ allow( dead_code) ]
110
110
pub enum StateRootMessage < BPF : BlindedProviderFactory > {
111
+ /// Prefetch proof targets
112
+ PrefetchProofs ( HashSet < Address > ) ,
111
113
/// New state update from transaction execution
112
114
StateUpdate ( EvmState ) ,
113
115
/// Proof calculation completed for a specific state update
@@ -340,6 +342,29 @@ where
340
342
}
341
343
}
342
344
345
+ /// Handles request for proof prefetch.
346
+ fn on_prefetch_proof (
347
+ scope : & rayon:: Scope < ' env > ,
348
+ config : StateRootConfig < Factory > ,
349
+ targets : HashSet < Address > ,
350
+ fetched_proof_targets : & mut MultiProofTargets ,
351
+ proof_sequence_number : u64 ,
352
+ state_root_message_sender : Sender < StateRootMessage < BPF > > ,
353
+ ) {
354
+ let proof_targets =
355
+ targets. into_iter ( ) . map ( |address| ( keccak256 ( address) , Default :: default ( ) ) ) . collect ( ) ;
356
+ extend_multi_proof_targets_ref ( fetched_proof_targets, & proof_targets) ;
357
+
358
+ Self :: spawn_multiproof (
359
+ scope,
360
+ config,
361
+ Default :: default ( ) ,
362
+ proof_targets,
363
+ proof_sequence_number,
364
+ state_root_message_sender,
365
+ ) ;
366
+ }
367
+
343
368
/// Handles state updates.
344
369
///
345
370
/// Returns proof targets derived from the state update.
@@ -356,46 +381,39 @@ where
356
381
let proof_targets = get_proof_targets ( & hashed_state_update, fetched_proof_targets) ;
357
382
extend_multi_proof_targets_ref ( fetched_proof_targets, & proof_targets) ;
358
383
384
+ Self :: spawn_multiproof (
385
+ scope,
386
+ config,
387
+ hashed_state_update,
388
+ proof_targets,
389
+ proof_sequence_number,
390
+ state_root_message_sender,
391
+ ) ;
392
+ }
393
+
394
+ fn spawn_multiproof (
395
+ scope : & rayon:: Scope < ' env > ,
396
+ config : StateRootConfig < Factory > ,
397
+ hashed_state_update : HashedPostState ,
398
+ proof_targets : MultiProofTargets ,
399
+ proof_sequence_number : u64 ,
400
+ state_root_message_sender : Sender < StateRootMessage < BPF > > ,
401
+ ) {
359
402
// Dispatch proof gathering for this state update
360
- scope. spawn ( move |_| {
361
- let provider = match config. consistent_view . provider_ro ( ) {
362
- Ok ( provider) => provider,
363
- Err ( error) => {
364
- error ! ( target: "engine::root" , ?error, "Could not get provider" ) ;
365
- let _ = state_root_message_sender
366
- . send ( StateRootMessage :: ProofCalculationError ( error) ) ;
367
- return ;
368
- }
369
- } ;
370
-
371
- // TODO: replace with parallel proof
372
- let result = Proof :: from_tx ( provider. tx_ref ( ) )
373
- . with_trie_cursor_factory ( InMemoryTrieCursorFactory :: new (
374
- DatabaseTrieCursorFactory :: new ( provider. tx_ref ( ) ) ,
375
- & config. nodes_sorted ,
376
- ) )
377
- . with_hashed_cursor_factory ( HashedPostStateCursorFactory :: new (
378
- DatabaseHashedCursorFactory :: new ( provider. tx_ref ( ) ) ,
379
- & config. state_sorted ,
380
- ) )
381
- . with_prefix_sets_mut ( config. prefix_sets . as_ref ( ) . clone ( ) )
382
- . with_branch_node_hash_masks ( true )
383
- . multiproof ( proof_targets. clone ( ) ) ;
384
- match result {
385
- Ok ( proof) => {
386
- let _ = state_root_message_sender. send ( StateRootMessage :: ProofCalculated (
387
- Box :: new ( ProofCalculated {
388
- state_update : hashed_state_update,
389
- targets : proof_targets,
390
- proof,
391
- sequence_number : proof_sequence_number,
392
- } ) ,
393
- ) ) ;
394
- }
395
- Err ( error) => {
396
- let _ = state_root_message_sender
397
- . send ( StateRootMessage :: ProofCalculationError ( error. into ( ) ) ) ;
398
- }
403
+ scope. spawn ( move |_| match calculate_multiproof ( config, proof_targets. clone ( ) ) {
404
+ Ok ( proof) => {
405
+ let _ = state_root_message_sender. send ( StateRootMessage :: ProofCalculated (
406
+ Box :: new ( ProofCalculated {
407
+ state_update : hashed_state_update,
408
+ targets : proof_targets,
409
+ proof,
410
+ sequence_number : proof_sequence_number,
411
+ } ) ,
412
+ ) ) ;
413
+ }
414
+ Err ( error) => {
415
+ let _ =
416
+ state_root_message_sender. send ( StateRootMessage :: ProofCalculationError ( error) ) ;
399
417
}
400
418
} ) ;
401
419
}
@@ -486,6 +504,21 @@ where
486
504
loop {
487
505
match self . rx . recv ( ) {
488
506
Ok ( message) => match message {
507
+ StateRootMessage :: PrefetchProofs ( targets) => {
508
+ debug ! (
509
+ target: "engine::root" ,
510
+ len = targets. len( ) ,
511
+ "Prefetching proofs"
512
+ ) ;
513
+ Self :: on_prefetch_proof (
514
+ scope,
515
+ self . config . clone ( ) ,
516
+ targets,
517
+ & mut self . fetched_proof_targets ,
518
+ self . proof_sequencer . next_sequence ( ) ,
519
+ self . tx . clone ( ) ,
520
+ ) ;
521
+ }
489
522
StateRootMessage :: StateUpdate ( update) => {
490
523
if updates_received == 0 {
491
524
first_update_time = Some ( Instant :: now ( ) ) ;
@@ -681,6 +714,31 @@ fn get_proof_targets(
681
714
targets
682
715
}
683
716
717
+ /// Calculate multiproof for the targets.
718
+ #[ inline]
719
+ fn calculate_multiproof < Factory > (
720
+ config : StateRootConfig < Factory > ,
721
+ proof_targets : MultiProofTargets ,
722
+ ) -> ProviderResult < MultiProof >
723
+ where
724
+ Factory : DatabaseProviderFactory < Provider : BlockReader > + StateCommitmentProvider ,
725
+ {
726
+ let provider = config. consistent_view . provider_ro ( ) ?;
727
+
728
+ Ok ( Proof :: from_tx ( provider. tx_ref ( ) )
729
+ . with_trie_cursor_factory ( InMemoryTrieCursorFactory :: new (
730
+ DatabaseTrieCursorFactory :: new ( provider. tx_ref ( ) ) ,
731
+ & config. nodes_sorted ,
732
+ ) )
733
+ . with_hashed_cursor_factory ( HashedPostStateCursorFactory :: new (
734
+ DatabaseHashedCursorFactory :: new ( provider. tx_ref ( ) ) ,
735
+ & config. state_sorted ,
736
+ ) )
737
+ . with_prefix_sets_mut ( config. prefix_sets . as_ref ( ) . clone ( ) )
738
+ . with_branch_node_hash_masks ( true )
739
+ . multiproof ( proof_targets) ?)
740
+ }
741
+
684
742
/// Updates the sparse trie with the given proofs and state, and returns the updated trie and the
685
743
/// time it took.
686
744
fn update_sparse_trie <
0 commit comments