* 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 = [
|
dependencies = [
|
||||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -11,6 +11,7 @@ log = "0.3"
|
|||||||
env_logger = "0.4"
|
env_logger = "0.4"
|
||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
docopt = "0.8"
|
docopt = "0.8"
|
||||||
|
clap = "2"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
num_cpus = "1.2"
|
num_cpus = "1.2"
|
||||||
number_prefix = "0.2"
|
number_prefix = "0.2"
|
||||||
|
1662
parity/cli/mod.rs
1662
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 {
|
macro_rules! otry {
|
||||||
($e: expr) => (
|
($e:expr) => (
|
||||||
match $e {
|
match $e {
|
||||||
Some(ref v) => v,
|
Some(ref v) => v,
|
||||||
None => {
|
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 {
|
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]
|
||||||
)*
|
$(
|
||||||
}
|
FLAG $flag:ident : (bool) = false, or $flag_from_config:expr, $flag_usage:expr, $flag_help:expr,
|
||||||
{
|
)*
|
||||||
$(
|
$(
|
||||||
$field_s:ident : $typ_s:ty, display $default_s:expr, or $from_config_s: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::{fs, io, process};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use util::version;
|
use util::version;
|
||||||
use docopt::{Docopt, Error as DocoptError};
|
use clap::{Arg, App, SubCommand, AppSettings, Error as ClapError};
|
||||||
use helpers::replace_home;
|
use helpers::replace_home;
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ArgsError {
|
pub enum ArgsError {
|
||||||
Docopt(DocoptError),
|
Clap(ClapError),
|
||||||
Decode(toml::de::Error),
|
Decode(toml::de::Error),
|
||||||
Config(String, io::Error),
|
Config(String, io::Error),
|
||||||
}
|
}
|
||||||
@ -66,7 +157,7 @@ macro_rules! usage {
|
|||||||
impl ArgsError {
|
impl ArgsError {
|
||||||
pub fn exit(self) -> ! {
|
pub fn exit(self) -> ! {
|
||||||
match self {
|
match self {
|
||||||
ArgsError::Docopt(e) => e.exit(),
|
ArgsError::Clap(e) => e.exit(),
|
||||||
ArgsError::Decode(e) => {
|
ArgsError::Decode(e) => {
|
||||||
println_stderr!("You might have supplied invalid parameters in config file.");
|
println_stderr!("You might have supplied invalid parameters in config file.");
|
||||||
println_stderr!("{}", e);
|
println_stderr!("{}", e);
|
||||||
@ -81,9 +172,9 @@ macro_rules! usage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DocoptError> for ArgsError {
|
impl From<ClapError> for ArgsError {
|
||||||
fn from(e: DocoptError) -> Self {
|
fn from(e: ClapError) -> Self {
|
||||||
ArgsError::Docopt(e)
|
ArgsError::Clap(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,15 +187,33 @@ macro_rules! usage {
|
|||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Args {
|
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 $subc_flag: bool,
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
pub $subc_arg: $($subc_arg_type_tt)+,
|
||||||
|
)*
|
||||||
)*
|
)*
|
||||||
|
|
||||||
$(
|
$(
|
||||||
pub $field: $typ,
|
$(
|
||||||
)*
|
pub $flag: bool,
|
||||||
|
)*
|
||||||
$(
|
$(
|
||||||
pub $field_s: $typ_s,
|
pub $arg: $($arg_type_tt)+,
|
||||||
|
)*
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,15 +221,32 @@ macro_rules! usage {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Args {
|
Args {
|
||||||
$(
|
$(
|
||||||
$field_a: Default::default(),
|
$subc: Default::default(),
|
||||||
|
$(
|
||||||
|
$subc_subc: Default::default(),
|
||||||
|
$(
|
||||||
|
$subc_subc_flag: Default::default(),
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
$subc_subc_arg: Default::default(),
|
||||||
|
)*
|
||||||
|
)*
|
||||||
|
|
||||||
|
$(
|
||||||
|
$subc_flag: Default::default(),
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
$subc_arg: Default::default(),
|
||||||
|
)*
|
||||||
)*
|
)*
|
||||||
|
|
||||||
$(
|
$(
|
||||||
$field: $default.into(),
|
$(
|
||||||
)*
|
$flag: Default::default(),
|
||||||
|
)*
|
||||||
$(
|
$(
|
||||||
$field_s: Default::default(),
|
$arg: Default::default(),
|
||||||
|
)*
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,13 +255,46 @@ macro_rules! usage {
|
|||||||
#[derive(Default, Debug, PartialEq, Clone, Deserialize)]
|
#[derive(Default, Debug, PartialEq, Clone, Deserialize)]
|
||||||
struct RawArgs {
|
struct RawArgs {
|
||||||
$(
|
$(
|
||||||
$field_a: $typ_a,
|
$subc: bool,
|
||||||
|
|
||||||
|
$(
|
||||||
|
$subc_subc: bool,
|
||||||
|
$(
|
||||||
|
$subc_subc_flag: bool,
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
$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,
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
$subc_arg: if_option!(
|
||||||
|
$($subc_arg_type_tt)+,
|
||||||
|
THEN { $($subc_arg_type_tt)+ }
|
||||||
|
ELSE { Option<$($subc_arg_type_tt)+> }
|
||||||
|
),
|
||||||
|
)*
|
||||||
|
|
||||||
)*
|
)*
|
||||||
$(
|
$(
|
||||||
$field: Option<$typ>,
|
$(
|
||||||
)*
|
$flag: bool,
|
||||||
$(
|
)*
|
||||||
$field_s: Option<$typ_s>,
|
|
||||||
|
$(
|
||||||
|
$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()));
|
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);
|
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
|
// Load config file
|
||||||
(Ok(mut file), _) => {
|
(Ok(mut file), _) => {
|
||||||
println_stderr!("Loading config file from {}", &config_file);
|
println_stderr!("Loading config file from {}", &config_file);
|
||||||
@ -178,7 +337,7 @@ macro_rules! usage {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn parse_with_config<S: AsRef<str>>(command: &[S], config: Config) -> Result<Self, ArgsError> {
|
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> {
|
fn parse_config(config: &str) -> Result<Config, ArgsError> {
|
||||||
@ -188,41 +347,346 @@ macro_rules! usage {
|
|||||||
pub fn print_version() -> String {
|
pub fn print_version() -> String {
|
||||||
format!(include_str!("./version.txt"), version())
|
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 {
|
impl RawArgs {
|
||||||
fn into_args(self, config: Config) -> Args {
|
fn into_args(self, config: Config) -> Args {
|
||||||
let mut args = Args::default();
|
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.$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.$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.$field = self.$field.or_else(|| $from_config(&config)).unwrap_or_else(|| $default.into());
|
$(
|
||||||
)*
|
args.$flag = self.$flag || $flag_from_config(&config).unwrap_or(false);
|
||||||
$(
|
)*
|
||||||
args.$field_s = self.$field_s.or_else(|| $from_config_s(&config)).unwrap_or(None);
|
$(
|
||||||
|
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
|
args
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, DocoptError> {
|
#[allow(unused_variables)] // the submatches of arg-less subcommands aren't used
|
||||||
Docopt::new(Self::usage()).and_then(|d| d.argv(command).deserialize())
|
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, ClapError> {
|
||||||
|
|
||||||
|
let usages = vec![
|
||||||
|
$(
|
||||||
|
$(
|
||||||
|
usage_with_ident!(stringify!($arg), $arg_usage, $arg_help),
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage() -> String {
|
}
|
||||||
format!(
|
|
||||||
include_str!("./usage.txt"),
|
#[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![
|
||||||
|
$(
|
||||||
$(
|
$(
|
||||||
$field={ let v: $typ = $default.into(); v },
|
$(
|
||||||
// Uncomment this to debug
|
$subc_subc_arg_usage,
|
||||||
// "named argument never used" error
|
)*
|
||||||
// $field = $default,
|
|
||||||
)*
|
)*
|
||||||
$(
|
$(
|
||||||
$field_s = $default_s,
|
$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
|
By Wood/Paronyan/Kotewicz/Drwięga/Volf
|
||||||
Habermeier/Czaban/Greeff/Gotchac/Redmann
|
Habermeier/Czaban/Greeff/Gotchac/Redmann
|
||||||
|
|
||||||
|
@ -106,13 +106,13 @@ impl Configuration {
|
|||||||
|
|
||||||
pub fn into_command(self) -> Result<Execute, String> {
|
pub fn into_command(self) -> Result<Execute, String> {
|
||||||
let dirs = self.directories();
|
let dirs = self.directories();
|
||||||
let pruning = self.args.flag_pruning.parse()?;
|
let pruning = self.args.arg_pruning.parse()?;
|
||||||
let pruning_history = self.args.flag_pruning_history;
|
let pruning_history = self.args.arg_pruning_history;
|
||||||
let vm_type = self.vm_type()?;
|
let vm_type = self.vm_type()?;
|
||||||
let spec = self.chain().parse()?;
|
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,
|
"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 update_policy = self.update_policy()?;
|
||||||
let logger_config = self.logger_config();
|
let logger_config = self.logger_config();
|
||||||
@ -123,18 +123,21 @@ impl Configuration {
|
|||||||
let ui_conf = self.ui_config();
|
let ui_conf = self.ui_config();
|
||||||
let network_id = self.network_id();
|
let network_id = self.network_id();
|
||||||
let cache_config = self.cache_config();
|
let cache_config = self.cache_config();
|
||||||
let tracing = self.args.flag_tracing.parse()?;
|
let tracing = self.args.arg_tracing.parse()?;
|
||||||
let fat_db = self.args.flag_fat_db.parse()?;
|
let fat_db = self.args.arg_fat_db.parse()?;
|
||||||
let compaction = self.args.flag_db_compaction.parse()?;
|
let compaction = self.args.arg_db_compaction.parse()?;
|
||||||
let wal = !self.args.flag_fast_and_loose;
|
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;
|
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 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 geth_compatibility = self.args.flag_geth;
|
||||||
let mut dapps_conf = self.dapps_config();
|
let mut dapps_conf = self.dapps_config();
|
||||||
@ -142,9 +145,9 @@ impl Configuration {
|
|||||||
let secretstore_conf = self.secretstore_config()?;
|
let secretstore_conf = self.secretstore_config()?;
|
||||||
let format = self.format()?;
|
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;
|
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 {
|
let cmd = if self.args.flag_version {
|
||||||
@ -152,25 +155,25 @@ impl Configuration {
|
|||||||
} else if self.args.cmd_signer {
|
} else if self.args.cmd_signer {
|
||||||
let authfile = ::signer::codes_path(&ws_conf.signer_path);
|
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())
|
Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone())
|
||||||
} else if self.args.cmd_sign {
|
} else if self.args.cmd_signer_sign {
|
||||||
let pwfile = self.args.flag_password.get(0).map(|pwfile| {
|
let pwfile = self.args.arg_signer_sign_password.map(|pwfile| {
|
||||||
PathBuf::from(pwfile)
|
PathBuf::from(pwfile)
|
||||||
});
|
});
|
||||||
Cmd::SignerSign {
|
Cmd::SignerSign {
|
||||||
id: self.args.arg_id,
|
id: self.args.arg_signer_sign_id,
|
||||||
pwfile: pwfile,
|
pwfile: pwfile,
|
||||||
port: ws_conf.port,
|
port: ws_conf.port,
|
||||||
authfile: authfile,
|
authfile: authfile,
|
||||||
}
|
}
|
||||||
} else if self.args.cmd_reject {
|
} else if self.args.cmd_signer_reject {
|
||||||
Cmd::SignerReject {
|
Cmd::SignerReject {
|
||||||
id: self.args.arg_id,
|
id: self.args.arg_signer_reject_id,
|
||||||
port: ws_conf.port,
|
port: ws_conf.port,
|
||||||
authfile: authfile,
|
authfile: authfile,
|
||||||
}
|
}
|
||||||
} else if self.args.cmd_list {
|
} else if self.args.cmd_signer_list {
|
||||||
Cmd::SignerList {
|
Cmd::SignerList {
|
||||||
port: ws_conf.port,
|
port: ws_conf.port,
|
||||||
authfile: authfile,
|
authfile: authfile,
|
||||||
@ -178,32 +181,32 @@ impl Configuration {
|
|||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
} else if self.args.cmd_tools && self.args.cmd_hash {
|
} else if self.args.cmd_tools && self.args.cmd_tools_hash {
|
||||||
Cmd::Hash(self.args.arg_file)
|
Cmd::Hash(self.args.arg_tools_hash_file)
|
||||||
} else if self.args.cmd_db && self.args.cmd_kill {
|
} else if self.args.cmd_db && self.args.cmd_db_kill {
|
||||||
Cmd::Blockchain(BlockchainCmd::Kill(KillBlockchain {
|
Cmd::Blockchain(BlockchainCmd::Kill(KillBlockchain {
|
||||||
spec: spec,
|
spec: spec,
|
||||||
dirs: dirs,
|
dirs: dirs,
|
||||||
pruning: pruning,
|
pruning: pruning,
|
||||||
}))
|
}))
|
||||||
} else if self.args.cmd_account {
|
} 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 {
|
let new_acc = NewAccount {
|
||||||
iterations: self.args.flag_keys_iterations,
|
iterations: self.args.arg_keys_iterations,
|
||||||
path: dirs.keys,
|
path: dirs.keys,
|
||||||
spec: spec,
|
spec: spec,
|
||||||
password_file: self.args.flag_password.first().cloned(),
|
password_file: self.args.arg_account_new_password.clone(),
|
||||||
};
|
};
|
||||||
AccountCmd::New(new_acc)
|
AccountCmd::New(new_acc)
|
||||||
} else if self.args.cmd_list {
|
} else if self.args.cmd_account_list {
|
||||||
let list_acc = ListAccounts {
|
let list_acc = ListAccounts {
|
||||||
path: dirs.keys,
|
path: dirs.keys,
|
||||||
spec: spec,
|
spec: spec,
|
||||||
};
|
};
|
||||||
AccountCmd::List(list_acc)
|
AccountCmd::List(list_acc)
|
||||||
} else if self.args.cmd_import {
|
} else if self.args.cmd_account_import {
|
||||||
let import_acc = ImportAccounts {
|
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,
|
to: dirs.keys,
|
||||||
spec: spec,
|
spec: spec,
|
||||||
};
|
};
|
||||||
@ -223,11 +226,11 @@ impl Configuration {
|
|||||||
Cmd::Account(account_cmd)
|
Cmd::Account(account_cmd)
|
||||||
} else if self.args.cmd_wallet {
|
} else if self.args.cmd_wallet {
|
||||||
let presale_cmd = ImportWallet {
|
let presale_cmd = ImportWallet {
|
||||||
iterations: self.args.flag_keys_iterations,
|
iterations: self.args.arg_keys_iterations,
|
||||||
path: dirs.keys,
|
path: dirs.keys,
|
||||||
spec: spec,
|
spec: spec,
|
||||||
wallet_path: self.args.arg_path.first().unwrap().clone(),
|
wallet_path: self.args.arg_wallet_import_path.unwrap().clone(),
|
||||||
password_file: self.args.flag_password.first().cloned(),
|
password_file: self.args.arg_wallet_import_password,
|
||||||
};
|
};
|
||||||
Cmd::ImportPresaleWallet(presale_cmd)
|
Cmd::ImportPresaleWallet(presale_cmd)
|
||||||
} else if self.args.cmd_import {
|
} else if self.args.cmd_import {
|
||||||
@ -235,11 +238,11 @@ impl Configuration {
|
|||||||
spec: spec,
|
spec: spec,
|
||||||
cache_config: cache_config,
|
cache_config: cache_config,
|
||||||
dirs: dirs,
|
dirs: dirs,
|
||||||
file_path: self.args.arg_file.clone(),
|
file_path: self.args.arg_import_file.clone(),
|
||||||
format: format,
|
format: format,
|
||||||
pruning: pruning,
|
pruning: pruning,
|
||||||
pruning_history: pruning_history,
|
pruning_history: pruning_history,
|
||||||
pruning_memory: self.args.flag_pruning_memory,
|
pruning_memory: self.args.arg_pruning_memory,
|
||||||
compaction: compaction,
|
compaction: compaction,
|
||||||
wal: wal,
|
wal: wal,
|
||||||
tracing: tracing,
|
tracing: tracing,
|
||||||
@ -252,44 +255,44 @@ impl Configuration {
|
|||||||
};
|
};
|
||||||
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
||||||
} else if self.args.cmd_export {
|
} else if self.args.cmd_export {
|
||||||
if self.args.cmd_blocks {
|
if self.args.cmd_export_blocks {
|
||||||
let export_cmd = ExportBlockchain {
|
let export_cmd = ExportBlockchain {
|
||||||
spec: spec,
|
spec: spec,
|
||||||
cache_config: cache_config,
|
cache_config: cache_config,
|
||||||
dirs: dirs,
|
dirs: dirs,
|
||||||
file_path: self.args.arg_file.clone(),
|
file_path: self.args.arg_export_blocks_file.clone(),
|
||||||
format: format,
|
format: format,
|
||||||
pruning: pruning,
|
pruning: pruning,
|
||||||
pruning_history: pruning_history,
|
pruning_history: pruning_history,
|
||||||
pruning_memory: self.args.flag_pruning_memory,
|
pruning_memory: self.args.arg_pruning_memory,
|
||||||
compaction: compaction,
|
compaction: compaction,
|
||||||
wal: wal,
|
wal: wal,
|
||||||
tracing: tracing,
|
tracing: tracing,
|
||||||
fat_db: fat_db,
|
fat_db: fat_db,
|
||||||
from_block: to_block_id(&self.args.flag_from)?,
|
from_block: to_block_id(&self.args.arg_export_blocks_from)?,
|
||||||
to_block: to_block_id(&self.args.flag_to)?,
|
to_block: to_block_id(&self.args.arg_export_blocks_to)?,
|
||||||
check_seal: !self.args.flag_no_seal_check,
|
check_seal: !self.args.flag_no_seal_check,
|
||||||
};
|
};
|
||||||
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
|
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
|
||||||
} else if self.args.cmd_state {
|
} else if self.args.cmd_export_state {
|
||||||
let export_cmd = ExportState {
|
let export_cmd = ExportState {
|
||||||
spec: spec,
|
spec: spec,
|
||||||
cache_config: cache_config,
|
cache_config: cache_config,
|
||||||
dirs: dirs,
|
dirs: dirs,
|
||||||
file_path: self.args.arg_file.clone(),
|
file_path: self.args.arg_export_state_file.clone(),
|
||||||
format: format,
|
format: format,
|
||||||
pruning: pruning,
|
pruning: pruning,
|
||||||
pruning_history: pruning_history,
|
pruning_history: pruning_history,
|
||||||
pruning_memory: self.args.flag_pruning_memory,
|
pruning_memory: self.args.arg_pruning_memory,
|
||||||
compaction: compaction,
|
compaction: compaction,
|
||||||
wal: wal,
|
wal: wal,
|
||||||
tracing: tracing,
|
tracing: tracing,
|
||||||
fat_db: fat_db,
|
fat_db: fat_db,
|
||||||
at: to_block_id(&self.args.flag_at)?,
|
at: to_block_id(&self.args.arg_export_state_at)?,
|
||||||
storage: !self.args.flag_no_storage,
|
storage: !self.args.flag_export_state_no_storage,
|
||||||
code: !self.args.flag_no_code,
|
code: !self.args.flag_export_state_no_code,
|
||||||
min_balance: self.args.flag_min_balance.and_then(|s| to_u256(&s).ok()),
|
min_balance: self.args.arg_export_state_min_balance.and_then(|s| to_u256(&s).ok()),
|
||||||
max_balance: self.args.flag_max_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))
|
Cmd::Blockchain(BlockchainCmd::ExportState(export_cmd))
|
||||||
} else {
|
} else {
|
||||||
@ -302,14 +305,14 @@ impl Configuration {
|
|||||||
spec: spec,
|
spec: spec,
|
||||||
pruning: pruning,
|
pruning: pruning,
|
||||||
pruning_history: pruning_history,
|
pruning_history: pruning_history,
|
||||||
pruning_memory: self.args.flag_pruning_memory,
|
pruning_memory: self.args.arg_pruning_memory,
|
||||||
tracing: tracing,
|
tracing: tracing,
|
||||||
fat_db: fat_db,
|
fat_db: fat_db,
|
||||||
compaction: compaction,
|
compaction: compaction,
|
||||||
file_path: self.args.arg_file.clone(),
|
file_path: self.args.arg_snapshot_file.clone(),
|
||||||
wal: wal,
|
wal: wal,
|
||||||
kind: snapshot::Kind::Take,
|
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)
|
Cmd::Snapshot(snapshot_cmd)
|
||||||
} else if self.args.cmd_restore {
|
} else if self.args.cmd_restore {
|
||||||
@ -319,11 +322,11 @@ impl Configuration {
|
|||||||
spec: spec,
|
spec: spec,
|
||||||
pruning: pruning,
|
pruning: pruning,
|
||||||
pruning_history: pruning_history,
|
pruning_history: pruning_history,
|
||||||
pruning_memory: self.args.flag_pruning_memory,
|
pruning_memory: self.args.arg_pruning_memory,
|
||||||
tracing: tracing,
|
tracing: tracing,
|
||||||
fat_db: fat_db,
|
fat_db: fat_db,
|
||||||
compaction: compaction,
|
compaction: compaction,
|
||||||
file_path: self.args.arg_file.clone(),
|
file_path: self.args.arg_restore_file.clone(),
|
||||||
wal: wal,
|
wal: wal,
|
||||||
kind: snapshot::Kind::Restore,
|
kind: snapshot::Kind::Restore,
|
||||||
block_at: to_block_id("latest")?, // unimportant.
|
block_at: to_block_id("latest")?, // unimportant.
|
||||||
@ -331,7 +334,7 @@ impl Configuration {
|
|||||||
Cmd::Snapshot(restore_cmd)
|
Cmd::Snapshot(restore_cmd)
|
||||||
} else {
|
} else {
|
||||||
let daemon = if self.args.cmd_daemon {
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -345,10 +348,10 @@ impl Configuration {
|
|||||||
spec: spec,
|
spec: spec,
|
||||||
pruning: pruning,
|
pruning: pruning,
|
||||||
pruning_history: pruning_history,
|
pruning_history: pruning_history,
|
||||||
pruning_memory: self.args.flag_pruning_memory,
|
pruning_memory: self.args.arg_pruning_memory,
|
||||||
daemon: daemon,
|
daemon: daemon,
|
||||||
logger_config: logger_config.clone(),
|
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(),
|
ntp_servers: self.ntp_servers(),
|
||||||
ws_conf: ws_conf,
|
ws_conf: ws_conf,
|
||||||
http_conf: http_conf,
|
http_conf: http_conf,
|
||||||
@ -376,8 +379,8 @@ impl Configuration {
|
|||||||
secretstore_conf: secretstore_conf,
|
secretstore_conf: secretstore_conf,
|
||||||
dapp: self.dapp_to_open()?,
|
dapp: self.dapp_to_open()?,
|
||||||
ui: self.args.cmd_ui,
|
ui: self.args.cmd_ui,
|
||||||
name: self.args.flag_identity,
|
name: self.args.arg_identity,
|
||||||
custom_bootnodes: self.args.flag_bootnodes.is_some(),
|
custom_bootnodes: self.args.arg_bootnodes.is_some(),
|
||||||
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
||||||
check_seal: !self.args.flag_no_seal_check,
|
check_seal: !self.args.flag_no_seal_check,
|
||||||
download_old_blocks: !self.args.flag_no_ancient_blocks,
|
download_old_blocks: !self.args.flag_no_ancient_blocks,
|
||||||
@ -408,8 +411,8 @@ impl Configuration {
|
|||||||
let extras = MinerExtras {
|
let extras = MinerExtras {
|
||||||
author: self.author()?,
|
author: self.author()?,
|
||||||
extra_data: self.extra_data()?,
|
extra_data: self.extra_data()?,
|
||||||
gas_floor_target: to_u256(&self.args.flag_gas_floor_target)?,
|
gas_floor_target: to_u256(&self.args.arg_gas_floor_target)?,
|
||||||
gas_ceil_target: to_u256(&self.args.flag_gas_cap)?,
|
gas_ceil_target: to_u256(&self.args.arg_gas_cap)?,
|
||||||
engine_signer: self.engine_signer()?,
|
engine_signer: self.engine_signer()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -417,37 +420,39 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn author(&self) -> Result<Address, String> {
|
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> {
|
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> {
|
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()?)),
|
Some(ref f) => Ok(Some(f.parse()?)),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cache_config(&self) -> CacheConfig {
|
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),
|
Some(size) => CacheConfig::new_with_total_cache_size(size),
|
||||||
None => CacheConfig::new(
|
None => CacheConfig::new(
|
||||||
self.args.flag_cache_size_db,
|
self.args.arg_cache_size_db,
|
||||||
self.args.flag_cache_size_blocks,
|
self.args.arg_cache_size_blocks,
|
||||||
self.args.flag_cache_size_queue,
|
self.args.arg_cache_size_queue,
|
||||||
self.args.flag_cache_size_state,
|
self.args.arg_cache_size_state,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn logger_config(&self) -> LogConfig {
|
fn logger_config(&self) -> LogConfig {
|
||||||
LogConfig {
|
LogConfig {
|
||||||
mode: self.args.flag_logging.clone(),
|
mode: self.args.arg_logging.clone(),
|
||||||
color: !self.args.flag_no_color && !cfg!(windows),
|
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 {
|
else if self.args.flag_testnet {
|
||||||
"testnet".to_owned()
|
"testnet".to_owned()
|
||||||
} else {
|
} else {
|
||||||
self.args.flag_chain.clone()
|
self.args.arg_chain.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_peers(&self) -> u32 {
|
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)
|
max(self.min_peers(), peers)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ip_filter(&self) -> Result<IpFilter, String> {
|
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),
|
Ok(allow_ip) => Ok(allow_ip),
|
||||||
Err(_) => Err("Invalid IP filter value".to_owned()),
|
Err(_) => Err("Invalid IP filter value".to_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min_peers(&self) -> u32 {
|
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 {
|
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 {
|
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> {
|
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> {
|
fn accounts_config(&self) -> Result<AccountsConfig, String> {
|
||||||
let cfg = AccountsConfig {
|
let cfg = AccountsConfig {
|
||||||
iterations: self.args.flag_keys_iterations,
|
iterations: self.args.arg_keys_iterations,
|
||||||
testnet: self.args.flag_testnet,
|
testnet: self.args.flag_testnet,
|
||||||
password_files: self.args.flag_password.clone(),
|
password_files: self.args.arg_password.clone(),
|
||||||
unlocked_accounts: to_addresses(&self.args.flag_unlock)?,
|
unlocked_accounts: to_addresses(&self.args.arg_unlock)?,
|
||||||
enable_hardware_wallets: !self.args.flag_no_hardware_wallets,
|
enable_hardware_wallets: !self.args.flag_no_hardware_wallets,
|
||||||
enable_fast_unlock: self.args.flag_fast_unlock,
|
enable_fast_unlock: self.args.flag_fast_unlock,
|
||||||
};
|
};
|
||||||
@ -508,8 +513,8 @@ impl Configuration {
|
|||||||
Ok(Some(StratumOptions {
|
Ok(Some(StratumOptions {
|
||||||
io_path: self.directories().db,
|
io_path: self.directories().db,
|
||||||
listen_addr: self.stratum_interface(),
|
listen_addr: self.stratum_interface(),
|
||||||
port: self.args.flag_ports_shift + self.args.flag_stratum_port,
|
port: self.args.arg_ports_shift + self.args.arg_stratum_port,
|
||||||
secret: self.args.flag_stratum_secret.as_ref().map(|s| s.parse::<H256>().unwrap_or_else(|_| keccak(s))),
|
secret: self.args.arg_stratum_secret.as_ref().map(|s| s.parse::<H256>().unwrap_or_else(|_| keccak(s))),
|
||||||
}))
|
}))
|
||||||
} else { Ok(None) }
|
} else { Ok(None) }
|
||||||
}
|
}
|
||||||
@ -519,7 +524,7 @@ impl Configuration {
|
|||||||
return Err("Force sealing can't be used with reseal_min_period = 0".into());
|
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 {
|
let options = MinerOptions {
|
||||||
new_work_notify: self.work_notify(),
|
new_work_notify: self.work_notify(),
|
||||||
@ -527,26 +532,26 @@ impl Configuration {
|
|||||||
reseal_on_external_tx: reseal.external,
|
reseal_on_external_tx: reseal.external,
|
||||||
reseal_on_own_tx: reseal.own,
|
reseal_on_own_tx: reseal.own,
|
||||||
reseal_on_uncle: self.args.flag_reseal_on_uncle,
|
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)?,
|
Some(ref d) => to_u256(d)?,
|
||||||
None => U256::max_value(),
|
None => U256::max_value(),
|
||||||
},
|
},
|
||||||
tx_queue_size: self.args.flag_tx_queue_size,
|
tx_queue_size: self.args.arg_tx_queue_size,
|
||||||
tx_queue_memory_limit: if self.args.flag_tx_queue_mem_limit > 0 {
|
tx_queue_memory_limit: if self.args.arg_tx_queue_mem_limit > 0 {
|
||||||
Some(self.args.flag_tx_queue_mem_limit as usize * 1024 * 1024)
|
Some(self.args.arg_tx_queue_mem_limit as usize * 1024 * 1024)
|
||||||
} else { None },
|
} else { None },
|
||||||
tx_queue_gas_limit: to_gas_limit(&self.args.flag_tx_queue_gas)?,
|
tx_queue_gas_limit: to_gas_limit(&self.args.arg_tx_queue_gas)?,
|
||||||
tx_queue_strategy: to_queue_strategy(&self.args.flag_tx_queue_strategy)?,
|
tx_queue_strategy: to_queue_strategy(&self.args.arg_tx_queue_strategy)?,
|
||||||
pending_set: to_pending_set(&self.args.flag_relay_set)?,
|
pending_set: to_pending_set(&self.args.arg_relay_set)?,
|
||||||
reseal_min_period: Duration::from_millis(reseal_min_period),
|
reseal_min_period: Duration::from_millis(reseal_min_period),
|
||||||
reseal_max_period: Duration::from_millis(self.args.flag_reseal_max_period),
|
reseal_max_period: Duration::from_millis(self.args.arg_reseal_max_period),
|
||||||
work_queue_size: self.args.flag_work_queue_size,
|
work_queue_size: self.args.arg_work_queue_size,
|
||||||
enable_resubmission: !self.args.flag_remove_solved,
|
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 {
|
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),
|
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,
|
None => Banning::Disabled,
|
||||||
},
|
},
|
||||||
@ -557,11 +562,11 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ui_port(&self) -> u16 {
|
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> {
|
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 {
|
fn ui_config(&self) -> UiConfiguration {
|
||||||
@ -581,7 +586,7 @@ impl Configuration {
|
|||||||
enabled: self.dapps_enabled(),
|
enabled: self.dapps_enabled(),
|
||||||
dapps_path: PathBuf::from(self.directories().dapps),
|
dapps_path: PathBuf::from(self.directories().dapps),
|
||||||
extra_dapps: if self.args.cmd_dapp {
|
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 {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
},
|
},
|
||||||
@ -616,9 +621,9 @@ impl Configuration {
|
|||||||
self_secret: self.secretstore_self_secret()?,
|
self_secret: self.secretstore_self_secret()?,
|
||||||
nodes: self.secretstore_nodes()?,
|
nodes: self.secretstore_nodes()?,
|
||||||
interface: self.secretstore_interface(),
|
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_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,
|
data_path: self.directories().secretstore,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -626,7 +631,7 @@ impl Configuration {
|
|||||||
fn ipfs_config(&self) -> IpfsConfiguration {
|
fn ipfs_config(&self) -> IpfsConfiguration {
|
||||||
IpfsConfiguration {
|
IpfsConfiguration {
|
||||||
enabled: self.args.flag_ipfs_api,
|
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(),
|
interface: self.ipfs_interface(),
|
||||||
cors: self.ipfs_cors(),
|
cors: self.ipfs_cors(),
|
||||||
hosts: self.ipfs_hosts(),
|
hosts: self.ipfs_hosts(),
|
||||||
@ -637,7 +642,7 @@ impl Configuration {
|
|||||||
if !self.args.cmd_dapp {
|
if !self.args.cmd_dapp {
|
||||||
return Ok(None);
|
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()
|
let path = Path::new(path).canonicalize()
|
||||||
.map_err(|e| format!("Invalid path: {}. Error: {:?}", path, e))?;
|
.map_err(|e| format!("Invalid path: {}. Error: {:?}", path, e))?;
|
||||||
let name = path.file_name()
|
let name = path.file_name()
|
||||||
@ -654,14 +659,14 @@ impl Configuration {
|
|||||||
U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap()
|
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)?));
|
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)));
|
return Ok(GasPricerConfig::Fixed(U256::from(dec)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let usd_per_tx = to_price(&self.args.flag_usd_per_tx)?;
|
let usd_per_tx = to_price(&self.args.arg_usd_per_tx)?;
|
||||||
if "auto" == self.args.flag_usd_per_eth.as_str() {
|
if "auto" == self.args.arg_usd_per_eth.as_str() {
|
||||||
// Just a very rough estimate to avoid accepting
|
// Just a very rough estimate to avoid accepting
|
||||||
// ZGP transactions before the price is fetched
|
// ZGP transactions before the price is fetched
|
||||||
// if user does not want it.
|
// if user does not want it.
|
||||||
@ -669,11 +674,11 @@ impl Configuration {
|
|||||||
return Ok(GasPricerConfig::Calibrated {
|
return Ok(GasPricerConfig::Calibrated {
|
||||||
initial_minimum: wei_per_gas(usd_per_tx, last_known_usd_per_eth),
|
initial_minimum: wei_per_gas(usd_per_tx, last_known_usd_per_eth),
|
||||||
usd_per_tx: usd_per_tx,
|
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);
|
let wei_per_gas = wei_per_gas(usd_per_tx, usd_per_eth);
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
@ -686,7 +691,7 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn extra_data(&self) -> Result<Bytes, String> {
|
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()),
|
Some(x) if x.len() <= 32 => Ok(x.as_bytes().to_owned()),
|
||||||
None => Ok(version_data()),
|
None => Ok(version_data()),
|
||||||
Some(_) => Err("Extra data must be at most 32 characters".into()),
|
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> {
|
fn init_reserved_nodes(&self) -> Result<Vec<String>, String> {
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
match self.args.flag_reserved_peers {
|
match self.args.arg_reserved_peers {
|
||||||
Some(ref path) => {
|
Some(ref path) => {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
let mut node_file = File::open(path).map_err(|e| format!("Error opening reserved nodes file: {}", e))?;
|
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> {
|
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 listen_address = SocketAddr::new("0.0.0.0".parse().unwrap(), port);
|
||||||
let public_address = if self.args.flag_nat.starts_with("extip:") {
|
let public_address = if self.args.arg_nat.starts_with("extip:") {
|
||||||
let host = &self.args.flag_nat[6..];
|
let host = &self.args.arg_nat[6..];
|
||||||
let host = host.parse().map_err(|_| format!("Invalid host given with `--nat extip:{}`", host))?;
|
let host = host.parse().map_err(|_| format!("Invalid host given with `--nat extip:{}`", host))?;
|
||||||
Some(SocketAddr::new(host, port))
|
Some(SocketAddr::new(host, port))
|
||||||
} else {
|
} else {
|
||||||
@ -726,12 +731,12 @@ impl Configuration {
|
|||||||
|
|
||||||
fn net_config(&self) -> Result<NetworkConfiguration, String> {
|
fn net_config(&self) -> Result<NetworkConfiguration, String> {
|
||||||
let mut ret = NetworkConfiguration::new();
|
let mut ret = NetworkConfiguration::new();
|
||||||
ret.nat_enabled = self.args.flag_nat == "any" || self.args.flag_nat == "upnp";
|
ret.nat_enabled = self.args.arg_nat == "any" || self.args.arg_nat == "upnp";
|
||||||
ret.boot_nodes = to_bootnodes(&self.args.flag_bootnodes)?;
|
ret.boot_nodes = to_bootnodes(&self.args.arg_bootnodes)?;
|
||||||
let (listen, public) = self.net_addresses()?;
|
let (listen, public) = self.net_addresses()?;
|
||||||
ret.listen_address = Some(format!("{}", listen));
|
ret.listen_address = Some(format!("{}", listen));
|
||||||
ret.public_address = public.map(|p| format!("{}", p));
|
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))
|
.map(|s| s.parse::<Secret>().or_else(|_| Secret::from_unsafe_slice(&keccak(s))).map_err(|e| format!("Invalid key: {:?}", e))
|
||||||
) {
|
) {
|
||||||
None => None,
|
None => None,
|
||||||
@ -753,13 +758,13 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn network_id(&self) -> Option<u64> {
|
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 {
|
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()
|
.as_ref()
|
||||||
.unwrap_or(&self.args.flag_jsonrpc_apis)
|
.unwrap_or(&self.args.arg_jsonrpc_apis)
|
||||||
.split(",")
|
.split(",")
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -775,12 +780,12 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_cors(&self) -> Option<Vec<String>> {
|
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)
|
Self::cors(cors)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ipfs_cors(&self) -> Option<Vec<String>> {
|
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>> {
|
fn hosts(&self, hosts: &str, interface: &str) -> Option<Vec<String>> {
|
||||||
@ -806,15 +811,15 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ui_hosts(&self) -> Option<Vec<String>> {
|
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>> {
|
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>> {
|
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>> {
|
fn ws_origins(&self) -> Option<Vec<String>> {
|
||||||
@ -822,11 +827,11 @@ impl Configuration {
|
|||||||
return None;
|
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>> {
|
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> {
|
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),
|
enabled: !(self.args.flag_ipcdisable || self.args.flag_ipc_off || self.args.flag_no_ipc),
|
||||||
socket_addr: self.ipc_path(),
|
socket_addr: self.ipc_path(),
|
||||||
apis: {
|
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 self.args.flag_geth {
|
||||||
if !apis.is_empty() {
|
if !apis.is_empty() {
|
||||||
apis.push_str(",");
|
apis.push_str(",");
|
||||||
@ -852,19 +857,19 @@ impl Configuration {
|
|||||||
let conf = HttpConfiguration {
|
let conf = HttpConfiguration {
|
||||||
enabled: self.rpc_enabled(),
|
enabled: self.rpc_enabled(),
|
||||||
interface: self.rpc_interface(),
|
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 {
|
apis: match self.args.flag_public_node {
|
||||||
false => self.rpc_apis().parse()?,
|
false => self.rpc_apis().parse()?,
|
||||||
true => self.rpc_apis().parse::<ApiSet>()?.retain(ApiSet::PublicContext),
|
true => self.rpc_apis().parse::<ApiSet>()?.retain(ApiSet::PublicContext),
|
||||||
},
|
},
|
||||||
hosts: self.rpc_hosts(),
|
hosts: self.rpc_hosts(),
|
||||||
cors: self.rpc_cors(),
|
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),
|
Some(threads) if threads > 0 => Some(threads),
|
||||||
None => None,
|
None => None,
|
||||||
_ => return Err("--jsonrpc-server-threads number needs to be positive.".into()),
|
_ => 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)
|
Ok(conf)
|
||||||
@ -876,8 +881,8 @@ impl Configuration {
|
|||||||
let conf = WsConfiguration {
|
let conf = WsConfiguration {
|
||||||
enabled: self.ws_enabled(),
|
enabled: self.ws_enabled(),
|
||||||
interface: self.ws_interface(),
|
interface: self.ws_interface(),
|
||||||
port: self.args.flag_ports_shift + self.args.flag_ws_port,
|
port: self.args.arg_ports_shift + self.args.arg_ws_port,
|
||||||
apis: self.args.flag_ws_apis.parse()?,
|
apis: self.args.arg_ws_apis.parse()?,
|
||||||
hosts: self.ws_hosts(),
|
hosts: self.ws_hosts(),
|
||||||
origins: self.ws_origins(),
|
origins: self.ws_origins(),
|
||||||
signer_path: self.directories().signer.into(),
|
signer_path: self.directories().signer.into(),
|
||||||
@ -892,7 +897,7 @@ impl Configuration {
|
|||||||
let http_conf = self.http_config()?;
|
let http_conf = self.http_config()?;
|
||||||
let net_addresses = self.net_addresses()?;
|
let net_addresses = self.net_addresses()?;
|
||||||
Ok(NetworkSettings {
|
Ok(NetworkSettings {
|
||||||
name: self.args.flag_identity.clone(),
|
name: self.args.arg_identity.clone(),
|
||||||
chain: self.chain(),
|
chain: self.chain(),
|
||||||
network_port: net_addresses.0.port(),
|
network_port: net_addresses.0.port(),
|
||||||
rpc_enabled: http_conf.enabled,
|
rpc_enabled: http_conf.enabled,
|
||||||
@ -905,13 +910,13 @@ impl Configuration {
|
|||||||
Ok(UpdatePolicy {
|
Ok(UpdatePolicy {
|
||||||
enable_downloading: !self.args.flag_no_download,
|
enable_downloading: !self.args.flag_no_download,
|
||||||
require_consensus: !self.args.flag_no_consensus,
|
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,
|
"none" => UpdateFilter::None,
|
||||||
"critical" => UpdateFilter::Critical,
|
"critical" => UpdateFilter::Critical,
|
||||||
"all" => UpdateFilter::All,
|
"all" => UpdateFilter::All,
|
||||||
_ => return Err("Invalid value for `--auto-update`. See `--help` for more information.".into()),
|
_ => 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,
|
"stable" => ReleaseTrack::Stable,
|
||||||
"beta" => ReleaseTrack::Beta,
|
"beta" => ReleaseTrack::Beta,
|
||||||
"nightly" => ReleaseTrack::Nightly,
|
"nightly" => ReleaseTrack::Nightly,
|
||||||
@ -927,23 +932,23 @@ impl Configuration {
|
|||||||
use path;
|
use path;
|
||||||
|
|
||||||
let local_path = default_local_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 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.
|
// 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"
|
"$BASE/chains"
|
||||||
} else {
|
} 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 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 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 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 keys_path = replace_home(&data_path, &self.args.arg_keys_path);
|
||||||
let dapps_path = replace_home(&data_path, &self.args.flag_dapps_path);
|
let dapps_path = replace_home(&data_path, &self.args.arg_dapps_path);
|
||||||
let secretstore_path = replace_home(&data_path, &self.args.flag_secretstore_path);
|
let secretstore_path = replace_home(&data_path, &self.args.arg_secretstore_path);
|
||||||
let ui_path = replace_home(&data_path, &self.args.flag_ui_path);
|
let ui_path = replace_home(&data_path, &self.args.arg_ui_path);
|
||||||
|
|
||||||
if self.args.flag_geth && !cfg!(windows) {
|
if self.args.flag_geth && !cfg!(windows) {
|
||||||
let geth_root = if self.chain() == "testnet".to_owned() { path::ethereum::test() } else { path::ethereum::default() };
|
let geth_root = if self.chain() == "testnet".to_owned() { path::ethereum::test() } else { path::ethereum::default() };
|
||||||
@ -977,8 +982,8 @@ impl Configuration {
|
|||||||
} else {
|
} else {
|
||||||
parity_ipc_path(
|
parity_ipc_path(
|
||||||
&self.directories().base,
|
&self.directories().base,
|
||||||
&self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone()),
|
&self.args.arg_ipcpath.clone().unwrap_or(self.args.arg_ipc_path.clone()),
|
||||||
self.args.flag_ports_shift,
|
self.args.arg_ports_shift,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -996,32 +1001,32 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ui_interface(&self) -> String {
|
fn ui_interface(&self) -> String {
|
||||||
self.interface(&self.args.flag_ui_interface)
|
self.interface(&self.args.arg_ui_interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_interface(&self) -> String {
|
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)
|
self.interface(&rpc_interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ws_interface(&self) -> String {
|
fn ws_interface(&self) -> String {
|
||||||
self.interface(&self.args.flag_ws_interface)
|
self.interface(&self.args.arg_ws_interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ipfs_interface(&self) -> String {
|
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 {
|
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 {
|
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> {
|
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()
|
Some(ref s) if s.len() == 64 => Ok(Some(NodeSecretKey::Plain(s.parse()
|
||||||
.map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))),
|
.map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))),
|
||||||
Some(ref s) if s.len() == 40 => Ok(Some(NodeSecretKey::KeyStore(s.parse()
|
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> {
|
fn secretstore_nodes(&self) -> Result<BTreeMap<Public, (String, u16)>, String> {
|
||||||
let mut nodes = BTreeMap::new();
|
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();
|
let public_and_addr: Vec<_> = node.split('@').collect();
|
||||||
if public_and_addr.len() != 2 {
|
if public_and_addr.len() != 2 {
|
||||||
return Err(format!("Invalid secret store node: {}", node));
|
return Err(format!("Invalid secret store node: {}", node));
|
||||||
@ -1056,7 +1061,7 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn stratum_interface(&self) -> String {
|
fn stratum_interface(&self) -> String {
|
||||||
self.interface(&self.args.flag_stratum_interface)
|
self.interface(&self.args.arg_stratum_interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_enabled(&self) -> bool {
|
fn rpc_enabled(&self) -> bool {
|
||||||
@ -1088,7 +1093,7 @@ impl Configuration {
|
|||||||
return true;
|
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_geth ||
|
||||||
self.args.flag_no_ui;
|
self.args.flag_no_ui;
|
||||||
|
|
||||||
@ -1098,7 +1103,7 @@ impl Configuration {
|
|||||||
fn verifier_settings(&self) -> VerifierSettings {
|
fn verifier_settings(&self) -> VerifierSettings {
|
||||||
let mut settings = VerifierSettings::default();
|
let mut settings = VerifierSettings::default();
|
||||||
settings.scale_verifiers = self.args.flag_scale_verifiers;
|
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;
|
settings.num_verifiers = num_verifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1108,7 +1113,7 @@ impl Configuration {
|
|||||||
fn whisper_config(&self) -> ::whisper::Config {
|
fn whisper_config(&self) -> ::whisper::Config {
|
||||||
::whisper::Config {
|
::whisper::Config {
|
||||||
enabled: self.args.flag_whisper,
|
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"]);
|
let conf3 = parse(&["parity", "--tx-queue-strategy", "gas"]);
|
||||||
|
|
||||||
// then
|
// 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);
|
assert_eq!(conf0.miner_options(min_period).unwrap(), mining_options);
|
||||||
mining_options.tx_queue_strategy = PrioritizationStrategy::GasFactorAndGasPrice;
|
mining_options.tx_queue_strategy = PrioritizationStrategy::GasFactorAndGasPrice;
|
||||||
assert_eq!(conf1.miner_options(min_period).unwrap(), mining_options);
|
assert_eq!(conf1.miner_options(min_period).unwrap(), mining_options);
|
||||||
@ -1563,10 +1568,10 @@ mod tests {
|
|||||||
// given
|
// given
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let conf0 = parse(&["parity", "--ui-path", "signer"]);
|
let conf0 = parse(&["parity", "--ui-path=signer"]);
|
||||||
let conf1 = parse(&["parity", "--ui-path", "signer", "--ui-no-validation"]);
|
let conf1 = parse(&["parity", "--ui-path=signer", "--ui-no-validation"]);
|
||||||
let conf2 = parse(&["parity", "--ui-path", "signer", "--ui-port", "3123"]);
|
let conf2 = parse(&["parity", "--ui-path=signer", "--ui-port", "3123"]);
|
||||||
let conf3 = parse(&["parity", "--ui-path", "signer", "--ui-interface", "test"]);
|
let conf3 = parse(&["parity", "--ui-path=signer", "--ui-interface", "test"]);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(conf0.directories().signer, "signer".to_owned());
|
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"));
|
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"));
|
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"));
|
result.push(Deprecated::Replaced("--extradata", "--extra-data"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removed in 1.7
|
// 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"));
|
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"));
|
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"));
|
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"));
|
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"));
|
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"));
|
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"));
|
result.push(Deprecated::Replaced("--dapps-apis-all", "--jsonrpc-apis"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,15 +124,15 @@ mod tests {
|
|||||||
args.flag_dapps_off = true;
|
args.flag_dapps_off = true;
|
||||||
args.flag_ipcdisable = true;
|
args.flag_ipcdisable = true;
|
||||||
args.flag_ipc_off = true;
|
args.flag_ipc_off = true;
|
||||||
args.flag_etherbase = Some(Default::default());
|
args.arg_etherbase = Some(Default::default());
|
||||||
args.flag_extradata = Some(Default::default());
|
args.arg_extradata = Some(Default::default());
|
||||||
args.flag_dapps_port = Some(Default::default());
|
args.arg_dapps_port = Some(Default::default());
|
||||||
args.flag_dapps_interface = Some(Default::default());
|
args.arg_dapps_interface = Some(Default::default());
|
||||||
args.flag_dapps_hosts = Some(Default::default());
|
args.arg_dapps_hosts = Some(Default::default());
|
||||||
args.flag_dapps_cors = Some(Default::default());
|
args.arg_dapps_cors = Some(Default::default());
|
||||||
args.flag_dapps_user = Some(Default::default());
|
args.arg_dapps_user = Some(Default::default());
|
||||||
args.flag_dapps_pass = Some(Default::default());
|
args.arg_dapps_pass = Some(Default::default());
|
||||||
args.flag_dapps_apis_all = Some(Default::default());
|
args.flag_dapps_apis_all = true;
|
||||||
args
|
args
|
||||||
}), vec![
|
}), vec![
|
||||||
Deprecated::DoesNothing("--jsonrpc"),
|
Deprecated::DoesNothing("--jsonrpc"),
|
||||||
|
@ -26,6 +26,8 @@ extern crate ansi_term;
|
|||||||
extern crate app_dirs;
|
extern crate app_dirs;
|
||||||
extern crate ctrlc;
|
extern crate ctrlc;
|
||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate clap;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate fdlimit;
|
extern crate fdlimit;
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
|
Loading…
Reference in New Issue
Block a user