Skip to content

Commit cbaa95b

Browse files
committed
Add pending_state_sync_attempt
There is an edge case where the finalized block notification is received, but the conditions required to initiate the state sync are not fully met. In such cases, state sync would fail to start as expected and remain stalled. This fixes it by storing the pending attempt and trying to start it later.
1 parent a58bf78 commit cbaa95b

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

substrate/client/network/sync/src/strategy/chain_sync.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)