mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 22:51:03 +00:00
Rework the event system of sc-network (#1370)
This commit introduces a new concept called `NotificationService` which allows Polkadot protocols to communicate with the underlying notification protocol implementation directly, without routing events through `NetworkWorker`. This implies that each protocol has its own service which it uses to communicate with remote peers and that each `NotificationService` is unique with respect to the underlying notification protocol, meaning `NotificationService` for the transaction protocol can only be used to send and receive transaction-related notifications. The `NotificationService` concept introduces two additional benefits: * allow protocols to start using custom handshakes * allow protocols to accept/reject inbound peers Previously the validation of inbound connections was solely the responsibility of `ProtocolController`. This caused issues with light peers and `SyncingEngine` as `ProtocolController` would accept more peers than `SyncingEngine` could accept which caused peers to have differing views of their own states. `SyncingEngine` would reject excess peers but these rejections were not properly communicated to those peers causing them to assume that they were accepted. With `NotificationService`, the local handshake is not sent to remote peer if peer is rejected which allows it to detect that it was rejected. This commit also deprecates the use of `NetworkEventStream` for all notification-related events and going forward only DHT events are provided through `NetworkEventStream`. If protocols wish to follow each other's events, they must introduce additional abtractions, as is done for GRANDPA and transactions protocols by following the syncing protocol through `SyncEventStream`. Fixes https://github.com/paritytech/polkadot-sdk/issues/512 Fixes https://github.com/paritytech/polkadot-sdk/issues/514 Fixes https://github.com/paritytech/polkadot-sdk/issues/515 Fixes https://github.com/paritytech/polkadot-sdk/issues/554 Fixes https://github.com/paritytech/polkadot-sdk/issues/556 --- These changes are transferred from https://github.com/paritytech/substrate/pull/14197 but there are no functional changes compared to that PR --------- Co-authored-by: Dmitry Markin <dmitry@markin.tech> Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
@@ -15,7 +15,8 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use futures::{select, StreamExt};
|
||||
use std::sync::Arc;
|
||||
use parking_lot::Mutex;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use polkadot_availability_recovery::AvailabilityRecoverySubsystem;
|
||||
use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide};
|
||||
@@ -28,7 +29,7 @@ use polkadot_node_core_chain_api::ChainApiSubsystem;
|
||||
use polkadot_node_core_prospective_parachains::ProspectiveParachainsSubsystem;
|
||||
use polkadot_node_core_runtime_api::RuntimeApiSubsystem;
|
||||
use polkadot_node_network_protocol::{
|
||||
peer_set::PeerSetProtocolNames,
|
||||
peer_set::{PeerSet, PeerSetProtocolNames},
|
||||
request_response::{
|
||||
v1::{self, AvailableDataFetchingRequest},
|
||||
v2, IncomingRequestReceiver, ReqProtocolNames,
|
||||
@@ -42,7 +43,7 @@ use polkadot_overseer::{
|
||||
use polkadot_primitives::CollatorPair;
|
||||
|
||||
use sc_authority_discovery::Service as AuthorityDiscoveryService;
|
||||
use sc_network::NetworkStateInfo;
|
||||
use sc_network::{NetworkStateInfo, NotificationService};
|
||||
use sc_service::TaskManager;
|
||||
use sc_utils::mpsc::tracing_unbounded;
|
||||
|
||||
@@ -77,6 +78,8 @@ pub(crate) struct CollatorOverseerGenArgs<'a> {
|
||||
pub req_protocol_names: ReqProtocolNames,
|
||||
/// Peerset protocols name mapping
|
||||
pub peer_set_protocol_names: PeerSetProtocolNames,
|
||||
/// Notification services for validation/collation protocols.
|
||||
pub notification_services: HashMap<PeerSet, Box<dyn NotificationService>>,
|
||||
}
|
||||
|
||||
fn build_overseer(
|
||||
@@ -94,6 +97,7 @@ fn build_overseer(
|
||||
collator_pair,
|
||||
req_protocol_names,
|
||||
peer_set_protocol_names,
|
||||
notification_services,
|
||||
}: CollatorOverseerGenArgs<'_>,
|
||||
) -> Result<
|
||||
(Overseer<SpawnGlue<sc_service::SpawnTaskHandle>, Arc<BlockChainRpcClient>>, OverseerHandle),
|
||||
@@ -101,6 +105,8 @@ fn build_overseer(
|
||||
> {
|
||||
let spawner = SpawnGlue(spawner);
|
||||
let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?;
|
||||
let notification_sinks = Arc::new(Mutex::new(HashMap::new()));
|
||||
|
||||
let builder = Overseer::builder()
|
||||
.availability_distribution(DummySubsystem)
|
||||
.availability_recovery(AvailabilityRecoverySubsystem::for_collator(
|
||||
@@ -131,6 +137,8 @@ fn build_overseer(
|
||||
sync_oracle,
|
||||
network_bridge_metrics.clone(),
|
||||
peer_set_protocol_names.clone(),
|
||||
notification_services,
|
||||
notification_sinks.clone(),
|
||||
))
|
||||
.network_bridge_tx(NetworkBridgeTxSubsystem::new(
|
||||
network_service,
|
||||
@@ -138,6 +146,7 @@ fn build_overseer(
|
||||
network_bridge_metrics,
|
||||
req_protocol_names,
|
||||
peer_set_protocol_names,
|
||||
notification_sinks,
|
||||
))
|
||||
.provisioner(DummySubsystem)
|
||||
.runtime_api(RuntimeApiSubsystem::new(
|
||||
|
||||
@@ -21,7 +21,7 @@ use cumulus_relay_chain_rpc_interface::{RelayChainRpcClient, RelayChainRpcInterf
|
||||
use network::build_collator_network;
|
||||
use polkadot_network_bridge::{peer_sets_info, IsAuthority};
|
||||
use polkadot_node_network_protocol::{
|
||||
peer_set::PeerSetProtocolNames,
|
||||
peer_set::{PeerSet, PeerSetProtocolNames},
|
||||
request_response::{
|
||||
v1, v2, IncomingRequest, IncomingRequestReceiver, Protocol, ReqProtocolNames,
|
||||
},
|
||||
@@ -175,10 +175,13 @@ async fn new_minimal_relay_chain(
|
||||
let peer_set_protocol_names =
|
||||
PeerSetProtocolNames::new(genesis_hash, config.chain_spec.fork_id());
|
||||
let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No };
|
||||
|
||||
for config in peer_sets_info(is_authority, &peer_set_protocol_names) {
|
||||
net_config.add_notification_protocol(config);
|
||||
}
|
||||
let notification_services = peer_sets_info(is_authority, &peer_set_protocol_names)
|
||||
.into_iter()
|
||||
.map(|(config, (peerset, service))| {
|
||||
net_config.add_notification_protocol(config);
|
||||
(peerset, service)
|
||||
})
|
||||
.collect::<std::collections::HashMap<PeerSet, Box<dyn sc_network::NotificationService>>>();
|
||||
|
||||
let request_protocol_names = ReqProtocolNames::new(genesis_hash, config.chain_spec.fork_id());
|
||||
let (collation_req_receiver_v1, collation_req_receiver_v2, available_data_req_receiver) =
|
||||
@@ -218,6 +221,7 @@ async fn new_minimal_relay_chain(
|
||||
collator_pair,
|
||||
req_protocol_names: request_protocol_names,
|
||||
peer_set_protocol_names,
|
||||
notification_services,
|
||||
};
|
||||
|
||||
let overseer_handle =
|
||||
|
||||
@@ -26,10 +26,9 @@ use sc_network::{
|
||||
NetworkService,
|
||||
};
|
||||
|
||||
use sc_network::config::FullNetworkConfiguration;
|
||||
use sc_network::{config::FullNetworkConfiguration, NotificationService};
|
||||
use sc_network_common::{role::Roles, sync::message::BlockAnnouncesHandshake};
|
||||
use sc_service::{error::Error, Configuration, NetworkStarter, SpawnTaskHandle};
|
||||
use sc_utils::mpsc::tracing_unbounded;
|
||||
|
||||
use std::{iter, sync::Arc};
|
||||
|
||||
@@ -45,7 +44,7 @@ pub(crate) fn build_collator_network(
|
||||
Error,
|
||||
> {
|
||||
let protocol_id = config.protocol_id();
|
||||
let block_announce_config = get_block_announce_proto_config::<Block>(
|
||||
let (block_announce_config, _notification_service) = get_block_announce_proto_config::<Block>(
|
||||
protocol_id.clone(),
|
||||
&None,
|
||||
Roles::from(&config.role),
|
||||
@@ -69,8 +68,6 @@ pub(crate) fn build_collator_network(
|
||||
let peer_store_handle = peer_store.handle();
|
||||
spawn_handle.spawn("peer-store", Some("networking"), peer_store.run());
|
||||
|
||||
// RX is not used for anything because syncing is not started for the minimal node
|
||||
let (tx, _rx) = tracing_unbounded("mpsc_syncing_engine_protocol", 100_000);
|
||||
let network_params = sc_network::config::Params::<Block> {
|
||||
role: config.role.clone(),
|
||||
executor: {
|
||||
@@ -86,7 +83,6 @@ pub(crate) fn build_collator_network(
|
||||
protocol_id,
|
||||
metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()),
|
||||
block_announce_config,
|
||||
tx,
|
||||
};
|
||||
|
||||
let network_worker = sc_network::NetworkWorker::new(network_params)?;
|
||||
@@ -150,7 +146,7 @@ fn get_block_announce_proto_config<B: BlockT>(
|
||||
best_number: NumberFor<B>,
|
||||
best_hash: B::Hash,
|
||||
genesis_hash: B::Hash,
|
||||
) -> NonDefaultSetConfig {
|
||||
) -> (NonDefaultSetConfig, Box<dyn NotificationService>) {
|
||||
let block_announces_protocol = {
|
||||
let genesis_hash = genesis_hash.as_ref();
|
||||
if let Some(ref fork_id) = fork_id {
|
||||
@@ -160,12 +156,11 @@ fn get_block_announce_proto_config<B: BlockT>(
|
||||
}
|
||||
};
|
||||
|
||||
NonDefaultSetConfig {
|
||||
notifications_protocol: block_announces_protocol.into(),
|
||||
fallback_names: iter::once(format!("/{}/block-announces/1", protocol_id.as_ref()).into())
|
||||
.collect(),
|
||||
max_notification_size: 1024 * 1024,
|
||||
handshake: Some(NotificationHandshake::new(BlockAnnouncesHandshake::<B>::build(
|
||||
NonDefaultSetConfig::new(
|
||||
block_announces_protocol.into(),
|
||||
iter::once(format!("/{}/block-announces/1", protocol_id.as_ref()).into()).collect(),
|
||||
1024 * 1024,
|
||||
Some(NotificationHandshake::new(BlockAnnouncesHandshake::<B>::build(
|
||||
roles,
|
||||
best_number,
|
||||
best_hash,
|
||||
@@ -173,11 +168,11 @@ fn get_block_announce_proto_config<B: BlockT>(
|
||||
))),
|
||||
// NOTE: `set_config` will be ignored by `protocol.rs` as the block announcement
|
||||
// protocol is still hardcoded into the peerset.
|
||||
set_config: SetConfig {
|
||||
SetConfig {
|
||||
in_peers: 0,
|
||||
out_peers: 0,
|
||||
reserved_nodes: Vec::new(),
|
||||
non_reserved_mode: NonReservedPeerMode::Deny,
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user