diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 74175d4a4..a66707e00 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -22,21 +22,18 @@ use std::sync::{Arc, Weak}; use std::path::{Path, PathBuf}; use std::fmt; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; -use std::time::Instant; +use std::time::{Instant, Duration}; +use time::precise_time_ns; // util +use util::{journaldb, rlp, Bytes, Stream, View, PerfTimer, Itertools, Mutex, RwLock, Colour}; +use util::journaldb::JournalDB; +use util::rlp::{RlpStream, Rlp, UntrustedRlp}; use util::numbers::*; use util::panics::*; use util::io::*; -use util::rlp; use util::sha3::*; -use util::Bytes; -use util::rlp::{RlpStream, Rlp, UntrustedRlp}; -use util::journaldb; -use util::journaldb::JournalDB; use util::kvdb::*; -use util::{Stream, View, PerfTimer, Itertools}; -use util::{Mutex, RwLock}; // other use views::BlockView; @@ -145,6 +142,8 @@ pub struct Client { notify: RwLock>>, queue_transactions: AtomicUsize, previous_enode: Mutex>, + skipped: AtomicUsize, + last_import: Mutex, last_hashes: RwLock>, } @@ -233,6 +232,8 @@ impl Client { notify: RwLock::new(None), queue_transactions: AtomicUsize::new(0), previous_enode: Mutex::new(None), + skipped: AtomicUsize::new(0), + last_import: Mutex::new(Instant::now()), last_hashes: RwLock::new(VecDeque::new()), }; Ok(Arc::new(client)) @@ -367,16 +368,21 @@ impl Client { for block in blocks { let header = &block.header; + let start = precise_time_ns(); if invalid_blocks.contains(&header.parent_hash) { invalid_blocks.insert(header.hash()); continue; } + let tx_count = block.transactions.len(); + let size = block.bytes.len(); + let closed_block = self.check_and_close_block(&block); if let Err(_) = closed_block { invalid_blocks.insert(header.hash()); continue; } + let closed_block = closed_block.unwrap(); imported_blocks.push(header.hash()); @@ -384,7 +390,30 @@ impl Client { import_results.push(route); self.report.write().accrue_block(&block); - trace!(target: "client", "Imported #{} ({})", header.number(), header.hash()); + + let duration_ns = precise_time_ns() - start; + + let mut last_import = self.last_import.lock(); + if Instant::now() > *last_import + Duration::from_secs(1) { + let queue_info = self.queue_info(); + let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3; + if !importing { + let skipped = self.skipped.load(AtomicOrdering::Relaxed); + info!(target: "import", "Imported {} {} ({} txs, {} Mgas, {} ms, {} KiB){}", + Colour::White.bold().paint(format!("#{}", header.number())), + Colour::White.bold().paint(format!("{}", header.hash())), + Colour::Yellow.bold().paint(format!("{}", tx_count)), + Colour::Yellow.bold().paint(format!("{:.2}", header.gas_used.low_u64() as f32 / 1000000f32)), + Colour::Purple.bold().paint(format!("{:.2}", duration_ns 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() } + ); + *last_import = Instant::now(); + } + self.skipped.store(0, AtomicOrdering::Relaxed); + } else { + self.skipped.fetch_add(1, AtomicOrdering::Relaxed); + } } let imported = imported_blocks.len(); diff --git a/parity/informant.rs b/parity/informant.rs index e8dc14d9a..1235842d2 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . extern crate ansi_term; -use self::ansi_term::Colour::{White, Yellow, Green, Cyan, Blue, Purple}; +use self::ansi_term::Colour::{White, Yellow, Green, Cyan, Blue}; use self::ansi_term::Style; use std::time::{Instant, Duration}; @@ -83,12 +83,17 @@ impl Informant { return; } - *self.last_tick.write() = Instant::now(); - let chain_info = client.chain_info(); let queue_info = client.queue_info(); let cache_info = client.blockchain_cache_info(); + let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3; + if !importing && elapsed < Duration::from_secs(30) { + return; + } + + *self.last_tick.write() = Instant::now(); + let mut write_report = self.report.write(); let report = client.report(); @@ -97,42 +102,46 @@ impl Informant { false => t, }; - if let (_, _, &Some(ref last_report)) = ( - self.chain_info.read().deref(), - self.cache_info.read().deref(), - write_report.deref() - ) { - println!("{} {} {} blk/s {} tx/s {} Mgas/s {}{}+{} Qed {} db {} chain {} queue{}", - paint(White.bold(), format!("{:>8}", format!("#{}", chain_info.best_block_number))), - paint(White.bold(), format!("{}", chain_info.best_block_hash)), - - 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())), - - match maybe_status { - Some((ref sync_info, ref net_config)) => { - format!("{}/{}/{} peers {} ", - paint(Green.bold(), format!("{:2}", sync_info.num_active_peers)), - paint(Green.bold(), format!("{:2}", sync_info.num_peers)), - paint(Green.bold(), format!("{:2}", net_config.ideal_peers)), - paint(Cyan.bold(), format!("{:>8}", format!("#{}", sync_info.last_imported_block_number.unwrap_or(chain_info.best_block_number)))), + info!("{} {} {}", + match importing { + true => format!("{} {} {} {}+{} 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.deref() { &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())) ) - } - None => String::new() - }, - - paint(Blue.bold(), format!("{:5}", queue_info.unverified_queue_size)), - paint(Blue.bold(), format!("{:5}", queue_info.verified_queue_size)), - - paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(report.state_db_mem))), - paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(cache_info.total()))), - paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(queue_info.mem_used))), - if let Some((ref sync_info, _)) = maybe_status { - format!(" {} sync", paint(Purple.bold(), format!("{:>8}", Informant::format_bytes(sync_info.mem_used)))) - } else { String::new() }, - ); - } + }, + paint(Green.bold(), format!("{:5}", queue_info.unverified_queue_size)), + paint(Green.bold(), format!("{:5}", queue_info.verified_queue_size)) + ), + false => String::new(), + }, + match maybe_status { + Some((ref sync_info, 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(), + }, + paint(Cyan.bold(), format!("{:2}", sync_info.num_active_peers)), + paint(Cyan.bold(), format!("{:2}", sync_info.num_peers)), + paint(Cyan.bold(), format!("{:2}", net_config.ideal_peers)) + ), + None => 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))), + match maybe_status { + Some((ref sync_info, _)) => format!(" {} sync", paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(sync_info.mem_used)))), + _ => String::new(), + } + ) + ); *self.chain_info.write().deref_mut() = Some(chain_info); *self.cache_info.write().deref_mut() = Some(cache_info); diff --git a/parity/main.rs b/parity/main.rs index 933d0dfaa..fbfa76510 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -83,7 +83,7 @@ use std::thread::sleep; use std::time::Duration; use rustc_serialize::hex::FromHex; use ctrlc::CtrlC; -use util::{H256, ToPretty, PayloadInfo, Bytes, Colour, version, journaldb}; +use util::{H256, ToPretty, PayloadInfo, Bytes, Colour, version, journaldb, RotatingLogger}; use util::panics::{MayPanic, ForwardPanic, PanicHandler}; use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError, ChainNotify, Mode}; @@ -129,6 +129,13 @@ fn execute(conf: Configuration) { daemonize(&conf); } + // Setup panic handler + let panic_handler = PanicHandler::new_in_arc(); + // Setup logging + let logger = setup_log::setup_log(&conf.args.flag_logging, conf.have_color(), &conf.args.flag_log_file); + // Raise fdlimit + unsafe { ::fdlimit::raise_fd_limit(); } + if conf.args.cmd_account { execute_account_cli(conf); return; @@ -140,16 +147,16 @@ fn execute(conf: Configuration) { } if conf.args.cmd_export { - execute_export(conf); + execute_export(conf, panic_handler); return; } if conf.args.cmd_import { - execute_import(conf); + execute_import(conf, panic_handler); return; } - execute_client(conf, spec, client_config); + execute_client(conf, spec, client_config, panic_handler, logger); } #[cfg(not(windows))] @@ -169,7 +176,7 @@ fn daemonize(_conf: &Configuration) { fn execute_upgrades(conf: &Configuration, spec: &Spec, client_config: &ClientConfig) { match ::upgrade::upgrade(Some(&conf.path())) { Ok(upgrades_applied) if upgrades_applied > 0 => { - println!("Executed {} upgrade scripts - ok", upgrades_applied); + debug!("Executed {} upgrade scripts - ok", upgrades_applied); }, Err(e) => { die!("Error upgrading parity data: {:?}", e); @@ -184,15 +191,7 @@ fn execute_upgrades(conf: &Configuration, spec: &Spec, client_config: &ClientCon } } -fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) { - // Setup panic handler - let panic_handler = PanicHandler::new_in_arc(); - - // Setup logging - let logger = setup_log::setup_log(&conf.args.flag_logging, conf.have_color(), &conf.args.flag_log_file); - // Raise fdlimit - unsafe { ::fdlimit::raise_fd_limit(); } - +fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig, panic_handler: Arc, logger: Arc) { info!("Starting {}", Colour::White.bold().paint(format!("{}", version()))); info!("Using state DB journalling strategy {}", Colour::White.bold().paint(match client_config.pruning { journaldb::Algorithm::Archive => "archive", @@ -337,15 +336,7 @@ enum DataFormat { Binary, } -fn execute_export(conf: Configuration) { - // Setup panic handler - let panic_handler = PanicHandler::new_in_arc(); - - // Setup logging - let _logger = setup_log::setup_log(&conf.args.flag_logging, conf.have_color(), &conf.args.flag_log_file); - // Raise fdlimit - unsafe { ::fdlimit::raise_fd_limit(); } - +fn execute_export(conf: Configuration, panic_handler: Arc) { let spec = conf.spec(); let client_config = conf.client_config(&spec); @@ -398,15 +389,7 @@ fn execute_export(conf: Configuration) { } } -fn execute_import(conf: Configuration) { - // Setup panic handler - let panic_handler = PanicHandler::new_in_arc(); - - // Setup logging - let _logger = setup_log::setup_log(&conf.args.flag_logging, conf.have_color(), &conf.args.flag_log_file); - // Raise fdlimit - unsafe { ::fdlimit::raise_fd_limit(); } - +fn execute_import(conf: Configuration, panic_handler: Arc) { let spec = conf.spec(); let client_config = conf.client_config(&spec); @@ -441,11 +424,11 @@ fn execute_import(conf: Configuration) { first_read = instream.read(&mut(first_bytes[..])).unwrap_or_else(|_| die!("Error reading from the file/stream.")); match first_bytes[0] { 0xf9 => { - println!("Autodetected binary data format."); + info!("Autodetected binary data format."); DataFormat::Binary } _ => { - println!("Autodetected hex data format."); + info!("Autodetected hex data format."); DataFormat::Hex } } @@ -496,9 +479,10 @@ fn execute_signer(conf: Configuration) { } let path = conf.directories().signer; - new_token(path).unwrap_or_else(|e| { + let code = new_token(path).unwrap_or_else(|e| { die!("Error generating token: {:?}", e) }); + println!("This key code will authorise your System Signer UI: {}", if conf.args.flag_no_color { code } else { format!("{}", Colour::White.bold().paint(code)) }); } fn execute_account_cli(conf: Configuration) { diff --git a/parity/signer.rs b/parity/signer.rs index aaad81389..4cf9b006d 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -54,13 +54,13 @@ fn codes_path(path: String) -> PathBuf { p } -pub fn new_token(path: String) -> io::Result<()> { +pub fn new_token(path: String) -> io::Result { let path = codes_path(path); let mut codes = try!(signer::AuthCodes::from_file(&path)); let code = try!(codes.generate_new()); try!(codes.to_file(&path)); - info!("This key code will authorise your System Signer UI: {}", Colour::White.bold().paint(code)); - Ok(()) + trace!("New key code created: {}", Colour::White.bold().paint(&code[..])); + Ok(code) } fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer { diff --git a/parity/upgrade.rs b/parity/upgrade.rs index e976535b0..7e5b73622 100644 --- a/parity/upgrade.rs +++ b/parity/upgrade.rs @@ -64,7 +64,6 @@ impl UpgradeKey { // dummy upgrade (remove when the first one is in) fn dummy_upgrade() -> Result<(), Error> { - println!("Adding ver.lock"); Ok(()) } diff --git a/rpc/src/v1/impls/personal_signer.rs b/rpc/src/v1/impls/personal_signer.rs index a31a3820f..d9c3be21d 100644 --- a/rpc/src/v1/impls/personal_signer.rs +++ b/rpc/src/v1/impls/personal_signer.rs @@ -71,25 +71,25 @@ impl PersonalSigner for SignerClient where C: Mini let client = take_weak!(self.client); let miner = take_weak!(self.miner); queue.peek(&id).and_then(|confirmation| { - let mut request = confirmation.transaction; - // apply modification - if let Some(gas_price) = modification.gas_price { - request.gas_price = Some(gas_price.into()); - } + let mut request = confirmation.transaction; + // apply modification + if let Some(gas_price) = modification.gas_price { + request.gas_price = Some(gas_price.into()); + } - let sender = request.from; + let sender = request.from; - match unlock_sign_and_dispatch(&*client, &*miner, request, &*accounts, sender, pass) { - Ok(hash) => { - queue.request_confirmed(id, Ok(hash.clone())); - Some(to_value(&hash)) - }, - _ => None - } - }) - .unwrap_or_else(|| { - to_value(&false) - }) + match unlock_sign_and_dispatch(&*client, &*miner, request, &*accounts, sender, pass) { + Ok(hash) => { + queue.request_confirmed(id, Ok(hash.clone())); + Some(to_value(&hash)) + }, + _ => None + } + }) + .unwrap_or_else(|| { + to_value(&false) + }) } ) }