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