Skip to content

Commit e71c484

Browse files
altonendmitry-markinlexnv
authored
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 #512 Fixes #514 Fixes #515 Fixes #554 Fixes #556 --- These changes are transferred from paritytech/substrate#14197 but there are no functional changes compared to that PR --------- Co-authored-by: Dmitry Markin <[email protected]> Co-authored-by: Alexandru Vasile <[email protected]>
1 parent ec3a61e commit e71c484

File tree

102 files changed

+5628
-2537
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+5628
-2537
lines changed

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cumulus/client/relay-chain-minimal-node/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ array-bytes = "6.1"
4747
tracing = "0.1.37"
4848
async-trait = "0.1.73"
4949
futures = "0.3.28"
50+
parking_lot = "0.12.1"
5051

cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
1616

1717
use futures::{select, StreamExt};
18-
use std::sync::Arc;
18+
use parking_lot::Mutex;
19+
use std::{collections::HashMap, sync::Arc};
1920

2021
use polkadot_availability_recovery::AvailabilityRecoverySubsystem;
2122
use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide};
@@ -28,7 +29,7 @@ use polkadot_node_core_chain_api::ChainApiSubsystem;
2829
use polkadot_node_core_prospective_parachains::ProspectiveParachainsSubsystem;
2930
use polkadot_node_core_runtime_api::RuntimeApiSubsystem;
3031
use polkadot_node_network_protocol::{
31-
peer_set::PeerSetProtocolNames,
32+
peer_set::{PeerSet, PeerSetProtocolNames},
3233
request_response::{
3334
v1::{self, AvailableDataFetchingRequest},
3435
v2, IncomingRequestReceiver, ReqProtocolNames,
@@ -42,7 +43,7 @@ use polkadot_overseer::{
4243
use polkadot_primitives::CollatorPair;
4344

4445
use sc_authority_discovery::Service as AuthorityDiscoveryService;
45-
use sc_network::NetworkStateInfo;
46+
use sc_network::{NetworkStateInfo, NotificationService};
4647
use sc_service::TaskManager;
4748
use sc_utils::mpsc::tracing_unbounded;
4849

@@ -77,6 +78,8 @@ pub(crate) struct CollatorOverseerGenArgs<'a> {
7778
pub req_protocol_names: ReqProtocolNames,
7879
/// Peerset protocols name mapping
7980
pub peer_set_protocol_names: PeerSetProtocolNames,
81+
/// Notification services for validation/collation protocols.
82+
pub notification_services: HashMap<PeerSet, Box<dyn NotificationService>>,
8083
}
8184

8285
fn build_overseer(
@@ -94,13 +97,16 @@ fn build_overseer(
9497
collator_pair,
9598
req_protocol_names,
9699
peer_set_protocol_names,
100+
notification_services,
97101
}: CollatorOverseerGenArgs<'_>,
98102
) -> Result<
99103
(Overseer<SpawnGlue<sc_service::SpawnTaskHandle>, Arc<BlockChainRpcClient>>, OverseerHandle),
100104
RelayChainError,
101105
> {
102106
let spawner = SpawnGlue(spawner);
103107
let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?;
108+
let notification_sinks = Arc::new(Mutex::new(HashMap::new()));
109+
104110
let builder = Overseer::builder()
105111
.availability_distribution(DummySubsystem)
106112
.availability_recovery(AvailabilityRecoverySubsystem::for_collator(
@@ -131,13 +137,16 @@ fn build_overseer(
131137
sync_oracle,
132138
network_bridge_metrics.clone(),
133139
peer_set_protocol_names.clone(),
140+
notification_services,
141+
notification_sinks.clone(),
134142
))
135143
.network_bridge_tx(NetworkBridgeTxSubsystem::new(
136144
network_service,
137145
authority_discovery_service,
138146
network_bridge_metrics,
139147
req_protocol_names,
140148
peer_set_protocol_names,
149+
notification_sinks,
141150
))
142151
.provisioner(DummySubsystem)
143152
.runtime_api(RuntimeApiSubsystem::new(

cumulus/client/relay-chain-minimal-node/src/lib.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use cumulus_relay_chain_rpc_interface::{RelayChainRpcClient, RelayChainRpcInterf
2121
use network::build_collator_network;
2222
use polkadot_network_bridge::{peer_sets_info, IsAuthority};
2323
use polkadot_node_network_protocol::{
24-
peer_set::PeerSetProtocolNames,
24+
peer_set::{PeerSet, PeerSetProtocolNames},
2525
request_response::{
2626
v1, v2, IncomingRequest, IncomingRequestReceiver, Protocol, ReqProtocolNames,
2727
},
@@ -175,10 +175,13 @@ async fn new_minimal_relay_chain(
175175
let peer_set_protocol_names =
176176
PeerSetProtocolNames::new(genesis_hash, config.chain_spec.fork_id());
177177
let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No };
178-
179-
for config in peer_sets_info(is_authority, &peer_set_protocol_names) {
180-
net_config.add_notification_protocol(config);
181-
}
178+
let notification_services = peer_sets_info(is_authority, &peer_set_protocol_names)
179+
.into_iter()
180+
.map(|(config, (peerset, service))| {
181+
net_config.add_notification_protocol(config);
182+
(peerset, service)
183+
})
184+
.collect::<std::collections::HashMap<PeerSet, Box<dyn sc_network::NotificationService>>>();
182185

183186
let request_protocol_names = ReqProtocolNames::new(genesis_hash, config.chain_spec.fork_id());
184187
let (collation_req_receiver_v1, collation_req_receiver_v2, available_data_req_receiver) =
@@ -218,6 +221,7 @@ async fn new_minimal_relay_chain(
218221
collator_pair,
219222
req_protocol_names: request_protocol_names,
220223
peer_set_protocol_names,
224+
notification_services,
221225
};
222226

223227
let overseer_handle =

cumulus/client/relay-chain-minimal-node/src/network.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ use sc_network::{
2626
NetworkService,
2727
};
2828

29-
use sc_network::config::FullNetworkConfiguration;
29+
use sc_network::{config::FullNetworkConfiguration, NotificationService};
3030
use sc_network_common::{role::Roles, sync::message::BlockAnnouncesHandshake};
3131
use sc_service::{error::Error, Configuration, NetworkStarter, SpawnTaskHandle};
32-
use sc_utils::mpsc::tracing_unbounded;
3332

3433
use std::{iter, sync::Arc};
3534

@@ -45,7 +44,7 @@ pub(crate) fn build_collator_network(
4544
Error,
4645
> {
4746
let protocol_id = config.protocol_id();
48-
let block_announce_config = get_block_announce_proto_config::<Block>(
47+
let (block_announce_config, _notification_service) = get_block_announce_proto_config::<Block>(
4948
protocol_id.clone(),
5049
&None,
5150
Roles::from(&config.role),
@@ -69,8 +68,6 @@ pub(crate) fn build_collator_network(
6968
let peer_store_handle = peer_store.handle();
7069
spawn_handle.spawn("peer-store", Some("networking"), peer_store.run());
7170

72-
// RX is not used for anything because syncing is not started for the minimal node
73-
let (tx, _rx) = tracing_unbounded("mpsc_syncing_engine_protocol", 100_000);
7471
let network_params = sc_network::config::Params::<Block> {
7572
role: config.role.clone(),
7673
executor: {
@@ -86,7 +83,6 @@ pub(crate) fn build_collator_network(
8683
protocol_id,
8784
metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()),
8885
block_announce_config,
89-
tx,
9086
};
9187

9288
let network_worker = sc_network::NetworkWorker::new(network_params)?;
@@ -150,7 +146,7 @@ fn get_block_announce_proto_config<B: BlockT>(
150146
best_number: NumberFor<B>,
151147
best_hash: B::Hash,
152148
genesis_hash: B::Hash,
153-
) -> NonDefaultSetConfig {
149+
) -> (NonDefaultSetConfig, Box<dyn NotificationService>) {
154150
let block_announces_protocol = {
155151
let genesis_hash = genesis_hash.as_ref();
156152
if let Some(ref fork_id) = fork_id {
@@ -160,24 +156,23 @@ fn get_block_announce_proto_config<B: BlockT>(
160156
}
161157
};
162158

163-
NonDefaultSetConfig {
164-
notifications_protocol: block_announces_protocol.into(),
165-
fallback_names: iter::once(format!("/{}/block-announces/1", protocol_id.as_ref()).into())
166-
.collect(),
167-
max_notification_size: 1024 * 1024,
168-
handshake: Some(NotificationHandshake::new(BlockAnnouncesHandshake::<B>::build(
159+
NonDefaultSetConfig::new(
160+
block_announces_protocol.into(),
161+
iter::once(format!("/{}/block-announces/1", protocol_id.as_ref()).into()).collect(),
162+
1024 * 1024,
163+
Some(NotificationHandshake::new(BlockAnnouncesHandshake::<B>::build(
169164
roles,
170165
best_number,
171166
best_hash,
172167
genesis_hash,
173168
))),
174169
// NOTE: `set_config` will be ignored by `protocol.rs` as the block announcement
175170
// protocol is still hardcoded into the peerset.
176-
set_config: SetConfig {
171+
SetConfig {
177172
in_peers: 0,
178173
out_peers: 0,
179174
reserved_nodes: Vec::new(),
180175
non_reserved_mode: NonReservedPeerMode::Deny,
181176
},
182-
}
177+
)
183178
}

polkadot/node/network/bridge/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub(crate) enum WireMessage<M> {
8383
ViewUpdate(View),
8484
}
8585

86+
#[derive(Debug)]
8687
pub(crate) struct PeerData {
8788
/// The Latest view sent by the peer.
8889
view: View,

0 commit comments

Comments
 (0)