1use sc_client_api::{AuxStore, BlockBackend, BlockchainEvents, ProofProvider};
2use sc_consensus::ImportQueue;
3use sc_network::NetworkBackend;
4use sc_network_common::role::Roles;
5use sc_network_sync::SyncingService;
6use sc_network_sync::block_relay_protocol::{BlockDownloader, BlockRelayParams};
7use sc_network_sync::engine::SyncingEngine;
8use sc_network_sync::service::network::{NetworkServiceHandle, NetworkServiceProvider};
9use sc_service::{
10 BuildNetworkAdvancedParams, BuildNetworkParams, Error, NetworkStarter,
11 build_default_block_downloader, build_network_advanced, build_polkadot_syncing_strategy,
12};
13use sc_transaction_pool_api::TransactionPool;
14use sc_utils::mpsc::TracingUnboundedSender;
15use sp_api::__private::BlockT;
16use sp_api::ProvideRuntimeApi;
17use sp_blockchain::{HeaderBackend, HeaderMetadata};
18use sp_consensus::block_validation::{Chain, DefaultBlockAnnounceValidator};
19use sp_runtime::traits::BlockIdTo;
20use std::sync::Arc;
21use subspace_runtime_primitives::BlockHashFor;
22
23#[allow(clippy::type_complexity)]
25#[expect(clippy::result_large_err, reason = "Comes from Substrate")]
26pub fn build_network<Block, Net, TxPool, IQ, Client>(
27 params: BuildNetworkParams<Block, Net, TxPool, IQ, Client>,
28) -> Result<
29 (
30 Arc<dyn sc_network::service::traits::NetworkService>,
31 TracingUnboundedSender<sc_rpc::system::Request<Block>>,
32 sc_network_transactions::TransactionsHandlerController<BlockHashFor<Block>>,
33 NetworkStarter,
34 Arc<SyncingService<Block>>,
35 NetworkServiceHandle,
36 Arc<dyn BlockDownloader<Block>>,
37 ),
38 Error,
39>
40where
41 Block: BlockT,
42 Client: ProvideRuntimeApi<Block>
43 + HeaderMetadata<Block, Error = sp_blockchain::Error>
44 + Chain<Block>
45 + BlockBackend<Block>
46 + BlockIdTo<Block, Error = sp_blockchain::Error>
47 + ProofProvider<Block>
48 + HeaderBackend<Block>
49 + BlockchainEvents<Block>
50 + AuxStore
51 + 'static,
52 TxPool: TransactionPool<Block = Block, Hash = BlockHashFor<Block>> + 'static,
53 IQ: ImportQueue<Block> + 'static,
54 Net: NetworkBackend<Block, BlockHashFor<Block>>,
55{
56 let BuildNetworkParams {
57 config,
58 mut net_config,
59 client,
60 transaction_pool,
61 spawn_handle,
62 import_queue,
63 block_announce_validator_builder,
64 warp_sync_config,
65 block_relay,
66 metrics,
67 } = params;
68 let fork_id = config.chain_spec.fork_id();
69
70 let block_announce_validator = if let Some(f) = block_announce_validator_builder {
71 f(client.clone())
72 } else {
73 Box::new(DefaultBlockAnnounceValidator)
74 };
75
76 let network_service_provider = NetworkServiceProvider::new();
77 let protocol_id = config.protocol_id();
78 let metrics_registry = config
79 .prometheus_config
80 .as_ref()
81 .map(|config| &config.registry);
82
83 let block_downloader = match block_relay {
84 Some(params) => {
85 let BlockRelayParams {
86 mut server,
87 downloader,
88 request_response_config,
89 } = params;
90
91 net_config.add_request_response_protocol(request_response_config);
92
93 spawn_handle.spawn("block-request-handler", Some("networking"), async move {
94 server.run().await;
95 });
96
97 downloader
98 }
99 None => build_default_block_downloader(
100 &protocol_id,
101 fork_id,
102 &mut net_config,
103 network_service_provider.handle(),
104 Arc::clone(&client),
105 config.network.default_peers_set.in_peers as usize
106 + config.network.default_peers_set.out_peers as usize,
107 &spawn_handle,
108 ),
109 };
110
111 let syncing_strategy = build_polkadot_syncing_strategy(
112 protocol_id.clone(),
113 fork_id,
114 &mut net_config,
115 warp_sync_config,
116 block_downloader.clone(),
117 client.clone(),
118 &spawn_handle,
119 metrics_registry,
120 )?;
121
122 let (syncing_engine, sync_service, block_announce_config) = SyncingEngine::new(
123 Roles::from(&config.role),
124 Arc::clone(&client),
125 metrics_registry,
126 metrics.clone(),
127 &net_config,
128 protocol_id.clone(),
129 fork_id,
130 block_announce_validator,
131 syncing_strategy,
132 network_service_provider.handle(),
133 import_queue.service(),
134 net_config.peer_store_handle(),
135 config.network.force_synced,
136 )?;
137
138 spawn_handle.spawn_blocking("syncing", None, syncing_engine.run());
139
140 let network_service_handle = network_service_provider.handle();
141 build_network_advanced(BuildNetworkAdvancedParams {
142 role: config.role,
143 protocol_id,
144 fork_id,
145 ipfs_server: config.network.ipfs_server,
146 announce_block: config.announce_block,
147 net_config,
148 client,
149 transaction_pool,
150 spawn_handle,
151 import_queue,
152 sync_service,
153 block_announce_config,
154 network_service_provider,
155 metrics_registry,
156 metrics,
157 })
158 .map(
159 |(network_service, system_rpc_tx, tx_handler_controller, network_starter, sync_service)| {
160 (
161 network_service,
162 system_rpc_tx,
163 tx_handler_controller,
164 network_starter,
165 sync_service,
166 network_service_handle,
167 block_downloader,
168 )
169 },
170 )
171}