Network sync refactoring (part 1) (#11303)

* Remove unnecessary imports, move one internal re-export into where it is actually used, make one import explicit

* Move a few data structures down into modules

* Use generic parameters in `sc-network` instead of `chain::Client` trait

* Remove unnecessary bound
This commit is contained in:
Nazar Mokrynskyi
2022-04-29 17:02:03 +03:00
committed by GitHub
parent 887acda7d0
commit af6773aba9
15 changed files with 380 additions and 206 deletions
+95 -26
View File
@@ -54,16 +54,18 @@ use libp2p::{
ping::Failure as PingFailure,
swarm::{
AddressScore, ConnectionError, ConnectionLimits, DialError, NetworkBehaviour,
PendingConnectionError, SwarmBuilder, SwarmEvent,
PendingConnectionError, Swarm, SwarmBuilder, SwarmEvent,
},
Multiaddr, PeerId,
};
use log::{debug, error, info, trace, warn};
use metrics::{Histogram, HistogramVec, MetricSources, Metrics};
use parking_lot::Mutex;
use sc_client_api::{BlockBackend, ProofProvider};
use sc_consensus::{BlockImportError, BlockImportStatus, ImportQueue, Link};
use sc_peerset::PeersetHandle;
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
use sp_blockchain::{HeaderBackend, HeaderMetadata};
use sp_runtime::traits::{Block as BlockT, NumberFor};
use std::{
borrow::Cow,
@@ -98,7 +100,7 @@ pub use libp2p::{
},
kad::record::Key as KademliaKey,
};
pub use signature::*;
pub use signature::Signature;
/// Substrate network service. Handles network IO and manages connectivity.
pub struct NetworkService<B: BlockT + 'static, H: ExHashT> {
@@ -130,13 +132,24 @@ pub struct NetworkService<B: BlockT + 'static, H: ExHashT> {
_marker: PhantomData<H>,
}
impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
impl<B, H, Client> NetworkWorker<B, H, Client>
where
B: BlockT + 'static,
H: ExHashT,
Client: HeaderBackend<B>
+ BlockBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ ProofProvider<B>
+ Send
+ Sync
+ 'static,
{
/// Creates the network service.
///
/// Returns a `NetworkWorker` that implements `Future` and must be regularly polled in order
/// for the network processing to advance. From it, you can extract a `NetworkService` using
/// `worker.service()`. The `NetworkService` can be shared through the codebase.
pub fn new(mut params: Params<B, H>) -> Result<Self, Error> {
pub fn new(mut params: Params<B, H, Client>) -> Result<Self, Error> {
// Ensure the listen addresses are consistent with the transport.
ensure_addresses_consistent_with_transport(
params.network_config.listen_addresses.iter(),
@@ -247,7 +260,7 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
// Build the swarm.
let client = params.chain.clone();
let (mut swarm, bandwidth): (Swarm<B>, _) = {
let (mut swarm, bandwidth): (Swarm<Behaviour<B, Client>>, _) = {
let user_agent = format!(
"{} ({})",
params.network_config.client_version, params.network_config.node_name
@@ -392,14 +405,18 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
// Listen on multiaddresses.
for addr in &params.network_config.listen_addresses {
if let Err(err) = Swarm::<B>::listen_on(&mut swarm, addr.clone()) {
if let Err(err) = Swarm::<Behaviour<B, Client>>::listen_on(&mut swarm, addr.clone()) {
warn!(target: "sub-libp2p", "Can't listen on {} because: {:?}", addr, err)
}
}
// Add external addresses.
for addr in &params.network_config.public_addresses {
Swarm::<B>::add_external_address(&mut swarm, addr.clone(), AddressScore::Infinite);
Swarm::<Behaviour<B, Client>>::add_external_address(
&mut swarm,
addr.clone(),
AddressScore::Infinite,
);
}
let external_addresses = Arc::new(Mutex::new(Vec::new()));
@@ -540,14 +557,14 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
/// Returns the local `PeerId`.
pub fn local_peer_id(&self) -> &PeerId {
Swarm::<B>::local_peer_id(&self.network_service)
Swarm::<Behaviour<B, Client>>::local_peer_id(&self.network_service)
}
/// Returns the list of addresses we are listening on.
///
/// Does **NOT** include a trailing `/p2p/` with our `PeerId`.
pub fn listen_addresses(&self) -> impl Iterator<Item = &Multiaddr> {
Swarm::<B>::listeners(&self.network_service)
Swarm::<Behaviour<B, Client>>::listeners(&self.network_service)
}
/// Get network state.
@@ -627,7 +644,7 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkWorker<B, H> {
.collect()
};
let peer_id = Swarm::<B>::local_peer_id(&swarm).to_base58();
let peer_id = Swarm::<Behaviour<B, Client>>::local_peer_id(&swarm).to_base58();
let listened_addresses = swarm.listeners().cloned().collect();
let external_addresses = swarm.external_addresses().map(|r| &r.addr).cloned().collect();
@@ -1445,7 +1462,18 @@ enum ServiceToWorkerMsg<B: BlockT, H: ExHashT> {
///
/// You are encouraged to poll this in a separate background thread or task.
#[must_use = "The NetworkWorker must be polled in order for the network to advance"]
pub struct NetworkWorker<B: BlockT + 'static, H: ExHashT> {
pub struct NetworkWorker<B, H, Client>
where
B: BlockT + 'static,
H: ExHashT,
Client: HeaderBackend<B>
+ BlockBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ ProofProvider<B>
+ Send
+ Sync
+ 'static,
{
/// Updated by the `NetworkWorker` and loaded by the `NetworkService`.
external_addresses: Arc<Mutex<Vec<Multiaddr>>>,
/// Updated by the `NetworkWorker` and loaded by the `NetworkService`.
@@ -1455,7 +1483,7 @@ pub struct NetworkWorker<B: BlockT + 'static, H: ExHashT> {
/// The network service that can be extracted and shared through the codebase.
service: Arc<NetworkService<B, H>>,
/// The *actual* network.
network_service: Swarm<B>,
network_service: Swarm<Behaviour<B, Client>>,
/// The import queue that was passed at initialization.
import_queue: Box<dyn ImportQueue<B>>,
/// Messages from the [`NetworkService`] that must be processed.
@@ -1473,7 +1501,18 @@ pub struct NetworkWorker<B: BlockT + 'static, H: ExHashT> {
tx_handler_controller: transactions::TransactionsHandlerController<H>,
}
impl<B: BlockT + 'static, H: ExHashT> Future for NetworkWorker<B, H> {
impl<B, H, Client> Future for NetworkWorker<B, H, Client>
where
B: BlockT + 'static,
H: ExHashT,
Client: HeaderBackend<B>
+ BlockBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ ProofProvider<B>
+ Send
+ Sync
+ 'static,
{
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context) -> Poll<Self::Output> {
@@ -2055,10 +2094,11 @@ impl<B: BlockT + 'static, H: ExHashT> Future for NetworkWorker<B, H> {
// Update the variables shared with the `NetworkService`.
this.num_connected.store(num_connected_peers, Ordering::Relaxed);
{
let external_addresses = Swarm::<B>::external_addresses(&this.network_service)
.map(|r| &r.addr)
.cloned()
.collect();
let external_addresses =
Swarm::<Behaviour<B, Client>>::external_addresses(&this.network_service)
.map(|r| &r.addr)
.cloned()
.collect();
*this.external_addresses.lock() = external_addresses;
}
@@ -2113,17 +2153,46 @@ impl<B: BlockT + 'static, H: ExHashT> Future for NetworkWorker<B, H> {
}
}
impl<B: BlockT + 'static, H: ExHashT> Unpin for NetworkWorker<B, H> {}
/// The libp2p swarm, customized for our needs.
type Swarm<B> = libp2p::swarm::Swarm<Behaviour<B>>;
// Implementation of `import_queue::Link` trait using the available local variables.
struct NetworkLink<'a, B: BlockT> {
protocol: &'a mut Swarm<B>,
impl<B, H, Client> Unpin for NetworkWorker<B, H, Client>
where
B: BlockT + 'static,
H: ExHashT,
Client: HeaderBackend<B>
+ BlockBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ ProofProvider<B>
+ Send
+ Sync
+ 'static,
{
}
impl<'a, B: BlockT> Link<B> for NetworkLink<'a, B> {
// Implementation of `import_queue::Link` trait using the available local variables.
struct NetworkLink<'a, B, Client>
where
B: BlockT,
Client: HeaderBackend<B>
+ BlockBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ ProofProvider<B>
+ Send
+ Sync
+ 'static,
{
protocol: &'a mut Swarm<Behaviour<B, Client>>,
}
impl<'a, B, Client> Link<B> for NetworkLink<'a, B, Client>
where
B: BlockT,
Client: HeaderBackend<B>
+ BlockBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ ProofProvider<B>
+ Send
+ Sync
+ 'static,
{
fn blocks_processed(
&mut self,
imported: usize,