// Copyright 2017-2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see .
//! Substrate CLI library.
#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#[macro_use]
mod traits;
mod params;
mod execution_strategy;
pub mod error;
pub mod informant;
use client::ExecutionStrategies;
use service::{
config::{Configuration, DatabaseConfig},
ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert,
RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec,
};
use network::{
self,
multiaddr::Protocol,
config::{
NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr
},
};
use primitives::H256;
use std::{
io::{Write, Read, Seek, Cursor, stdin, stdout, ErrorKind}, iter, fs::{self, File},
net::{Ipv4Addr, SocketAddr}, path::{Path, PathBuf}, str::FromStr,
};
use names::{Generator, Name};
use regex::Regex;
use structopt::{StructOpt, clap::AppSettings};
#[doc(hidden)]
pub use structopt::clap::App;
use params::{
RunCmd, PurgeChainCmd, RevertCmd, ImportBlocksCmd, ExportBlocksCmd, BuildSpecCmd,
NetworkConfigurationParams, MergeParameters, TransactionPoolParams,
NodeKeyParams, NodeKeyType, Cors,
};
pub use params::{NoCustom, CoreParams, SharedParams, ExecutionStrategy as ExecutionStrategyParam};
pub use traits::{GetLogFilter, AugmentClap};
use app_dirs::{AppInfo, AppDataType};
use log::info;
use lazy_static::lazy_static;
use futures::Future;
use substrate_telemetry::TelemetryEndpoints;
/// default sub directory to store network config
const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network";
/// default sub directory to store database
const DEFAULT_DB_CONFIG_PATH : &'static str = "db";
/// default sub directory for the key store
const DEFAULT_KEYSTORE_CONFIG_PATH : &'static str = "keystore";
/// The maximum number of characters for a node name.
const NODE_NAME_MAX_LENGTH: usize = 32;
/// The file name of the node's Ed25519 secret key inside the chain-specific
/// network config directory, if neither `--node-key` nor `--node-key-file`
/// is specified in combination with `--node-key-type=ed25519`.
const NODE_KEY_ED25519_FILE: &str = "secret_ed25519";
/// Executable version. Used to pass version information from the root crate.
#[derive(Clone)]
pub struct VersionInfo {
/// Implementaiton name.
pub name: &'static str,
/// Implementation version.
pub version: &'static str,
/// SCM Commit hash.
pub commit: &'static str,
/// Executable file name.
pub executable_name: &'static str,
/// Executable file description.
pub description: &'static str,
/// Executable file author.
pub author: &'static str,
/// Support URL.
pub support_url: &'static str,
}
/// Something that can be converted into an exit signal.
pub trait IntoExit {
/// Exit signal type.
type Exit: Future + Send + 'static;
/// Convert into exit signal.
fn into_exit(self) -> Self::Exit;
}
fn get_chain_key(cli: &SharedParams) -> String {
match cli.chain {
Some(ref chain) => chain.clone(),
None => if cli.dev { "dev".into() } else { "".into() }
}
}
fn generate_node_name() -> String {
let result = loop {
let node_name = Generator::with_naming(Name::Numbered).next().unwrap();
let count = node_name.chars().count();
if count < NODE_NAME_MAX_LENGTH {
break node_name
}
};
result
}
fn load_spec(cli: &SharedParams, factory: F) -> error::Result> where
G: RuntimeGenesis,
E: ChainSpecExtension,
F: FnOnce(&str) -> Result