1use sc_chain_spec::ChainSpec;
2use sc_network::config::{
3 MultiaddrWithPeerId, NetworkBackendType, NetworkConfiguration, NodeKeyConfig, SetConfig,
4 SyncMode, TransportConfig, DEFAULT_KADEMLIA_REPLICATION_FACTOR,
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::atomic::AtomicBool;
20use std::sync::Arc;
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: 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}