pub use jsonrpsee::server::BatchRequestConfig as RpcBatchRequestConfig;
use prometheus_endpoint::Registry;
use sc_chain_spec::ChainSpec;
pub use sc_client_db::{BlocksPruning, Database, DatabaseSource, PruningMode};
pub use sc_executor::{WasmExecutionMethod, WasmtimeInstantiationStrategy};
pub use sc_network::{
config::{
MultiaddrWithPeerId, NetworkConfiguration, NodeKeyConfig, NonDefaultSetConfig, ProtocolId,
Role, SetConfig, SyncMode, TransportConfig,
},
request_responses::{
IncomingRequest, OutgoingResponse, ProtocolConfig as RequestResponseConfig,
},
Multiaddr,
};
pub use sc_rpc_server::{
IpNetwork, RpcEndpoint, RpcMethods, SubscriptionIdProvider as RpcSubscriptionIdProvider,
};
pub use sc_telemetry::TelemetryEndpoints;
pub use sc_transaction_pool::TransactionPoolOptions;
use sp_core::crypto::SecretString;
use std::{
io, iter,
net::SocketAddr,
num::NonZeroU32,
path::{Path, PathBuf},
};
use tempfile::TempDir;
#[derive(Debug)]
pub struct Configuration {
pub impl_name: String,
pub impl_version: String,
pub role: Role,
pub tokio_handle: tokio::runtime::Handle,
pub transaction_pool: TransactionPoolOptions,
pub network: NetworkConfiguration,
pub keystore: KeystoreConfig,
pub database: DatabaseSource,
pub trie_cache_maximum_size: Option<usize>,
pub warm_up_trie_cache: Option<TrieCacheWarmUpStrategy>,
pub state_pruning: Option<PruningMode>,
pub blocks_pruning: BlocksPruning,
pub chain_spec: Box<dyn ChainSpec>,
pub executor: ExecutorConfiguration,
pub wasm_runtime_overrides: Option<PathBuf>,
pub rpc: RpcConfiguration,
pub prometheus_config: Option<PrometheusConfig>,
pub telemetry_endpoints: Option<TelemetryEndpoints>,
pub offchain_worker: OffchainWorkerConfig,
pub force_authoring: bool,
pub disable_grandpa: bool,
pub dev_key_seed: Option<String>,
pub tracing_targets: Option<String>,
pub tracing_receiver: sc_tracing::TracingReceiver,
pub announce_block: bool,
pub data_path: PathBuf,
pub base_path: BasePath,
}
#[derive(Debug, Clone, Copy)]
pub enum TrieCacheWarmUpStrategy {
NonBlocking,
Blocking,
}
impl TrieCacheWarmUpStrategy {
pub(crate) fn is_blocking(&self) -> bool {
matches!(self, Self::Blocking)
}
}
#[derive(PartialEq)]
pub enum TaskType {
Async,
Blocking,
}
#[derive(Debug, Clone)]
pub enum KeystoreConfig {
Path {
path: PathBuf,
password: Option<SecretString>,
},
InMemory,
}
impl KeystoreConfig {
pub fn path(&self) -> Option<&Path> {
match self {
Self::Path { path, .. } => Some(path),
Self::InMemory => None,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct OffchainWorkerConfig {
pub enabled: bool,
pub indexing_enabled: bool,
}
#[derive(Debug, Clone)]
pub struct PrometheusConfig {
pub port: SocketAddr,
pub registry: Registry,
}
impl PrometheusConfig {
pub fn new_with_default_registry(port: SocketAddr, chain_id: String) -> Self {
let param = iter::once((String::from("chain"), chain_id)).collect();
Self {
port,
registry: Registry::new_custom(None, Some(param))
.expect("this can only fail if the prefix is empty"),
}
}
}
impl Configuration {
pub fn display_role(&self) -> String {
self.role.to_string()
}
pub fn prometheus_registry(&self) -> Option<&Registry> {
self.prometheus_config.as_ref().map(|config| &config.registry)
}
pub fn protocol_id(&self) -> ProtocolId {
let protocol_id_full = match self.chain_spec.protocol_id() {
Some(pid) => pid,
None => {
log::warn!(
"Using default protocol ID {:?} because none is configured in the \
chain specs",
crate::DEFAULT_PROTOCOL_ID
);
crate::DEFAULT_PROTOCOL_ID
},
};
ProtocolId::from(protocol_id_full)
}
pub fn no_genesis(&self) -> bool {
matches!(self.network.sync_mode, SyncMode::LightState { .. } | SyncMode::Warp { .. })
}
pub fn db_config(&self) -> sc_client_db::DatabaseSettings {
sc_client_db::DatabaseSettings {
trie_cache_maximum_size: self.trie_cache_maximum_size,
state_pruning: self.state_pruning.clone(),
source: self.database.clone(),
blocks_pruning: self.blocks_pruning,
pruning_filters: Default::default(),
metrics_registry: self.prometheus_registry().cloned(),
}
}
}
#[static_init::dynamic(drop, lazy)]
static mut BASE_PATH_TEMP: Option<TempDir> = None;
#[derive(Clone, Debug)]
pub struct BasePath {
path: PathBuf,
}
impl BasePath {
pub fn new_temp_dir() -> io::Result<BasePath> {
let mut temp = BASE_PATH_TEMP.write();
match &*temp {
Some(p) => Ok(Self::new(p.path())),
None => {
let temp_dir = tempfile::Builder::new().prefix("substrate").tempdir()?;
let path = PathBuf::from(temp_dir.path());
*temp = Some(temp_dir);
Ok(Self::new(path))
},
}
}
pub fn new<P: Into<PathBuf>>(path: P) -> BasePath {
Self { path: path.into() }
}
pub fn from_project(qualifier: &str, organization: &str, application: &str) -> BasePath {
BasePath::new(
directories::ProjectDirs::from(qualifier, organization, application)
.expect("app directories exist on all supported platforms; qed")
.data_local_dir(),
)
}
pub fn path(&self) -> &Path {
&self.path
}
pub fn config_dir(&self, chain_id: &str) -> PathBuf {
self.path().join("chains").join(chain_id)
}
}
impl From<PathBuf> for BasePath {
fn from(path: PathBuf) -> Self {
BasePath::new(path)
}
}
#[derive(Debug)]
pub struct RpcConfiguration {
pub addr: Option<Vec<RpcEndpoint>>,
pub max_connections: u32,
pub cors: Option<Vec<String>>,
pub methods: RpcMethods,
pub max_request_size: u32,
pub max_response_size: u32,
pub id_provider: Option<Box<dyn RpcSubscriptionIdProvider>>,
pub max_subs_per_conn: u32,
pub port: u16,
pub message_buffer_capacity: u32,
pub batch_config: RpcBatchRequestConfig,
pub rate_limit: Option<NonZeroU32>,
pub rate_limit_whitelisted_ips: Vec<IpNetwork>,
pub rate_limit_trust_proxy_headers: bool,
pub request_logger_limit: u32,
}
#[derive(Debug, Clone)]
pub struct ExecutorConfiguration {
pub wasm_method: WasmExecutionMethod,
pub max_runtime_instances: usize,
pub default_heap_pages: Option<u64>,
pub runtime_cache_size: u8,
}
impl Default for ExecutorConfiguration {
fn default() -> Self {
Self {
wasm_method: WasmExecutionMethod::default(),
max_runtime_instances: 8,
default_heap_pages: None,
runtime_cache_size: 2,
}
}
}