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::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#[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 state_pruning: Option<PruningMode>,
75 pub blocks_pruning: BlocksPruning,
79 pub chain_spec: Box<dyn ChainSpec>,
81 pub executor: ExecutorConfiguration,
83 pub wasm_runtime_overrides: Option<PathBuf>,
87 pub rpc: RpcConfiguration,
89 pub prometheus_config: Option<PrometheusConfig>,
91 pub telemetry_endpoints: Option<TelemetryEndpoints>,
93 pub offchain_worker: OffchainWorkerConfig,
95 pub force_authoring: bool,
97 pub disable_grandpa: bool,
99 pub dev_key_seed: Option<String>,
106 pub tracing_targets: Option<String>,
108 pub tracing_receiver: sc_tracing::TracingReceiver,
110 pub announce_block: bool,
112 pub data_path: PathBuf,
114 pub base_path: BasePath,
116}
117
118#[derive(PartialEq)]
120pub enum TaskType {
121 Async,
123 Blocking,
125}
126
127#[derive(Debug, Clone)]
129pub enum KeystoreConfig {
130 Path {
132 path: PathBuf,
134 password: Option<SecretString>,
136 },
137 InMemory,
139}
140
141impl KeystoreConfig {
142 pub fn path(&self) -> Option<&Path> {
144 match self {
145 Self::Path { path, .. } => Some(path),
146 Self::InMemory => None,
147 }
148 }
149}
150#[derive(Debug, Clone, Default)]
152pub struct OffchainWorkerConfig {
153 pub enabled: bool,
155 pub indexing_enabled: bool,
157}
158
159#[derive(Debug, Clone)]
161pub struct PrometheusConfig {
162 pub port: SocketAddr,
164 pub registry: Registry,
166}
167
168impl PrometheusConfig {
169 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 pub fn display_role(&self) -> String {
183 self.role.to_string()
184 }
185
186 pub fn prometheus_registry(&self) -> Option<&Registry> {
188 self.prometheus_config.as_ref().map(|config| &config.registry)
189 }
190
191 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 pub fn no_genesis(&self) -> bool {
210 matches!(self.network.sync_mode, SyncMode::LightState { .. } | SyncMode::Warp { .. })
211 }
212
213 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#[derive(Clone, Debug)]
229pub struct BasePath {
230 path: PathBuf,
231}
232
233impl BasePath {
234 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 pub fn new<P: Into<PathBuf>>(path: P) -> BasePath {
260 Self { path: path.into() }
261 }
262
263 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 pub fn path(&self) -> &Path {
274 &self.path
275 }
276
277 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#[derive(Debug)]
293pub struct RpcConfiguration {
294 pub addr: Option<Vec<RpcEndpoint>>,
296 pub max_connections: u32,
298 pub cors: Option<Vec<String>>,
300 pub methods: RpcMethods,
302 pub max_request_size: u32,
304 pub max_response_size: u32,
306 pub id_provider: Option<Box<dyn RpcSubscriptionIdProvider>>,
310 pub max_subs_per_conn: u32,
312 pub port: u16,
314 pub message_buffer_capacity: u32,
316 pub batch_config: RpcBatchRequestConfig,
318 pub rate_limit: Option<NonZeroU32>,
320 pub rate_limit_whitelisted_ips: Vec<IpNetwork>,
322 pub rate_limit_trust_proxy_headers: bool,
324}
325
326#[derive(Debug, Clone)]
328pub struct ExecutorConfiguration {
329 pub wasm_method: WasmExecutionMethod,
331 pub max_runtime_instances: usize,
335 pub default_heap_pages: Option<u64>,
337 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}