referrerpolicy=no-referrer-when-downgrade

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::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	/// Force the trie cache to be in memory.
74	pub warm_up_trie_cache: Option<TrieCacheWarmUpStrategy>,
75	/// State pruning settings.
76	pub state_pruning: Option<PruningMode>,
77	/// Number of blocks to keep in the db.
78	///
79	/// NOTE: only finalized blocks are subject for removal!
80	pub blocks_pruning: BlocksPruning,
81	/// Chain configuration.
82	pub chain_spec: Box<dyn ChainSpec>,
83	/// Runtime executor configuration.
84	pub executor: ExecutorConfiguration,
85	/// Directory where local WASM runtimes live. These runtimes take precedence
86	/// over on-chain runtimes when the spec version matches. Set to `None` to
87	/// disable overrides (default).
88	pub wasm_runtime_overrides: Option<PathBuf>,
89	/// RPC configuration.
90	pub rpc: RpcConfiguration,
91	/// Prometheus endpoint configuration. `None` if disabled.
92	pub prometheus_config: Option<PrometheusConfig>,
93	/// Telemetry service URL. `None` if disabled.
94	pub telemetry_endpoints: Option<TelemetryEndpoints>,
95	/// Should offchain workers be executed.
96	pub offchain_worker: OffchainWorkerConfig,
97	/// Enable authoring even when offline.
98	pub force_authoring: bool,
99	/// Disable GRANDPA when running in validator mode
100	pub disable_grandpa: bool,
101	/// Development key seed.
102	///
103	/// When running in development mode, the seed will be used to generate authority keys by the
104	/// keystore.
105	///
106	/// Should only be set when `node` is running development mode.
107	pub dev_key_seed: Option<String>,
108	/// Tracing targets
109	pub tracing_targets: Option<String>,
110	/// Tracing receiver
111	pub tracing_receiver: sc_tracing::TracingReceiver,
112	/// Announce block automatically after they have been imported
113	pub announce_block: bool,
114	/// Data path root for the configured chain.
115	pub data_path: PathBuf,
116	/// Base path of the configuration. This is shared between chains.
117	pub base_path: BasePath,
118}
119
120/// Warmup strategy for the trie cache.
121#[derive(Debug, Clone, Copy)]
122pub enum TrieCacheWarmUpStrategy {
123	/// Warm up the cache in a non-blocking way.
124	NonBlocking,
125	/// Warm up the cache in a blocking way.
126	Blocking,
127}
128
129impl TrieCacheWarmUpStrategy {
130	/// Returns true if the warmup strategy is blocking.
131	pub(crate) fn is_blocking(&self) -> bool {
132		matches!(self, Self::Blocking)
133	}
134}
135
136/// Type for tasks spawned by the executor.
137#[derive(PartialEq)]
138pub enum TaskType {
139	/// Regular non-blocking futures. Polling the task is expected to be a lightweight operation.
140	Async,
141	/// The task might perform a lot of expensive CPU operations and/or call `thread::sleep`.
142	Blocking,
143}
144
145/// Configuration of the client keystore.
146#[derive(Debug, Clone)]
147pub enum KeystoreConfig {
148	/// Keystore at a path on-disk. Recommended for native nodes.
149	Path {
150		/// The path of the keystore.
151		path: PathBuf,
152		/// Node keystore's password.
153		password: Option<SecretString>,
154	},
155	/// In-memory keystore. Recommended for in-browser nodes.
156	InMemory,
157}
158
159impl KeystoreConfig {
160	/// Returns the path for the keystore.
161	pub fn path(&self) -> Option<&Path> {
162		match self {
163			Self::Path { path, .. } => Some(path),
164			Self::InMemory => None,
165		}
166	}
167}
168/// Configuration of the database of the client.
169#[derive(Debug, Clone, Default)]
170pub struct OffchainWorkerConfig {
171	/// If this is allowed.
172	pub enabled: bool,
173	/// allow writes from the runtime to the offchain worker database.
174	pub indexing_enabled: bool,
175}
176
177/// Configuration of the Prometheus endpoint.
178#[derive(Debug, Clone)]
179pub struct PrometheusConfig {
180	/// Port to use.
181	pub port: SocketAddr,
182	/// A metrics registry to use. Useful for setting the metric prefix.
183	pub registry: Registry,
184}
185
186impl PrometheusConfig {
187	/// Create a new config using the default registry.
188	pub fn new_with_default_registry(port: SocketAddr, chain_id: String) -> Self {
189		let param = iter::once((String::from("chain"), chain_id)).collect();
190		Self {
191			port,
192			registry: Registry::new_custom(None, Some(param))
193				.expect("this can only fail if the prefix is empty"),
194		}
195	}
196}
197
198impl Configuration {
199	/// Returns a string displaying the node role.
200	pub fn display_role(&self) -> String {
201		self.role.to_string()
202	}
203
204	/// Returns the prometheus metrics registry, if available.
205	pub fn prometheus_registry(&self) -> Option<&Registry> {
206		self.prometheus_config.as_ref().map(|config| &config.registry)
207	}
208
209	/// Returns the network protocol id from the chain spec, or the default.
210	pub fn protocol_id(&self) -> ProtocolId {
211		let protocol_id_full = match self.chain_spec.protocol_id() {
212			Some(pid) => pid,
213			None => {
214				log::warn!(
215					"Using default protocol ID {:?} because none is configured in the \
216					chain specs",
217					crate::DEFAULT_PROTOCOL_ID
218				);
219				crate::DEFAULT_PROTOCOL_ID
220			},
221		};
222		ProtocolId::from(protocol_id_full)
223	}
224
225	/// Returns true if the genesis state writing will be skipped while initializing the genesis
226	/// block.
227	pub fn no_genesis(&self) -> bool {
228		matches!(self.network.sync_mode, SyncMode::LightState { .. } | SyncMode::Warp { .. })
229	}
230
231	/// Returns the database config for creating the backend.
232	pub fn db_config(&self) -> sc_client_db::DatabaseSettings {
233		sc_client_db::DatabaseSettings {
234			trie_cache_maximum_size: self.trie_cache_maximum_size,
235			state_pruning: self.state_pruning.clone(),
236			source: self.database.clone(),
237			blocks_pruning: self.blocks_pruning,
238			metrics_registry: self.prometheus_registry().cloned(),
239		}
240	}
241}
242
243#[static_init::dynamic(drop, lazy)]
244static mut BASE_PATH_TEMP: Option<TempDir> = None;
245
246/// The base path that is used for everything that needs to be written on disk to run a node.
247#[derive(Clone, Debug)]
248pub struct BasePath {
249	path: PathBuf,
250}
251
252impl BasePath {
253	/// Create a `BasePath` instance using a temporary directory prefixed with "substrate" and use
254	/// it as base path.
255	///
256	/// Note: The temporary directory will be created automatically and deleted when the program
257	/// exits. Every call to this function will return the same path for the lifetime of the
258	/// program.
259	pub fn new_temp_dir() -> io::Result<BasePath> {
260		let mut temp = BASE_PATH_TEMP.write();
261
262		match &*temp {
263			Some(p) => Ok(Self::new(p.path())),
264			None => {
265				let temp_dir = tempfile::Builder::new().prefix("substrate").tempdir()?;
266				let path = PathBuf::from(temp_dir.path());
267
268				*temp = Some(temp_dir);
269				Ok(Self::new(path))
270			},
271		}
272	}
273
274	/// Create a `BasePath` instance based on an existing path on disk.
275	///
276	/// Note: this function will not ensure that the directory exist nor create the directory. It
277	/// will also not delete the directory when the instance is dropped.
278	pub fn new<P: Into<PathBuf>>(path: P) -> BasePath {
279		Self { path: path.into() }
280	}
281
282	/// Create a base path from values describing the project.
283	pub fn from_project(qualifier: &str, organization: &str, application: &str) -> BasePath {
284		BasePath::new(
285			directories::ProjectDirs::from(qualifier, organization, application)
286				.expect("app directories exist on all supported platforms; qed")
287				.data_local_dir(),
288		)
289	}
290
291	/// Retrieve the base path.
292	pub fn path(&self) -> &Path {
293		&self.path
294	}
295
296	/// Returns the configuration directory inside this base path.
297	///
298	/// The path looks like `$base_path/chains/$chain_id`
299	pub fn config_dir(&self, chain_id: &str) -> PathBuf {
300		self.path().join("chains").join(chain_id)
301	}
302}
303
304impl From<PathBuf> for BasePath {
305	fn from(path: PathBuf) -> Self {
306		BasePath::new(path)
307	}
308}
309
310/// RPC configuration.
311#[derive(Debug)]
312pub struct RpcConfiguration {
313	/// JSON-RPC server endpoints.
314	pub addr: Option<Vec<RpcEndpoint>>,
315	/// Maximum number of connections for JSON-RPC server.
316	pub max_connections: u32,
317	/// CORS settings for HTTP & WS servers. `None` if all origins are allowed.
318	pub cors: Option<Vec<String>>,
319	/// RPC methods to expose (by default only a safe subset or all of them).
320	pub methods: RpcMethods,
321	/// Maximum payload of a rpc request
322	pub max_request_size: u32,
323	/// Maximum payload of a rpc response.
324	pub max_response_size: u32,
325	/// Custom JSON-RPC subscription ID provider.
326	///
327	/// Default: [`crate::RandomStringSubscriptionId`].
328	pub id_provider: Option<Box<dyn RpcSubscriptionIdProvider>>,
329	/// Maximum allowed subscriptions per rpc connection
330	pub max_subs_per_conn: u32,
331	/// JSON-RPC server default port.
332	pub port: u16,
333	/// The number of messages the JSON-RPC server is allowed to keep in memory.
334	pub message_buffer_capacity: u32,
335	/// JSON-RPC server batch config.
336	pub batch_config: RpcBatchRequestConfig,
337	/// RPC rate limit per minute.
338	pub rate_limit: Option<NonZeroU32>,
339	/// RPC rate limit whitelisted ip addresses.
340	pub rate_limit_whitelisted_ips: Vec<IpNetwork>,
341	/// RPC rate limit trust proxy headers.
342	pub rate_limit_trust_proxy_headers: bool,
343}
344
345/// Runtime executor configuration.
346#[derive(Debug, Clone)]
347pub struct ExecutorConfiguration {
348	/// Wasm execution method.
349	pub wasm_method: WasmExecutionMethod,
350	/// The size of the instances cache.
351	///
352	/// The default value is 8.
353	pub max_runtime_instances: usize,
354	/// The default number of 64KB pages to allocate for Wasm execution
355	pub default_heap_pages: Option<u64>,
356	/// Maximum number of different runtime versions that can be cached.
357	pub runtime_cache_size: u8,
358}
359
360impl Default for ExecutorConfiguration {
361	fn default() -> Self {
362		Self {
363			wasm_method: WasmExecutionMethod::default(),
364			max_runtime_instances: 8,
365			default_heap_pages: None,
366			runtime_cache_size: 2,
367		}
368	}
369}