Skip to content

Commit

Permalink
Update common block in sync after importing blocks of a peer, please …
Browse files Browse the repository at this point in the history
…read UPDATE (paritytech#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>
  • Loading branch information
2 people authored and darkfriend77 committed Jan 11, 2021
1 parent f75f345 commit 5c42cbc
Show file tree
Hide file tree
Showing 7 changed files with 546 additions and 107 deletions.
54 changes: 40 additions & 14 deletions client/network/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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()
);
}

Expand Down
Loading

0 comments on commit 5c42cbc

Please sign in to comment.