diff --git a/substrate/client/network/src/protocol.rs b/substrate/client/network/src/protocol.rs index 7662a476e9a6fc9a45e48c0643cc4fcfaa7f5be8..4153129a0ac4d3a85ad7b74cf05544987c91908f 100644 --- a/substrate/client/network/src/protocol.rs +++ b/substrate/client/network/src/protocol.rs @@ -111,7 +111,7 @@ mod rep { /// reputation change should be refunded with `ANY_EXTRINSIC_REFUND` pub const ANY_EXTRINSIC: Rep = Rep::new(-(1 << 4), "Any extrinsic"); /// Reputation change when a peer sends us any extrinsic that is not invalid. - pub const ANY_EXTRINSIC_REFUND: Rep = Rep::new(1 << 4, "Any extrinsic (refund)"); + pub const ANY_EXTRINSIC_REFUND: Rep = Rep::new(1 << 4, "Any extrinsic (refund)"); /// Reputation change when a peer sends us an extrinsic that we didn't know about. pub const GOOD_EXTRINSIC: Rep = Rep::new(1 << 7, "Good extrinsic"); /// Reputation change when a peer sends us a bad extrinsic. @@ -535,6 +535,12 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> { self.sync.num_sync_requests() } + /// Sync local state with the blockchain state. + pub fn update_chain(&mut self) { + let info = self.context_data.chain.info(); + self.sync.update_chain_info(&info.best_hash, info.best_number); + } + /// Accepts a response from the legacy substream and determines what the corresponding /// request was. fn handle_response( @@ -1419,17 +1425,6 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> { } } - /// Call this when a block has been imported in the import queue - pub fn on_block_imported(&mut self, header: &B::Header, is_best: bool) { - if is_best { - self.sync.update_chain_info(header); - self.behaviour.set_notif_protocol_handshake( - &self.block_announces_protocol, - BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() - ); - } - } - /// Call this when a block has been finalized. The sync layer may have some additional /// requesting to perform. pub fn on_block_finalized(&mut self, hash: B::Hash, header: &B::Header) { @@ -1494,12 +1489,23 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> { /// A batch of blocks have been processed, with or without errors. /// Call this when a batch of blocks have been processed by the importqueue, with or without /// errors. - pub fn blocks_processed( + pub fn on_blocks_processed( &mut self, imported: usize, count: usize, results: Vec<(Result<BlockImportResult<NumberFor<B>>, BlockImportError>, B::Hash)> ) { + let new_best = results.iter().rev().find_map(|r| match r { + (Ok(BlockImportResult::ImportedUnknown(n, aux, _)), hash) if aux.is_new_best => Some((*n, hash.clone())), + _ => None, + }); + if let Some((best_num, best_hash)) = new_best { + self.sync.update_chain_info(&best_hash, best_num); + self.behaviour.set_notif_protocol_handshake( + &self.block_announces_protocol, + BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() + ); + } let results = self.sync.on_blocks_processed( imported, count, diff --git a/substrate/client/network/src/protocol/sync.rs b/substrate/client/network/src/protocol/sync.rs index f4c935de5d3af5d02a7e1c71a8b8b788caca6779..e08fcf4e9b580297d455dc6663758d10968c6831 100644 --- a/substrate/client/network/src/protocol/sync.rs +++ b/substrate/client/network/src/protocol/sync.rs @@ -513,10 +513,10 @@ impl<B: BlockT> ChainSync<B> { } } - /// Signal that `best_header` has been queued for import and update the + /// Signal that a new best block has been imported. /// `ChainSync` state with that information. - pub fn update_chain_info(&mut self, best_header: &B::Header) { - self.on_block_queued(&best_header.hash(), *best_header.number()) + pub fn update_chain_info(&mut self, best_hash: &B::Hash, best_number: NumberFor<B>) { + self.on_block_queued(best_hash, best_number); } /// Schedule a justification request for the given block. diff --git a/substrate/client/network/src/service.rs b/substrate/client/network/src/service.rs index ba6c7a39b4b2125c5ac3c70c28e43804f605b9ca..544856893060143fa7e8e80f3be2accc02ef7ac8 100644 --- a/substrate/client/network/src/service.rs +++ b/substrate/client/network/src/service.rs @@ -400,16 +400,18 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> { &self.service } - /// You must call this when a new block is imported by the client. - pub fn on_block_imported(&mut self, header: B::Header, is_best: bool) { - self.network_service.user_protocol_mut().on_block_imported(&header, is_best); - } - /// You must call this when a new block is finalized by the client. pub fn on_block_finalized(&mut self, hash: B::Hash, header: B::Header) { self.network_service.user_protocol_mut().on_block_finalized(hash, &header); } + /// This should be called when blocks are added to the + /// chain by something other than the import queue. + /// Currently this is only useful for tests. + pub fn update_chain(&mut self) { + self.network_service.user_protocol_mut().update_chain(); + } + /// Returns the local `PeerId`. pub fn local_peer_id(&self) -> &PeerId { Swarm::<B, H>::local_peer_id(&self.network_service) @@ -1349,7 +1351,7 @@ impl<'a, B: BlockT, H: ExHashT> Link<B> for NetworkLink<'a, B, H> { count: usize, results: Vec<(Result<BlockImportResult<NumberFor<B>>, BlockImportError>, B::Hash)> ) { - self.protocol.user_protocol_mut().blocks_processed(imported, count, results) + self.protocol.user_protocol_mut().on_blocks_processed(imported, count, results) } fn justification_imported(&mut self, who: PeerId, hash: &B::Hash, number: NumberFor<B>, success: bool) { self.protocol.user_protocol_mut().justification_import_result(hash.clone(), number, success); diff --git a/substrate/client/network/test/src/lib.rs b/substrate/client/network/test/src/lib.rs index 76bc2afa6953cf09b39048aba733869077b80b61..25a7f3a606fa2a0b6890a17fae3591af1414071e 100644 --- a/substrate/client/network/test/src/lib.rs +++ b/substrate/client/network/test/src/lib.rs @@ -295,11 +295,11 @@ impl<D> Peer<D> { Default::default() }; self.block_import.import_block(import_block, cache).expect("block_import failed"); - self.network.on_block_imported(header, true); self.network.service().announce_block(hash, Vec::new()); at = hash; } + self.network.update_chain(); self.network.service().announce_block(at.clone(), Vec::new()); at } @@ -813,10 +813,6 @@ pub trait TestNetFactory: Sized { // We poll `imported_blocks_stream`. while let Poll::Ready(Some(notification)) = peer.imported_blocks_stream.as_mut().poll_next(cx) { - peer.network.on_block_imported( - notification.header, - true, - ); peer.network.service().announce_block(notification.hash, Vec::new()); } diff --git a/substrate/client/service/src/lib.rs b/substrate/client/service/src/lib.rs index ebd2b99ef1d31956d849eec21fc5eb977dda41c8..5604b98e82dbc8da6a16760524cce1e730ce04bd 100644 --- a/substrate/client/service/src/lib.rs +++ b/substrate/client/service/src/lib.rs @@ -369,8 +369,6 @@ fn build_network_future< // We poll `imported_blocks_stream`. while let Poll::Ready(Some(notification)) = Pin::new(&mut imported_blocks_stream).poll_next(cx) { - network.on_block_imported(notification.header, notification.is_new_best); - if announce_imported_blocks { network.service().announce_block(notification.hash, Vec::new()); }