Skip to content
Snippets Groups Projects
Commit 8948567c authored by Arkadiy Paronyan's avatar Arkadiy Paronyan Committed by Gav Wood
Browse files

Fixed ancestry search/block queue interaction (#1337)

* Fixed ancestry search - block queue interaction

* Style
parent 5db38433
No related merge requests found
......@@ -23,7 +23,7 @@ use consensus::BlockOrigin;
use consensus::import_queue::{ImportQueue, IncomingBlock};
use client::error::Error as ClientError;
use blocks::BlockCollection;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero};
use runtime_primitives::generic::BlockId;
use message::{self, generic::Message as GenericMessage};
use config::Roles;
......@@ -32,9 +32,10 @@ use config::Roles;
const MAX_BLOCKS_TO_REQUEST: usize = 128;
// Maximum blocks to store in the import queue.
const MAX_IMPORTING_BLOCKS: usize = 2048;
// Number of blocks in the queue that prevents ancestry search.
const MAJOR_SYNC_BLOCKS: usize = 5;
struct PeerSync<B: BlockT> {
pub common_hash: B::Hash,
pub common_number: NumberFor<B>,
pub best_hash: B::Hash,
pub best_number: NumberFor<B>,
......@@ -141,16 +142,25 @@ impl<B: BlockT> ChainSync<B> {
(Ok(BlockStatus::KnownBad), _) => {
protocol.report_peer(who, Severity::Bad(&format!("New peer with known bad best block {} ({}).", info.best_hash, info.best_number)));
},
(Ok(BlockStatus::Unknown), b) if b == As::sa(0) => {
(Ok(BlockStatus::Unknown), b) if b.is_zero() => {
protocol.report_peer(who, Severity::Bad(&format!("New peer with unknown genesis hash {} ({}).", info.best_hash, info.best_number)));
},
(Ok(BlockStatus::Unknown), _) if self.import_queue.status().importing_count > MAJOR_SYNC_BLOCKS => {
// when actively syncing the common point moves too fast.
debug!(target:"sync", "New peer with unknown best hash {} ({}), assuming common block.", self.best_queued_hash, self.best_queued_number);
self.peers.insert(who, PeerSync {
common_number: self.best_queued_number,
best_hash: info.best_hash,
best_number: info.best_number,
state: PeerSyncState::Available,
});
}
(Ok(BlockStatus::Unknown), _) => {
let our_best = self.best_queued_number;
if our_best > As::sa(0) {
let common_best = ::std::cmp::min(our_best, info.best_number);
debug!(target:"sync", "New peer with unknown best hash {} ({}), searching for common ancestor.", info.best_hash, info.best_number);
self.peers.insert(who, PeerSync {
common_hash: self.genesis_hash,
common_number: As::sa(0),
best_hash: info.best_hash,
best_number: info.best_number,
......@@ -161,7 +171,6 @@ impl<B: BlockT> ChainSync<B> {
// We are at genesis, just start downloading
debug!(target:"sync", "New peer with best hash {} ({}).", info.best_hash, info.best_number);
self.peers.insert(who, PeerSync {
common_hash: self.genesis_hash,
common_number: As::sa(0),
best_hash: info.best_hash,
best_number: info.best_number,
......@@ -173,7 +182,6 @@ impl<B: BlockT> ChainSync<B> {
(Ok(BlockStatus::Queued), _) | (Ok(BlockStatus::InChain), _) => {
debug!(target:"sync", "New peer with known best hash {} ({}).", info.best_hash, info.best_number);
self.peers.insert(who, PeerSync {
common_hash: info.best_hash,
common_number: info.best_number,
best_hash: info.best_hash,
best_number: info.best_number,
......@@ -230,7 +238,6 @@ impl<B: BlockT> ChainSync<B> {
match protocol.client().block_hash(n) {
Ok(Some(block_hash)) if block_hash == block.hash => {
if peer.common_number < n {
peer.common_hash = block.hash;
peer.common_number = n;
}
peer.state = PeerSyncState::Available;
......@@ -300,15 +307,14 @@ impl<B: BlockT> ChainSync<B> {
// Update common blocks
for (n, peer) in self.peers.iter_mut() {
if let PeerSyncState::AncestorSearch(_) = peer.state {
continue;
// Abort search.
peer.state = PeerSyncState::Available;
}
trace!(target: "sync", "Updating peer {} info, ours={}, common={}, their best={}", n, number, peer.common_number, peer.best_number);
if peer.best_number >= number {
peer.common_number = number;
peer.common_hash = *hash;
} else {
peer.common_number = peer.best_number;
peer.common_hash = peer.best_hash;
}
}
}
......@@ -379,10 +385,6 @@ impl<B: BlockT> ChainSync<B> {
pub(crate) fn restart(&mut self, protocol: &mut Context<B>) {
self.import_queue.clear();
self.blocks.clear();
let ids: Vec<NodeIndex> = self.peers.keys().map(|p| *p).collect();
for id in ids {
self.new_peer(protocol, id);
}
match protocol.client().info() {
Ok(info) => {
self.best_queued_hash = info.best_queued_hash.unwrap_or(info.chain.best_hash);
......@@ -395,6 +397,10 @@ impl<B: BlockT> ChainSync<B> {
self.best_queued_number = As::sa(0);
}
}
let ids: Vec<NodeIndex> = self.peers.drain().map(|(id, _)| id).collect();
for id in ids {
self.new_peer(protocol, id);
}
}
pub(crate) fn clear(&mut self) {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment