@@ -254,6 +254,14 @@ pub struct ChainSync<B: BlockT, Client> {
254254 /// A set of hashes of blocks that are being downloaded or have been
255255 /// downloaded and are queued for import.
256256 queue_blocks : HashSet < B :: Hash > ,
257+ /// A pending attempt to start the state sync.
258+ ///
259+ /// The initiation of state sync may be deferred in cases where other conditions
260+ /// are not yet met when the finalized block notification is received, such as
261+ /// when `queue_blocks` is not empty or there are no peers. This field holds the
262+ /// necessary information to attempt the state sync at a later point when
263+ /// conditions are satisfied.
264+ pending_state_sync_attempt : Option < ( B :: Hash , NumberFor < B > , bool ) > ,
257265 /// Fork sync targets.
258266 fork_targets : HashMap < B :: Hash , ForkTarget < B > > ,
259267 /// A set of peers for which there might be potential block requests
@@ -376,6 +384,7 @@ where
376384 extra_justifications : ExtraRequests :: new ( "justification" , metrics_registry) ,
377385 mode,
378386 queue_blocks : Default :: default ( ) ,
387+ pending_state_sync_attempt : None ,
379388 fork_targets : Default :: default ( ) ,
380389 allowed_requests : Default :: default ( ) ,
381390 max_parallel_downloads,
@@ -1013,8 +1022,12 @@ where
10131022 } ) ;
10141023
10151024 if let ChainSyncMode :: LightState { skip_proofs, .. } = & self . mode {
1016- if self . state_sync . is_none ( ) && !self . peers . is_empty ( ) && self . queue_blocks . is_empty ( ) {
1017- self . attempt_state_sync ( * hash, number, * skip_proofs)
1025+ if self . state_sync . is_none ( ) {
1026+ if !self . peers . is_empty ( ) && self . queued_blocks . is_empty ( ) {
1027+ self . attempt_state_sync ( * hash, number, * skip_proofs)
1028+ } else {
1029+ self . pending_state_sync_attempt . replace ( ( * hash, number, * skip_proofs) )
1030+ }
10181031 }
10191032 }
10201033
@@ -1886,6 +1899,12 @@ where
18861899 /// Get pending actions to perform.
18871900 #[ must_use]
18881901 pub fn actions ( & mut self ) -> impl Iterator < Item = ChainSyncAction < B > > {
1902+ if !self . peers . is_empty ( ) && self . queued_blocks . is_empty ( ) {
1903+ if let Some ( ( hash, number, skip_proofs) ) = self . pending_state_sync_attempt . take ( ) {
1904+ self . attempt_state_sync ( hash, number, skip_proofs) ;
1905+ }
1906+ }
1907+
18891908 let block_requests = self
18901909 . block_requests ( )
18911910 . into_iter ( )
0 commit comments