cumulus_client_bootnodes/config.rs
1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
5// Cumulus is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9
10// Cumulus is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
17
18//! Parachain bootnode request-response protocol configuration.
19
20use sc_network::{
21 request_responses::IncomingRequest, service::traits::NetworkBackend, ProtocolName,
22};
23use sp_runtime::traits::Block as BlockT;
24use std::time::Duration;
25
26/// Maximum number of addresses allowed in the response.
27pub const MAX_ADDRESSES: usize = 32;
28/// Expected maximum number of simultaneous requests from remote peers.
29/// Should be enough for a testnet with a plenty of nodes starting at the same time.
30const INBOUND_CHANNEL_SIZE: usize = 1000;
31/// Maximum request size. Should be enough to fit SCALE-compact-encoded `para_id`.
32const MAX_REQUEST_SIZE: u64 = 128;
33/// Maximum response size as per RFC.
34const MAX_RESPONSE_SIZE: u64 = 16 * 1024;
35/// Request-response protocol timeout.
36const TIMEOUT: Duration = Duration::from_secs(20);
37
38/// Bootnode request-response protocol name given a genesis hash and fork id.
39pub fn paranode_protocol_name<Hash: AsRef<[u8]>>(
40 genesis_hash: Hash,
41 fork_id: Option<&str>,
42) -> ProtocolName {
43 let genesis_hash = genesis_hash.as_ref();
44 if let Some(fork_id) = fork_id {
45 // This is not stated in RFC-0008, but other polkadot protocol names are based on `fork_id`
46 // if it is present, so we also use it here.
47 format!("/{}/{}/paranode", array_bytes::bytes2hex("", genesis_hash), fork_id)
48 } else {
49 format!("/{}/paranode", array_bytes::bytes2hex("", genesis_hash))
50 }
51 .into()
52}
53
54/// Bootnode request-response protocol config.
55pub fn bootnode_request_response_config<
56 Hash: AsRef<[u8]>,
57 B: BlockT,
58 N: NetworkBackend<B, <B as BlockT>::Hash>,
59>(
60 genesis_hash: Hash,
61 fork_id: Option<&str>,
62) -> (N::RequestResponseProtocolConfig, async_channel::Receiver<IncomingRequest>) {
63 let (inbound_tx, inbound_rx) = async_channel::bounded(INBOUND_CHANNEL_SIZE);
64
65 let config = N::request_response_config(
66 paranode_protocol_name(genesis_hash, fork_id),
67 Vec::new(),
68 MAX_REQUEST_SIZE,
69 MAX_RESPONSE_SIZE,
70 TIMEOUT,
71 Some(inbound_tx),
72 );
73
74 (config, inbound_rx)
75}