From 7858828d980bbd1f7c73797208a44d2805e998b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 19 Jun 2020 16:00:58 +0200 Subject: [PATCH] Update sync chain info on own block import (#6424) Before we only updated the chain info of sync when we have imported something using the import queue. However, if you import your own blocks, this is not done using the import queue and so sync is not updated. If we don't do this, it can lead to sync switching to "major sync" mode because sync is not informed about new blocks. This especially happens on Cumulus, where a collator is selected multiple times to include its block into the relay chain and thus, sync switches to major sync mode while the node is still building blocks. --- substrate/client/network/src/protocol.rs | 5 +++++ substrate/client/network/src/service.rs | 9 +++++++++ substrate/client/service/src/lib.rs | 9 ++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/substrate/client/network/src/protocol.rs b/substrate/client/network/src/protocol.rs index 06f117b3bb..ccd4463901 100644 --- a/substrate/client/network/src/protocol.rs +++ b/substrate/client/network/src/protocol.rs @@ -544,6 +544,11 @@ impl Protocol { self.sync.update_chain_info(&info.best_hash, info.best_number); } + /// Inform sync about an own imported block. + pub fn own_block_imported(&mut self, hash: B::Hash, number: NumberFor) { + self.sync.update_chain_info(&hash, number); + } + fn update_peer_info(&mut self, who: &PeerId) { if let Some(info) = self.sync.peer_info(who) { if let Some(ref mut peer) = self.context_data.peers.get_mut(who) { diff --git a/substrate/client/network/src/service.rs b/substrate/client/network/src/service.rs index 0d5f037a37..90fffc8a37 100644 --- a/substrate/client/network/src/service.rs +++ b/substrate/client/network/src/service.rs @@ -746,6 +746,12 @@ impl NetworkService { .unbounded_send(ServiceToWorkerMsg::UpdateChain); } + /// Inform the network service about an own imported block. + pub fn own_block_imported(&self, hash: B::Hash, number: NumberFor) { + let _ = self + .to_worker + .unbounded_send(ServiceToWorkerMsg::OwnBlockImported(hash, number)); + } } impl sp_consensus::SyncOracle @@ -812,6 +818,7 @@ enum ServiceToWorkerMsg { }, DisconnectPeer(PeerId), UpdateChain, + OwnBlockImported(B::Hash, NumberFor), } /// Main network worker. Must be polled in order for the network to advance. @@ -1142,6 +1149,8 @@ impl Future for NetworkWorker { this.network_service.user_protocol_mut().disconnect_peer(&who), ServiceToWorkerMsg::UpdateChain => this.network_service.user_protocol_mut().update_chain(), + ServiceToWorkerMsg::OwnBlockImported(hash, number) => + this.network_service.user_protocol_mut().own_block_imported(hash, number), } } diff --git a/substrate/client/service/src/lib.rs b/substrate/client/service/src/lib.rs index 37bac171c9..5184886efd 100644 --- a/substrate/client/service/src/lib.rs +++ b/substrate/client/service/src/lib.rs @@ -55,7 +55,7 @@ use sc_network::{NetworkService, NetworkStatus, network_state::NetworkState, Pee use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; use sp_runtime::generic::BlockId; -use sp_runtime::traits::Block as BlockT; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}}; @@ -382,6 +382,13 @@ fn build_network_future< if announce_imported_blocks { network.service().announce_block(notification.hash, Vec::new()); } + + if let sp_consensus::BlockOrigin::Own = notification.origin { + network.service().own_block_imported( + notification.hash, + notification.header.number().clone(), + ); + } } // We poll `finality_notification_stream`, but we only take the last event.