Update common block in sync after importing blocks of a peer, please read UPDATE (#7733)

* Update common block in sync after importing blocks of a peer

This updates the sync code to update the common block of a peer, after
we have imported blocks from this peer. This fixes a bug for when we are
connected to one or more nodes that are doing a full sync as our node.
Nodes in full sync will not announce new blocks, as we don't send import
notifications on full sync. The problem as now that we were connected to
some peer that reported some low number as its best and we tried to sync
these blocks. But, as we did not update the common block of this peer,
we would sync these blocks over and over again. Being captured in some
time warp.
The solution to this problem is that we increase the common number as we
import blocks from this peer.

* Test

* Test name..

* Fix test

* Cleanup some code and write some new regression test

* Implement the ancestor search

* Check that the common number is smaller than the last finalized block

* Update client/network/src/protocol/sync.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Update client/network/src/protocol/sync.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Update client/network/src/protocol/sync.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Change the way we build the status messages

* Start some new test...

* Finish test

* Rename test

* Update client/network/src/protocol.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
Bastian Köcher
2020-12-18 12:04:17 +01:00
committed by GitHub
parent 9a3cab74ac
commit d3c7a99d3c
7 changed files with 546 additions and 107 deletions
+40 -14
View File
@@ -307,27 +307,35 @@ struct BlockAnnouncesHandshake<B: BlockT> {
}
impl<B: BlockT> BlockAnnouncesHandshake<B> {
fn build(protocol_config: &ProtocolConfig, chain: &Arc<dyn Client<B>>) -> Self {
let info = chain.info();
fn build(
protocol_config: &ProtocolConfig,
best_number: NumberFor<B>,
best_hash: B::Hash,
genesis_hash: B::Hash,
) -> Self {
BlockAnnouncesHandshake {
genesis_hash: info.genesis_hash,
genesis_hash,
roles: protocol_config.roles,
best_number: info.best_number,
best_hash: info.best_hash,
best_number,
best_hash,
}
}
}
/// Builds a SCALE-encoded "Status" message to send as handshake for the legacy protocol.
fn build_status_message<B: BlockT>(protocol_config: &ProtocolConfig, chain: &Arc<dyn Client<B>>) -> Vec<u8> {
let info = chain.info();
fn build_status_message<B: BlockT>(
protocol_config: &ProtocolConfig,
best_number: NumberFor<B>,
best_hash: B::Hash,
genesis_hash: B::Hash,
) -> Vec<u8> {
let status = message::generic::Status {
version: CURRENT_VERSION,
min_supported_version: MIN_VERSION,
genesis_hash: info.genesis_hash,
genesis_hash,
roles: protocol_config.roles.into(),
best_number: info.best_number,
best_hash: info.best_hash,
best_number,
best_hash,
chain_status: Vec::new(), // TODO: find a way to make this backwards-compatible
};
@@ -400,12 +408,22 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
let behaviour = {
let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::<Vec<u8>>();
let block_announces_handshake = BlockAnnouncesHandshake::build(&config, &chain).encode();
let best_number = info.best_number;
let best_hash = info.best_hash;
let genesis_hash = info.genesis_hash;
let block_announces_handshake = BlockAnnouncesHandshake::<B>::build(
&config,
best_number,
best_hash,
genesis_hash,
).encode();
GenericProto::new(
local_peer_id,
protocol_id.clone(),
versions,
build_status_message(&config, &chain),
build_status_message::<B>(&config, best_number, best_hash, genesis_hash),
peerset,
// As documented in `GenericProto`, the first protocol in the list is always the
// one carrying the handshake reported in the `CustomProtocolOpen` event.
@@ -528,13 +546,21 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
/// Inform sync about new best imported block.
pub fn new_best_block_imported(&mut self, hash: B::Hash, number: NumberFor<B>) {
trace!(target: "sync", "New best block imported {:?}/#{}", hash, number);
self.sync.update_chain_info(&hash, number);
self.behaviour.set_legacy_handshake_message(
build_status_message(&self.config, &self.context_data.chain),
build_status_message::<B>(&self.config, number, hash, self.genesis_hash),
);
self.behaviour.set_notif_protocol_handshake(
&self.block_announces_protocol,
BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode()
BlockAnnouncesHandshake::<B>::build(
&self.config,
number,
hash,
self.genesis_hash,
).encode()
);
}