Actually fix major sync detection (#12114)

* Actually fix major sync detection

* Introduce `SyncState::Importing` state

* Add target to SyncState enum variants and add `is_major_syncing` method on it

* Remove unnecessary duplicated `best_seen_block` from `SyncState` struct

* Revert "Remove unnecessary duplicated `best_seen_block` from `SyncState` struct"

This reverts commit bb8abd458c939881c049f69d59f3acba47c97c5c.

* Add missing `websocket` feature to `libp2p`

Co-authored-by: parity-processbot <>
This commit is contained in:
Nazar Mokrynskyi
2022-10-21 16:38:53 +03:00
committed by GitHub
parent 7f8aab84b1
commit bf57a2e92d
6 changed files with 71 additions and 62 deletions
+20 -17
View File
@@ -410,13 +410,21 @@ where
/// Returns the current sync status.
fn status(&self) -> SyncStatus<B> {
let best_seen = self.best_seen();
let sync_state = if let Some(n) = best_seen {
let median_seen = self.median_seen();
let best_seen_block =
median_seen.and_then(|median| (median > self.best_queued_number).then_some(median));
let sync_state = if let Some(target) = median_seen {
// A chain is classified as downloading if the provided best block is
// more than `MAJOR_SYNC_BLOCKS` behind the best block.
// more than `MAJOR_SYNC_BLOCKS` behind the best block or as importing
// if the same can be said about queued blocks.
let best_block = self.client.info().best_number;
if n > best_block && n - best_block > MAJOR_SYNC_BLOCKS.into() {
SyncState::Downloading
if target > best_block && target - best_block > MAJOR_SYNC_BLOCKS.into() {
// If target is not queued, we're downloading, otherwise importing.
if target > self.best_queued_number {
SyncState::Downloading { target }
} else {
SyncState::Importing { target }
}
} else {
SyncState::Idle
}
@@ -437,7 +445,7 @@ where
SyncStatus {
state: sync_state,
best_seen_block: best_seen,
best_seen_block,
num_peers: self.peers.len() as u32,
queued_blocks: self.queue_blocks.len() as u32,
state_sync: self.state_sync.as_ref().map(|s| s.progress()),
@@ -693,7 +701,7 @@ where
trace!(target: "sync", "Too many blocks in the queue.");
return Box::new(std::iter::empty())
}
let major_sync = self.status().state == SyncState::Downloading;
let is_major_syncing = self.status().state.is_major_syncing();
let attrs = self.required_block_attributes();
let blocks = &mut self.blocks;
let fork_targets = &mut self.fork_targets;
@@ -703,7 +711,7 @@ where
let client = &self.client;
let queue = &self.queue_blocks;
let allowed_requests = self.allowed_requests.take();
let max_parallel = if major_sync { 1 } else { self.max_parallel_downloads };
let max_parallel = if is_major_syncing { 1 } else { self.max_parallel_downloads };
let gap_sync = &mut self.gap_sync;
let iter = self.peers.iter_mut().filter_map(move |(&id, peer)| {
if !peer.state.is_available() || !allowed_requests.contains(&id) {
@@ -1797,8 +1805,8 @@ where
Ok((sync, Box::new(ChainSyncInterfaceHandle::new(tx))))
}
/// Returns the best seen block number if we don't have that block yet, `None` otherwise.
fn best_seen(&self) -> Option<NumberFor<B>> {
/// Returns the median seen block number.
fn median_seen(&self) -> Option<NumberFor<B>> {
let mut best_seens = self.peers.values().map(|p| p.best_number).collect::<Vec<_>>();
if best_seens.is_empty() {
@@ -1807,12 +1815,7 @@ where
let middle = best_seens.len() / 2;
// Not the "perfect median" when we have an even number of peers.
let median = *best_seens.select_nth_unstable(middle).1;
if median > self.best_queued_number {
Some(median)
} else {
None
}
Some(*best_seens.select_nth_unstable(middle).1)
}
}
@@ -1854,7 +1857,7 @@ where
);
}
let origin = if !gap && self.status().state != SyncState::Downloading {
let origin = if !gap && !self.status().state.is_major_syncing() {
BlockOrigin::NetworkBroadcast
} else {
BlockOrigin::NetworkInitialSync