mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-18 15:15:42 +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:
@@ -59,7 +59,10 @@ use crate::{
|
||||
use gossip::{
|
||||
FullCatchUpMessage, FullCommitMessage, GossipMessage, GossipValidator, PeerReport, VoteMessage,
|
||||
};
|
||||
use sc_network_common::service::{NetworkBlock, NetworkSyncForkRequest};
|
||||
use sc_network_common::{
|
||||
service::{NetworkBlock, NetworkSyncForkRequest},
|
||||
sync::SyncEventStream,
|
||||
};
|
||||
use sc_utils::mpsc::TracingUnboundedReceiver;
|
||||
use sp_consensus_grandpa::{AuthorityId, AuthoritySignature, RoundNumber, SetId as SetIdNumber};
|
||||
|
||||
@@ -163,24 +166,35 @@ const TELEMETRY_VOTERS_LIMIT: usize = 10;
|
||||
|
||||
/// A handle to the network.
|
||||
///
|
||||
/// Something that provides both the capabilities needed for the `gossip_network::Network` trait as
|
||||
/// well as the ability to set a fork sync request for a particular block.
|
||||
pub trait Network<Block: BlockT>:
|
||||
/// Something that provides the capabilities needed for the `gossip_network::Network` trait.
|
||||
pub trait Network<Block: BlockT>: GossipNetwork<Block> + Clone + Send + 'static {}
|
||||
|
||||
impl<Block, T> Network<Block> for T
|
||||
where
|
||||
Block: BlockT,
|
||||
T: GossipNetwork<Block> + Clone + Send + 'static,
|
||||
{
|
||||
}
|
||||
|
||||
/// A handle to syncing-related services.
|
||||
///
|
||||
/// Something that provides the ability to set a fork sync request for a particular block.
|
||||
pub trait Syncing<Block: BlockT>:
|
||||
NetworkSyncForkRequest<Block::Hash, NumberFor<Block>>
|
||||
+ NetworkBlock<Block::Hash, NumberFor<Block>>
|
||||
+ GossipNetwork<Block>
|
||||
+ SyncEventStream
|
||||
+ Clone
|
||||
+ Send
|
||||
+ 'static
|
||||
{
|
||||
}
|
||||
|
||||
impl<Block, T> Network<Block> for T
|
||||
impl<Block, T> Syncing<Block> for T
|
||||
where
|
||||
Block: BlockT,
|
||||
T: NetworkSyncForkRequest<Block::Hash, NumberFor<Block>>
|
||||
+ NetworkBlock<Block::Hash, NumberFor<Block>>
|
||||
+ GossipNetwork<Block>
|
||||
+ SyncEventStream
|
||||
+ Clone
|
||||
+ Send
|
||||
+ 'static,
|
||||
@@ -198,8 +212,9 @@ pub(crate) fn global_topic<B: BlockT>(set_id: SetIdNumber) -> B::Hash {
|
||||
}
|
||||
|
||||
/// Bridge between the underlying network service, gossiping consensus messages and Grandpa
|
||||
pub(crate) struct NetworkBridge<B: BlockT, N: Network<B>> {
|
||||
pub(crate) struct NetworkBridge<B: BlockT, N: Network<B>, S: Syncing<B>> {
|
||||
service: N,
|
||||
sync: S,
|
||||
gossip_engine: Arc<Mutex<GossipEngine<B>>>,
|
||||
validator: Arc<GossipValidator<B>>,
|
||||
|
||||
@@ -225,15 +240,16 @@ pub(crate) struct NetworkBridge<B: BlockT, N: Network<B>> {
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
}
|
||||
|
||||
impl<B: BlockT, N: Network<B>> Unpin for NetworkBridge<B, N> {}
|
||||
impl<B: BlockT, N: Network<B>, S: Syncing<B>> Unpin for NetworkBridge<B, N, S> {}
|
||||
|
||||
impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
|
||||
impl<B: BlockT, N: Network<B>, S: Syncing<B>> NetworkBridge<B, N, S> {
|
||||
/// Create a new NetworkBridge to the given NetworkService. Returns the service
|
||||
/// handle.
|
||||
/// On creation it will register previous rounds' votes with the gossip
|
||||
/// service taken from the VoterSetState.
|
||||
pub(crate) fn new(
|
||||
service: N,
|
||||
sync: S,
|
||||
config: crate::Config,
|
||||
set_state: crate::environment::SharedVoterSetState<B>,
|
||||
prometheus_registry: Option<&Registry>,
|
||||
@@ -246,6 +262,7 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
|
||||
let validator = Arc::new(validator);
|
||||
let gossip_engine = Arc::new(Mutex::new(GossipEngine::new(
|
||||
service.clone(),
|
||||
sync.clone(),
|
||||
protocol,
|
||||
validator.clone(),
|
||||
prometheus_registry,
|
||||
@@ -290,6 +307,7 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
|
||||
|
||||
NetworkBridge {
|
||||
service,
|
||||
sync,
|
||||
gossip_engine,
|
||||
validator,
|
||||
neighbor_sender: neighbor_packet_sender,
|
||||
@@ -475,11 +493,11 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
|
||||
hash: B::Hash,
|
||||
number: NumberFor<B>,
|
||||
) {
|
||||
self.service.set_sync_fork_request(peers, hash, number)
|
||||
self.sync.set_sync_fork_request(peers, hash, number)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT, N: Network<B>> Future for NetworkBridge<B, N> {
|
||||
impl<B: BlockT, N: Network<B>, S: Syncing<B>> Future for NetworkBridge<B, N, S> {
|
||||
type Output = Result<(), Error>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
@@ -661,10 +679,11 @@ fn incoming_global<B: BlockT>(
|
||||
})
|
||||
}
|
||||
|
||||
impl<B: BlockT, N: Network<B>> Clone for NetworkBridge<B, N> {
|
||||
impl<B: BlockT, N: Network<B>, S: Syncing<B>> Clone for NetworkBridge<B, N, S> {
|
||||
fn clone(&self) -> Self {
|
||||
NetworkBridge {
|
||||
service: self.service.clone(),
|
||||
sync: self.sync.clone(),
|
||||
gossip_engine: self.gossip_engine.clone(),
|
||||
validator: Arc::clone(&self.validator),
|
||||
neighbor_sender: self.neighbor_sender.clone(),
|
||||
|
||||
@@ -33,6 +33,7 @@ use sc_network_common::{
|
||||
NetworkBlock, NetworkEventStream, NetworkNotification, NetworkPeers,
|
||||
NetworkSyncForkRequest, NotificationSender, NotificationSenderError,
|
||||
},
|
||||
sync::{SyncEvent as SyncStreamEvent, SyncEventStream},
|
||||
};
|
||||
use sc_network_gossip::Validator;
|
||||
use sc_network_test::{Block, Hash};
|
||||
@@ -153,6 +154,10 @@ impl NetworkNotification for TestNetwork {
|
||||
) -> Result<Box<dyn NotificationSender>, NotificationSenderError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_notification_handshake(&self, _protocol: ProtocolName, _handshake: Vec<u8>) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkBlock<Hash, NumberFor<Block>> for TestNetwork {
|
||||
@@ -186,8 +191,34 @@ impl sc_network_gossip::ValidatorContext<Block> for TestNetwork {
|
||||
fn send_topic(&mut self, _: &PeerId, _: Hash, _: bool) {}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct TestSync;
|
||||
|
||||
impl SyncEventStream for TestSync {
|
||||
fn event_stream(
|
||||
&self,
|
||||
_name: &'static str,
|
||||
) -> Pin<Box<dyn Stream<Item = SyncStreamEvent> + Send>> {
|
||||
Box::pin(futures::stream::pending())
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkBlock<Hash, NumberFor<Block>> for TestSync {
|
||||
fn announce_block(&self, _hash: Hash, _data: Option<Vec<u8>>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn new_best_block_imported(&self, _hash: Hash, _number: NumberFor<Block>) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkSyncForkRequest<Hash, NumberFor<Block>> for TestSync {
|
||||
fn set_sync_fork_request(&self, _peers: Vec<PeerId>, _hash: Hash, _number: NumberFor<Block>) {}
|
||||
}
|
||||
|
||||
pub(crate) struct Tester {
|
||||
pub(crate) net_handle: super::NetworkBridge<Block, TestNetwork>,
|
||||
pub(crate) net_handle: super::NetworkBridge<Block, TestNetwork, TestSync>,
|
||||
gossip_validator: Arc<GossipValidator<Block>>,
|
||||
pub(crate) events: TracingUnboundedReceiver<Event>,
|
||||
}
|
||||
@@ -255,6 +286,7 @@ fn voter_set_state() -> SharedVoterSetState<Block> {
|
||||
pub(crate) fn make_test_network() -> (impl Future<Output = Tester>, TestNetwork) {
|
||||
let (tx, rx) = tracing_unbounded("test", 100_000);
|
||||
let net = TestNetwork { sender: tx };
|
||||
let sync = TestSync {};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Exit;
|
||||
@@ -267,7 +299,8 @@ pub(crate) fn make_test_network() -> (impl Future<Output = Tester>, TestNetwork)
|
||||
}
|
||||
}
|
||||
|
||||
let bridge = super::NetworkBridge::new(net.clone(), config(), voter_set_state(), None, None);
|
||||
let bridge =
|
||||
super::NetworkBridge::new(net.clone(), sync, config(), voter_set_state(), None, None);
|
||||
|
||||
(
|
||||
futures::future::ready(Tester {
|
||||
@@ -370,6 +403,7 @@ fn good_commit_leads_to_relay() {
|
||||
protocol: grandpa_protocol_name::NAME.into(),
|
||||
negotiated_fallback: None,
|
||||
role: ObservedRole::Full,
|
||||
received_handshake: vec![],
|
||||
});
|
||||
|
||||
let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived {
|
||||
@@ -387,6 +421,7 @@ fn good_commit_leads_to_relay() {
|
||||
protocol: grandpa_protocol_name::NAME.into(),
|
||||
negotiated_fallback: None,
|
||||
role: ObservedRole::Full,
|
||||
received_handshake: vec![],
|
||||
});
|
||||
|
||||
// Announce its local set has being on the current set id through a neighbor
|
||||
@@ -519,6 +554,7 @@ fn bad_commit_leads_to_report() {
|
||||
protocol: grandpa_protocol_name::NAME.into(),
|
||||
negotiated_fallback: None,
|
||||
role: ObservedRole::Full,
|
||||
received_handshake: vec![],
|
||||
});
|
||||
let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived {
|
||||
remote: sender_id,
|
||||
|
||||
Reference in New Issue
Block a user