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 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#[derive(Clone, Debug)]
248pub struct BasePath {
249 path: PathBuf,
250}
251
252impl BasePath {
253 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 pub fn new<P: Into<PathBuf>>(path: P) -> BasePath {
279 Self { path: path.into() }
280 }
281
282 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 pub fn path(&self) -> &Path {
293 &self.path
294 }
295
296 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#[derive(Debug)]
312pub struct RpcConfiguration {
313 pub addr: Option<Vec<RpcEndpoint>>,
315 pub max_connections: u32,
317 pub cors: Option<Vec<String>>,
319 pub methods: RpcMethods,
321 pub max_request_size: u32,
323 pub max_response_size: u32,
325 pub id_provider: Option<Box<dyn RpcSubscriptionIdProvider>>,
329 pub max_subs_per_conn: u32,
331 pub port: u16,
333 pub message_buffer_capacity: u32,
335 pub batch_config: RpcBatchRequestConfig,
337 pub rate_limit: Option<NonZeroU32>,
339 pub rate_limit_whitelisted_ips: Vec<IpNetwork>,
341 pub rate_limit_trust_proxy_headers: bool,
343}
344
345#[derive(Debug, Clone)]
347pub struct ExecutorConfiguration {
348 pub wasm_method: WasmExecutionMethod,
350 pub max_runtime_instances: usize,
354 pub default_heap_pages: Option<u64>,
356 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}