* Refactor and port CLI from Docopt to Clap (#2066) * Add --can-restart and --force-direct to help * Add flag support to subc & move import/export options to subcommand * Reorder subcommand args (put positional args last in CLI help message)
This commit is contained in:
parent
a62238c19d
commit
be745f711f
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1870,6 +1870,7 @@ version = "1.8.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
|
||||
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -11,6 +11,7 @@ log = "0.3"
|
||||
env_logger = "0.4"
|
||||
rustc-hex = "1.0"
|
||||
docopt = "0.8"
|
||||
clap = "2"
|
||||
time = "0.1"
|
||||
num_cpus = "1.2"
|
||||
number_prefix = "0.2"
|
||||
|
1660
parity/cli/mod.rs
1660
parity/cli/mod.rs
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ macro_rules! println_stderr(
|
||||
);
|
||||
|
||||
macro_rules! otry {
|
||||
($e: expr) => (
|
||||
($e:expr) => (
|
||||
match $e {
|
||||
Some(ref v) => v,
|
||||
None => {
|
||||
@ -31,21 +31,107 @@ macro_rules! otry {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! if_option {
|
||||
(Option<$type:ty>, THEN {$($then:tt)*} ELSE {$($otherwise:tt)*}) => (
|
||||
$($then)*
|
||||
);
|
||||
($type:ty, THEN {$($then:tt)*} ELSE {$($otherwise:tt)*}) => (
|
||||
$($otherwise)*
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! if_vec {
|
||||
(Vec<$type:ty>, THEN {$($then:tt)*} ELSE {$($otherwise:tt)*}) => (
|
||||
$($then)*
|
||||
);
|
||||
($type:ty, THEN {$($then:tt)*} ELSE {$($otherwise:tt)*}) => (
|
||||
$($otherwise)*
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! if_option_vec {
|
||||
(Option<Vec<String>>, THEN {$then:expr} ELSE {$otherwise:expr}) => (
|
||||
$then
|
||||
);
|
||||
(Option<$type:ty>, THEN {$then:expr} ELSE {$otherwise:expr}) => (
|
||||
$otherwise
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! inner_option_type {
|
||||
(Option<$type:ty>) => (
|
||||
$type
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! inner_vec_type {
|
||||
(Vec<$type:ty>) => (
|
||||
$type
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! inner_option_vec_type {
|
||||
(Option<Vec<String>>) => (
|
||||
String
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! usage_with_ident {
|
||||
($name:expr, $usage:expr, $help:expr) => (
|
||||
if $usage.contains("<") {
|
||||
format!("<{}> {} '{}'",$name, $usage, $help)
|
||||
} else {
|
||||
format!("[{}] {} '{}'",$name, $usage, $help)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! underscore_to_hyphen {
|
||||
($e:expr) => (
|
||||
str::replace($e, "_", "-")
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! usage {
|
||||
(
|
||||
{
|
||||
$(
|
||||
$field_a:ident : $typ_a:ty,
|
||||
CMD $subc:ident
|
||||
{
|
||||
$subc_help:expr,
|
||||
|
||||
$(
|
||||
CMD $subc_subc:ident
|
||||
{
|
||||
$subc_subc_help:expr,
|
||||
$(
|
||||
FLAG $subc_subc_flag:ident : (bool) = false, $subc_subc_flag_usage:expr, $subc_subc_flag_help:expr,
|
||||
)*
|
||||
$(
|
||||
ARG $subc_subc_arg:ident : ($($subc_subc_arg_type_tt:tt)+) = $subc_subc_arg_default:expr, $subc_subc_arg_usage:expr, $subc_subc_arg_help:expr,
|
||||
)*
|
||||
}
|
||||
)*
|
||||
|
||||
$(
|
||||
FLAG $subc_flag:ident : (bool) = false, $subc_flag_usage:expr, $subc_flag_help:expr,
|
||||
)*
|
||||
$(
|
||||
ARG $subc_arg:ident : ($($subc_arg_type_tt:tt)+) = $subc_arg_default:expr, $subc_arg_usage:expr, $subc_arg_help:expr,
|
||||
)*
|
||||
}
|
||||
)*
|
||||
}
|
||||
{
|
||||
$(
|
||||
$field:ident : $typ:ty = $default:expr, or $from_config:expr,
|
||||
)*
|
||||
}
|
||||
{
|
||||
[$group_name:expr]
|
||||
$(
|
||||
$field_s:ident : $typ_s:ty, display $default_s:expr, or $from_config_s:expr,
|
||||
FLAG $flag:ident : (bool) = false, or $flag_from_config:expr, $flag_usage:expr, $flag_help:expr,
|
||||
)*
|
||||
$(
|
||||
ARG $arg:ident : ($($arg_type_tt:tt)+) = $arg_default:expr, or $arg_from_config:expr, $arg_usage:expr, $arg_help:expr,
|
||||
)*
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
@ -53,12 +139,17 @@ macro_rules! usage {
|
||||
use std::{fs, io, process};
|
||||
use std::io::{Read, Write};
|
||||
use util::version;
|
||||
use docopt::{Docopt, Error as DocoptError};
|
||||
use clap::{Arg, App, SubCommand, AppSettings, Error as ClapError};
|
||||
use helpers::replace_home;
|
||||
use std::ffi::OsStr;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(test)]
|
||||
use regex::Regex;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ArgsError {
|
||||
Docopt(DocoptError),
|
||||
Clap(ClapError),
|
||||
Decode(toml::de::Error),
|
||||
Config(String, io::Error),
|
||||
}
|
||||
@ -66,7 +157,7 @@ macro_rules! usage {
|
||||
impl ArgsError {
|
||||
pub fn exit(self) -> ! {
|
||||
match self {
|
||||
ArgsError::Docopt(e) => e.exit(),
|
||||
ArgsError::Clap(e) => e.exit(),
|
||||
ArgsError::Decode(e) => {
|
||||
println_stderr!("You might have supplied invalid parameters in config file.");
|
||||
println_stderr!("{}", e);
|
||||
@ -81,9 +172,9 @@ macro_rules! usage {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DocoptError> for ArgsError {
|
||||
fn from(e: DocoptError) -> Self {
|
||||
ArgsError::Docopt(e)
|
||||
impl From<ClapError> for ArgsError {
|
||||
fn from(e: ClapError) -> Self {
|
||||
ArgsError::Clap(e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,15 +187,33 @@ macro_rules! usage {
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Args {
|
||||
$(
|
||||
pub $field_a: $typ_a,
|
||||
pub $subc: bool,
|
||||
|
||||
$(
|
||||
pub $subc_subc: bool,
|
||||
$(
|
||||
pub $subc_subc_flag: bool,
|
||||
)*
|
||||
$(
|
||||
pub $subc_subc_arg: $($subc_subc_arg_type_tt)+,
|
||||
)*
|
||||
)*
|
||||
|
||||
$(
|
||||
pub $field: $typ,
|
||||
pub $subc_flag: bool,
|
||||
)*
|
||||
$(
|
||||
pub $subc_arg: $($subc_arg_type_tt)+,
|
||||
)*
|
||||
)*
|
||||
|
||||
$(
|
||||
pub $field_s: $typ_s,
|
||||
$(
|
||||
pub $flag: bool,
|
||||
)*
|
||||
$(
|
||||
pub $arg: $($arg_type_tt)+,
|
||||
)*
|
||||
)*
|
||||
}
|
||||
|
||||
@ -112,15 +221,32 @@ macro_rules! usage {
|
||||
fn default() -> Self {
|
||||
Args {
|
||||
$(
|
||||
$field_a: Default::default(),
|
||||
$subc: Default::default(),
|
||||
$(
|
||||
$subc_subc: Default::default(),
|
||||
$(
|
||||
$subc_subc_flag: Default::default(),
|
||||
)*
|
||||
$(
|
||||
$subc_subc_arg: Default::default(),
|
||||
)*
|
||||
)*
|
||||
|
||||
$(
|
||||
$field: $default.into(),
|
||||
$subc_flag: Default::default(),
|
||||
)*
|
||||
$(
|
||||
$subc_arg: Default::default(),
|
||||
)*
|
||||
)*
|
||||
|
||||
$(
|
||||
$field_s: Default::default(),
|
||||
$(
|
||||
$flag: Default::default(),
|
||||
)*
|
||||
$(
|
||||
$arg: Default::default(),
|
||||
)*
|
||||
)*
|
||||
}
|
||||
}
|
||||
@ -129,13 +255,46 @@ macro_rules! usage {
|
||||
#[derive(Default, Debug, PartialEq, Clone, Deserialize)]
|
||||
struct RawArgs {
|
||||
$(
|
||||
$field_a: $typ_a,
|
||||
$subc: bool,
|
||||
|
||||
$(
|
||||
$subc_subc: bool,
|
||||
$(
|
||||
$subc_subc_flag: bool,
|
||||
)*
|
||||
$(
|
||||
$field: Option<$typ>,
|
||||
$subc_subc_arg: if_option!(
|
||||
$($subc_subc_arg_type_tt)+,
|
||||
THEN { $($subc_subc_arg_type_tt)+ }
|
||||
ELSE { Option<$($subc_subc_arg_type_tt)+> }
|
||||
),
|
||||
)*
|
||||
)*
|
||||
|
||||
$(
|
||||
$subc_flag: bool,
|
||||
)*
|
||||
$(
|
||||
$field_s: Option<$typ_s>,
|
||||
$subc_arg: if_option!(
|
||||
$($subc_arg_type_tt)+,
|
||||
THEN { $($subc_arg_type_tt)+ }
|
||||
ELSE { Option<$($subc_arg_type_tt)+> }
|
||||
),
|
||||
)*
|
||||
|
||||
)*
|
||||
$(
|
||||
$(
|
||||
$flag: bool,
|
||||
)*
|
||||
|
||||
$(
|
||||
$arg: if_option!(
|
||||
$($arg_type_tt)+,
|
||||
THEN { $($arg_type_tt)+ }
|
||||
ELSE { Option<$($arg_type_tt)+> }
|
||||
),
|
||||
)*
|
||||
)*
|
||||
}
|
||||
|
||||
@ -149,9 +308,9 @@ macro_rules! usage {
|
||||
return Ok(raw_args.into_args(Config::default()));
|
||||
}
|
||||
|
||||
let config_file = raw_args.flag_config.clone().unwrap_or_else(|| raw_args.clone().into_args(Config::default()).flag_config);
|
||||
let config_file = raw_args.arg_config.clone().unwrap_or_else(|| raw_args.clone().into_args(Config::default()).arg_config);
|
||||
let config_file = replace_home(&::dir::default_data_path(), &config_file);
|
||||
match (fs::File::open(&config_file), raw_args.flag_config.clone()) {
|
||||
match (fs::File::open(&config_file), raw_args.arg_config.clone()) {
|
||||
// Load config file
|
||||
(Ok(mut file), _) => {
|
||||
println_stderr!("Loading config file from {}", &config_file);
|
||||
@ -178,7 +337,7 @@ macro_rules! usage {
|
||||
|
||||
#[cfg(test)]
|
||||
fn parse_with_config<S: AsRef<str>>(command: &[S], config: Config) -> Result<Self, ArgsError> {
|
||||
RawArgs::parse(command).map(|raw| raw.into_args(config)).map_err(ArgsError::Docopt)
|
||||
RawArgs::parse(command).map(|raw| raw.into_args(config)).map_err(ArgsError::Clap)
|
||||
}
|
||||
|
||||
fn parse_config(config: &str) -> Result<Config, ArgsError> {
|
||||
@ -188,41 +347,346 @@ macro_rules! usage {
|
||||
pub fn print_version() -> String {
|
||||
format!(include_str!("./version.txt"), version())
|
||||
}
|
||||
|
||||
#[allow(unused_mut)] // subc_subc_exist may be assigned true by the macro
|
||||
#[allow(unused_assignments)] // Rust issue #22630
|
||||
pub fn print_help() -> String {
|
||||
let mut help : String = include_str!("./usage_header.txt").to_owned();
|
||||
|
||||
help.push_str("\n\n");
|
||||
|
||||
// Subcommands
|
||||
help.push_str("parity [options]\n");
|
||||
$(
|
||||
{
|
||||
let mut subc_subc_exist = false;
|
||||
|
||||
$(
|
||||
subc_subc_exist = true;
|
||||
let subc_subc_usages : Vec<&str> = vec![
|
||||
$(
|
||||
concat!("[",$subc_subc_flag_usage,"]"),
|
||||
)*
|
||||
$(
|
||||
$subc_subc_arg_usage,
|
||||
)*
|
||||
];
|
||||
|
||||
if subc_subc_usages.is_empty() {
|
||||
help.push_str(&format!("parity [options] {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..])));
|
||||
} else {
|
||||
help.push_str(&format!("parity [options] {} {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]), subc_subc_usages.join(" ")));
|
||||
}
|
||||
)*
|
||||
|
||||
// Print the subcommand on its own only if it has no subsubcommands
|
||||
if !subc_subc_exist {
|
||||
let subc_usages : Vec<&str> = vec![
|
||||
$(
|
||||
concat!("[",$subc_flag_usage,"]"),
|
||||
)*
|
||||
$(
|
||||
$subc_arg_usage,
|
||||
)*
|
||||
];
|
||||
|
||||
if subc_usages.is_empty() {
|
||||
help.push_str(&format!("parity [options] {}\n", underscore_to_hyphen!(&stringify!($subc)[4..])));
|
||||
} else {
|
||||
help.push_str(&format!("parity [options] {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), subc_usages.join(" ")));
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
// Arguments and flags
|
||||
$(
|
||||
help.push_str("\n");
|
||||
help.push_str($group_name); help.push_str(":\n");
|
||||
|
||||
$(
|
||||
help.push_str(&format!("\t{}\n\t\t{}\n", $flag_usage, $flag_help));
|
||||
)*
|
||||
|
||||
$(
|
||||
if_option!(
|
||||
$($arg_type_tt)+,
|
||||
THEN {
|
||||
if_option_vec!(
|
||||
$($arg_type_tt)+,
|
||||
THEN {
|
||||
help.push_str(&format!("\t{}\n\t\t{} (default: {:?})\n", $arg_usage, $arg_help, {let x : inner_option_type!($($arg_type_tt)+)> = $arg_default; x}))
|
||||
}
|
||||
ELSE {
|
||||
help.push_str(&format!("\t{}\n\t\t{}{}\n", $arg_usage, $arg_help, $arg_default.map(|x: inner_option_type!($($arg_type_tt)+)| format!(" (default: {})",x)).unwrap_or("".to_owned())))
|
||||
}
|
||||
)
|
||||
}
|
||||
ELSE {
|
||||
if_vec!(
|
||||
$($arg_type_tt)+,
|
||||
THEN {
|
||||
help.push_str(&format!("\t{}\n\t\t{} (default: {:?})\n", $arg_usage, $arg_help, {let x : $($arg_type_tt)+ = $arg_default; x}))
|
||||
}
|
||||
ELSE {
|
||||
help.push_str(&format!("\t{}\n\t\t{} (default: {})\n", $arg_usage, $arg_help, $arg_default))
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
)*
|
||||
|
||||
)*
|
||||
|
||||
help
|
||||
}
|
||||
}
|
||||
|
||||
impl RawArgs {
|
||||
fn into_args(self, config: Config) -> Args {
|
||||
let mut args = Args::default();
|
||||
$(
|
||||
args.$field_a = self.$field_a;
|
||||
args.$subc = self.$subc;
|
||||
|
||||
$(
|
||||
args.$subc_subc = self.$subc_subc;
|
||||
$(
|
||||
args.$subc_subc_flag = self.$subc_subc_flag;
|
||||
)*
|
||||
$(
|
||||
args.$field = self.$field.or_else(|| $from_config(&config)).unwrap_or_else(|| $default.into());
|
||||
args.$subc_subc_arg = if_option!(
|
||||
$($subc_subc_arg_type_tt)+,
|
||||
THEN { self.$subc_subc_arg.or($subc_subc_arg_default) }
|
||||
ELSE { self.$subc_subc_arg.unwrap_or($subc_subc_arg_default.into()) }
|
||||
);
|
||||
)*
|
||||
)*
|
||||
|
||||
$(
|
||||
args.$subc_flag = self.$subc_flag;
|
||||
)*
|
||||
$(
|
||||
args.$field_s = self.$field_s.or_else(|| $from_config_s(&config)).unwrap_or(None);
|
||||
args.$subc_arg = if_option!(
|
||||
$($subc_arg_type_tt)+,
|
||||
THEN { self.$subc_arg.or($subc_arg_default) }
|
||||
ELSE { self.$subc_arg.unwrap_or($subc_arg_default.into()) }
|
||||
);
|
||||
)*
|
||||
)*
|
||||
|
||||
$(
|
||||
$(
|
||||
args.$flag = self.$flag || $flag_from_config(&config).unwrap_or(false);
|
||||
)*
|
||||
$(
|
||||
args.$arg = if_option!(
|
||||
$($arg_type_tt)+,
|
||||
THEN { self.$arg.or_else(|| $arg_from_config(&config)).or_else(|| $arg_default.into()) }
|
||||
ELSE { self.$arg.or_else(|| $arg_from_config(&config)).unwrap_or_else(|| $arg_default.into()) }
|
||||
);
|
||||
)*
|
||||
)*
|
||||
args
|
||||
}
|
||||
|
||||
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, DocoptError> {
|
||||
Docopt::new(Self::usage()).and_then(|d| d.argv(command).deserialize())
|
||||
}
|
||||
#[allow(unused_variables)] // the submatches of arg-less subcommands aren't used
|
||||
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, ClapError> {
|
||||
|
||||
fn usage() -> String {
|
||||
format!(
|
||||
include_str!("./usage.txt"),
|
||||
let usages = vec![
|
||||
$(
|
||||
$field={ let v: $typ = $default.into(); v },
|
||||
// Uncomment this to debug
|
||||
// "named argument never used" error
|
||||
// $field = $default,
|
||||
$(
|
||||
usage_with_ident!(stringify!($arg), $arg_usage, $arg_help),
|
||||
)*
|
||||
$(
|
||||
$field_s = $default_s,
|
||||
usage_with_ident!(stringify!($flag), $flag_usage, $flag_help),
|
||||
)*
|
||||
)*
|
||||
];
|
||||
|
||||
// Hash of subc|subc_subc => Vec<String>
|
||||
let mut subc_usages = HashMap::new();
|
||||
$(
|
||||
{
|
||||
let this_subc_usages = vec![
|
||||
$(
|
||||
usage_with_ident!(stringify!($subc_flag), $subc_flag_usage, $subc_flag_help),
|
||||
)*
|
||||
$(
|
||||
usage_with_ident!(stringify!($subc_arg), $subc_arg_usage, $subc_arg_help),
|
||||
)*
|
||||
];
|
||||
|
||||
subc_usages.insert(stringify!($subc),this_subc_usages);
|
||||
|
||||
$(
|
||||
{
|
||||
let this_subc_subc_usages = vec![
|
||||
$(
|
||||
usage_with_ident!(stringify!($subc_subc_flag), $subc_subc_flag_usage, $subc_subc_flag_help),
|
||||
)*
|
||||
$(
|
||||
usage_with_ident!(stringify!($subc_subc_arg), $subc_subc_arg_usage, $subc_subc_arg_help),
|
||||
)*
|
||||
];
|
||||
|
||||
subc_usages.insert(stringify!($subc_subc), this_subc_subc_usages);
|
||||
}
|
||||
)*
|
||||
}
|
||||
)*
|
||||
|
||||
let matches = App::new("Parity")
|
||||
.global_setting(AppSettings::VersionlessSubcommands)
|
||||
.global_setting(AppSettings::AllowLeadingHyphen) // allow for example --allow-ips -10.0.0.0/8
|
||||
.global_setting(AppSettings::DisableHelpSubcommand)
|
||||
.help(Args::print_help().as_ref())
|
||||
.args(&usages.iter().map(|u| Arg::from_usage(u).use_delimiter(false)).collect::<Vec<Arg>>())
|
||||
$(
|
||||
.subcommand(
|
||||
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc)[4..]))
|
||||
.about($subc_help)
|
||||
.args(&subc_usages.get(stringify!($subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false)).collect::<Vec<Arg>>())
|
||||
$(
|
||||
.setting(AppSettings::SubcommandRequired) // prevent from running `parity account`
|
||||
.subcommand(
|
||||
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]))
|
||||
.about($subc_subc_help)
|
||||
.args(&subc_usages.get(stringify!($subc_subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false)).collect::<Vec<Arg>>())
|
||||
)
|
||||
)*
|
||||
)
|
||||
)*
|
||||
.get_matches_from_safe(command.iter().map(|x| OsStr::new(x.as_ref())))?;
|
||||
|
||||
let mut raw_args : RawArgs = Default::default();
|
||||
$(
|
||||
$(
|
||||
raw_args.$flag = matches.is_present(stringify!($flag));
|
||||
)*
|
||||
$(
|
||||
raw_args.$arg = if_option!(
|
||||
$($arg_type_tt)+,
|
||||
THEN {
|
||||
if_option_vec!(
|
||||
$($arg_type_tt)+,
|
||||
THEN { values_t!(matches, stringify!($arg), inner_option_vec_type!($($arg_type_tt)+)).ok() }
|
||||
ELSE { value_t!(matches, stringify!($arg), inner_option_type!($($arg_type_tt)+)).ok() }
|
||||
)
|
||||
}
|
||||
ELSE {
|
||||
if_vec!(
|
||||
$($arg_type_tt)+,
|
||||
THEN { values_t!(matches, stringify!($arg), inner_vec_type!($($arg_type_tt)+)).ok() }
|
||||
ELSE { value_t!(matches, stringify!($arg), $($arg_type_tt)+).ok() }
|
||||
)
|
||||
}
|
||||
);
|
||||
)*
|
||||
)*
|
||||
|
||||
// Subcommands
|
||||
$(
|
||||
if let Some(submatches) = matches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc)[4..])) {
|
||||
raw_args.$subc = true;
|
||||
|
||||
// Subcommand flags
|
||||
$(
|
||||
raw_args.$subc_flag = submatches.is_present(&stringify!($subc_flag));
|
||||
)*
|
||||
// Subcommand arguments
|
||||
$(
|
||||
raw_args.$subc_arg = if_option!(
|
||||
$($subc_arg_type_tt)+,
|
||||
THEN {
|
||||
if_option_vec!(
|
||||
$($subc_arg_type_tt)+,
|
||||
THEN { values_t!(submatches, stringify!($subc_arg), inner_option_vec_type!($($subc_arg_type_tt)+)).ok() }
|
||||
ELSE { value_t!(submatches, stringify!($subc_arg), inner_option_type!($($subc_arg_type_tt)+)).ok() }
|
||||
)
|
||||
}
|
||||
ELSE {
|
||||
if_vec!(
|
||||
$($subc_arg_type_tt)+,
|
||||
THEN { values_t!(submatches, stringify!($subc_arg), inner_vec_type!($($subc_arg_type_tt)+)).ok() }
|
||||
ELSE { value_t!(submatches, stringify!($subc_arg), $($subc_arg_type_tt)+).ok() }
|
||||
)
|
||||
}
|
||||
);
|
||||
)*
|
||||
|
||||
// Sub-subcommands
|
||||
$(
|
||||
if let Some(subsubmatches) = submatches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..])) {
|
||||
raw_args.$subc_subc = true;
|
||||
|
||||
// Sub-subcommand flags
|
||||
$(
|
||||
raw_args.$subc_subc_flag = subsubmatches.is_present(&stringify!($subc_subc_flag));
|
||||
)*
|
||||
// Sub-subcommand arguments
|
||||
$(
|
||||
raw_args.$subc_subc_arg = if_option!(
|
||||
$($subc_subc_arg_type_tt)+,
|
||||
THEN {
|
||||
if_option_vec!(
|
||||
$($subc_subc_arg_type_tt)+,
|
||||
THEN { values_t!(subsubmatches, stringify!($subc_subc_arg), inner_option_vec_type!($($subc_subc_arg_type_tt)+)).ok() }
|
||||
ELSE { value_t!(subsubmatches, stringify!($subc_subc_arg), inner_option_type!($($subc_subc_arg_type_tt)+)).ok() }
|
||||
)
|
||||
}
|
||||
ELSE {
|
||||
if_vec!(
|
||||
$($subc_subc_arg_type_tt)+,
|
||||
THEN { values_t!(subsubmatches, stringify!($subc_subc_arg), inner_vec_type!($($subc_subc_arg_type_tt)+)).ok() }
|
||||
ELSE { value_t!(subsubmatches, stringify!($subc_subc_arg), $($subc_subc_arg_type_tt)+).ok() }
|
||||
)
|
||||
}
|
||||
);
|
||||
)*
|
||||
}
|
||||
else {
|
||||
raw_args.$subc_subc = false;
|
||||
}
|
||||
)*
|
||||
}
|
||||
else {
|
||||
raw_args.$subc = false;
|
||||
}
|
||||
)*
|
||||
|
||||
Ok(raw_args)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn usages_valid() {
|
||||
let re = Regex::new(r"^(?:(-[a-zA-Z-]+, )?--[a-z-]+(=\[[a-zA-Z]+\](\.\.\.)?|=<[a-zA-Z]+>(\.\.\.)?)?)|(?:\[[a-zA-Z-]+\])(\.\.\.)?|(?:<[a-zA-Z-]+>)(\.\.\.)?$").unwrap();
|
||||
|
||||
let usages = vec![
|
||||
$(
|
||||
$(
|
||||
$(
|
||||
$subc_subc_arg_usage,
|
||||
)*
|
||||
)*
|
||||
$(
|
||||
$subc_arg_usage,
|
||||
)*
|
||||
)*
|
||||
$(
|
||||
$(
|
||||
$flag_usage,
|
||||
)*
|
||||
$(
|
||||
$arg_usage,
|
||||
)*
|
||||
)*
|
||||
];
|
||||
|
||||
for usage in &usages {
|
||||
assert!(re.is_match(usage));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,499 +0,0 @@
|
||||
Parity. Ethereum Client.
|
||||
By Wood/Paronyan/Kotewicz/Drwięga/Volf et al.
|
||||
Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd
|
||||
|
||||
Usage:
|
||||
parity [options]
|
||||
parity ui [options]
|
||||
parity dapp <path> [options]
|
||||
parity daemon <pid-file> [options]
|
||||
parity account (new | list ) [options]
|
||||
parity account import <path>... [options]
|
||||
parity wallet import <path> --password FILE [options]
|
||||
parity import [ <file> ] [options]
|
||||
parity export (blocks | state) [ <file> ] [options]
|
||||
parity signer new-token [options]
|
||||
parity signer list [options]
|
||||
parity signer sign [ <id> ] [ --password FILE ] [options]
|
||||
parity signer reject <id> [options]
|
||||
parity snapshot <file> [options]
|
||||
parity restore [ <file> ] [options]
|
||||
parity tools hash <file>
|
||||
parity db kill [options]
|
||||
|
||||
Operating Options:
|
||||
--mode MODE Set the operating mode. MODE can be one of:
|
||||
last - Uses the last-used mode, active if none.
|
||||
active - Parity continuously syncs the chain.
|
||||
passive - Parity syncs initially, then sleeps and
|
||||
wakes regularly to resync.
|
||||
dark - Parity syncs only when the RPC is active.
|
||||
offline - Parity doesn't sync. (default: {flag_mode}).
|
||||
--mode-timeout SECS Specify the number of seconds before inactivity
|
||||
timeout occurs when mode is dark or passive
|
||||
(default: {flag_mode_timeout}).
|
||||
--mode-alarm SECS Specify the number of seconds before auto sleep
|
||||
reawake timeout occurs when mode is passive
|
||||
(default: {flag_mode_alarm}).
|
||||
--auto-update SET Set a releases set to automatically update and
|
||||
install.
|
||||
all - All updates in the our release track.
|
||||
critical - Only consensus/security updates.
|
||||
none - No updates will be auto-installed.
|
||||
(default: {flag_auto_update}).
|
||||
--release-track TRACK Set which release track we should use for updates.
|
||||
stable - Stable releases.
|
||||
beta - Beta releases.
|
||||
nightly - Nightly releases (unstable).
|
||||
testing - Testing releases (do not use).
|
||||
current - Whatever track this executable was
|
||||
released on (default: {flag_release_track}).
|
||||
--public-node Start Parity as a public web server. Account storage
|
||||
and transaction signing will be delegated to the UI.
|
||||
(default: {flag_public_node}).
|
||||
--no-download Normally new releases will be downloaded ready for
|
||||
updating. This disables it. Not recommended.
|
||||
(default: {flag_no_download}).
|
||||
--no-consensus Force the binary to run even if there are known
|
||||
issues regarding consensus. Not recommended.
|
||||
(default: {flag_no_consensus}).
|
||||
--force-direct Run the originally installed version of Parity,
|
||||
ignoring any updates that have since been installed.
|
||||
--chain CHAIN Specify the blockchain type. CHAIN may be either a
|
||||
JSON chain specification file or olympic, frontier,
|
||||
homestead, mainnet, morden, ropsten, classic, expanse,
|
||||
testnet, kovan or dev (default: {flag_chain}).
|
||||
-d --base-path PATH Specify the base data storage path.
|
||||
(default: {flag_base_path}).
|
||||
--db-path PATH Specify the database directory path
|
||||
(default: {flag_db_path}).
|
||||
--keys-path PATH Specify the path for JSON key files to be found
|
||||
(default: {flag_keys_path}).
|
||||
--identity NAME Specify your node's name. (default: {flag_identity})
|
||||
--light Experimental: run in light client mode. Light clients
|
||||
synchronize a bare minimum of data and fetch necessary
|
||||
data on-demand from the network. Much lower in storage,
|
||||
potentially higher in bandwidth. Has no effect with
|
||||
subcommands (default: {flag_light}).
|
||||
|
||||
Convenience Options:
|
||||
-c --config CONFIG Specify a configuration. CONFIG may be either a
|
||||
configuration file or a preset: dev, insecure, dev-insecure,
|
||||
mining, or non-standard-ports.
|
||||
(default: {flag_config}).
|
||||
--ports-shift SHIFT Add SHIFT to all port numbers Parity is listening on.
|
||||
Includes network port and all servers (RPC, WebSockets, UI, IPFS, SecretStore).
|
||||
(default: {flag_ports_shift})
|
||||
--unsafe-expose All servers will listen on external interfaces and will
|
||||
be remotely accessible. It's equivalent with setting
|
||||
the following: --{{ws,jsonrpc,ui,ipfs,secret_store,stratum}}-interface=all --*-hosts=all
|
||||
This option is UNSAFE and should be used with great care!
|
||||
(default: {flag_unsafe_expose})
|
||||
|
||||
Account Options:
|
||||
--unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution.
|
||||
ACCOUNTS is a comma-delimited list of addresses.
|
||||
Implies --no-ui. (default: {flag_unlock:?})
|
||||
--password FILE Provide a file containing a password for unlocking
|
||||
an account. Leading and trailing whitespace is trimmed.
|
||||
(default: {flag_password:?})
|
||||
--keys-iterations NUM Specify the number of iterations to use when
|
||||
deriving key from the password (bigger is more
|
||||
secure) (default: {flag_keys_iterations}).
|
||||
--no-hardware-wallets Disables hardware wallet support. (default: {flag_no_hardware_wallets})
|
||||
--fast-unlock Use drasticly faster unlocking mode. This setting causes
|
||||
raw secrets to be stored unprotected in memory,
|
||||
so use with care. (default: {flag_fast_unlock})
|
||||
|
||||
UI Options:
|
||||
--force-ui Enable Trusted UI WebSocket endpoint,
|
||||
even when --unlock is in use. (default: {flag_force_ui})
|
||||
--no-ui Disable Trusted UI WebSocket endpoint.
|
||||
(default: {flag_no_ui})
|
||||
--ui-port PORT Specify the port of Trusted UI server
|
||||
(default: {flag_ui_port}).
|
||||
--ui-interface IP Specify the hostname portion of the Trusted UI
|
||||
server, IP should be an interface's IP address,
|
||||
or local (default: {flag_ui_interface}).
|
||||
--ui-hosts HOSTS List of allowed Host header values. This option will
|
||||
validate the Host header sent by the browser, it
|
||||
is additional security against some attack
|
||||
vectors. Special options: "all", "none",
|
||||
(default: {flag_ui_hosts}).
|
||||
--ui-path PATH Specify directory where Trusted UIs tokens should
|
||||
be stored. (default: {flag_ui_path})
|
||||
--ui-no-validation Disable Origin and Host headers validation for
|
||||
Trusted UI. WARNING: INSECURE. Used only for
|
||||
development. (default: {flag_ui_no_validation})
|
||||
|
||||
Networking Options:
|
||||
--no-warp Disable syncing from the snapshot over the network. (default: {flag_no_warp})
|
||||
--port PORT Override the port on which the node should listen
|
||||
(default: {flag_port}).
|
||||
--min-peers NUM Try to maintain at least NUM peers (default: {flag_min_peers}).
|
||||
--max-peers NUM Allow up to NUM peers (default: {flag_max_peers}).
|
||||
--snapshot-peers NUM Allow additional NUM peers for a snapshot sync
|
||||
(default: {flag_snapshot_peers}).
|
||||
--nat METHOD Specify method to use for determining public
|
||||
address. Must be one of: any, none, upnp,
|
||||
extip:<IP> (default: {flag_nat}).
|
||||
--network-id INDEX Override the network identifier from the chain we
|
||||
are on. (default: {flag_network_id:?})
|
||||
--bootnodes NODES Override the bootnodes from our chain. NODES should
|
||||
be comma-delimited enodes. (default: {flag_bootnodes:?})
|
||||
--no-discovery Disable new peer discovery. (default: {flag_no_discovery})
|
||||
--node-key KEY Specify node secret key, either as 64-character hex
|
||||
string or input to SHA3 operation. (default: {flag_node_key:?})
|
||||
--reserved-peers FILE Provide a file containing enodes, one per line.
|
||||
These nodes will always have a reserved slot on top
|
||||
of the normal maximum peers. (default: {flag_reserved_peers:?})
|
||||
--reserved-only Connect only to reserved nodes. (default: {flag_reserved_only})
|
||||
--allow-ips FILTER Filter outbound connections. FILTER can be one of:
|
||||
private - connect to private network IP addresses only;
|
||||
public - connect to public network IP addresses only;
|
||||
all - connect to any IP address;
|
||||
none - block all (for use with a custom filter as below);
|
||||
a custom filter list in the format: "private ip_range1 -ip_range2 ...".
|
||||
Where ip_range1 would be allowed and ip_range2 blocked;
|
||||
Custom blocks ("-ip_range") override custom allows ("ip_range");
|
||||
(default: {flag_allow_ips}).
|
||||
--max-pending-peers NUM Allow up to NUM pending connections. (default: {flag_max_pending_peers})
|
||||
--no-ancient-blocks Disable downloading old blocks after snapshot restoration
|
||||
or warp sync. (default: {flag_no_ancient_blocks})
|
||||
--no-serve-light Disable serving of light peers. (default: {flag_no_serve_light})
|
||||
|
||||
API and Console Options:
|
||||
--no-jsonrpc Disable the JSON-RPC API server. (default: {flag_no_jsonrpc})
|
||||
--jsonrpc-port PORT Specify the port portion of the JSONRPC API server
|
||||
(default: {flag_jsonrpc_port}).
|
||||
--jsonrpc-interface IP Specify the hostname portion of the JSONRPC API
|
||||
server, IP should be an interface's IP address, or
|
||||
all (all interfaces) or local (default: {flag_jsonrpc_interface}).
|
||||
--jsonrpc-cors URL Specify CORS header for JSON-RPC API responses.
|
||||
(default: {flag_jsonrpc_cors:?})
|
||||
--jsonrpc-apis APIS Specify the APIs available through the JSONRPC
|
||||
interface. APIS is a comma-delimited list of API
|
||||
name. Possible name are all, safe, web3, eth, net, personal,
|
||||
parity, parity_set, traces, rpc, parity_accounts.
|
||||
You can also disable a specific API by putting '-' in the front: all,-personal
|
||||
(default: {flag_jsonrpc_apis}).
|
||||
--jsonrpc-hosts HOSTS List of allowed Host header values. This option will
|
||||
validate the Host header sent by the browser, it
|
||||
is additional security against some attack
|
||||
vectors. Special options: "all", "none",
|
||||
(default: {flag_jsonrpc_hosts}).
|
||||
--jsonrpc-server-threads NUM Enables experimental faster implementation of JSON-RPC server.
|
||||
Requires Dapps server to be disabled
|
||||
using --no-dapps. (default: {flag_jsonrpc_server_threads:?})
|
||||
--jsonrpc-threads THREADS Turn on additional processing threads in all RPC servers.
|
||||
Setting this to non-zero value allows parallel cpu-heavy queries
|
||||
execution. (default: {flag_jsonrpc_threads})
|
||||
|
||||
--no-ws Disable the WebSockets server. (default: {flag_no_ws})
|
||||
--ws-port PORT Specify the port portion of the WebSockets server
|
||||
(default: {flag_ws_port}).
|
||||
--ws-interface IP Specify the hostname portion of the WebSockets
|
||||
server, IP should be an interface's IP address, or
|
||||
all (all interfaces) or local (default: {flag_ws_interface}).
|
||||
--ws-apis APIS Specify the APIs available through the WebSockets
|
||||
interface. APIS is a comma-delimited list of API
|
||||
name. Possible name are web3, eth, pubsub, net, personal,
|
||||
parity, parity_set, traces, rpc, parity_accounts.
|
||||
(default: {flag_ws_apis}).
|
||||
--ws-origins URL Specify Origin header values allowed to connect.
|
||||
Special options: "all", "none".
|
||||
(default: {flag_ws_origins})
|
||||
--ws-hosts HOSTS List of allowed Host header values. This option will
|
||||
validate the Host header sent by the browser, it
|
||||
is additional security against some attack
|
||||
vectors. Special options: "all", "none",
|
||||
(default: {flag_ws_hosts}).
|
||||
|
||||
--no-ipc Disable JSON-RPC over IPC service. (default: {flag_no_ipc})
|
||||
--ipc-path PATH Specify custom path for JSON-RPC over IPC service
|
||||
(default: {flag_ipc_path}).
|
||||
--ipc-apis APIS Specify custom API set available via JSON-RPC over
|
||||
IPC (default: {flag_ipc_apis}).
|
||||
|
||||
--no-dapps Disable the Dapps server (e.g. status page). (default: {flag_no_dapps})
|
||||
--dapps-path PATH Specify directory where dapps should be installed.
|
||||
(default: {flag_dapps_path})
|
||||
--ipfs-api Enable IPFS-compatible HTTP API. (default: {flag_ipfs_api})
|
||||
--ipfs-api-port PORT Configure on which port the IPFS HTTP API should listen.
|
||||
(default: {flag_ipfs_api_port})
|
||||
--ipfs-api-interface IP Specify the hostname portion of the IPFS API server,
|
||||
IP should be an interface's IP address or local.
|
||||
(default: {flag_ipfs_api_interface})
|
||||
--ipfs-api-cors URL Specify CORS header for IPFS API responses.
|
||||
(default: {flag_ipfs_api_cors:?})
|
||||
--ipfs-api-hosts HOSTS List of allowed Host header values. This option will
|
||||
validate the Host header sent by the browser, it
|
||||
is additional security against some attack
|
||||
vectors. Special options: "all", "none"
|
||||
(default: {flag_ipfs_api_hosts}).
|
||||
|
||||
Secret Store Options:
|
||||
--no-secretstore Disable Secret Store functionality. (default: {flag_no_secretstore})
|
||||
--no-secretstore-http Disable Secret Store HTTP API. (default: {flag_no_secretstore_http})
|
||||
--no-acl-check Disable ACL check (useful for test environments). (default: {flag_no_secretstore_acl_check})
|
||||
--secretstore-secret SECRET Hex-encoded secret key of this node.
|
||||
(required, default: {flag_secretstore_secret:?}).
|
||||
--secretstore-nodes NODES Comma-separated list of other secret store cluster nodes in form
|
||||
NODE_PUBLIC_KEY_IN_HEX@NODE_IP_ADDR:NODE_PORT.
|
||||
(required, default: {flag_secretstore_nodes}).
|
||||
--secretstore-interface IP Specify the hostname portion for listening to Secret Store Key Server
|
||||
internal requests, IP should be an interface's IP address, or local
|
||||
(default: {flag_secretstore_interface}).
|
||||
--secretstore-port PORT Specify the port portion for listening to Secret Store Key Server
|
||||
internal requests (default: {flag_secretstore_port}).
|
||||
--secretstore-http-interface IP Specify the hostname portion for listening to Secret Store Key Server
|
||||
HTTP requests, IP should be an interface's IP address, or local
|
||||
(default: {flag_secretstore_http_interface}).
|
||||
--secretstore-http-port PORT Specify the port portion for listening to Secret Store Key Server
|
||||
HTTP requests (default: {flag_secretstore_http_port}).
|
||||
--secretstore-path PATH Specify directory where Secret Store should save its data.
|
||||
(default: {flag_secretstore_path}).
|
||||
|
||||
Sealing/Mining Options:
|
||||
--author ADDRESS Specify the block author (aka "coinbase") address
|
||||
for sending block rewards from sealed blocks.
|
||||
NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION.
|
||||
(default: {flag_author:?})
|
||||
--engine-signer ADDRESS Specify the address which should be used to
|
||||
sign consensus messages and issue blocks.
|
||||
Relevant only to non-PoW chains.
|
||||
(default: {flag_engine_signer:?})
|
||||
--force-sealing Force the node to author new blocks as if it were
|
||||
always sealing/mining.
|
||||
(default: {flag_force_sealing})
|
||||
--reseal-on-txs SET Specify which transactions should force the node
|
||||
to reseal a block. SET is one of:
|
||||
none - never reseal on new transactions;
|
||||
own - reseal only on a new local transaction;
|
||||
ext - reseal only on a new external transaction;
|
||||
all - reseal on all new transactions
|
||||
(default: {flag_reseal_on_txs}).
|
||||
--reseal-on-uncle Force the node to author new blocks when a new uncle
|
||||
block is imported.
|
||||
(default: {flag_reseal_on_uncle})
|
||||
--reseal-min-period MS Specify the minimum time between reseals from
|
||||
incoming transactions. MS is time measured in
|
||||
milliseconds (default: {flag_reseal_min_period}).
|
||||
--reseal-max-period MS Specify the maximum time since last block to enable
|
||||
force-sealing. MS is time measured in
|
||||
milliseconds (default: {flag_reseal_max_period}).
|
||||
--work-queue-size ITEMS Specify the number of historical work packages
|
||||
which are kept cached lest a solution is found for
|
||||
them later. High values take more memory but result
|
||||
in fewer unusable solutions (default: {flag_work_queue_size}).
|
||||
--tx-gas-limit GAS Apply a limit of GAS as the maximum amount of gas
|
||||
a single transaction may have for it to be mined.
|
||||
(default: {flag_tx_gas_limit:?})
|
||||
--tx-time-limit MS Maximal time for processing single transaction.
|
||||
If enabled senders/recipients/code of transactions
|
||||
offending the limit will be banned from being included
|
||||
in transaction queue for 180 seconds.
|
||||
(default: {flag_tx_time_limit:?})
|
||||
--relay-set SET Set of transactions to relay. SET may be:
|
||||
cheap - Relay any transaction in the queue (this
|
||||
may include invalid transactions);
|
||||
strict - Relay only executed transactions (this
|
||||
guarantees we don't relay invalid transactions, but
|
||||
means we relay nothing if not mining);
|
||||
lenient - Same as strict when mining, and cheap
|
||||
when not (default: {flag_relay_set}).
|
||||
--min-gas-price WEI Minimum amount of Wei per GAS to be paid for a
|
||||
transaction to be accepted for mining. Overrides
|
||||
--basic-tx-usd.
|
||||
(default: {flag_min_gas_price:?})
|
||||
--usd-per-tx USD Amount of USD to be paid for a basic transaction
|
||||
(default: {flag_usd_per_tx}). The minimum gas price is set
|
||||
accordingly.
|
||||
--usd-per-eth SOURCE USD value of a single ETH. SOURCE may be either an
|
||||
amount in USD, a web service or 'auto' to use each
|
||||
web service in turn and fallback on the last known
|
||||
good value (default: {flag_usd_per_eth}).
|
||||
--price-update-period T T will be allowed to pass between each gas price
|
||||
update. T may be daily, hourly, a number of seconds,
|
||||
or a time string of the form "2 days", "30 minutes"
|
||||
etc. (default: {flag_price_update_period}).
|
||||
--gas-floor-target GAS Amount of gas per block to target when sealing a new
|
||||
block (default: {flag_gas_floor_target}).
|
||||
--gas-cap GAS A cap on how large we will raise the gas limit per
|
||||
block due to transaction volume (default: {flag_gas_cap}).
|
||||
--extra-data STRING Specify a custom extra-data for authored blocks, no
|
||||
more than 32 characters. (default: {flag_extra_data:?})
|
||||
--tx-queue-mem-limit MB Maximum amount of memory that can be used by the
|
||||
transaction queue. Setting this parameter to 0
|
||||
disables limiting (default: {flag_tx_queue_mem_limit}).
|
||||
--tx-queue-size LIMIT Maximum amount of transactions in the queue (waiting
|
||||
to be included in next block) (default: {flag_tx_queue_size}).
|
||||
--tx-queue-gas LIMIT Maximum amount of total gas for external transactions in
|
||||
the queue. LIMIT can be either an amount of gas or
|
||||
'auto' or 'off'. 'auto' sets the limit to be 20x
|
||||
the current block gas limit. (default: {flag_tx_queue_gas}).
|
||||
--tx-queue-strategy S Prioritization strategy used to order transactions
|
||||
in the queue. S may be:
|
||||
gas - Prioritize txs with low gas limit;
|
||||
gas_price - Prioritize txs with high gas price;
|
||||
gas_factor - Prioritize txs using gas price
|
||||
and gas limit ratio (default: {flag_tx_queue_strategy}).
|
||||
--tx-queue-ban-count C Number of times maximal time for execution (--tx-time-limit)
|
||||
can be exceeded before banning sender/recipient/code.
|
||||
(default: {flag_tx_queue_ban_count})
|
||||
--tx-queue-ban-time SEC Banning time (in seconds) for offenders of specified
|
||||
execution time limit. Also number of offending actions
|
||||
have to reach the threshold within that time.
|
||||
(default: {flag_tx_queue_ban_time} seconds)
|
||||
--no-persistent-txqueue Don't save pending local transactions to disk to be
|
||||
restored whenever the node restarts.
|
||||
(default: {flag_no_persistent_txqueue}).
|
||||
--remove-solved Move solved blocks from the work package queue
|
||||
instead of cloning them. This gives a slightly
|
||||
faster import speed, but means that extra solutions
|
||||
submitted for the same work package will go unused.
|
||||
(default: {flag_remove_solved})
|
||||
--notify-work URLS URLs to which work package notifications are pushed.
|
||||
URLS should be a comma-delimited list of HTTP URLs.
|
||||
(default: {flag_notify_work:?})
|
||||
--refuse-service-transactions Always refuse service transactions.
|
||||
(default: {flag_refuse_service_transactions}).
|
||||
--stratum Run Stratum server for miner push notification. (default: {flag_stratum})
|
||||
--stratum-interface IP Interface address for Stratum server. (default: {flag_stratum_interface})
|
||||
--stratum-port PORT Port for Stratum server to listen on. (default: {flag_stratum_port})
|
||||
--stratum-secret STRING Secret for authorizing Stratum server for peers.
|
||||
(default: {flag_stratum_secret:?})
|
||||
|
||||
Footprint Options:
|
||||
--tracing BOOL Indicates if full transaction tracing should be
|
||||
enabled. Works only if client had been fully synced
|
||||
with tracing enabled. BOOL may be one of auto, on,
|
||||
off. auto uses last used value of this option (off
|
||||
if it does not exist) (default: {flag_tracing}).
|
||||
--pruning METHOD Configure pruning of the state/storage trie. METHOD
|
||||
may be one of auto, archive, fast:
|
||||
archive - keep all state trie data. No pruning.
|
||||
fast - maintain journal overlay. Fast but 50MB used.
|
||||
auto - use the method most recently synced or
|
||||
default to fast if none synced (default: {flag_pruning}).
|
||||
--pruning-history NUM Set a minimum number of recent states to keep when pruning
|
||||
is active. (default: {flag_pruning_history}).
|
||||
--pruning-memory MB The ideal amount of memory in megabytes to use to store
|
||||
recent states. As many states as possible will be kept
|
||||
within this limit, and at least --pruning-history states
|
||||
will always be kept. (default: {flag_pruning_memory})
|
||||
--cache-size-db MB Override database cache size (default: {flag_cache_size_db}).
|
||||
--cache-size-blocks MB Specify the prefered size of the blockchain cache in
|
||||
megabytes (default: {flag_cache_size_blocks}).
|
||||
--cache-size-queue MB Specify the maximum size of memory to use for block
|
||||
queue (default: {flag_cache_size_queue}).
|
||||
--cache-size-state MB Specify the maximum size of memory to use for
|
||||
the state cache (default: {flag_cache_size_state}).
|
||||
--cache-size MB Set total amount of discretionary memory to use for
|
||||
the entire system, overrides other cache and queue
|
||||
options. (default: {flag_cache_size:?})
|
||||
--fast-and-loose Disables DB WAL, which gives a significant speed up
|
||||
but means an unclean exit is unrecoverable. (default: {flag_fast_and_loose})
|
||||
--db-compaction TYPE Database compaction type. TYPE may be one of:
|
||||
ssd - suitable for SSDs and fast HDDs;
|
||||
hdd - suitable for slow HDDs;
|
||||
auto - determine automatically (default: {flag_db_compaction}).
|
||||
--fat-db BOOL Build appropriate information to allow enumeration
|
||||
of all accounts and storage keys. Doubles the size
|
||||
of the state database. BOOL may be one of on, off
|
||||
or auto. (default: {flag_fat_db})
|
||||
--scale-verifiers Automatically scale amount of verifier threads based on
|
||||
workload. Not guaranteed to be faster.
|
||||
(default: {flag_scale_verifiers})
|
||||
--num-verifiers INT Amount of verifier threads to use or to begin with, if verifier
|
||||
auto-scaling is enabled. (default: {flag_num_verifiers:?})
|
||||
|
||||
Import/Export Options:
|
||||
--from BLOCK Export from block BLOCK, which may be an index or
|
||||
hash (default: {flag_from}).
|
||||
--to BLOCK Export to (including) block BLOCK, which may be an
|
||||
index, hash or 'latest' (default: {flag_to}).
|
||||
--format FORMAT For import/export in given format. FORMAT must be
|
||||
one of 'hex' and 'binary'.
|
||||
(default: {flag_format:?} = Import: auto, Export: binary)
|
||||
--no-seal-check Skip block seal check. (default: {flag_no_seal_check})
|
||||
--at BLOCK Export state at the given block, which may be an
|
||||
index, hash, or 'latest'. (default: {flag_at})
|
||||
--no-storage Don't export account storage. (default: {flag_no_storage})
|
||||
--no-code Don't export account code. (default: {flag_no_code})
|
||||
--min-balance WEI Don't export accounts with balance less than specified.
|
||||
(default: {flag_min_balance:?})
|
||||
--max-balance WEI Don't export accounts with balance greater than specified.
|
||||
(default: {flag_max_balance:?})
|
||||
|
||||
Snapshot Options:
|
||||
--at BLOCK Take a snapshot at the given block, which may be an
|
||||
index, hash, or 'latest'. Note that taking snapshots at
|
||||
non-recent blocks will only work with --pruning archive
|
||||
(default: {flag_at})
|
||||
--no-periodic-snapshot Disable automated snapshots which usually occur once
|
||||
every 10000 blocks. (default: {flag_no_periodic_snapshot})
|
||||
|
||||
Virtual Machine Options:
|
||||
--jitvm Enable the JIT VM. (default: {flag_jitvm})
|
||||
|
||||
Whisper Options:
|
||||
--whisper Enable the Whisper network. (default: {flag_whisper})
|
||||
--whisper-pool-size MB Target size of the whisper message pool in megabytes.
|
||||
(default: {flag_whisper_pool_size})
|
||||
|
||||
Legacy Options:
|
||||
--geth Run in Geth-compatibility mode. Sets the IPC path
|
||||
to be the same as Geth's. Overrides the --ipc-path
|
||||
and --ipcpath options. Alters RPCs to reflect Geth
|
||||
bugs. Includes the personal_ RPC by default.
|
||||
--testnet Testnet mode. Equivalent to --chain testnet.
|
||||
Overrides the --keys-path option.
|
||||
--import-geth-keys Attempt to import keys from Geth client.
|
||||
--datadir PATH Equivalent to --base-path PATH.
|
||||
--networkid INDEX Equivalent to --network-id INDEX.
|
||||
--peers NUM Equivalent to --min-peers NUM.
|
||||
--nodekey KEY Equivalent to --node-key KEY.
|
||||
--nodiscover Equivalent to --no-discovery.
|
||||
-j --jsonrpc Does nothing; JSON-RPC is on by default now.
|
||||
--jsonrpc-off Equivalent to --no-jsonrpc.
|
||||
-w --webapp Does nothing; dapps server is on by default now.
|
||||
--dapps-off Equivalent to --no-dapps.
|
||||
--dapps-user USERNAME Dapps server authentication has been removed. (default: {flag_dapps_user:?})
|
||||
--dapps-pass PASSWORD Dapps server authentication has been removed. (default: {flag_dapps_pass:?})
|
||||
--dapps-apis-all Dapps server is merged with RPC server. Use --jsonrpc-apis. (default: {flag_dapps_apis_all:?})
|
||||
--dapps-cors URL Dapps server is merged with RPC server. Use --jsonrpc-cors. (default: {flag_dapps_cors:?})
|
||||
--dapps-hosts HOSTS Dapps server is merged with RPC server. Use --jsonrpc-hosts. (default: {flag_dapps_hosts:?})
|
||||
--dapps-interface IP Dapps server is merged with RPC server. Use --jsonrpc-interface. (default: {flag_dapps_interface:?})
|
||||
--dapps-port PORT Dapps server is merged with RPC server. Use --jsonrpc-port. (default: {flag_dapps_port:?})
|
||||
--rpc Does nothing; JSON-RPC is on by default now.
|
||||
--warp Does nothing; Warp sync is on by default. (default: {flag_warp})
|
||||
--rpcaddr IP Equivalent to --jsonrpc-interface IP.
|
||||
--rpcport PORT Equivalent to --jsonrpc-port PORT.
|
||||
--rpcapi APIS Equivalent to --jsonrpc-apis APIS.
|
||||
--rpccorsdomain URL Equivalent to --jsonrpc-cors URL.
|
||||
--ipcdisable Equivalent to --no-ipc.
|
||||
--ipc-off Equivalent to --no-ipc.
|
||||
--ipcapi APIS Equivalent to --ipc-apis APIS.
|
||||
--ipcpath PATH Equivalent to --ipc-path PATH.
|
||||
--gasprice WEI Equivalent to --min-gas-price WEI.
|
||||
--etherbase ADDRESS Equivalent to --author ADDRESS.
|
||||
--extradata STRING Equivalent to --extra-data STRING.
|
||||
--cache MB Equivalent to --cache-size MB.
|
||||
|
||||
Internal Options:
|
||||
--can-restart Executable will auto-restart if exiting with 69.
|
||||
|
||||
Miscellaneous Options:
|
||||
--ntp-servers HOSTS Comma separated list of NTP servers to provide current time (host:port).
|
||||
Used to verify node health. Parity uses pool.ntp.org NTP servers,
|
||||
consider joining the pool: http://www.pool.ntp.org/join.html
|
||||
(default: {flag_ntp_servers})
|
||||
-l --logging LOGGING Specify the logging level. Must conform to the same
|
||||
format as RUST_LOG. (default: {flag_logging:?})
|
||||
--log-file FILENAME Specify a filename into which logging should be
|
||||
appended. (default: {flag_log_file:?})
|
||||
--no-config Don't load a configuration file.
|
||||
--no-color Don't use terminal color codes in output. (default: {flag_no_color})
|
||||
-v --version Show information about version.
|
||||
-h --help Show this screen.
|
3
parity/cli/usage_header.txt
Normal file
3
parity/cli/usage_header.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Parity. Ethereum Client.
|
||||
By Wood/Paronyan/Kotewicz/Drwięga/Volf et al.
|
||||
Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd
|
@ -7,4 +7,3 @@ There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
By Wood/Paronyan/Kotewicz/Drwięga/Volf
|
||||
Habermeier/Czaban/Greeff/Gotchac/Redmann
|
||||
|
||||
|
@ -106,13 +106,13 @@ impl Configuration {
|
||||
|
||||
pub fn into_command(self) -> Result<Execute, String> {
|
||||
let dirs = self.directories();
|
||||
let pruning = self.args.flag_pruning.parse()?;
|
||||
let pruning_history = self.args.flag_pruning_history;
|
||||
let pruning = self.args.arg_pruning.parse()?;
|
||||
let pruning_history = self.args.arg_pruning_history;
|
||||
let vm_type = self.vm_type()?;
|
||||
let spec = self.chain().parse()?;
|
||||
let mode = match self.args.flag_mode.as_ref() {
|
||||
let mode = match self.args.arg_mode.as_ref() {
|
||||
"last" => None,
|
||||
mode => Some(to_mode(&mode, self.args.flag_mode_timeout, self.args.flag_mode_alarm)?),
|
||||
mode => Some(to_mode(&mode, self.args.arg_mode_timeout, self.args.arg_mode_alarm)?),
|
||||
};
|
||||
let update_policy = self.update_policy()?;
|
||||
let logger_config = self.logger_config();
|
||||
@ -123,18 +123,21 @@ impl Configuration {
|
||||
let ui_conf = self.ui_config();
|
||||
let network_id = self.network_id();
|
||||
let cache_config = self.cache_config();
|
||||
let tracing = self.args.flag_tracing.parse()?;
|
||||
let fat_db = self.args.flag_fat_db.parse()?;
|
||||
let compaction = self.args.flag_db_compaction.parse()?;
|
||||
let tracing = self.args.arg_tracing.parse()?;
|
||||
let fat_db = self.args.arg_fat_db.parse()?;
|
||||
let compaction = self.args.arg_db_compaction.parse()?;
|
||||
let wal = !self.args.flag_fast_and_loose;
|
||||
match self.args.flag_warp {
|
||||
// Logging is not initialized yet, so we print directly to stderr
|
||||
Some(true) if fat_db == Switch::On => writeln!(&mut stderr(), "Warning: Warp Sync is disabled because Fat DB is turned on").expect("Error writing to stderr"),
|
||||
Some(true) if tracing == Switch::On => writeln!(&mut stderr(), "Warning: Warp Sync is disabled because tracing is turned on").expect("Error writing to stderr"),
|
||||
Some(true) if pruning == Pruning::Specific(Algorithm::Archive) => writeln!(&mut stderr(), "Warning: Warp Sync is disabled because pruning mode is set to archive").expect("Error writing to stderr"),
|
||||
_ => {},
|
||||
};
|
||||
let public_node = self.args.flag_public_node;
|
||||
if !self.args.flag_no_warp {
|
||||
// Logging is not initialized yet, so we print directly to stderr
|
||||
if fat_db == Switch::On {
|
||||
writeln!(&mut stderr(), "Warning: Warp Sync is disabled because Fat DB is turned on").expect("Error writing to stderr");
|
||||
} else if tracing == Switch::On {
|
||||
writeln!(&mut stderr(), "Warning: Warp Sync is disabled because tracing is turned on").expect("Error writing to stderr");
|
||||
} else if pruning == Pruning::Specific(Algorithm::Archive) {
|
||||
writeln!(&mut stderr(), "Warning: Warp Sync is disabled because pruning mode is set to archive").expect("Error writing to stderr");
|
||||
}
|
||||
}
|
||||
let warp_sync = !self.args.flag_no_warp && fat_db != Switch::On && tracing != Switch::On && pruning != Pruning::Specific(Algorithm::Archive);
|
||||
let geth_compatibility = self.args.flag_geth;
|
||||
let mut dapps_conf = self.dapps_config();
|
||||
@ -142,9 +145,9 @@ impl Configuration {
|
||||
let secretstore_conf = self.secretstore_config()?;
|
||||
let format = self.format()?;
|
||||
|
||||
if self.args.flag_jsonrpc_server_threads.is_some() && dapps_conf.enabled {
|
||||
if self.args.arg_jsonrpc_server_threads.is_some() && dapps_conf.enabled {
|
||||
dapps_conf.enabled = false;
|
||||
writeln!(&mut stderr(), "Warning: Disabling Dapps server because fast RPC server was enabled.").expect("Error writing to stderr.")
|
||||
writeln!(&mut stderr(), "Warning: Disabling Dapps server because fast RPC server was enabled.").expect("Error writing to stderr.");
|
||||
}
|
||||
|
||||
let cmd = if self.args.flag_version {
|
||||
@ -152,25 +155,25 @@ impl Configuration {
|
||||
} else if self.args.cmd_signer {
|
||||
let authfile = ::signer::codes_path(&ws_conf.signer_path);
|
||||
|
||||
if self.args.cmd_new_token {
|
||||
if self.args.cmd_signer_new_token {
|
||||
Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone())
|
||||
} else if self.args.cmd_sign {
|
||||
let pwfile = self.args.flag_password.get(0).map(|pwfile| {
|
||||
} else if self.args.cmd_signer_sign {
|
||||
let pwfile = self.args.arg_signer_sign_password.map(|pwfile| {
|
||||
PathBuf::from(pwfile)
|
||||
});
|
||||
Cmd::SignerSign {
|
||||
id: self.args.arg_id,
|
||||
id: self.args.arg_signer_sign_id,
|
||||
pwfile: pwfile,
|
||||
port: ws_conf.port,
|
||||
authfile: authfile,
|
||||
}
|
||||
} else if self.args.cmd_reject {
|
||||
} else if self.args.cmd_signer_reject {
|
||||
Cmd::SignerReject {
|
||||
id: self.args.arg_id,
|
||||
id: self.args.arg_signer_reject_id,
|
||||
port: ws_conf.port,
|
||||
authfile: authfile,
|
||||
}
|
||||
} else if self.args.cmd_list {
|
||||
} else if self.args.cmd_signer_list {
|
||||
Cmd::SignerList {
|
||||
port: ws_conf.port,
|
||||
authfile: authfile,
|
||||
@ -178,32 +181,32 @@ impl Configuration {
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
} else if self.args.cmd_tools && self.args.cmd_hash {
|
||||
Cmd::Hash(self.args.arg_file)
|
||||
} else if self.args.cmd_db && self.args.cmd_kill {
|
||||
} else if self.args.cmd_tools && self.args.cmd_tools_hash {
|
||||
Cmd::Hash(self.args.arg_tools_hash_file)
|
||||
} else if self.args.cmd_db && self.args.cmd_db_kill {
|
||||
Cmd::Blockchain(BlockchainCmd::Kill(KillBlockchain {
|
||||
spec: spec,
|
||||
dirs: dirs,
|
||||
pruning: pruning,
|
||||
}))
|
||||
} else if self.args.cmd_account {
|
||||
let account_cmd = if self.args.cmd_new {
|
||||
let account_cmd = if self.args.cmd_account_new {
|
||||
let new_acc = NewAccount {
|
||||
iterations: self.args.flag_keys_iterations,
|
||||
iterations: self.args.arg_keys_iterations,
|
||||
path: dirs.keys,
|
||||
spec: spec,
|
||||
password_file: self.args.flag_password.first().cloned(),
|
||||
password_file: self.args.arg_account_new_password.clone(),
|
||||
};
|
||||
AccountCmd::New(new_acc)
|
||||
} else if self.args.cmd_list {
|
||||
} else if self.args.cmd_account_list {
|
||||
let list_acc = ListAccounts {
|
||||
path: dirs.keys,
|
||||
spec: spec,
|
||||
};
|
||||
AccountCmd::List(list_acc)
|
||||
} else if self.args.cmd_import {
|
||||
} else if self.args.cmd_account_import {
|
||||
let import_acc = ImportAccounts {
|
||||
from: self.args.arg_path.clone(),
|
||||
from: self.args.arg_account_import_path.expect("CLI argument is required; qed").clone(),
|
||||
to: dirs.keys,
|
||||
spec: spec,
|
||||
};
|
||||
@ -223,11 +226,11 @@ impl Configuration {
|
||||
Cmd::Account(account_cmd)
|
||||
} else if self.args.cmd_wallet {
|
||||
let presale_cmd = ImportWallet {
|
||||
iterations: self.args.flag_keys_iterations,
|
||||
iterations: self.args.arg_keys_iterations,
|
||||
path: dirs.keys,
|
||||
spec: spec,
|
||||
wallet_path: self.args.arg_path.first().unwrap().clone(),
|
||||
password_file: self.args.flag_password.first().cloned(),
|
||||
wallet_path: self.args.arg_wallet_import_path.unwrap().clone(),
|
||||
password_file: self.args.arg_wallet_import_password,
|
||||
};
|
||||
Cmd::ImportPresaleWallet(presale_cmd)
|
||||
} else if self.args.cmd_import {
|
||||
@ -235,11 +238,11 @@ impl Configuration {
|
||||
spec: spec,
|
||||
cache_config: cache_config,
|
||||
dirs: dirs,
|
||||
file_path: self.args.arg_file.clone(),
|
||||
file_path: self.args.arg_import_file.clone(),
|
||||
format: format,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
pruning_memory: self.args.flag_pruning_memory,
|
||||
pruning_memory: self.args.arg_pruning_memory,
|
||||
compaction: compaction,
|
||||
wal: wal,
|
||||
tracing: tracing,
|
||||
@ -252,44 +255,44 @@ impl Configuration {
|
||||
};
|
||||
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
||||
} else if self.args.cmd_export {
|
||||
if self.args.cmd_blocks {
|
||||
if self.args.cmd_export_blocks {
|
||||
let export_cmd = ExportBlockchain {
|
||||
spec: spec,
|
||||
cache_config: cache_config,
|
||||
dirs: dirs,
|
||||
file_path: self.args.arg_file.clone(),
|
||||
file_path: self.args.arg_export_blocks_file.clone(),
|
||||
format: format,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
pruning_memory: self.args.flag_pruning_memory,
|
||||
pruning_memory: self.args.arg_pruning_memory,
|
||||
compaction: compaction,
|
||||
wal: wal,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
from_block: to_block_id(&self.args.flag_from)?,
|
||||
to_block: to_block_id(&self.args.flag_to)?,
|
||||
from_block: to_block_id(&self.args.arg_export_blocks_from)?,
|
||||
to_block: to_block_id(&self.args.arg_export_blocks_to)?,
|
||||
check_seal: !self.args.flag_no_seal_check,
|
||||
};
|
||||
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
|
||||
} else if self.args.cmd_state {
|
||||
} else if self.args.cmd_export_state {
|
||||
let export_cmd = ExportState {
|
||||
spec: spec,
|
||||
cache_config: cache_config,
|
||||
dirs: dirs,
|
||||
file_path: self.args.arg_file.clone(),
|
||||
file_path: self.args.arg_export_state_file.clone(),
|
||||
format: format,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
pruning_memory: self.args.flag_pruning_memory,
|
||||
pruning_memory: self.args.arg_pruning_memory,
|
||||
compaction: compaction,
|
||||
wal: wal,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
at: to_block_id(&self.args.flag_at)?,
|
||||
storage: !self.args.flag_no_storage,
|
||||
code: !self.args.flag_no_code,
|
||||
min_balance: self.args.flag_min_balance.and_then(|s| to_u256(&s).ok()),
|
||||
max_balance: self.args.flag_max_balance.and_then(|s| to_u256(&s).ok()),
|
||||
at: to_block_id(&self.args.arg_export_state_at)?,
|
||||
storage: !self.args.flag_export_state_no_storage,
|
||||
code: !self.args.flag_export_state_no_code,
|
||||
min_balance: self.args.arg_export_state_min_balance.and_then(|s| to_u256(&s).ok()),
|
||||
max_balance: self.args.arg_export_state_max_balance.and_then(|s| to_u256(&s).ok()),
|
||||
};
|
||||
Cmd::Blockchain(BlockchainCmd::ExportState(export_cmd))
|
||||
} else {
|
||||
@ -302,14 +305,14 @@ impl Configuration {
|
||||
spec: spec,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
pruning_memory: self.args.flag_pruning_memory,
|
||||
pruning_memory: self.args.arg_pruning_memory,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
compaction: compaction,
|
||||
file_path: self.args.arg_file.clone(),
|
||||
file_path: self.args.arg_snapshot_file.clone(),
|
||||
wal: wal,
|
||||
kind: snapshot::Kind::Take,
|
||||
block_at: to_block_id(&self.args.flag_at)?,
|
||||
block_at: to_block_id(&self.args.arg_snapshot_at)?,
|
||||
};
|
||||
Cmd::Snapshot(snapshot_cmd)
|
||||
} else if self.args.cmd_restore {
|
||||
@ -319,11 +322,11 @@ impl Configuration {
|
||||
spec: spec,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
pruning_memory: self.args.flag_pruning_memory,
|
||||
pruning_memory: self.args.arg_pruning_memory,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
compaction: compaction,
|
||||
file_path: self.args.arg_file.clone(),
|
||||
file_path: self.args.arg_restore_file.clone(),
|
||||
wal: wal,
|
||||
kind: snapshot::Kind::Restore,
|
||||
block_at: to_block_id("latest")?, // unimportant.
|
||||
@ -331,7 +334,7 @@ impl Configuration {
|
||||
Cmd::Snapshot(restore_cmd)
|
||||
} else {
|
||||
let daemon = if self.args.cmd_daemon {
|
||||
Some(self.args.arg_pid_file.clone())
|
||||
Some(self.args.arg_daemon_pid_file.clone().expect("CLI argument is required; qed"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -345,10 +348,10 @@ impl Configuration {
|
||||
spec: spec,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
pruning_memory: self.args.flag_pruning_memory,
|
||||
pruning_memory: self.args.arg_pruning_memory,
|
||||
daemon: daemon,
|
||||
logger_config: logger_config.clone(),
|
||||
miner_options: self.miner_options(self.args.flag_reseal_min_period)?,
|
||||
miner_options: self.miner_options(self.args.arg_reseal_min_period)?,
|
||||
ntp_servers: self.ntp_servers(),
|
||||
ws_conf: ws_conf,
|
||||
http_conf: http_conf,
|
||||
@ -376,8 +379,8 @@ impl Configuration {
|
||||
secretstore_conf: secretstore_conf,
|
||||
dapp: self.dapp_to_open()?,
|
||||
ui: self.args.cmd_ui,
|
||||
name: self.args.flag_identity,
|
||||
custom_bootnodes: self.args.flag_bootnodes.is_some(),
|
||||
name: self.args.arg_identity,
|
||||
custom_bootnodes: self.args.arg_bootnodes.is_some(),
|
||||
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
||||
check_seal: !self.args.flag_no_seal_check,
|
||||
download_old_blocks: !self.args.flag_no_ancient_blocks,
|
||||
@ -408,8 +411,8 @@ impl Configuration {
|
||||
let extras = MinerExtras {
|
||||
author: self.author()?,
|
||||
extra_data: self.extra_data()?,
|
||||
gas_floor_target: to_u256(&self.args.flag_gas_floor_target)?,
|
||||
gas_ceil_target: to_u256(&self.args.flag_gas_cap)?,
|
||||
gas_floor_target: to_u256(&self.args.arg_gas_floor_target)?,
|
||||
gas_ceil_target: to_u256(&self.args.arg_gas_cap)?,
|
||||
engine_signer: self.engine_signer()?,
|
||||
};
|
||||
|
||||
@ -417,37 +420,39 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn author(&self) -> Result<Address, String> {
|
||||
to_address(self.args.flag_etherbase.clone().or(self.args.flag_author.clone()))
|
||||
to_address(self.args.arg_etherbase.clone().or(self.args.arg_author.clone()))
|
||||
}
|
||||
|
||||
fn engine_signer(&self) -> Result<Address, String> {
|
||||
to_address(self.args.flag_engine_signer.clone())
|
||||
to_address(self.args.arg_engine_signer.clone())
|
||||
}
|
||||
|
||||
fn format(&self) -> Result<Option<DataFormat>, String> {
|
||||
match self.args.flag_format {
|
||||
match self.args.arg_import_format.clone()
|
||||
.or(self.args.arg_export_blocks_format.clone())
|
||||
.or(self.args.arg_export_state_format.clone()) {
|
||||
Some(ref f) => Ok(Some(f.parse()?)),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn cache_config(&self) -> CacheConfig {
|
||||
match self.args.flag_cache_size.or(self.args.flag_cache) {
|
||||
match self.args.arg_cache_size.or(self.args.arg_cache) {
|
||||
Some(size) => CacheConfig::new_with_total_cache_size(size),
|
||||
None => CacheConfig::new(
|
||||
self.args.flag_cache_size_db,
|
||||
self.args.flag_cache_size_blocks,
|
||||
self.args.flag_cache_size_queue,
|
||||
self.args.flag_cache_size_state,
|
||||
self.args.arg_cache_size_db,
|
||||
self.args.arg_cache_size_blocks,
|
||||
self.args.arg_cache_size_queue,
|
||||
self.args.arg_cache_size_state,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn logger_config(&self) -> LogConfig {
|
||||
LogConfig {
|
||||
mode: self.args.flag_logging.clone(),
|
||||
mode: self.args.arg_logging.clone(),
|
||||
color: !self.args.flag_no_color && !cfg!(windows),
|
||||
file: self.args.flag_log_file.clone(),
|
||||
file: self.args.arg_log_file.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,44 +463,44 @@ impl Configuration {
|
||||
else if self.args.flag_testnet {
|
||||
"testnet".to_owned()
|
||||
} else {
|
||||
self.args.flag_chain.clone()
|
||||
self.args.arg_chain.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn max_peers(&self) -> u32 {
|
||||
let peers = self.args.flag_max_peers as u32;
|
||||
let peers = self.args.arg_max_peers as u32;
|
||||
max(self.min_peers(), peers)
|
||||
}
|
||||
|
||||
fn ip_filter(&self) -> Result<IpFilter, String> {
|
||||
match IpFilter::parse(self.args.flag_allow_ips.as_str()) {
|
||||
match IpFilter::parse(self.args.arg_allow_ips.as_str()) {
|
||||
Ok(allow_ip) => Ok(allow_ip),
|
||||
Err(_) => Err("Invalid IP filter value".to_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
fn min_peers(&self) -> u32 {
|
||||
self.args.flag_peers.unwrap_or(self.args.flag_min_peers) as u32
|
||||
self.args.arg_peers.unwrap_or(self.args.arg_min_peers) as u32
|
||||
}
|
||||
|
||||
fn max_pending_peers(&self) -> u32 {
|
||||
self.args.flag_max_pending_peers as u32
|
||||
self.args.arg_max_pending_peers as u32
|
||||
}
|
||||
|
||||
fn snapshot_peers(&self) -> u32 {
|
||||
self.args.flag_snapshot_peers as u32
|
||||
self.args.arg_snapshot_peers as u32
|
||||
}
|
||||
|
||||
fn work_notify(&self) -> Vec<String> {
|
||||
self.args.flag_notify_work.as_ref().map_or_else(Vec::new, |s| s.split(',').map(|s| s.to_owned()).collect())
|
||||
self.args.arg_notify_work.as_ref().map_or_else(Vec::new, |s| s.split(',').map(|s| s.to_owned()).collect())
|
||||
}
|
||||
|
||||
fn accounts_config(&self) -> Result<AccountsConfig, String> {
|
||||
let cfg = AccountsConfig {
|
||||
iterations: self.args.flag_keys_iterations,
|
||||
iterations: self.args.arg_keys_iterations,
|
||||
testnet: self.args.flag_testnet,
|
||||
password_files: self.args.flag_password.clone(),
|
||||
unlocked_accounts: to_addresses(&self.args.flag_unlock)?,
|
||||
password_files: self.args.arg_password.clone(),
|
||||
unlocked_accounts: to_addresses(&self.args.arg_unlock)?,
|
||||
enable_hardware_wallets: !self.args.flag_no_hardware_wallets,
|
||||
enable_fast_unlock: self.args.flag_fast_unlock,
|
||||
};
|
||||
@ -508,8 +513,8 @@ impl Configuration {
|
||||
Ok(Some(StratumOptions {
|
||||
io_path: self.directories().db,
|
||||
listen_addr: self.stratum_interface(),
|
||||
port: self.args.flag_ports_shift + self.args.flag_stratum_port,
|
||||
secret: self.args.flag_stratum_secret.as_ref().map(|s| s.parse::<H256>().unwrap_or_else(|_| keccak(s))),
|
||||
port: self.args.arg_ports_shift + self.args.arg_stratum_port,
|
||||
secret: self.args.arg_stratum_secret.as_ref().map(|s| s.parse::<H256>().unwrap_or_else(|_| keccak(s))),
|
||||
}))
|
||||
} else { Ok(None) }
|
||||
}
|
||||
@ -519,7 +524,7 @@ impl Configuration {
|
||||
return Err("Force sealing can't be used with reseal_min_period = 0".into());
|
||||
}
|
||||
|
||||
let reseal = self.args.flag_reseal_on_txs.parse::<ResealPolicy>()?;
|
||||
let reseal = self.args.arg_reseal_on_txs.parse::<ResealPolicy>()?;
|
||||
|
||||
let options = MinerOptions {
|
||||
new_work_notify: self.work_notify(),
|
||||
@ -527,26 +532,26 @@ impl Configuration {
|
||||
reseal_on_external_tx: reseal.external,
|
||||
reseal_on_own_tx: reseal.own,
|
||||
reseal_on_uncle: self.args.flag_reseal_on_uncle,
|
||||
tx_gas_limit: match self.args.flag_tx_gas_limit {
|
||||
tx_gas_limit: match self.args.arg_tx_gas_limit {
|
||||
Some(ref d) => to_u256(d)?,
|
||||
None => U256::max_value(),
|
||||
},
|
||||
tx_queue_size: self.args.flag_tx_queue_size,
|
||||
tx_queue_memory_limit: if self.args.flag_tx_queue_mem_limit > 0 {
|
||||
Some(self.args.flag_tx_queue_mem_limit as usize * 1024 * 1024)
|
||||
tx_queue_size: self.args.arg_tx_queue_size,
|
||||
tx_queue_memory_limit: if self.args.arg_tx_queue_mem_limit > 0 {
|
||||
Some(self.args.arg_tx_queue_mem_limit as usize * 1024 * 1024)
|
||||
} else { None },
|
||||
tx_queue_gas_limit: to_gas_limit(&self.args.flag_tx_queue_gas)?,
|
||||
tx_queue_strategy: to_queue_strategy(&self.args.flag_tx_queue_strategy)?,
|
||||
pending_set: to_pending_set(&self.args.flag_relay_set)?,
|
||||
tx_queue_gas_limit: to_gas_limit(&self.args.arg_tx_queue_gas)?,
|
||||
tx_queue_strategy: to_queue_strategy(&self.args.arg_tx_queue_strategy)?,
|
||||
pending_set: to_pending_set(&self.args.arg_relay_set)?,
|
||||
reseal_min_period: Duration::from_millis(reseal_min_period),
|
||||
reseal_max_period: Duration::from_millis(self.args.flag_reseal_max_period),
|
||||
work_queue_size: self.args.flag_work_queue_size,
|
||||
reseal_max_period: Duration::from_millis(self.args.arg_reseal_max_period),
|
||||
work_queue_size: self.args.arg_work_queue_size,
|
||||
enable_resubmission: !self.args.flag_remove_solved,
|
||||
tx_queue_banning: match self.args.flag_tx_time_limit {
|
||||
tx_queue_banning: match self.args.arg_tx_time_limit {
|
||||
Some(limit) => Banning::Enabled {
|
||||
min_offends: self.args.flag_tx_queue_ban_count,
|
||||
min_offends: self.args.arg_tx_queue_ban_count,
|
||||
offend_threshold: Duration::from_millis(limit),
|
||||
ban_duration: Duration::from_secs(self.args.flag_tx_queue_ban_time as u64),
|
||||
ban_duration: Duration::from_secs(self.args.arg_tx_queue_ban_time as u64),
|
||||
},
|
||||
None => Banning::Disabled,
|
||||
},
|
||||
@ -557,11 +562,11 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn ui_port(&self) -> u16 {
|
||||
self.args.flag_ports_shift + self.args.flag_ui_port
|
||||
self.args.arg_ports_shift + self.args.arg_ui_port
|
||||
}
|
||||
|
||||
fn ntp_servers(&self) -> Vec<String> {
|
||||
self.args.flag_ntp_servers.split(",").map(str::to_owned).collect()
|
||||
self.args.arg_ntp_servers.split(",").map(str::to_owned).collect()
|
||||
}
|
||||
|
||||
fn ui_config(&self) -> UiConfiguration {
|
||||
@ -581,7 +586,7 @@ impl Configuration {
|
||||
enabled: self.dapps_enabled(),
|
||||
dapps_path: PathBuf::from(self.directories().dapps),
|
||||
extra_dapps: if self.args.cmd_dapp {
|
||||
self.args.arg_path.iter().map(|path| PathBuf::from(path)).collect()
|
||||
self.args.arg_dapp_path.iter().map(|path| PathBuf::from(path)).collect()
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
@ -616,9 +621,9 @@ impl Configuration {
|
||||
self_secret: self.secretstore_self_secret()?,
|
||||
nodes: self.secretstore_nodes()?,
|
||||
interface: self.secretstore_interface(),
|
||||
port: self.args.flag_ports_shift + self.args.flag_secretstore_port,
|
||||
port: self.args.arg_ports_shift + self.args.arg_secretstore_port,
|
||||
http_interface: self.secretstore_http_interface(),
|
||||
http_port: self.args.flag_ports_shift + self.args.flag_secretstore_http_port,
|
||||
http_port: self.args.arg_ports_shift + self.args.arg_secretstore_http_port,
|
||||
data_path: self.directories().secretstore,
|
||||
})
|
||||
}
|
||||
@ -626,7 +631,7 @@ impl Configuration {
|
||||
fn ipfs_config(&self) -> IpfsConfiguration {
|
||||
IpfsConfiguration {
|
||||
enabled: self.args.flag_ipfs_api,
|
||||
port: self.args.flag_ports_shift + self.args.flag_ipfs_api_port,
|
||||
port: self.args.arg_ports_shift + self.args.arg_ipfs_api_port,
|
||||
interface: self.ipfs_interface(),
|
||||
cors: self.ipfs_cors(),
|
||||
hosts: self.ipfs_hosts(),
|
||||
@ -637,7 +642,7 @@ impl Configuration {
|
||||
if !self.args.cmd_dapp {
|
||||
return Ok(None);
|
||||
}
|
||||
let path = self.args.arg_path.get(0).map(String::as_str).unwrap_or(".");
|
||||
let path = self.args.arg_dapp_path.as_ref().map(String::as_str).unwrap_or(".");
|
||||
let path = Path::new(path).canonicalize()
|
||||
.map_err(|e| format!("Invalid path: {}. Error: {:?}", path, e))?;
|
||||
let name = path.file_name()
|
||||
@ -654,14 +659,14 @@ impl Configuration {
|
||||
U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap()
|
||||
}
|
||||
|
||||
if let Some(dec) = self.args.flag_gasprice.as_ref() {
|
||||
if let Some(dec) = self.args.arg_gasprice.as_ref() {
|
||||
return Ok(GasPricerConfig::Fixed(to_u256(dec)?));
|
||||
} else if let Some(dec) = self.args.flag_min_gas_price {
|
||||
} else if let Some(dec) = self.args.arg_min_gas_price {
|
||||
return Ok(GasPricerConfig::Fixed(U256::from(dec)));
|
||||
}
|
||||
|
||||
let usd_per_tx = to_price(&self.args.flag_usd_per_tx)?;
|
||||
if "auto" == self.args.flag_usd_per_eth.as_str() {
|
||||
let usd_per_tx = to_price(&self.args.arg_usd_per_tx)?;
|
||||
if "auto" == self.args.arg_usd_per_eth.as_str() {
|
||||
// Just a very rough estimate to avoid accepting
|
||||
// ZGP transactions before the price is fetched
|
||||
// if user does not want it.
|
||||
@ -669,11 +674,11 @@ impl Configuration {
|
||||
return Ok(GasPricerConfig::Calibrated {
|
||||
initial_minimum: wei_per_gas(usd_per_tx, last_known_usd_per_eth),
|
||||
usd_per_tx: usd_per_tx,
|
||||
recalibration_period: to_duration(self.args.flag_price_update_period.as_str())?,
|
||||
recalibration_period: to_duration(self.args.arg_price_update_period.as_str())?,
|
||||
});
|
||||
}
|
||||
|
||||
let usd_per_eth = to_price(&self.args.flag_usd_per_eth)?;
|
||||
let usd_per_eth = to_price(&self.args.arg_usd_per_eth)?;
|
||||
let wei_per_gas = wei_per_gas(usd_per_tx, usd_per_eth);
|
||||
|
||||
info!(
|
||||
@ -686,7 +691,7 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn extra_data(&self) -> Result<Bytes, String> {
|
||||
match self.args.flag_extradata.as_ref().or(self.args.flag_extra_data.as_ref()) {
|
||||
match self.args.arg_extradata.as_ref().or(self.args.arg_extra_data.as_ref()) {
|
||||
Some(x) if x.len() <= 32 => Ok(x.as_bytes().to_owned()),
|
||||
None => Ok(version_data()),
|
||||
Some(_) => Err("Extra data must be at most 32 characters".into()),
|
||||
@ -696,7 +701,7 @@ impl Configuration {
|
||||
fn init_reserved_nodes(&self) -> Result<Vec<String>, String> {
|
||||
use std::fs::File;
|
||||
|
||||
match self.args.flag_reserved_peers {
|
||||
match self.args.arg_reserved_peers {
|
||||
Some(ref path) => {
|
||||
let mut buffer = String::new();
|
||||
let mut node_file = File::open(path).map_err(|e| format!("Error opening reserved nodes file: {}", e))?;
|
||||
@ -712,10 +717,10 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn net_addresses(&self) -> Result<(SocketAddr, Option<SocketAddr>), String> {
|
||||
let port = self.args.flag_ports_shift + self.args.flag_port;
|
||||
let port = self.args.arg_ports_shift + self.args.arg_port;
|
||||
let listen_address = SocketAddr::new("0.0.0.0".parse().unwrap(), port);
|
||||
let public_address = if self.args.flag_nat.starts_with("extip:") {
|
||||
let host = &self.args.flag_nat[6..];
|
||||
let public_address = if self.args.arg_nat.starts_with("extip:") {
|
||||
let host = &self.args.arg_nat[6..];
|
||||
let host = host.parse().map_err(|_| format!("Invalid host given with `--nat extip:{}`", host))?;
|
||||
Some(SocketAddr::new(host, port))
|
||||
} else {
|
||||
@ -726,12 +731,12 @@ impl Configuration {
|
||||
|
||||
fn net_config(&self) -> Result<NetworkConfiguration, String> {
|
||||
let mut ret = NetworkConfiguration::new();
|
||||
ret.nat_enabled = self.args.flag_nat == "any" || self.args.flag_nat == "upnp";
|
||||
ret.boot_nodes = to_bootnodes(&self.args.flag_bootnodes)?;
|
||||
ret.nat_enabled = self.args.arg_nat == "any" || self.args.arg_nat == "upnp";
|
||||
ret.boot_nodes = to_bootnodes(&self.args.arg_bootnodes)?;
|
||||
let (listen, public) = self.net_addresses()?;
|
||||
ret.listen_address = Some(format!("{}", listen));
|
||||
ret.public_address = public.map(|p| format!("{}", p));
|
||||
ret.use_secret = match self.args.flag_node_key.as_ref()
|
||||
ret.use_secret = match self.args.arg_node_key.as_ref()
|
||||
.map(|s| s.parse::<Secret>().or_else(|_| Secret::from_unsafe_slice(&keccak(s))).map_err(|e| format!("Invalid key: {:?}", e))
|
||||
) {
|
||||
None => None,
|
||||
@ -753,13 +758,13 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn network_id(&self) -> Option<u64> {
|
||||
self.args.flag_network_id.or(self.args.flag_networkid)
|
||||
self.args.arg_network_id.or(self.args.arg_networkid)
|
||||
}
|
||||
|
||||
fn rpc_apis(&self) -> String {
|
||||
let mut apis: Vec<&str> = self.args.flag_rpcapi
|
||||
let mut apis: Vec<&str> = self.args.arg_rpcapi
|
||||
.as_ref()
|
||||
.unwrap_or(&self.args.flag_jsonrpc_apis)
|
||||
.unwrap_or(&self.args.arg_jsonrpc_apis)
|
||||
.split(",")
|
||||
.collect();
|
||||
|
||||
@ -775,12 +780,12 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn rpc_cors(&self) -> Option<Vec<String>> {
|
||||
let cors = self.args.flag_jsonrpc_cors.as_ref().or(self.args.flag_rpccorsdomain.as_ref());
|
||||
let cors = self.args.arg_jsonrpc_cors.as_ref().or(self.args.arg_rpccorsdomain.as_ref());
|
||||
Self::cors(cors)
|
||||
}
|
||||
|
||||
fn ipfs_cors(&self) -> Option<Vec<String>> {
|
||||
Self::cors(self.args.flag_ipfs_api_cors.as_ref())
|
||||
Self::cors(self.args.arg_ipfs_api_cors.as_ref())
|
||||
}
|
||||
|
||||
fn hosts(&self, hosts: &str, interface: &str) -> Option<Vec<String>> {
|
||||
@ -806,15 +811,15 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn ui_hosts(&self) -> Option<Vec<String>> {
|
||||
self.hosts(&self.args.flag_ui_hosts, &self.ui_interface())
|
||||
self.hosts(&self.args.arg_ui_hosts, &self.ui_interface())
|
||||
}
|
||||
|
||||
fn rpc_hosts(&self) -> Option<Vec<String>> {
|
||||
self.hosts(&self.args.flag_jsonrpc_hosts, &self.rpc_interface())
|
||||
self.hosts(&self.args.arg_jsonrpc_hosts, &self.rpc_interface())
|
||||
}
|
||||
|
||||
fn ws_hosts(&self) -> Option<Vec<String>> {
|
||||
self.hosts(&self.args.flag_ws_hosts, &self.ws_interface())
|
||||
self.hosts(&self.args.arg_ws_hosts, &self.ws_interface())
|
||||
}
|
||||
|
||||
fn ws_origins(&self) -> Option<Vec<String>> {
|
||||
@ -822,11 +827,11 @@ impl Configuration {
|
||||
return None;
|
||||
}
|
||||
|
||||
Self::parse_hosts(&self.args.flag_ws_origins)
|
||||
Self::parse_hosts(&self.args.arg_ws_origins)
|
||||
}
|
||||
|
||||
fn ipfs_hosts(&self) -> Option<Vec<String>> {
|
||||
self.hosts(&self.args.flag_ipfs_api_hosts, &self.ipfs_interface())
|
||||
self.hosts(&self.args.arg_ipfs_api_hosts, &self.ipfs_interface())
|
||||
}
|
||||
|
||||
fn ipc_config(&self) -> Result<IpcConfiguration, String> {
|
||||
@ -834,7 +839,7 @@ impl Configuration {
|
||||
enabled: !(self.args.flag_ipcdisable || self.args.flag_ipc_off || self.args.flag_no_ipc),
|
||||
socket_addr: self.ipc_path(),
|
||||
apis: {
|
||||
let mut apis = self.args.flag_ipcapi.clone().unwrap_or(self.args.flag_ipc_apis.clone());
|
||||
let mut apis = self.args.arg_ipcapi.clone().unwrap_or(self.args.arg_ipc_apis.clone());
|
||||
if self.args.flag_geth {
|
||||
if !apis.is_empty() {
|
||||
apis.push_str(",");
|
||||
@ -852,19 +857,19 @@ impl Configuration {
|
||||
let conf = HttpConfiguration {
|
||||
enabled: self.rpc_enabled(),
|
||||
interface: self.rpc_interface(),
|
||||
port: self.args.flag_ports_shift + self.args.flag_rpcport.unwrap_or(self.args.flag_jsonrpc_port),
|
||||
port: self.args.arg_ports_shift + self.args.arg_rpcport.unwrap_or(self.args.arg_jsonrpc_port),
|
||||
apis: match self.args.flag_public_node {
|
||||
false => self.rpc_apis().parse()?,
|
||||
true => self.rpc_apis().parse::<ApiSet>()?.retain(ApiSet::PublicContext),
|
||||
},
|
||||
hosts: self.rpc_hosts(),
|
||||
cors: self.rpc_cors(),
|
||||
server_threads: match self.args.flag_jsonrpc_server_threads {
|
||||
server_threads: match self.args.arg_jsonrpc_server_threads {
|
||||
Some(threads) if threads > 0 => Some(threads),
|
||||
None => None,
|
||||
_ => return Err("--jsonrpc-server-threads number needs to be positive.".into()),
|
||||
},
|
||||
processing_threads: self.args.flag_jsonrpc_threads,
|
||||
processing_threads: self.args.arg_jsonrpc_threads,
|
||||
};
|
||||
|
||||
Ok(conf)
|
||||
@ -876,8 +881,8 @@ impl Configuration {
|
||||
let conf = WsConfiguration {
|
||||
enabled: self.ws_enabled(),
|
||||
interface: self.ws_interface(),
|
||||
port: self.args.flag_ports_shift + self.args.flag_ws_port,
|
||||
apis: self.args.flag_ws_apis.parse()?,
|
||||
port: self.args.arg_ports_shift + self.args.arg_ws_port,
|
||||
apis: self.args.arg_ws_apis.parse()?,
|
||||
hosts: self.ws_hosts(),
|
||||
origins: self.ws_origins(),
|
||||
signer_path: self.directories().signer.into(),
|
||||
@ -892,7 +897,7 @@ impl Configuration {
|
||||
let http_conf = self.http_config()?;
|
||||
let net_addresses = self.net_addresses()?;
|
||||
Ok(NetworkSettings {
|
||||
name: self.args.flag_identity.clone(),
|
||||
name: self.args.arg_identity.clone(),
|
||||
chain: self.chain(),
|
||||
network_port: net_addresses.0.port(),
|
||||
rpc_enabled: http_conf.enabled,
|
||||
@ -905,13 +910,13 @@ impl Configuration {
|
||||
Ok(UpdatePolicy {
|
||||
enable_downloading: !self.args.flag_no_download,
|
||||
require_consensus: !self.args.flag_no_consensus,
|
||||
filter: match self.args.flag_auto_update.as_ref() {
|
||||
filter: match self.args.arg_auto_update.as_ref() {
|
||||
"none" => UpdateFilter::None,
|
||||
"critical" => UpdateFilter::Critical,
|
||||
"all" => UpdateFilter::All,
|
||||
_ => return Err("Invalid value for `--auto-update`. See `--help` for more information.".into()),
|
||||
},
|
||||
track: match self.args.flag_release_track.as_ref() {
|
||||
track: match self.args.arg_release_track.as_ref() {
|
||||
"stable" => ReleaseTrack::Stable,
|
||||
"beta" => ReleaseTrack::Beta,
|
||||
"nightly" => ReleaseTrack::Nightly,
|
||||
@ -927,23 +932,23 @@ impl Configuration {
|
||||
use path;
|
||||
|
||||
let local_path = default_local_path();
|
||||
let base_path = self.args.flag_base_path.as_ref().or_else(|| self.args.flag_datadir.as_ref()).map_or_else(|| default_data_path(), |s| s.clone());
|
||||
let base_path = self.args.arg_base_path.as_ref().or_else(|| self.args.arg_datadir.as_ref()).map_or_else(|| default_data_path(), |s| s.clone());
|
||||
let data_path = replace_home("", &base_path);
|
||||
let is_using_base_path = self.args.flag_base_path.is_some();
|
||||
let is_using_base_path = self.args.arg_base_path.is_some();
|
||||
// If base_path is set and db_path is not we default to base path subdir instead of LOCAL.
|
||||
let base_db_path = if is_using_base_path && self.args.flag_db_path.is_none() {
|
||||
let base_db_path = if is_using_base_path && self.args.arg_db_path.is_none() {
|
||||
"$BASE/chains"
|
||||
} else {
|
||||
self.args.flag_db_path.as_ref().map_or(dir::CHAINS_PATH, |s| &s)
|
||||
self.args.arg_db_path.as_ref().map_or(dir::CHAINS_PATH, |s| &s)
|
||||
};
|
||||
let cache_path = if is_using_base_path { "$BASE/cache" } else { dir::CACHE_PATH };
|
||||
|
||||
let db_path = replace_home_and_local(&data_path, &local_path, &base_db_path);
|
||||
let cache_path = replace_home_and_local(&data_path, &local_path, cache_path);
|
||||
let keys_path = replace_home(&data_path, &self.args.flag_keys_path);
|
||||
let dapps_path = replace_home(&data_path, &self.args.flag_dapps_path);
|
||||
let secretstore_path = replace_home(&data_path, &self.args.flag_secretstore_path);
|
||||
let ui_path = replace_home(&data_path, &self.args.flag_ui_path);
|
||||
let keys_path = replace_home(&data_path, &self.args.arg_keys_path);
|
||||
let dapps_path = replace_home(&data_path, &self.args.arg_dapps_path);
|
||||
let secretstore_path = replace_home(&data_path, &self.args.arg_secretstore_path);
|
||||
let ui_path = replace_home(&data_path, &self.args.arg_ui_path);
|
||||
|
||||
if self.args.flag_geth && !cfg!(windows) {
|
||||
let geth_root = if self.chain() == "testnet".to_owned() { path::ethereum::test() } else { path::ethereum::default() };
|
||||
@ -977,8 +982,8 @@ impl Configuration {
|
||||
} else {
|
||||
parity_ipc_path(
|
||||
&self.directories().base,
|
||||
&self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone()),
|
||||
self.args.flag_ports_shift,
|
||||
&self.args.arg_ipcpath.clone().unwrap_or(self.args.arg_ipc_path.clone()),
|
||||
self.args.arg_ports_shift,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -996,32 +1001,32 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn ui_interface(&self) -> String {
|
||||
self.interface(&self.args.flag_ui_interface)
|
||||
self.interface(&self.args.arg_ui_interface)
|
||||
}
|
||||
|
||||
fn rpc_interface(&self) -> String {
|
||||
let rpc_interface = self.args.flag_rpcaddr.clone().unwrap_or(self.args.flag_jsonrpc_interface.clone());
|
||||
let rpc_interface = self.args.arg_rpcaddr.clone().unwrap_or(self.args.arg_jsonrpc_interface.clone());
|
||||
self.interface(&rpc_interface)
|
||||
}
|
||||
|
||||
fn ws_interface(&self) -> String {
|
||||
self.interface(&self.args.flag_ws_interface)
|
||||
self.interface(&self.args.arg_ws_interface)
|
||||
}
|
||||
|
||||
fn ipfs_interface(&self) -> String {
|
||||
self.interface(&self.args.flag_ipfs_api_interface)
|
||||
self.interface(&self.args.arg_ipfs_api_interface)
|
||||
}
|
||||
|
||||
fn secretstore_interface(&self) -> String {
|
||||
self.interface(&self.args.flag_secretstore_interface)
|
||||
self.interface(&self.args.arg_secretstore_interface)
|
||||
}
|
||||
|
||||
fn secretstore_http_interface(&self) -> String {
|
||||
self.interface(&self.args.flag_secretstore_http_interface)
|
||||
self.interface(&self.args.arg_secretstore_http_interface)
|
||||
}
|
||||
|
||||
fn secretstore_self_secret(&self) -> Result<Option<NodeSecretKey>, String> {
|
||||
match self.args.flag_secretstore_secret {
|
||||
match self.args.arg_secretstore_secret {
|
||||
Some(ref s) if s.len() == 64 => Ok(Some(NodeSecretKey::Plain(s.parse()
|
||||
.map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))),
|
||||
Some(ref s) if s.len() == 40 => Ok(Some(NodeSecretKey::KeyStore(s.parse()
|
||||
@ -1033,7 +1038,7 @@ impl Configuration {
|
||||
|
||||
fn secretstore_nodes(&self) -> Result<BTreeMap<Public, (String, u16)>, String> {
|
||||
let mut nodes = BTreeMap::new();
|
||||
for node in self.args.flag_secretstore_nodes.split(',').filter(|n| n != &"") {
|
||||
for node in self.args.arg_secretstore_nodes.split(',').filter(|n| n != &"") {
|
||||
let public_and_addr: Vec<_> = node.split('@').collect();
|
||||
if public_and_addr.len() != 2 {
|
||||
return Err(format!("Invalid secret store node: {}", node));
|
||||
@ -1056,7 +1061,7 @@ impl Configuration {
|
||||
}
|
||||
|
||||
fn stratum_interface(&self) -> String {
|
||||
self.interface(&self.args.flag_stratum_interface)
|
||||
self.interface(&self.args.arg_stratum_interface)
|
||||
}
|
||||
|
||||
fn rpc_enabled(&self) -> bool {
|
||||
@ -1088,7 +1093,7 @@ impl Configuration {
|
||||
return true;
|
||||
}
|
||||
|
||||
let ui_disabled = self.args.flag_unlock.is_some() ||
|
||||
let ui_disabled = self.args.arg_unlock.is_some() ||
|
||||
self.args.flag_geth ||
|
||||
self.args.flag_no_ui;
|
||||
|
||||
@ -1098,7 +1103,7 @@ impl Configuration {
|
||||
fn verifier_settings(&self) -> VerifierSettings {
|
||||
let mut settings = VerifierSettings::default();
|
||||
settings.scale_verifiers = self.args.flag_scale_verifiers;
|
||||
if let Some(num_verifiers) = self.args.flag_num_verifiers {
|
||||
if let Some(num_verifiers) = self.args.arg_num_verifiers {
|
||||
settings.num_verifiers = num_verifiers;
|
||||
}
|
||||
|
||||
@ -1108,7 +1113,7 @@ impl Configuration {
|
||||
fn whisper_config(&self) -> ::whisper::Config {
|
||||
::whisper::Config {
|
||||
enabled: self.args.flag_whisper,
|
||||
target_message_pool_size: self.args.flag_whisper_pool_size * 1024 * 1024,
|
||||
target_message_pool_size: self.args.arg_whisper_pool_size * 1024 * 1024,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1404,7 +1409,7 @@ mod tests {
|
||||
let conf3 = parse(&["parity", "--tx-queue-strategy", "gas"]);
|
||||
|
||||
// then
|
||||
let min_period = conf0.args.flag_reseal_min_period;
|
||||
let min_period = conf0.args.arg_reseal_min_period;
|
||||
assert_eq!(conf0.miner_options(min_period).unwrap(), mining_options);
|
||||
mining_options.tx_queue_strategy = PrioritizationStrategy::GasFactorAndGasPrice;
|
||||
assert_eq!(conf1.miner_options(min_period).unwrap(), mining_options);
|
||||
@ -1563,10 +1568,10 @@ mod tests {
|
||||
// given
|
||||
|
||||
// when
|
||||
let conf0 = parse(&["parity", "--ui-path", "signer"]);
|
||||
let conf1 = parse(&["parity", "--ui-path", "signer", "--ui-no-validation"]);
|
||||
let conf2 = parse(&["parity", "--ui-path", "signer", "--ui-port", "3123"]);
|
||||
let conf3 = parse(&["parity", "--ui-path", "signer", "--ui-interface", "test"]);
|
||||
let conf0 = parse(&["parity", "--ui-path=signer"]);
|
||||
let conf1 = parse(&["parity", "--ui-path=signer", "--ui-no-validation"]);
|
||||
let conf2 = parse(&["parity", "--ui-path=signer", "--ui-port", "3123"]);
|
||||
let conf3 = parse(&["parity", "--ui-path=signer", "--ui-interface", "test"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.directories().signer, "signer".to_owned());
|
||||
|
@ -65,40 +65,40 @@ pub fn find_deprecated(args: &Args) -> Vec<Deprecated> {
|
||||
result.push(Deprecated::Replaced("--ipc-off", "--no-ipc"));
|
||||
}
|
||||
|
||||
if args.flag_etherbase.is_some() {
|
||||
if args.arg_etherbase.is_some() {
|
||||
result.push(Deprecated::Replaced("--etherbase", "--author"));
|
||||
}
|
||||
|
||||
if args.flag_extradata.is_some() {
|
||||
if args.arg_extradata.is_some() {
|
||||
result.push(Deprecated::Replaced("--extradata", "--extra-data"));
|
||||
}
|
||||
|
||||
// Removed in 1.7
|
||||
if args.flag_dapps_port.is_some() {
|
||||
if args.arg_dapps_port.is_some() {
|
||||
result.push(Deprecated::Replaced("--dapps-port", "--jsonrpc-port"));
|
||||
}
|
||||
|
||||
if args.flag_dapps_interface.is_some() {
|
||||
if args.arg_dapps_interface.is_some() {
|
||||
result.push(Deprecated::Replaced("--dapps-interface", "--jsonrpc-interface"));
|
||||
}
|
||||
|
||||
if args.flag_dapps_hosts.is_some() {
|
||||
if args.arg_dapps_hosts.is_some() {
|
||||
result.push(Deprecated::Replaced("--dapps-hosts", "--jsonrpc-hosts"));
|
||||
}
|
||||
|
||||
if args.flag_dapps_cors.is_some() {
|
||||
if args.arg_dapps_cors.is_some() {
|
||||
result.push(Deprecated::Replaced("--dapps-cors", "--jsonrpc-cors"));
|
||||
}
|
||||
|
||||
if args.flag_dapps_user.is_some() {
|
||||
if args.arg_dapps_user.is_some() {
|
||||
result.push(Deprecated::Removed("--dapps-user"));
|
||||
}
|
||||
|
||||
if args.flag_dapps_pass.is_some() {
|
||||
if args.arg_dapps_pass.is_some() {
|
||||
result.push(Deprecated::Removed("--dapps-pass"));
|
||||
}
|
||||
|
||||
if args.flag_dapps_apis_all.is_some() {
|
||||
if args.flag_dapps_apis_all {
|
||||
result.push(Deprecated::Replaced("--dapps-apis-all", "--jsonrpc-apis"));
|
||||
}
|
||||
|
||||
@ -124,15 +124,15 @@ mod tests {
|
||||
args.flag_dapps_off = true;
|
||||
args.flag_ipcdisable = true;
|
||||
args.flag_ipc_off = true;
|
||||
args.flag_etherbase = Some(Default::default());
|
||||
args.flag_extradata = Some(Default::default());
|
||||
args.flag_dapps_port = Some(Default::default());
|
||||
args.flag_dapps_interface = Some(Default::default());
|
||||
args.flag_dapps_hosts = Some(Default::default());
|
||||
args.flag_dapps_cors = Some(Default::default());
|
||||
args.flag_dapps_user = Some(Default::default());
|
||||
args.flag_dapps_pass = Some(Default::default());
|
||||
args.flag_dapps_apis_all = Some(Default::default());
|
||||
args.arg_etherbase = Some(Default::default());
|
||||
args.arg_extradata = Some(Default::default());
|
||||
args.arg_dapps_port = Some(Default::default());
|
||||
args.arg_dapps_interface = Some(Default::default());
|
||||
args.arg_dapps_hosts = Some(Default::default());
|
||||
args.arg_dapps_cors = Some(Default::default());
|
||||
args.arg_dapps_user = Some(Default::default());
|
||||
args.arg_dapps_pass = Some(Default::default());
|
||||
args.flag_dapps_apis_all = true;
|
||||
args
|
||||
}), vec![
|
||||
Deprecated::DoesNothing("--jsonrpc"),
|
||||
|
@ -26,6 +26,8 @@ extern crate ansi_term;
|
||||
extern crate app_dirs;
|
||||
extern crate ctrlc;
|
||||
extern crate docopt;
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate fdlimit;
|
||||
extern crate futures;
|
||||
|
Loading…
Reference in New Issue
Block a user