Merge remote-tracking branch 'parity/master' into bft
This commit is contained in:
@@ -21,7 +21,6 @@ use std::time::{Instant, Duration};
|
||||
use std::thread::sleep;
|
||||
use std::sync::Arc;
|
||||
use rustc_serialize::hex::FromHex;
|
||||
use ethcore_logger::{setup_log, Config as LogConfig};
|
||||
use io::{PanicHandler, ForwardPanic};
|
||||
use util::{ToPretty, Uint};
|
||||
use rlp::PayloadInfo;
|
||||
@@ -71,7 +70,6 @@ pub enum BlockchainCmd {
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ImportBlockchain {
|
||||
pub spec: SpecType,
|
||||
pub logger_config: LogConfig,
|
||||
pub cache_config: CacheConfig,
|
||||
pub dirs: Directories,
|
||||
pub file_path: Option<String>,
|
||||
@@ -80,17 +78,16 @@ pub struct ImportBlockchain {
|
||||
pub pruning_history: u64,
|
||||
pub compaction: DatabaseCompactionProfile,
|
||||
pub wal: bool,
|
||||
pub mode: Mode,
|
||||
pub tracing: Switch,
|
||||
pub fat_db: Switch,
|
||||
pub vm_type: VMType,
|
||||
pub check_seal: bool,
|
||||
pub with_color: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ExportBlockchain {
|
||||
pub spec: SpecType,
|
||||
pub logger_config: LogConfig,
|
||||
pub cache_config: CacheConfig,
|
||||
pub dirs: Directories,
|
||||
pub file_path: Option<String>,
|
||||
@@ -99,7 +96,6 @@ pub struct ExportBlockchain {
|
||||
pub pruning_history: u64,
|
||||
pub compaction: DatabaseCompactionProfile,
|
||||
pub wal: bool,
|
||||
pub mode: Mode,
|
||||
pub fat_db: Switch,
|
||||
pub tracing: Switch,
|
||||
pub from_block: BlockID,
|
||||
@@ -120,9 +116,6 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
||||
// Setup panic handler
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
|
||||
// Setup logging
|
||||
let _logger = setup_log(&cmd.logger_config);
|
||||
|
||||
// create dirs used by parity
|
||||
try!(cmd.dirs.create_dirs());
|
||||
|
||||
@@ -160,7 +153,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||
|
||||
// prepare client config
|
||||
let client_config = to_client_config(&cmd.cache_config, cmd.mode, tracing, fat_db, cmd.compaction, cmd.wal, cmd.vm_type, "".into(), algorithm, cmd.pruning_history, cmd.check_seal);
|
||||
let client_config = to_client_config(&cmd.cache_config, Mode::Active, tracing, fat_db, cmd.compaction, cmd.wal, cmd.vm_type, "".into(), algorithm, cmd.pruning_history, cmd.check_seal);
|
||||
|
||||
// build client
|
||||
let service = try!(ClientService::start(
|
||||
@@ -196,7 +189,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
|
||||
}
|
||||
};
|
||||
|
||||
let informant = Informant::new(client.clone(), None, None, None, cmd.logger_config.color);
|
||||
let informant = Informant::new(client.clone(), None, None, None, cmd.with_color);
|
||||
|
||||
try!(service.register_io_handler(Arc::new(ImportIoHandler {
|
||||
info: Arc::new(informant),
|
||||
@@ -269,9 +262,6 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
||||
// Setup panic handler
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
|
||||
// Setup logging
|
||||
let _logger = setup_log(&cmd.logger_config);
|
||||
|
||||
// create dirs used by parity
|
||||
try!(cmd.dirs.create_dirs());
|
||||
|
||||
@@ -311,7 +301,7 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
|
||||
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||
|
||||
// prepare client config
|
||||
let client_config = to_client_config(&cmd.cache_config, cmd.mode, tracing, fat_db, cmd.compaction, cmd.wal, VMType::default(), "".into(), algorithm, cmd.pruning_history, cmd.check_seal);
|
||||
let client_config = to_client_config(&cmd.cache_config, Mode::Active, tracing, fat_db, cmd.compaction, cmd.wal, VMType::default(), "".into(), algorithm, cmd.pruning_history, cmd.check_seal);
|
||||
|
||||
let service = try!(ClientService::start(
|
||||
client_config,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[parity]
|
||||
mode = "active"
|
||||
mode = "last"
|
||||
mode_timeout = 300
|
||||
mode_alarm = 3600
|
||||
chain = "homestead"
|
||||
@@ -12,7 +12,7 @@ unlock = ["0xdeadbeefcafe0000000000000000000000000000"]
|
||||
password = ["~/.safe/password.file"]
|
||||
keys_iterations = 10240
|
||||
|
||||
[signer]
|
||||
[ui]
|
||||
force = false
|
||||
disable = false
|
||||
port = 8180
|
||||
@@ -25,7 +25,7 @@ port = 30303
|
||||
min_peers = 25
|
||||
max_peers = 50
|
||||
nat = "any"
|
||||
id = "0x1"
|
||||
id = 1
|
||||
bootnodes = []
|
||||
discovery = true
|
||||
warp = true
|
||||
@@ -41,13 +41,13 @@ disable = false
|
||||
port = 8545
|
||||
interface = "local"
|
||||
cors = "null"
|
||||
apis = ["web3", "eth", "net", "ethcore", "traces", "rpc", "personal_safe"]
|
||||
apis = ["web3", "eth", "net", "parity", "traces", "rpc"]
|
||||
hosts = ["none"]
|
||||
|
||||
[ipc]
|
||||
disable = false
|
||||
path = "$HOME/.parity/jsonrpc.ipc"
|
||||
apis = ["web3", "eth", "net", "ethcore", "traces", "rpc", "personal_safe"]
|
||||
apis = ["web3", "eth", "net", "parity", "parity_accounts", "personal", "traces", "rpc"]
|
||||
|
||||
[dapps]
|
||||
disable = false
|
||||
|
||||
@@ -8,7 +8,7 @@ chain = "./chain.json"
|
||||
unlock = ["0x1", "0x2", "0x3"]
|
||||
password = ["passwdfile path"]
|
||||
|
||||
[signer]
|
||||
[ui]
|
||||
disable = true
|
||||
|
||||
[network]
|
||||
|
||||
@@ -46,7 +46,7 @@ usage! {
|
||||
flag_testnet: bool,
|
||||
flag_import_geth_keys: bool,
|
||||
flag_datadir: Option<String>,
|
||||
flag_networkid: Option<String>,
|
||||
flag_networkid: Option<usize>,
|
||||
flag_peers: Option<u16>,
|
||||
flag_nodekey: Option<String>,
|
||||
flag_nodiscover: bool,
|
||||
@@ -74,7 +74,7 @@ usage! {
|
||||
}
|
||||
{
|
||||
// -- Operating Options
|
||||
flag_mode: String = "active", or |c: &Config| otry!(c.parity).mode.clone(),
|
||||
flag_mode: String = "last", or |c: &Config| otry!(c.parity).mode.clone(),
|
||||
flag_mode_timeout: u64 = 300u64, or |c: &Config| otry!(c.parity).mode_timeout.clone(),
|
||||
flag_mode_alarm: u64 = 3600u64, or |c: &Config| otry!(c.parity).mode_alarm.clone(),
|
||||
flag_chain: String = "homestead", or |c: &Config| otry!(c.parity).chain.clone(),
|
||||
@@ -90,22 +90,20 @@ usage! {
|
||||
flag_keys_iterations: u32 = 10240u32,
|
||||
or |c: &Config| otry!(c.account).keys_iterations.clone(),
|
||||
|
||||
flag_force_signer: bool = false,
|
||||
or |c: &Config| otry!(c.signer).force.clone(),
|
||||
flag_no_signer: bool = false,
|
||||
or |c: &Config| otry!(c.signer).disable.clone(),
|
||||
flag_signer_port: u16 = 8180u16,
|
||||
or |c: &Config| otry!(c.signer).port.clone(),
|
||||
flag_signer_interface: String = "local",
|
||||
or |c: &Config| otry!(c.signer).interface.clone(),
|
||||
flag_signer_path: String = "$HOME/.parity/signer",
|
||||
or |c: &Config| otry!(c.signer).path.clone(),
|
||||
flag_force_ui: bool = false,
|
||||
or |c: &Config| otry!(c.ui).force.clone(),
|
||||
flag_no_ui: bool = false,
|
||||
or |c: &Config| otry!(c.ui).disable.clone(),
|
||||
flag_ui_port: u16 = 8180u16,
|
||||
or |c: &Config| otry!(c.ui).port.clone(),
|
||||
flag_ui_interface: String = "local",
|
||||
or |c: &Config| otry!(c.ui).interface.clone(),
|
||||
flag_ui_path: String = "$HOME/.parity/signer",
|
||||
or |c: &Config| otry!(c.ui).path.clone(),
|
||||
// NOTE [todr] For security reasons don't put this to config files
|
||||
flag_signer_no_validation: bool = false, or |_| None,
|
||||
flag_ui_no_validation: bool = false, or |_| None,
|
||||
|
||||
// -- Networking Options
|
||||
flag_no_network: bool = false,
|
||||
or |c: &Config| otry!(c.network).disable.clone(),
|
||||
flag_warp: bool = false,
|
||||
or |c: &Config| otry!(c.network).warp.clone(),
|
||||
flag_port: u16 = 30303u16,
|
||||
@@ -122,7 +120,7 @@ usage! {
|
||||
or |c: &Config| otry!(c.network).nat.clone(),
|
||||
flag_allow_ips: String = "all",
|
||||
or |c: &Config| otry!(c.network).allow_ips.clone(),
|
||||
flag_network_id: Option<String> = None,
|
||||
flag_network_id: Option<usize> = None,
|
||||
or |c: &Config| otry!(c.network).id.clone().map(Some),
|
||||
flag_bootnodes: Option<String> = None,
|
||||
or |c: &Config| otry!(c.network).bootnodes.clone().map(|vec| Some(vec.join(","))),
|
||||
@@ -145,7 +143,7 @@ usage! {
|
||||
or |c: &Config| otry!(c.rpc).interface.clone(),
|
||||
flag_jsonrpc_cors: Option<String> = None,
|
||||
or |c: &Config| otry!(c.rpc).cors.clone().map(Some),
|
||||
flag_jsonrpc_apis: String = "web3,eth,net,ethcore,traces,rpc,personal_safe",
|
||||
flag_jsonrpc_apis: String = "web3,eth,net,parity,traces,rpc",
|
||||
or |c: &Config| otry!(c.rpc).apis.clone().map(|vec| vec.join(",")),
|
||||
flag_jsonrpc_hosts: String = "none",
|
||||
or |c: &Config| otry!(c.rpc).hosts.clone().map(|vec| vec.join(",")),
|
||||
@@ -155,7 +153,7 @@ usage! {
|
||||
or |c: &Config| otry!(c.ipc).disable.clone(),
|
||||
flag_ipc_path: String = "$HOME/.parity/jsonrpc.ipc",
|
||||
or |c: &Config| otry!(c.ipc).path.clone(),
|
||||
flag_ipc_apis: String = "web3,eth,net,ethcore,traces,rpc,personal_safe",
|
||||
flag_ipc_apis: String = "web3,eth,net,parity,parity_accounts,traces,rpc",
|
||||
or |c: &Config| otry!(c.ipc).apis.clone().map(|vec| vec.join(",")),
|
||||
|
||||
// DAPPS
|
||||
@@ -273,7 +271,7 @@ usage! {
|
||||
struct Config {
|
||||
parity: Option<Operating>,
|
||||
account: Option<Account>,
|
||||
signer: Option<Signer>,
|
||||
ui: Option<Ui>,
|
||||
network: Option<Network>,
|
||||
rpc: Option<Rpc>,
|
||||
ipc: Option<Ipc>,
|
||||
@@ -304,7 +302,7 @@ struct Account {
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
||||
struct Signer {
|
||||
struct Ui {
|
||||
force: Option<bool>,
|
||||
disable: Option<bool>,
|
||||
port: Option<u16>,
|
||||
@@ -323,7 +321,7 @@ struct Network {
|
||||
max_pending_peers: Option<u16>,
|
||||
nat: Option<String>,
|
||||
allow_ips: Option<String>,
|
||||
id: Option<String>,
|
||||
id: Option<usize>,
|
||||
bootnodes: Option<Vec<String>>,
|
||||
discovery: Option<bool>,
|
||||
node_key: Option<String>,
|
||||
@@ -420,7 +418,7 @@ struct Misc {
|
||||
mod tests {
|
||||
use super::{
|
||||
Args, ArgsError,
|
||||
Config, Operating, Account, Signer, Network, Rpc, Ipc, Dapps, Mining, Footprint, Snapshots, VM, Misc
|
||||
Config, Operating, Account, Ui, Network, Rpc, Ipc, Dapps, Mining, Footprint, Snapshots, VM, Misc
|
||||
};
|
||||
use toml;
|
||||
|
||||
@@ -500,7 +498,7 @@ mod tests {
|
||||
arg_path: vec![],
|
||||
|
||||
// -- Operating Options
|
||||
flag_mode: "active".into(),
|
||||
flag_mode: "last".into(),
|
||||
flag_mode_timeout: 300u64,
|
||||
flag_mode_alarm: 3600u64,
|
||||
flag_chain: "xyz".into(),
|
||||
@@ -513,15 +511,14 @@ mod tests {
|
||||
flag_password: vec!["~/.safe/password.file".into()],
|
||||
flag_keys_iterations: 10240u32,
|
||||
|
||||
flag_force_signer: false,
|
||||
flag_no_signer: false,
|
||||
flag_signer_port: 8180u16,
|
||||
flag_signer_interface: "127.0.0.1".into(),
|
||||
flag_signer_path: "$HOME/.parity/signer".into(),
|
||||
flag_signer_no_validation: false,
|
||||
flag_force_ui: false,
|
||||
flag_no_ui: false,
|
||||
flag_ui_port: 8180u16,
|
||||
flag_ui_interface: "127.0.0.1".into(),
|
||||
flag_ui_path: "$HOME/.parity/signer".into(),
|
||||
flag_ui_no_validation: false,
|
||||
|
||||
// -- Networking Options
|
||||
flag_no_network: false,
|
||||
flag_warp: true,
|
||||
flag_port: 30303u16,
|
||||
flag_min_peers: 25u16,
|
||||
@@ -530,7 +527,7 @@ mod tests {
|
||||
flag_snapshot_peers: 0u16,
|
||||
flag_allow_ips: "all".into(),
|
||||
flag_nat: "any".into(),
|
||||
flag_network_id: Some("0x1".into()),
|
||||
flag_network_id: Some(1),
|
||||
flag_bootnodes: Some("".into()),
|
||||
flag_no_discovery: false,
|
||||
flag_node_key: None,
|
||||
@@ -543,13 +540,13 @@ mod tests {
|
||||
flag_jsonrpc_port: 8545u16,
|
||||
flag_jsonrpc_interface: "local".into(),
|
||||
flag_jsonrpc_cors: Some("null".into()),
|
||||
flag_jsonrpc_apis: "web3,eth,net,ethcore,traces,rpc,personal_safe".into(),
|
||||
flag_jsonrpc_apis: "web3,eth,net,parity,traces,rpc".into(),
|
||||
flag_jsonrpc_hosts: "none".into(),
|
||||
|
||||
// IPC
|
||||
flag_no_ipc: false,
|
||||
flag_ipc_path: "$HOME/.parity/jsonrpc.ipc".into(),
|
||||
flag_ipc_apis: "web3,eth,net,ethcore,traces,rpc,personal_safe".into(),
|
||||
flag_ipc_apis: "web3,eth,net,parity,parity_accounts,personal,traces,rpc".into(),
|
||||
|
||||
// DAPPS
|
||||
flag_no_dapps: false,
|
||||
@@ -683,7 +680,7 @@ mod tests {
|
||||
password: Some(vec!["passwdfile path".into()]),
|
||||
keys_iterations: None,
|
||||
}),
|
||||
signer: Some(Signer {
|
||||
ui: Some(Ui {
|
||||
force: None,
|
||||
disable: Some(true),
|
||||
port: None,
|
||||
|
||||
@@ -18,11 +18,12 @@ Usage:
|
||||
|
||||
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 an external interface
|
||||
is active. (default: {flag_mode}).
|
||||
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}).
|
||||
@@ -31,8 +32,8 @@ Operating Options:
|
||||
(default: {flag_mode_alarm}).
|
||||
--chain CHAIN Specify the blockchain type. CHAIN may be either a
|
||||
JSON chain specification file or olympic, frontier,
|
||||
homestead, mainnet, morden, classic, expanse or
|
||||
testnet (default: {flag_chain}).
|
||||
homestead, mainnet, morden, classic, expanse,
|
||||
testnet or dev (default: {flag_chain}).
|
||||
-d --db-path PATH Specify the database & configuration directory path
|
||||
(default: {flag_db_path}).
|
||||
--keys-path PATH Specify the path for JSON key files to be found
|
||||
@@ -42,31 +43,31 @@ Operating Options:
|
||||
Account Options:
|
||||
--unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution.
|
||||
ACCOUNTS is a comma-delimited list of addresses.
|
||||
Implies --no-signer. (default: {flag_unlock:?})
|
||||
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}).
|
||||
--force-signer Enable Trusted Signer WebSocket endpoint used by
|
||||
Signer UIs, even when --unlock is in use.
|
||||
(default: ${flag_force_signer})
|
||||
--no-signer Disable Trusted Signer WebSocket endpoint used by
|
||||
Signer UIs. (default: ${flag_no_signer})
|
||||
--signer-port PORT Specify the port of Trusted Signer server
|
||||
(default: {flag_signer_port}).
|
||||
--signer-interface IP Specify the hostname portion of the Trusted Signer
|
||||
|
||||
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_signer_interface}).
|
||||
--signer-path PATH Specify directory where Signer UIs tokens should
|
||||
be stored. (default: {flag_signer_path})
|
||||
--signer-no-validation Disable Origin and Host headers validation for
|
||||
Trusted Signer. WARNING: INSECURE. Used only for
|
||||
development. (default: {flag_signer_no_validation})
|
||||
or local (default: {flag_ui_interface}).
|
||||
--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-network Disable p2p networking. (default: {flag_no_network})
|
||||
--warp Enable syncing from the snapshot over the network. (default: {flag_warp})
|
||||
--port PORT Override the port on which the node should listen
|
||||
(default: {flag_port}).
|
||||
@@ -107,7 +108,7 @@ API and Console Options:
|
||||
--jsonrpc-apis APIS Specify the APIs available through the JSONRPC
|
||||
interface. APIS is a comma-delimited list of API
|
||||
name. Possible name are web3, eth, net, personal,
|
||||
ethcore, ethcore_set, traces, rpc, personal_safe.
|
||||
parity, parity_set, traces, rpc, parity_accounts.
|
||||
(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
|
||||
@@ -284,7 +285,7 @@ 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.
|
||||
bugs. Includes the personal_ RPC by default.
|
||||
--testnet Geth-compatible testnet mode. Equivalent to --chain
|
||||
testnet --keys-path $HOME/parity/testnet-keys.
|
||||
Overrides the --keys-path option.
|
||||
|
||||
@@ -5,5 +5,6 @@ License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
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
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ use cli::{Args, ArgsError};
|
||||
use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address};
|
||||
use util::log::Colour;
|
||||
use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP};
|
||||
use ethcore::client::{VMType, Mode};
|
||||
use ethcore::client::VMType;
|
||||
use ethcore::miner::{MinerOptions, Banning};
|
||||
|
||||
use rpc::{IpcConfiguration, HttpConfiguration};
|
||||
@@ -35,7 +35,7 @@ use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras};
|
||||
use ethcore_logger::Config as LogConfig;
|
||||
use dir::Directories;
|
||||
use dapps::Configuration as DappsConfiguration;
|
||||
use signer::Configuration as SignerConfiguration;
|
||||
use signer::{Configuration as SignerConfiguration, SignerCommand};
|
||||
use run::RunCmd;
|
||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat};
|
||||
use presale::ImportWallet;
|
||||
@@ -49,11 +49,16 @@ pub enum Cmd {
|
||||
Account(AccountCmd),
|
||||
ImportPresaleWallet(ImportWallet),
|
||||
Blockchain(BlockchainCmd),
|
||||
SignerToken(String),
|
||||
SignerToken(SignerCommand),
|
||||
Snapshot(SnapshotCommand),
|
||||
Hash(Option<String>),
|
||||
}
|
||||
|
||||
pub struct Execute {
|
||||
pub logger: LogConfig,
|
||||
pub cmd: Cmd,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Configuration {
|
||||
pub args: Args,
|
||||
@@ -70,28 +75,27 @@ impl Configuration {
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub fn into_command(self) -> Result<Cmd, String> {
|
||||
pub fn into_command(self) -> Result<Execute, String> {
|
||||
let dirs = self.directories();
|
||||
let pruning = try!(self.args.flag_pruning.parse());
|
||||
let pruning_history = self.args.flag_pruning_history;
|
||||
let vm_type = try!(self.vm_type());
|
||||
let mode = try!(to_mode(&self.args.flag_mode, self.args.flag_mode_timeout, self.args.flag_mode_alarm));
|
||||
let mode = match self.args.flag_mode.as_ref() { "last" => None, mode => Some(try!(to_mode(&mode, self.args.flag_mode_timeout, self.args.flag_mode_alarm))), };
|
||||
let miner_options = try!(self.miner_options());
|
||||
let logger_config = self.logger_config();
|
||||
let http_conf = try!(self.http_config());
|
||||
let ipc_conf = try!(self.ipc_config());
|
||||
let net_conf = try!(self.net_config());
|
||||
let network_id = try!(self.network_id());
|
||||
let network_id = self.network_id();
|
||||
let cache_config = self.cache_config();
|
||||
let spec = try!(self.chain().parse());
|
||||
let tracing = try!(self.args.flag_tracing.parse());
|
||||
let fat_db = try!(self.args.flag_fat_db.parse());
|
||||
let compaction = try!(self.args.flag_db_compaction.parse());
|
||||
let wal = !self.args.flag_fast_and_loose;
|
||||
let enable_network = self.enable_network(&mode);
|
||||
let warp_sync = self.args.flag_warp;
|
||||
let geth_compatibility = self.args.flag_geth;
|
||||
let signer_port = self.signer_port();
|
||||
let ui_address = self.ui_port().map(|port| (self.ui_interface(), port));
|
||||
let dapps_conf = self.dapps_config();
|
||||
let signer_conf = self.signer_config();
|
||||
let format = try!(self.format());
|
||||
@@ -99,7 +103,9 @@ impl Configuration {
|
||||
let cmd = if self.args.flag_version {
|
||||
Cmd::Version
|
||||
} else if self.args.cmd_signer && self.args.cmd_new_token {
|
||||
Cmd::SignerToken(dirs.signer)
|
||||
Cmd::SignerToken(SignerCommand {
|
||||
path: dirs.signer
|
||||
})
|
||||
} else if self.args.cmd_tools && self.args.cmd_hash {
|
||||
Cmd::Hash(self.args.arg_file)
|
||||
} else if self.args.cmd_account {
|
||||
@@ -141,7 +147,6 @@ impl Configuration {
|
||||
} else if self.args.cmd_import {
|
||||
let import_cmd = ImportBlockchain {
|
||||
spec: spec,
|
||||
logger_config: logger_config,
|
||||
cache_config: cache_config,
|
||||
dirs: dirs,
|
||||
file_path: self.args.arg_file.clone(),
|
||||
@@ -150,17 +155,16 @@ impl Configuration {
|
||||
pruning_history: pruning_history,
|
||||
compaction: compaction,
|
||||
wal: wal,
|
||||
mode: mode,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
vm_type: vm_type,
|
||||
check_seal: !self.args.flag_no_seal_check,
|
||||
with_color: logger_config.color,
|
||||
};
|
||||
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
|
||||
} else if self.args.cmd_export {
|
||||
let export_cmd = ExportBlockchain {
|
||||
spec: spec,
|
||||
logger_config: logger_config,
|
||||
cache_config: cache_config,
|
||||
dirs: dirs,
|
||||
file_path: self.args.arg_file.clone(),
|
||||
@@ -169,7 +173,6 @@ impl Configuration {
|
||||
pruning_history: pruning_history,
|
||||
compaction: compaction,
|
||||
wal: wal,
|
||||
mode: mode,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
from_block: try!(to_block_id(&self.args.flag_from)),
|
||||
@@ -184,8 +187,6 @@ impl Configuration {
|
||||
spec: spec,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
logger_config: logger_config,
|
||||
mode: mode,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
compaction: compaction,
|
||||
@@ -202,8 +203,6 @@ impl Configuration {
|
||||
spec: spec,
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
logger_config: logger_config,
|
||||
mode: mode,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
compaction: compaction,
|
||||
@@ -227,7 +226,7 @@ impl Configuration {
|
||||
pruning: pruning,
|
||||
pruning_history: pruning_history,
|
||||
daemon: daemon,
|
||||
logger_config: logger_config,
|
||||
logger_config: logger_config.clone(),
|
||||
miner_options: miner_options,
|
||||
http_conf: http_conf,
|
||||
ipc_conf: ipc_conf,
|
||||
@@ -242,10 +241,9 @@ impl Configuration {
|
||||
compaction: compaction,
|
||||
wal: wal,
|
||||
vm_type: vm_type,
|
||||
enable_network: enable_network,
|
||||
warp_sync: warp_sync,
|
||||
geth_compatibility: geth_compatibility,
|
||||
signer_port: signer_port,
|
||||
ui_address: ui_address,
|
||||
net_settings: self.network_settings(),
|
||||
dapps_conf: dapps_conf,
|
||||
signer_conf: signer_conf,
|
||||
@@ -258,14 +256,10 @@ impl Configuration {
|
||||
Cmd::Run(run_cmd)
|
||||
};
|
||||
|
||||
Ok(cmd)
|
||||
}
|
||||
|
||||
fn enable_network(&self, mode: &Mode) -> bool {
|
||||
match *mode {
|
||||
Mode::Dark(_) => false,
|
||||
_ => !self.args.flag_no_network,
|
||||
}
|
||||
Ok(Execute {
|
||||
logger: logger_config,
|
||||
cmd: cmd,
|
||||
})
|
||||
}
|
||||
|
||||
fn vm_type(&self) -> Result<VMType, String> {
|
||||
@@ -402,11 +396,11 @@ impl Configuration {
|
||||
|
||||
fn signer_config(&self) -> SignerConfiguration {
|
||||
SignerConfiguration {
|
||||
enabled: self.signer_enabled(),
|
||||
port: self.args.flag_signer_port,
|
||||
interface: self.signer_interface(),
|
||||
enabled: self.ui_enabled(),
|
||||
port: self.args.flag_ui_port,
|
||||
interface: self.ui_interface(),
|
||||
signer_path: self.directories().signer,
|
||||
skip_origin_validation: self.args.flag_signer_no_validation,
|
||||
skip_origin_validation: self.args.flag_ui_no_validation,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,16 +504,19 @@ impl Configuration {
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn network_id(&self) -> Result<Option<U256>, String> {
|
||||
let net_id = self.args.flag_network_id.as_ref().or(self.args.flag_networkid.as_ref());
|
||||
match net_id {
|
||||
Some(id) => Ok(Some(try!(to_u256(id)))),
|
||||
None => Ok(None),
|
||||
}
|
||||
fn network_id(&self) -> Option<usize> {
|
||||
self.args.flag_network_id.or(self.args.flag_networkid)
|
||||
}
|
||||
|
||||
fn rpc_apis(&self) -> String {
|
||||
self.args.flag_rpcapi.clone().unwrap_or(self.args.flag_jsonrpc_apis.clone())
|
||||
let mut apis = self.args.flag_rpcapi.clone().unwrap_or(self.args.flag_jsonrpc_apis.clone());
|
||||
if self.args.flag_geth {
|
||||
if !apis.is_empty() {
|
||||
apis.push_str(",");
|
||||
}
|
||||
apis.push_str("personal");
|
||||
}
|
||||
apis
|
||||
}
|
||||
|
||||
fn rpc_cors(&self) -> Option<Vec<String>> {
|
||||
@@ -551,7 +548,16 @@ impl Configuration {
|
||||
let conf = IpcConfiguration {
|
||||
enabled: !(self.args.flag_ipcdisable || self.args.flag_ipc_off || self.args.flag_no_ipc),
|
||||
socket_addr: self.ipc_path(),
|
||||
apis: try!(self.args.flag_ipcapi.clone().unwrap_or(self.args.flag_ipc_apis.clone()).parse()),
|
||||
apis: {
|
||||
let mut apis = self.args.flag_ipcapi.clone().unwrap_or(self.args.flag_ipc_apis.clone());
|
||||
if self.args.flag_geth {
|
||||
if !apis.is_empty() {
|
||||
apis.push_str(",");
|
||||
}
|
||||
apis.push_str("personal");
|
||||
}
|
||||
try!(apis.parse())
|
||||
},
|
||||
};
|
||||
|
||||
Ok(conf)
|
||||
@@ -595,7 +601,7 @@ impl Configuration {
|
||||
);
|
||||
|
||||
let dapps_path = replace_home(&self.args.flag_dapps_path);
|
||||
let signer_path = replace_home(&self.args.flag_signer_path);
|
||||
let ui_path = replace_home(&self.args.flag_ui_path);
|
||||
|
||||
if self.args.flag_geth && !cfg!(windows) {
|
||||
let geth_root = if self.args.flag_testnet { path::ethereum::test() } else { path::ethereum::default() };
|
||||
@@ -616,7 +622,7 @@ impl Configuration {
|
||||
keys: keys_path,
|
||||
db: db_path,
|
||||
dapps: dapps_path,
|
||||
signer: signer_path,
|
||||
signer: ui_path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,16 +634,16 @@ impl Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
fn signer_port(&self) -> Option<u16> {
|
||||
if !self.signer_enabled() {
|
||||
fn ui_port(&self) -> Option<u16> {
|
||||
if !self.ui_enabled() {
|
||||
None
|
||||
} else {
|
||||
Some(self.args.flag_signer_port)
|
||||
Some(self.args.flag_ui_port)
|
||||
}
|
||||
}
|
||||
|
||||
fn signer_interface(&self) -> String {
|
||||
match self.args.flag_signer_interface.as_str() {
|
||||
fn ui_interface(&self) -> String {
|
||||
match self.args.flag_ui_interface.as_str() {
|
||||
"local" => "127.0.0.1",
|
||||
x => x,
|
||||
}.into()
|
||||
@@ -662,16 +668,16 @@ impl Configuration {
|
||||
!self.args.flag_dapps_off && !self.args.flag_no_dapps && cfg!(feature = "dapps")
|
||||
}
|
||||
|
||||
fn signer_enabled(&self) -> bool {
|
||||
if self.args.flag_force_signer {
|
||||
fn ui_enabled(&self) -> bool {
|
||||
if self.args.flag_force_ui {
|
||||
return true;
|
||||
}
|
||||
|
||||
let signer_disabled = self.args.flag_unlock.is_some() ||
|
||||
let ui_disabled = self.args.flag_unlock.is_some() ||
|
||||
self.args.flag_geth ||
|
||||
self.args.flag_no_signer;
|
||||
self.args.flag_no_ui;
|
||||
|
||||
!signer_disabled
|
||||
!ui_disabled
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,7 +690,7 @@ mod tests {
|
||||
use ethcore::miner::{MinerOptions, PrioritizationStrategy};
|
||||
use helpers::{replace_home, default_network_config};
|
||||
use run::RunCmd;
|
||||
use signer::Configuration as SignerConfiguration;
|
||||
use signer::{Configuration as SignerConfiguration, SignerCommand};
|
||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, DataFormat};
|
||||
use presale::ImportWallet;
|
||||
use account::{AccountCmd, NewAccount, ImportAccounts};
|
||||
@@ -705,14 +711,14 @@ mod tests {
|
||||
fn test_command_version() {
|
||||
let args = vec!["parity", "--version"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Version);
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Version);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_command_account_new() {
|
||||
let args = vec!["parity", "account", "new"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Account(AccountCmd::New(NewAccount {
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Account(AccountCmd::New(NewAccount {
|
||||
iterations: 10240,
|
||||
path: replace_home("$HOME/.parity/keys"),
|
||||
password_file: None,
|
||||
@@ -723,16 +729,16 @@ mod tests {
|
||||
fn test_command_account_list() {
|
||||
let args = vec!["parity", "account", "list"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Account(
|
||||
AccountCmd::List(replace_home("$HOME/.parity/keys")))
|
||||
);
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Account(
|
||||
AccountCmd::List(replace_home("$HOME/.parity/keys")),
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_command_account_import() {
|
||||
let args = vec!["parity", "account", "import", "my_dir", "another_dir"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Account(AccountCmd::Import(ImportAccounts {
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Account(AccountCmd::Import(ImportAccounts {
|
||||
from: vec!["my_dir".into(), "another_dir".into()],
|
||||
to: replace_home("$HOME/.parity/keys"),
|
||||
})));
|
||||
@@ -742,7 +748,7 @@ mod tests {
|
||||
fn test_command_wallet_import() {
|
||||
let args = vec!["parity", "wallet", "import", "my_wallet.json", "--password", "pwd"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::ImportPresaleWallet(ImportWallet {
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::ImportPresaleWallet(ImportWallet {
|
||||
iterations: 10240,
|
||||
path: replace_home("$HOME/.parity/keys"),
|
||||
wallet_path: "my_wallet.json".into(),
|
||||
@@ -754,9 +760,8 @@ mod tests {
|
||||
fn test_command_blockchain_import() {
|
||||
let args = vec!["parity", "import", "blockchain.json"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Blockchain(BlockchainCmd::Import(ImportBlockchain {
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::Import(ImportBlockchain {
|
||||
spec: Default::default(),
|
||||
logger_config: Default::default(),
|
||||
cache_config: Default::default(),
|
||||
dirs: Default::default(),
|
||||
file_path: Some("blockchain.json".into()),
|
||||
@@ -765,11 +770,11 @@ mod tests {
|
||||
pruning_history: 64,
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
mode: Default::default(),
|
||||
tracing: Default::default(),
|
||||
fat_db: Default::default(),
|
||||
vm_type: VMType::Interpreter,
|
||||
check_seal: true,
|
||||
with_color: !cfg!(windows),
|
||||
})));
|
||||
}
|
||||
|
||||
@@ -777,9 +782,8 @@ mod tests {
|
||||
fn test_command_blockchain_export() {
|
||||
let args = vec!["parity", "export", "blockchain.json"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
||||
spec: Default::default(),
|
||||
logger_config: Default::default(),
|
||||
cache_config: Default::default(),
|
||||
dirs: Default::default(),
|
||||
file_path: Some("blockchain.json".into()),
|
||||
@@ -788,7 +792,6 @@ mod tests {
|
||||
format: Default::default(),
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
mode: Default::default(),
|
||||
tracing: Default::default(),
|
||||
fat_db: Default::default(),
|
||||
from_block: BlockID::Number(1),
|
||||
@@ -801,9 +804,8 @@ mod tests {
|
||||
fn test_command_blockchain_export_with_custom_format() {
|
||||
let args = vec!["parity", "export", "--format", "hex", "blockchain.json"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Blockchain(BlockchainCmd::Export(ExportBlockchain {
|
||||
spec: Default::default(),
|
||||
logger_config: Default::default(),
|
||||
cache_config: Default::default(),
|
||||
dirs: Default::default(),
|
||||
file_path: Some("blockchain.json".into()),
|
||||
@@ -812,7 +814,6 @@ mod tests {
|
||||
format: Some(DataFormat::Hex),
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
mode: Default::default(),
|
||||
tracing: Default::default(),
|
||||
fat_db: Default::default(),
|
||||
from_block: BlockID::Number(1),
|
||||
@@ -826,14 +827,16 @@ mod tests {
|
||||
let args = vec!["parity", "signer", "new-token"];
|
||||
let conf = parse(&args);
|
||||
let expected = replace_home("$HOME/.parity/signer");
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::SignerToken(expected));
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::SignerToken(SignerCommand {
|
||||
path: expected,
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_run_cmd() {
|
||||
let args = vec!["parity"];
|
||||
let conf = parse(&args);
|
||||
assert_eq!(conf.into_command().unwrap(), Cmd::Run(RunCmd {
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Run(RunCmd {
|
||||
cache_config: Default::default(),
|
||||
dirs: Default::default(),
|
||||
spec: Default::default(),
|
||||
@@ -855,9 +858,8 @@ mod tests {
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
vm_type: Default::default(),
|
||||
enable_network: true,
|
||||
geth_compatibility: false,
|
||||
signer_port: Some(8180),
|
||||
ui_address: Some(("127.0.0.1".into(), 8180)),
|
||||
net_settings: Default::default(),
|
||||
dapps_conf: Default::default(),
|
||||
signer_conf: Default::default(),
|
||||
@@ -980,11 +982,11 @@ mod tests {
|
||||
|
||||
// when
|
||||
let conf0 = parse(&["parity", "--geth"]);
|
||||
let conf1 = parse(&["parity", "--geth", "--force-signer"]);
|
||||
let conf1 = parse(&["parity", "--geth", "--force-ui"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.signer_enabled(), false);
|
||||
assert_eq!(conf1.signer_enabled(), true);
|
||||
assert_eq!(conf0.ui_enabled(), false);
|
||||
assert_eq!(conf1.ui_enabled(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -995,7 +997,7 @@ mod tests {
|
||||
let conf0 = parse(&["parity", "--unlock", "0x0"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.signer_enabled(), false);
|
||||
assert_eq!(conf0.ui_enabled(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1003,10 +1005,10 @@ mod tests {
|
||||
// given
|
||||
|
||||
// when
|
||||
let conf0 = parse(&["parity", "--signer-path", "signer"]);
|
||||
let conf1 = parse(&["parity", "--signer-path", "signer", "--signer-no-validation"]);
|
||||
let conf2 = parse(&["parity", "--signer-path", "signer", "--signer-port", "3123"]);
|
||||
let conf3 = parse(&["parity", "--signer-path", "signer", "--signer-interface", "test"]);
|
||||
let conf0 = parse(&["parity", "--ui-path", "signer"]);
|
||||
let conf1 = parse(&["parity", "--ui-path", "signer", "--ui-no-validation"]);
|
||||
let conf2 = parse(&["parity", "--ui-path", "signer", "--ui-port", "3123"]);
|
||||
let conf3 = parse(&["parity", "--ui-path", "signer", "--ui-interface", "test"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.signer_config(), SignerConfiguration {
|
||||
|
||||
@@ -58,7 +58,7 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<We
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let signer_port = deps.apis.signer_service.port();
|
||||
let signer_address = deps.apis.signer_service.address();
|
||||
let url = format!("{}:{}", configuration.interface, configuration.port);
|
||||
let addr = try!(url.parse().map_err(|_| format!("Invalid Webapps listen host/port given: {}", url)));
|
||||
|
||||
@@ -73,7 +73,7 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<We
|
||||
(username.to_owned(), password)
|
||||
});
|
||||
|
||||
Ok(Some(try!(setup_dapps_server(deps, configuration.dapps_path, &addr, configuration.hosts, auth, signer_port))))
|
||||
Ok(Some(try!(setup_dapps_server(deps, configuration.dapps_path, &addr, configuration.hosts, auth, signer_address))))
|
||||
}
|
||||
|
||||
pub use self::server::WebappServer;
|
||||
@@ -91,7 +91,7 @@ mod server {
|
||||
_url: &SocketAddr,
|
||||
_allowed_hosts: Option<Vec<String>>,
|
||||
_auth: Option<(String, String)>,
|
||||
_signer_port: Option<u16>,
|
||||
_signer_address: Option<(String, u16)>,
|
||||
) -> Result<WebappServer, String> {
|
||||
Err("Your Parity version has been compiled without WebApps support.".into())
|
||||
}
|
||||
@@ -120,7 +120,7 @@ mod server {
|
||||
url: &SocketAddr,
|
||||
allowed_hosts: Option<Vec<String>>,
|
||||
auth: Option<(String, String)>,
|
||||
signer_port: Option<u16>,
|
||||
signer_address: Option<(String, u16)>,
|
||||
) -> Result<WebappServer, String> {
|
||||
use ethcore_dapps as dapps;
|
||||
|
||||
@@ -131,7 +131,7 @@ mod server {
|
||||
let sync = deps.sync.clone();
|
||||
let client = deps.client.clone();
|
||||
server.with_sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info())));
|
||||
server.with_signer_port(signer_port);
|
||||
server.with_signer_address(signer_address);
|
||||
|
||||
let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext);
|
||||
let start_result = match auth {
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::{io, env};
|
||||
use std::io::{Write, Read, BufReader, BufRead};
|
||||
use std::io::{Write, BufReader, BufRead};
|
||||
use std::time::Duration;
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use util::{clean_0x, U256, Uint, Address, path, CompactionProfile};
|
||||
use util::journaldb::Algorithm;
|
||||
@@ -46,7 +45,7 @@ fn to_seconds(s: &str) -> Result<u64, String> {
|
||||
"hourly" | "1hour" | "1 hour" | "hour" => Ok(60 * 60),
|
||||
"daily" | "1day" | "1 day" | "day" => Ok(24 * 60 * 60),
|
||||
x if x.ends_with("seconds") => x[0..x.len() - 7].parse().map_err(bad),
|
||||
x if x.ends_with("minutes") => x[0..x.len() -7].parse::<u64>().map_err(bad).map(|x| x * 60),
|
||||
x if x.ends_with("minutes") => x[0..x.len() - 7].parse::<u64>().map_err(bad).map(|x| x * 60),
|
||||
x if x.ends_with("hours") => x[0..x.len() - 5].parse::<u64>().map_err(bad).map(|x| x * 60 * 60),
|
||||
x if x.ends_with("days") => x[0..x.len() - 4].parse::<u64>().map_err(bad).map(|x| x * 24 * 60 * 60),
|
||||
x => x.parse().map_err(bad),
|
||||
@@ -58,7 +57,8 @@ pub fn to_mode(s: &str, timeout: u64, alarm: u64) -> Result<Mode, String> {
|
||||
"active" => Ok(Mode::Active),
|
||||
"passive" => Ok(Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm))),
|
||||
"dark" => Ok(Mode::Dark(Duration::from_secs(timeout))),
|
||||
_ => Err(format!("{}: Invalid address for --mode. Must be one of active, passive or dark.", s)),
|
||||
"offline" => Ok(Mode::Off),
|
||||
_ => Err(format!("{}: Invalid value for --mode. Must be one of active, passive, dark or offline.", s)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,17 +278,18 @@ pub fn execute_upgrades(
|
||||
/// Prompts user asking for password.
|
||||
pub fn password_prompt() -> Result<String, String> {
|
||||
use rpassword::read_password;
|
||||
const STDIN_ERROR: &'static str = "Unable to ask for password on non-interactive terminal.";
|
||||
|
||||
println!("Please note that password is NOT RECOVERABLE.");
|
||||
print!("Type password: ");
|
||||
flush_stdout();
|
||||
|
||||
let password = read_password().unwrap();
|
||||
let password = try!(read_password().map_err(|_| STDIN_ERROR.to_owned()));
|
||||
|
||||
print!("Repeat password: ");
|
||||
flush_stdout();
|
||||
|
||||
let password_repeat = read_password().unwrap();
|
||||
let password_repeat = try!(read_password().map_err(|_| STDIN_ERROR.to_owned()));
|
||||
|
||||
if password != password_repeat {
|
||||
return Err("Passwords do not match!".into());
|
||||
@@ -298,13 +299,11 @@ pub fn password_prompt() -> Result<String, String> {
|
||||
}
|
||||
|
||||
/// Read a password from password file.
|
||||
pub fn password_from_file<P>(path: P) -> Result<String, String> where P: AsRef<Path> {
|
||||
let mut file = try!(File::open(path).map_err(|_| "Unable to open password file."));
|
||||
let mut file_content = String::new();
|
||||
match file.read_to_string(&mut file_content) {
|
||||
Ok(_) => Ok(file_content.trim().into()),
|
||||
Err(_) => Err("Unable to read password file.".into()),
|
||||
}
|
||||
pub fn password_from_file(path: String) -> Result<String, String> {
|
||||
let passwords = try!(passwords_from_files(vec![path]));
|
||||
// use only first password from the file
|
||||
passwords.get(0).map(String::to_owned)
|
||||
.ok_or_else(|| "Password file seems to be empty.".to_owned())
|
||||
}
|
||||
|
||||
/// Reads passwords from files. Treats each line as a separate password.
|
||||
@@ -313,10 +312,11 @@ pub fn passwords_from_files(files: Vec<String>) -> Result<Vec<String>, String> {
|
||||
let file = try!(File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)));
|
||||
let reader = BufReader::new(&file);
|
||||
let lines = reader.lines()
|
||||
.map(|l| l.unwrap())
|
||||
.filter_map(|l| l.ok())
|
||||
.map(|pwd| pwd.trim().to_owned())
|
||||
.collect::<Vec<String>>();
|
||||
Ok(lines)
|
||||
}).collect::<Result<Vec<Vec<String>>, String>>();
|
||||
}).collect::<Result<Vec<Vec<String>>, String>>();
|
||||
Ok(try!(passwords).into_iter().flat_map(|x| x).collect())
|
||||
}
|
||||
|
||||
@@ -417,7 +417,20 @@ mod tests {
|
||||
let path = RandomTempPath::new();
|
||||
let mut file = File::create(path.as_path()).unwrap();
|
||||
file.write_all(b"a bc ").unwrap();
|
||||
assert_eq!(password_from_file(path).unwrap().as_bytes(), b"a bc");
|
||||
assert_eq!(password_from_file(path.as_str().into()).unwrap().as_bytes(), b"a bc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_password_multiline() {
|
||||
let path = RandomTempPath::new();
|
||||
let mut file = File::create(path.as_path()).unwrap();
|
||||
file.write_all(br#" password with trailing whitespace
|
||||
those passwords should be
|
||||
ignored
|
||||
but the first password is trimmed
|
||||
|
||||
"#).unwrap();
|
||||
assert_eq!(&password_from_file(path.as_str().into()).unwrap(), "password with trailing whitespace");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -114,12 +114,13 @@ mod user_defaults;
|
||||
mod stratum;
|
||||
|
||||
use std::{process, env};
|
||||
use std::io::BufReader;
|
||||
use std::io::{self as stdio, BufReader, Write};
|
||||
use std::fs::File;
|
||||
use util::sha3::sha3;
|
||||
use cli::Args;
|
||||
use configuration::{Cmd, Configuration};
|
||||
use configuration::{Cmd, Execute, Configuration};
|
||||
use deprecated::find_deprecated;
|
||||
use ethcore_logger::setup_log;
|
||||
|
||||
fn print_hash_of(maybe_file: Option<String>) -> Result<String, String> {
|
||||
if let Some(file) = maybe_file {
|
||||
@@ -131,10 +132,12 @@ fn print_hash_of(maybe_file: Option<String>) -> Result<String, String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(command: Cmd) -> Result<String, String> {
|
||||
match command {
|
||||
fn execute(command: Execute) -> Result<String, String> {
|
||||
let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed");
|
||||
|
||||
match command.cmd {
|
||||
Cmd::Run(run_cmd) => {
|
||||
try!(run::execute(run_cmd));
|
||||
try!(run::execute(run_cmd, logger));
|
||||
Ok("".into())
|
||||
},
|
||||
Cmd::Version => Ok(Args::print_version()),
|
||||
@@ -142,7 +145,7 @@ fn execute(command: Cmd) -> Result<String, String> {
|
||||
Cmd::Account(account_cmd) => account::execute(account_cmd),
|
||||
Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd),
|
||||
Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd),
|
||||
Cmd::SignerToken(path) => signer::new_token(path),
|
||||
Cmd::SignerToken(signer_cmd) => signer::execute(signer_cmd),
|
||||
Cmd::Snapshot(snapshot_cmd) => snapshot::execute(snapshot_cmd),
|
||||
}
|
||||
}
|
||||
@@ -198,7 +201,7 @@ fn sync_main() -> bool {
|
||||
fn main() {
|
||||
// Always print backtrace on panic.
|
||||
::std::env::set_var("RUST_BACKTRACE", "1");
|
||||
|
||||
|
||||
if sync_main() {
|
||||
return;
|
||||
}
|
||||
@@ -210,7 +213,7 @@ fn main() {
|
||||
info!("{}", result);
|
||||
},
|
||||
Err(err) => {
|
||||
info!("{}", err);
|
||||
writeln!(&mut stdio::stderr(), "{}", err).expect("StdErr available; qed");
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ use util::{Address, U256, version_data};
|
||||
use util::journaldb::Algorithm;
|
||||
use ethcore::spec::Spec;
|
||||
use ethcore::ethereum;
|
||||
use ethcore::client::Mode;
|
||||
use ethcore::miner::{GasPricer, GasPriceCalibratorOptions};
|
||||
use user_defaults::UserDefaults;
|
||||
|
||||
@@ -30,6 +31,7 @@ pub enum SpecType {
|
||||
Olympic,
|
||||
Classic,
|
||||
Expanse,
|
||||
Dev,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
@@ -49,6 +51,7 @@ impl str::FromStr for SpecType {
|
||||
"morden" | "testnet" => SpecType::Testnet,
|
||||
"olympic" => SpecType::Olympic,
|
||||
"expanse" => SpecType::Expanse,
|
||||
"dev" => SpecType::Dev,
|
||||
other => SpecType::Custom(other.into()),
|
||||
};
|
||||
Ok(spec)
|
||||
@@ -63,6 +66,7 @@ impl SpecType {
|
||||
SpecType::Olympic => Ok(ethereum::new_olympic()),
|
||||
SpecType::Classic => Ok(ethereum::new_classic()),
|
||||
SpecType::Expanse => Ok(ethereum::new_expanse()),
|
||||
SpecType::Dev => Ok(Spec::new_instant()),
|
||||
SpecType::Custom(ref filename) => {
|
||||
let file = try!(fs::File::open(filename).map_err(|_| "Could not load specification file."));
|
||||
Spec::load(file)
|
||||
@@ -264,6 +268,10 @@ pub fn fatdb_switch_to_bool(switch: Switch, user_defaults: &UserDefaults, algori
|
||||
result
|
||||
}
|
||||
|
||||
pub fn mode_switch_to_bool(switch: Option<Mode>, user_defaults: &UserDefaults) -> Result<Mode, String> {
|
||||
Ok(switch.unwrap_or(user_defaults.mode.clone()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use util::journaldb::Algorithm;
|
||||
|
||||
@@ -63,7 +63,7 @@ impl Default for IpcConfiguration {
|
||||
IpcConfiguration {
|
||||
enabled: true,
|
||||
socket_addr: parity_ipc_path("$HOME/.parity/jsonrpc.ipc"),
|
||||
apis: ApiSet::UnsafeContext,
|
||||
apis: ApiSet::IpcContext,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,15 +31,25 @@ pub use ethcore_rpc::SignerService;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
||||
pub enum Api {
|
||||
/// Web3 (Safe)
|
||||
Web3,
|
||||
/// Net (Safe)
|
||||
Net,
|
||||
/// Eth (Safe)
|
||||
Eth,
|
||||
PersonalSafe,
|
||||
PersonalAccounts,
|
||||
/// Geth-compatible "personal" API (DEPRECATED; only used in `--geth` mode.)
|
||||
Personal,
|
||||
/// Signer - Confirm transactions in Signer (UNSAFE: Passwords, List of transactions)
|
||||
Signer,
|
||||
Ethcore,
|
||||
EthcoreSet,
|
||||
/// Parity - Custom extensions (Safe)
|
||||
Parity,
|
||||
/// Parity Accounts extensions (UNSAFE: Passwords, Side Effects (new account))
|
||||
ParityAccounts,
|
||||
/// Parity - Set methods (UNSAFE: Side Effects affecting node operation)
|
||||
ParitySet,
|
||||
/// Traces (Safe)
|
||||
Traces,
|
||||
/// Rpc (Safe)
|
||||
Rpc,
|
||||
}
|
||||
|
||||
@@ -53,11 +63,11 @@ impl FromStr for Api {
|
||||
"web3" => Ok(Web3),
|
||||
"net" => Ok(Net),
|
||||
"eth" => Ok(Eth),
|
||||
"personal" => Ok(PersonalAccounts),
|
||||
"personal_safe" => Ok(PersonalSafe),
|
||||
"personal" => Ok(Personal),
|
||||
"signer" => Ok(Signer),
|
||||
"ethcore" => Ok(Ethcore),
|
||||
"ethcore_set" => Ok(EthcoreSet),
|
||||
"parity" => Ok(Parity),
|
||||
"parity_accounts" => Ok(ParityAccounts),
|
||||
"parity_set" => Ok(ParitySet),
|
||||
"traces" => Ok(Traces),
|
||||
"rpc" => Ok(Rpc),
|
||||
api => Err(format!("Unknown api: {}", api))
|
||||
@@ -69,6 +79,7 @@ impl FromStr for Api {
|
||||
pub enum ApiSet {
|
||||
SafeContext,
|
||||
UnsafeContext,
|
||||
IpcContext,
|
||||
List(HashSet<Api>),
|
||||
}
|
||||
|
||||
@@ -108,6 +119,7 @@ pub struct Dependencies {
|
||||
pub settings: Arc<NetworkSettings>,
|
||||
pub net_service: Arc<ManageNetwork>,
|
||||
pub geth_compatibility: bool,
|
||||
pub dapps_interface: Option<String>,
|
||||
pub dapps_port: Option<u16>,
|
||||
}
|
||||
|
||||
@@ -118,11 +130,11 @@ fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
||||
Api::Web3 => ("web3", "1.0"),
|
||||
Api::Net => ("net", "1.0"),
|
||||
Api::Eth => ("eth", "1.0"),
|
||||
Api::PersonalSafe => ("personal_safe", "1.0"),
|
||||
Api::PersonalAccounts => ("personal", "1.0"),
|
||||
Api::Personal => ("personal", "1.0"),
|
||||
Api::Signer => ("signer", "1.0"),
|
||||
Api::Ethcore => ("ethcore", "1.0"),
|
||||
Api::EthcoreSet => ("ethcore_set", "1.0"),
|
||||
Api::Parity => ("parity", "1.0"),
|
||||
Api::ParityAccounts => ("parity_accounts", "1.0"),
|
||||
Api::ParitySet => ("parity_set", "1.0"),
|
||||
Api::Traces => ("traces", "1.0"),
|
||||
Api::Rpc => ("rpc", "1.0"),
|
||||
};
|
||||
@@ -133,20 +145,37 @@ fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
||||
|
||||
impl ApiSet {
|
||||
pub fn list_apis(&self) -> HashSet<Api> {
|
||||
let mut safe_list = vec![Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc]
|
||||
.into_iter().collect();
|
||||
match *self {
|
||||
ApiSet::List(ref apis) => apis.clone(),
|
||||
ApiSet::UnsafeContext => {
|
||||
vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc, Api::PersonalSafe]
|
||||
.into_iter().collect()
|
||||
ApiSet::UnsafeContext => safe_list,
|
||||
ApiSet::IpcContext => {
|
||||
safe_list.insert(Api::ParityAccounts);
|
||||
safe_list
|
||||
},
|
||||
ApiSet::SafeContext => {
|
||||
vec![Api::Web3, Api::Net, Api::Eth, Api::PersonalAccounts, Api::PersonalSafe, Api::Signer, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc]
|
||||
.into_iter().collect()
|
||||
safe_list.insert(Api::ParityAccounts);
|
||||
safe_list.insert(Api::ParitySet);
|
||||
safe_list.insert(Api::Signer);
|
||||
safe_list
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! add_signing_methods {
|
||||
($namespace:ident, $server:expr, $deps:expr) => {
|
||||
let server = &$server;
|
||||
let deps = &$deps;
|
||||
if deps.signer_service.is_enabled() {
|
||||
server.add_delegate($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, &deps.client, &deps.miner, &deps.secret_store)))
|
||||
} else {
|
||||
server.add_delegate($namespace::to_delegate(SigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet) -> T {
|
||||
use ethcore_rpc::v1::*;
|
||||
|
||||
@@ -178,39 +207,40 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
||||
let filter_client = EthFilterClient::new(&deps.client, &deps.miner);
|
||||
server.add_delegate(filter_client.to_delegate());
|
||||
|
||||
if deps.signer_service.is_enabled() {
|
||||
server.add_delegate(EthSigningQueueClient::new(&deps.signer_service, &deps.client, &deps.miner, &deps.secret_store).to_delegate());
|
||||
} else {
|
||||
server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate());
|
||||
}
|
||||
add_signing_methods!(EthSigning, server, deps);
|
||||
},
|
||||
Api::PersonalAccounts => {
|
||||
server.add_delegate(PersonalAccountsClient::new(&deps.secret_store, &deps.client, &deps.miner, deps.geth_compatibility).to_delegate());
|
||||
},
|
||||
Api::PersonalSafe => {
|
||||
server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client).to_delegate());
|
||||
Api::Personal => {
|
||||
server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner, deps.geth_compatibility).to_delegate());
|
||||
},
|
||||
Api::Signer => {
|
||||
server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_service).to_delegate());
|
||||
},
|
||||
Api::Ethcore => {
|
||||
Api::Parity => {
|
||||
let signer = match deps.signer_service.is_enabled() {
|
||||
true => Some(deps.signer_service.clone()),
|
||||
false => None,
|
||||
};
|
||||
server.add_delegate(EthcoreClient::new(
|
||||
server.add_delegate(ParityClient::new(
|
||||
&deps.client,
|
||||
&deps.miner,
|
||||
&deps.sync,
|
||||
&deps.net_service,
|
||||
&deps.secret_store,
|
||||
deps.logger.clone(),
|
||||
deps.settings.clone(),
|
||||
signer,
|
||||
deps.dapps_interface.clone(),
|
||||
deps.dapps_port,
|
||||
).to_delegate())
|
||||
).to_delegate());
|
||||
|
||||
add_signing_methods!(EthSigning, server, deps);
|
||||
add_signing_methods!(ParitySigning, server, deps);
|
||||
},
|
||||
Api::EthcoreSet => {
|
||||
server.add_delegate(EthcoreSetClient::new(&deps.client, &deps.miner, &deps.net_service).to_delegate())
|
||||
Api::ParityAccounts => {
|
||||
server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate());
|
||||
},
|
||||
Api::ParitySet => {
|
||||
server.add_delegate(ParitySetClient::new(&deps.client, &deps.miner, &deps.net_service).to_delegate())
|
||||
},
|
||||
Api::Traces => {
|
||||
server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate())
|
||||
@@ -233,11 +263,11 @@ mod test {
|
||||
assert_eq!(Api::Web3, "web3".parse().unwrap());
|
||||
assert_eq!(Api::Net, "net".parse().unwrap());
|
||||
assert_eq!(Api::Eth, "eth".parse().unwrap());
|
||||
assert_eq!(Api::PersonalAccounts, "personal".parse().unwrap());
|
||||
assert_eq!(Api::PersonalSafe, "personal_safe".parse().unwrap());
|
||||
assert_eq!(Api::Personal, "personal".parse().unwrap());
|
||||
assert_eq!(Api::Signer, "signer".parse().unwrap());
|
||||
assert_eq!(Api::Ethcore, "ethcore".parse().unwrap());
|
||||
assert_eq!(Api::EthcoreSet, "ethcore_set".parse().unwrap());
|
||||
assert_eq!(Api::Parity, "parity".parse().unwrap());
|
||||
assert_eq!(Api::ParityAccounts, "parity_accounts".parse().unwrap());
|
||||
assert_eq!(Api::ParitySet, "parity_set".parse().unwrap());
|
||||
assert_eq!(Api::Traces, "traces".parse().unwrap());
|
||||
assert_eq!(Api::Rpc, "rpc".parse().unwrap());
|
||||
assert!("rp".parse::<Api>().is_err());
|
||||
@@ -255,15 +285,34 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_api_set_unsafe_context() {
|
||||
let expected = vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc, Api::PersonalSafe]
|
||||
.into_iter().collect();
|
||||
let expected = vec![
|
||||
// make sure this list contains only SAFE methods
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc
|
||||
].into_iter().collect();
|
||||
assert_eq!(ApiSet::UnsafeContext.list_apis(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_api_set_ipc_context() {
|
||||
let expected = vec![
|
||||
// safe
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||
// semi-safe
|
||||
Api::ParityAccounts
|
||||
].into_iter().collect();
|
||||
assert_eq!(ApiSet::IpcContext.list_apis(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_api_set_safe_context() {
|
||||
let expected = vec![Api::Web3, Api::Net, Api::Eth, Api::PersonalAccounts, Api::PersonalSafe, Api::Signer, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc]
|
||||
.into_iter().collect();
|
||||
let expected = vec![
|
||||
// safe
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||
// semi-safe
|
||||
Api::ParityAccounts,
|
||||
// Unsafe
|
||||
Api::ParitySet, Api::Signer,
|
||||
].into_iter().collect();
|
||||
assert_eq!(ApiSet::SafeContext.list_apis(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::sync::{Arc, Mutex, Condvar};
|
||||
use std::net::{TcpListener};
|
||||
use ctrlc::CtrlC;
|
||||
use fdlimit::raise_fd_limit;
|
||||
use ethcore_logger::{Config as LogConfig, setup_log};
|
||||
use ethcore_rpc::{NetworkSettings, is_major_importing};
|
||||
use ethsync::NetworkConfiguration;
|
||||
use util::{Colour, version, U256};
|
||||
use util::{Colour, version, RotatingLogger};
|
||||
use io::{MayPanic, ForwardPanic, PanicHandler};
|
||||
use ethcore_logger::{Config as LogConfig};
|
||||
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, ChainNotify, BlockChainClient};
|
||||
use ethcore::service::ClientService;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
@@ -36,7 +37,7 @@ use dapps::WebappServer;
|
||||
use io_handler::ClientIoHandler;
|
||||
use params::{
|
||||
SpecType, Pruning, AccountsConfig, GasPricerConfig, MinerExtras, Switch,
|
||||
tracing_switch_to_bool, fatdb_switch_to_bool,
|
||||
tracing_switch_to_bool, fatdb_switch_to_bool, mode_switch_to_bool
|
||||
};
|
||||
use helpers::{to_client_config, execute_upgrades, passwords_from_files};
|
||||
use dir::Directories;
|
||||
@@ -69,20 +70,19 @@ pub struct RunCmd {
|
||||
pub http_conf: HttpConfiguration,
|
||||
pub ipc_conf: IpcConfiguration,
|
||||
pub net_conf: NetworkConfiguration,
|
||||
pub network_id: Option<U256>,
|
||||
pub network_id: Option<usize>,
|
||||
pub warp_sync: bool,
|
||||
pub acc_conf: AccountsConfig,
|
||||
pub gas_pricer: GasPricerConfig,
|
||||
pub miner_extras: MinerExtras,
|
||||
pub mode: Mode,
|
||||
pub mode: Option<Mode>,
|
||||
pub tracing: Switch,
|
||||
pub fat_db: Switch,
|
||||
pub compaction: DatabaseCompactionProfile,
|
||||
pub wal: bool,
|
||||
pub vm_type: VMType,
|
||||
pub enable_network: bool,
|
||||
pub geth_compatibility: bool,
|
||||
pub signer_port: Option<u16>,
|
||||
pub ui_address: Option<(String, u16)>,
|
||||
pub net_settings: NetworkSettings,
|
||||
pub dapps_conf: dapps::Configuration,
|
||||
pub signer_conf: signer::Configuration,
|
||||
@@ -93,13 +93,19 @@ pub struct RunCmd {
|
||||
pub check_seal: bool,
|
||||
}
|
||||
|
||||
pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
||||
if cmd.ui && cmd.dapps_conf.enabled {
|
||||
// Check if Parity is already running
|
||||
let addr = format!("{}:{}", cmd.dapps_conf.interface, cmd.dapps_conf.port);
|
||||
if !TcpListener::bind(&addr as &str).is_ok() {
|
||||
url::open(&format!("http://{}:{}/", cmd.dapps_conf.interface, cmd.dapps_conf.port));
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
// set up panic handler
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
|
||||
// set up logger
|
||||
let logger = try!(setup_log(&cmd.logger_config));
|
||||
|
||||
// increase max number of open files
|
||||
raise_fd_limit();
|
||||
|
||||
@@ -130,6 +136,11 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
// check if fatdb is on
|
||||
let fat_db = try!(fatdb_switch_to_bool(cmd.fat_db, &user_defaults, algorithm));
|
||||
|
||||
// get the mode
|
||||
let mode = try!(mode_switch_to_bool(cmd.mode, &user_defaults));
|
||||
trace!(target: "mode", "mode is {:?}", mode);
|
||||
let network_enabled = match &mode { &Mode::Dark(_) | &Mode::Off => false, _ => true, };
|
||||
|
||||
// prepare client and snapshot paths.
|
||||
let client_path = db_dirs.client_path(algorithm);
|
||||
let snapshot_path = db_dirs.snapshot_path();
|
||||
@@ -155,6 +166,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
false => "".to_owned(),
|
||||
}
|
||||
);
|
||||
info!("Operating mode: {}", Colour::White.bold().paint(format!("{}", mode)));
|
||||
|
||||
// display warning about using experimental journaldb alorithm
|
||||
if !algorithm.is_stable() {
|
||||
@@ -189,7 +201,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
// create client config
|
||||
let client_config = to_client_config(
|
||||
&cmd.cache_config,
|
||||
cmd.mode,
|
||||
mode,
|
||||
tracing,
|
||||
fat_db,
|
||||
cmd.compaction,
|
||||
@@ -241,7 +253,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
service.add_notify(chain_notify.clone());
|
||||
|
||||
// start network
|
||||
if cmd.enable_network {
|
||||
if network_enabled {
|
||||
chain_notify.start();
|
||||
}
|
||||
|
||||
@@ -250,7 +262,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies {
|
||||
signer_service: Arc::new(rpc_apis::SignerService::new(move || {
|
||||
signer::generate_new_token(signer_path.clone()).map_err(|e| format!("{:?}", e))
|
||||
}, cmd.signer_port)),
|
||||
}, cmd.ui_address)),
|
||||
snapshot: snapshot_service.clone(),
|
||||
client: client.clone(),
|
||||
sync: sync_provider.clone(),
|
||||
@@ -262,6 +274,10 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
settings: Arc::new(cmd.net_settings.clone()),
|
||||
net_service: manage_network.clone(),
|
||||
geth_compatibility: cmd.geth_compatibility,
|
||||
dapps_interface: match cmd.dapps_conf.enabled {
|
||||
true => Some(cmd.dapps_conf.interface.clone()),
|
||||
false => None,
|
||||
},
|
||||
dapps_port: match cmd.dapps_conf.enabled {
|
||||
true => Some(cmd.dapps_conf.port),
|
||||
false => None,
|
||||
@@ -314,6 +330,19 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
});
|
||||
service.register_io_handler(io_handler.clone()).expect("Error registering IO handler");
|
||||
|
||||
// save user defaults
|
||||
user_defaults.pruning = algorithm;
|
||||
user_defaults.tracing = tracing;
|
||||
try!(user_defaults.save(&user_defaults_path));
|
||||
|
||||
let on_mode_change = move |mode: &Mode| {
|
||||
user_defaults.mode = mode.clone();
|
||||
let _ = user_defaults.save(&user_defaults_path); // discard failures - there's nothing we can do
|
||||
};
|
||||
|
||||
// tell client how to save the default mode if it gets changed.
|
||||
client.on_mode_change(on_mode_change);
|
||||
|
||||
// the watcher must be kept alive.
|
||||
let _watcher = match cmd.no_periodic_snapshot {
|
||||
true => None,
|
||||
@@ -340,11 +369,6 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
url::open(&format!("http://{}:{}/", cmd.dapps_conf.interface, cmd.dapps_conf.port));
|
||||
}
|
||||
|
||||
// save user defaults
|
||||
user_defaults.pruning = algorithm;
|
||||
user_defaults.tracing = tracing;
|
||||
try!(user_defaults.save(&user_defaults_path));
|
||||
|
||||
// Handle exit
|
||||
wait_for_exit(panic_handler, http_server, ipc_server, dapps_server, signer_server);
|
||||
|
||||
|
||||
@@ -68,8 +68,13 @@ fn codes_path(path: String) -> PathBuf {
|
||||
p
|
||||
}
|
||||
|
||||
pub fn new_token(path: String) -> Result<String, String> {
|
||||
generate_new_token(path)
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct SignerCommand {
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
pub fn execute(cmd: SignerCommand) -> Result<String, String> {
|
||||
generate_new_token(cmd.path)
|
||||
.map(|code| format!("This key code will authorise your System Signer UI: {}", Colour::White.bold().paint(code)))
|
||||
.map_err(|err| format!("Error generating token: {:?}", err))
|
||||
}
|
||||
@@ -104,7 +109,7 @@ fn do_start(conf: Configuration, deps: Dependencies) -> Result<SignerServer, Str
|
||||
|
||||
match start_result {
|
||||
Err(signer::ServerError::IoError(err)) => match err.kind() {
|
||||
io::ErrorKind::AddrInUse => Err(format!("Trusted Signer address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --signer-port and --signer-interface options.", addr)),
|
||||
io::ErrorKind::AddrInUse => Err(format!("Trusted UI address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --ui-port and --ui-interface options.", addr)),
|
||||
_ => Err(format!("Trusted Signer io error: {}", err)),
|
||||
},
|
||||
Err(e) => Err(format!("Trusted Signer Error: {:?}", e)),
|
||||
|
||||
@@ -20,7 +20,6 @@ use std::time::Duration;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ethcore_logger::{setup_log, Config as LogConfig};
|
||||
use ethcore::snapshot::{Progress, RestorationStatus, SnapshotService as SS};
|
||||
use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter};
|
||||
use ethcore::snapshot::service::Service as SnapshotService;
|
||||
@@ -55,8 +54,6 @@ pub struct SnapshotCommand {
|
||||
pub spec: SpecType,
|
||||
pub pruning: Pruning,
|
||||
pub pruning_history: u64,
|
||||
pub logger_config: LogConfig,
|
||||
pub mode: Mode,
|
||||
pub tracing: Switch,
|
||||
pub fat_db: Switch,
|
||||
pub compaction: DatabaseCompactionProfile,
|
||||
@@ -69,6 +66,8 @@ pub struct SnapshotCommand {
|
||||
// helper for reading chunks from arbitrary reader and feeding them into the
|
||||
// service.
|
||||
fn restore_using<R: SnapshotReader>(snapshot: Arc<SnapshotService>, reader: &R, recover: bool) -> Result<(), String> {
|
||||
use util::sha3::Hashable;
|
||||
|
||||
let manifest = reader.manifest();
|
||||
|
||||
info!("Restoring to block #{} (0x{:?})", manifest.block_number, manifest.block_hash);
|
||||
@@ -96,6 +95,12 @@ fn restore_using<R: SnapshotReader>(snapshot: Arc<SnapshotService>, reader: &R,
|
||||
|
||||
let chunk = try!(reader.chunk(state_hash)
|
||||
.map_err(|e| format!("Encountered error while reading chunk {:?}: {}", state_hash, e)));
|
||||
|
||||
let hash = chunk.sha3();
|
||||
if hash != state_hash {
|
||||
return Err(format!("Mismatched chunk hash. Expected {:?}, got {:?}", state_hash, hash));
|
||||
}
|
||||
|
||||
snapshot.feed_state_chunk(state_hash, &chunk);
|
||||
}
|
||||
|
||||
@@ -107,6 +112,11 @@ fn restore_using<R: SnapshotReader>(snapshot: Arc<SnapshotService>, reader: &R,
|
||||
|
||||
let chunk = try!(reader.chunk(block_hash)
|
||||
.map_err(|e| format!("Encountered error while reading chunk {:?}: {}", block_hash, e)));
|
||||
|
||||
let hash = chunk.sha3();
|
||||
if hash != block_hash {
|
||||
return Err(format!("Mismatched chunk hash. Expected {:?}, got {:?}", block_hash, hash));
|
||||
}
|
||||
snapshot.feed_block_chunk(block_hash, &chunk);
|
||||
}
|
||||
|
||||
@@ -141,9 +151,6 @@ impl SnapshotCommand {
|
||||
// load user defaults
|
||||
let user_defaults = try!(UserDefaults::load(&user_defaults_path));
|
||||
|
||||
// Setup logging
|
||||
let _logger = setup_log(&self.logger_config);
|
||||
|
||||
fdlimit::raise_fd_limit();
|
||||
|
||||
// select pruning algorithm
|
||||
@@ -163,7 +170,7 @@ impl SnapshotCommand {
|
||||
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.fork_path().as_path())));
|
||||
|
||||
// prepare client config
|
||||
let client_config = to_client_config(&self.cache_config, self.mode, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
|
||||
let client_config = to_client_config(&self.cache_config, Mode::Active, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
|
||||
|
||||
let service = try!(ClientService::start(
|
||||
client_config,
|
||||
|
||||
@@ -18,6 +18,7 @@ use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::collections::BTreeMap;
|
||||
use std::time::Duration;
|
||||
use serde::{Serialize, Serializer, Error, Deserialize, Deserializer};
|
||||
use serde::de::{Visitor, MapVisitor};
|
||||
use serde::de::impls::BTreeMapVisitor;
|
||||
@@ -25,12 +26,14 @@ use serde_json::Value;
|
||||
use serde_json::de::from_reader;
|
||||
use serde_json::ser::to_string;
|
||||
use util::journaldb::Algorithm;
|
||||
use ethcore::client::Mode;
|
||||
|
||||
pub struct UserDefaults {
|
||||
pub is_first_launch: bool,
|
||||
pub pruning: Algorithm,
|
||||
pub tracing: bool,
|
||||
pub fat_db: bool,
|
||||
pub mode: Mode,
|
||||
}
|
||||
|
||||
impl Serialize for UserDefaults {
|
||||
@@ -40,6 +43,21 @@ impl Serialize for UserDefaults {
|
||||
map.insert("pruning".into(), Value::String(self.pruning.as_str().into()));
|
||||
map.insert("tracing".into(), Value::Bool(self.tracing));
|
||||
map.insert("fat_db".into(), Value::Bool(self.fat_db));
|
||||
let mode_str = match self.mode {
|
||||
Mode::Off => "offline",
|
||||
Mode::Dark(timeout) => {
|
||||
map.insert("mode.timeout".into(), Value::U64(timeout.as_secs()));
|
||||
"dark"
|
||||
},
|
||||
Mode::Passive(timeout, alarm) => {
|
||||
map.insert("mode.timeout".into(), Value::U64(timeout.as_secs()));
|
||||
map.insert("mode.alarm".into(), Value::U64(alarm.as_secs()));
|
||||
"passive"
|
||||
},
|
||||
Mode::Active => "active",
|
||||
};
|
||||
map.insert("mode".into(), Value::String(mode_str.into()));
|
||||
|
||||
map.serialize(serializer)
|
||||
}
|
||||
}
|
||||
@@ -67,11 +85,28 @@ impl Visitor for UserDefaultsVisitor {
|
||||
let fat_db: Value = map.remove("fat_db".into()).unwrap_or_else(|| Value::Bool(false));
|
||||
let fat_db = try!(fat_db.as_bool().ok_or_else(|| Error::custom("invalid fat_db value")));
|
||||
|
||||
let mode: Value = map.remove("mode".into()).unwrap_or_else(|| Value::String("active".to_owned()));
|
||||
let mode = match try!(mode.as_str().ok_or_else(|| Error::custom("invalid mode value"))) {
|
||||
"offline" => Mode::Off,
|
||||
"dark" => {
|
||||
let timeout = try!(map.remove("mode.timeout".into()).and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value")));
|
||||
Mode::Dark(Duration::from_secs(timeout))
|
||||
},
|
||||
"passive" => {
|
||||
let timeout = try!(map.remove("mode.timeout".into()).and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.timeout value")));
|
||||
let alarm = try!(map.remove("mode.alarm".into()).and_then(|v| v.as_u64()).ok_or_else(|| Error::custom("invalid/missing mode.alarm value")));
|
||||
Mode::Passive(Duration::from_secs(timeout), Duration::from_secs(alarm))
|
||||
},
|
||||
"active" => Mode::Active,
|
||||
_ => { return Err(Error::custom("invalid mode value")); },
|
||||
};
|
||||
|
||||
let user_defaults = UserDefaults {
|
||||
is_first_launch: false,
|
||||
pruning: pruning,
|
||||
tracing: tracing,
|
||||
fat_db: fat_db,
|
||||
mode: mode,
|
||||
};
|
||||
|
||||
Ok(user_defaults)
|
||||
@@ -85,6 +120,7 @@ impl Default for UserDefaults {
|
||||
pruning: Algorithm::default(),
|
||||
tracing: false,
|
||||
fat_db: false,
|
||||
mode: Mode::Active,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,7 +133,7 @@ impl UserDefaults {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save<P>(self, path: P) -> Result<(), String> where P: AsRef<Path> {
|
||||
pub fn save<P>(&self, path: P) -> Result<(), String> where P: AsRef<Path> {
|
||||
let mut file: File = try!(File::create(path).map_err(|_| "Cannot create user defaults file".to_owned()));
|
||||
file.write_all(to_string(&self).unwrap().as_bytes()).map_err(|_| "Failed to save user defaults".to_owned())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user