mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 18:07:58 +00:00
Integrate litep2p into Polkadot SDK (#2944)
[litep2p](https://github.com/altonen/litep2p) is a libp2p-compatible P2P networking library. It supports all of the features of `rust-libp2p` that are currently being utilized by Polkadot SDK. Compared to `rust-libp2p`, `litep2p` has a quite different architecture which is why the new `litep2p` network backend is only able to use a little of the existing code in `sc-network`. The design has been mainly influenced by how we'd wish to structure our networking-related code in Polkadot SDK: independent higher-levels protocols directly communicating with the network over links that support bidirectional backpressure. A good example would be `NotificationHandle`/`RequestResponseHandle` abstractions which allow, e.g., `SyncingEngine` to directly communicate with peers to announce/request blocks. I've tried running `polkadot --network-backend litep2p` with a few different peer configurations and there is a noticeable reduction in networking CPU usage. For high load (`--out-peers 200`), networking CPU usage goes down from ~110% to ~30% (80 pp) and for normal load (`--out-peers 40`), the usage goes down from ~55% to ~18% (37 pp). These should not be taken as final numbers because: a) there are still some low-hanging optimization fruits, such as enabling [receive window auto-tuning](https://github.com/libp2p/rust-yamux/pull/176), integrating `Peerset` more closely with `litep2p` or improving memory usage of the WebSocket transport b) fixing bugs/instabilities that incorrectly cause `litep2p` to do less work will increase the networking CPU usage c) verification in a more diverse set of tests/conditions is needed Nevertheless, these numbers should give an early estimate for CPU usage of the new networking backend. This PR consists of three separate changes: * introduce a generic `PeerId` (wrapper around `Multihash`) so that we don't have use `NetworkService::PeerId` in every part of the code that uses a `PeerId` * introduce `NetworkBackend` trait, implement it for the libp2p network stack and make Polkadot SDK generic over `NetworkBackend` * implement `NetworkBackend` for litep2p The new library should be considered experimental which is why `rust-libp2p` will remain as the default option for the time being. This PR currently depends on the master branch of `litep2p` but I'll cut a new release for the library once all review comments have been addresses. --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Dmitry Markin <dmitry@markin.tech> Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Co-authored-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
@@ -21,9 +21,9 @@
|
||||
|
||||
use crate::{futures_stream::FuturesStream, LOG_TARGET};
|
||||
use futures::{stream::FusedStream, Future, FutureExt, Stream, StreamExt};
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, error, trace, warn};
|
||||
use sc_network_common::sync::message::BlockAnnounce;
|
||||
use sc_network_types::PeerId;
|
||||
use sp_consensus::block_validation::Validation;
|
||||
use sp_runtime::traits::{Block as BlockT, Header, Zero};
|
||||
use std::{
|
||||
@@ -309,7 +309,7 @@ impl<B: BlockT> FusedStream for BlockAnnounceValidator<B> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::block_announce_validator::AllocateSlotForBlockAnnounceValidation;
|
||||
use libp2p::PeerId;
|
||||
use sc_network_types::PeerId;
|
||||
use sp_consensus::block_validation::DefaultBlockAnnounceValidator;
|
||||
use substrate_test_runtime_client::runtime::Block;
|
||||
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
//! Block relay protocol related definitions.
|
||||
|
||||
use futures::channel::oneshot;
|
||||
use libp2p::PeerId;
|
||||
use sc_network::{
|
||||
request_responses::{ProtocolConfig, RequestFailure},
|
||||
ProtocolName,
|
||||
};
|
||||
use sc_network::{request_responses::RequestFailure, NetworkBackend, ProtocolName};
|
||||
use sc_network_common::sync::message::{BlockData, BlockRequest};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -68,8 +65,8 @@ pub enum BlockResponseError {
|
||||
|
||||
/// Block relay specific params for network creation, specified in
|
||||
/// ['sc_service::BuildNetworkParams'].
|
||||
pub struct BlockRelayParams<Block: BlockT> {
|
||||
pub struct BlockRelayParams<Block: BlockT, N: NetworkBackend<Block, <Block as BlockT>::Hash>> {
|
||||
pub server: Box<dyn BlockServer<Block>>,
|
||||
pub downloader: Arc<dyn BlockDownloader<Block>>,
|
||||
pub request_response_config: ProtocolConfig,
|
||||
pub request_response_config: N::RequestResponseProtocolConfig,
|
||||
}
|
||||
|
||||
@@ -29,24 +29,26 @@ use crate::{
|
||||
|
||||
use codec::{Decode, DecodeAll, Encode};
|
||||
use futures::{channel::oneshot, stream::StreamExt};
|
||||
use libp2p::PeerId;
|
||||
use log::debug;
|
||||
use prost::Message;
|
||||
use schnellru::{ByLength, LruMap};
|
||||
|
||||
use sc_client_api::BlockBackend;
|
||||
use sc_network::{
|
||||
config::ProtocolId,
|
||||
request_responses::{
|
||||
IfDisconnected, IncomingRequest, OutgoingResponse, ProtocolConfig, RequestFailure,
|
||||
},
|
||||
request_responses::{IfDisconnected, IncomingRequest, OutgoingResponse, RequestFailure},
|
||||
service::traits::RequestResponseConfig,
|
||||
types::ProtocolName,
|
||||
NetworkBackend,
|
||||
};
|
||||
use sc_network_common::sync::message::{BlockAttributes, BlockData, BlockRequest, FromBlock};
|
||||
use schnellru::{ByLength, LruMap};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header, One, Zero},
|
||||
};
|
||||
|
||||
use std::{
|
||||
cmp::min,
|
||||
hash::{Hash, Hasher},
|
||||
@@ -71,21 +73,26 @@ mod rep {
|
||||
Rep::new(-(1 << 10), "same small block request multiple times");
|
||||
}
|
||||
|
||||
/// Generates a [`ProtocolConfig`] for the block request protocol, refusing incoming requests.
|
||||
pub fn generate_protocol_config<Hash: AsRef<[u8]>>(
|
||||
/// Generates a `RequestResponseProtocolConfig` for the block request protocol,
|
||||
/// refusing incoming requests.
|
||||
pub fn generate_protocol_config<
|
||||
Hash: AsRef<[u8]>,
|
||||
B: BlockT,
|
||||
N: NetworkBackend<B, <B as BlockT>::Hash>,
|
||||
>(
|
||||
protocol_id: &ProtocolId,
|
||||
genesis_hash: Hash,
|
||||
fork_id: Option<&str>,
|
||||
) -> ProtocolConfig {
|
||||
ProtocolConfig {
|
||||
name: generate_protocol_name(genesis_hash, fork_id).into(),
|
||||
fallback_names: std::iter::once(generate_legacy_protocol_name(protocol_id).into())
|
||||
.collect(),
|
||||
max_request_size: 1024 * 1024,
|
||||
max_response_size: 16 * 1024 * 1024,
|
||||
request_timeout: Duration::from_secs(20),
|
||||
inbound_queue: None,
|
||||
}
|
||||
inbound_queue: async_channel::Sender<IncomingRequest>,
|
||||
) -> N::RequestResponseProtocolConfig {
|
||||
N::request_response_config(
|
||||
generate_protocol_name(genesis_hash, fork_id).into(),
|
||||
std::iter::once(generate_legacy_protocol_name(protocol_id).into()).collect(),
|
||||
1024 * 1024,
|
||||
16 * 1024 * 1024,
|
||||
Duration::from_secs(20),
|
||||
Some(inbound_queue),
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate the block protocol name from the genesis hash and fork id.
|
||||
@@ -154,19 +161,19 @@ where
|
||||
Client: HeaderBackend<B> + BlockBackend<B> + Send + Sync + 'static,
|
||||
{
|
||||
/// Create a new [`BlockRequestHandler`].
|
||||
pub fn new(
|
||||
pub fn new<N: NetworkBackend<B, <B as BlockT>::Hash>>(
|
||||
network: NetworkServiceHandle,
|
||||
protocol_id: &ProtocolId,
|
||||
fork_id: Option<&str>,
|
||||
client: Arc<Client>,
|
||||
num_peer_hint: usize,
|
||||
) -> BlockRelayParams<B> {
|
||||
) -> BlockRelayParams<B, N> {
|
||||
// Reserve enough request slots for one request per peer when we are at the maximum
|
||||
// number of peers.
|
||||
let capacity = std::cmp::max(num_peer_hint, 1);
|
||||
let (tx, request_receiver) = async_channel::bounded(capacity);
|
||||
|
||||
let mut protocol_config = generate_protocol_config(
|
||||
let protocol_config = generate_protocol_config::<_, B, N>(
|
||||
protocol_id,
|
||||
client
|
||||
.block_hash(0u32.into())
|
||||
@@ -174,15 +181,18 @@ where
|
||||
.flatten()
|
||||
.expect("Genesis block exists; qed"),
|
||||
fork_id,
|
||||
tx,
|
||||
);
|
||||
protocol_config.inbound_queue = Some(tx);
|
||||
|
||||
let capacity = ByLength::new(num_peer_hint.max(1) as u32 * 2);
|
||||
let seen_requests = LruMap::new(capacity);
|
||||
|
||||
BlockRelayParams {
|
||||
server: Box::new(Self { client, request_receiver, seen_requests }),
|
||||
downloader: Arc::new(FullBlockDownloader::new(protocol_config.name.clone(), network)),
|
||||
downloader: Arc::new(FullBlockDownloader::new(
|
||||
protocol_config.protocol_name().clone(),
|
||||
network,
|
||||
)),
|
||||
request_response_config: protocol_config,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::LOG_TARGET;
|
||||
use libp2p::PeerId;
|
||||
use log::trace;
|
||||
use sc_network_common::sync::message;
|
||||
use sc_network_types::PeerId;
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor, One};
|
||||
use std::{
|
||||
cmp,
|
||||
@@ -262,8 +262,8 @@ impl<B: BlockT> BlockCollection<B> {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{BlockCollection, BlockData, BlockRangeState};
|
||||
use libp2p::PeerId;
|
||||
use sc_network_common::sync::message;
|
||||
use sc_network_types::PeerId;
|
||||
use sp_core::H256;
|
||||
use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper};
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ use futures::{
|
||||
future::{BoxFuture, Fuse},
|
||||
FutureExt, StreamExt,
|
||||
};
|
||||
use libp2p::{request_response::OutboundFailure, PeerId};
|
||||
use libp2p::request_response::OutboundFailure;
|
||||
use log::{debug, error, trace, warn};
|
||||
use prometheus_endpoint::{
|
||||
register, Counter, Gauge, MetricSource, Opts, PrometheusError, Registry, SourcedGauge, U64,
|
||||
@@ -59,21 +59,22 @@ use tokio::time::{Interval, MissedTickBehavior};
|
||||
use sc_client_api::{BlockBackend, HeaderBackend, ProofProvider};
|
||||
use sc_consensus::{import_queue::ImportQueueService, IncomingBlock};
|
||||
use sc_network::{
|
||||
config::{
|
||||
FullNetworkConfiguration, NonDefaultSetConfig, NonReservedPeerMode, NotificationHandshake,
|
||||
ProtocolId, SetConfig,
|
||||
},
|
||||
peer_store::{PeerStoreHandle, PeerStoreProvider},
|
||||
config::{FullNetworkConfiguration, NotificationHandshake, ProtocolId, SetConfig},
|
||||
peer_store::PeerStoreProvider,
|
||||
request_responses::{IfDisconnected, RequestFailure},
|
||||
service::traits::{Direction, NotificationEvent, ValidationResult},
|
||||
service::{
|
||||
traits::{Direction, NotificationConfig, NotificationEvent, ValidationResult},
|
||||
NotificationMetrics,
|
||||
},
|
||||
types::ProtocolName,
|
||||
utils::LruHashSet,
|
||||
NotificationService, ReputationChange,
|
||||
NetworkBackend, NotificationService, ReputationChange,
|
||||
};
|
||||
use sc_network_common::{
|
||||
role::Roles,
|
||||
sync::message::{BlockAnnounce, BlockAnnouncesHandshake, BlockRequest, BlockState},
|
||||
};
|
||||
use sc_network_types::PeerId;
|
||||
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
|
||||
use sp_blockchain::{Error as ClientError, HeaderMetadata};
|
||||
use sp_consensus::{block_validation::BlockAnnounceValidator, BlockOrigin};
|
||||
@@ -296,7 +297,7 @@ pub struct SyncingEngine<B: BlockT, Client> {
|
||||
syncing_started: Option<Instant>,
|
||||
|
||||
/// Handle to `PeerStore`.
|
||||
peer_store_handle: PeerStoreHandle,
|
||||
peer_store_handle: Arc<dyn PeerStoreProvider>,
|
||||
|
||||
/// Instant when the last notification was sent or received.
|
||||
last_notification_io: Instant,
|
||||
@@ -328,11 +329,12 @@ where
|
||||
+ Sync
|
||||
+ 'static,
|
||||
{
|
||||
pub fn new(
|
||||
pub fn new<N>(
|
||||
roles: Roles,
|
||||
client: Arc<Client>,
|
||||
metrics_registry: Option<&Registry>,
|
||||
net_config: &FullNetworkConfiguration,
|
||||
network_metrics: NotificationMetrics,
|
||||
net_config: &FullNetworkConfiguration<B, <B as BlockT>::Hash, N>,
|
||||
protocol_id: ProtocolId,
|
||||
fork_id: &Option<String>,
|
||||
block_announce_validator: Box<dyn BlockAnnounceValidator<B> + Send>,
|
||||
@@ -342,8 +344,11 @@ where
|
||||
block_downloader: Arc<dyn BlockDownloader<B>>,
|
||||
state_request_protocol_name: ProtocolName,
|
||||
warp_sync_protocol_name: Option<ProtocolName>,
|
||||
peer_store_handle: PeerStoreHandle,
|
||||
) -> Result<(Self, SyncingService<B>, NonDefaultSetConfig), ClientError> {
|
||||
peer_store_handle: Arc<dyn PeerStoreProvider>,
|
||||
) -> Result<(Self, SyncingService<B>, N::NotificationProtocolConfig), ClientError>
|
||||
where
|
||||
N: NetworkBackend<B, <B as BlockT>::Hash>,
|
||||
{
|
||||
let mode = net_config.network_config.sync_mode;
|
||||
let max_parallel_downloads = net_config.network_config.max_parallel_downloads;
|
||||
let max_blocks_per_request =
|
||||
@@ -411,18 +416,22 @@ where
|
||||
total.saturating_sub(net_config.network_config.default_peers_set_num_full) as usize
|
||||
};
|
||||
|
||||
let (block_announce_config, notification_service) = Self::get_block_announce_proto_config(
|
||||
protocol_id,
|
||||
fork_id,
|
||||
roles,
|
||||
client.info().best_number,
|
||||
client.info().best_hash,
|
||||
client
|
||||
.block_hash(Zero::zero())
|
||||
.ok()
|
||||
.flatten()
|
||||
.expect("Genesis block exists; qed"),
|
||||
);
|
||||
let (block_announce_config, notification_service) =
|
||||
Self::get_block_announce_proto_config::<N>(
|
||||
protocol_id,
|
||||
fork_id,
|
||||
roles,
|
||||
client.info().best_number,
|
||||
client.info().best_hash,
|
||||
client
|
||||
.block_hash(Zero::zero())
|
||||
.ok()
|
||||
.flatten()
|
||||
.expect("Genesis block exists; qed"),
|
||||
&net_config.network_config.default_peers_set,
|
||||
network_metrics,
|
||||
Arc::clone(&peer_store_handle),
|
||||
);
|
||||
|
||||
// Split warp sync params into warp sync config and a channel to retrieve target block
|
||||
// header.
|
||||
@@ -1385,14 +1394,17 @@ where
|
||||
}
|
||||
|
||||
/// Get config for the block announcement protocol
|
||||
fn get_block_announce_proto_config(
|
||||
fn get_block_announce_proto_config<N: NetworkBackend<B, <B as BlockT>::Hash>>(
|
||||
protocol_id: ProtocolId,
|
||||
fork_id: &Option<String>,
|
||||
roles: Roles,
|
||||
best_number: NumberFor<B>,
|
||||
best_hash: B::Hash,
|
||||
genesis_hash: B::Hash,
|
||||
) -> (NonDefaultSetConfig, Box<dyn NotificationService>) {
|
||||
set_config: &SetConfig,
|
||||
metrics: NotificationMetrics,
|
||||
peer_store_handle: Arc<dyn PeerStoreProvider>,
|
||||
) -> (N::NotificationProtocolConfig, Box<dyn NotificationService>) {
|
||||
let block_announces_protocol = {
|
||||
let genesis_hash = genesis_hash.as_ref();
|
||||
if let Some(ref fork_id) = fork_id {
|
||||
@@ -1406,7 +1418,7 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
NonDefaultSetConfig::new(
|
||||
N::notification_config(
|
||||
block_announces_protocol.into(),
|
||||
iter::once(format!("/{}/block-announces/1", protocol_id.as_ref()).into()).collect(),
|
||||
MAX_BLOCK_ANNOUNCE_SIZE,
|
||||
@@ -1416,14 +1428,9 @@ where
|
||||
best_hash,
|
||||
genesis_hash,
|
||||
))),
|
||||
// NOTE: `set_config` will be ignored by `protocol.rs` as the block announcement
|
||||
// protocol is still hardcoded into the peerset.
|
||||
SetConfig {
|
||||
in_peers: 0,
|
||||
out_peers: 0,
|
||||
reserved_nodes: Vec::new(),
|
||||
non_reserved_mode: NonReservedPeerMode::Deny,
|
||||
},
|
||||
set_config.clone(),
|
||||
metrics,
|
||||
peer_store_handle,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ use crate::{
|
||||
LOG_TARGET,
|
||||
};
|
||||
use fork_tree::ForkTree;
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, trace, warn};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_blockchain::Error as ClientError;
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor, Zero};
|
||||
use std::{
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
use crate::block_relay_protocol::{BlockDownloader as BlockDownloaderT, BlockResponseError};
|
||||
|
||||
use futures::channel::oneshot;
|
||||
use libp2p::PeerId;
|
||||
use sc_network::{ProtocolName, RequestFailure};
|
||||
use sc_network_common::sync::message::{BlockData, BlockRequest};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
mockall::mock! {
|
||||
|
||||
@@ -26,9 +26,10 @@ use futures::{
|
||||
stream::{BoxStream, FusedStream, Stream},
|
||||
FutureExt, StreamExt,
|
||||
};
|
||||
use libp2p::PeerId;
|
||||
use log::error;
|
||||
|
||||
use sc_network::{request_responses::RequestFailure, types::ProtocolName};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::task::{Context, Poll, Waker};
|
||||
use tokio_stream::StreamMap;
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use futures::channel::oneshot;
|
||||
use libp2p::{Multiaddr, PeerId};
|
||||
|
||||
use sc_consensus::{BlockImportError, BlockImportStatus};
|
||||
use sc_network::{
|
||||
config::MultiaddrWithPeerId,
|
||||
request_responses::{IfDisconnected, RequestFailure},
|
||||
types::ProtocolName,
|
||||
NetworkNotification, NetworkPeers, NetworkRequest, NetworkSyncForkRequest,
|
||||
NotificationSenderError, NotificationSenderT, ReputationChange,
|
||||
Multiaddr, NetworkPeers, NetworkRequest, NetworkSyncForkRequest, ReputationChange,
|
||||
};
|
||||
use sc_network_common::role::ObservedRole;
|
||||
use sc_network_types::PeerId;
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor};
|
||||
|
||||
use std::collections::HashSet;
|
||||
@@ -80,6 +79,7 @@ mockall::mock! {
|
||||
mockall::mock! {
|
||||
pub Network {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl NetworkPeers for Network {
|
||||
fn set_authorized_peers(&self, peers: HashSet<PeerId>);
|
||||
fn set_authorized_only(&self, reserved_only: bool);
|
||||
@@ -108,6 +108,7 @@ mockall::mock! {
|
||||
) -> Result<(), String>;
|
||||
fn sync_num_connected(&self) -> usize;
|
||||
fn peer_role(&self, peer_id: PeerId, handshake: Vec<u8>) -> Option<ObservedRole>;
|
||||
async fn reserved_peers(&self) -> Result<Vec<sc_network_types::PeerId>, ()>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@@ -130,14 +131,4 @@ mockall::mock! {
|
||||
connect: IfDisconnected,
|
||||
);
|
||||
}
|
||||
|
||||
impl NetworkNotification for Network {
|
||||
fn write_notification(&self, target: PeerId, protocol: ProtocolName, message: Vec<u8>);
|
||||
fn notification_sender(
|
||||
&self,
|
||||
target: PeerId,
|
||||
protocol: ProtocolName,
|
||||
) -> Result<Box<dyn NotificationSenderT>, NotificationSenderError>;
|
||||
fn set_notification_handshake(&self, protocol: ProtocolName, handshake: Vec<u8>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,21 +17,21 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use futures::{channel::oneshot, StreamExt};
|
||||
use libp2p::PeerId;
|
||||
use sc_network_types::PeerId;
|
||||
|
||||
use sc_network::{
|
||||
request_responses::{IfDisconnected, RequestFailure},
|
||||
types::ProtocolName,
|
||||
NetworkNotification, NetworkPeers, NetworkRequest, ReputationChange,
|
||||
NetworkPeers, NetworkRequest, ReputationChange,
|
||||
};
|
||||
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Network-related services required by `sc-network-sync`
|
||||
pub trait Network: NetworkPeers + NetworkRequest + NetworkNotification {}
|
||||
pub trait Network: NetworkPeers + NetworkRequest {}
|
||||
|
||||
impl<T> Network for T where T: NetworkPeers + NetworkRequest + NetworkNotification {}
|
||||
impl<T> Network for T where T: NetworkPeers + NetworkRequest {}
|
||||
|
||||
/// Network service provider for `ChainSync`
|
||||
///
|
||||
@@ -57,12 +57,6 @@ pub enum ToServiceCommand {
|
||||
oneshot::Sender<Result<(Vec<u8>, ProtocolName), RequestFailure>>,
|
||||
IfDisconnected,
|
||||
),
|
||||
|
||||
/// Call `NetworkNotification::write_notification()`
|
||||
WriteNotification(PeerId, ProtocolName, Vec<u8>),
|
||||
|
||||
/// Call `NetworkNotification::set_notification_handshake()`
|
||||
SetNotificationHandshake(ProtocolName, Vec<u8>),
|
||||
}
|
||||
|
||||
/// Handle that is (temporarily) passed to `ChainSync` so it can
|
||||
@@ -101,20 +95,6 @@ impl NetworkServiceHandle {
|
||||
.tx
|
||||
.unbounded_send(ToServiceCommand::StartRequest(who, protocol, request, tx, connect));
|
||||
}
|
||||
|
||||
/// Send notification to peer
|
||||
pub fn write_notification(&self, who: PeerId, protocol: ProtocolName, message: Vec<u8>) {
|
||||
let _ = self
|
||||
.tx
|
||||
.unbounded_send(ToServiceCommand::WriteNotification(who, protocol, message));
|
||||
}
|
||||
|
||||
/// Set handshake for the notification protocol.
|
||||
pub fn set_notification_handshake(&self, protocol: ProtocolName, handshake: Vec<u8>) {
|
||||
let _ = self
|
||||
.tx
|
||||
.unbounded_send(ToServiceCommand::SetNotificationHandshake(protocol, handshake));
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkServiceProvider {
|
||||
@@ -135,10 +115,6 @@ impl NetworkServiceProvider {
|
||||
service.report_peer(peer, reputation_change),
|
||||
ToServiceCommand::StartRequest(peer, protocol, request, tx, connect) =>
|
||||
service.start_request(peer, protocol, request, None, tx, connect),
|
||||
ToServiceCommand::WriteNotification(peer, protocol, message) =>
|
||||
service.write_notification(peer, protocol, message),
|
||||
ToServiceCommand::SetNotificationHandshake(protocol, handshake) =>
|
||||
service.set_notification_handshake(protocol, handshake),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use crate::types::{ExtendedPeerInfo, SyncEvent, SyncEventStream, SyncStatus, SyncStatusProvider};
|
||||
|
||||
use futures::{channel::oneshot, Stream};
|
||||
use libp2p::PeerId;
|
||||
use sc_network_types::PeerId;
|
||||
|
||||
use sc_consensus::{BlockImportError, BlockImportStatus, JustificationSyncLink, Link};
|
||||
use sc_network::{NetworkBlock, NetworkSyncForkRequest};
|
||||
|
||||
@@ -24,15 +24,16 @@ use crate::{
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use futures::{channel::oneshot, stream::StreamExt};
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, trace};
|
||||
use prost::Message;
|
||||
use sc_network_types::PeerId;
|
||||
use schnellru::{ByLength, LruMap};
|
||||
|
||||
use sc_client_api::{BlockBackend, ProofProvider};
|
||||
use sc_network::{
|
||||
config::ProtocolId,
|
||||
request_responses::{IncomingRequest, OutgoingResponse, ProtocolConfig},
|
||||
request_responses::{IncomingRequest, OutgoingResponse},
|
||||
NetworkBackend,
|
||||
};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
@@ -52,21 +53,26 @@ mod rep {
|
||||
pub const SAME_REQUEST: Rep = Rep::new(i32::MIN, "Same state request multiple times");
|
||||
}
|
||||
|
||||
/// Generates a [`ProtocolConfig`] for the state request protocol, refusing incoming requests.
|
||||
pub fn generate_protocol_config<Hash: AsRef<[u8]>>(
|
||||
/// Generates a `RequestResponseProtocolConfig` for the state request protocol, refusing incoming
|
||||
/// requests.
|
||||
pub fn generate_protocol_config<
|
||||
Hash: AsRef<[u8]>,
|
||||
B: BlockT,
|
||||
N: NetworkBackend<B, <B as BlockT>::Hash>,
|
||||
>(
|
||||
protocol_id: &ProtocolId,
|
||||
genesis_hash: Hash,
|
||||
fork_id: Option<&str>,
|
||||
) -> ProtocolConfig {
|
||||
ProtocolConfig {
|
||||
name: generate_protocol_name(genesis_hash, fork_id).into(),
|
||||
fallback_names: std::iter::once(generate_legacy_protocol_name(protocol_id).into())
|
||||
.collect(),
|
||||
max_request_size: 1024 * 1024,
|
||||
max_response_size: 16 * 1024 * 1024,
|
||||
request_timeout: Duration::from_secs(40),
|
||||
inbound_queue: None,
|
||||
}
|
||||
inbound_queue: async_channel::Sender<IncomingRequest>,
|
||||
) -> N::RequestResponseProtocolConfig {
|
||||
N::request_response_config(
|
||||
generate_protocol_name(genesis_hash, fork_id).into(),
|
||||
std::iter::once(generate_legacy_protocol_name(protocol_id).into()).collect(),
|
||||
1024 * 1024,
|
||||
16 * 1024 * 1024,
|
||||
Duration::from_secs(40),
|
||||
Some(inbound_queue),
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate the state protocol name from the genesis hash and fork id.
|
||||
@@ -125,18 +131,18 @@ where
|
||||
Client: BlockBackend<B> + ProofProvider<B> + Send + Sync + 'static,
|
||||
{
|
||||
/// Create a new [`StateRequestHandler`].
|
||||
pub fn new(
|
||||
pub fn new<N: NetworkBackend<B, <B as BlockT>::Hash>>(
|
||||
protocol_id: &ProtocolId,
|
||||
fork_id: Option<&str>,
|
||||
client: Arc<Client>,
|
||||
num_peer_hint: usize,
|
||||
) -> (Self, ProtocolConfig) {
|
||||
) -> (Self, N::RequestResponseProtocolConfig) {
|
||||
// Reserve enough request slots for one request per peer when we are at the maximum
|
||||
// number of peers.
|
||||
let capacity = std::cmp::max(num_peer_hint, 1);
|
||||
let (tx, request_receiver) = async_channel::bounded(capacity);
|
||||
|
||||
let mut protocol_config = generate_protocol_config(
|
||||
let protocol_config = generate_protocol_config::<_, B, N>(
|
||||
protocol_id,
|
||||
client
|
||||
.block_hash(0u32.into())
|
||||
@@ -144,8 +150,8 @@ where
|
||||
.flatten()
|
||||
.expect("Genesis block exists; qed"),
|
||||
fork_id,
|
||||
tx,
|
||||
);
|
||||
protocol_config.inbound_queue = Some(tx);
|
||||
|
||||
let capacity = ByLength::new(num_peer_hint.max(1) as u32 * 2);
|
||||
let seen_requests = LruMap::new(capacity);
|
||||
|
||||
@@ -29,7 +29,6 @@ use crate::{
|
||||
LOG_TARGET,
|
||||
};
|
||||
use chain_sync::{ChainSync, ChainSyncAction, ChainSyncMode};
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, error, info, warn};
|
||||
use prometheus_endpoint::Registry;
|
||||
use sc_client_api::{BlockBackend, ProofProvider};
|
||||
@@ -38,6 +37,7 @@ use sc_network_common::sync::{
|
||||
message::{BlockAnnounce, BlockData, BlockRequest},
|
||||
SyncMode,
|
||||
};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus::BlockOrigin;
|
||||
use sp_runtime::{
|
||||
|
||||
@@ -41,7 +41,6 @@ use crate::{
|
||||
};
|
||||
|
||||
use codec::Encode;
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use prometheus_endpoint::{register, Gauge, GaugeVec, Opts, PrometheusError, Registry, U64};
|
||||
use sc_client_api::{BlockBackend, ProofProvider};
|
||||
@@ -49,6 +48,7 @@ use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock};
|
||||
use sc_network_common::sync::message::{
|
||||
BlockAnnounce, BlockAttributes, BlockData, BlockRequest, BlockResponse, Direction, FromBlock,
|
||||
};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_arithmetic::traits::Saturating;
|
||||
use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus::{BlockOrigin, BlockStatus};
|
||||
|
||||
@@ -24,11 +24,11 @@ use crate::{
|
||||
types::{BadPeer, OpaqueStateRequest, OpaqueStateResponse, SyncState, SyncStatus},
|
||||
LOG_TARGET,
|
||||
};
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, error, trace};
|
||||
use sc_client_api::ProofProvider;
|
||||
use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock};
|
||||
use sc_network_common::sync::message::BlockAnnounce;
|
||||
use sc_network_types::PeerId;
|
||||
use sp_consensus::BlockOrigin;
|
||||
use sp_runtime::{
|
||||
traits::{Block as BlockT, Header, NumberFor},
|
||||
|
||||
@@ -27,11 +27,11 @@ use crate::{
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use futures::channel::oneshot;
|
||||
use libp2p::PeerId;
|
||||
use log::{debug, error, trace};
|
||||
use sc_network_common::sync::message::{
|
||||
BlockAnnounce, BlockAttributes, BlockData, BlockRequest, Direction, FromBlock,
|
||||
};
|
||||
use sc_network_types::PeerId;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_runtime::{
|
||||
traits::{Block as BlockT, Header, NumberFor, Zero},
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
use futures::Stream;
|
||||
use sc_network_common::{role::Roles, types::ReputationChange};
|
||||
|
||||
use libp2p::PeerId;
|
||||
|
||||
use crate::strategy::{state_sync::StateSyncProgress, warp::WarpSyncProgress};
|
||||
|
||||
use sc_network_common::sync::message::BlockRequest;
|
||||
use sc_network_types::PeerId;
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor};
|
||||
|
||||
use std::{any::Any, fmt, fmt::Formatter, pin::Pin, sync::Arc};
|
||||
|
||||
@@ -26,9 +26,8 @@ use crate::{
|
||||
};
|
||||
use sc_network::{
|
||||
config::ProtocolId,
|
||||
request_responses::{
|
||||
IncomingRequest, OutgoingResponse, ProtocolConfig as RequestResponseConfig,
|
||||
},
|
||||
request_responses::{IncomingRequest, OutgoingResponse},
|
||||
NetworkBackend,
|
||||
};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
@@ -39,22 +38,26 @@ const MAX_RESPONSE_SIZE: u64 = 16 * 1024 * 1024;
|
||||
/// Incoming warp requests bounded queue size.
|
||||
const MAX_WARP_REQUEST_QUEUE: usize = 20;
|
||||
|
||||
/// Generates a [`RequestResponseConfig`] for the grandpa warp sync request protocol, refusing
|
||||
/// Generates a `RequestResponseProtocolConfig` for the grandpa warp sync request protocol, refusing
|
||||
/// incoming requests.
|
||||
pub fn generate_request_response_config<Hash: AsRef<[u8]>>(
|
||||
pub fn generate_request_response_config<
|
||||
Hash: AsRef<[u8]>,
|
||||
B: BlockT,
|
||||
N: NetworkBackend<B, <B as BlockT>::Hash>,
|
||||
>(
|
||||
protocol_id: ProtocolId,
|
||||
genesis_hash: Hash,
|
||||
fork_id: Option<&str>,
|
||||
) -> RequestResponseConfig {
|
||||
RequestResponseConfig {
|
||||
name: generate_protocol_name(genesis_hash, fork_id).into(),
|
||||
fallback_names: std::iter::once(generate_legacy_protocol_name(protocol_id).into())
|
||||
.collect(),
|
||||
max_request_size: 32,
|
||||
max_response_size: MAX_RESPONSE_SIZE,
|
||||
request_timeout: Duration::from_secs(10),
|
||||
inbound_queue: None,
|
||||
}
|
||||
inbound_queue: async_channel::Sender<IncomingRequest>,
|
||||
) -> N::RequestResponseProtocolConfig {
|
||||
N::request_response_config(
|
||||
generate_protocol_name(genesis_hash, fork_id).into(),
|
||||
std::iter::once(generate_legacy_protocol_name(protocol_id).into()).collect(),
|
||||
32,
|
||||
MAX_RESPONSE_SIZE,
|
||||
Duration::from_secs(10),
|
||||
Some(inbound_queue),
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate the grandpa warp sync protocol name from the genesis hash and fork id.
|
||||
@@ -80,17 +83,20 @@ pub struct RequestHandler<TBlock: BlockT> {
|
||||
|
||||
impl<TBlock: BlockT> RequestHandler<TBlock> {
|
||||
/// Create a new [`RequestHandler`].
|
||||
pub fn new<Hash: AsRef<[u8]>>(
|
||||
pub fn new<Hash: AsRef<[u8]>, N: NetworkBackend<TBlock, <TBlock as BlockT>::Hash>>(
|
||||
protocol_id: ProtocolId,
|
||||
genesis_hash: Hash,
|
||||
fork_id: Option<&str>,
|
||||
backend: Arc<dyn WarpSyncProvider<TBlock>>,
|
||||
) -> (Self, RequestResponseConfig) {
|
||||
) -> (Self, N::RequestResponseProtocolConfig) {
|
||||
let (tx, request_receiver) = async_channel::bounded(MAX_WARP_REQUEST_QUEUE);
|
||||
|
||||
let mut request_response_config =
|
||||
generate_request_response_config(protocol_id, genesis_hash, fork_id);
|
||||
request_response_config.inbound_queue = Some(tx);
|
||||
let request_response_config = generate_request_response_config::<_, TBlock, N>(
|
||||
protocol_id,
|
||||
genesis_hash,
|
||||
fork_id,
|
||||
tx,
|
||||
);
|
||||
|
||||
(Self { backend, request_receiver }, request_response_config)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user