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