// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
use crate::{
arg_enums::RpcMethods,
error::{Error, Result},
params::{
ImportParams, KeystoreParams, NetworkParams, OffchainWorkerParams, SharedParams,
TransactionPoolParams,
},
CliConfiguration, PrometheusParams, RuntimeParams, TelemetryParams,
RPC_DEFAULT_MAX_CONNECTIONS, RPC_DEFAULT_MAX_REQUEST_SIZE_MB, RPC_DEFAULT_MAX_RESPONSE_SIZE_MB,
RPC_DEFAULT_MAX_SUBS_PER_CONN,
};
use clap::Parser;
use regex::Regex;
use sc_service::{
config::{BasePath, PrometheusConfig, TransactionPoolOptions},
ChainSpec, Role,
};
use sc_telemetry::TelemetryEndpoints;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
/// The `run` command used to run a node.
#[derive(Debug, Clone, Parser)]
pub struct RunCmd {
/// Enable validator mode.
/// The node will be started with the authority role and actively
/// participate in any consensus task that it can (e.g. depending on
/// availability of local keys).
#[arg(long)]
pub validator: bool,
/// Disable GRANDPA voter when running in validator mode, otherwise disable the GRANDPA
/// observer.
#[arg(long)]
pub no_grandpa: bool,
/// Listen to all RPC interfaces.
/// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use an RPC
/// proxy server to filter out dangerous methods. More details:
/// .
/// Use `--unsafe-rpc-external` to suppress the warning if you understand the risks.
#[arg(long)]
pub rpc_external: bool,
/// Listen to all RPC interfaces.
/// Same as `--rpc-external`.
#[arg(long)]
pub unsafe_rpc_external: bool,
/// RPC methods to expose.
/// - `unsafe`: Exposes every RPC method.
/// - `safe`: Exposes only a safe subset of RPC methods, denying unsafe RPC methods.
/// - `auto`: Acts as `safe` if RPC is served externally, e.g. when `--rpc--external` is
/// passed, otherwise acts as `unsafe`.
#[arg(
long,
value_name = "METHOD SET",
value_enum,
ignore_case = true,
default_value_t = RpcMethods::Auto,
verbatim_doc_comment
)]
pub rpc_methods: RpcMethods,
/// Set the the maximum RPC request payload size for both HTTP and WS in megabytes.
#[arg(long, default_value_t = RPC_DEFAULT_MAX_REQUEST_SIZE_MB)]
pub rpc_max_request_size: u32,
/// Set the the maximum RPC response payload size for both HTTP and WS in megabytes.
#[arg(long, default_value_t = RPC_DEFAULT_MAX_RESPONSE_SIZE_MB)]
pub rpc_max_response_size: u32,
/// Set the the maximum concurrent subscriptions per connection.
#[arg(long, default_value_t = RPC_DEFAULT_MAX_SUBS_PER_CONN)]
pub rpc_max_subscriptions_per_connection: u32,
/// Specify JSON-RPC server TCP port.
#[arg(long, value_name = "PORT")]
pub rpc_port: Option,
/// Maximum number of RPC server connections.
#[arg(long, value_name = "COUNT", default_value_t = RPC_DEFAULT_MAX_CONNECTIONS)]
pub rpc_max_connections: u32,
/// Specify browser Origins allowed to access the HTTP & WS RPC servers.
/// A comma-separated list of origins (protocol://domain or special `null`
/// value). Value of `all` will disable origin validation. Default is to
/// allow localhost and origins. When running in
/// --dev mode the default is to allow all origins.
#[arg(long, value_name = "ORIGINS", value_parser = parse_cors)]
pub rpc_cors: Option,
/// The human-readable name for this node.
/// It's used as network node name.
#[arg(long, value_name = "NAME")]
pub name: Option,
#[allow(missing_docs)]
#[clap(flatten)]
pub telemetry_params: TelemetryParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub prometheus_params: PrometheusParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub runtime_params: RuntimeParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub offchain_worker_params: OffchainWorkerParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub shared_params: SharedParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub import_params: ImportParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub network_params: NetworkParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub pool_config: TransactionPoolParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub keystore_params: KeystoreParams,
/// Shortcut for `--name Alice --validator` with session keys for `Alice` added to keystore.
#[arg(long, conflicts_with_all = &["bob", "charlie", "dave", "eve", "ferdie", "one", "two"])]
pub alice: bool,
/// Shortcut for `--name Bob --validator` with session keys for `Bob` added to keystore.
#[arg(long, conflicts_with_all = &["alice", "charlie", "dave", "eve", "ferdie", "one", "two"])]
pub bob: bool,
/// Shortcut for `--name Charlie --validator` with session keys for `Charlie` added to
/// keystore.
#[arg(long, conflicts_with_all = &["alice", "bob", "dave", "eve", "ferdie", "one", "two"])]
pub charlie: bool,
/// Shortcut for `--name Dave --validator` with session keys for `Dave` added to keystore.
#[arg(long, conflicts_with_all = &["alice", "bob", "charlie", "eve", "ferdie", "one", "two"])]
pub dave: bool,
/// Shortcut for `--name Eve --validator` with session keys for `Eve` added to keystore.
#[arg(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "ferdie", "one", "two"])]
pub eve: bool,
/// Shortcut for `--name Ferdie --validator` with session keys for `Ferdie` added to keystore.
#[arg(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "eve", "one", "two"])]
pub ferdie: bool,
/// Shortcut for `--name One --validator` with session keys for `One` added to keystore.
#[arg(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "eve", "ferdie", "two"])]
pub one: bool,
/// Shortcut for `--name Two --validator` with session keys for `Two` added to keystore.
#[arg(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "eve", "ferdie", "one"])]
pub two: bool,
/// Enable authoring even when offline.
#[arg(long)]
pub force_authoring: bool,
/// Run a temporary node.
/// A temporary directory will be created to store the configuration and will be deleted
/// at the end of the process.
/// Note: the directory is random per process execution. This directory is used as base path
/// which includes: database, node key and keystore.
/// When `--dev` is given and no explicit `--base-path`, this option is implied.
#[arg(long, conflicts_with = "base_path")]
pub tmp: bool,
}
impl RunCmd {
/// Get the `Sr25519Keyring` matching one of the flag.
pub fn get_keyring(&self) -> Option {
use sp_keyring::Sr25519Keyring::*;
if self.alice {
Some(Alice)
} else if self.bob {
Some(Bob)
} else if self.charlie {
Some(Charlie)
} else if self.dave {
Some(Dave)
} else if self.eve {
Some(Eve)
} else if self.ferdie {
Some(Ferdie)
} else if self.one {
Some(One)
} else if self.two {
Some(Two)
} else {
None
}
}
}
impl CliConfiguration for RunCmd {
fn shared_params(&self) -> &SharedParams {
&self.shared_params
}
fn import_params(&self) -> Option<&ImportParams> {
Some(&self.import_params)
}
fn network_params(&self) -> Option<&NetworkParams> {
Some(&self.network_params)
}
fn keystore_params(&self) -> Option<&KeystoreParams> {
Some(&self.keystore_params)
}
fn offchain_worker_params(&self) -> Option<&OffchainWorkerParams> {
Some(&self.offchain_worker_params)
}
fn node_name(&self) -> Result {
let name: String = match (self.name.as_ref(), self.get_keyring()) {
(Some(name), _) => name.to_string(),
(_, Some(keyring)) => keyring.to_string(),
(None, None) => crate::generate_node_name(),
};
is_node_name_valid(&name).map_err(|msg| {
Error::Input(format!(
"Invalid node name '{}'. Reason: {}. If unsure, use none.",
name, msg
))
})?;
Ok(name)
}
fn dev_key_seed(&self, is_dev: bool) -> Result