mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 21:21:11 +00:00
Extract syncing protocol from sc-network (#12828)
* 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. * Move stuff to SyncingEngine * Move `ChainSync` instanation to `SyncingEngine` Some of the tests have to be rewritten * Move peer hashmap to `SyncingEngine` * Let `SyncingEngine` to implement `ChainSyncInterface` * Introduce `SyncStatusProvider` * Move `sync_peer_(connected|disconnected)` to `SyncingEngine` * Implement `SyncEventStream` Remove `SyncConnected`/`SyncDisconnected` events from `NetworkEvenStream` and provide those events through `ChainSyncInterface` instead. Modify BEEFY/GRANDPA/transactions protocol and `NetworkGossip` to take `SyncEventStream` object which they listen to for incoming sync peer events. * Introduce `ChainSyncInterface` This interface provides a set of miscellaneous functions that other subsystems can use to query, for example, the syncing status. * Move event stream polling to `SyncingEngine` Subscribe to `NetworkStreamEvent` and poll the incoming notifications and substream events from `SyncingEngine`. The code needs refactoring. * Make `SyncingEngine` into an asynchronous runner This commits removes the last hard dependency of syncing from `sc-network` meaning the protocol now lives completely outside of `sc-network`, ignoring the hardcoded peerset entry which will be addressed in the future. Code needs a lot of refactoring. * Fix warnings * Code refactoring * Use `SyncingService` for BEEFY * Use `SyncingService` for GRANDPA * Remove call delegation from `NetworkService` * Remove `ChainSyncService` * Remove `ChainSync` service tests They were written for the sole purpose of verifying that `NetworWorker` continues to function while the calls are being dispatched to `ChainSync`. * Refactor code * Refactor code * Update client/finality-grandpa/src/communication/tests.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * Fix warnings * Apply review comments * Fix docs * Fix test * cargo-fmt * Update client/network/sync/src/engine.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * Update client/network/sync/src/engine.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * Add missing docs * Refactor code --------- Co-authored-by: Anton <anton.kalyaev@gmail.com>
This commit is contained in:
@@ -37,6 +37,7 @@ use sc_network_common::{
|
||||
error,
|
||||
protocol::{event::Event, role::ObservedRole, ProtocolName},
|
||||
service::{NetworkEventStream, NetworkNotification, NetworkPeers},
|
||||
sync::{SyncEvent, SyncEventStream},
|
||||
utils::{interval, LruHashSet},
|
||||
ExHashT,
|
||||
};
|
||||
@@ -161,14 +162,17 @@ impl TransactionsHandlerPrototype {
|
||||
pub fn build<
|
||||
B: BlockT + 'static,
|
||||
H: ExHashT,
|
||||
S: NetworkPeers + NetworkEventStream + NetworkNotification + sp_consensus::SyncOracle,
|
||||
N: NetworkPeers + NetworkEventStream + NetworkNotification,
|
||||
S: SyncEventStream + sp_consensus::SyncOracle,
|
||||
>(
|
||||
self,
|
||||
service: S,
|
||||
network: N,
|
||||
sync: S,
|
||||
transaction_pool: Arc<dyn TransactionPool<H, B>>,
|
||||
metrics_registry: Option<&Registry>,
|
||||
) -> error::Result<(TransactionsHandler<B, H, S>, TransactionsHandlerController<H>)> {
|
||||
let event_stream = service.event_stream("transactions-handler");
|
||||
) -> error::Result<(TransactionsHandler<B, H, N, S>, TransactionsHandlerController<H>)> {
|
||||
let net_event_stream = network.event_stream("transactions-handler-net");
|
||||
let sync_event_stream = sync.event_stream("transactions-handler-sync");
|
||||
let (to_handler, from_controller) = tracing_unbounded("mpsc_transactions_handler", 100_000);
|
||||
|
||||
let handler = TransactionsHandler {
|
||||
@@ -178,8 +182,10 @@ impl TransactionsHandlerPrototype {
|
||||
.fuse(),
|
||||
pending_transactions: FuturesUnordered::new(),
|
||||
pending_transactions_peers: HashMap::new(),
|
||||
service,
|
||||
event_stream: event_stream.fuse(),
|
||||
network,
|
||||
sync,
|
||||
net_event_stream: net_event_stream.fuse(),
|
||||
sync_event_stream: sync_event_stream.fuse(),
|
||||
peers: HashMap::new(),
|
||||
transaction_pool,
|
||||
from_controller,
|
||||
@@ -228,7 +234,8 @@ enum ToHandler<H: ExHashT> {
|
||||
pub struct TransactionsHandler<
|
||||
B: BlockT + 'static,
|
||||
H: ExHashT,
|
||||
S: NetworkPeers + NetworkEventStream + NetworkNotification + sp_consensus::SyncOracle,
|
||||
N: NetworkPeers + NetworkEventStream + NetworkNotification,
|
||||
S: SyncEventStream + sp_consensus::SyncOracle,
|
||||
> {
|
||||
protocol_name: ProtocolName,
|
||||
/// Interval at which we call `propagate_transactions`.
|
||||
@@ -241,9 +248,13 @@ pub struct TransactionsHandler<
|
||||
/// multiple times concurrently.
|
||||
pending_transactions_peers: HashMap<H, Vec<PeerId>>,
|
||||
/// Network service to use to send messages and manage peers.
|
||||
service: S,
|
||||
network: N,
|
||||
/// Syncing service.
|
||||
sync: S,
|
||||
/// Stream of networking events.
|
||||
event_stream: stream::Fuse<Pin<Box<dyn Stream<Item = Event> + Send>>>,
|
||||
net_event_stream: stream::Fuse<Pin<Box<dyn Stream<Item = Event> + Send>>>,
|
||||
/// Receiver for syncing-related events.
|
||||
sync_event_stream: stream::Fuse<Pin<Box<dyn Stream<Item = SyncEvent> + Send>>>,
|
||||
// All connected peers
|
||||
peers: HashMap<PeerId, Peer<H>>,
|
||||
transaction_pool: Arc<dyn TransactionPool<H, B>>,
|
||||
@@ -260,11 +271,12 @@ struct Peer<H: ExHashT> {
|
||||
role: ObservedRole,
|
||||
}
|
||||
|
||||
impl<B, H, S> TransactionsHandler<B, H, S>
|
||||
impl<B, H, N, S> TransactionsHandler<B, H, N, S>
|
||||
where
|
||||
B: BlockT + 'static,
|
||||
H: ExHashT,
|
||||
S: NetworkPeers + NetworkEventStream + NetworkNotification + sp_consensus::SyncOracle,
|
||||
N: NetworkPeers + NetworkEventStream + NetworkNotification,
|
||||
S: SyncEventStream + sp_consensus::SyncOracle,
|
||||
{
|
||||
/// Turns the [`TransactionsHandler`] into a future that should run forever and not be
|
||||
/// interrupted.
|
||||
@@ -281,7 +293,7 @@ where
|
||||
warn!(target: "sub-libp2p", "Inconsistent state, no peers for pending transaction!");
|
||||
}
|
||||
},
|
||||
network_event = self.event_stream.next() => {
|
||||
network_event = self.net_event_stream.next() => {
|
||||
if let Some(network_event) = network_event {
|
||||
self.handle_network_event(network_event).await;
|
||||
} else {
|
||||
@@ -289,6 +301,14 @@ where
|
||||
return;
|
||||
}
|
||||
},
|
||||
sync_event = self.sync_event_stream.next() => {
|
||||
if let Some(sync_event) = sync_event {
|
||||
self.handle_sync_event(sync_event);
|
||||
} else {
|
||||
// Syncing has seemingly closed. Closing as well.
|
||||
return;
|
||||
}
|
||||
}
|
||||
message = self.from_controller.select_next_some() => {
|
||||
match message {
|
||||
ToHandler::PropagateTransaction(hash) => self.propagate_transaction(&hash),
|
||||
@@ -299,13 +319,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_network_event(&mut self, event: Event) {
|
||||
fn handle_sync_event(&mut self, event: SyncEvent) {
|
||||
match event {
|
||||
Event::Dht(_) => {},
|
||||
Event::SyncConnected { remote } => {
|
||||
SyncEvent::PeerConnected(remote) => {
|
||||
let addr = iter::once(multiaddr::Protocol::P2p(remote.into()))
|
||||
.collect::<multiaddr::Multiaddr>();
|
||||
let result = self.service.add_peers_to_reserved_set(
|
||||
let result = self.network.add_peers_to_reserved_set(
|
||||
self.protocol_name.clone(),
|
||||
iter::once(addr).collect(),
|
||||
);
|
||||
@@ -313,13 +332,18 @@ where
|
||||
log::error!(target: "sync", "Add reserved peer failed: {}", err);
|
||||
}
|
||||
},
|
||||
Event::SyncDisconnected { remote } => {
|
||||
self.service.remove_peers_from_reserved_set(
|
||||
SyncEvent::PeerDisconnected(remote) => {
|
||||
self.network.remove_peers_from_reserved_set(
|
||||
self.protocol_name.clone(),
|
||||
iter::once(remote).collect(),
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_network_event(&mut self, event: Event) {
|
||||
match event {
|
||||
Event::Dht(_) => {},
|
||||
Event::NotificationStreamOpened { remote, protocol, role, .. }
|
||||
if protocol == self.protocol_name =>
|
||||
{
|
||||
@@ -365,7 +389,7 @@ where
|
||||
/// Called when peer sends us new transactions
|
||||
fn on_transactions(&mut self, who: PeerId, transactions: Transactions<B::Extrinsic>) {
|
||||
// Accept transactions only when node is not major syncing
|
||||
if self.service.is_major_syncing() {
|
||||
if self.sync.is_major_syncing() {
|
||||
trace!(target: "sync", "{} Ignoring transactions while major syncing", who);
|
||||
return
|
||||
}
|
||||
@@ -385,7 +409,7 @@ where
|
||||
let hash = self.transaction_pool.hash_of(&t);
|
||||
peer.known_transactions.insert(hash.clone());
|
||||
|
||||
self.service.report_peer(who, rep::ANY_TRANSACTION);
|
||||
self.network.report_peer(who, rep::ANY_TRANSACTION);
|
||||
|
||||
match self.pending_transactions_peers.entry(hash.clone()) {
|
||||
Entry::Vacant(entry) => {
|
||||
@@ -406,9 +430,9 @@ where
|
||||
fn on_handle_transaction_import(&mut self, who: PeerId, import: TransactionImport) {
|
||||
match import {
|
||||
TransactionImport::KnownGood =>
|
||||
self.service.report_peer(who, rep::ANY_TRANSACTION_REFUND),
|
||||
TransactionImport::NewGood => self.service.report_peer(who, rep::GOOD_TRANSACTION),
|
||||
TransactionImport::Bad => self.service.report_peer(who, rep::BAD_TRANSACTION),
|
||||
self.network.report_peer(who, rep::ANY_TRANSACTION_REFUND),
|
||||
TransactionImport::NewGood => self.network.report_peer(who, rep::GOOD_TRANSACTION),
|
||||
TransactionImport::Bad => self.network.report_peer(who, rep::BAD_TRANSACTION),
|
||||
TransactionImport::None => {},
|
||||
}
|
||||
}
|
||||
@@ -416,7 +440,7 @@ where
|
||||
/// Propagate one transaction.
|
||||
pub fn propagate_transaction(&mut self, hash: &H) {
|
||||
// Accept transactions only when node is not major syncing
|
||||
if self.service.is_major_syncing() {
|
||||
if self.sync.is_major_syncing() {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -453,7 +477,7 @@ where
|
||||
propagated_to.entry(hash).or_default().push(who.to_base58());
|
||||
}
|
||||
trace!(target: "sync", "Sending {} transactions to {}", to_send.len(), who);
|
||||
self.service
|
||||
self.network
|
||||
.write_notification(*who, self.protocol_name.clone(), to_send.encode());
|
||||
}
|
||||
}
|
||||
@@ -468,7 +492,7 @@ where
|
||||
/// Call when we must propagate ready transactions to peers.
|
||||
fn propagate_transactions(&mut self) {
|
||||
// Accept transactions only when node is not major syncing
|
||||
if self.service.is_major_syncing() {
|
||||
if self.sync.is_major_syncing() {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user