Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Start
  • Loading branch information
bkchr committed Jun 20, 2020
commit 76fcfac79a784aa3a8dddc7fb4bd7b2b9266fec1
47 changes: 30 additions & 17 deletions client/network/src/protocol/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, Header, NumberFor, Zero, One, CheckedSub, SaturatedConversion, Hash, HashFor}
};
use sp_arithmetic::traits::Saturating;
use std::{fmt, ops::Range, collections::{HashMap, HashSet, VecDeque}, sync::Arc};

mod blocks;
Expand Down Expand Up @@ -388,7 +389,7 @@ impl<B: BlockT> ChainSync<B> {

/// Returns the current sync status.
pub fn status(&self) -> Status<B> {
let best_seen = self.peers.values().max_by_key(|p| p.best_number).map(|p| p.best_number);
let best_seen = self.peers.values().map(|p| p.best_number).max();
let sync_state =
if let Some(n) = best_seen {
// A chain is classified as downloading if the provided best block is
Expand Down Expand Up @@ -1130,6 +1131,7 @@ impl<B: BlockT> ChainSync<B> {
trace!(target: "sync", "Completed fork sync {:?}", hash);
}
if number > self.best_queued_number {
println!("BEST QUEUED NUMBER!!! {}", number);
self.best_queued_number = number;
self.best_queued_hash = *hash;
// Update common blocks
Expand Down Expand Up @@ -1189,6 +1191,21 @@ impl<B: BlockT> ChainSync<B> {
peer.recently_announced.pop_front();
}
peer.recently_announced.push_back(hash.clone());

// Let external validator check the block announcement.
let assoc_data = announce.data.as_ref().map_or(&[][..], |v| v.as_slice());
let is_best = match self.block_announce_validator.validate(&header, assoc_data) {
Ok(Validation::Success { is_new_best }) => is_new_best || is_best,
Ok(Validation::Failure) => {
debug!(target: "sync", "Block announcement validation of block {} from {} failed", hash, who);
return OnBlockAnnounce::Nothing
}
Err(e) => {
error!(target: "sync", "💔 Block announcement validation errored: {}", e);
return OnBlockAnnounce::Nothing
}
};

if is_best {
// update their best block
peer.best_number = number;
Expand Down Expand Up @@ -1219,20 +1236,6 @@ impl<B: BlockT> ChainSync<B> {
return OnBlockAnnounce::Nothing
}

// Let external validator check the block announcement.
let assoc_data = announce.data.as_ref().map_or(&[][..], |v| v.as_slice());
match self.block_announce_validator.validate(&header, assoc_data) {
Ok(Validation::Success) => (),
Ok(Validation::Failure) => {
debug!(target: "sync", "Block announcement validation of block {} from {} failed", hash, who);
return OnBlockAnnounce::Nothing
}
Err(e) => {
error!(target: "sync", "💔 Block announcement validation errored: {}", e);
return OnBlockAnnounce::Nothing
}
}

if ancient_parent {
trace!(target: "sync", "Ignored ancient block announced from {}: {} {:?}", who, hash, header);
return OnBlockAnnounce::Nothing
Expand Down Expand Up @@ -1431,14 +1434,24 @@ fn peer_block_request<B: BlockT>(
max_parallel_downloads,
MAX_DOWNLOAD_AHEAD,
) {
// The end is not part of the range.
let last = range.end.saturating_sub(One::one());

let from = if peer.best_number == last {
message::FromBlock::Hash(peer.best_hash)
} else {
message::FromBlock::Number(last)
};

let request = message::generic::BlockRequest {
id: 0,
fields: attrs.clone(),
from: message::FromBlock::Number(range.start),
from,
to: None,
direction: message::Direction::Ascending,
direction: message::Direction::Descending,
max: Some((range.end - range.start).saturated_into::<u32>())
};

Some((range, request))
} else {
None
Expand Down
7 changes: 5 additions & 2 deletions primitives/consensus/common/src/block_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ impl<T: Chain<B>, B: Block> Chain<B> for Arc<T> {
#[derive(Debug, PartialEq, Eq)]
pub enum Validation {
/// Valid block announcement.
Success,
Success {
/// Is this the new best block of the node?
is_new_best: bool,
},
/// Invalid block announcement.
Failure,
}
Expand All @@ -61,6 +64,6 @@ impl<C> DefaultBlockAnnounceValidator<C> {

impl<B: Block, C: Chain<B>> BlockAnnounceValidator<B> for DefaultBlockAnnounceValidator<C> {
fn validate(&mut self, _h: &B::Header, _d: &[u8]) -> Result<Validation, Box<dyn Error + Send>> {
Ok(Validation::Success)
Ok(Validation::Success { is_new_best: false })
}
}