domain_service/
network.rs

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/// Build the network service, the network status sinks and an RPC sender.
24#[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}