Send block status with announcement (#3607)

* Send block status with announcement

* Fixed tests

* Whitespace

Co-Authored-By: Gavin Wood <gavin@parity.io>

* Additional comment

* Update comment

Co-Authored-By: André Silva <andre.beat@gmail.com>
This commit is contained in:
Arkadiy Paronyan
2019-09-17 11:19:46 +02:00
committed by Bastian Köcher
parent 6679c8b051
commit 84d0c790f3
6 changed files with 85 additions and 30 deletions
+37 -2
View File
@@ -107,6 +107,15 @@ pub enum Direction {
Descending = 1,
}
/// Block state in the chain.
#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode)]
pub enum BlockState {
/// Block is not part of the best chain.
Normal,
/// Latest best block.
Best,
}
/// Remote call response.
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
pub struct RemoteCallResponse {
@@ -127,12 +136,13 @@ pub struct RemoteReadResponse {
/// Generic types.
pub mod generic {
use codec::{Encode, Decode};
use codec::{Encode, Decode, Input, Output};
use sr_primitives::Justification;
use crate::config::Roles;
use super::{
RemoteReadResponse, Transactions, Direction,
RequestId, BlockAttributes, RemoteCallResponse, ConsensusEngineId,
BlockState,
};
/// Consensus is mostly opaque to us
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
@@ -257,10 +267,35 @@ pub mod generic {
}
/// Announce a new complete relay chain block on the network.
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct BlockAnnounce<H> {
/// New block header.
pub header: H,
/// Block state. TODO: Remove `Option` and custom encoding when v4 becomes common.
pub state: Option<BlockState>,
}
// Custom Encode/Decode impl to maintain backwards compatibility with v3.
// This assumes that the packet contains nothing but the announcement message.
// TODO: Get rid of it once protocol v4 is common.
impl<H: Encode> Encode for BlockAnnounce<H> {
fn encode_to<T: Output>(&self, dest: &mut T) {
self.header.encode_to(dest);
if let Some(state) = &self.state {
state.encode_to(dest);
}
}
}
impl<H: Decode> Decode for BlockAnnounce<H> {
fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
let header = H::decode(input)?;
let state = BlockState::decode(input).ok();
Ok(BlockAnnounce {
header,
state,
})
}
}
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
+6 -4
View File
@@ -885,7 +885,9 @@ impl<B: BlockT> ChainSync<B> {
/// header (call `on_block_data`). The network request isn't sent
/// in this case. Both hash and header is passed as an optimization
/// to avoid rehashing the header.
pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, header: &B::Header) -> OnBlockAnnounce<B> {
pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, header: &B::Header, is_best: bool)
-> OnBlockAnnounce<B>
{
let number = *header.number();
debug!(target: "sync", "Received block announcement with number {:?}", number);
if number.is_zero() {
@@ -907,7 +909,7 @@ impl<B: BlockT> ChainSync<B> {
peer.recently_announced.pop_front();
}
peer.recently_announced.push_back(hash.clone());
if number > peer.best_number {
if is_best && number > peer.best_number {
// update their best block
peer.best_number = number;
peer.best_hash = hash;
@@ -915,9 +917,9 @@ impl<B: BlockT> ChainSync<B> {
if let PeerSyncState::AncestorSearch(_, _) = peer.state {
return OnBlockAnnounce::Nothing
}
// We assume that the announced block is the latest they have seen, and so our common number
// If the announced block is the best they have seen, our common number
// is either one further ahead or it's the one they just announced, if we know about it.
if known {
if known && is_best {
peer.common_number = number
} else if header.parent_hash() == &self.best_queued_hash || known_parent {
peer.common_number = number - One::one();