cumulus_relay_chain_minimal_node/
network.rs1use polkadot_core_primitives::{Block, Hash, Header};
19use sp_runtime::traits::NumberFor;
20
21use sc_network::{
22 config::{
23 NetworkConfiguration, NonReservedPeerMode, NotificationHandshake, PeerStore, ProtocolId,
24 SetConfig,
25 },
26 peer_store::PeerStoreProvider,
27 service::traits::NetworkService,
28 NotificationMetrics,
29};
30
31use sc_network::{config::FullNetworkConfiguration, NetworkBackend, NotificationService};
32use sc_network_common::{role::Roles, sync::message::BlockAnnouncesHandshake};
33use sc_service::{error::Error, Configuration, SpawnTaskHandle};
34
35use std::{iter, sync::Arc};
36
37pub(crate) fn build_collator_network<Network: NetworkBackend<Block, Hash>>(
39 config: &Configuration,
40 mut network_config: FullNetworkConfiguration<Block, Hash, Network>,
41 spawn_handle: SpawnTaskHandle,
42 genesis_hash: Hash,
43 best_header: Header,
44 notification_metrics: NotificationMetrics,
45) -> Result<(Arc<dyn NetworkService>, Arc<dyn sp_consensus::SyncOracle + Send + Sync>), Error> {
46 let protocol_id = config.protocol_id();
47 let (block_announce_config, notification_service) = get_block_announce_proto_config::<Network>(
48 protocol_id.clone(),
49 &None,
50 Roles::from(&config.role),
51 best_header.number,
52 best_header.hash(),
53 genesis_hash,
54 notification_metrics.clone(),
55 network_config.peer_store_handle(),
56 );
57
58 adjust_network_config_light_in_peers(&mut network_config.network_config);
61
62 let peer_store = network_config.take_peer_store();
63 spawn_handle.spawn("peer-store", Some("networking"), peer_store.run());
64
65 let network_params = sc_network::config::Params::<Block, Hash, Network> {
66 role: config.role,
67 executor: {
68 let spawn_handle = Clone::clone(&spawn_handle);
69 Box::new(move |fut| {
70 spawn_handle.spawn("libp2p-node", Some("networking"), fut);
71 })
72 },
73 fork_id: None,
74 network_config,
75 genesis_hash,
76 protocol_id,
77 metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()),
78 block_announce_config,
79 bitswap_config: None,
80 notification_metrics,
81 };
82
83 let network_worker = Network::new(network_params)?;
84 let network_service = network_worker.network_service();
85
86 spawn_handle.spawn_blocking("network-worker", Some("networking"), async move {
94 let _notification_service = notification_service;
106 network_worker.run().await;
107 });
108
109 Ok((network_service, Arc::new(SyncOracle {})))
110}
111
112fn adjust_network_config_light_in_peers(config: &mut NetworkConfiguration) {
113 let light_client_in_peers = (config.default_peers_set.in_peers +
114 config.default_peers_set.out_peers)
115 .saturating_sub(config.default_peers_set_num_full);
116 if light_client_in_peers > 0 {
117 tracing::debug!(target: crate::LOG_TARGET, "Detected {light_client_in_peers} peer slots for light clients. Since this minimal node does support\
118 neither syncing nor light-client request/response, we are setting them to 0.");
119 }
120 config.default_peers_set.in_peers =
121 config.default_peers_set.in_peers.saturating_sub(light_client_in_peers);
122}
123
124struct SyncOracle;
125
126impl sp_consensus::SyncOracle for SyncOracle {
127 fn is_major_syncing(&self) -> bool {
128 false
129 }
130
131 fn is_offline(&self) -> bool {
132 true
133 }
134}
135
136fn get_block_announce_proto_config<Network: NetworkBackend<Block, Hash>>(
137 protocol_id: ProtocolId,
138 fork_id: &Option<String>,
139 roles: Roles,
140 best_number: NumberFor<Block>,
141 best_hash: Hash,
142 genesis_hash: Hash,
143 metrics: NotificationMetrics,
144 peer_store_handle: Arc<dyn PeerStoreProvider>,
145) -> (Network::NotificationProtocolConfig, Box<dyn NotificationService>) {
146 let block_announces_protocol = {
147 let genesis_hash = genesis_hash.as_ref();
148 if let Some(ref fork_id) = fork_id {
149 format!("/{}/{}/block-announces/1", array_bytes::bytes2hex("", genesis_hash), fork_id)
150 } else {
151 format!("/{}/block-announces/1", array_bytes::bytes2hex("", genesis_hash))
152 }
153 };
154
155 Network::notification_config(
156 block_announces_protocol.into(),
157 iter::once(format!("/{}/block-announces/1", protocol_id.as_ref()).into()).collect(),
158 1024 * 1024,
159 Some(NotificationHandshake::new(BlockAnnouncesHandshake::<Block>::build(
160 roles,
161 best_number,
162 best_hash,
163 genesis_hash,
164 ))),
165 SetConfig {
168 in_peers: 0,
169 out_peers: 0,
170 reserved_nodes: Vec::new(),
171 non_reserved_mode: NonReservedPeerMode::Deny,
172 },
173 metrics,
174 peer_store_handle,
175 )
176}