1use sc_chain_spec::ChainSpec;
2use sc_network::config::{
3    DEFAULT_KADEMLIA_REPLICATION_FACTOR, MultiaddrWithPeerId, NetworkBackendType,
4    NetworkConfiguration, NodeKeyConfig, SetConfig, SyncMode, TransportConfig,
5};
6use sc_rpc_server::RpcEndpoint;
7use sc_service::config::{
8    ExecutorConfiguration, IpNetwork, KeystoreConfig, OffchainWorkerConfig, PrometheusConfig,
9    RpcBatchRequestConfig, RpcConfiguration,
10};
11use sc_service::{
12    BasePath, BlocksPruning, Configuration, DatabaseSource, PruningMode, RpcMethods,
13    TransactionPoolOptions,
14};
15use sc_telemetry::TelemetryEndpoints;
16use std::net::SocketAddr;
17use std::num::{NonZeroU32, NonZeroUsize};
18use std::path::PathBuf;
19use std::sync::Arc;
20use std::sync::atomic::AtomicBool;
21use tokio::runtime::Handle;
22
23pub const RPC_DEFAULT_MAX_REQUEST_SIZE_MB: u32 = 15;
25pub const RPC_DEFAULT_MAX_RESPONSE_SIZE_MB: u32 = 15;
27
28#[derive(Debug)]
30pub struct SubstrateRpcConfiguration {
31    pub listen_on: Option<SocketAddr>,
33    pub max_connections: u32,
35    pub cors: Option<Vec<String>>,
37    pub methods: RpcMethods,
39    pub rate_limit: Option<NonZeroU32>,
41    pub rate_limit_whitelisted_ips: Vec<IpNetwork>,
43    pub rate_limit_trust_proxy_headers: bool,
45    pub max_subscriptions_per_connection: u32,
47    pub message_buffer_capacity_per_connection: u32,
49    pub disable_batch_requests: bool,
51    pub max_batch_request_len: Option<u32>,
53}
54
55#[derive(Debug)]
57pub struct SubstrateNetworkConfiguration {
58    pub listen_on: Vec<sc_network::Multiaddr>,
60    pub public_addresses: Vec<sc_network::Multiaddr>,
62    pub bootstrap_nodes: Vec<MultiaddrWithPeerId>,
64    pub node_key: NodeKeyConfig,
66    pub default_peers_set: SetConfig,
68    pub node_name: String,
70    pub allow_private_ips: bool,
73    pub force_synced: bool,
77}
78
79#[derive(Debug)]
82pub struct SubstrateConfiguration {
83    pub impl_name: String,
85    pub impl_version: String,
87    pub operator: bool,
89    pub base_path: PathBuf,
91    pub transaction_pool: TransactionPoolOptions,
93    pub network: SubstrateNetworkConfiguration,
95    pub keystore: KeystoreConfig,
97    pub state_pruning: PruningMode,
99    pub blocks_pruning: BlocksPruning,
103    pub rpc_options: SubstrateRpcConfiguration,
105    pub prometheus_listen_on: Option<SocketAddr>,
107    pub telemetry_endpoints: Option<TelemetryEndpoints>,
109    pub force_authoring: bool,
111    pub chain_spec: Box<dyn ChainSpec>,
113    pub executor: ExecutorConfiguration,
115    pub trie_cache_size: Option<usize>,
117}
118
119impl From<SubstrateConfiguration> for Configuration {
120    fn from(configuration: SubstrateConfiguration) -> Self {
121        let default_peers_set_num_full = configuration.network.default_peers_set.in_peers
122            + configuration.network.default_peers_set.out_peers;
123        let client_version = format!("{}/{}", configuration.impl_name, configuration.impl_version);
124
125        let rpc_batch_config = if configuration.rpc_options.disable_batch_requests {
126            RpcBatchRequestConfig::Disabled
127        } else if let Some(l) = configuration.rpc_options.max_batch_request_len {
128            RpcBatchRequestConfig::Limit(l)
129        } else {
130            RpcBatchRequestConfig::Unlimited
131        };
132        let rpc_addr = configuration.rpc_options.listen_on.map(|listen_addr| {
133            vec![RpcEndpoint {
134                batch_config: rpc_batch_config,
135                max_connections: configuration.rpc_options.max_connections,
136                listen_addr,
137                rpc_methods: configuration.rpc_options.methods,
138                rate_limit: configuration.rpc_options.rate_limit,
139                rate_limit_trust_proxy_headers: configuration
140                    .rpc_options
141                    .rate_limit_trust_proxy_headers,
142                rate_limit_whitelisted_ips: configuration
143                    .rpc_options
144                    .rate_limit_whitelisted_ips
145                    .clone(),
146                max_payload_in_mb: RPC_DEFAULT_MAX_REQUEST_SIZE_MB,
147                max_payload_out_mb: RPC_DEFAULT_MAX_RESPONSE_SIZE_MB,
148                max_subscriptions_per_connection: configuration
149                    .rpc_options
150                    .max_subscriptions_per_connection,
151                max_buffer_capacity_per_connection: configuration
152                    .rpc_options
153                    .message_buffer_capacity_per_connection,
154                cors: configuration.rpc_options.cors.clone(),
155                retry_random_port: true,
156                is_optional: false,
157            }]
158        });
159
160        Self {
161            impl_name: configuration.impl_name,
162            impl_version: configuration.impl_version,
163            tokio_handle: Handle::current(),
164            transaction_pool: configuration.transaction_pool,
165            network: NetworkConfiguration {
166                net_config_path: None,
167                listen_addresses: configuration.network.listen_on,
168                public_addresses: configuration.network.public_addresses,
169                boot_nodes: if !configuration.network.bootstrap_nodes.is_empty() {
170                    configuration.network.bootstrap_nodes
171                } else {
172                    configuration.chain_spec.boot_nodes().to_vec()
173                },
174                node_key: configuration.network.node_key,
175                default_peers_set: configuration.network.default_peers_set,
176                default_peers_set_num_full,
177                client_version,
178                node_name: configuration.network.node_name,
179                transport: TransportConfig::Normal {
180                    enable_mdns: false,
181                    allow_private_ip: configuration.network.allow_private_ips,
182                },
183                max_parallel_downloads: 5,
185                max_blocks_per_request: 64,
187                sync_mode: SyncMode::Full,
189                pause_sync: Arc::new(AtomicBool::new(true)),
192                enable_dht_random_walk: true,
194                allow_non_globals_in_dht: configuration.network.allow_private_ips,
196                kademlia_disjoint_query_paths: false,
198                kademlia_replication_factor: NonZeroUsize::new(DEFAULT_KADEMLIA_REPLICATION_FACTOR)
199                    .expect("value is a constant; constant is non-zero; qed"),
200                ipfs_server: false,
201                yamux_window_size: None,
202                network_backend: Some(NetworkBackendType::Libp2p),
203                force_synced: configuration.network.force_synced,
204            },
205            keystore: configuration.keystore,
207            database: DatabaseSource::ParityDb {
208                path: configuration.base_path.join("db"),
209            },
210            data_path: configuration.base_path.clone(),
211            trie_cache_maximum_size: configuration.trie_cache_size,
212            state_pruning: Some(configuration.state_pruning),
213            blocks_pruning: configuration.blocks_pruning,
214            executor: configuration.executor,
215            wasm_runtime_overrides: None,
216            rpc: RpcConfiguration {
217                addr: rpc_addr,
218                methods: configuration.rpc_options.methods,
219                max_connections: configuration.rpc_options.max_connections,
220                cors: configuration.rpc_options.cors,
221                max_request_size: RPC_DEFAULT_MAX_REQUEST_SIZE_MB,
222                max_response_size: RPC_DEFAULT_MAX_RESPONSE_SIZE_MB,
223                id_provider: None,
224                max_subs_per_conn: configuration.rpc_options.max_subscriptions_per_connection,
225                port: 0,
227                message_buffer_capacity: configuration
228                    .rpc_options
229                    .message_buffer_capacity_per_connection,
230                batch_config: rpc_batch_config,
231                rate_limit: configuration.rpc_options.rate_limit,
232                rate_limit_whitelisted_ips: configuration.rpc_options.rate_limit_whitelisted_ips,
233                rate_limit_trust_proxy_headers: configuration
234                    .rpc_options
235                    .rate_limit_trust_proxy_headers,
236            },
237            prometheus_config: configuration
238                .prometheus_listen_on
239                .map(|prometheus_listen_on| {
240                    PrometheusConfig::new_with_default_registry(
241                        prometheus_listen_on,
242                        configuration.chain_spec.id().to_string(),
243                    )
244                }),
245            telemetry_endpoints: configuration.telemetry_endpoints,
246            offchain_worker: OffchainWorkerConfig {
248                enabled: false,
249                indexing_enabled: false,
250            },
251            force_authoring: configuration.force_authoring,
252            disable_grandpa: true,
253            dev_key_seed: None,
254            tracing_targets: None,
255            tracing_receiver: Default::default(),
256            chain_spec: configuration.chain_spec,
257            announce_block: true,
259            role: if configuration.operator {
260                sc_service::Role::Authority
261            } else {
262                sc_service::Role::Full
263            },
264            base_path: BasePath::new(configuration.base_path),
265        }
266    }
267}