11//! State root task related functionality.
22
3- use alloy_primitives:: map:: HashSet ;
3+ use alloy_primitives:: { map:: HashSet , Address } ;
44use derive_more:: derive:: Deref ;
55use rayon:: iter:: { ParallelBridge , ParallelIterator } ;
6- use reth_errors:: ProviderError ;
6+ use reth_errors:: { ProviderError , ProviderResult } ;
77use reth_evm:: system_calls:: OnStateHook ;
88use reth_provider:: {
99 providers:: ConsistentDbView , BlockReader , DBProvider , DatabaseProviderFactory ,
@@ -108,6 +108,8 @@ impl<Factory> StateRootConfig<Factory> {
108108#[ derive( Debug ) ]
109109#[ allow( dead_code) ]
110110pub enum StateRootMessage < BPF : BlindedProviderFactory > {
111+ /// Prefetch proof targets
112+ PrefetchProofs ( HashSet < Address > ) ,
111113 /// New state update from transaction execution
112114 StateUpdate ( EvmState ) ,
113115 /// Proof calculation completed for a specific state update
@@ -340,6 +342,29 @@ where
340342 }
341343 }
342344
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+
343368 /// Handles state updates.
344369 ///
345370 /// Returns proof targets derived from the state update.
@@ -356,46 +381,39 @@ where
356381 let proof_targets = get_proof_targets ( & hashed_state_update, fetched_proof_targets) ;
357382 extend_multi_proof_targets_ref ( fetched_proof_targets, & proof_targets) ;
358383
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+ ) {
359402 // 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) ) ;
399417 }
400418 } ) ;
401419 }
@@ -486,6 +504,21 @@ where
486504 loop {
487505 match self . rx . recv ( ) {
488506 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+ }
489522 StateRootMessage :: StateUpdate ( update) => {
490523 if updates_received == 0 {
491524 first_update_time = Some ( Instant :: now ( ) ) ;
@@ -681,6 +714,31 @@ fn get_proof_targets(
681714 targets
682715}
683716
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+
684742/// Updates the sparse trie with the given proofs and state, and returns the updated trie and the
685743/// time it took.
686744fn update_sparse_trie <
0 commit comments