Merge remote-tracking branch 'parity/master' into bft

This commit is contained in:
keorn
2016-11-07 11:34:45 +00:00
1245 changed files with 71972 additions and 5008 deletions

View File

@@ -77,12 +77,14 @@ pub struct ImportBlockchain {
pub file_path: Option<String>,
pub format: Option<DataFormat>,
pub pruning: Pruning,
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,
}
#[derive(Debug, PartialEq)]
@@ -94,6 +96,7 @@ pub struct ExportBlockchain {
pub file_path: Option<String>,
pub format: Option<DataFormat>,
pub pruning: Pruning,
pub pruning_history: u64,
pub compaction: DatabaseCompactionProfile,
pub wal: bool,
pub mode: Mode,
@@ -101,6 +104,7 @@ pub struct ExportBlockchain {
pub tracing: Switch,
pub from_block: BlockID,
pub to_block: BlockID,
pub check_seal: bool,
}
pub fn execute(cmd: BlockchainCmd) -> Result<String, String> {
@@ -153,10 +157,10 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
let snapshot_path = db_dirs.snapshot_path();
// execute upgrades
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile()));
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);
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);
// build client
let service = try!(ClientService::start(
@@ -192,7 +196,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
}
};
let informant = Informant::new(client.clone(), None, None, cmd.logger_config.color);
let informant = Informant::new(client.clone(), None, None, None, cmd.logger_config.color);
try!(service.register_io_handler(Arc::new(ImportIoHandler {
info: Arc::new(informant),
@@ -304,10 +308,10 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
let snapshot_path = db_dirs.snapshot_path();
// execute upgrades
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile()));
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);
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 service = try!(ClientService::start(
client_config,

View File

@@ -21,15 +21,13 @@ const MIN_DB_CACHE_MB: u32 = 2;
const MIN_BLOCK_QUEUE_SIZE_LIMIT_MB: u32 = 16;
const DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB: u32 = 50;
const DEFAULT_TRACE_CACHE_SIZE: u32 = 20;
const DEFAULT_STATE_CACHE_SIZE: u32 = 25;
/// Configuration for application cache sizes.
/// All values are represented in MB.
#[derive(Debug, PartialEq)]
pub struct CacheConfig {
/// Size of database cache set using option `set_block_cache_size_mb`
/// 50% is blockchain
/// 25% is tracing
/// 25% is state
/// Size of rocksDB cache. Almost all goes to the state column.
db: u32,
/// Size of blockchain cache.
blockchain: u32,
@@ -37,11 +35,13 @@ pub struct CacheConfig {
queue: u32,
/// Size of traces cache.
traces: u32,
/// Size of the state cache.
state: u32,
}
impl Default for CacheConfig {
fn default() -> Self {
CacheConfig::new(64, 8, DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB)
CacheConfig::new(64, 8, DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, DEFAULT_STATE_CACHE_SIZE)
}
}
@@ -49,26 +49,28 @@ impl CacheConfig {
/// Creates new cache config with cumulative size equal `total`.
pub fn new_with_total_cache_size(total: u32) -> Self {
CacheConfig {
db: total * 7 / 8,
blockchain: total / 8,
db: total * 7 / 10,
blockchain: total / 10,
queue: DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB,
traces: DEFAULT_TRACE_CACHE_SIZE,
state: total * 2 / 10,
}
}
/// Creates new cache config with gitven details.
pub fn new(db: u32, blockchain: u32, queue: u32) -> Self {
pub fn new(db: u32, blockchain: u32, queue: u32, state: u32) -> Self {
CacheConfig {
db: db,
blockchain: blockchain,
queue: queue,
traces: DEFAULT_TRACE_CACHE_SIZE,
state: state,
}
}
/// Size of db cache for blockchain.
pub fn db_blockchain_cache_size(&self) -> u32 {
max(MIN_DB_CACHE_MB, self.blockchain / 4)
max(MIN_DB_CACHE_MB, self.db / 4)
}
/// Size of db cache for state.
@@ -90,6 +92,16 @@ impl CacheConfig {
pub fn traces(&self) -> u32 {
self.traces
}
/// Size of the state cache.
pub fn state(&self) -> u32 {
self.state * 3 / 4
}
/// Size of the jump-tables cache.
pub fn jump_tables(&self) -> u32 {
self.state / 4
}
}
#[cfg(test)]
@@ -99,21 +111,24 @@ mod tests {
#[test]
fn test_cache_config_constructor() {
let config = CacheConfig::new_with_total_cache_size(200);
assert_eq!(config.db, 175);
assert_eq!(config.blockchain(), 25);
assert_eq!(config.db, 140);
assert_eq!(config.blockchain(), 20);
assert_eq!(config.queue(), 50);
assert_eq!(config.state(), 30);
assert_eq!(config.jump_tables(), 10);
}
#[test]
fn test_cache_config_db_cache_sizes() {
let config = CacheConfig::new_with_total_cache_size(400);
assert_eq!(config.db, 350);
assert_eq!(config.db_blockchain_cache_size(), 12);
assert_eq!(config.db_state_cache_size(), 262);
assert_eq!(config.db, 280);
assert_eq!(config.db_blockchain_cache_size(), 70);
assert_eq!(config.db_state_cache_size(), 210);
}
#[test]
fn test_cache_config_default() {
assert_eq!(CacheConfig::default(), CacheConfig::new(64, 8, super::DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB));
assert_eq!(CacheConfig::default(),
CacheConfig::new(64, 8, super::DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, super::DEFAULT_STATE_CACHE_SIZE));
}
}

View File

@@ -28,6 +28,10 @@ nat = "any"
id = "0x1"
bootnodes = []
discovery = true
warp = true
allow_ips = "all"
snapshot_peers = 0
max_pending_peers = 64
reserved_only = false
reserved_peers = "./path_to_file"
@@ -37,13 +41,13 @@ disable = false
port = 8545
interface = "local"
cors = "null"
apis = ["web3", "eth", "net", "personal", "ethcore", "traces", "rpc"]
apis = ["web3", "eth", "net", "ethcore", "traces", "rpc", "personal_safe"]
hosts = ["none"]
[ipc]
disable = false
path = "$HOME/.parity/jsonrpc.ipc"
apis = ["web3", "eth", "net", "personal", "ethcore", "traces", "rpc"]
apis = ["web3", "eth", "net", "ethcore", "traces", "rpc", "personal_safe"]
[dapps]
disable = false
@@ -67,9 +71,13 @@ usd_per_eth = "auto"
price_update_period = "hourly"
gas_floor_target = "4700000"
gas_cap = "6283184"
tx_queue_size = 2048
tx_queue_size = 1024
tx_queue_gas = "auto"
tx_queue_strategy = "gas_factor"
tx_queue_ban_count = 1
tx_queue_ban_time = 180 #s
tx_gas_limit = "6283184"
tx_time_limit = 100 #ms
extra_data = "Parity"
remove_solved = false
notify_work = ["http://localhost:3001"]
@@ -77,9 +85,11 @@ notify_work = ["http://localhost:3001"]
[footprint]
tracing = "auto"
pruning = "auto"
pruning_history = 64
cache_size_db = 64
cache_size_blocks = 8
cache_size_queue = 50
cache_size_state = 25
cache_size = 128 # Overrides above caches with total size
fast_and_loose = false
db_compaction = "ssd"

View File

@@ -13,10 +13,14 @@ disable = true
[network]
disable = false
warp = false
discovery = true
nat = "any"
min_peers = 10
max_peers = 20
max_pending_peers = 30
snapshot_peers = 40
allow_ips = "public"
reserved_only = true
reserved_peers = "./path/to/reserved_peers"
@@ -40,15 +44,17 @@ force_sealing = true
reseal_on_txs = "all"
reseal_min_period = 4000
price_update_period = "hourly"
tx_queue_size = 2048
tx_queue_size = 1024
tx_queue_gas = "auto"
[footprint]
tracing = "on"
pruning = "fast"
pruning_history = 64
cache_size_db = 128
cache_size_blocks = 16
cache_size_queue = 100
cache_size_state = 25
db_compaction = "ssd"
fat_db = "off"

View File

@@ -106,14 +106,22 @@ usage! {
// -- 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,
or |c: &Config| otry!(c.network).port.clone(),
flag_min_peers: u16 = 25u16,
or |c: &Config| otry!(c.network).min_peers.clone(),
flag_max_peers: u16 = 50u16,
or |c: &Config| otry!(c.network).max_peers.clone(),
flag_max_pending_peers: u16 = 64u16,
or |c: &Config| otry!(c.network).max_pending_peers.clone(),
flag_snapshot_peers: u16 = 0u16,
or |c: &Config| otry!(c.network).snapshot_peers.clone(),
flag_nat: String = "any",
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,
or |c: &Config| otry!(c.network).id.clone().map(Some),
flag_bootnodes: Option<String> = None,
@@ -137,7 +145,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,personal,traces,rpc",
flag_jsonrpc_apis: String = "web3,eth,net,ethcore,traces,rpc,personal_safe",
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(",")),
@@ -147,7 +155,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,personal,traces,rpc",
flag_ipc_apis: String = "web3,eth,net,ethcore,traces,rpc,personal_safe",
or |c: &Config| otry!(c.ipc).apis.clone().map(|vec| vec.join(",")),
// DAPPS
@@ -179,6 +187,8 @@ usage! {
or |c: &Config| otry!(c.mining).work_queue_size.clone(),
flag_tx_gas_limit: Option<String> = None,
or |c: &Config| otry!(c.mining).tx_gas_limit.clone().map(Some),
flag_tx_time_limit: Option<u64> = None,
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_usd_per_tx: String = "0",
@@ -197,6 +207,12 @@ usage! {
or |c: &Config| otry!(c.mining).tx_queue_size.clone(),
flag_tx_queue_gas: String = "auto",
or |c: &Config| otry!(c.mining).tx_queue_gas.clone(),
flag_tx_queue_strategy: String = "gas_price",
or |c: &Config| otry!(c.mining).tx_queue_strategy.clone(),
flag_tx_queue_ban_count: u16 = 1u16,
or |c: &Config| otry!(c.mining).tx_queue_ban_count.clone(),
flag_tx_queue_ban_time: u16 = 180u16,
or |c: &Config| otry!(c.mining).tx_queue_ban_time.clone(),
flag_remove_solved: bool = false,
or |c: &Config| otry!(c.mining).remove_solved.clone(),
flag_notify_work: Option<String> = None,
@@ -207,17 +223,21 @@ usage! {
or |c: &Config| otry!(c.footprint).tracing.clone(),
flag_pruning: String = "auto",
or |c: &Config| otry!(c.footprint).pruning.clone(),
flag_pruning_history: u64 = 64u64,
or |c: &Config| otry!(c.footprint).pruning_history.clone(),
flag_cache_size_db: u32 = 64u32,
or |c: &Config| otry!(c.footprint).cache_size_db.clone(),
flag_cache_size_blocks: u32 = 8u32,
or |c: &Config| otry!(c.footprint).cache_size_blocks.clone(),
flag_cache_size_queue: u32 = 50u32,
or |c: &Config| otry!(c.footprint).cache_size_queue.clone(),
flag_cache_size_state: u32 = 25u32,
or |c: &Config| otry!(c.footprint).cache_size_state.clone(),
flag_cache_size: Option<u32> = None,
or |c: &Config| otry!(c.footprint).cache_size.clone().map(Some),
flag_fast_and_loose: bool = false,
or |c: &Config| otry!(c.footprint).fast_and_loose.clone(),
flag_db_compaction: String = "ssd",
flag_db_compaction: String = "auto",
or |c: &Config| otry!(c.footprint).db_compaction.clone(),
flag_fat_db: String = "auto",
or |c: &Config| otry!(c.footprint).fat_db.clone(),
@@ -226,6 +246,7 @@ usage! {
flag_from: String = "1", or |_| None,
flag_to: String = "latest", or |_| None,
flag_format: Option<String> = None, or |_| None,
flag_no_seal_check: bool = false, or |_| None,
// -- Snapshot Optons
flag_at: String = "latest", or |_| None,
@@ -294,10 +315,14 @@ struct Signer {
#[derive(Default, Debug, PartialEq, RustcDecodable)]
struct Network {
disable: Option<bool>,
warp: Option<bool>,
port: Option<u16>,
min_peers: Option<u16>,
max_peers: Option<u16>,
snapshot_peers: Option<u16>,
max_pending_peers: Option<u16>,
nat: Option<String>,
allow_ips: Option<String>,
id: Option<String>,
bootnodes: Option<Vec<String>>,
discovery: Option<bool>,
@@ -342,6 +367,7 @@ struct Mining {
reseal_min_period: Option<u64>,
work_queue_size: Option<usize>,
tx_gas_limit: Option<String>,
tx_time_limit: Option<u64>,
relay_set: Option<String>,
usd_per_tx: Option<String>,
usd_per_eth: Option<String>,
@@ -351,6 +377,9 @@ struct Mining {
extra_data: Option<String>,
tx_queue_size: Option<usize>,
tx_queue_gas: Option<String>,
tx_queue_strategy: Option<String>,
tx_queue_ban_count: Option<u16>,
tx_queue_ban_time: Option<u16>,
remove_solved: Option<bool>,
notify_work: Option<Vec<String>>,
}
@@ -359,11 +388,13 @@ struct Mining {
struct Footprint {
tracing: Option<String>,
pruning: Option<String>,
pruning_history: Option<u64>,
fast_and_loose: Option<bool>,
cache_size: Option<u32>,
cache_size_db: Option<u32>,
cache_size_blocks: Option<u32>,
cache_size_queue: Option<u32>,
cache_size_state: Option<u32>,
db_compaction: Option<String>,
fat_db: Option<String>,
}
@@ -423,6 +454,20 @@ mod tests {
assert_eq!(args.flag_chain, "xyz".to_owned());
}
#[test]
fn should_use_config_if_cli_is_missing() {
let mut config = Config::default();
let mut footprint = Footprint::default();
footprint.pruning_history = Some(128);
config.footprint = Some(footprint);
// when
let args = Args::parse_with_config(&["parity"], config).unwrap();
// then
assert_eq!(args.flag_pruning_history, 128);
}
#[test]
fn should_parse_full_config() {
// given
@@ -477,9 +522,13 @@ mod tests {
// -- Networking Options
flag_no_network: false,
flag_warp: true,
flag_port: 30303u16,
flag_min_peers: 25u16,
flag_max_peers: 50u16,
flag_max_pending_peers: 64u16,
flag_snapshot_peers: 0u16,
flag_allow_ips: "all".into(),
flag_nat: "any".into(),
flag_network_id: Some("0x1".into()),
flag_bootnodes: Some("".into()),
@@ -494,13 +543,13 @@ mod tests {
flag_jsonrpc_port: 8545u16,
flag_jsonrpc_interface: "local".into(),
flag_jsonrpc_cors: Some("null".into()),
flag_jsonrpc_apis: "web3,eth,net,personal,ethcore,traces,rpc".into(),
flag_jsonrpc_apis: "web3,eth,net,ethcore,traces,rpc,personal_safe".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,personal,ethcore,traces,rpc".into(),
flag_ipc_apis: "web3,eth,net,ethcore,traces,rpc,personal_safe".into(),
// DAPPS
flag_no_dapps: false,
@@ -518,6 +567,7 @@ mod tests {
flag_reseal_min_period: 4000u64,
flag_work_queue_size: 20usize,
flag_tx_gas_limit: Some("6283184".into()),
flag_tx_time_limit: Some(100u64),
flag_relay_set: "cheap".into(),
flag_usd_per_tx: "0".into(),
flag_usd_per_eth: "auto".into(),
@@ -525,17 +575,27 @@ mod tests {
flag_gas_floor_target: "4700000".into(),
flag_gas_cap: "6283184".into(),
flag_extra_data: Some("Parity".into()),
<<<<<<< HEAD
flag_tx_queue_size: 2048usize,
flag_tx_queue_gas: "auto".into(),
=======
flag_tx_queue_size: 1024usize,
flag_tx_queue_gas: "auto".into(),
flag_tx_queue_strategy: "gas_factor".into(),
flag_tx_queue_ban_count: 1u16,
flag_tx_queue_ban_time: 180u16,
>>>>>>> parity/master
flag_remove_solved: false,
flag_notify_work: Some("http://localhost:3001".into()),
// -- Footprint Options
flag_tracing: "auto".into(),
flag_pruning: "auto".into(),
flag_pruning_history: 64u64,
flag_cache_size_db: 64u32,
flag_cache_size_blocks: 8u32,
flag_cache_size_queue: 50u32,
flag_cache_size_state: 25u32,
flag_cache_size: Some(128),
flag_fast_and_loose: false,
flag_db_compaction: "ssd".into(),
@@ -545,6 +605,7 @@ mod tests {
flag_from: "1".into(),
flag_to: "latest".into(),
flag_format: None,
flag_no_seal_check: false,
// -- Snapshot Optons
flag_at: "latest".into(),
@@ -631,9 +692,13 @@ mod tests {
}),
network: Some(Network {
disable: Some(false),
warp: Some(false),
port: None,
min_peers: Some(10),
max_peers: Some(20),
max_pending_peers: Some(30),
snapshot_peers: Some(40),
allow_ips: Some("public".into()),
nat: Some("any".into()),
id: None,
bootnodes: None,
@@ -676,9 +741,18 @@ mod tests {
price_update_period: Some("hourly".into()),
gas_floor_target: None,
gas_cap: None,
<<<<<<< HEAD
tx_queue_size: Some(2048),
tx_queue_gas: Some("auto".into()),
=======
tx_queue_size: Some(1024),
tx_queue_gas: Some("auto".into()),
tx_queue_strategy: None,
tx_queue_ban_count: None,
tx_queue_ban_time: None,
>>>>>>> parity/master
tx_gas_limit: None,
tx_time_limit: None,
extra_data: None,
remove_solved: None,
notify_work: None,
@@ -686,11 +760,13 @@ mod tests {
footprint: Some(Footprint {
tracing: Some("on".into()),
pruning: Some("fast".into()),
pruning_history: Some(64),
fast_and_loose: None,
cache_size: None,
cache_size_db: Some(128),
cache_size_blocks: Some(16),
cache_size_queue: Some(100),
cache_size_state: Some(25),
db_compaction: Some("ssd".into()),
fat_db: Some("off".into()),
}),

View File

@@ -14,6 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
macro_rules! println_stderr(
($($arg:tt)*) => { {
let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
r.expect("failed printing to stderr");
} }
);
macro_rules! otry {
($e: expr) => (
match $e {
@@ -39,7 +46,7 @@ macro_rules! usage {
) => {
use toml;
use std::{fs, io, process};
use std::io::Read;
use std::io::{Read, Write};
use util::version;
use docopt::{Docopt, Error as DocoptError};
use helpers::replace_home;
@@ -58,20 +65,20 @@ macro_rules! usage {
match self {
ArgsError::Docopt(e) => e.exit(),
ArgsError::Parsing(errors) => {
println!("There is an error in config file.");
println_stderr!("There is an error in config file.");
for e in &errors {
println!("{}", e);
println_stderr!("{}", e);
}
process::exit(2)
},
ArgsError::Decode(e) => {
println!("You might have supplied invalid parameters in config file.");
println!("{}", e);
println_stderr!("You might have supplied invalid parameters in config file.");
println_stderr!("{}", e);
process::exit(2)
},
ArgsError::Config(path, e) => {
println!("There was an error reading your config file at: {}", path);
println!("{}", e);
println_stderr!("There was an error reading your config file at: {}", path);
println_stderr!("{}", e);
process::exit(2)
}
}
@@ -136,7 +143,7 @@ macro_rules! usage {
let config = match (fs::File::open(&config_file), raw_args.flag_config.is_some()) {
// Load config file
(Ok(mut file), _) => {
println!("Loading config file from {}", &config_file);
println_stderr!("Loading config file from {}", &config_file);
let mut config = String::new();
try!(file.read_to_string(&mut config).map_err(|e| ArgsError::Config(config_file, e)));
try!(Self::parse_config(&config))

View File

@@ -67,10 +67,13 @@ Account Options:
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}).
--min-peers NUM Try to maintain at least NUM peers (default: {flag_min_peers}).
--max-peers NUM Allow up to that many peers (default: {flag_max_peers}).
--max-peers NUM Allow up to NUM peers (default: {flag_max_peers}).
--snapshot-peers NUM Allow additional NUM peers for a snapshot sync
(default: {flag_snapshot_peers}).
--nat METHOD Specify method to use for determining public
address. Must be one of: any, none, upnp,
extip:<IP> (default: {flag_nat}).
@@ -85,6 +88,12 @@ 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:
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})
--max-pending-peers NUM Allow up to NUM pending connections. (default: {flag_max_pending_peers})
API and Console Options:
--no-jsonrpc Disable the JSON-RPC API server. (default: {flag_no_jsonrpc})
@@ -98,7 +107,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.
ethcore, ethcore_set, traces, rpc, personal_safe.
(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
@@ -157,6 +166,11 @@ Sealing/Mining Options:
--tx-gas-limit GAS Apply a limit of GAS as the maximum amount of gas
a single transaction may have for it to be mined.
(default: {flag_tx_gas_limit:?})
--tx-time-limit MS Maximal time for processing single transaction.
If enabled senders/recipients/code of transactions
offending the limit will be banned from being included
in transaction queue for 180 seconds.
(default: {flag_tx_time_limit:?})
--relay-set SET Set of transactions to relay. SET may be:
cheap - Relay any transaction in the queue (this
may include invalid transactions);
@@ -186,8 +200,21 @@ Sealing/Mining Options:
to be included in next block) (default: {flag_tx_queue_size}).
--tx-queue-gas LIMIT Maximum amount of total gas for external transactions in
the queue. LIMIT can be either an amount of gas or
'auto' or 'off'. 'auto' sets the limit to be 2x
'auto' or 'off'. 'auto' sets the limit to be 20x
the current block gas limit. (default: {flag_tx_queue_gas}).
--tx-queue-strategy S Prioritization strategy used to order transactions
in the queue. S may be:
gas - Prioritize txs with low gas limit;
gas_price - Prioritize txs with high gas price;
gas_factor - Prioritize txs using gas price
and gas limit ratio (default: {flag_tx_queue_strategy}).
--tx-queue-ban-count C Number of times maximal time for execution (--tx-time-limit)
can be exceeded before banning sender/recipient/code.
(default: {flag_tx_queue_ban_count})
--tx-queue-ban-time SEC Banning time (in seconds) for offenders of specified
execution time limit. Also number of offending actions
have to reach the threshold within that time.
(default: {flag_tx_queue_ban_time} seconds)
--remove-solved Move solved blocks from the work package queue
instead of cloning them. This gives a slightly
faster import speed, but means that extra solutions
@@ -209,11 +236,15 @@ Footprint Options:
fast - maintain journal overlay. Fast but 50MB used.
auto - use the method most recently synced or
default to fast if none synced (default: {flag_pruning}).
--pruning-history NUM Set a number of recent states to keep when pruning
is active. (default: {flag_pruning_history}).
--cache-size-db MB Override database cache size (default: {flag_cache_size_db}).
--cache-size-blocks MB Specify the prefered size of the blockchain cache in
megabytes (default: {flag_cache_size_blocks}).
--cache-size-queue MB Specify the maximum size of memory to use for block
queue (default: {flag_cache_size_queue}).
--cache-size-state MB Specify the maximum size of memory to use for
the state cache (default: {flag_cache_size_state}).
--cache-size MB Set total amount of discretionary memory to use for
the entire system, overrides other cache and queue
options.a (default: {flag_cache_size:?})
@@ -221,7 +252,8 @@ Footprint Options:
but means an unclean exit is unrecoverable. (default: {flag_fast_and_loose})
--db-compaction TYPE Database compaction type. TYPE may be one of:
ssd - suitable for SSDs and fast HDDs;
hdd - suitable for slow HDDs (default: {flag_db_compaction}).
hdd - suitable for slow HDDs;
auto - determine automatically (default: {flag_db_compaction}).
--fat-db BOOL Build appropriate information to allow enumeration
of all accounts and storage keys. Doubles the size
of the state database. BOOL may be one of on, off
@@ -235,6 +267,7 @@ Import/Export Options:
--format FORMAT For import/export in given format. FORMAT must be
one of 'hex' and 'binary'.
(default: {flag_format:?} = Import: auto, Export: binary)
--no-seal-check Skip block seal check. (default: {flag_no_seal_check})
Snapshot Options:
--at BLOCK Take a snapshot at the given block, which may be an

View File

@@ -22,16 +22,16 @@ use std::cmp::max;
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};
use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP};
use ethcore::client::{VMType, Mode};
use ethcore::miner::MinerOptions;
use ethcore::miner::{MinerOptions, Banning};
use rpc::{IpcConfiguration, HttpConfiguration};
use ethcore_rpc::NetworkSettings;
use cache::CacheConfig;
use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home,
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit};
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, SpecType};
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy};
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras};
use ethcore_logger::Config as LogConfig;
use dir::Directories;
use dapps::Configuration as DappsConfiguration;
@@ -73,6 +73,7 @@ impl Configuration {
pub fn into_command(self) -> Result<Cmd, 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 miner_options = try!(self.miner_options());
@@ -88,6 +89,7 @@ impl Configuration {
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 dapps_conf = self.dapps_config();
@@ -145,12 +147,14 @@ impl Configuration {
file_path: self.args.arg_file.clone(),
format: format,
pruning: pruning,
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,
};
Cmd::Blockchain(BlockchainCmd::Import(import_cmd))
} else if self.args.cmd_export {
@@ -162,6 +166,7 @@ impl Configuration {
file_path: self.args.arg_file.clone(),
format: format,
pruning: pruning,
pruning_history: pruning_history,
compaction: compaction,
wal: wal,
mode: mode,
@@ -169,6 +174,7 @@ impl Configuration {
fat_db: fat_db,
from_block: try!(to_block_id(&self.args.flag_from)),
to_block: try!(to_block_id(&self.args.flag_to)),
check_seal: !self.args.flag_no_seal_check,
};
Cmd::Blockchain(BlockchainCmd::Export(export_cmd))
} else if self.args.cmd_snapshot {
@@ -177,6 +183,7 @@ impl Configuration {
dirs: dirs,
spec: spec,
pruning: pruning,
pruning_history: pruning_history,
logger_config: logger_config,
mode: mode,
tracing: tracing,
@@ -194,6 +201,7 @@ impl Configuration {
dirs: dirs,
spec: spec,
pruning: pruning,
pruning_history: pruning_history,
logger_config: logger_config,
mode: mode,
tracing: tracing,
@@ -217,6 +225,7 @@ impl Configuration {
dirs: dirs,
spec: spec,
pruning: pruning,
pruning_history: pruning_history,
daemon: daemon,
logger_config: logger_config,
miner_options: miner_options,
@@ -234,6 +243,7 @@ impl Configuration {
wal: wal,
vm_type: vm_type,
enable_network: enable_network,
warp_sync: warp_sync,
geth_compatibility: geth_compatibility,
signer_port: signer_port,
net_settings: self.network_settings(),
@@ -243,6 +253,7 @@ impl Configuration {
name: self.args.flag_identity,
custom_bootnodes: self.args.flag_bootnodes.is_some(),
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
check_seal: !self.args.flag_no_seal_check,
};
Cmd::Run(run_cmd)
};
@@ -291,7 +302,12 @@ impl Configuration {
fn cache_config(&self) -> CacheConfig {
match self.args.flag_cache_size.or(self.args.flag_cache) {
Some(size) => CacheConfig::new_with_total_cache_size(size),
None => CacheConfig::new(self.args.flag_cache_size_db, self.args.flag_cache_size_blocks, self.args.flag_cache_size_queue),
None => CacheConfig::new(
self.args.flag_cache_size_db,
self.args.flag_cache_size_blocks,
self.args.flag_cache_size_queue,
self.args.flag_cache_size_state,
),
}
}
@@ -316,10 +332,27 @@ 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 min_peers(&self) -> u32 {
self.args.flag_peers.unwrap_or(self.args.flag_min_peers) as u32
}
fn max_pending_peers(&self) -> u32 {
self.args.flag_max_pending_peers as u32
}
fn snapshot_peers(&self) -> u32 {
self.args.flag_snapshot_peers as u32
}
fn work_notify(&self) -> Vec<String> {
self.args.flag_notify_work.as_ref().map_or_else(Vec::new, |s| s.split(',').map(|s| s.to_owned()).collect())
}
@@ -349,10 +382,19 @@ impl Configuration {
},
tx_queue_size: self.args.flag_tx_queue_size,
tx_queue_gas_limit: try!(to_gas_limit(&self.args.flag_tx_queue_gas)),
tx_queue_strategy: try!(to_queue_strategy(&self.args.flag_tx_queue_strategy)),
pending_set: try!(to_pending_set(&self.args.flag_relay_set)),
reseal_min_period: Duration::from_millis(self.args.flag_reseal_min_period),
work_queue_size: self.args.flag_work_queue_size,
enable_resubmission: !self.args.flag_remove_solved,
tx_queue_banning: match self.args.flag_tx_time_limit {
Some(limit) => Banning::Enabled {
min_offends: self.args.flag_tx_queue_ban_count,
offend_threshold: Duration::from_millis(limit),
ban_duration: Duration::from_secs(self.args.flag_tx_queue_ban_time as u64),
},
None => Banning::Disabled,
}
};
Ok(options)
@@ -457,25 +499,17 @@ impl Configuration {
ret.discovery_enabled = !self.args.flag_no_discovery && !self.args.flag_nodiscover;
ret.max_peers = self.max_peers();
ret.min_peers = self.min_peers();
ret.snapshot_peers = self.snapshot_peers();
ret.allow_ips = try!(self.allow_ips());
ret.max_pending_peers = self.max_pending_peers();
let mut net_path = PathBuf::from(self.directories().db);
net_path.push("network");
let net_specific_path = net_path.join(&try!(self.network_specific_path()));
ret.config_path = Some(net_path.to_str().unwrap().to_owned());
ret.net_config_path = Some(net_specific_path.to_str().unwrap().to_owned());
ret.reserved_nodes = try!(self.init_reserved_nodes());
ret.allow_non_reserved = !self.args.flag_reserved_only;
Ok(ret)
}
fn network_specific_path(&self) -> Result<PathBuf, String> {
let spec_type : SpecType = try!(self.chain().parse());
let spec = try!(spec_type.spec());
let id = try!(self.network_id());
let mut path = PathBuf::new();
path.push(format!("{}", id.unwrap_or_else(|| spec.network_id())));
Ok(path)
}
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 {
@@ -563,10 +597,10 @@ impl Configuration {
let dapps_path = replace_home(&self.args.flag_dapps_path);
let signer_path = replace_home(&self.args.flag_signer_path);
if self.args.flag_geth {
let geth_path = path::ethereum::default();
::std::fs::create_dir_all(geth_path.as_path()).unwrap_or_else(
|e| warn!("Failed to create '{}' for geth mode: {}", &geth_path.to_str().unwrap(), e));
if self.args.flag_geth && !cfg!(windows) {
let geth_root = if self.args.flag_testnet { path::ethereum::test() } else { path::ethereum::default() };
::std::fs::create_dir_all(geth_root.as_path()).unwrap_or_else(
|e| warn!("Failed to create '{}' for geth mode: {}", &geth_root.to_str().unwrap(), e));
}
if cfg!(feature = "ipc") && !cfg!(feature = "windows") {
@@ -647,6 +681,7 @@ mod tests {
use cli::Args;
use ethcore_rpc::NetworkSettings;
use ethcore::client::{VMType, BlockID};
use ethcore::miner::{MinerOptions, PrioritizationStrategy};
use helpers::{replace_home, default_network_config};
use run::RunCmd;
use signer::Configuration as SignerConfiguration;
@@ -727,12 +762,14 @@ mod tests {
file_path: Some("blockchain.json".into()),
format: Default::default(),
pruning: Default::default(),
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,
})));
}
@@ -747,6 +784,7 @@ mod tests {
dirs: Default::default(),
file_path: Some("blockchain.json".into()),
pruning: Default::default(),
pruning_history: 64,
format: Default::default(),
compaction: Default::default(),
wal: true,
@@ -755,6 +793,7 @@ mod tests {
fat_db: Default::default(),
from_block: BlockID::Number(1),
to_block: BlockID::Latest,
check_seal: true,
})));
}
@@ -769,6 +808,7 @@ mod tests {
dirs: Default::default(),
file_path: Some("blockchain.json".into()),
pruning: Default::default(),
pruning_history: 64,
format: Some(DataFormat::Hex),
compaction: Default::default(),
wal: true,
@@ -777,6 +817,7 @@ mod tests {
fat_db: Default::default(),
from_block: BlockID::Number(1),
to_block: BlockID::Latest,
check_seal: true,
})));
}
@@ -797,6 +838,7 @@ mod tests {
dirs: Default::default(),
spec: Default::default(),
pruning: Default::default(),
pruning_history: 64,
daemon: None,
logger_config: Default::default(),
miner_options: Default::default(),
@@ -804,6 +846,7 @@ mod tests {
ipc_conf: Default::default(),
net_conf: default_network_config(),
network_id: None,
warp_sync: false,
acc_conf: Default::default(),
gas_pricer: Default::default(),
miner_extras: Default::default(),
@@ -823,9 +866,31 @@ mod tests {
custom_bootnodes: false,
fat_db: Default::default(),
no_periodic_snapshot: false,
check_seal: true,
}));
}
#[test]
fn should_parse_mining_options() {
// given
let mut mining_options = MinerOptions::default();
// when
let conf0 = parse(&["parity"]);
let conf1 = parse(&["parity", "--tx-queue-strategy", "gas_factor"]);
let conf2 = parse(&["parity", "--tx-queue-strategy", "gas_price"]);
let conf3 = parse(&["parity", "--tx-queue-strategy", "gas"]);
// then
assert_eq!(conf0.miner_options().unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasFactorAndGasPrice;
assert_eq!(conf1.miner_options().unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasPriceOnly;
assert_eq!(conf2.miner_options().unwrap(), mining_options);
mining_options.tx_queue_strategy = PrioritizationStrategy::GasAndGasPrice;
assert_eq!(conf3.miner_options().unwrap(), mining_options);
}
#[test]
fn should_parse_network_settings() {
// given

View File

@@ -58,6 +58,7 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<We
return Ok(None);
}
let signer_port = deps.apis.signer_service.port();
let url = format!("{}:{}", configuration.interface, configuration.port);
let addr = try!(url.parse().map_err(|_| format!("Invalid Webapps listen host/port given: {}", url)));
@@ -72,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))))
Ok(Some(try!(setup_dapps_server(deps, configuration.dapps_path, &addr, configuration.hosts, auth, signer_port))))
}
pub use self::server::WebappServer;
@@ -90,6 +91,7 @@ mod server {
_url: &SocketAddr,
_allowed_hosts: Option<Vec<String>>,
_auth: Option<(String, String)>,
_signer_port: Option<u16>,
) -> Result<WebappServer, String> {
Err("Your Parity version has been compiled without WebApps support.".into())
}
@@ -100,12 +102,14 @@ mod server {
use super::Dependencies;
use std::sync::Arc;
use std::net::SocketAddr;
use std::io;
use util::{Bytes, Address, U256};
use ethcore::transaction::{Transaction, Action};
use ethcore::client::{Client, BlockChainClient, BlockID};
use rpc_apis;
use ethcore_rpc::is_major_importing;
use ethcore_dapps::ContractClient;
pub use ethcore_dapps::Server as WebappServer;
@@ -115,7 +119,8 @@ mod server {
dapps_path: String,
url: &SocketAddr,
allowed_hosts: Option<Vec<String>>,
auth: Option<(String, String)>
auth: Option<(String, String)>,
signer_port: Option<u16>,
) -> Result<WebappServer, String> {
use ethcore_dapps as dapps;
@@ -124,7 +129,10 @@ mod server {
Arc::new(Registrar { client: deps.client.clone() })
);
let sync = deps.sync.clone();
server.with_sync_status(Arc::new(move || sync.status().is_major_syncing()));
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);
let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext);
let start_result = match auth {
None => {
@@ -136,7 +144,10 @@ mod server {
};
match start_result {
Err(dapps::ServerError::IoError(err)) => Err(format!("WebApps io error: {}", err)),
Err(dapps::ServerError::IoError(err)) => match err.kind() {
io::ErrorKind::AddrInUse => Err(format!("WebApps address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --dapps-port and --dapps-interface options.", url)),
_ => Err(format!("WebApps io error: {}", err)),
},
Err(e) => Err(format!("WebApps error: {:?}", e)),
Ok(server) => {
server.set_panic_handler(move || {

View File

@@ -77,7 +77,8 @@ pub struct DatabaseDirectories {
}
impl DatabaseDirectories {
fn fork_path(&self) -> PathBuf {
/// Base DB directory for the given fork.
pub fn fork_path(&self) -> PathBuf {
let mut dir = Path::new(&self.path).to_path_buf();
dir.push(format!("{:?}{}", H64::from(self.genesis_hash), self.fork_name.as_ref().map(|f| format!("-{}", f)).unwrap_or_default()));
dir
@@ -110,6 +111,13 @@ impl DatabaseDirectories {
dir.push("snapshot");
dir
}
/// Get the path for the network directory.
pub fn network_path(&self) -> PathBuf {
let mut dir = self.fork_path();
dir.push("network");
dir
}
}
#[cfg(test)]

View File

@@ -21,8 +21,8 @@ use std::path::Path;
use std::fs::File;
use util::{clean_0x, U256, Uint, Address, path, CompactionProfile};
use util::journaldb::Algorithm;
use ethcore::client::{Mode, BlockID, VMType, DatabaseCompactionProfile, ClientConfig};
use ethcore::miner::{PendingSet, GasLimit};
use ethcore::client::{Mode, BlockID, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType};
use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy};
use cache::CacheConfig;
use dir::DatabaseDirectories;
use upgrade::upgrade;
@@ -101,6 +101,15 @@ pub fn to_gas_limit(s: &str) -> Result<GasLimit, String> {
}
}
pub fn to_queue_strategy(s: &str) -> Result<PrioritizationStrategy, String> {
match s {
"gas" => Ok(PrioritizationStrategy::GasAndGasPrice),
"gas_price" => Ok(PrioritizationStrategy::GasPriceOnly),
"gas_factor" => Ok(PrioritizationStrategy::GasFactorAndGasPrice),
other => Err(format!("Invalid queue strategy: {}", other)),
}
}
pub fn to_address(s: Option<String>) -> Result<Address, String> {
match s {
Some(ref a) => clean_0x(a).parse().map_err(|_| format!("Invalid address: {:?}", a)),
@@ -176,10 +185,10 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
#[cfg(test)]
pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
use ethsync::NetworkConfiguration;
use ethsync::{NetworkConfiguration, AllowIP};
NetworkConfiguration {
config_path: Some(replace_home("$HOME/.parity/network")),
net_config_path: Some(replace_home("$HOME/.parity/network/1")),
net_config_path: None,
listen_address: Some("0.0.0.0:30303".into()),
public_address: None,
udp_port: None,
@@ -189,6 +198,9 @@ pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
use_secret: None,
max_peers: 50,
min_peers: 25,
snapshot_peers: 0,
max_pending_peers: 64,
allow_ips: AllowIP::All,
reserved_nodes: Vec::new(),
allow_non_reserved: true,
}
@@ -205,6 +217,8 @@ pub fn to_client_config(
vm_type: VMType,
name: String,
pruning: Algorithm,
pruning_history: u64,
check_seal: bool,
) -> ClientConfig {
let mut client_config = ClientConfig::default();
@@ -223,15 +237,21 @@ pub fn to_client_config(
client_config.tracing.max_cache_size = cache_config.traces() as usize * mb;
// in bytes
client_config.tracing.pref_cache_size = cache_config.traces() as usize * 3 / 4 * mb;
// in bytes
client_config.state_cache_size = cache_config.state() as usize * mb;
// in bytes
client_config.jump_table_size = cache_config.jump_tables() as usize * mb;
client_config.mode = mode;
client_config.tracing.enabled = tracing;
client_config.fat_db = fat_db;
client_config.pruning = pruning;
client_config.history = pruning_history;
client_config.db_compaction = compaction;
client_config.db_wal = wal;
client_config.vm_type = vm_type;
client_config.name = name;
client_config.verifier_type = if check_seal { VerifierType::Canon } else { VerifierType::CanonNoSeal };
client_config
}

View File

@@ -26,7 +26,10 @@ use ethsync::{SyncProvider, ManageNetwork};
use util::{Uint, RwLock, Mutex, H256, Colour};
use ethcore::client::*;
use ethcore::views::BlockView;
use ethcore::snapshot::service::Service as SnapshotService;
use ethcore::snapshot::{RestorationStatus, SnapshotService as SS};
use number_prefix::{binary_prefix, Standalone, Prefixed};
use ethcore_rpc::is_major_importing;
pub struct Informant {
chain_info: RwLock<Option<BlockChainInfo>>,
@@ -35,10 +38,20 @@ pub struct Informant {
last_tick: RwLock<Instant>,
with_color: bool,
client: Arc<Client>,
snapshot: Option<Arc<SnapshotService>>,
sync: Option<Arc<SyncProvider>>,
net: Option<Arc<ManageNetwork>>,
last_import: Mutex<Instant>,
skipped: AtomicUsize,
skipped_txs: AtomicUsize,
}
/// Format byte counts to standard denominations.
pub fn format_bytes(b: usize) -> String {
match binary_prefix(b as f64) {
Standalone(bytes) => format!("{} bytes", bytes),
Prefixed(prefix, n) => format!("{:.0} {}B", n, prefix),
}
}
/// Something that can be converted to milliseconds.
@@ -55,7 +68,7 @@ impl MillisecondDuration for Duration {
impl Informant {
/// Make a new instance potentially `with_color` output.
pub fn new(client: Arc<Client>, sync: Option<Arc<SyncProvider>>, net: Option<Arc<ManageNetwork>>, with_color: bool) -> Self {
pub fn new(client: Arc<Client>, sync: Option<Arc<SyncProvider>>, net: Option<Arc<ManageNetwork>>, snapshot: Option<Arc<SnapshotService>>, with_color: bool) -> Self {
Informant {
chain_info: RwLock::new(None),
cache_info: RwLock::new(None),
@@ -63,17 +76,12 @@ impl Informant {
last_tick: RwLock::new(Instant::now()),
with_color: with_color,
client: client,
snapshot: snapshot,
sync: sync,
net: net,
last_import: Mutex::new(Instant::now()),
skipped: AtomicUsize::new(0),
}
}
fn format_bytes(b: usize) -> String {
match binary_prefix(b as f64) {
Standalone(bytes) => format!("{} bytes", bytes),
Prefixed(prefix, n) => format!("{:.0} {}B", n, prefix),
skipped_txs: AtomicUsize::new(0),
}
}
@@ -91,9 +99,16 @@ impl Informant {
let network_config = self.net.as_ref().map(|n| n.network_config());
let sync_status = self.sync.as_ref().map(|s| s.status());
let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3
|| self.sync.as_ref().map_or(false, |s| s.status().is_major_syncing());
if !importing && elapsed < Duration::from_secs(30) {
let importing = is_major_importing(sync_status.map(|s| s.state), self.client.queue_info());
let (snapshot_sync, snapshot_current, snapshot_total) = self.snapshot.as_ref().map_or((false, 0, 0), |s|
match s.status() {
RestorationStatus::Ongoing { state_chunks, block_chunks, state_chunks_done, block_chunks_done } =>
(true, state_chunks_done + block_chunks_done, state_chunks + block_chunks),
_ => (false, 0, 0),
}
);
if !importing && !snapshot_sync && elapsed < Duration::from_secs(30) {
return;
}
@@ -109,27 +124,33 @@ impl Informant {
info!(target: "import", "{} {} {}",
match importing {
true => format!("Syncing {} {} {} {}+{} Qed",
paint(White.bold(), format!("{:>8}", format!("#{}", chain_info.best_block_number))),
paint(White.bold(), format!("{}", chain_info.best_block_hash)),
{
let last_report = match *write_report { Some(ref last_report) => last_report.clone(), _ => ClientReport::default() };
format!("{} blk/s {} tx/s {} Mgas/s",
paint(Yellow.bold(), format!("{:4}", ((report.blocks_imported - last_report.blocks_imported) * 1000) as u64 / elapsed.as_milliseconds())),
paint(Yellow.bold(), format!("{:4}", ((report.transactions_applied - last_report.transactions_applied) * 1000) as u64 / elapsed.as_milliseconds())),
paint(Yellow.bold(), format!("{:3}", ((report.gas_processed - last_report.gas_processed) / From::from(elapsed.as_milliseconds() * 1000)).low_u64()))
)
},
paint(Green.bold(), format!("{:5}", queue_info.unverified_queue_size)),
paint(Green.bold(), format!("{:5}", queue_info.verified_queue_size))
),
true => match snapshot_sync {
false => format!("Syncing {} {} {} {}+{} Qed",
paint(White.bold(), format!("{:>8}", format!("#{}", chain_info.best_block_number))),
paint(White.bold(), format!("{}", chain_info.best_block_hash)),
{
let last_report = match *write_report { Some(ref last_report) => last_report.clone(), _ => ClientReport::default() };
format!("{} blk/s {} tx/s {} Mgas/s",
paint(Yellow.bold(), format!("{:4}", ((report.blocks_imported - last_report.blocks_imported) * 1000) as u64 / elapsed.as_milliseconds())),
paint(Yellow.bold(), format!("{:4}", ((report.transactions_applied - last_report.transactions_applied) * 1000) as u64 / elapsed.as_milliseconds())),
paint(Yellow.bold(), format!("{:3}", ((report.gas_processed - last_report.gas_processed) / From::from(elapsed.as_milliseconds() * 1000)).low_u64()))
)
},
paint(Green.bold(), format!("{:5}", queue_info.unverified_queue_size)),
paint(Green.bold(), format!("{:5}", queue_info.verified_queue_size))
),
true => format!("Syncing snapshot {}/{}", snapshot_current, snapshot_total),
},
false => String::new(),
},
match (&sync_status, &network_config) {
(&Some(ref sync_info), &Some(ref net_config)) => format!("{}{}/{}/{} peers",
match importing {
true => format!("{} ", paint(Green.bold(), format!("{:>8}", format!("#{}", sync_info.last_imported_block_number.unwrap_or(chain_info.best_block_number))))),
false => String::new(),
false => match sync_info.last_imported_old_block_number {
Some(number) => format!("{} ", paint(Yellow.bold(), format!("{:>8}", format!("#{}", number)))),
None => String::new(),
}
},
paint(Cyan.bold(), format!("{:2}", sync_info.num_active_peers)),
paint(Cyan.bold(), format!("{:2}", sync_info.num_peers)),
@@ -138,11 +159,11 @@ impl Informant {
_ => String::new(),
},
format!("{} db {} chain {} queue{}",
paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(report.state_db_mem))),
paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(cache_info.total()))),
paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(queue_info.mem_used))),
paint(Blue.bold(), format!("{:>8}", format_bytes(report.state_db_mem))),
paint(Blue.bold(), format!("{:>8}", format_bytes(cache_info.total()))),
paint(Blue.bold(), format!("{:>8}", format_bytes(queue_info.mem_used))),
match sync_status {
Some(ref sync_info) => format!(" {} sync", paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(sync_info.mem_used)))),
Some(ref sync_info) => format!(" {} sync", paint(Blue.bold(), format!("{:>8}", format_bytes(sync_info.mem_used)))),
_ => String::new(),
}
)
@@ -157,16 +178,23 @@ impl Informant {
impl ChainNotify for Informant {
fn new_blocks(&self, imported: Vec<H256>, _invalid: Vec<H256>, _enacted: Vec<H256>, _retracted: Vec<H256>, _sealed: Vec<H256>, duration: u64) {
let mut last_import = self.last_import.lock();
let queue_info = self.client.queue_info();
let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3
|| self.sync.as_ref().map_or(false, |s| s.status().is_major_syncing());
if Instant::now() > *last_import + Duration::from_secs(1) && !importing {
let sync_state = self.sync.as_ref().map(|s| s.status().state);
let importing = is_major_importing(sync_state, self.client.queue_info());
let ripe = Instant::now() > *last_import + Duration::from_secs(1) && !importing;
let txs_imported = imported.iter()
.take(imported.len() - if ripe {1} else {0})
.filter_map(|h| self.client.block(BlockID::Hash(*h)))
.map(|b| BlockView::new(&b).transactions_count())
.sum();
if ripe {
if let Some(block) = imported.last().and_then(|h| self.client.block(BlockID::Hash(*h))) {
let view = BlockView::new(&block);
let header = view.header();
let tx_count = view.transactions_count();
let size = block.len();
let skipped = self.skipped.load(AtomicOrdering::Relaxed);
let (skipped, skipped_txs) = (self.skipped.load(AtomicOrdering::Relaxed) + imported.len() - 1, self.skipped_txs.load(AtomicOrdering::Relaxed) + txs_imported);
info!(target: "import", "Imported {} {} ({} txs, {} Mgas, {} ms, {} KiB){}",
Colour::White.bold().paint(format!("#{}", header.number())),
Colour::White.bold().paint(format!("{}", header.hash())),
@@ -174,13 +202,22 @@ impl ChainNotify for Informant {
Colour::Yellow.bold().paint(format!("{:.2}", header.gas_used().low_u64() as f32 / 1000000f32)),
Colour::Purple.bold().paint(format!("{:.2}", duration as f32 / 1000000f32)),
Colour::Blue.bold().paint(format!("{:.2}", size as f32 / 1024f32)),
if skipped > 0 { format!(" + another {} block(s)", Colour::Red.bold().paint(format!("{}", skipped))) } else { String::new() }
if skipped > 0 {
format!(" + another {} block(s) containing {} tx(s)",
Colour::Red.bold().paint(format!("{}", skipped)),
Colour::Red.bold().paint(format!("{}", skipped_txs))
)
} else {
String::new()
}
);
self.skipped.store(0, AtomicOrdering::Relaxed);
self.skipped_txs.store(0, AtomicOrdering::Relaxed);
*last_import = Instant::now();
}
self.skipped.store(0, AtomicOrdering::Relaxed);
} else {
self.skipped.fetch_add(imported.len(), AtomicOrdering::Relaxed);
self.skipped_txs.fetch_add(txs_imported, AtomicOrdering::Relaxed);
}
}
}

View File

@@ -61,4 +61,4 @@ impl IoHandler<ClientIoMessage> for ImportIoHandler {
self.info.tick()
}
}
}
}

View File

@@ -207,10 +207,10 @@ fn main() {
match start() {
Ok(result) => {
println!("{}", result);
info!("{}", result);
},
Err(err) => {
println!("{}", err);
info!("{}", err);
process::exit(1);
}
}

View File

@@ -239,9 +239,11 @@ pub fn migrate(path: &Path, pruning: Algorithm, compaction_profile: CompactionPr
// Perform pre-consolidation migrations
if version < CONSOLIDATION_VERSION && exists(&legacy::blocks_database_path(path)) {
println!("Migrating database from version {} to {}", version, CONSOLIDATION_VERSION);
try!(migrate_database(version, legacy::blocks_database_path(path), try!(legacy::blocks_database_migrations(&compaction_profile))));
try!(migrate_database(version, legacy::extras_database_path(path), try!(legacy::extras_database_migrations(&compaction_profile))));
try!(migrate_database(version, legacy::state_database_path(path), try!(legacy::state_database_migrations(pruning, &compaction_profile))));
try!(migrate_database(version, legacy::blocks_database_path(path), try!(legacy::blocks_database_migrations(&compaction_profile))));
let db_path = consolidated_database_path(path);
// Remove the database dir (it shouldn't exist anyway, but it might when migration was interrupted)
let _ = fs::remove_dir_all(db_path.clone());
@@ -257,6 +259,9 @@ pub fn migrate(path: &Path, pruning: Algorithm, compaction_profile: CompactionPr
println!("Migration finished");
}
// update version so we can apply post-consolidation migrations.
let version = ::std::cmp::max(CONSOLIDATION_VERSION, version);
// Further migrations
if version >= CONSOLIDATION_VERSION && version < CURRENT_VERSION && exists(&consolidated_database_path(path)) {
println!("Migrating database from version {} to {}", ::std::cmp::max(CONSOLIDATION_VERSION, version), CURRENT_VERSION);

View File

@@ -17,6 +17,7 @@
use std::fmt;
use std::sync::Arc;
use std::net::SocketAddr;
use std::io;
use io::PanicHandler;
use ethcore_rpc::{RpcServerError, RpcServer as Server};
use jsonipc;
@@ -108,7 +109,10 @@ pub fn setup_http_rpc_server(
let ph = dependencies.panic_handler.clone();
let start_result = server.start_http(url, cors_domains, allowed_hosts, ph);
match start_result {
Err(RpcServerError::IoError(err)) => Err(format!("RPC io error: {}", err)),
Err(RpcServerError::IoError(err)) => match err.kind() {
io::ErrorKind::AddrInUse => Err(format!("RPC address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --jsonrpc-port and --jsonrpc-interface options.", url)),
_ => Err(format!("RPC io error: {}", err)),
},
Err(e) => Err(format!("RPC error: {:?}", e)),
Ok(server) => Ok(server),
}

View File

@@ -23,6 +23,7 @@ use util::RotatingLogger;
use ethcore::miner::{Miner, ExternalMiner};
use ethcore::client::Client;
use ethcore::account_provider::AccountProvider;
use ethcore::snapshot::SnapshotService;
use ethsync::{ManageNetwork, SyncProvider};
use ethcore_rpc::{Extendable, NetworkSettings};
pub use ethcore_rpc::SignerService;
@@ -33,7 +34,8 @@ pub enum Api {
Web3,
Net,
Eth,
Personal,
PersonalSafe,
PersonalAccounts,
Signer,
Ethcore,
EthcoreSet,
@@ -51,7 +53,8 @@ impl FromStr for Api {
"web3" => Ok(Web3),
"net" => Ok(Net),
"eth" => Ok(Eth),
"personal" => Ok(Personal),
"personal" => Ok(PersonalAccounts),
"personal_safe" => Ok(PersonalSafe),
"signer" => Ok(Signer),
"ethcore" => Ok(Ethcore),
"ethcore_set" => Ok(EthcoreSet),
@@ -93,9 +96,9 @@ impl FromStr for ApiSet {
}
pub struct Dependencies {
pub signer_port: Option<u16>,
pub signer_service: Arc<SignerService>,
pub client: Arc<Client>,
pub snapshot: Arc<SnapshotService>,
pub sync: Arc<SyncProvider>,
pub net: Arc<ManageNetwork>,
pub secret_store: Arc<AccountProvider>,
@@ -105,6 +108,7 @@ pub struct Dependencies {
pub settings: Arc<NetworkSettings>,
pub net_service: Arc<ManageNetwork>,
pub geth_compatibility: bool,
pub dapps_port: Option<u16>,
}
fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
@@ -114,7 +118,8 @@ fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
Api::Web3 => ("web3", "1.0"),
Api::Net => ("net", "1.0"),
Api::Eth => ("eth", "1.0"),
Api::Personal => ("personal", "1.0"),
Api::PersonalSafe => ("personal_safe", "1.0"),
Api::PersonalAccounts => ("personal", "1.0"),
Api::Signer => ("signer", "1.0"),
Api::Ethcore => ("ethcore", "1.0"),
Api::EthcoreSet => ("ethcore_set", "1.0"),
@@ -131,11 +136,11 @@ impl ApiSet {
match *self {
ApiSet::List(ref apis) => apis.clone(),
ApiSet::UnsafeContext => {
vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Ethcore, Api::Traces, Api::Rpc]
vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc, Api::PersonalSafe]
.into_iter().collect()
},
_ => {
vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Signer, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc]
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()
},
}
@@ -158,6 +163,7 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
Api::Eth => {
let client = EthClient::new(
&deps.client,
&deps.snapshot,
&deps.sync,
&deps.secret_store,
&deps.miner,
@@ -172,21 +178,36 @@ 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_port.is_some() {
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());
}
},
Api::Personal => {
server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner, deps.signer_port, deps.geth_compatibility).to_delegate());
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::Signer => {
server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_service).to_delegate());
},
Api::Ethcore => {
let signer = deps.signer_port.map(|_| deps.signer_service.clone());
server.add_delegate(EthcoreClient::new(&deps.client, &deps.miner, &deps.sync, &deps.net_service, deps.logger.clone(), deps.settings.clone(), signer).to_delegate())
let signer = match deps.signer_service.is_enabled() {
true => Some(deps.signer_service.clone()),
false => None,
};
server.add_delegate(EthcoreClient::new(
&deps.client,
&deps.miner,
&deps.sync,
&deps.net_service,
deps.logger.clone(),
deps.settings.clone(),
signer,
deps.dapps_port,
).to_delegate())
},
Api::EthcoreSet => {
server.add_delegate(EthcoreSetClient::new(&deps.client, &deps.miner, &deps.net_service).to_delegate())
@@ -212,7 +233,8 @@ 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::Personal, "personal".parse().unwrap());
assert_eq!(Api::PersonalAccounts, "personal".parse().unwrap());
assert_eq!(Api::PersonalSafe, "personal_safe".parse().unwrap());
assert_eq!(Api::Signer, "signer".parse().unwrap());
assert_eq!(Api::Ethcore, "ethcore".parse().unwrap());
assert_eq!(Api::EthcoreSet, "ethcore_set".parse().unwrap());
@@ -233,14 +255,14 @@ mod test {
#[test]
fn test_api_set_unsafe_context() {
let expected = vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Ethcore, Api::Traces, Api::Rpc]
let expected = vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc, Api::PersonalSafe]
.into_iter().collect();
assert_eq!(ApiSet::UnsafeContext.list_apis(), expected);
}
#[test]
fn test_api_set_safe_context() {
let expected = vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Signer, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc]
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();
assert_eq!(ApiSet::SafeContext.list_apis(), expected);
}

View File

@@ -18,16 +18,16 @@ use std::sync::{Arc, Mutex, Condvar};
use ctrlc::CtrlC;
use fdlimit::raise_fd_limit;
use ethcore_logger::{Config as LogConfig, setup_log};
use ethcore_rpc::NetworkSettings;
use ethcore_rpc::{NetworkSettings, is_major_importing};
use ethsync::NetworkConfiguration;
use util::{Colour, version, U256};
use io::{MayPanic, ForwardPanic, PanicHandler};
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, ChainNotify};
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, ChainNotify, BlockChainClient};
use ethcore::service::ClientService;
use ethcore::account_provider::AccountProvider;
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
use ethcore::snapshot;
use ethsync::{SyncConfig, SyncProvider};
use ethsync::SyncConfig;
use informant::Informant;
use rpc::{HttpServer, IpcServer, HttpConfiguration, IpcConfiguration};
@@ -53,7 +53,7 @@ use url;
const SNAPSHOT_PERIOD: u64 = 10000;
// how many blocks to wait before starting a periodic snapshot.
const SNAPSHOT_HISTORY: u64 = 500;
const SNAPSHOT_HISTORY: u64 = 100;
#[derive(Debug, PartialEq)]
pub struct RunCmd {
@@ -61,6 +61,7 @@ pub struct RunCmd {
pub dirs: Directories,
pub spec: SpecType,
pub pruning: Pruning,
pub pruning_history: u64,
/// Some if execution should be daemonized. Contains pid_file path.
pub daemon: Option<String>,
pub logger_config: LogConfig,
@@ -69,6 +70,7 @@ pub struct RunCmd {
pub ipc_conf: IpcConfiguration,
pub net_conf: NetworkConfiguration,
pub network_id: Option<U256>,
pub warp_sync: bool,
pub acc_conf: AccountsConfig,
pub gas_pricer: GasPricerConfig,
pub miner_extras: MinerExtras,
@@ -88,6 +90,7 @@ pub struct RunCmd {
pub name: String,
pub custom_bootnodes: bool,
pub no_periodic_snapshot: bool,
pub check_seal: bool,
}
pub fn execute(cmd: RunCmd) -> Result<(), String> {
@@ -132,7 +135,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
let snapshot_path = db_dirs.snapshot_path();
// execute upgrades
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile()));
try!(execute_upgrades(&db_dirs, algorithm, cmd.compaction.compaction_profile(db_dirs.fork_path().as_path())));
// run in daemon mode
if let Some(pid_file) = cmd.daemon {
@@ -170,6 +173,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
sync_config.subprotocol_name.clone_from_slice(spec.subprotocol_name().as_bytes());
}
sync_config.fork_block = spec.fork_block();
sync_config.warp_sync = cmd.warp_sync;
// prepare account provider
let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf)));
@@ -193,6 +197,8 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
cmd.vm_type,
cmd.name,
algorithm,
cmd.pruning_history,
cmd.check_seal,
);
// set up bootnodes
@@ -201,6 +207,9 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
net_conf.boot_nodes = spec.nodes.clone();
}
// set network path.
net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned());
// create supervisor
let mut hypervisor = modules::hypervisor(&cmd.dirs.ipc_path());
@@ -226,7 +235,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
// create sync object
let (sync_provider, manage_network, chain_notify) = try!(modules::sync(
&mut hypervisor, sync_config, net_conf.into(), client.clone(), snapshot_service, &cmd.logger_config,
&mut hypervisor, sync_config, net_conf.into(), client.clone(), snapshot_service.clone(), &cmd.logger_config,
).map_err(|e| format!("Sync error: {}", e)));
service.add_notify(chain_notify.clone());
@@ -239,10 +248,10 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
// set up dependencies for rpc servers
let signer_path = cmd.signer_conf.signer_path.clone();
let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies {
signer_port: cmd.signer_port,
signer_service: Arc::new(rpc_apis::SignerService::new(move || {
signer::generate_new_token(signer_path.clone()).map_err(|e| format!("{:?}", e))
})),
}, cmd.signer_port)),
snapshot: snapshot_service.clone(),
client: client.clone(),
sync: sync_provider.clone(),
net: manage_network.clone(),
@@ -253,6 +262,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_port: match cmd.dapps_conf.enabled {
true => Some(cmd.dapps_conf.port),
false => None,
},
});
let dependencies = rpc::Dependencies {
@@ -282,7 +295,13 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
// start signer server
let signer_server = try!(signer::start(cmd.signer_conf, signer_deps));
let informant = Arc::new(Informant::new(service.client(), Some(sync_provider.clone()), Some(manage_network.clone()), cmd.logger_config.color));
let informant = Arc::new(Informant::new(
service.client(),
Some(sync_provider.clone()),
Some(manage_network.clone()),
Some(snapshot_service.clone()),
cmd.logger_config.color
));
let info_notify: Arc<ChainNotify> = informant.clone();
service.add_notify(info_notify);
let io_handler = Arc::new(ClientIoHandler {
@@ -302,7 +321,7 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
let sync = sync_provider.clone();
let watcher = Arc::new(snapshot::Watcher::new(
service.client(),
move || sync.status().is_major_syncing(),
move || is_major_importing(Some(sync.status().state), client.queue_info()),
service.io().channel(),
SNAPSHOT_PERIOD,
SNAPSHOT_HISTORY,

View File

@@ -103,7 +103,10 @@ fn do_start(conf: Configuration, deps: Dependencies) -> Result<SignerServer, Str
};
match start_result {
Err(signer::ServerError::IoError(err)) => Err(format!("Trusted Signer Error: {}", err)),
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)),
_ => Err(format!("Trusted Signer io error: {}", err)),
},
Err(e) => Err(format!("Trusted Signer Error: {:?}", e)),
Ok(server) => {
deps.panic_handler.forward_from(&server);

View File

@@ -54,6 +54,7 @@ pub struct SnapshotCommand {
pub dirs: Directories,
pub spec: SpecType,
pub pruning: Pruning,
pub pruning_history: u64,
pub logger_config: LogConfig,
pub mode: Mode,
pub tracing: Switch,
@@ -80,7 +81,7 @@ fn restore_using<R: SnapshotReader>(snapshot: Arc<SnapshotService>, reader: &R,
let informant_handle = snapshot.clone();
::std::thread::spawn(move || {
while let RestorationStatus::Ongoing { state_chunks_done, block_chunks_done } = informant_handle.status() {
while let RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } = informant_handle.status() {
info!("Processed {}/{} state chunks and {}/{} block chunks.",
state_chunks_done, num_state, block_chunks_done, num_blocks);
::std::thread::sleep(Duration::from_secs(5));
@@ -159,10 +160,10 @@ impl SnapshotCommand {
let snapshot_path = db_dirs.snapshot_path();
// execute upgrades
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile()));
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);
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 service = try!(ClientService::start(
client_config,
@@ -231,9 +232,8 @@ impl SnapshotCommand {
let cur_size = p.size();
if cur_size != last_size {
last_size = cur_size;
info!("Snapshot: {} accounts {} blocks {} bytes", p.accounts(), p.blocks(), p.size());
} else {
info!("Snapshot: No progress since last update.");
let bytes = ::informant::format_bytes(p.size());
info!("Snapshot: {} accounts {} blocks {}", p.accounts(), p.blocks(), bytes);
}
::std::thread::sleep(Duration::from_secs(5));