Move import queue out of sc-network (#12764)

* Move import queue out of `sc-network`

Add supplementary asynchronous API for the import queue which means
it can be run as an independent task and communicated with through
the `ImportQueueService`.

This commit removes removes block and justification imports from
`sc-network` and provides `ChainSync` with a handle to import queue so
it can import blocks and justifications. Polling of the import queue is
moved complete out of `sc-network` and `sc_consensus::Link` is
implemented for `ChainSyncInterfaceHandled` so the import queue
can still influence the syncing process.

* Fix tests

* Apply review comments

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <git@kchr.de>

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

Co-authored-by: Bastian Köcher <git@kchr.de>

Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
Aaro Altonen
2022-12-09 21:50:57 +02:00
committed by GitHub
parent 225c260e07
commit d6827185c3
24 changed files with 716 additions and 490 deletions
@@ -17,6 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use libp2p::PeerId;
use sc_consensus::{BlockImportError, BlockImportStatus, JustificationSyncLink, Link};
use sc_network_common::service::NetworkSyncForkRequest;
use sc_utils::mpsc::TracingUnboundedSender;
use sp_runtime::traits::{Block as BlockT, NumberFor};
@@ -25,9 +26,18 @@ use sp_runtime::traits::{Block as BlockT, NumberFor};
#[derive(Debug)]
pub enum ToServiceCommand<B: BlockT> {
SetSyncForkRequest(Vec<PeerId>, B::Hash, NumberFor<B>),
RequestJustification(B::Hash, NumberFor<B>),
ClearJustificationRequests,
BlocksProcessed(
usize,
usize,
Vec<(Result<BlockImportStatus<NumberFor<B>>, BlockImportError>, B::Hash)>,
),
JustificationImported(PeerId, B::Hash, NumberFor<B>, bool),
}
/// Handle for communicating with `ChainSync` asynchronously
#[derive(Clone)]
pub struct ChainSyncInterfaceHandle<B: BlockT> {
tx: TracingUnboundedSender<ToServiceCommand<B>>,
}
@@ -56,3 +66,46 @@ impl<B: BlockT + 'static> NetworkSyncForkRequest<B::Hash, NumberFor<B>>
.unbounded_send(ToServiceCommand::SetSyncForkRequest(peers, hash, number));
}
}
impl<B: BlockT> JustificationSyncLink<B> for ChainSyncInterfaceHandle<B> {
/// Request a justification for the given block from the network.
///
/// On success, the justification will be passed to the import queue that was part at
/// initialization as part of the configuration.
fn request_justification(&self, hash: &B::Hash, number: NumberFor<B>) {
let _ = self.tx.unbounded_send(ToServiceCommand::RequestJustification(*hash, number));
}
fn clear_justification_requests(&self) {
let _ = self.tx.unbounded_send(ToServiceCommand::ClearJustificationRequests);
}
}
impl<B: BlockT> Link<B> for ChainSyncInterfaceHandle<B> {
fn blocks_processed(
&mut self,
imported: usize,
count: usize,
results: Vec<(Result<BlockImportStatus<NumberFor<B>>, BlockImportError>, B::Hash)>,
) {
let _ = self
.tx
.unbounded_send(ToServiceCommand::BlocksProcessed(imported, count, results));
}
fn justification_imported(
&mut self,
who: PeerId,
hash: &B::Hash,
number: NumberFor<B>,
success: bool,
) {
let _ = self
.tx
.unbounded_send(ToServiceCommand::JustificationImported(who, *hash, number, success));
}
fn request_justification(&mut self, hash: &B::Hash, number: NumberFor<B>) {
let _ = self.tx.unbounded_send(ToServiceCommand::RequestJustification(*hash, number));
}
}
@@ -18,6 +18,7 @@
use futures::channel::oneshot;
use libp2p::{Multiaddr, PeerId};
use sc_consensus::{BlockImportError, BlockImportStatus};
use sc_network_common::{
config::MultiaddrWithPeerId,
protocol::ProtocolName,
@@ -29,13 +30,43 @@ use sp_runtime::traits::{Block as BlockT, NumberFor};
use std::collections::HashSet;
mockall::mock! {
pub ChainSyncInterface<B: BlockT> {}
pub ChainSyncInterface<B: BlockT> {
pub fn justification_sync_link_request_justification(&self, hash: &B::Hash, number: NumberFor<B>);
pub fn justification_sync_link_clear_justification_requests(&self);
}
impl<B: BlockT + 'static> NetworkSyncForkRequest<B::Hash, NumberFor<B>>
for ChainSyncInterface<B>
{
fn set_sync_fork_request(&self, peers: Vec<PeerId>, hash: B::Hash, number: NumberFor<B>);
}
impl<B: BlockT> sc_consensus::Link<B> for ChainSyncInterface<B> {
fn blocks_processed(
&mut self,
imported: usize,
count: usize,
results: Vec<(Result<BlockImportStatus<NumberFor<B>>, BlockImportError>, B::Hash)>,
);
fn justification_imported(
&mut self,
who: PeerId,
hash: &B::Hash,
number: NumberFor<B>,
success: bool,
);
fn request_justification(&mut self, hash: &B::Hash, number: NumberFor<B>);
}
}
impl<B: BlockT> sc_consensus::JustificationSyncLink<B> for MockChainSyncInterface<B> {
fn request_justification(&self, hash: &B::Hash, number: NumberFor<B>) {
self.justification_sync_link_request_justification(hash, number);
}
fn clear_justification_requests(&self) {
self.justification_sync_link_clear_justification_requests();
}
}
mockall::mock! {