sc_service/
config.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Service configuration.
20
21pub use jsonrpsee::server::BatchRequestConfig as RpcBatchRequestConfig;
22use prometheus_endpoint::Registry;
23use sc_chain_spec::ChainSpec;
24pub use sc_client_db::{BlocksPruning, Database, DatabaseSource, PruningMode};
25pub use sc_executor::{WasmExecutionMethod, WasmtimeInstantiationStrategy};
26pub use sc_network::{
27	config::{
28		MultiaddrWithPeerId, NetworkConfiguration, NodeKeyConfig, NonDefaultSetConfig, ProtocolId,
29		Role, SetConfig, SyncMode, TransportConfig,
30	},
31	request_responses::{
32		IncomingRequest, OutgoingResponse, ProtocolConfig as RequestResponseConfig,
33	},
34	Multiaddr,
35};
36pub use sc_rpc_server::{
37	IpNetwork, RpcEndpoint, RpcMethods, SubscriptionIdProvider as RpcSubscriptionIdProvider,
38};
39pub use sc_telemetry::TelemetryEndpoints;
40pub use sc_transaction_pool::Options as TransactionPoolOptions;
41use sp_core::crypto::SecretString;
42use std::{
43	io, iter,
44	net::SocketAddr,
45	num::NonZeroU32,
46	path::{Path, PathBuf},
47};
48use tempfile::TempDir;
49
50/// Service configuration.
51#[derive(Debug)]
52pub struct Configuration {
53	/// Implementation name
54	pub impl_name: String,
55	/// Implementation version (see sc-cli to see an example of format)
56	pub impl_version: String,
57	/// Node role.
58	pub role: Role,
59	/// Handle to the tokio runtime. Will be used to spawn futures by the task manager.
60	pub tokio_handle: tokio::runtime::Handle,
61	/// Extrinsic pool configuration.
62	pub transaction_pool: TransactionPoolOptions,
63	/// Network configuration.
64	pub network: NetworkConfiguration,
65	/// Configuration for the keystore.
66	pub keystore: KeystoreConfig,
67	/// Configuration for the database.
68	pub database: DatabaseSource,
69	/// Maximum size of internal trie cache in bytes.
70	///
71	/// If `None` is given the cache is disabled.
72	pub trie_cache_maximum_size: Option<usize>,
73	/// State pruning settings.
74	pub state_pruning: Option<PruningMode>,
75	/// Number of blocks to keep in the db.
76	///
77	/// NOTE: only finalized blocks are subject for removal!
78	pub blocks_pruning: BlocksPruning,
79	/// Chain configuration.
80	pub chain_spec: Box<dyn ChainSpec>,
81	/// Runtime executor configuration.
82	pub executor: ExecutorConfiguration,
83	/// Directory where local WASM runtimes live. These runtimes take precedence
84	/// over on-chain runtimes when the spec version matches. Set to `None` to
85	/// disable overrides (default).
86	pub wasm_runtime_overrides: Option<PathBuf>,
87	/// RPC configuration.
88	pub rpc: RpcConfiguration,
89	/// Prometheus endpoint configuration. `None` if disabled.
90	pub prometheus_config: Option<PrometheusConfig>,
91	/// Telemetry service URL. `None` if disabled.
92	pub telemetry_endpoints: Option<TelemetryEndpoints>,
93	/// Should offchain workers be executed.
94	pub offchain_worker: OffchainWorkerConfig,
95	/// Enable authoring even when offline.
96	pub force_authoring: bool,
97	/// Disable GRANDPA when running in validator mode
98	pub disable_grandpa: bool,
99	/// Development key seed.
100	///
101	/// When running in development mode, the seed will be used to generate authority keys by the
102	/// keystore.
103	///
104	/// Should only be set when `node` is running development mode.
105	pub dev_key_seed: Option<String>,
106	/// Tracing targets
107	pub tracing_targets: Option<String>,
108	/// Tracing receiver
109	pub tracing_receiver: sc_tracing::TracingReceiver,
110	/// Announce block automatically after they have been imported
111	pub announce_block: bool,
112	/// Data path root for the configured chain.
113	pub data_path: PathBuf,
114	/// Base path of the configuration. This is shared between chains.
115	pub base_path: BasePath,
116}
117
118/// Type for tasks spawned by the executor.
119#[derive(PartialEq)]
120pub enum TaskType {
121	/// Regular non-blocking futures. Polling the task is expected to be a lightweight operation.
122	Async,
123	/// The task might perform a lot of expensive CPU operations and/or call `thread::sleep`.
124	Blocking,
125}
126
127/// Configuration of the client keystore.
128#[derive(Debug, Clone)]
129pub enum KeystoreConfig {
130	/// Keystore at a path on-disk. Recommended for native nodes.
131	Path {
132		/// The path of the keystore.
133		path: PathBuf,
134		/// Node keystore's password.
135		password: Option<SecretString>,
136	},
137	/// In-memory keystore. Recommended for in-browser nodes.
138	InMemory,
139}
140
141impl KeystoreConfig {
142	/// Returns the path for the keystore.
143	pub fn path(&self) -> Option<&Path> {
144		match self {
145			Self::Path { path, .. } => Some(path),
146			Self::InMemory => None,
147		}
148	}
149}
150/// Configuration of the database of the client.
151#[derive(Debug, Clone, Default)]
152pub struct OffchainWorkerConfig {
153	/// If this is allowed.
154	pub enabled: bool,
155	/// allow writes from the runtime to the offchain worker database.
156	pub indexing_enabled: bool,
157}
158
159/// Configuration of the Prometheus endpoint.
160#[derive(Debug, Clone)]
161pub struct PrometheusConfig {
162	/// Port to use.
163	pub port: SocketAddr,
164	/// A metrics registry to use. Useful for setting the metric prefix.
165	pub registry: Registry,
166}
167
168impl PrometheusConfig {
169	/// Create a new config using the default registry.
170	pub fn new_with_default_registry(port: SocketAddr, chain_id: String) -> Self {
171		let param = iter::once((String::from("chain"), chain_id)).collect();
172		Self {
173			port,
174			registry: Registry::new_custom(None, Some(param))
175				.expect("this can only fail if the prefix is empty"),
176		}
177	}
178}
179
180impl Configuration {
181	/// Returns a string displaying the node role.
182	pub fn display_role(&self) -> String {
183		self.role.to_string()
184	}
185
186	/// Returns the prometheus metrics registry, if available.
187	pub fn prometheus_registry(&self) -> Option<&Registry> {
188		self.prometheus_config.as_ref().map(|config| &config.registry)
189	}
190
191	/// Returns the network protocol id from the chain spec, or the default.
192	pub fn protocol_id(&self) -> ProtocolId {
193		let protocol_id_full = match self.chain_spec.protocol_id() {
194			Some(pid) => pid,
195			None => {
196				log::warn!(
197					"Using default protocol ID {:?} because none is configured in the \
198					chain specs",
199					crate::DEFAULT_PROTOCOL_ID
200				);
201				crate::DEFAULT_PROTOCOL_ID
202			},
203		};
204		ProtocolId::from(protocol_id_full)
205	}
206
207	/// Returns true if the genesis state writing will be skipped while initializing the genesis
208	/// block.
209	pub fn no_genesis(&self) -> bool {
210		matches!(self.network.sync_mode, SyncMode::LightState { .. } | SyncMode::Warp { .. })
211	}
212
213	/// Returns the database config for creating the backend.
214	pub fn db_config(&self) -> sc_client_db::DatabaseSettings {
215		sc_client_db::DatabaseSettings {
216			trie_cache_maximum_size: self.trie_cache_maximum_size,
217			state_pruning: self.state_pruning.clone(),
218			source: self.database.clone(),
219			blocks_pruning: self.blocks_pruning,
220		}
221	}
222}
223
224#[static_init::dynamic(drop, lazy)]
225static mut BASE_PATH_TEMP: Option<TempDir> = None;
226
227/// The base path that is used for everything that needs to be written on disk to run a node.
228#[derive(Clone, Debug)]
229pub struct BasePath {
230	path: PathBuf,
231}
232
233impl BasePath {
234	/// Create a `BasePath` instance using a temporary directory prefixed with "substrate" and use
235	/// it as base path.
236	///
237	/// Note: The temporary directory will be created automatically and deleted when the program
238	/// exits. Every call to this function will return the same path for the lifetime of the
239	/// program.
240	pub fn new_temp_dir() -> io::Result<BasePath> {
241		let mut temp = BASE_PATH_TEMP.write();
242
243		match &*temp {
244			Some(p) => Ok(Self::new(p.path())),
245			None => {
246				let temp_dir = tempfile::Builder::new().prefix("substrate").tempdir()?;
247				let path = PathBuf::from(temp_dir.path());
248
249				*temp = Some(temp_dir);
250				Ok(Self::new(path))
251			},
252		}
253	}
254
255	/// Create a `BasePath` instance based on an existing path on disk.
256	///
257	/// Note: this function will not ensure that the directory exist nor create the directory. It
258	/// will also not delete the directory when the instance is dropped.
259	pub fn new<P: Into<PathBuf>>(path: P) -> BasePath {
260		Self { path: path.into() }
261	}
262
263	/// Create a base path from values describing the project.
264	pub fn from_project(qualifier: &str, organization: &str, application: &str) -> BasePath {
265		BasePath::new(
266			directories::ProjectDirs::from(qualifier, organization, application)
267				.expect("app directories exist on all supported platforms; qed")
268				.data_local_dir(),
269		)
270	}
271
272	/// Retrieve the base path.
273	pub fn path(&self) -> &Path {
274		&self.path
275	}
276
277	/// Returns the configuration directory inside this base path.
278	///
279	/// The path looks like `$base_path/chains/$chain_id`
280	pub fn config_dir(&self, chain_id: &str) -> PathBuf {
281		self.path().join("chains").join(chain_id)
282	}
283}
284
285impl From<PathBuf> for BasePath {
286	fn from(path: PathBuf) -> Self {
287		BasePath::new(path)
288	}
289}
290
291/// RPC configuration.
292#[derive(Debug)]
293pub struct RpcConfiguration {
294	/// JSON-RPC server endpoints.
295	pub addr: Option<Vec<RpcEndpoint>>,
296	/// Maximum number of connections for JSON-RPC server.
297	pub max_connections: u32,
298	/// CORS settings for HTTP & WS servers. `None` if all origins are allowed.
299	pub cors: Option<Vec<String>>,
300	/// RPC methods to expose (by default only a safe subset or all of them).
301	pub methods: RpcMethods,
302	/// Maximum payload of a rpc request
303	pub max_request_size: u32,
304	/// Maximum payload of a rpc response.
305	pub max_response_size: u32,
306	/// Custom JSON-RPC subscription ID provider.
307	///
308	/// Default: [`crate::RandomStringSubscriptionId`].
309	pub id_provider: Option<Box<dyn RpcSubscriptionIdProvider>>,
310	/// Maximum allowed subscriptions per rpc connection
311	pub max_subs_per_conn: u32,
312	/// JSON-RPC server default port.
313	pub port: u16,
314	/// The number of messages the JSON-RPC server is allowed to keep in memory.
315	pub message_buffer_capacity: u32,
316	/// JSON-RPC server batch config.
317	pub batch_config: RpcBatchRequestConfig,
318	/// RPC rate limit per minute.
319	pub rate_limit: Option<NonZeroU32>,
320	/// RPC rate limit whitelisted ip addresses.
321	pub rate_limit_whitelisted_ips: Vec<IpNetwork>,
322	/// RPC rate limit trust proxy headers.
323	pub rate_limit_trust_proxy_headers: bool,
324}
325
326/// Runtime executor configuration.
327#[derive(Debug, Clone)]
328pub struct ExecutorConfiguration {
329	/// Wasm execution method.
330	pub wasm_method: WasmExecutionMethod,
331	/// The size of the instances cache.
332	///
333	/// The default value is 8.
334	pub max_runtime_instances: usize,
335	/// The default number of 64KB pages to allocate for Wasm execution
336	pub default_heap_pages: Option<u64>,
337	/// Maximum number of different runtime versions that can be cached.
338	pub runtime_cache_size: u8,
339}
340
341impl Default for ExecutorConfiguration {
342	fn default() -> Self {
343		Self {
344			wasm_method: WasmExecutionMethod::default(),
345			max_runtime_instances: 8,
346			default_heap_pages: None,
347			runtime_cache_size: 2,
348		}
349	}
350}