1pub 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#[derive(Debug)]
52pub struct Configuration {
53 pub impl_name: String,
55 pub impl_version: String,
57 pub role: Role,
59 pub tokio_handle: tokio::runtime::Handle,
61 pub transaction_pool: TransactionPoolOptions,
63 pub network: NetworkConfiguration,
65 pub keystore: KeystoreConfig,
67 pub database: DatabaseSource,
69 pub trie_cache_maximum_size: Option<usize>,
73 pub warm_up_trie_cache: Option<TrieCacheWarmUpStrategy>,
75 pub state_pruning: Option<PruningMode>,
77 pub blocks_pruning: BlocksPruning,
81 pub chain_spec: Box<dyn ChainSpec>,
83 pub executor: ExecutorConfiguration,
85 pub wasm_runtime_overrides: Option<PathBuf>,
89 pub rpc: RpcConfiguration,
91 pub prometheus_config: Option<PrometheusConfig>,
93 pub telemetry_endpoints: Option<TelemetryEndpoints>,
95 pub offchain_worker: OffchainWorkerConfig,
97 pub force_authoring: bool,
99 pub disable_grandpa: bool,
101 pub dev_key_seed: Option<String>,
108 pub tracing_targets: Option<String>,
110 pub tracing_receiver: sc_tracing::TracingReceiver,
112 pub announce_block: bool,
114 pub data_path: PathBuf,
116 pub base_path: BasePath,
118}
119
120#[derive(Debug, Clone, Copy)]
122pub enum TrieCacheWarmUpStrategy {
123 NonBlocking,
125 Blocking,
127}
128
129impl TrieCacheWarmUpStrategy {
130 pub(crate) fn is_blocking(&self) -> bool {
132 matches!(self, Self::Blocking)
133 }
134}
135
136#[derive(PartialEq)]
138pub enum TaskType {
139 Async,
141 Blocking,
143}
144
145#[derive(Debug, Clone)]
147pub enum KeystoreConfig {
148 Path {
150 path: PathBuf,
152 password: Option<SecretString>,
154 },
155 InMemory,
157}
158
159impl KeystoreConfig {
160 pub fn path(&self) -> Option<&Path> {
162 match self {
163 Self::Path { path, .. } => Some(path),
164 Self::InMemory => None,
165 }
166 }
167}
168#[derive(Debug, Clone, Default)]
170pub struct OffchainWorkerConfig {
171 pub enabled: bool,
173 pub indexing_enabled: bool,
175}
176
177#[derive(Debug, Clone)]
179pub struct PrometheusConfig {
180 pub port: SocketAddr,
182 pub registry: Registry,
184}
185
186impl PrometheusConfig {
187 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 pub fn display_role(&self) -> String {
201 self.role.to_string()
202 }
203
204 pub fn prometheus_registry(&self) -> Option<&Registry> {
206 self.prometheus_config.as_ref().map(|config| &config.registry)
207 }
208
209 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 pub fn no_genesis(&self) -> bool {
228 matches!(self.network.sync_mode, SyncMode::LightState { .. } | SyncMode::Warp { .. })
229 }
230
231 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 pruning_filters: Default::default(),
239 metrics_registry: self.prometheus_registry().cloned(),
240 }
241 }
242}
243
244#[static_init::dynamic(drop, lazy)]
245static mut BASE_PATH_TEMP: Option<TempDir> = None;
246
247#[derive(Clone, Debug)]
249pub struct BasePath {
250 path: PathBuf,
251}
252
253impl BasePath {
254 pub fn new_temp_dir() -> io::Result<BasePath> {
261 let mut temp = BASE_PATH_TEMP.write();
262
263 match &*temp {
264 Some(p) => Ok(Self::new(p.path())),
265 None => {
266 let temp_dir = tempfile::Builder::new().prefix("substrate").tempdir()?;
267 let path = PathBuf::from(temp_dir.path());
268
269 *temp = Some(temp_dir);
270 Ok(Self::new(path))
271 },
272 }
273 }
274
275 pub fn new<P: Into<PathBuf>>(path: P) -> BasePath {
280 Self { path: path.into() }
281 }
282
283 pub fn from_project(qualifier: &str, organization: &str, application: &str) -> BasePath {
285 BasePath::new(
286 directories::ProjectDirs::from(qualifier, organization, application)
287 .expect("app directories exist on all supported platforms; qed")
288 .data_local_dir(),
289 )
290 }
291
292 pub fn path(&self) -> &Path {
294 &self.path
295 }
296
297 pub fn config_dir(&self, chain_id: &str) -> PathBuf {
301 self.path().join("chains").join(chain_id)
302 }
303}
304
305impl From<PathBuf> for BasePath {
306 fn from(path: PathBuf) -> Self {
307 BasePath::new(path)
308 }
309}
310
311#[derive(Debug)]
313pub struct RpcConfiguration {
314 pub addr: Option<Vec<RpcEndpoint>>,
316 pub max_connections: u32,
318 pub cors: Option<Vec<String>>,
320 pub methods: RpcMethods,
322 pub max_request_size: u32,
324 pub max_response_size: u32,
326 pub id_provider: Option<Box<dyn RpcSubscriptionIdProvider>>,
330 pub max_subs_per_conn: u32,
332 pub port: u16,
334 pub message_buffer_capacity: u32,
336 pub batch_config: RpcBatchRequestConfig,
338 pub rate_limit: Option<NonZeroU32>,
340 pub rate_limit_whitelisted_ips: Vec<IpNetwork>,
342 pub rate_limit_trust_proxy_headers: bool,
344 pub request_logger_limit: u32,
346}
347
348#[derive(Debug, Clone)]
350pub struct ExecutorConfiguration {
351 pub wasm_method: WasmExecutionMethod,
353 pub max_runtime_instances: usize,
357 pub default_heap_pages: Option<u64>,
359 pub runtime_cache_size: u8,
361}
362
363impl Default for ExecutorConfiguration {
364 fn default() -> Self {
365 Self {
366 wasm_method: WasmExecutionMethod::default(),
367 max_runtime_instances: 8,
368 default_heap_pages: None,
369 runtime_cache_size: 2,
370 }
371 }
372}