mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 22:51:13 +00:00
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:
@@ -32,7 +32,6 @@ use libp2p::{
|
||||
NetworkBehaviour,
|
||||
};
|
||||
|
||||
use sc_consensus::import_queue::{IncomingBlock, RuntimeOrigin};
|
||||
use sc_network_common::{
|
||||
protocol::{
|
||||
event::DhtEvent,
|
||||
@@ -43,18 +42,14 @@ use sc_network_common::{
|
||||
};
|
||||
use sc_peerset::{PeersetHandle, ReputationChange};
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_consensus::BlockOrigin;
|
||||
use sp_runtime::{
|
||||
traits::{Block as BlockT, NumberFor},
|
||||
Justifications,
|
||||
};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::{collections::HashSet, time::Duration};
|
||||
|
||||
pub use crate::request_responses::{InboundFailure, OutboundFailure, RequestId, ResponseFailure};
|
||||
|
||||
/// General behaviour of the network. Combines all protocols together.
|
||||
#[derive(NetworkBehaviour)]
|
||||
#[behaviour(out_event = "BehaviourOut<B>")]
|
||||
#[behaviour(out_event = "BehaviourOut")]
|
||||
pub struct Behaviour<B, Client>
|
||||
where
|
||||
B: BlockT,
|
||||
@@ -72,10 +67,7 @@ where
|
||||
}
|
||||
|
||||
/// Event generated by `Behaviour`.
|
||||
pub enum BehaviourOut<B: BlockT> {
|
||||
BlockImport(BlockOrigin, Vec<IncomingBlock<B>>),
|
||||
JustificationImport(RuntimeOrigin, B::Hash, NumberFor<B>, Justifications),
|
||||
|
||||
pub enum BehaviourOut {
|
||||
/// Started a random iterative Kademlia discovery query.
|
||||
RandomKademliaStarted,
|
||||
|
||||
@@ -107,10 +99,7 @@ pub enum BehaviourOut<B: BlockT> {
|
||||
},
|
||||
|
||||
/// A request protocol handler issued reputation changes for the given peer.
|
||||
ReputationChanges {
|
||||
peer: PeerId,
|
||||
changes: Vec<ReputationChange>,
|
||||
},
|
||||
ReputationChanges { peer: PeerId, changes: Vec<ReputationChange> },
|
||||
|
||||
/// Opened a substream with the given node with the given notifications protocol.
|
||||
///
|
||||
@@ -306,13 +295,9 @@ fn reported_roles_to_observed_role(roles: Roles) -> ObservedRole {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT> From<CustomMessageOutcome<B>> for BehaviourOut<B> {
|
||||
impl<B: BlockT> From<CustomMessageOutcome<B>> for BehaviourOut {
|
||||
fn from(event: CustomMessageOutcome<B>) -> Self {
|
||||
match event {
|
||||
CustomMessageOutcome::BlockImport(origin, blocks) =>
|
||||
BehaviourOut::BlockImport(origin, blocks),
|
||||
CustomMessageOutcome::JustificationImport(origin, hash, nb, justification) =>
|
||||
BehaviourOut::JustificationImport(origin, hash, nb, justification),
|
||||
CustomMessageOutcome::NotificationStreamOpened {
|
||||
remote,
|
||||
protocol,
|
||||
@@ -344,7 +329,7 @@ impl<B: BlockT> From<CustomMessageOutcome<B>> for BehaviourOut<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT> From<request_responses::Event> for BehaviourOut<B> {
|
||||
impl From<request_responses::Event> for BehaviourOut {
|
||||
fn from(event: request_responses::Event) -> Self {
|
||||
match event {
|
||||
request_responses::Event::InboundRequest { peer, protocol, result } =>
|
||||
@@ -357,14 +342,14 @@ impl<B: BlockT> From<request_responses::Event> for BehaviourOut<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT> From<peer_info::PeerInfoEvent> for BehaviourOut<B> {
|
||||
impl From<peer_info::PeerInfoEvent> for BehaviourOut {
|
||||
fn from(event: peer_info::PeerInfoEvent) -> Self {
|
||||
let peer_info::PeerInfoEvent::Identified { peer_id, info } = event;
|
||||
BehaviourOut::PeerIdentify { peer_id, info }
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT> From<DiscoveryOut> for BehaviourOut<B> {
|
||||
impl From<DiscoveryOut> for BehaviourOut {
|
||||
fn from(event: DiscoveryOut) -> Self {
|
||||
match event {
|
||||
DiscoveryOut::UnroutablePeer(_peer_id) => {
|
||||
|
||||
@@ -40,7 +40,6 @@ use libp2p::{
|
||||
multiaddr, Multiaddr,
|
||||
};
|
||||
use prometheus_endpoint::Registry;
|
||||
use sc_consensus::ImportQueue;
|
||||
use sc_network_common::{
|
||||
config::{MultiaddrWithPeerId, NonDefaultSetConfig, SetConfig, TransportConfig},
|
||||
sync::ChainSync,
|
||||
@@ -82,12 +81,6 @@ where
|
||||
/// name on the wire.
|
||||
pub fork_id: Option<String>,
|
||||
|
||||
/// Import queue to use.
|
||||
///
|
||||
/// The import queue is the component that verifies that blocks received from other nodes are
|
||||
/// valid.
|
||||
pub import_queue: Box<dyn ImportQueue<B>>,
|
||||
|
||||
/// Instance of chain sync implementation.
|
||||
pub chain_sync: Box<dyn ChainSync<B>>,
|
||||
|
||||
|
||||
@@ -258,6 +258,7 @@ pub mod network_state;
|
||||
#[doc(inline)]
|
||||
pub use libp2p::{multiaddr, Multiaddr, PeerId};
|
||||
pub use protocol::PeerInfo;
|
||||
use sc_consensus::{JustificationSyncLink, Link};
|
||||
pub use sc_network_common::{
|
||||
protocol::{
|
||||
event::{DhtEvent, Event},
|
||||
@@ -297,11 +298,15 @@ const MAX_CONNECTIONS_ESTABLISHED_INCOMING: u32 = 10_000;
|
||||
|
||||
/// Abstraction over syncing-related services
|
||||
pub trait ChainSyncInterface<B: BlockT>:
|
||||
NetworkSyncForkRequest<B::Hash, NumberFor<B>> + Send + Sync
|
||||
NetworkSyncForkRequest<B::Hash, NumberFor<B>> + JustificationSyncLink<B> + Link<B> + Send + Sync
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, B: BlockT> ChainSyncInterface<B> for T where
|
||||
T: NetworkSyncForkRequest<B::Hash, NumberFor<B>> + Send + Sync
|
||||
T: NetworkSyncForkRequest<B::Hash, NumberFor<B>>
|
||||
+ JustificationSyncLink<B>
|
||||
+ Link<B>
|
||||
+ Send
|
||||
+ Sync
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,32 +29,26 @@ use libp2p::{
|
||||
},
|
||||
Multiaddr, PeerId,
|
||||
};
|
||||
use log::{debug, error, info, log, trace, warn, Level};
|
||||
use log::{debug, error, log, trace, warn, Level};
|
||||
use lru::LruCache;
|
||||
use message::{generic::Message as GenericMessage, Message};
|
||||
use notifications::{Notifications, NotificationsOut};
|
||||
use prometheus_endpoint::{register, Gauge, GaugeVec, Opts, PrometheusError, Registry, U64};
|
||||
use sc_client_api::HeaderBackend;
|
||||
use sc_consensus::import_queue::{
|
||||
BlockImportError, BlockImportStatus, IncomingBlock, RuntimeOrigin,
|
||||
};
|
||||
use sc_network_common::{
|
||||
config::NonReservedPeerMode,
|
||||
error,
|
||||
protocol::{role::Roles, ProtocolName},
|
||||
sync::{
|
||||
message::{BlockAnnounce, BlockAnnouncesHandshake, BlockData, BlockResponse, BlockState},
|
||||
BadPeer, ChainSync, ImportResult, OnBlockData, PollBlockAnnounceValidation, PollResult,
|
||||
SyncStatus,
|
||||
BadPeer, ChainSync, PollBlockAnnounceValidation, SyncStatus,
|
||||
},
|
||||
utils::{interval, LruHashSet},
|
||||
};
|
||||
use sp_arithmetic::traits::SaturatedConversion;
|
||||
use sp_consensus::BlockOrigin;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, CheckedSub, Header as HeaderT, NumberFor, Zero},
|
||||
Justifications,
|
||||
};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet, VecDeque},
|
||||
@@ -481,12 +475,7 @@ where
|
||||
}
|
||||
|
||||
if let Some(_peer_data) = self.peers.remove(&peer) {
|
||||
if let Some(OnBlockData::Import(origin, blocks)) =
|
||||
self.chain_sync.peer_disconnected(&peer)
|
||||
{
|
||||
self.pending_messages
|
||||
.push_back(CustomMessageOutcome::BlockImport(origin, blocks));
|
||||
}
|
||||
self.chain_sync.peer_disconnected(&peer);
|
||||
self.default_peers_set_no_slot_connected_peers.remove(&peer);
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -785,25 +774,13 @@ where
|
||||
}],
|
||||
},
|
||||
);
|
||||
self.chain_sync.process_block_response_data(blocks_to_import);
|
||||
|
||||
if is_best {
|
||||
self.pending_messages.push_back(CustomMessageOutcome::PeerNewBest(who, number));
|
||||
}
|
||||
|
||||
match blocks_to_import {
|
||||
Ok(OnBlockData::Import(origin, blocks)) =>
|
||||
CustomMessageOutcome::BlockImport(origin, blocks),
|
||||
Ok(OnBlockData::Request(peer, req)) => {
|
||||
self.chain_sync.send_block_request(peer, req);
|
||||
CustomMessageOutcome::None
|
||||
},
|
||||
Ok(OnBlockData::Continue) => CustomMessageOutcome::None,
|
||||
Err(BadPeer(id, repu)) => {
|
||||
self.behaviour.disconnect_peer(&id, HARDCODED_PEERSETS_SYNC);
|
||||
self.peerset_handle.report_peer(id, repu);
|
||||
CustomMessageOutcome::None
|
||||
},
|
||||
}
|
||||
CustomMessageOutcome::None
|
||||
}
|
||||
|
||||
/// Call this when a block has been finalized. The sync layer may have some additional
|
||||
@@ -812,58 +789,6 @@ where
|
||||
self.chain_sync.on_block_finalized(&hash, *header.number())
|
||||
}
|
||||
|
||||
/// Request a justification for the given block.
|
||||
///
|
||||
/// Uses `protocol` to queue a new justification request and tries to dispatch all pending
|
||||
/// requests.
|
||||
pub fn request_justification(&mut self, hash: &B::Hash, number: NumberFor<B>) {
|
||||
self.chain_sync.request_justification(hash, number)
|
||||
}
|
||||
|
||||
/// Clear all pending justification requests.
|
||||
pub fn clear_justification_requests(&mut self) {
|
||||
self.chain_sync.clear_justification_requests();
|
||||
}
|
||||
|
||||
/// 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 on_blocks_processed(
|
||||
&mut self,
|
||||
imported: usize,
|
||||
count: usize,
|
||||
results: Vec<(Result<BlockImportStatus<NumberFor<B>>, BlockImportError>, B::Hash)>,
|
||||
) {
|
||||
let results = self.chain_sync.on_blocks_processed(imported, count, results);
|
||||
for result in results {
|
||||
match result {
|
||||
Ok((id, req)) => self.chain_sync.send_block_request(id, req),
|
||||
Err(BadPeer(id, repu)) => {
|
||||
self.behaviour.disconnect_peer(&id, HARDCODED_PEERSETS_SYNC);
|
||||
self.peerset_handle.report_peer(id, repu)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Call this when a justification has been processed by the import queue, with or without
|
||||
/// errors.
|
||||
pub fn justification_import_result(
|
||||
&mut self,
|
||||
who: PeerId,
|
||||
hash: B::Hash,
|
||||
number: NumberFor<B>,
|
||||
success: bool,
|
||||
) {
|
||||
self.chain_sync.on_justification_import(hash, number, success);
|
||||
if !success {
|
||||
info!("💔 Invalid justification provided by {} for #{}", who, hash);
|
||||
self.behaviour.disconnect_peer(&who, HARDCODED_PEERSETS_SYNC);
|
||||
self.peerset_handle
|
||||
.report_peer(who, sc_peerset::ReputationChange::new_fatal("Invalid justification"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Set whether the syncing peers set is in reserved-only mode.
|
||||
pub fn set_reserved_only(&self, reserved_only: bool) {
|
||||
self.peerset_handle.set_reserved_only(HARDCODED_PEERSETS_SYNC, reserved_only);
|
||||
@@ -997,8 +922,6 @@ where
|
||||
#[derive(Debug)]
|
||||
#[must_use]
|
||||
pub enum CustomMessageOutcome<B: BlockT> {
|
||||
BlockImport(BlockOrigin, Vec<IncomingBlock<B>>),
|
||||
JustificationImport(RuntimeOrigin, B::Hash, NumberFor<B>, Justifications),
|
||||
/// Notification protocols have been opened with a remote.
|
||||
NotificationStreamOpened {
|
||||
remote: PeerId,
|
||||
@@ -1106,23 +1029,9 @@ where
|
||||
// Process any received requests received from `NetworkService` and
|
||||
// check if there is any block announcement validation finished.
|
||||
while let Poll::Ready(result) = self.chain_sync.poll(cx) {
|
||||
match result {
|
||||
PollResult::Import(import) => self.pending_messages.push_back(match import {
|
||||
ImportResult::BlockImport(origin, blocks) =>
|
||||
CustomMessageOutcome::BlockImport(origin, blocks),
|
||||
ImportResult::JustificationImport(origin, hash, number, justifications) =>
|
||||
CustomMessageOutcome::JustificationImport(
|
||||
origin,
|
||||
hash,
|
||||
number,
|
||||
justifications,
|
||||
),
|
||||
}),
|
||||
PollResult::Announce(announce) =>
|
||||
match self.process_block_announce_validation_result(announce) {
|
||||
CustomMessageOutcome::None => {},
|
||||
outcome => self.pending_messages.push_back(outcome),
|
||||
},
|
||||
match self.process_block_announce_validation_result(result) {
|
||||
CustomMessageOutcome::None => {},
|
||||
outcome => self.pending_messages.push_back(outcome),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ use libp2p::{
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use metrics::{Histogram, HistogramVec, MetricSources, Metrics};
|
||||
use parking_lot::Mutex;
|
||||
use sc_consensus::{BlockImportError, BlockImportStatus, ImportQueue, Link};
|
||||
use sc_network_common::{
|
||||
config::{MultiaddrWithPeerId, TransportConfig},
|
||||
error::Error,
|
||||
@@ -450,7 +449,6 @@ where
|
||||
is_major_syncing,
|
||||
network_service: swarm,
|
||||
service,
|
||||
import_queue: params.import_queue,
|
||||
from_service,
|
||||
event_streams: out_events::OutChannels::new(params.metrics_registry.as_ref())?,
|
||||
peers_notifications_sinks,
|
||||
@@ -748,13 +746,11 @@ impl<B: BlockT, H: ExHashT> sc_consensus::JustificationSyncLink<B> for NetworkSe
|
||||
/// 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
|
||||
.to_worker
|
||||
.unbounded_send(ServiceToWorkerMsg::RequestJustification(*hash, number));
|
||||
let _ = self.chain_sync_service.request_justification(hash, number);
|
||||
}
|
||||
|
||||
fn clear_justification_requests(&self) {
|
||||
let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::ClearJustificationRequests);
|
||||
let _ = self.chain_sync_service.clear_justification_requests();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,8 +1204,6 @@ impl<'a> NotificationSenderReadyT for NotificationSenderReady<'a> {
|
||||
///
|
||||
/// Each entry corresponds to a method of `NetworkService`.
|
||||
enum ServiceToWorkerMsg<B: BlockT> {
|
||||
RequestJustification(B::Hash, NumberFor<B>),
|
||||
ClearJustificationRequests,
|
||||
AnnounceBlock(B::Hash, Option<Vec<u8>>),
|
||||
GetValue(KademliaKey),
|
||||
PutValue(KademliaKey, Vec<u8>),
|
||||
@@ -1261,8 +1255,6 @@ where
|
||||
service: Arc<NetworkService<B, H>>,
|
||||
/// The *actual* network.
|
||||
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.
|
||||
from_service: TracingUnboundedReceiver<ServiceToWorkerMsg<B>>,
|
||||
/// Senders for events that happen on the network.
|
||||
@@ -1290,10 +1282,6 @@ where
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context) -> Poll<Self::Output> {
|
||||
let this = &mut *self;
|
||||
|
||||
// Poll the import queue for actions to perform.
|
||||
this.import_queue
|
||||
.poll_actions(cx, &mut NetworkLink { protocol: &mut this.network_service });
|
||||
|
||||
// At the time of writing of this comment, due to a high volume of messages, the network
|
||||
// worker sometimes takes a long time to process the loop below. When that happens, the
|
||||
// rest of the polling is frozen. In order to avoid negative side-effects caused by this
|
||||
@@ -1322,16 +1310,6 @@ where
|
||||
.behaviour_mut()
|
||||
.user_protocol_mut()
|
||||
.announce_block(hash, data),
|
||||
ServiceToWorkerMsg::RequestJustification(hash, number) => this
|
||||
.network_service
|
||||
.behaviour_mut()
|
||||
.user_protocol_mut()
|
||||
.request_justification(&hash, number),
|
||||
ServiceToWorkerMsg::ClearJustificationRequests => this
|
||||
.network_service
|
||||
.behaviour_mut()
|
||||
.user_protocol_mut()
|
||||
.clear_justification_requests(),
|
||||
ServiceToWorkerMsg::GetValue(key) =>
|
||||
this.network_service.behaviour_mut().get_value(key),
|
||||
ServiceToWorkerMsg::PutValue(key, value) =>
|
||||
@@ -1435,23 +1413,6 @@ where
|
||||
|
||||
match poll_value {
|
||||
Poll::Pending => break,
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::BlockImport(origin, blocks))) => {
|
||||
if let Some(metrics) = this.metrics.as_ref() {
|
||||
metrics.import_queue_blocks_submitted.inc();
|
||||
}
|
||||
this.import_queue.import_blocks(origin, blocks);
|
||||
},
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::JustificationImport(
|
||||
origin,
|
||||
hash,
|
||||
nb,
|
||||
justifications,
|
||||
))) => {
|
||||
if let Some(metrics) = this.metrics.as_ref() {
|
||||
metrics.import_queue_justifications_submitted.inc();
|
||||
}
|
||||
this.import_queue.import_justifications(origin, hash, nb, justifications);
|
||||
},
|
||||
Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::InboundRequest {
|
||||
protocol,
|
||||
result,
|
||||
@@ -1952,51 +1913,6 @@ where
|
||||
{
|
||||
}
|
||||
|
||||
// Implementation of `import_queue::Link` trait using the available local variables.
|
||||
struct NetworkLink<'a, B, Client>
|
||||
where
|
||||
B: BlockT,
|
||||
Client: HeaderBackend<B> + '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> + 'static,
|
||||
{
|
||||
fn blocks_processed(
|
||||
&mut self,
|
||||
imported: usize,
|
||||
count: usize,
|
||||
results: Vec<(Result<BlockImportStatus<NumberFor<B>>, BlockImportError>, B::Hash)>,
|
||||
) {
|
||||
self.protocol
|
||||
.behaviour_mut()
|
||||
.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
|
||||
.behaviour_mut()
|
||||
.user_protocol_mut()
|
||||
.justification_import_result(who, *hash, number, success);
|
||||
}
|
||||
fn request_justification(&mut self, hash: &B::Hash, number: NumberFor<B>) {
|
||||
self.protocol
|
||||
.behaviour_mut()
|
||||
.user_protocol_mut()
|
||||
.request_justification(hash, number)
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_addresses_consistent_with_transport<'a>(
|
||||
addresses: impl Iterator<Item = &'a Multiaddr>,
|
||||
transport: &TransportConfig,
|
||||
|
||||
@@ -53,8 +53,6 @@ pub struct Metrics {
|
||||
pub connections_opened_total: CounterVec<U64>,
|
||||
pub distinct_peers_connections_closed_total: Counter<U64>,
|
||||
pub distinct_peers_connections_opened_total: Counter<U64>,
|
||||
pub import_queue_blocks_submitted: Counter<U64>,
|
||||
pub import_queue_justifications_submitted: Counter<U64>,
|
||||
pub incoming_connections_errors_total: CounterVec<U64>,
|
||||
pub incoming_connections_total: Counter<U64>,
|
||||
pub issued_light_requests: Counter<U64>,
|
||||
@@ -103,14 +101,6 @@ impl Metrics {
|
||||
"substrate_sub_libp2p_distinct_peers_connections_opened_total",
|
||||
"Total number of connections opened with distinct peers"
|
||||
)?, registry)?,
|
||||
import_queue_blocks_submitted: prometheus::register(Counter::new(
|
||||
"substrate_import_queue_blocks_submitted",
|
||||
"Number of blocks submitted to the import queue.",
|
||||
)?, registry)?,
|
||||
import_queue_justifications_submitted: prometheus::register(Counter::new(
|
||||
"substrate_import_queue_justifications_submitted",
|
||||
"Number of justifications submitted to the import queue.",
|
||||
)?, registry)?,
|
||||
incoming_connections_errors_total: prometheus::register(CounterVec::new(
|
||||
Opts::new(
|
||||
"substrate_sub_libp2p_incoming_connections_handshake_errors_total",
|
||||
|
||||
@@ -86,27 +86,26 @@ async fn normal_network_poll_no_peers() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn request_justification() {
|
||||
// build `ChainSyncInterface` provider and set no expecations for it (i.e., it cannot be
|
||||
// called)
|
||||
let chain_sync_service =
|
||||
Box::new(MockChainSyncInterface::<substrate_test_runtime_client::runtime::Block>::new());
|
||||
|
||||
// build `ChainSync` and verify that call to `request_justification()` is made
|
||||
let mut chain_sync =
|
||||
Box::new(MockChainSync::<substrate_test_runtime_client::runtime::Block>::new());
|
||||
|
||||
let hash = H256::random();
|
||||
let number = 1337u64;
|
||||
|
||||
chain_sync
|
||||
.expect_request_justification()
|
||||
// build `ChainSyncInterface` provider and and expect
|
||||
// `JustificationSyncLink::request_justification() to be called once
|
||||
let mut chain_sync_service =
|
||||
Box::new(MockChainSyncInterface::<substrate_test_runtime_client::runtime::Block>::new());
|
||||
|
||||
chain_sync_service
|
||||
.expect_justification_sync_link_request_justification()
|
||||
.withf(move |in_hash, in_number| &hash == in_hash && &number == in_number)
|
||||
.once()
|
||||
.returning(|_, _| ());
|
||||
|
||||
// build `ChainSync` and set default expecations for it
|
||||
let mut chain_sync = MockChainSync::<substrate_test_runtime_client::runtime::Block>::new();
|
||||
|
||||
set_default_expecations_no_peers(&mut chain_sync);
|
||||
let mut network = TestNetworkBuilder::new(Handle::current())
|
||||
.with_chain_sync((chain_sync, chain_sync_service))
|
||||
.with_chain_sync((Box::new(chain_sync), chain_sync_service))
|
||||
.build();
|
||||
|
||||
// send "request justifiction" message and poll the network
|
||||
@@ -121,17 +120,20 @@ async fn request_justification() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn clear_justification_requests() {
|
||||
// build `ChainSyncInterface` provider and set no expecations for it (i.e., it cannot be
|
||||
// called)
|
||||
let chain_sync_service =
|
||||
// build `ChainSyncInterface` provider and expect
|
||||
// `JustificationSyncLink::clear_justification_requests()` to be called
|
||||
let mut chain_sync_service =
|
||||
Box::new(MockChainSyncInterface::<substrate_test_runtime_client::runtime::Block>::new());
|
||||
|
||||
// build `ChainSync` and verify that call to `clear_justification_requests()` is made
|
||||
chain_sync_service
|
||||
.expect_justification_sync_link_clear_justification_requests()
|
||||
.once()
|
||||
.returning(|| ());
|
||||
|
||||
// build `ChainSync` and set default expecations for it
|
||||
let mut chain_sync =
|
||||
Box::new(MockChainSync::<substrate_test_runtime_client::runtime::Block>::new());
|
||||
|
||||
chain_sync.expect_clear_justification_requests().once().returning(|| ());
|
||||
|
||||
set_default_expecations_no_peers(&mut chain_sync);
|
||||
let mut network = TestNetworkBuilder::new(Handle::current())
|
||||
.with_chain_sync((chain_sync, chain_sync_service))
|
||||
@@ -235,19 +237,13 @@ async fn on_block_finalized() {
|
||||
// and verify that connection to the peer is closed
|
||||
#[tokio::test]
|
||||
async fn invalid_justification_imported() {
|
||||
struct DummyImportQueue(
|
||||
Arc<
|
||||
RwLock<
|
||||
Option<(
|
||||
PeerId,
|
||||
substrate_test_runtime_client::runtime::Hash,
|
||||
sp_runtime::traits::NumberFor<substrate_test_runtime_client::runtime::Block>,
|
||||
)>,
|
||||
>,
|
||||
>,
|
||||
);
|
||||
struct DummyImportQueueHandle;
|
||||
|
||||
impl sc_consensus::ImportQueue<substrate_test_runtime_client::runtime::Block> for DummyImportQueue {
|
||||
impl
|
||||
sc_consensus::import_queue::ImportQueueService<
|
||||
substrate_test_runtime_client::runtime::Block,
|
||||
> for DummyImportQueueHandle
|
||||
{
|
||||
fn import_blocks(
|
||||
&mut self,
|
||||
_origin: sp_consensus::BlockOrigin,
|
||||
@@ -265,7 +261,23 @@ async fn invalid_justification_imported() {
|
||||
_justifications: sp_runtime::Justifications,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
struct DummyImportQueue(
|
||||
Arc<
|
||||
RwLock<
|
||||
Option<(
|
||||
PeerId,
|
||||
substrate_test_runtime_client::runtime::Hash,
|
||||
sp_runtime::traits::NumberFor<substrate_test_runtime_client::runtime::Block>,
|
||||
)>,
|
||||
>,
|
||||
>,
|
||||
DummyImportQueueHandle,
|
||||
);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl sc_consensus::ImportQueue<substrate_test_runtime_client::runtime::Block> for DummyImportQueue {
|
||||
fn poll_actions(
|
||||
&mut self,
|
||||
_cx: &mut futures::task::Context,
|
||||
@@ -275,13 +287,40 @@ async fn invalid_justification_imported() {
|
||||
link.justification_imported(peer, &hash, number, false);
|
||||
}
|
||||
}
|
||||
|
||||
fn service(
|
||||
&self,
|
||||
) -> Box<
|
||||
dyn sc_consensus::import_queue::ImportQueueService<
|
||||
substrate_test_runtime_client::runtime::Block,
|
||||
>,
|
||||
> {
|
||||
Box::new(DummyImportQueueHandle {})
|
||||
}
|
||||
|
||||
fn service_ref(
|
||||
&mut self,
|
||||
) -> &mut dyn sc_consensus::import_queue::ImportQueueService<
|
||||
substrate_test_runtime_client::runtime::Block,
|
||||
> {
|
||||
&mut self.1
|
||||
}
|
||||
|
||||
async fn run(
|
||||
self,
|
||||
_link: Box<dyn sc_consensus::Link<substrate_test_runtime_client::runtime::Block>>,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
let justification_info = Arc::new(RwLock::new(None));
|
||||
let listen_addr = config::build_multiaddr![Memory(rand::random::<u64>())];
|
||||
|
||||
let (service1, mut event_stream1) = TestNetworkBuilder::new(Handle::current())
|
||||
.with_import_queue(Box::new(DummyImportQueue(justification_info.clone())))
|
||||
.with_import_queue(Box::new(DummyImportQueue(
|
||||
justification_info.clone(),
|
||||
DummyImportQueueHandle {},
|
||||
)))
|
||||
.with_listen_addresses(vec![listen_addr.clone()])
|
||||
.build()
|
||||
.start_network();
|
||||
@@ -331,6 +370,7 @@ async fn disconnect_peer_using_chain_sync_handle() {
|
||||
let client = Arc::new(TestClientBuilder::with_default_backend().build_with_longest_chain().0);
|
||||
let listen_addr = config::build_multiaddr![Memory(rand::random::<u64>())];
|
||||
|
||||
let import_queue = Box::new(sc_consensus::import_queue::mock::MockImportQueueHandle::new());
|
||||
let (chain_sync_network_provider, chain_sync_network_handle) =
|
||||
sc_network_sync::service::network::NetworkServiceProvider::new();
|
||||
let handle_clone = chain_sync_network_handle.clone();
|
||||
@@ -344,7 +384,9 @@ async fn disconnect_peer_using_chain_sync_handle() {
|
||||
Box::new(sp_consensus::block_validation::DefaultBlockAnnounceValidator),
|
||||
1u32,
|
||||
None,
|
||||
None,
|
||||
chain_sync_network_handle.clone(),
|
||||
import_queue,
|
||||
ProtocolName::from("block-request"),
|
||||
ProtocolName::from("state-request"),
|
||||
None,
|
||||
@@ -353,7 +395,7 @@ async fn disconnect_peer_using_chain_sync_handle() {
|
||||
|
||||
let (node1, mut event_stream1) = TestNetworkBuilder::new(Handle::current())
|
||||
.with_listen_addresses(vec![listen_addr.clone()])
|
||||
.with_chain_sync((Box::new(chain_sync), chain_sync_service))
|
||||
.with_chain_sync((Box::new(chain_sync), Box::new(chain_sync_service)))
|
||||
.with_chain_sync_network((chain_sync_network_provider, chain_sync_network_handle))
|
||||
.with_client(client.clone())
|
||||
.build()
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::{config, ChainSyncInterface, NetworkService, NetworkWorker};
|
||||
use futures::prelude::*;
|
||||
use libp2p::Multiaddr;
|
||||
use sc_client_api::{BlockBackend, HeaderBackend};
|
||||
use sc_consensus::ImportQueue;
|
||||
use sc_consensus::{ImportQueue, Link};
|
||||
use sc_network_common::{
|
||||
config::{
|
||||
NonDefaultSetConfig, NonReservedPeerMode, NotificationHandshake, ProtocolId, SetConfig,
|
||||
@@ -93,6 +93,7 @@ impl TestNetwork {
|
||||
|
||||
struct TestNetworkBuilder {
|
||||
import_queue: Option<Box<dyn ImportQueue<TestBlock>>>,
|
||||
link: Option<Box<dyn Link<TestBlock>>>,
|
||||
client: Option<Arc<substrate_test_runtime_client::TestClient>>,
|
||||
listen_addresses: Vec<Multiaddr>,
|
||||
set_config: Option<SetConfig>,
|
||||
@@ -106,6 +107,7 @@ impl TestNetworkBuilder {
|
||||
pub fn new(rt_handle: Handle) -> Self {
|
||||
Self {
|
||||
import_queue: None,
|
||||
link: None,
|
||||
client: None,
|
||||
listen_addresses: Vec::new(),
|
||||
set_config: None,
|
||||
@@ -212,13 +214,14 @@ impl TestNetworkBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
let import_queue = self.import_queue.unwrap_or(Box::new(sc_consensus::BasicQueue::new(
|
||||
PassThroughVerifier(false),
|
||||
Box::new(client.clone()),
|
||||
None,
|
||||
&sp_core::testing::TaskExecutor::new(),
|
||||
None,
|
||||
)));
|
||||
let mut import_queue =
|
||||
self.import_queue.unwrap_or(Box::new(sc_consensus::BasicQueue::new(
|
||||
PassThroughVerifier(false),
|
||||
Box::new(client.clone()),
|
||||
None,
|
||||
&sp_core::testing::TaskExecutor::new(),
|
||||
None,
|
||||
)));
|
||||
|
||||
let protocol_id = ProtocolId::from("test-protocol-name");
|
||||
let fork_id = Some(String::from("test-fork-id"));
|
||||
@@ -289,15 +292,23 @@ impl TestNetworkBuilder {
|
||||
Box::new(sp_consensus::block_validation::DefaultBlockAnnounceValidator),
|
||||
network_config.max_parallel_downloads,
|
||||
None,
|
||||
None,
|
||||
chain_sync_network_handle,
|
||||
import_queue.service(),
|
||||
block_request_protocol_config.name.clone(),
|
||||
state_request_protocol_config.name.clone(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
(Box::new(chain_sync), chain_sync_service)
|
||||
if let None = self.link {
|
||||
self.link = Some(Box::new(chain_sync_service.clone()));
|
||||
}
|
||||
(Box::new(chain_sync), Box::new(chain_sync_service))
|
||||
});
|
||||
let mut link = self
|
||||
.link
|
||||
.unwrap_or(Box::new(sc_network_sync::service::mock::MockChainSyncInterface::new()));
|
||||
|
||||
let handle = self.rt_handle.clone();
|
||||
let executor = move |f| {
|
||||
@@ -316,7 +327,6 @@ impl TestNetworkBuilder {
|
||||
chain: client.clone(),
|
||||
protocol_id,
|
||||
fork_id,
|
||||
import_queue,
|
||||
chain_sync,
|
||||
chain_sync_service,
|
||||
metrics_registry: None,
|
||||
@@ -333,6 +343,16 @@ impl TestNetworkBuilder {
|
||||
self.rt_handle.spawn(async move {
|
||||
let _ = chain_sync_network_provider.run(service).await;
|
||||
});
|
||||
self.rt_handle.spawn(async move {
|
||||
loop {
|
||||
futures::future::poll_fn(|cx| {
|
||||
import_queue.poll_actions(cx, &mut *link);
|
||||
std::task::Poll::Ready(())
|
||||
})
|
||||
.await;
|
||||
tokio::time::sleep(std::time::Duration::from_millis(250)).await;
|
||||
}
|
||||
});
|
||||
|
||||
TestNetwork::new(worker, self.rt_handle)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user