Merge branch 'master' into secretstore_stresstest

This commit is contained in:
Svyatoslav Nikolsky
2017-08-09 12:29:09 +03:00
336 changed files with 22036 additions and 2436 deletions

View File

@@ -93,6 +93,7 @@ pub struct ImportBlockchain {
pub check_seal: bool,
pub with_color: bool,
pub verifier_settings: VerifierSettings,
pub light: bool,
}
#[derive(Debug, PartialEq)]
@@ -138,12 +139,165 @@ pub struct ExportState {
pub fn execute(cmd: BlockchainCmd) -> Result<(), String> {
match cmd {
BlockchainCmd::Kill(kill_cmd) => kill_db(kill_cmd),
BlockchainCmd::Import(import_cmd) => execute_import(import_cmd),
BlockchainCmd::Import(import_cmd) => {
if import_cmd.light {
execute_import_light(import_cmd)
} else {
execute_import(import_cmd)
}
}
BlockchainCmd::Export(export_cmd) => execute_export(export_cmd),
BlockchainCmd::ExportState(export_cmd) => execute_export_state(export_cmd),
}
}
fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> {
use light::client::{Service as LightClientService, Config as LightClientConfig};
use light::cache::Cache as LightDataCache;
let timer = Instant::now();
// load spec file
let spec = cmd.spec.spec(&cmd.dirs.cache)?;
// load genesis hash
let genesis_hash = spec.genesis_header().hash();
// database paths
let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir.clone());
// user defaults path
let user_defaults_path = db_dirs.user_defaults_path();
// load user defaults
let user_defaults = UserDefaults::load(&user_defaults_path)?;
fdlimit::raise_fd_limit();
// select pruning algorithm
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
// prepare client and snapshot paths.
let client_path = db_dirs.client_path(algorithm);
// execute upgrades
let compaction = cmd.compaction.compaction_profile(db_dirs.db_root_path().as_path());
execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, compaction)?;
// create dirs used by parity
cmd.dirs.create_dirs(false, false, false)?;
let cache = Arc::new(::util::Mutex::new(
LightDataCache::new(Default::default(), ::time::Duration::seconds(0))
));
let mut config = LightClientConfig {
queue: Default::default(),
chain_column: ::ethcore::db::COL_LIGHT_CHAIN,
db_cache_size: Some(cmd.cache_config.blockchain() as usize * 1024 * 1024),
db_compaction: compaction,
db_wal: cmd.wal,
verify_full: true,
check_seal: cmd.check_seal,
};
config.queue.max_mem_use = cmd.cache_config.queue() as usize * 1024 * 1024;
config.queue.verifier_settings = cmd.verifier_settings;
let service = LightClientService::start(config, &spec, &client_path, cache)
.map_err(|e| format!("Failed to start client: {}", e))?;
// free up the spec in memory.
drop(spec);
let client = service.client();
let mut instream: Box<io::Read> = match cmd.file_path {
Some(f) => Box::new(fs::File::open(&f).map_err(|_| format!("Cannot open given file: {}", f))?),
None => Box::new(io::stdin()),
};
const READAHEAD_BYTES: usize = 8;
let mut first_bytes: Vec<u8> = vec![0; READAHEAD_BYTES];
let mut first_read = 0;
let format = match cmd.format {
Some(format) => format,
None => {
first_read = instream.read(&mut first_bytes).map_err(|_| "Error reading from the file/stream.")?;
match first_bytes[0] {
0xf9 => DataFormat::Binary,
_ => DataFormat::Hex,
}
}
};
let do_import = |bytes: Vec<u8>| {
while client.queue_info().is_full() { sleep(Duration::from_secs(1)); }
let header: ::ethcore::header::Header = ::rlp::UntrustedRlp::new(&bytes).val_at(0)
.map_err(|e| format!("Bad block: {}", e))?;
if client.best_block_header().number() >= header.number() { return Ok(()) }
if header.number() % 10000 == 0 {
info!("#{}", header.number());
}
match client.import_header(header) {
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => {
trace!("Skipping block already in chain.");
}
Err(e) => {
return Err(format!("Cannot import block: {:?}", e));
},
Ok(_) => {},
}
Ok(())
};
match format {
DataFormat::Binary => {
loop {
let mut bytes = if first_read > 0 {first_bytes.clone()} else {vec![0; READAHEAD_BYTES]};
let n = if first_read > 0 {
first_read
} else {
instream.read(&mut bytes).map_err(|_| "Error reading from the file/stream.")?
};
if n == 0 { break; }
first_read = 0;
let s = PayloadInfo::from(&bytes).map_err(|e| format!("Invalid RLP in the file/stream: {:?}", e))?.total();
bytes.resize(s, 0);
instream.read_exact(&mut bytes[n..]).map_err(|_| "Error reading from the file/stream.")?;
do_import(bytes)?;
}
}
DataFormat::Hex => {
for line in BufReader::new(instream).lines() {
let s = line.map_err(|_| "Error reading from the file/stream.")?;
let s = if first_read > 0 {from_utf8(&first_bytes).unwrap().to_owned() + &(s[..])} else {s};
first_read = 0;
let bytes = s.from_hex().map_err(|_| "Invalid hex in file/stream.")?;
do_import(bytes)?;
}
}
}
client.flush_queue();
let ms = timer.elapsed().as_milliseconds();
let report = client.report();
info!("Import completed in {} seconds, {} headers, {} hdr/s",
ms / 1000,
report.blocks_imported,
(report.blocks_imported * 1000) as u64 / ms,
);
Ok(())
}
fn execute_import(cmd: ImportBlockchain) -> Result<(), String> {
let timer = Instant::now();
@@ -531,10 +685,12 @@ pub fn kill_db(cmd: KillBlockchain) -> Result<(), String> {
let genesis_hash = spec.genesis_header().hash();
let db_dirs = cmd.dirs.database(genesis_hash, None, spec.data_dir);
let user_defaults_path = db_dirs.user_defaults_path();
let user_defaults = UserDefaults::load(&user_defaults_path)?;
let mut user_defaults = UserDefaults::load(&user_defaults_path)?;
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
let dir = db_dirs.db_path(algorithm);
fs::remove_dir_all(&dir).map_err(|e| format!("Error removing database: {:?}", e))?;
user_defaults.is_first_launch = true;
user_defaults.save(&user_defaults_path)?;
info!("Database deleted.");
Ok(())
}

View File

@@ -103,6 +103,7 @@ reseal_min_period = 4000
reseal_max_period = 60000
work_queue_size = 20
relay_set = "cheap"
min_gas_price = 0
usd_per_tx = "0.0025"
usd_per_eth = "auto"
price_update_period = "hourly"
@@ -146,3 +147,7 @@ jit = false
logging = "own_tx=trace"
log_file = "/var/log/parity.log"
color = true
[whisper]
enabled = false
pool_size = 20

View File

@@ -78,9 +78,13 @@ disable_periodic = true
jit = false
[misc]
ntp_server = "pool.ntp.org:123"
ntp_servers = ["0.parity.pool.ntp.org:123"]
logging = "own_tx=trace"
log_file = "/var/log/parity.log"
color = true
ports_shift = 0
unsafe_expose = false
[whisper]
enabled = true
pool_size = 50

View File

@@ -16,6 +16,7 @@
#[macro_use]
mod usage;
mod presets;
use dir;
usage! {
@@ -176,7 +177,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,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore",
flag_jsonrpc_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore,shh,shh_pubsub",
or |c: &Config| otry!(c.rpc).apis.as_ref().map(|vec| vec.join(",")),
flag_jsonrpc_hosts: String = "none",
or |c: &Config| otry!(c.rpc).hosts.as_ref().map(|vec| vec.join(",")),
@@ -192,7 +193,7 @@ usage! {
or |c: &Config| otry!(c.websockets).port.clone(),
flag_ws_interface: String = "local",
or |c: &Config| otry!(c.websockets).interface.clone(),
flag_ws_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore",
flag_ws_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,traces,rpc,secretstore,shh,shh_pubsub",
or |c: &Config| otry!(c.websockets).apis.as_ref().map(|vec| vec.join(",")),
flag_ws_origins: String = "chrome-extension://*",
or |c: &Config| otry!(c.websockets).origins.as_ref().map(|vec| vec.join(",")),
@@ -204,7 +205,7 @@ usage! {
or |c: &Config| otry!(c.ipc).disable.clone(),
flag_ipc_path: String = if cfg!(windows) { r"\\.\pipe\jsonrpc.ipc" } else { "$BASE/jsonrpc.ipc" },
or |c: &Config| otry!(c.ipc).path.clone(),
flag_ipc_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces,rpc,secretstore",
flag_ipc_apis: String = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces,rpc,secretstore,shh,shh_pubsub",
or |c: &Config| otry!(c.ipc).apis.as_ref().map(|vec| vec.join(",")),
// DAPPS
@@ -270,6 +271,8 @@ usage! {
or |c: &Config| otry!(c.mining).tx_time_limit.clone().map(Some),
flag_relay_set: String = "cheap",
or |c: &Config| otry!(c.mining).relay_set.clone(),
flag_min_gas_price: Option<u64> = None,
or |c: &Config| otry!(c.mining).min_gas_price.clone().map(Some),
flag_usd_per_tx: String = "0.0025",
or |c: &Config| otry!(c.mining).usd_per_tx.clone(),
flag_usd_per_eth: String = "auto",
@@ -360,8 +363,8 @@ usage! {
or |c: &Config| otry!(c.vm).jit.clone(),
// -- Miscellaneous Options
flag_ntp_server: String = "pool.ntp.org:123",
or |c: &Config| otry!(c.misc).ntp_server.clone(),
flag_ntp_servers: String = "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123",
or |c: &Config| otry!(c.misc).ntp_servers.clone().map(|vec| vec.join(",")),
flag_logging: Option<String> = None,
or |c: &Config| otry!(c.misc).logging.clone().map(Some),
flag_log_file: Option<String> = None,
@@ -369,6 +372,12 @@ usage! {
flag_no_color: bool = false,
or |c: &Config| otry!(c.misc).color.map(|c| !c).clone(),
// -- Whisper options
flag_whisper: bool = false,
or |c: &Config| otry!(c.whisper).enabled,
flag_whisper_pool_size: usize = 10usize,
or |c: &Config| otry!(c.whisper).pool_size.clone(),
// -- Legacy Options supported in configs
flag_dapps_port: Option<u16> = None,
or |c: &Config| otry!(c.dapps).port.clone().map(Some),
@@ -411,6 +420,7 @@ struct Config {
vm: Option<VM>,
misc: Option<Misc>,
stratum: Option<Stratum>,
whisper: Option<Whisper>,
}
#[derive(Default, Debug, PartialEq, Deserialize)]
@@ -547,6 +557,7 @@ struct Mining {
tx_gas_limit: Option<String>,
tx_time_limit: Option<u64>,
relay_set: Option<String>,
min_gas_price: Option<u64>,
usd_per_tx: Option<String>,
usd_per_eth: Option<String>,
price_update_period: Option<String>,
@@ -601,7 +612,7 @@ struct VM {
#[derive(Default, Debug, PartialEq, Deserialize)]
struct Misc {
ntp_server: Option<String>,
ntp_servers: Option<Vec<String>>,
logging: Option<String>,
log_file: Option<String>,
color: Option<bool>,
@@ -609,12 +620,18 @@ struct Misc {
unsafe_expose: Option<bool>,
}
#[derive(Default, Debug, PartialEq, Deserialize)]
struct Whisper {
enabled: Option<bool>,
pool_size: Option<usize>,
}
#[cfg(test)]
mod tests {
use super::{
Args, ArgsError,
Config, Operating, Account, Ui, Network, Ws, Rpc, Ipc, Dapps, Ipfs, Mining, Footprint,
Snapshots, VM, Misc, SecretStore,
Snapshots, VM, Misc, Whisper, SecretStore,
};
use toml;
@@ -814,6 +831,7 @@ mod tests {
flag_tx_gas_limit: Some("6283184".into()),
flag_tx_time_limit: Some(100u64),
flag_relay_set: "cheap".into(),
flag_min_gas_price: Some(0u64),
flag_usd_per_tx: "0.0025".into(),
flag_usd_per_eth: "auto".into(),
flag_price_update_period: "hourly".into(),
@@ -868,6 +886,10 @@ mod tests {
// -- Virtual Machine Options
flag_jitvm: false,
// -- Whisper options.
flag_whisper: false,
flag_whisper_pool_size: 20,
// -- Legacy Options
flag_geth: false,
flag_testnet: false,
@@ -905,7 +927,7 @@ mod tests {
flag_dapps_apis_all: None,
// -- Miscellaneous Options
flag_ntp_server: "pool.ntp.org:123".into(),
flag_ntp_servers: "0.parity.pool.ntp.org:123,1.parity.pool.ntp.org:123,2.parity.pool.ntp.org:123,3.parity.pool.ntp.org:123".into(),
flag_version: false,
flag_logging: Some("own_tx=trace".into()),
flag_log_file: Some("/var/log/parity.log".into()),
@@ -1044,6 +1066,7 @@ mod tests {
reseal_max_period: Some(60000),
work_queue_size: None,
relay_set: None,
min_gas_price: None,
usd_per_tx: None,
usd_per_eth: None,
price_update_period: Some("hourly".into()),
@@ -1085,13 +1108,17 @@ mod tests {
jit: Some(false),
}),
misc: Some(Misc {
ntp_server: Some("pool.ntp.org:123".into()),
ntp_servers: Some(vec!["0.parity.pool.ntp.org:123".into()]),
logging: Some("own_tx=trace".into()),
log_file: Some("/var/log/parity.log".into()),
color: Some(true),
ports_shift: Some(0),
unsafe_expose: Some(false),
}),
whisper: Some(Whisper {
enabled: Some(true),
pool_size: Some(50),
}),
stratum: None,
});
}

View File

@@ -0,0 +1,16 @@
[parity]
no_consensus = true
chain = "dev"
[mining]
reseal_min_period = 0
min_gas_price = 0
[rpc]
interface = "all"
apis = ["all"]
hosts = ["all"]
[ipfs]
enable = false # this is the default
hosts = ["all"]

View File

@@ -0,0 +1,6 @@
[parity]
chain = "dev"
[mining]
reseal_min_period = 0
min_gas_price = 0

View File

@@ -0,0 +1,11 @@
[parity]
no_consensus = true
[rpc]
interface = "all"
apis = ["all"]
hosts = ["all"]
[ipfs]
enable = false # this is the default
hosts = ["all"]

View File

@@ -0,0 +1,31 @@
[network]
# Parity will try to maintain connection to at least 50 peers.
min_peers = 50
# Parity will maintain at most 100 peers.
max_peers = 100
[ipc]
# You won't be able to use IPC to interact with Parity.
disable = true
[dapps]
# You won't be able to access any web Dapps.
disable = true
[mining]
# Prepare a block to seal even when there are no miners connected.
force_sealing = true
# New pending block will be created for all transactions (both local and external).
reseal_on_txs = "all"
# New pending block will be created only once per 4000 milliseconds.
reseal_min_period = 4000
# Parity will keep/relay at most 2048 transactions in queue.
tx_queue_size = 2048
[footprint]
# If defined will never use more then 256MB for all caches. (Overrides other cache settings).
cache_size = 256
[misc]
# Logging pattern (`<module>=<level>`, e.g. `own_tx=trace`).
logging = "miner=trace,own_tx=trace"

View File

@@ -0,0 +1,7 @@
[network]
# Parity will listen for connections on port 30305.
port = 30305
[rpc]
# JSON-RPC over HTTP will be accessible on port 8645.
port = 8645

28
parity/cli/presets/mod.rs Normal file
View File

@@ -0,0 +1,28 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::io::{Error, ErrorKind};
pub fn preset_config_string(arg: &str) -> Result<&'static str, Error> {
match arg.to_lowercase().as_ref() {
"dev" => Ok(include_str!("./config.dev.toml")),
"mining" => Ok(include_str!("./config.mining.toml")),
"non-standard-ports" => Ok(include_str!("./config.non-standard-ports.toml")),
"insecure" => Ok(include_str!("./config.insecure.toml")),
"dev-insecure" => Ok(include_str!("./config.dev-insecure.toml")),
_ => Err(Error::new(ErrorKind::InvalidInput, "Config doesn't match any presets [dev, mining, non-standard-ports, insecure, dev-insecure]"))
}
}

View File

@@ -151,23 +151,24 @@ macro_rules! usage {
let config_file = raw_args.flag_config.clone().unwrap_or_else(|| raw_args.clone().into_args(Config::default()).flag_config);
let config_file = replace_home(&::dir::default_data_path(), &config_file);
let config = match (fs::File::open(&config_file), raw_args.flag_config.is_some()) {
match (fs::File::open(&config_file), raw_args.flag_config.clone()) {
// Load config file
(Ok(mut file), _) => {
println_stderr!("Loading config file from {}", &config_file);
let mut config = String::new();
file.read_to_string(&mut config).map_err(|e| ArgsError::Config(config_file, e))?;
Self::parse_config(&config)?
Ok(raw_args.into_args(Self::parse_config(&config)?))
},
// Don't display error in case default config cannot be loaded.
(Err(_), false) => Config::default(),
(Err(_), None) => Ok(raw_args.into_args(Config::default())),
// Config set from CLI (fail with error)
(Err(e), true) => {
return Err(ArgsError::Config(config_file, e));
(Err(_), Some(ref config_arg)) => {
match presets::preset_config_string(config_arg) {
Ok(s) => Ok(raw_args.into_args(Self::parse_config(&s)?)),
Err(e) => Err(ArgsError::Config(config_file, e))
}
},
};
Ok(raw_args.into_args(config))
}
}
#[cfg(test)]

View File

@@ -77,8 +77,10 @@ Operating Options:
subcommands (default: {flag_light}).
Convenience Options:
-c --config CONFIG Specify a filename containing a configuration file.
(default: {flag_config})
-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})
@@ -146,11 +148,15 @@ Networking Options:
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. Must be one of:
--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.
(default: {flag_allow_ips})
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})
@@ -296,6 +302,10 @@ Sealing/Mining Options:
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.
@@ -427,6 +437,11 @@ Snapshot Options:
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
@@ -461,9 +476,7 @@ Legacy Options:
--ipc-off Equivalent to --no-ipc.
--ipcapi APIS Equivalent to --ipc-apis APIS.
--ipcpath PATH Equivalent to --ipc-path PATH.
--gasprice WEI Minimum amount of Wei per GAS to be paid for a
transaction to be accepted for mining. Overrides
--basic-tx-usd.
--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.
@@ -472,8 +485,10 @@ Internal Options:
--can-restart Executable will auto-restart if exiting with 69.
Miscellaneous Options:
--ntp-server HOST NTP server to provide current time (host:port). Used to verify node health.
(default: {flag_ntp_server})
--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

View File

@@ -24,7 +24,7 @@ use cli::{Args, ArgsError};
use util::{Hashable, H256, U256, Bytes, version_data, Address};
use util::journaldb::Algorithm;
use util::Colour;
use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP};
use ethsync::{NetworkConfiguration, is_valid_node_url};
use ethcore::ethstore::ethkey::{Secret, Public};
use ethcore::client::{VMType};
use ethcore::miner::{MinerOptions, Banning, StratumOptions};
@@ -36,7 +36,7 @@ use parity_rpc::NetworkSettings;
use cache::CacheConfig;
use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_and_local,
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy};
use params::{SpecType, ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, Pruning, Switch};
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, Pruning, Switch};
use ethcore_logger::Config as LogConfig;
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
use dapps::Configuration as DappsConfiguration;
@@ -48,6 +48,7 @@ use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockcha
use presale::ImportWallet;
use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts};
use snapshot::{self, SnapshotCommand};
use network::{IpFilter};
#[derive(Debug, PartialEq)]
pub enum Cmd {
@@ -56,7 +57,7 @@ pub enum Cmd {
Account(AccountCmd),
ImportPresaleWallet(ImportWallet),
Blockchain(BlockchainCmd),
SignerToken(WsConfiguration, UiConfiguration),
SignerToken(WsConfiguration, UiConfiguration, LogConfig),
SignerSign {
id: Option<usize>,
pwfile: Option<PathBuf>,
@@ -148,7 +149,7 @@ impl Configuration {
let authfile = ::signer::codes_path(&ws_conf.signer_path);
if self.args.cmd_new_token {
Cmd::SignerToken(ws_conf, ui_conf)
Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone())
} else if self.args.cmd_sign {
let pwfile = self.args.flag_password.get(0).map(|pwfile| {
PathBuf::from(pwfile)
@@ -243,6 +244,7 @@ impl Configuration {
check_seal: !self.args.flag_no_seal_check,
with_color: logger_config.color,
verifier_settings: self.verifier_settings(),
light: self.args.flag_light,
};
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
} else if self.args.cmd_export {
@@ -331,12 +333,7 @@ impl Configuration {
};
let verifier_settings = self.verifier_settings();
// Special presets are present for the dev chain.
let (gas_pricer, miner_options) = match spec {
SpecType::Dev => (GasPricerConfig::Fixed(0.into()), self.miner_options(0)?),
_ => (self.gas_pricer_config()?, self.miner_options(self.args.flag_reseal_min_period)?),
};
let whisper_config = self.whisper_config();
let run_cmd = RunCmd {
cache_config: cache_config,
@@ -347,14 +344,14 @@ impl Configuration {
pruning_memory: self.args.flag_pruning_memory,
daemon: daemon,
logger_config: logger_config.clone(),
miner_options: miner_options,
miner_options: self.miner_options(self.args.flag_reseal_min_period)?,
ws_conf: ws_conf,
http_conf: http_conf,
ipc_conf: ipc_conf,
net_conf: net_conf,
network_id: network_id,
acc_conf: self.accounts_config()?,
gas_pricer: gas_pricer,
gas_pricer_conf: self.gas_pricer_config()?,
miner_extras: self.miner_extras()?,
stratum: self.stratum_options()?,
update_policy: update_policy,
@@ -383,6 +380,7 @@ impl Configuration {
serve_light: !self.args.flag_no_serve_light,
light: self.args.flag_light,
no_persistent_txqueue: self.args.flag_no_persistent_txqueue,
whisper: whisper_config,
};
Cmd::Run(run_cmd)
};
@@ -464,12 +462,10 @@ impl Configuration {
max(self.min_peers(), peers)
}
fn allow_ips(&self) -> Result<AllowIP, String> {
match self.args.flag_allow_ips.as_str() {
"all" => Ok(AllowIP::All),
"public" => Ok(AllowIP::Public),
"private" => Ok(AllowIP::Private),
_ => Err("Invalid IP filter value".to_owned()),
fn ip_filter(&self) -> Result<IpFilter, String> {
match IpFilter::parse(self.args.flag_allow_ips.as_str()) {
Ok(allow_ip) => Ok(allow_ip),
Err(_) => Err("Invalid IP filter value".to_owned()),
}
}
@@ -555,10 +551,14 @@ impl Configuration {
Ok(options)
}
fn ntp_servers(&self) -> Vec<String> {
self.args.flag_ntp_servers.split(",").map(str::to_owned).collect()
}
fn ui_config(&self) -> UiConfiguration {
UiConfiguration {
enabled: self.ui_enabled(),
ntp_server: self.args.flag_ntp_server.clone(),
ntp_servers: self.ntp_servers(),
interface: self.ui_interface(),
port: self.args.flag_ports_shift + self.args.flag_ui_port,
hosts: self.ui_hosts(),
@@ -568,7 +568,7 @@ impl Configuration {
fn dapps_config(&self) -> DappsConfiguration {
DappsConfiguration {
enabled: self.dapps_enabled(),
ntp_server: self.args.flag_ntp_server.clone(),
ntp_servers: self.ntp_servers(),
dapps_path: PathBuf::from(self.directories().dapps),
extra_dapps: if self.args.cmd_dapp {
self.args.arg_path.iter().map(|path| PathBuf::from(path)).collect()
@@ -629,8 +629,10 @@ impl Configuration {
U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap()
}
if let Some(d) = self.args.flag_gasprice.as_ref() {
return Ok(GasPricerConfig::Fixed(to_u256(d)?));
if let Some(dec) = self.args.flag_gasprice.as_ref() {
return Ok(GasPricerConfig::Fixed(to_u256(dec)?));
} else if let Some(dec) = self.args.flag_min_gas_price {
return Ok(GasPricerConfig::Fixed(U256::from(dec)));
}
let usd_per_tx = to_price(&self.args.flag_usd_per_tx)?;
@@ -715,7 +717,7 @@ impl Configuration {
ret.max_peers = self.max_peers();
ret.min_peers = self.min_peers();
ret.snapshot_peers = self.snapshot_peers();
ret.allow_ips = self.allow_ips()?;
ret.ip_filter = self.ip_filter()?;
ret.max_pending_peers = self.max_pending_peers();
let mut net_path = PathBuf::from(self.directories().base);
net_path.push("network");
@@ -909,13 +911,10 @@ impl Configuration {
} else {
self.args.flag_db_path.as_ref().map_or(dir::CHAINS_PATH, |s| &s)
};
let cache_path = if is_using_base_path {
"$BASE/cache".into()
} else {
replace_home_and_local(&data_path, &local_path, &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 cache_path = replace_home_and_local(&data_path, &local_path, cache_path);
let keys_path = replace_home(&data_path, &self.args.flag_keys_path);
let dapps_path = replace_home(&data_path, &self.args.flag_dapps_path);
let secretstore_path = replace_home(&data_path, &self.args.flag_secretstore_path);
@@ -971,7 +970,6 @@ impl Configuration {
}.into()
}
fn ui_interface(&self) -> String {
self.interface(&self.args.flag_ui_interface)
}
@@ -1081,12 +1079,20 @@ impl Configuration {
settings
}
fn whisper_config(&self) -> ::whisper::Config {
::whisper::Config {
enabled: self.args.flag_whisper,
target_message_pool_size: self.args.flag_whisper_pool_size * 1024 * 1024,
}
}
}
#[cfg(test)]
mod tests {
use std::io::Write;
use std::fs::{File, create_dir};
use std::str::FromStr;
use devtools::{RandomTempPath};
use ethcore::client::{VMType, BlockId};
@@ -1104,6 +1110,11 @@ mod tests {
use rpc::{WsConfiguration, UiConfiguration};
use run::RunCmd;
use network::{AllowIP, IpFilter};
extern crate ipnetwork;
use self::ipnetwork::IpNetwork;
use super::*;
#[derive(Debug, PartialEq)]
@@ -1192,6 +1203,7 @@ mod tests {
check_seal: true,
with_color: !cfg!(windows),
verifier_settings: Default::default(),
light: false,
})));
}
@@ -1283,11 +1295,20 @@ mod tests {
support_token_api: true
}, UiConfiguration {
enabled: true,
ntp_server: "pool.ntp.org:123".into(),
ntp_servers: vec![
"0.parity.pool.ntp.org:123".into(),
"1.parity.pool.ntp.org:123".into(),
"2.parity.pool.ntp.org:123".into(),
"3.parity.pool.ntp.org:123".into(),
],
interface: "127.0.0.1".into(),
port: 8180,
hosts: Some(vec![]),
}));
}, LogConfig {
color: true,
mode: None,
file: None,
} ));
}
#[test]
@@ -1312,7 +1333,7 @@ mod tests {
public_node: false,
warp_sync: true,
acc_conf: Default::default(),
gas_pricer: Default::default(),
gas_pricer_conf: Default::default(),
miner_extras: Default::default(),
update_policy: UpdatePolicy { enable_downloading: true, require_consensus: true, filter: UpdateFilter::Critical, track: ReleaseTrack::Unknown, path: default_hypervisor_path() },
mode: Default::default(),
@@ -1339,6 +1360,7 @@ mod tests {
serve_light: true,
light: false,
no_persistent_txqueue: false,
whisper: Default::default(),
};
expected.secretstore_conf.enabled = cfg!(feature = "secretstore");
expected.secretstore_conf.http_enabled = cfg!(feature = "secretstore");
@@ -1522,10 +1544,16 @@ mod tests {
let conf3 = parse(&["parity", "--ui-path", "signer", "--ui-interface", "test"]);
// then
let ntp_servers = vec![
"0.parity.pool.ntp.org:123".into(),
"1.parity.pool.ntp.org:123".into(),
"2.parity.pool.ntp.org:123".into(),
"3.parity.pool.ntp.org:123".into(),
];
assert_eq!(conf0.directories().signer, "signer".to_owned());
assert_eq!(conf0.ui_config(), UiConfiguration {
enabled: true,
ntp_server: "pool.ntp.org:123".into(),
ntp_servers: ntp_servers.clone(),
interface: "127.0.0.1".into(),
port: 8180,
hosts: Some(vec![]),
@@ -1534,7 +1562,7 @@ mod tests {
assert_eq!(conf1.directories().signer, "signer".to_owned());
assert_eq!(conf1.ui_config(), UiConfiguration {
enabled: true,
ntp_server: "pool.ntp.org:123".into(),
ntp_servers: ntp_servers.clone(),
interface: "127.0.0.1".into(),
port: 8180,
hosts: Some(vec![]),
@@ -1544,7 +1572,7 @@ mod tests {
assert_eq!(conf2.directories().signer, "signer".to_owned());
assert_eq!(conf2.ui_config(), UiConfiguration {
enabled: true,
ntp_server: "pool.ntp.org:123".into(),
ntp_servers: ntp_servers.clone(),
interface: "127.0.0.1".into(),
port: 3123,
hosts: Some(vec![]),
@@ -1553,7 +1581,7 @@ mod tests {
assert_eq!(conf3.directories().signer, "signer".to_owned());
assert_eq!(conf3.ui_config(), UiConfiguration {
enabled: true,
ntp_server: "pool.ntp.org:123".into(),
ntp_servers: ntp_servers.clone(),
interface: "test".into(),
port: 8180,
hosts: Some(vec![]),
@@ -1602,18 +1630,109 @@ mod tests {
}
#[test]
fn test_dev_chain() {
let args = vec!["parity", "--chain", "dev"];
let conf = parse(&args);
fn test_dev_preset() {
let args = vec!["parity", "--config", "dev"];
let conf = Configuration::parse(&args, None).unwrap();
match conf.into_command().unwrap().cmd {
Cmd::Run(c) => {
assert_eq!(c.gas_pricer, GasPricerConfig::Fixed(0.into()));
assert_eq!(c.net_settings.chain, "dev");
assert_eq!(c.gas_pricer_conf, GasPricerConfig::Fixed(0.into()));
assert_eq!(c.miner_options.reseal_min_period, Duration::from_millis(0));
},
_ => panic!("Should be Cmd::Run"),
}
}
#[test]
fn test_mining_preset() {
let args = vec!["parity", "--config", "mining"];
let conf = Configuration::parse(&args, None).unwrap();
match conf.into_command().unwrap().cmd {
Cmd::Run(c) => {
assert_eq!(c.net_conf.min_peers, 50);
assert_eq!(c.net_conf.max_peers, 100);
assert_eq!(c.ipc_conf.enabled, false);
assert_eq!(c.dapps_conf.enabled, false);
assert_eq!(c.miner_options.force_sealing, true);
assert_eq!(c.miner_options.reseal_on_external_tx, true);
assert_eq!(c.miner_options.reseal_on_own_tx, true);
assert_eq!(c.miner_options.reseal_min_period, Duration::from_millis(4000));
assert_eq!(c.miner_options.tx_queue_size, 2048);
assert_eq!(c.cache_config, CacheConfig::new_with_total_cache_size(256));
assert_eq!(c.logger_config.mode.unwrap(), "miner=trace,own_tx=trace");
},
_ => panic!("Should be Cmd::Run"),
}
}
#[test]
fn test_non_standard_ports_preset() {
let args = vec!["parity", "--config", "non-standard-ports"];
let conf = Configuration::parse(&args, None).unwrap();
match conf.into_command().unwrap().cmd {
Cmd::Run(c) => {
assert_eq!(c.net_settings.network_port, 30305);
assert_eq!(c.net_settings.rpc_port, 8645);
},
_ => panic!("Should be Cmd::Run"),
}
}
#[test]
fn test_insecure_preset() {
let args = vec!["parity", "--config", "insecure"];
let conf = Configuration::parse(&args, None).unwrap();
match conf.into_command().unwrap().cmd {
Cmd::Run(c) => {
assert_eq!(c.update_policy.require_consensus, false);
assert_eq!(c.net_settings.rpc_interface, "0.0.0.0");
match c.http_conf.apis {
ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()),
_ => panic!("Incorrect rpc apis"),
}
// "web3,eth,net,personal,parity,parity_set,traces,rpc,parity_accounts");
assert_eq!(c.http_conf.hosts, None);
assert_eq!(c.ipfs_conf.hosts, None);
},
_ => panic!("Should be Cmd::Run"),
}
}
#[test]
fn test_dev_insecure_preset() {
let args = vec!["parity", "--config", "dev-insecure"];
let conf = Configuration::parse(&args, None).unwrap();
match conf.into_command().unwrap().cmd {
Cmd::Run(c) => {
assert_eq!(c.net_settings.chain, "dev");
assert_eq!(c.gas_pricer_conf, GasPricerConfig::Fixed(0.into()));
assert_eq!(c.miner_options.reseal_min_period, Duration::from_millis(0));
assert_eq!(c.update_policy.require_consensus, false);
assert_eq!(c.net_settings.rpc_interface, "0.0.0.0");
match c.http_conf.apis {
ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()),
_ => panic!("Incorrect rpc apis"),
}
// "web3,eth,net,personal,parity,parity_set,traces,rpc,parity_accounts");
assert_eq!(c.http_conf.hosts, None);
assert_eq!(c.ipfs_conf.hosts, None);
},
_ => panic!("Should be Cmd::Run"),
}
}
#[test]
fn test_override_preset() {
let args = vec!["parity", "--config", "mining", "--min-peers=99"];
let conf = Configuration::parse(&args, None).unwrap();
match conf.into_command().unwrap().cmd {
Cmd::Run(c) => {
assert_eq!(c.net_conf.min_peers, 99);
},
_ => panic!("Should be Cmd::Run"),
}
}
#[test]
fn should_apply_ports_shift() {
// given
@@ -1667,4 +1786,61 @@ mod tests {
assert_eq!(&conf0.ipfs_config().interface, "0.0.0.0");
assert_eq!(conf0.ipfs_config().hosts, None);
}
#[test]
fn allow_ips() {
let all = parse(&["parity", "--allow-ips", "all"]);
let private = parse(&["parity", "--allow-ips", "private"]);
let block_custom = parse(&["parity", "--allow-ips", "-10.0.0.0/8"]);
let combo = parse(&["parity", "--allow-ips", "public 10.0.0.0/8 -1.0.0.0/8"]);
let ipv6_custom_public = parse(&["parity", "--allow-ips", "public fc00::/7"]);
let ipv6_custom_private = parse(&["parity", "--allow-ips", "private -fc00::/7"]);
assert_eq!(all.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::All,
custom_allow: vec![],
custom_block: vec![],
});
assert_eq!(private.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Private,
custom_allow: vec![],
custom_block: vec![],
});
assert_eq!(block_custom.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::All,
custom_allow: vec![],
custom_block: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()],
});
assert_eq!(combo.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Public,
custom_allow: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()],
custom_block: vec![IpNetwork::from_str("1.0.0.0/8").unwrap()],
});
assert_eq!(ipv6_custom_public.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Public,
custom_allow: vec![IpNetwork::from_str("fc00::/7").unwrap()],
custom_block: vec![],
});
assert_eq!(ipv6_custom_private.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Private,
custom_allow: vec![],
custom_block: vec![IpNetwork::from_str("fc00::/7").unwrap()],
});
}
#[test]
fn should_use_correct_cache_path_if_base_is_set() {
let std = parse(&["parity"]);
let base = parse(&["parity", "--base-path", "/test"]);
let base_path = ::dir::default_data_path();
let local_path = ::dir::default_local_path();
assert_eq!(std.directories().cache, ::helpers::replace_home_and_local(&base_path, &local_path, ::dir::CACHE_PATH));
assert_eq!(base.directories().cache, "/test/cache");
}
}

View File

@@ -36,7 +36,7 @@ use util::{Bytes, Address};
#[derive(Debug, PartialEq, Clone)]
pub struct Configuration {
pub enabled: bool,
pub ntp_server: String,
pub ntp_servers: Vec<String>,
pub dapps_path: PathBuf,
pub extra_dapps: Vec<PathBuf>,
pub extra_embed_on: Vec<(String, u16)>,
@@ -47,7 +47,12 @@ impl Default for Configuration {
let data_dir = default_data_path();
Configuration {
enabled: true,
ntp_server: "pool.ntp.org:123".into(),
ntp_servers: vec![
"0.parity.pool.ntp.org:123".into(),
"1.parity.pool.ntp.org:123".into(),
"2.parity.pool.ntp.org:123".into(),
"3.parity.pool.ntp.org:123".into(),
],
dapps_path: replace_home(&data_dir, "$BASE/dapps").into(),
extra_dapps: vec![],
extra_embed_on: vec![],
@@ -114,7 +119,7 @@ impl ContractClient for LightRegistrar {
tx: Transaction {
nonce: self.client.engine().account_start_nonce(header.number()),
action: Action::Call(address),
gas: 50_000_000.into(),
gas: 50_000.into(), // should be enough for all registry lookups. TODO: exponential backoff
gas_price: 0.into(),
value: 0.into(),
data: data,
@@ -158,7 +163,7 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<Mi
server::dapps_middleware(
deps,
&configuration.ntp_server,
&configuration.ntp_servers,
configuration.dapps_path,
configuration.extra_dapps,
rpc::DAPPS_DOMAIN,
@@ -166,14 +171,14 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<Mi
).map(Some)
}
pub fn new_ui(enabled: bool, ntp_server: &str, deps: Dependencies) -> Result<Option<Middleware>, String> {
pub fn new_ui(enabled: bool, ntp_servers: &[String], deps: Dependencies) -> Result<Option<Middleware>, String> {
if !enabled {
return Ok(None);
}
server::ui_middleware(
deps,
ntp_server,
ntp_servers,
rpc::DAPPS_DOMAIN,
).map(Some)
}
@@ -188,7 +193,10 @@ mod server {
use parity_rpc::{hyper, RequestMiddleware, RequestMiddlewareAction};
use rpc_apis;
pub type SyncStatus = Fn() -> bool;
pub trait SyncStatus {
fn is_major_importing(&self) -> bool;
fn peers(&self) -> (usize, usize);
}
pub struct Middleware;
impl RequestMiddleware for Middleware {
@@ -201,7 +209,7 @@ mod server {
pub fn dapps_middleware(
_deps: Dependencies,
_ntp_server: &str,
_ntp_servers: &[String],
_dapps_path: PathBuf,
_extra_dapps: Vec<PathBuf>,
_dapps_domain: &str,
@@ -212,7 +220,7 @@ mod server {
pub fn ui_middleware(
_deps: Dependencies,
_ntp_server: &str,
_ntp_servers: &[String],
_dapps_domain: &str,
) -> Result<Middleware, String> {
Err("Your Parity version has been compiled without UI support.".into())
@@ -238,7 +246,7 @@ mod server {
pub fn dapps_middleware(
deps: Dependencies,
ntp_server: &str,
ntp_servers: &[String],
dapps_path: PathBuf,
extra_dapps: Vec<PathBuf>,
dapps_domain: &str,
@@ -249,7 +257,7 @@ mod server {
let web_proxy_tokens = Arc::new(move |token| signer.web_proxy_access_token_domain(&token));
Ok(parity_dapps::Middleware::dapps(
ntp_server,
ntp_servers,
deps.pool,
parity_remote,
deps.ui_address,
@@ -266,12 +274,12 @@ mod server {
pub fn ui_middleware(
deps: Dependencies,
ntp_server: &str,
ntp_servers: &[String],
dapps_domain: &str,
) -> Result<Middleware, String> {
let parity_remote = parity_reactor::Remote::new(deps.remote.clone());
Ok(parity_dapps::Middleware::ui(
ntp_server,
ntp_servers,
deps.pool,
parity_remote,
dapps_domain,

View File

@@ -191,7 +191,8 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
#[cfg(test)]
pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
use ethsync::{NetworkConfiguration, AllowIP};
use ethsync::{NetworkConfiguration};
use super::network::IpFilter;
NetworkConfiguration {
config_path: Some(replace_home(&::dir::default_data_path(), "$BASE/network")),
net_config_path: None,
@@ -206,7 +207,7 @@ pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
min_peers: 25,
snapshot_peers: 0,
max_pending_peers: 64,
allow_ips: AllowIP::All,
ip_filter: IpFilter::default(),
reserved_nodes: Vec::new(),
allow_non_reserved: true,
}

View File

@@ -152,7 +152,7 @@ impl InformantData for FullNodeInformantData {
max_peers: status.current_max_peers(net_config.min_peers, net_config.max_peers),
}))
}
_ => (is_major_importing(None, queue_info.clone()), None),
_ => (is_major_importing(self.sync.as_ref().map(|s| s.status().state), queue_info.clone()), None),
};
Report {
@@ -254,21 +254,22 @@ impl<T: InformantData> Informant<T> {
return;
}
let (client_report, full_report) = {
let mut last_report = self.last_report.lock();
let full_report = self.target.report();
let diffed = full_report.client_report.clone() - &*last_report;
*last_report = full_report.client_report.clone();
(diffed, full_report)
};
let Report {
importing,
chain_info,
client_report,
queue_info,
cache_sizes,
sync_info,
} = self.target.report();
let client_report = {
let mut last_report = self.last_report.lock();
let diffed = client_report.clone() - &*last_report;
*last_report = client_report.clone();
diffed
};
..
} = full_report;
let rpc_stats = self.rpc_stats.as_ref();

View File

@@ -55,14 +55,17 @@ extern crate ethcore_ipc_nano as nanoipc;
extern crate ethcore_light as light;
extern crate ethcore_logger;
extern crate ethcore_util as util;
extern crate ethcore_network as network;
extern crate ethkey;
extern crate ethsync;
extern crate panic_hook;
extern crate parity_hash_fetch as hash_fetch;
extern crate parity_ipfs_api;
extern crate parity_local_store as local_store;
extern crate parity_reactor;
extern crate parity_rpc;
extern crate parity_updater as updater;
extern crate parity_whisper;
extern crate path;
extern crate rpc_cli;
@@ -110,6 +113,7 @@ mod snapshot;
mod upgrade;
mod url;
mod user_defaults;
mod whisper;
#[cfg(feature="ipc")]
mod boot;
@@ -160,7 +164,7 @@ fn execute(command: Execute, can_restart: bool) -> Result<PostExecutionAction, S
Cmd::Account(account_cmd) => account::execute(account_cmd).map(|s| PostExecutionAction::Print(s)),
Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd).map(|s| PostExecutionAction::Print(s)),
Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd).map(|_| PostExecutionAction::Quit),
Cmd::SignerToken(ws_conf, ui_conf) => signer::execute(ws_conf, ui_conf).map(|s| PostExecutionAction::Print(s)),
Cmd::SignerToken(ws_conf, ui_conf, logger_config) => signer::execute(ws_conf, ui_conf, logger_config).map(|s| PostExecutionAction::Print(s)),
Cmd::SignerSign { id, pwfile, port, authfile } => rpc_cli::signer_sign(id, pwfile, port, authfile).map(|s| PostExecutionAction::Print(s)),
Cmd::SignerList { port, authfile } => rpc_cli::signer_list(port, authfile).map(|s| PostExecutionAction::Print(s)),
Cmd::SignerReject { id, port, authfile } => rpc_cli::signer_reject(id, port, authfile).map(|s| PostExecutionAction::Print(s)),
@@ -313,8 +317,7 @@ macro_rules! trace_main {
}
fn main() {
// Always print backtrace on panic.
env::set_var("RUST_BACKTRACE", "1");
panic_hook::set();
// assuming the user is not running with `--force-direct`, then:
// if argv[0] == "parity" and this executable != ~/.parity-updates/parity, run that instead.
@@ -364,4 +367,3 @@ fn main() {
process::exit(main_direct(can_restart));
}
}

View File

@@ -19,7 +19,7 @@ use std::path::Path;
use ethcore::client::BlockChainClient;
use hypervisor::Hypervisor;
use ethsync::{SyncConfig, NetworkConfiguration, NetworkError, Params};
use ethsync::{AttachedProtocol, SyncConfig, NetworkConfiguration, NetworkError, Params};
use ethcore::snapshot::SnapshotService;
use light::Provider;
@@ -151,6 +151,7 @@ pub fn sync(
_snapshot_service: Arc<SnapshotService>,
_provider: Arc<Provider>,
log_settings: &LogConfig,
_attached_protos: Vec<AttachedProtocol>,
) -> Result<SyncModules, NetworkError> {
let mut hypervisor = hypervisor_ref.take().expect("There should be hypervisor for ipc configuration");
let args = sync_arguments(&hypervisor.io_path, sync_cfg, net_cfg, log_settings);
@@ -181,6 +182,7 @@ pub fn sync(
snapshot_service: Arc<SnapshotService>,
provider: Arc<Provider>,
_log_settings: &LogConfig,
attached_protos: Vec<AttachedProtocol>,
) -> Result<SyncModules, NetworkError> {
let eth_sync = EthSync::new(Params {
config: sync_cfg,
@@ -188,6 +190,7 @@ pub fn sync(
provider: provider,
snapshot_service: snapshot_service,
network_config: net_cfg,
attached_protos: attached_protos,
})?;
Ok((eth_sync.clone() as Arc<SyncProvider>, eth_sync.clone() as Arc<ManageNetwork>, eth_sync.clone() as Arc<ChainNotify>))

View File

@@ -22,6 +22,7 @@ use ethcore::spec::Spec;
use ethcore::ethereum;
use ethcore::client::Mode;
use ethcore::miner::{GasPricer, GasPriceCalibratorOptions};
use hash_fetch::fetch::Client as FetchClient;
use user_defaults::UserDefaults;
#[derive(Debug, PartialEq)]
@@ -226,15 +227,18 @@ impl Default for GasPricerConfig {
}
}
impl Into<GasPricer> for GasPricerConfig {
fn into(self) -> GasPricer {
match self {
impl GasPricerConfig {
pub fn to_gas_pricer(&self, fetch: FetchClient) -> GasPricer {
match *self {
GasPricerConfig::Fixed(u) => GasPricer::Fixed(u),
GasPricerConfig::Calibrated { usd_per_tx, recalibration_period, .. } => {
GasPricer::new_calibrated(GasPriceCalibratorOptions {
usd_per_tx: usd_per_tx,
recalibration_period: recalibration_period,
})
GasPricer::new_calibrated(
GasPriceCalibratorOptions {
usd_per_tx: usd_per_tx,
recalibration_period: recalibration_period,
},
fetch
)
}
}
}

View File

@@ -32,7 +32,6 @@ pub use parity_rpc::{IpcServer, HttpServer, RequestMiddleware};
pub use parity_rpc::ws::Server as WsServer;
pub use parity_rpc::informant::CpuPool;
pub const DAPPS_DOMAIN: &'static str = "web3.site";
#[derive(Debug, Clone, PartialEq)]
@@ -74,7 +73,7 @@ impl Default for HttpConfiguration {
#[derive(Debug, PartialEq, Clone)]
pub struct UiConfiguration {
pub enabled: bool,
pub ntp_server: String,
pub ntp_servers: Vec<String>,
pub interface: String,
pub port: u16,
pub hosts: Option<Vec<String>>,
@@ -108,7 +107,12 @@ impl Default for UiConfiguration {
fn default() -> Self {
UiConfiguration {
enabled: true && cfg!(feature = "ui-enabled"),
ntp_server: "pool.ntp.org:123".into(),
ntp_servers: vec![
"0.parity.pool.ntp.org:123".into(),
"1.parity.pool.ntp.org:123".into(),
"2.parity.pool.ntp.org:123".into(),
"3.parity.pool.ntp.org:123".into(),
],
port: 8180,
interface: "127.0.0.1".into(),
hosts: Some(vec![]),
@@ -168,7 +172,6 @@ impl Default for WsConfiguration {
}
}
impl WsConfiguration {
pub fn address(&self) -> Option<(String, u16)> {
match self.enabled {

View File

@@ -67,6 +67,12 @@ pub enum Api {
Rpc,
/// SecretStore (Safe)
SecretStore,
/// Whisper (Safe)
// TODO: _if_ someone guesses someone else's key or filter IDs they can remove
// BUT these are all ephemeral so it seems fine.
Whisper,
/// Whisper Pub-Sub (Safe but same concerns as above).
WhisperPubSub,
}
impl FromStr for Api {
@@ -89,6 +95,8 @@ impl FromStr for Api {
"traces" => Ok(Traces),
"rpc" => Ok(Rpc),
"secretstore" => Ok(SecretStore),
"shh" => Ok(Whisper),
"shh_pubsub" => Ok(WhisperPubSub),
api => Err(format!("Unknown api: {}", api))
}
}
@@ -172,6 +180,8 @@ fn to_modules(apis: &HashSet<Api>) -> BTreeMap<String, String> {
Api::Traces => ("traces", "1.0"),
Api::Rpc => ("rpc", "1.0"),
Api::SecretStore => ("secretstore", "1.0"),
Api::Whisper => ("shh", "1.0"),
Api::WhisperPubSub => ("shh_pubsub", "1.0"),
};
modules.insert(name.into(), version.into());
}
@@ -213,6 +223,7 @@ pub struct FullDependencies {
pub ws_address: Option<(String, u16)>,
pub fetch: FetchClient,
pub remote: parity_reactor::Remote,
pub whisper_rpc: Option<::whisper::RpcFactory>,
}
impl FullDependencies {
@@ -271,9 +282,11 @@ impl FullDependencies {
}
},
Api::EthPubSub => {
let client = EthPubSubClient::new(self.client.clone(), self.remote.clone());
self.client.add_notify(client.handler());
handler.extend_with(client.to_delegate());
if !for_generic_pubsub {
let client = EthPubSubClient::new(self.client.clone(), self.remote.clone());
self.client.add_notify(client.handler());
handler.extend_with(client.to_delegate());
}
},
Api::Personal => {
handler.extend_with(PersonalClient::new(&self.secret_store, dispatcher.clone(), self.geth_compatibility).to_delegate());
@@ -335,6 +348,22 @@ impl FullDependencies {
Api::SecretStore => {
handler.extend_with(SecretStoreClient::new(&self.secret_store).to_delegate());
},
Api::Whisper => {
if let Some(ref whisper_rpc) = self.whisper_rpc {
let whisper = whisper_rpc.make_handler();
handler.extend_with(::parity_whisper::rpc::Whisper::to_delegate(whisper));
}
}
Api::WhisperPubSub => {
if !for_generic_pubsub {
if let Some(ref whisper_rpc) = self.whisper_rpc {
let whisper = whisper_rpc.make_handler();
handler.extend_with(
::parity_whisper::rpc::WhisperPubSub::to_delegate(whisper)
);
}
}
}
}
}
}
@@ -383,6 +412,7 @@ pub struct LightDependencies {
pub fetch: FetchClient,
pub geth_compatibility: bool,
pub remote: parity_reactor::Remote,
pub whisper_rpc: Option<::whisper::RpcFactory>,
}
impl LightDependencies {
@@ -516,6 +546,18 @@ impl LightDependencies {
let secret_store = Some(self.secret_store.clone());
handler.extend_with(SecretStoreClient::new(&secret_store).to_delegate());
},
Api::Whisper => {
if let Some(ref whisper_rpc) = self.whisper_rpc {
let whisper = whisper_rpc.make_handler();
handler.extend_with(::parity_whisper::rpc::Whisper::to_delegate(whisper));
}
}
Api::WhisperPubSub => {
if let Some(ref whisper_rpc) = self.whisper_rpc {
let whisper = whisper_rpc.make_handler();
handler.extend_with(::parity_whisper::rpc::WhisperPubSub::to_delegate(whisper));
}
}
}
}
}
@@ -543,8 +585,17 @@ impl ApiSet {
pub fn list_apis(&self) -> HashSet<Api> {
let mut public_list = [
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::Rpc, Api::SecretStore,
Api::Web3,
Api::Net,
Api::Eth,
Api::EthPubSub,
Api::Parity,
Api::Rpc,
Api::SecretStore,
Api::Whisper,
Api::WhisperPubSub,
].into_iter().cloned().collect();
match *self {
ApiSet::List(ref apis) => apis.clone(),
ApiSet::PublicContext => public_list,
@@ -605,6 +656,8 @@ mod test {
assert_eq!(Api::Traces, "traces".parse().unwrap());
assert_eq!(Api::Rpc, "rpc".parse().unwrap());
assert_eq!(Api::SecretStore, "secretstore".parse().unwrap());
assert_eq!(Api::Whisper, "shh".parse().unwrap());
assert_eq!(Api::WhisperPubSub, "shh_pubsub".parse().unwrap());
assert!("rp".parse::<Api>().is_err());
}
@@ -622,7 +675,7 @@ mod test {
fn test_api_set_unsafe_context() {
let expected = vec![
// make sure this list contains only SAFE methods
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub,
].into_iter().collect();
assert_eq!(ApiSet::UnsafeContext.list_apis(), expected);
}
@@ -631,7 +684,7 @@ mod test {
fn test_api_set_ipc_context() {
let expected = vec![
// safe
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore,
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub,
// semi-safe
Api::ParityAccounts
].into_iter().collect();
@@ -642,7 +695,7 @@ mod test {
fn test_api_set_safe_context() {
let expected = vec![
// safe
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore,
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub,
// semi-safe
Api::ParityAccounts,
// Unsafe
@@ -654,7 +707,7 @@ mod test {
#[test]
fn test_all_apis() {
assert_eq!("all".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore,
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub,
Api::ParityAccounts,
Api::ParitySet, Api::Signer,
Api::Personal
@@ -664,7 +717,7 @@ mod test {
#[test]
fn test_all_without_personal_apis() {
assert_eq!("personal,all,-personal".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore,
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub,
Api::ParityAccounts,
Api::ParitySet, Api::Signer,
].into_iter().collect()));
@@ -673,7 +726,7 @@ mod test {
#[test]
fn test_safe_parsing() {
assert_eq!("safe".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore,
Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity, Api::ParityPubSub, Api::Traces, Api::Rpc, Api::SecretStore, Api::Whisper, Api::WhisperPubSub,
].into_iter().collect()));
}
}

View File

@@ -88,7 +88,7 @@ pub struct RunCmd {
pub warp_sync: bool,
pub public_node: bool,
pub acc_conf: AccountsConfig,
pub gas_pricer: GasPricerConfig,
pub gas_pricer_conf: GasPricerConfig,
pub miner_extras: MinerExtras,
pub update_policy: UpdatePolicy,
pub mode: Option<Mode>,
@@ -115,14 +115,15 @@ pub struct RunCmd {
pub serve_light: bool,
pub light: bool,
pub no_persistent_txqueue: bool,
pub whisper: ::whisper::Config
}
pub fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> Result<(), String> {
pub fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result<(), String> {
if !ui_conf.enabled {
return Err("Cannot use UI command with UI turned off.".into())
}
let token = signer::generate_token_and_url(ws_conf, ui_conf)?;
let token = signer::generate_token_and_url(ws_conf, ui_conf, logger_config)?;
// Open a browser
url::open(&token.url);
// Print a message
@@ -210,6 +211,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
db_compaction: compaction,
db_wal: cmd.wal,
verify_full: true,
check_seal: cmd.check_seal,
};
config.queue.max_mem_use = cmd.cache_config.queue() as usize * 1024 * 1024;
@@ -230,6 +232,17 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
// start on_demand service.
let on_demand = Arc::new(::light::on_demand::OnDemand::new(cache.clone()));
let mut attached_protos = Vec::new();
let whisper_factory = if cmd.whisper.enabled {
let (whisper_net, whisper_factory) = ::whisper::setup(cmd.whisper.target_message_pool_size)
.map_err(|e| format!("Failed to initialize whisper: {}", e))?;
attached_protos.push(whisper_net);
whisper_factory
} else {
None
};
// set network path.
net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned());
let sync_params = LightSyncParams {
@@ -238,6 +251,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
network_id: cmd.network_id.unwrap_or(spec.network_id()),
subprotocol_name: ethsync::LIGHT_PROTOCOL,
handlers: vec![on_demand.clone()],
attached_protos: attached_protos,
};
let light_sync = LightSync::new(sync_params).map_err(|e| format!("Error starting network: {}", e))?;
let light_sync = Arc::new(light_sync);
@@ -268,7 +282,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
let rpc_stats = Arc::new(informant::RpcStats::default());
// the dapps server
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf));
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config));
let dapps_deps = {
let contract_client = Arc::new(::dapps::LightRegistrar {
client: service.client().clone(),
@@ -297,7 +311,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
};
let dapps_middleware = dapps::new(cmd.dapps_conf.clone(), dapps_deps.clone())?;
let ui_middleware = dapps::new_ui(cmd.ui_conf.enabled, &cmd.ui_conf.ntp_server, dapps_deps)?;
let ui_middleware = dapps::new_ui(cmd.ui_conf.enabled, &cmd.ui_conf.ntp_servers, dapps_deps)?;
// start RPCs
let dapps_service = dapps::service(&dapps_middleware);
@@ -318,6 +332,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
fetch: fetch,
geth_compatibility: cmd.geth_compatibility,
remote: event_loop.remote(),
whisper_rpc: whisper_factory,
});
let dependencies = rpc::Dependencies {
@@ -363,7 +378,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
// Check if Parity is already running
let addr = format!("{}:{}", cmd.ui_conf.interface, cmd.ui_conf.port);
if !TcpListener::bind(&addr as &str).is_ok() {
return open_ui(&cmd.ws_conf, &cmd.ui_conf).map(|_| (false, None));
return open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config).map(|_| (false, None));
}
}
@@ -466,9 +481,12 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
// prepare account provider
let account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?);
// fetch service
let fetch = FetchClient::new().map_err(|e| format!("Error starting fetch client: {:?}", e))?;
// create miner
let initial_min_gas_price = cmd.gas_pricer.initial_min();
let miner = Miner::new(cmd.miner_options, cmd.gas_pricer.into(), &spec, Some(account_provider.clone()));
let initial_min_gas_price = cmd.gas_pricer_conf.initial_min();
let miner = Miner::new(cmd.miner_options, cmd.gas_pricer_conf.to_gas_pricer(fetch.clone()), &spec, Some(account_provider.clone()));
miner.set_author(cmd.miner_extras.author);
miner.set_gas_floor_target(cmd.miner_extras.gas_floor_target);
miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target);
@@ -589,6 +607,18 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
.map_err(|e| format!("Stratum start error: {:?}", e))?;
}
let mut attached_protos = Vec::new();
let whisper_factory = if cmd.whisper.enabled {
let (whisper_net, whisper_factory) = ::whisper::setup(cmd.whisper.target_message_pool_size)
.map_err(|e| format!("Failed to initialize whisper: {}", e))?;
attached_protos.push(whisper_net);
whisper_factory
} else {
None
};
// create sync object
let (sync_provider, manage_network, chain_notify) = modules::sync(
&mut hypervisor,
@@ -598,6 +628,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
snapshot_service.clone(),
client.clone(),
&cmd.logger_config,
attached_protos,
).map_err(|e| format!("Sync error: {}", e))?;
service.add_notify(chain_notify.clone());
@@ -610,9 +641,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
// spin up event loop
let event_loop = EventLoop::spawn();
// fetch service
let fetch = FetchClient::new().map_err(|e| format!("Error starting fetch client: {:?}", e))?;
// the updater service
let updater = Updater::new(
Arc::downgrade(&(service.client() as Arc<BlockChainClient>)),
@@ -630,7 +658,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
false => Some(account_provider.clone())
};
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf));
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config));
// the dapps server
let dapps_deps = {
@@ -659,7 +687,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
}
};
let dapps_middleware = dapps::new(cmd.dapps_conf.clone(), dapps_deps.clone())?;
let ui_middleware = dapps::new_ui(cmd.ui_conf.enabled, &cmd.ui_conf.ntp_server, dapps_deps)?;
let ui_middleware = dapps::new_ui(cmd.ui_conf.enabled, &cmd.ui_conf.ntp_servers, dapps_deps)?;
let dapps_service = dapps::service(&dapps_middleware);
let deps_for_rpc_apis = Arc::new(rpc_apis::FullDependencies {
@@ -681,6 +709,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
ws_address: cmd.ws_conf.address(),
fetch: fetch.clone(),
remote: event_loop.remote(),
whisper_rpc: whisper_factory,
});
let dependencies = rpc::Dependencies {
@@ -728,6 +757,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
service.register_io_handler(informant.clone()).map_err(|_| "Unable to register informant handler".to_owned())?;
// save user defaults
user_defaults.is_first_launch = false;
user_defaults.pruning = algorithm;
user_defaults.tracing = tracing;
user_defaults.fat_db = fat_db;
@@ -763,7 +793,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
// start ui
if cmd.ui {
open_ui(&cmd.ws_conf, &cmd.ui_conf)?;
open_ui(&cmd.ws_conf, &cmd.ui_conf, &cmd.logger_config)?;
}
if let Some(dapp) = cmd.dapp {

View File

@@ -17,13 +17,13 @@
use std::io;
use std::path::{Path, PathBuf};
use ansi_term::Colour;
use ansi_term::Colour::White;
use ethcore_logger::Config as LogConfig;
use rpc;
use rpc_apis;
use parity_rpc;
use path::restrict_permissions_owner;
pub const CODES_FILENAME: &'static str = "authcodes";
pub struct NewToken {
@@ -32,12 +32,13 @@ pub struct NewToken {
pub message: String,
}
pub fn new_service(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> rpc_apis::SignerService {
pub fn new_service(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> rpc_apis::SignerService {
let signer_path = ws_conf.signer_path.clone();
let logger_config_color = logger_config.color;
let signer_enabled = ui_conf.enabled;
rpc_apis::SignerService::new(move || {
generate_new_token(&signer_path).map_err(|e| format!("{:?}", e))
generate_new_token(&signer_path, logger_config_color).map_err(|e| format!("{:?}", e))
}, signer_enabled)
}
@@ -48,13 +49,14 @@ pub fn codes_path(path: &Path) -> PathBuf {
p
}
pub fn execute(ws_conf: rpc::WsConfiguration, ui_conf: rpc::UiConfiguration) -> Result<String, String> {
Ok(generate_token_and_url(&ws_conf, &ui_conf)?.message)
pub fn execute(ws_conf: rpc::WsConfiguration, ui_conf: rpc::UiConfiguration, logger_config: LogConfig) -> Result<String, String> {
Ok(generate_token_and_url(&ws_conf, &ui_conf, &logger_config)?.message)
}
pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration) -> Result<NewToken, String> {
let code = generate_new_token(&ws_conf.signer_path).map_err(|err| format!("Error generating token: {:?}", err))?;
pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result<NewToken, String> {
let code = generate_new_token(&ws_conf.signer_path, logger_config.color).map_err(|err| format!("Error generating token: {:?}", err))?;
let auth_url = format!("http://{}:{}/#/auth?token={}", ui_conf.interface, ui_conf.port, code);
// And print in to the console
Ok(NewToken {
token: code.clone(),
@@ -65,18 +67,24 @@ Open: {}
to authorize your browser.
Or use the generated token:
{}"#,
Colour::White.bold().paint(auth_url),
match logger_config.color {
true => format!("{}", White.bold().paint(auth_url)),
false => auth_url
},
code
)
})
}
fn generate_new_token(path: &Path) -> io::Result<String> {
fn generate_new_token(path: &Path, logger_config_color: bool) -> io::Result<String> {
let path = codes_path(path);
let mut codes = parity_rpc::AuthCodes::from_file(&path)?;
codes.clear_garbage();
let code = codes.generate_new()?;
codes.to_file(&path)?;
trace!("New key code created: {}", Colour::White.bold().paint(&code[..]));
trace!("New key code created: {}", match logger_config_color {
true => format!("{}", White.bold().paint(&code[..])),
false => format!("{}", &code[..])
});
Ok(code)
}

View File

@@ -52,11 +52,12 @@ pub fn main() {
let remote_provider = dependency!(LightProviderClient, &service_urls::with_base(&service_config.io_path, service_urls::LIGHT_PROVIDER));
let sync = EthSync::new(Params {
config: service_config.sync,
chain: remote_client.service().clone(),
snapshot_service: remote_snapshot.service().clone(),
config: service_config.sync,
chain: remote_client.service().clone(),
snapshot_service: remote_snapshot.service().clone(),
provider: remote_provider.service().clone(),
network_config: service_config.net
attached_protos: Vec::new(),
}).unwrap();
let _ = boot::main_thread();

View File

@@ -41,6 +41,7 @@ impl Serialize for UserDefaults {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
let mut map: BTreeMap<String, Value> = BTreeMap::new();
map.insert("is_first_launch".into(), Value::Bool(self.is_first_launch));
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));

77
parity/whisper.rs Normal file
View File

@@ -0,0 +1,77 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::Arc;
use std::io;
use ethsync::AttachedProtocol;
use parity_rpc::Metadata;
use parity_whisper::net::{self as whisper_net, PoolHandle, Network as WhisperNetwork};
use parity_whisper::rpc::{WhisperClient, FilterManager};
/// Whisper config.
#[derive(Debug, PartialEq, Eq)]
pub struct Config {
pub enabled: bool,
pub target_message_pool_size: usize,
}
impl Default for Config {
fn default() -> Self {
Config {
enabled: false,
target_message_pool_size: 10 * 1024 * 1024,
}
}
}
/// Factory for standard whisper RPC.
pub struct RpcFactory {
net: Arc<WhisperNetwork<Arc<FilterManager>>>,
manager: Arc<FilterManager>,
}
impl RpcFactory {
pub fn make_handler(&self) -> WhisperClient<PoolHandle, Metadata> {
WhisperClient::new(self.net.handle(), self.manager.clone())
}
}
/// Sets up whisper protocol and RPC handler.
///
/// Will target the given pool size.
#[cfg(not(feature = "ipc"))]
pub fn setup(target_pool_size: usize) -> io::Result<(AttachedProtocol, Option<RpcFactory>)> {
let manager = Arc::new(FilterManager::new()?);
let net = Arc::new(WhisperNetwork::new(target_pool_size, manager.clone()));
let proto = AttachedProtocol {
handler: net.clone() as Arc<_>,
packet_count: whisper_net::PACKET_COUNT,
versions: whisper_net::SUPPORTED_VERSIONS,
protocol_id: *b"shh",
};
let factory = RpcFactory { net: net, manager: manager };
Ok((proto, Some(factory)))
}
// TODO: make it possible to attach generic protocols in IPC.
#[cfg(feature = "ipc")]
pub fn setup(_pool: usize) -> (AttachedProtocol, Option<RpcFactory>) {
Ok((AttachedProtocol, None))
}