From 42fc770d30f9d0a16aa4aef2da89d31c6c966186 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 5 Dec 2016 16:25:03 +0300 Subject: [PATCH 01/14] use crates.io crate --- Cargo.lock | 4 +- Cargo.toml | 2 +- util/fdlimit/Cargo.toml | 10 ---- util/fdlimit/src/lib.rs | 19 ------- util/fdlimit/src/raise_fd_limit.rs | 88 ------------------------------ 5 files changed, 4 insertions(+), 119 deletions(-) delete mode 100644 util/fdlimit/Cargo.toml delete mode 100644 util/fdlimit/src/lib.rs delete mode 100644 util/fdlimit/src/raise_fd_limit.rs diff --git a/Cargo.lock b/Cargo.lock index 19fe95318..fce6577e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,7 +24,7 @@ dependencies = [ "ethcore-stratum 1.4.0", "ethcore-util 1.5.0", "ethsync 1.5.0", - "fdlimit 0.1.0", + "fdlimit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -685,6 +685,7 @@ dependencies = [ [[package]] name = "fdlimit" version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2027,6 +2028,7 @@ dependencies = [ "checksum env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aba65b63ffcc17ffacd6cf5aa843da7c5a25e3bd4bbe0b7def8b214e411250e5" "checksum eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)" = "" "checksum ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0c53453517f620847be51943db329276ae52f2e210cfc659e81182864be2f" +"checksum fdlimit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "651810f1715f923432bf2d94eef91d46ea0b66de5041dda9ce1af3f7aea42d6f" "checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" "checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" diff --git a/Cargo.toml b/Cargo.toml index e0e4df2e9..078d2916c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ serde = "0.8.0" serde_json = "0.8.0" hyper = { version = "0.9", default-features = false } ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" } -fdlimit = { path = "util/fdlimit" } +fdlimit = "0.1" ethcore = { path = "ethcore" } ethcore-util = { path = "util" } ethsync = { path = "sync" } diff --git a/util/fdlimit/Cargo.toml b/util/fdlimit/Cargo.toml deleted file mode 100644 index 42aa582fe..000000000 --- a/util/fdlimit/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -description = "Utility function to raise file descriptor limit on OS X" -homepage = "http://ethcore.io" -license = "GPL-3.0" -name = "fdlimit" -version = "0.1.0" -authors = ["Ethcore "] - -[dependencies] -libc = "0.2" diff --git a/util/fdlimit/src/lib.rs b/util/fdlimit/src/lib.rs deleted file mode 100644 index 92c403058..000000000 --- a/util/fdlimit/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015, 2016 Ethcore (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 .extern crate libc; - -extern crate libc; -mod raise_fd_limit; -pub use raise_fd_limit::raise_fd_limit; diff --git a/util/fdlimit/src/raise_fd_limit.rs b/util/fdlimit/src/raise_fd_limit.rs deleted file mode 100644 index d0539fda9..000000000 --- a/util/fdlimit/src/raise_fd_limit.rs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// darwin_fd_limit exists to work around an issue where launchctl on Mac OS X -/// defaults the rlimit maxfiles to 256/unlimited. The default soft limit of 256 -/// ends up being far too low for our multithreaded scheduler testing, depending -/// on the number of cores available. -/// -#[cfg(any(target_os = "macos", target_os = "ios"))] -#[allow(non_camel_case_types)] -pub fn raise_fd_limit() { - use libc; - use std::cmp; - use std::io; - use std::mem::size_of_val; - use std::ptr::null_mut; - - unsafe { - static CTL_KERN: libc::c_int = 1; - static KERN_MAXFILESPERPROC: libc::c_int = 29; - - // The strategy here is to fetch the current resource limits, read the - // kern.maxfilesperproc sysctl value, and bump the soft resource limit for - // maxfiles up to the sysctl value. - - // Fetch the kern.maxfilesperproc value - let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC]; - let mut maxfiles: libc::c_int = 0; - let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t; - if libc::sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size, - null_mut(), 0) != 0 { - let err = io::Error::last_os_error(); - panic!("raise_fd_limit: error calling sysctl: {}", err); - } - - // Fetch the current resource limits - let mut rlim = libc::rlimit{rlim_cur: 0, rlim_max: 0}; - if libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) != 0 { - let err = io::Error::last_os_error(); - panic!("raise_fd_limit: error calling getrlimit: {}", err); - } - - // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard - // limit - rlim.rlim_cur = cmp::min(maxfiles as libc::rlim_t, rlim.rlim_max); - - // Set our newly-increased resource limit - if libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) != 0 { - let err = io::Error::last_os_error(); - panic!("raise_fd_limit: error calling setrlimit: {}", err); - } - } -} - -#[cfg(any(target_os = "linux"))] -#[allow(non_camel_case_types)] -pub fn raise_fd_limit() { - use libc; - use std::io; - - unsafe { - // Fetch the current resource limits - let mut rlim = libc::rlimit{rlim_cur: 0, rlim_max: 0}; - if libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) != 0 { - let err = io::Error::last_os_error(); - panic!("raise_fd_limit: error calling getrlimit: {}", err); - } - - // Set soft limit to hard imit - rlim.rlim_cur = rlim.rlim_max; - - // Set our newly-increased resource limit - if libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) != 0 { - let err = io::Error::last_os_error(); - panic!("raise_fd_limit: error calling setrlimit: {}", err); - } - } -} - -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "linux")))] -pub fn raise_fd_limit() {} From c61a0e97b376734d3ee035974582aa58d11de96d Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 15:20:32 +0000 Subject: [PATCH 02/14] make engine determine block order --- ethcore/src/blockchain/blockchain.rs | 50 +++++++++++++++----------- ethcore/src/client/client.rs | 4 +-- ethcore/src/engines/authority_round.rs | 17 ++++++++- ethcore/src/engines/mod.rs | 9 ++++- ethcore/src/engines/null_engine.rs | 6 ++++ ethcore/src/ethereum/ethash.rs | 11 ++++++ ethcore/src/snapshot/service.rs | 3 +- ethcore/src/snapshot/tests/blocks.rs | 18 +++++----- ethcore/src/spec/spec.rs | 3 +- ethcore/src/tests/helpers.rs | 6 ++-- 10 files changed, 87 insertions(+), 40 deletions(-) diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 68fb40483..0e8e0a271 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -34,6 +34,7 @@ use blockchain::update::ExtrasUpdate; use blockchain::{CacheSize, ImportRoute, Config}; use db::{self, Writable, Readable, CacheUpdatePolicy}; use cache_manager::CacheManager; +use engines::Engine; const LOG_BLOOMS_LEVELS: usize = 3; const LOG_BLOOMS_ELEMENTS_PER_INDEX: usize = 16; @@ -198,6 +199,9 @@ pub struct BlockChain { pending_block_hashes: RwLock>, pending_block_details: RwLock>, pending_transaction_addresses: RwLock>>, + + // Used for block ordering. + engine: Arc, } impl BlockProvider for BlockChain { @@ -415,9 +419,8 @@ impl<'a> Iterator for AncestryIter<'a> { } impl BlockChain { - #[cfg_attr(feature="dev", allow(useless_let_if_seq))] - /// Create new instance of blockchain from given Genesis - pub fn new(config: Config, genesis: &[u8], db: Arc) -> BlockChain { + /// Create new instance of blockchain from given Genesis and block picking rules of Engine. + pub fn new(config: Config, genesis: &[u8], db: Arc, engine: Arc) -> BlockChain { // 400 is the avarage size of the key let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400); @@ -442,6 +445,7 @@ impl BlockChain { pending_block_hashes: RwLock::new(HashMap::new()), pending_block_details: RwLock::new(HashMap::new()), pending_transaction_addresses: RwLock::new(HashMap::new()), + engine: engine, }; // load best block @@ -858,13 +862,12 @@ impl BlockChain { let number = header.number(); let parent_hash = header.parent_hash(); let parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash)); - let total_difficulty = parent_details.total_difficulty + header.difficulty(); - let is_new_best = total_difficulty > self.best_block_total_difficulty(); + let is_new_best = self.engine.is_new_best_block(self.best_block_total_difficulty(), HeaderView::new(&self.best_block_header()), &parent_details, header); BlockInfo { hash: hash, number: number, - total_difficulty: total_difficulty, + total_difficulty: parent_details.total_difficulty + header.difficulty(), location: if is_new_best { // on new best block we need to make sure that all ancestors // are moved to "canon chain" @@ -1319,11 +1322,16 @@ mod tests { use views::BlockView; use transaction::{Transaction, Action}; use log_entry::{LogEntry, LocalizedLogEntry}; + use spec::Spec; fn new_db(path: &str) -> Arc { Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), path).unwrap()) } + fn new_chain(genesis: &[u8], db: Arc) -> BlockChain { + BlockChain::new(Config::default(), genesis, db, Spec::new_null().engine) + } + #[test] fn should_cache_best_block() { // given @@ -1334,7 +1342,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); assert_eq!(bc.best_block_number(), 0); // when @@ -1360,7 +1368,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); assert_eq!(bc.genesis_hash(), genesis_hash.clone()); assert_eq!(bc.best_block_hash(), genesis_hash.clone()); @@ -1391,7 +1399,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let mut block_hashes = vec![genesis_hash.clone()]; let mut batch = db.transaction(); @@ -1427,7 +1435,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let mut batch =db.transaction(); for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] { @@ -1489,7 +1497,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let mut batch = db.transaction(); let _ = bc.insert_block(&mut batch, &b1a, vec![]); @@ -1577,7 +1585,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let mut batch = db.transaction(); let _ = bc.insert_block(&mut batch, &b1a, vec![]); @@ -1639,7 +1647,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let mut batch = db.transaction(); let ir1 = bc.insert_block(&mut batch, &b1, vec![]); @@ -1755,7 +1763,7 @@ mod tests { let temp = RandomTempPath::new(); { let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); assert_eq!(bc.best_block_hash(), genesis_hash); let mut batch =db.transaction(); bc.insert_block(&mut batch, &first, vec![]); @@ -1766,7 +1774,7 @@ mod tests { { let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); assert_eq!(bc.best_block_hash(), first_hash); } @@ -1821,7 +1829,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let mut batch =db.transaction(); bc.insert_block(&mut batch, &b1, vec![]); db.write(batch).unwrap(); @@ -1881,7 +1889,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); insert_block(&db, &bc, &b1, vec![Receipt { state_root: H256::default(), gas_used: 10_000.into(), @@ -1985,7 +1993,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5); let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5); @@ -2042,7 +2050,7 @@ mod tests { { let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap(); let mut batch =db.transaction(); @@ -2061,7 +2069,7 @@ mod tests { // re-loading the blockchain should load the correct best block. let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); assert_eq!(bc.best_block_number(), 5); } @@ -2078,7 +2086,7 @@ mod tests { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(Config::default(), &genesis, db.clone()); + let bc = new_chain(&genesis, db.clone()); let mut batch =db.transaction(); bc.insert_block(&mut batch, &first, vec![]); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 85ec05b03..98260936d 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -164,7 +164,7 @@ impl Client { let gb = spec.genesis_block(); let db = Arc::new(try!(Database::open(&db_config, &path.to_str().expect("DB path could not be converted to string.")).map_err(ClientError::Database))); - let chain = Arc::new(BlockChain::new(config.blockchain.clone(), &gb, db.clone())); + let chain = Arc::new(BlockChain::new(config.blockchain.clone(), &gb, db.clone(), spec.engine.clone())); let tracedb = RwLock::new(TraceDB::new(config.tracing.clone(), db.clone(), chain.clone())); let trie_spec = match config.fat_db { @@ -787,7 +787,7 @@ impl snapshot::DatabaseRestore for Client { let cache_size = state_db.cache_size(); *state_db = StateDB::new(journaldb::new(db.clone(), self.pruning, ::db::COL_STATE), cache_size); - *chain = Arc::new(BlockChain::new(self.config.blockchain.clone(), &[], db.clone())); + *chain = Arc::new(BlockChain::new(self.config.blockchain.clone(), &[], db.clone(), self.engine.clone())); *tracedb = TraceDB::new(self.config.tracing.clone(), db.clone(), chain.clone()); Ok(()) } diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 6c1d0a409..c278a011a 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -21,7 +21,7 @@ use std::sync::Weak; use std::time::{UNIX_EPOCH, Duration}; use util::*; use ethkey::{verify_address, Signature}; -use rlp::{UntrustedRlp, View, encode}; +use rlp::{Rlp, UntrustedRlp, View, encode}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; @@ -35,6 +35,8 @@ use service::ClientIoMessage; use transaction::SignedTransaction; use env_info::EnvInfo; use builtin::Builtin; +use blockchain::extras::BlockDetails; +use views::HeaderView; /// `AuthorityRound` params. #[derive(Debug, PartialEq)] @@ -310,6 +312,19 @@ impl Engine for AuthorityRound { let mut guard = self.message_channel.lock(); *guard = Some(message_channel); } + + fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool { + let new_number = new_header.number(); + let best_number = best_header.number(); + if new_number != best_number { + new_number > best_number + } else { + // Take the oldest step at given height. + let new_step: usize = Rlp::new(&new_header.seal()[0]).as_val(); + let best_step: usize = Rlp::new(&best_header.seal()[0]).as_val(); + new_step < best_step + } + } } #[cfg(test)] diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index c70a19de8..163901edc 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -38,6 +38,9 @@ use io::IoChannel; use service::ClientIoMessage; use header::Header; use transaction::SignedTransaction; +use ethereum::ethash; +use blockchain::extras::BlockDetails; +use views::HeaderView; /// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. /// Provides hooks into each of the major parts of block import. @@ -146,5 +149,9 @@ pub trait Engine : Sync + Send { /// Add a channel for communication with Client which can be used for sealing. fn register_message_channel(&self, _message_channel: IoChannel) {} - // TODO: sealing stuff - though might want to leave this for later. + + /// Check if new block should be chosen as the one in chain. + fn is_new_best_block(&self, best_total_difficulty: U256, _best_header: HeaderView, parent_details: &BlockDetails, new_header: &HeaderView) -> bool { + ethash::is_new_best_block(best_total_difficulty, parent_details, new_header) + } } diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index e0906ce22..bd5a4474a 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -38,6 +38,12 @@ impl NullEngine { } } +impl Default for NullEngine { + fn default() -> Self { + Self::new(Default::default(), Default::default()) + } +} + impl Engine for NullEngine { fn name(&self) -> &str { "NullEngine" diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 38a1df525..0ca9ff00e 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -21,6 +21,7 @@ use builtin::Builtin; use env_info::EnvInfo; use error::{BlockError, TransactionError, Error}; use header::Header; +use views::HeaderView; use state::CleanupMode; use spec::CommonParams; use transaction::SignedTransaction; @@ -28,6 +29,7 @@ use engines::Engine; use evm::Schedule; use ethjson; use rlp::{self, UntrustedRlp, View}; +use blockchain::extras::BlockDetails; /// Ethash params. #[derive(Debug, PartialEq)] @@ -325,6 +327,15 @@ impl Engine for Ethash { fn verify_transaction(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> { t.sender().map(|_|()) // Perform EC recovery and cache sender } + + /// Check if a new block should replace the best blockchain block. + fn is_new_best_block(&self, best_total_difficulty: U256, _best_header: HeaderView, parent_details: &BlockDetails, new_header: &HeaderView) -> bool { + is_new_best_block(best_total_difficulty, parent_details, new_header) + } +} + +pub fn is_new_best_block(best_total_difficulty: U256, parent_details: &BlockDetails, new_header: &HeaderView) -> bool { + parent_details.total_difficulty + new_header.difficulty() > best_total_difficulty } #[cfg_attr(feature="dev", allow(wrong_self_convention))] diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index c0d34a6a9..47c4f992b 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -32,6 +32,7 @@ use engines::Engine; use error::Error; use ids::BlockID; use service::ClientIoMessage; +use spec::Spec; use io::IoChannel; @@ -99,7 +100,7 @@ impl Restoration { let raw_db = Arc::new(try!(Database::open(params.db_config, &*params.db_path.to_string_lossy()) .map_err(UtilError::SimpleString))); - let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone()); + let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone(), Spec::new_null().engine); let blocks = try!(BlockRebuilder::new(chain, raw_db.clone(), &manifest)); let root = manifest.state_root.clone(); diff --git a/ethcore/src/snapshot/tests/blocks.rs b/ethcore/src/snapshot/tests/blocks.rs index 18637bad1..3d9390d2e 100644 --- a/ethcore/src/snapshot/tests/blocks.rs +++ b/ethcore/src/snapshot/tests/blocks.rs @@ -37,13 +37,14 @@ fn chunk_and_restore(amount: u64) { let genesis = canon_chain.generate(&mut finalizer).unwrap(); let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); + let engine = Arc::new(::engines::NullEngine::default()); let orig_path = RandomTempPath::create_dir(); let new_path = RandomTempPath::create_dir(); let mut snapshot_path = new_path.as_path().to_owned(); snapshot_path.push("SNAP"); let old_db = Arc::new(Database::open(&db_cfg, orig_path.as_str()).unwrap()); - let bc = BlockChain::new(Default::default(), &genesis, old_db.clone()); + let bc = BlockChain::new(Default::default(), &genesis, old_db.clone(), engine.clone()); // build the blockchain. let mut batch = old_db.transaction(); @@ -73,21 +74,20 @@ fn chunk_and_restore(amount: u64) { // restore it. let new_db = Arc::new(Database::open(&db_cfg, new_path.as_str()).unwrap()); - let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone()); + let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone(), engine.clone()); let mut rebuilder = BlockRebuilder::new(new_chain, new_db.clone(), &manifest).unwrap(); let reader = PackedReader::new(&snapshot_path).unwrap().unwrap(); - let engine = ::engines::NullEngine::new(Default::default(), Default::default()); let flag = AtomicBool::new(true); for chunk_hash in &reader.manifest().block_hashes { let compressed = reader.chunk(*chunk_hash).unwrap(); let chunk = snappy::decompress(&compressed).unwrap(); - rebuilder.feed(&chunk, &engine, &flag).unwrap(); + rebuilder.feed(&chunk, engine.as_ref(), &flag).unwrap(); } rebuilder.finalize(HashMap::new()).unwrap(); // and test it. - let new_chain = BlockChain::new(Default::default(), &genesis, new_db); + let new_chain = BlockChain::new(Default::default(), &genesis, new_db, engine); assert_eq!(new_chain.best_block_hash(), best_hash); } @@ -121,8 +121,8 @@ fn checks_flag() { let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); let db = Arc::new(Database::open(&db_cfg, path.as_str()).unwrap()); - let chain = BlockChain::new(Default::default(), &genesis, db.clone()); - let engine = ::engines::NullEngine::new(Default::default(), Default::default()); + let engine = Arc::new(::engines::NullEngine::default()); + let chain = BlockChain::new(Default::default(), &genesis, db.clone(), engine.clone()); let manifest = ::snapshot::ManifestData { state_hashes: Vec::new(), @@ -134,8 +134,8 @@ fn checks_flag() { let mut rebuilder = BlockRebuilder::new(chain, db.clone(), &manifest).unwrap(); - match rebuilder.feed(&chunk, &engine, &AtomicBool::new(false)) { + match rebuilder.feed(&chunk, engine.as_ref(), &AtomicBool::new(false)) { Err(Error::Snapshot(SnapshotError::RestorationAborted)) => {} _ => panic!("Wrong result on abort flag set") } -} \ No newline at end of file +} diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 71c15bca2..1e00ae57b 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -30,8 +30,7 @@ use ethjson; use rlp::{Rlp, RlpStream, View, Stream}; /// Parameters common to all engines. -#[derive(Debug, PartialEq, Clone)] -#[cfg_attr(test, derive(Default))] +#[derive(Debug, PartialEq, Clone, Default)] pub struct CommonParams { /// Account start nonce. pub account_start_nonce: U256, diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 77a6f117a..e952fe27a 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -286,7 +286,7 @@ fn new_db(path: &str) -> Arc { pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); + let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone(), Spec::new_null().engine); let mut batch = db.transaction(); for block_order in 1..block_number { @@ -304,7 +304,7 @@ pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult GuardedTempResult { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); + let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone(), Spec::new_null().engine); let mut batch = db.transaction(); @@ -323,7 +323,7 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempRes pub fn generate_dummy_empty_blockchain() -> GuardedTempResult { let temp = RandomTempPath::new(); let db = new_db(temp.as_str()); - let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone()); + let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone(), Spec::new_null().engine); GuardedTempResult:: { _temp: temp, From 94302f3f610f0d1cd3ff08ae25d6663fce4afb2d Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 15:27:44 +0000 Subject: [PATCH 03/14] throw out difficulty checks --- ethcore/src/engines/authority_round.rs | 5 ----- ethcore/src/ethereum/ethash.rs | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index c278a011a..f28a06117 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -274,7 +274,6 @@ impl Engine for AuthorityRound { } fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { - // Don't calculate difficulty for genesis blocks. if header.number() == 0 { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() }))); } @@ -286,10 +285,6 @@ impl Engine for AuthorityRound { try!(Err(BlockError::DoubleVote(header.author().clone()))); } - // Check difficulty is correct given the two timestamps. - if header.difficulty() != parent.difficulty() { - return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() }))) - } let gas_limit_divisor = self.our_params.gas_limit_bound_divisor; let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor; let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 0ca9ff00e..96c1298cc 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -328,12 +328,12 @@ impl Engine for Ethash { t.sender().map(|_|()) // Perform EC recovery and cache sender } - /// Check if a new block should replace the best blockchain block. fn is_new_best_block(&self, best_total_difficulty: U256, _best_header: HeaderView, parent_details: &BlockDetails, new_header: &HeaderView) -> bool { is_new_best_block(best_total_difficulty, parent_details, new_header) } } +/// Check if a new block should replace the best blockchain block. pub fn is_new_best_block(best_total_difficulty: U256, parent_details: &BlockDetails, new_header: &HeaderView) -> bool { parent_details.total_difficulty + new_header.difficulty() > best_total_difficulty } From 53b479fb7a3b766ec5672dae8f55dd0f5d2b2451 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 15:43:46 +0000 Subject: [PATCH 04/14] pass engine to snapshot service --- ethcore/src/snapshot/service.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 47c4f992b..89ee68de0 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -32,7 +32,6 @@ use engines::Engine; use error::Error; use ids::BlockID; use service::ClientIoMessage; -use spec::Spec; use io::IoChannel; @@ -82,6 +81,7 @@ struct Restoration { struct RestorationParams<'a> { manifest: ManifestData, // manifest to base restoration on. pruning: Algorithm, // pruning algorithm for the database. + engine: Arc, // consensus engine of the chain. db_path: PathBuf, // database path db_config: &'a DatabaseConfig, // configuration for the database. writer: Option, // writer for recovered snapshot. @@ -100,7 +100,7 @@ impl Restoration { let raw_db = Arc::new(try!(Database::open(params.db_config, &*params.db_path.to_string_lossy()) .map_err(UtilError::SimpleString))); - let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone(), Spec::new_null().engine); + let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone(), params.engine); let blocks = try!(BlockRebuilder::new(chain, raw_db.clone(), &manifest)); let root = manifest.state_root.clone(); @@ -421,6 +421,7 @@ impl Service { let params = RestorationParams { manifest: manifest, pruning: self.pruning, + engine: self.engine.clone(), db_path: self.restoration_db(), db_config: &self.db_config, writer: writer, From 529a7fc33c61a88298a63fc205585538b219f4f5 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 17:08:16 +0000 Subject: [PATCH 05/14] add password and AccountProvider --- ethcore/src/engines/authority_round.rs | 46 +++++++++++------------ ethcore/src/engines/basic_authority.rs | 13 +++++-- ethcore/src/engines/instant_seal.rs | 12 ++---- ethcore/src/engines/mod.rs | 14 +++++-- ethcore/src/miner/miner.rs | 43 ++++++++++++++------- ethcore/src/miner/mod.rs | 3 ++ parity/run.rs | 5 ++- rpc/src/v1/impls/parity_set.rs | 6 +++ rpc/src/v1/tests/eth.rs | 1 + rpc/src/v1/tests/helpers/miner_service.rs | 10 +++++ rpc/src/v1/tests/helpers/sync_provider.rs | 2 +- rpc/src/v1/tests/mocked/parity_set.rs | 17 +++++++++ rpc/src/v1/traits/parity_set.rs | 4 ++ 13 files changed, 119 insertions(+), 57 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index f28a06117..646c107e0 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -21,13 +21,15 @@ use std::sync::Weak; use std::time::{UNIX_EPOCH, Duration}; use util::*; use ethkey::{verify_address, Signature}; -use rlp::{Rlp, UntrustedRlp, View, encode}; +use rlp::{UntrustedRlp, View, encode}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; use engines::Engine; use header::Header; use error::{Error, BlockError}; +use blockchain::extras::BlockDetails; +use views::HeaderView; use evm::Schedule; use ethjson; use io::{IoContext, IoHandler, TimerToken, IoService, IoChannel}; @@ -35,8 +37,6 @@ use service::ClientIoMessage; use transaction::SignedTransaction; use env_info::EnvInfo; use builtin::Builtin; -use blockchain::extras::BlockDetails; -use views::HeaderView; /// `AuthorityRound` params. #[derive(Debug, PartialEq)] @@ -72,6 +72,7 @@ pub struct AuthorityRound { message_channel: Mutex>>, step: AtomicUsize, proposed: AtomicBool, + account_provider: Mutex>>, } fn header_step(header: &Header) -> Result { @@ -104,7 +105,8 @@ impl AuthorityRound { transition_service: try!(IoService::::start()), message_channel: Mutex::new(None), step: AtomicUsize::new(initial_step), - proposed: AtomicBool::new(false) + proposed: AtomicBool::new(false), + account_provider: Mutex::new(None), }); let handler = TransitionHandler { engine: Arc::downgrade(&engine) }; try!(engine.transition_service.register_handler(Arc::new(handler))); @@ -196,7 +198,6 @@ impl Engine for AuthorityRound { } fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { - header.set_difficulty(parent.difficulty().clone()); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.our_params.gas_limit_bound_divisor; @@ -221,12 +222,12 @@ impl Engine for AuthorityRound { /// /// This operation is synchronous and may (quite reasonably) not be available, in which `false` will /// be returned. - fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option> { + fn generate_seal(&self, block: &ExecutedBlock) -> Option> { if self.proposed.load(AtomicOrdering::SeqCst) { return None; } let header = block.header(); let step = self.step(); if self.is_step_proposer(step, header.author()) { - if let Some(ap) = accounts { + if let Some(ref ap) = *self.account_provider.lock() { // Account should be permanently unlocked, otherwise sealing will fail. if let Ok(signature) = ap.sign(*header.author(), None, header.bare_hash()) { trace!(target: "poa", "generate_seal: Issuing a block for step {}.", step); @@ -303,22 +304,16 @@ impl Engine for AuthorityRound { t.sender().map(|_|()) // Perform EC recovery and cache sender } - fn register_message_channel(&self, message_channel: IoChannel) { - let mut guard = self.message_channel.lock(); - *guard = Some(message_channel); + fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool { + new_header.number() > best_header.number() } - fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool { - let new_number = new_header.number(); - let best_number = best_header.number(); - if new_number != best_number { - new_number > best_number - } else { - // Take the oldest step at given height. - let new_step: usize = Rlp::new(&new_header.seal()[0]).as_val(); - let best_step: usize = Rlp::new(&best_header.seal()[0]).as_val(); - new_step < best_step - } + fn register_message_channel(&self, message_channel: IoChannel) { + *self.message_channel.lock() = Some(message_channel); + } + + fn register_account_provider(&self, account_provider: Arc) { + *self.account_provider.lock() = Some(account_provider); } } @@ -393,6 +388,7 @@ mod tests { let spec = Spec::new_test_round(); let engine = &*spec.engine; + engine.register_account_provider(Arc::new(tap)); let genesis_header = spec.genesis_header(); let mut db1 = get_temp_state_db().take(); spec.ensure_db_good(&mut db1, &TrieFactory::new(TrieSpec::Secure)).unwrap(); @@ -404,16 +400,16 @@ mod tests { let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b2 = b2.close_and_lock(); - if let Some(seal) = engine.generate_seal(b1.block(), Some(&tap)) { + if let Some(seal) = engine.generate_seal(b1.block()) { assert!(b1.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. - assert!(engine.generate_seal(b1.block(), Some(&tap)).is_none()); + assert!(engine.generate_seal(b1.block()).is_none()); } - if let Some(seal) = engine.generate_seal(b2.block(), Some(&tap)) { + if let Some(seal) = engine.generate_seal(b2.block()) { assert!(b2.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. - assert!(engine.generate_seal(b2.block(), Some(&tap)).is_none()); + assert!(engine.generate_seal(b2.block()).is_none()); } } diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index fb2f9bde6..0b9040a11 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -58,6 +58,7 @@ pub struct BasicAuthority { params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap, + account_provider: Mutex>>, } impl BasicAuthority { @@ -67,6 +68,7 @@ impl BasicAuthority { params: params, our_params: our_params, builtins: builtins, + account_provider: Mutex::new(None) } } } @@ -113,8 +115,8 @@ impl Engine for BasicAuthority { /// /// This operation is synchronous and may (quite reasonably) not be available, in which `false` will /// be returned. - fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option> { - if let Some(ap) = accounts { + fn generate_seal(&self, block: &ExecutedBlock) -> Option> { + if let Some(ref ap) = *self.account_provider.lock() { let header = block.header(); let message = header.bare_hash(); // account should be pernamently unlocked, otherwise sealing will fail @@ -179,6 +181,10 @@ impl Engine for BasicAuthority { fn verify_transaction(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> { t.sender().map(|_|()) // Perform EC recovery and cache sender } + + fn register_account_provider(&self, ap: Arc) { + *self.account_provider.lock() = Some(ap); + } } #[cfg(test)] @@ -254,6 +260,7 @@ mod tests { let spec = new_test_authority(); let engine = &*spec.engine; + engine.register_account_provider(Arc::new(tap)); let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); @@ -261,7 +268,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); - let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); + let seal = engine.generate_seal(b.block()).unwrap(); assert!(b.try_seal(engine, seal).is_ok()); } diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index f50f7344b..83335fb03 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -23,7 +23,6 @@ use spec::CommonParams; use evm::Schedule; use block::ExecutedBlock; use util::Bytes; -use account_provider::AccountProvider; /// An engine which does not provide any consensus mechanism, just seals blocks internally. pub struct InstantSeal { @@ -60,7 +59,7 @@ impl Engine for InstantSeal { fn is_sealer(&self, _author: &Address) -> Option { Some(true) } - fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option> { + fn generate_seal(&self, _block: &ExecutedBlock) -> Option> { Some(Vec::new()) } } @@ -70,16 +69,12 @@ mod tests { use util::*; use util::trie::TrieSpec; use tests::helpers::*; - use account_provider::AccountProvider; use spec::Spec; use header::Header; use block::*; #[test] fn instant_can_seal() { - let tap = AccountProvider::transient_provider(); - let addr = tap.insert_account("".sha3(), "").unwrap(); - let spec = Spec::new_instant(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); @@ -87,10 +82,9 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); - // Seal with empty AccountProvider. - let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); + let seal = engine.generate_seal(b.block()).unwrap(); assert!(b.try_seal(engine, seal).is_ok()); } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 163901edc..0401ba667 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -94,7 +94,7 @@ pub trait Engine : Sync + Send { /// /// This operation is synchronous and may (quite reasonably) not be available, in which None will /// be returned. - fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option> { None } + fn generate_seal(&self, _block: &ExecutedBlock) -> Option> { None } /// Phase 1 quick block verification. Only does checks that are cheap. `block` (the header's full block) /// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import. @@ -147,11 +147,17 @@ pub trait Engine : Sync + Send { self.builtins().get(a).expect("attempted to execute nonexistent builtin").execute(input, output); } - /// Add a channel for communication with Client which can be used for sealing. - fn register_message_channel(&self, _message_channel: IoChannel) {} - /// Check if new block should be chosen as the one in chain. fn is_new_best_block(&self, best_total_difficulty: U256, _best_header: HeaderView, parent_details: &BlockDetails, new_header: &HeaderView) -> bool { ethash::is_new_best_block(best_total_difficulty, parent_details, new_header) } + + /// Register an account which signs consensus messages. + fn set_signer(&self, _address: Address, _password: String) {} + + /// Add a channel for communication with Client which can be used for sealing. + fn register_message_channel(&self, _message_channel: IoChannel) {} + + /// Add an account provider useful for Engines that sign stuff. + fn register_account_provider(&self, _account_provider: Arc) {} } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index a543e608d..4b38a7e07 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -19,7 +19,7 @@ use std::time::{Instant, Duration}; use util::*; use util::using_queue::{UsingQueue, GetAction}; -use account_provider::AccountProvider; +use account_provider::{AccountProvider, Error as AccountError}; use views::{BlockView, HeaderView}; use header::Header; use state::{State, CleanupMode}; @@ -464,15 +464,12 @@ impl Miner { /// Attempts to perform internal sealing (one that does not require work) to return Ok(sealed), /// Err(Some(block)) returns for unsuccesful sealing while Err(None) indicates misspecified engine. fn seal_block_internally(&self, block: ClosedBlock) -> Result> { - trace!(target: "miner", "seal_block_internally: block has transaction - attempting internal seal."); - let s = self.engine.generate_seal(block.block(), match self.accounts { - Some(ref x) => Some(&**x), - None => None, - }); + trace!(target: "miner", "seal_block_internally: attempting internal seal."); + let s = self.engine.generate_seal(block.block()); if let Some(seal) = s { trace!(target: "miner", "seal_block_internally: managed internal seal. importing..."); - block.lock().try_seal(&*self.engine, seal).or_else(|_| { - warn!("prepare_sealing: ERROR: try_seal failed when given internally generated seal. WTF?"); + block.lock().try_seal(&*self.engine, seal).or_else(|(e, _)| { + warn!("prepare_sealing: ERROR: try_seal failed when given internally generated seal: {}", e); Err(None) }) } else { @@ -485,7 +482,7 @@ impl Miner { fn seal_and_import_block_internally(&self, chain: &MiningBlockChainClient, block: ClosedBlock) -> bool { if !block.transactions().is_empty() || self.forced_sealing() { if let Ok(sealed) = self.seal_block_internally(block) { - if chain.import_block(sealed.rlp_bytes()).is_ok() { + if chain.import_sealed_block(sealed).is_ok() { trace!(target: "miner", "import_block_internally: imported internally sealed block"); return true } @@ -740,6 +737,19 @@ impl MinerService for Miner { *self.author.write() = author; } + fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + if self.seals_internally { + if let Some(ref ap) = self.accounts { + try!(ap.sign(address.clone(), Some(password.clone()), Default::default())); + } + let mut sealing_work = self.sealing_work.lock(); + sealing_work.enabled = self.engine.is_sealer(&address).unwrap_or(false); + *self.author.write() = address; + self.engine.set_signer(address, password); + } + Ok(()) + } + fn set_extra_data(&self, extra_data: Bytes) { *self.extra_data.write() = extra_data; } @@ -1020,6 +1030,11 @@ impl MinerService for Miner { let (block, original_work_hash) = self.prepare_block(chain); if self.seals_internally { trace!(target: "miner", "update_sealing: engine indicates internal sealing"); + { + let mut sealing_work = self.sealing_work.lock(); + sealing_work.queue.push(block.clone()); + sealing_work.queue.use_last_ref(); + } self.seal_and_import_block_internally(chain, block); } else { trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work"); @@ -1042,7 +1057,7 @@ impl MinerService for Miner { ret.map(f) } - fn submit_seal(&self, chain: &MiningBlockChainClient, pow_hash: H256, seal: Vec) -> Result<(), Error> { + fn submit_seal(&self, chain: &MiningBlockChainClient, block_hash: H256, seal: Vec) -> Result<(), Error> { let result = if let Some(b) = self.sealing_work.lock().queue.get_used_if( if self.options.enable_resubmission { @@ -1050,22 +1065,22 @@ impl MinerService for Miner { } else { GetAction::Take }, - |b| &b.hash() == &pow_hash + |b| &b.hash() == &block_hash ) { - trace!(target: "miner", "Sealing block {}={}={} with seal {:?}", pow_hash, b.hash(), b.header().bare_hash(), seal); + trace!(target: "miner", "Submitted block {}={}={} with seal {:?}", block_hash, b.hash(), b.header().bare_hash(), seal); b.lock().try_seal(&*self.engine, seal).or_else(|(e, _)| { warn!(target: "miner", "Mined solution rejected: {}", e); Err(Error::PowInvalid) }) } else { - warn!(target: "miner", "Mined solution rejected: Block unknown or out of date."); + warn!(target: "miner", "Submitted solution rejected: Block unknown or out of date."); Err(Error::PowHashInvalid) }; result.and_then(|sealed| { let n = sealed.header().number(); let h = sealed.header().hash(); try!(chain.import_sealed_block(sealed)); - info!(target: "miner", "Mined block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(h.hex())); + info!(target: "miner", "Submitted block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(h.hex())); Ok(()) }) } diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 1fb2244fd..26cefb295 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -76,6 +76,9 @@ pub trait MinerService : Send + Sync { /// Set the author that we will seal blocks as. fn set_author(&self, author: Address); + /// Set info necessary to sign consensus messages. + fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), ::account_provider::Error>; + /// Get the extra_data that we will seal blocks with. fn extra_data(&self) -> Bytes; diff --git a/parity/run.rs b/parity/run.rs index f977c450c..2509d1347 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -70,7 +70,7 @@ pub struct RunCmd { pub http_conf: HttpConfiguration, pub ipc_conf: IpcConfiguration, pub net_conf: NetworkConfiguration, - pub network_id: Option, + pub network_id: Option, pub warp_sync: bool, pub acc_conf: AccountsConfig, pub gas_pricer: GasPricerConfig, @@ -208,6 +208,9 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { // prepare account provider let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf))); + // let the Engine access the accounts + spec.engine.register_account_provider(account_provider.clone()); + // create miner let miner = Miner::new(cmd.miner_options, cmd.gas_pricer.into(), &spec, Some(account_provider.clone())); miner.set_author(cmd.miner_extras.author); diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 47634d518..e28f9a573 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -116,6 +116,12 @@ impl ParitySet for ParitySetClient where Ok(true) } + fn set_consensus_signer(&self, address: H160, password: String) -> Result { + try!(self.active()); + try!(take_weak!(self.miner).set_consensus_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)); + Ok(true) + } + fn set_transactions_limit(&self, limit: usize) -> Result { try!(self.active()); diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 7894fa111..3aa83fec9 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -116,6 +116,7 @@ impl EthTester { fn from_spec(spec: Spec) -> Self { let dir = RandomTempPath::new(); let account_provider = account_provider(); + spec.engine.register_account_provider(account_provider.clone()); let miner_service = miner_service(&spec, account_provider.clone()); let snapshot_service = snapshot_service(); diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index ad55faa7b..6037cdd4a 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -25,6 +25,7 @@ use ethcore::header::BlockNumber; use ethcore::transaction::SignedTransaction; use ethcore::receipt::{Receipt, RichReceipt}; use ethcore::miner::{MinerService, MinerStatus, TransactionImportResult, LocalTransactionStatus}; +use ethcore::account_provider::Error as AccountError; /// Test miner service. pub struct TestMinerService { @@ -40,6 +41,8 @@ pub struct TestMinerService { pub pending_receipts: Mutex>, /// Last nonces. pub last_nonces: RwLock>, + /// Password held by Engine. + pub password: RwLock, min_gas_price: RwLock, gas_range_target: RwLock<(U256, U256)>, @@ -61,6 +64,7 @@ impl Default for TestMinerService { min_gas_price: RwLock::new(U256::from(20_000_000)), gas_range_target: RwLock::new((U256::from(12345), U256::from(54321))), author: RwLock::new(Address::zero()), + password: RwLock::new(String::new()), extra_data: RwLock::new(vec![1, 2, 3, 4]), limit: RwLock::new(1024), tx_gas_limit: RwLock::new(!U256::zero()), @@ -83,6 +87,12 @@ impl MinerService for TestMinerService { *self.author.write() = author; } + fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + *self.author.write() = address; + *self.password.write() = password; + Ok(()) + } + fn set_extra_data(&self, extra_data: Bytes) { *self.extra_data.write() = extra_data; } diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index 24be33417..8800d926a 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -23,7 +23,7 @@ use ethsync::{SyncProvider, SyncStatus, SyncState, PeerInfo, TransactionStats}; /// TestSyncProvider config. pub struct Config { /// Protocol version. - pub network_id: usize, + pub network_id: u64, /// Number of peers. pub num_peers: usize, } diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 01f33e251..fdf3f2d0f 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -106,6 +106,23 @@ fn rpc_parity_set_author() { assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); } +#[test] +fn rpc_parity_set_consensus_signer() { + let miner = miner_service(); + let client = client_service(); + let network = network_service(); + let io = IoHandler::new(); + io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_setConsensusSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); + assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); + assert_eq!(*miner.password.read(), "password".to_string()); +} + + #[test] fn rpc_parity_set_transactions_limit() { let miner = miner_service(); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index c83eff022..e196a7d21 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -44,6 +44,10 @@ build_rpc_trait! { #[rpc(name = "parity_setAuthor")] fn set_author(&self, H160) -> Result; + /// Sets account for signing consensus messages. + #[rpc(name = "parity_setConsensusSigner")] + fn set_consensus_signer(&self, H160, String) -> Result; + /// Sets the limits for transaction queue. #[rpc(name = "parity_setTransactionsLimit")] fn set_transactions_limit(&self, usize) -> Result; From ebd4173d2177dc41cd0f4d0a36a4af3ee5ff3353 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 5 Dec 2016 20:15:05 +0300 Subject: [PATCH 06/14] bump version --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fce6577e7..907c9b3aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,7 +24,7 @@ dependencies = [ "ethcore-stratum 1.4.0", "ethcore-util 1.5.0", "ethsync 1.5.0", - "fdlimit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -684,7 +684,7 @@ dependencies = [ [[package]] name = "fdlimit" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2028,7 +2028,7 @@ dependencies = [ "checksum env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aba65b63ffcc17ffacd6cf5aa843da7c5a25e3bd4bbe0b7def8b214e411250e5" "checksum eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)" = "" "checksum ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0c53453517f620847be51943db329276ae52f2e210cfc659e81182864be2f" -"checksum fdlimit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "651810f1715f923432bf2d94eef91d46ea0b66de5041dda9ce1af3f7aea42d6f" +"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" "checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" From 1b6ebe1a6d3425612b4483f34c5a8e5610ce5039 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 5 Dec 2016 18:18:56 +0100 Subject: [PATCH 07/14] possible fix for queue drop deadlock (#3702) * possible fix for #3686 * queue: simplify conclusion, don't block on joining * queue: park verifiers with timeout to prevent race * more robust verification loop * queue: re-introduce wait for verifier joining --- ethcore/src/verification/queue/mod.rs | 201 +++++++++++--------------- 1 file changed, 84 insertions(+), 117 deletions(-) diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 686a1d093..14df0819c 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -17,7 +17,7 @@ //! A queue of blocks. Sits between network or other I/O and the `BlockChain`. //! Sorts them ready for blockchain insertion. -use std::thread::{JoinHandle, self}; +use std::thread::{self, JoinHandle}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}; use std::sync::{Condvar as SCondvar, Mutex as SMutex}; use util::*; @@ -64,35 +64,11 @@ impl Default for Config { } } -struct VerifierHandle { - deleting: Arc, - sleep: Arc, - thread: JoinHandle<()>, -} - -impl VerifierHandle { - // signal to the verifier thread that it should sleep. - fn sleep(&self) { - self.sleep.store(true, AtomicOrdering::SeqCst); - } - - // signal to the verifier thread that it should wake up. - fn wake_up(&self) { - self.sleep.store(false, AtomicOrdering::SeqCst); - self.thread.thread().unpark(); - } - - // signal to the verifier thread that it should conclude its - // operations. - fn conclude(&self) { - self.wake_up(); - self.deleting.store(true, AtomicOrdering::Release); - } - - // join the verifier thread. - fn join(self) { - self.thread.join().expect("Verifier thread panicked"); - } +// pool states +enum State { + // all threads with id < inner value are to work. + Work(usize), + Exit, } /// An item which is in the process of being verified. @@ -131,7 +107,6 @@ pub struct VerificationQueue { engine: Arc, more_to_verify: Arc, verification: Arc>, - verifiers: Mutex<(Vec, usize)>, deleting: Arc, ready_signal: Arc, empty: Arc, @@ -139,6 +114,8 @@ pub struct VerificationQueue { ticks_since_adjustment: AtomicUsize, max_queue_size: usize, max_mem_use: usize, + verifier_handles: Vec>, + state: Arc<(Mutex, Condvar)>, } struct QueueSignal { @@ -224,40 +201,39 @@ impl VerificationQueue { let max_verifiers = min(::num_cpus::get(), MAX_VERIFIERS); let default_amount = max(::num_cpus::get(), 3) - 2; - let mut verifiers = Vec::with_capacity(max_verifiers); + let state = Arc::new((Mutex::new(State::Work(default_amount)), Condvar::new())); + let mut verifier_handles = Vec::with_capacity(max_verifiers); debug!(target: "verification", "Allocating {} verifiers, {} initially active", max_verifiers, default_amount); for i in 0..max_verifiers { debug!(target: "verification", "Adding verification thread #{}", i); - let deleting = deleting.clone(); let panic_handler = panic_handler.clone(); let verification = verification.clone(); let engine = engine.clone(); let wait = more_to_verify.clone(); let ready = ready_signal.clone(); let empty = empty.clone(); + let state = state.clone(); - // enable only the first few verifiers. - let sleep = if i < default_amount { - Arc::new(AtomicBool::new(false)) - } else { - Arc::new(AtomicBool::new(true)) - }; - - verifiers.push(VerifierHandle { - deleting: deleting.clone(), - sleep: sleep.clone(), - thread: thread::Builder::new() - .name(format!("Verifier #{}", i)) - .spawn(move || { - panic_handler.catch_panic(move || { - VerificationQueue::verify(verification, engine, wait, ready, deleting, empty, sleep) - }).unwrap() - }) - .expect("Failed to create verifier thread.") - }); + let handle = thread::Builder::new() + .name(format!("Verifier #{}", i)) + .spawn(move || { + panic_handler.catch_panic(move || { + VerificationQueue::verify( + verification, + engine, + wait, + ready, + empty, + state, + i, + ) + }).unwrap() + }) + .expect("Failed to create verifier thread."); + verifier_handles.push(handle); } VerificationQueue { @@ -266,13 +242,14 @@ impl VerificationQueue { ready_signal: ready_signal, more_to_verify: more_to_verify, verification: verification, - verifiers: Mutex::new((verifiers, default_amount)), deleting: deleting, processing: RwLock::new(HashSet::new()), empty: empty, ticks_since_adjustment: AtomicUsize::new(0), max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT), max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT), + verifier_handles: verifier_handles, + state: state, } } @@ -281,23 +258,30 @@ impl VerificationQueue { engine: Arc, wait: Arc, ready: Arc, - deleting: Arc, empty: Arc, - sleep: Arc, + state: Arc<(Mutex, Condvar)>, + id: usize, ) { - while !deleting.load(AtomicOrdering::Acquire) { + loop { + // check current state. { - while sleep.load(AtomicOrdering::SeqCst) { - trace!(target: "verification", "Verifier sleeping"); - ::std::thread::park(); - trace!(target: "verification", "Verifier waking up"); + let mut cur_state = state.0.lock(); + while let State::Work(x) = *cur_state { + // sleep until this thread is required. + if id < x { break } - if deleting.load(AtomicOrdering::Acquire) { - return; - } + debug!(target: "verification", "verifier {} sleeping", id); + state.1.wait(&mut cur_state); + debug!(target: "verification", "verifier {} waking up", id); + } + + if let State::Exit = *cur_state { + debug!(target: "verification", "verifier {} exiting", id); + break; } } + // wait for work if empty. { let mut more_to_verify = verification.more_to_verify.lock().unwrap(); @@ -305,15 +289,22 @@ impl VerificationQueue { empty.notify_all(); } - while verification.unverified.lock().is_empty() && !deleting.load(AtomicOrdering::Acquire) { + while verification.unverified.lock().is_empty() { + if let State::Exit = *state.0.lock() { + debug!(target: "verification", "verifier {} exiting", id); + return; + } + more_to_verify = wait.wait(more_to_verify).unwrap(); } - if deleting.load(AtomicOrdering::Acquire) { + if let State::Exit = *state.0.lock() { + debug!(target: "verification", "verifier {} exiting", id); return; } } + // do work. let item = { // acquire these locks before getting the item to verify. let mut unverified = verification.unverified.lock(); @@ -568,6 +559,14 @@ impl VerificationQueue { } } + /// Get the current number of working verifiers. + pub fn num_verifiers(&self) -> usize { + match *self.state.0.lock() { + State::Work(x) => x, + State::Exit => panic!("state only set to exit on drop; queue live now; qed"), + } + } + /// Optimise memory footprint of the heap fields, and adjust the number of threads /// to better suit the workload. pub fn collect_garbage(&self) { @@ -604,7 +603,7 @@ impl VerificationQueue { return; } - let current = self.verifiers.lock().1; + let current = self.num_verifiers(); let diff = (v_len - u_len).abs(); let total = v_len + u_len; @@ -626,27 +625,14 @@ impl VerificationQueue { // possible, never going over the amount of initially allocated threads // or below 1. fn scale_verifiers(&self, target: usize) { - let mut verifiers = self.verifiers.lock(); - let &mut (ref mut verifiers, ref mut verifier_count) = &mut *verifiers; - - let target = min(verifiers.len(), target); + let current = self.num_verifiers(); + let target = min(self.verifier_handles.len(), target); let target = max(1, target); - debug!(target: "verification", "Scaling from {} to {} verifiers", verifier_count, target); + debug!(target: "verification", "Scaling from {} to {} verifiers", current, target); - // scaling up - for i in *verifier_count..target { - debug!(target: "verification", "Waking up verifier {}", i); - verifiers[i].wake_up(); - } - - // scaling down. - for i in target..*verifier_count { - debug!(target: "verification", "Putting verifier {} to sleep", i); - verifiers[i].sleep(); - } - - *verifier_count = target; + *self.state.0.lock() = State::Work(target); + self.state.1.notify_all(); } } @@ -660,22 +646,18 @@ impl Drop for VerificationQueue { fn drop(&mut self) { trace!(target: "shutdown", "[VerificationQueue] Closing..."); self.clear(); - self.deleting.store(true, AtomicOrdering::Release); + self.deleting.store(true, AtomicOrdering::SeqCst); - let mut verifiers = self.verifiers.get_mut(); - let mut verifiers = &mut verifiers.0; - - // first pass to signal conclusion. must be done before - // notify or deadlock possible. - for handle in verifiers.iter() { - handle.conclude(); - } + // set exit state; should be done before `more_to_verify` notification. + *self.state.0.lock() = State::Exit; + self.state.1.notify_all(); + // wake up all threads waiting for more work. self.more_to_verify.notify_all(); - // second pass to join. - for handle in verifiers.drain(..) { - handle.join(); + // wait for all verifier threads to join. + for thread in self.verifier_handles.drain(..) { + thread.join().expect("Propagating verifier thread panic on shutdown"); } trace!(target: "shutdown", "[VerificationQueue] Closed."); @@ -687,7 +669,7 @@ mod tests { use util::*; use io::*; use spec::*; - use super::{BlockQueue, Config}; + use super::{BlockQueue, Config, State}; use super::kind::blocks::Unverified; use tests::helpers::*; use error::*; @@ -784,11 +766,11 @@ mod tests { let queue = get_test_queue(); queue.scale_verifiers(MAX_VERIFIERS + 1); - assert!(queue.verifiers.lock().1 < MAX_VERIFIERS + 1); + assert!(queue.num_verifiers() < MAX_VERIFIERS + 1); queue.scale_verifiers(0); - assert!(queue.verifiers.lock().1 == 1); + assert!(queue.num_verifiers() == 1); } #[test] @@ -797,14 +779,7 @@ mod tests { // put all the verifiers to sleep to ensure // the test isn't timing sensitive. - let num_verifiers = { - let verifiers = queue.verifiers.lock(); - for i in 0..verifiers.1 { - verifiers.0[i].sleep(); - } - - verifiers.1 - }; + *queue.state.0.lock() = State::Work(0); for block in get_good_dummy_block_seq(5000) { queue.import(Unverified::new(block)).expect("Block good by definition; qed"); @@ -812,20 +787,12 @@ mod tests { // almost all unverified == bump verifier count. queue.collect_garbage(); - assert_eq!(queue.verifiers.lock().1, num_verifiers + 1); - - // wake them up again and verify everything. - { - let verifiers = queue.verifiers.lock(); - for i in 0..verifiers.1 { - verifiers.0[i].wake_up(); - } - } + assert_eq!(queue.num_verifiers(), 1); queue.flush(); // nothing to verify == use minimum number of verifiers. queue.collect_garbage(); - assert_eq!(queue.verifiers.lock().1, 1); + assert_eq!(queue.num_verifiers(), 1); } } From 01bf483b63152b3e5fb1a5cf4ea8285a033cfc6b Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 17:29:47 +0000 Subject: [PATCH 08/14] remove unnecessary impls --- ethcore/src/engines/authority_round.rs | 4 ---- ethcore/src/engines/basic_authority.rs | 5 ----- ethcore/src/miner/miner.rs | 5 ----- 3 files changed, 14 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 646c107e0..02993fe83 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -209,10 +209,6 @@ impl Engine for AuthorityRound { }); } - /// Apply the block reward on finalisation of the block. - /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). - fn on_close_block(&self, _block: &mut ExecutedBlock) {} - fn is_sealer(&self, author: &Address) -> Option { let p = &self.our_params; Some(p.authorities.contains(author)) diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 0b9040a11..264a2d55a 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -100,13 +100,8 @@ impl Engine for BasicAuthority { max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); -// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit); } - /// Apply the block reward on finalisation of the block. - /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). - fn on_close_block(&self, _block: &mut ExecutedBlock) {} - fn is_sealer(&self, author: &Address) -> Option { Some(self.our_params.authorities.contains(author)) } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 4b38a7e07..3b4223c68 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1030,11 +1030,6 @@ impl MinerService for Miner { let (block, original_work_hash) = self.prepare_block(chain); if self.seals_internally { trace!(target: "miner", "update_sealing: engine indicates internal sealing"); - { - let mut sealing_work = self.sealing_work.lock(); - sealing_work.queue.push(block.clone()); - sealing_work.queue.use_last_ref(); - } self.seal_and_import_block_internally(chain, block); } else { trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work"); From 873f451df123fe17ac91169b6fc75d84831af873 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 5 Dec 2016 18:42:44 +0100 Subject: [PATCH 09/14] Move decoding for contract deployment logic earlier (#3714) * Move decoding deployment logic earlier * Removed rendunant isContract --- js/src/ui/MethodDecoding/methodDecoding.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/js/src/ui/MethodDecoding/methodDecoding.js b/js/src/ui/MethodDecoding/methodDecoding.js index 70258f744..efb22b67b 100644 --- a/js/src/ui/MethodDecoding/methodDecoding.js +++ b/js/src/ui/MethodDecoding/methodDecoding.js @@ -457,6 +457,14 @@ class MethodDecoding extends Component { return; } + const { signature, paramdata } = api.util.decodeCallData(input); + this.setState({ methodSignature: signature, methodParams: paramdata }); + + if (!signature || signature === CONTRACT_CREATE || transaction.creates) { + this.setState({ isDeploy: true }); + return; + } + if (contractAddress === '0x') { return; } @@ -472,14 +480,6 @@ class MethodDecoding extends Component { return; } - const { signature, paramdata } = api.util.decodeCallData(input); - this.setState({ methodSignature: signature, methodParams: paramdata }); - - if (!signature || signature === CONTRACT_CREATE || transaction.creates) { - this.setState({ isDeploy: true }); - return; - } - return Contracts.get() .signatureReg .lookup(signature) From 98bfbdc5cb20516da71ede43ae3b86dcb9895fe1 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Mon, 5 Dec 2016 17:50:43 +0000 Subject: [PATCH 10/14] [ci skip] js-precompiled 20161205-174841 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6fa12b3a..660389a4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1270,7 +1270,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#7700411d2b0ba1372e0d6cf72a84ecf873a181f3" +source = "git+https://github.com/ethcore/js-precompiled.git#3cf6c68b7d08be71d12ff142e255a42043e50c75" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 5341cee31..42836bb7c 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.91", + "version": "0.2.92", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 5e7c21ad4aa613038d30715fc5b55f02e50a904b Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 19:23:03 +0000 Subject: [PATCH 11/14] add a cli flag --- parity/cli/config.full.toml | 1 + parity/cli/config.toml | 1 + parity/cli/mod.rs | 5 +++++ parity/cli/usage.txt | 4 ++++ parity/configuration.rs | 5 +++++ parity/helpers.rs | 4 ++-- parity/params.rs | 2 ++ parity/run.rs | 14 +++++++++----- 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/parity/cli/config.full.toml b/parity/cli/config.full.toml index fcd9a9712..e2e4aeb5a 100644 --- a/parity/cli/config.full.toml +++ b/parity/cli/config.full.toml @@ -61,6 +61,7 @@ pass = "test_pass" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" +consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/config.toml b/parity/cli/config.toml index c9bd563a8..b84c10b22 100644 --- a/parity/cli/config.toml +++ b/parity/cli/config.toml @@ -40,6 +40,7 @@ pass = "password" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" +consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 7fcdd2209..8939b22e1 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -178,6 +178,8 @@ usage! { // -- Sealing/Mining Options flag_author: Option = None, or |c: &Config| otry!(c.mining).author.clone().map(Some), + flag_engine_signer: Option = None, + or |c: &Config| otry!(c.mining).consensus_signer.clone().map(Some), flag_force_sealing: bool = false, or |c: &Config| otry!(c.mining).force_sealing.clone(), flag_reseal_on_txs: String = "own", @@ -367,6 +369,7 @@ struct Dapps { #[derive(Default, Debug, PartialEq, RustcDecodable)] struct Mining { author: Option, + consensus_signer: Option, force_sealing: Option, reseal_on_txs: Option, reseal_min_period: Option, @@ -569,6 +572,7 @@ mod tests { // -- Sealing/Mining Options flag_author: Some("0xdeadbeefcafe0000000000000000000000000001".into()), + flag_engine_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), flag_force_sealing: true, flag_reseal_on_txs: "all".into(), flag_reseal_min_period: 4000u64, @@ -738,6 +742,7 @@ mod tests { }), mining: Some(Mining { author: Some("0xdeadbeefcafe0000000000000000000000000001".into()), + consensus_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), force_sealing: Some(true), reseal_on_txs: Some("all".into()), reseal_min_period: Some(4000), diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index b67af6110..2829f4fe1 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -149,6 +149,10 @@ Sealing/Mining Options: for sending block rewards from sealed blocks. NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION. (default: {flag_author:?}) + --engine-signer ADDRESS Specify the address which should be used to + sign consensus messages and issue blocks. + Relevant only to non-PoW chains. + (default: {flag_engine_signer:?}) --force-sealing Force the node to author new blocks as if it were always sealing/mining. (default: {flag_force_sealing}) diff --git a/parity/configuration.rs b/parity/configuration.rs index 37c699521..0ba084673 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -300,6 +300,7 @@ impl Configuration { gas_floor_target: try!(to_u256(&self.args.flag_gas_floor_target)), gas_ceil_target: try!(to_u256(&self.args.flag_gas_cap)), transactions_limit: self.args.flag_tx_queue_size, + consensus_signer: try!(self.consensus_signer()), }; Ok(extras) @@ -309,6 +310,10 @@ impl Configuration { to_address(self.args.flag_etherbase.clone().or(self.args.flag_author.clone())) } + fn consensus_signer(&self) -> Result { + to_address(self.args.flag_engine_signer.clone()) + } + fn format(&self) -> Result, String> { match self.args.flag_format { Some(ref f) => Ok(Some(try!(f.parse()))), diff --git a/parity/helpers.rs b/parity/helpers.rs index ab0dafddd..654270b64 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -300,14 +300,14 @@ pub fn password_prompt() -> Result { /// Read a password from password file. pub fn password_from_file(path: String) -> Result { - let passwords = try!(passwords_from_files(vec![path])); + let passwords = try!(passwords_from_files(&[path])); // use only first password from the file passwords.get(0).map(String::to_owned) .ok_or_else(|| "Password file seems to be empty.".to_owned()) } /// Reads passwords from files. Treats each line as a separate password. -pub fn passwords_from_files(files: Vec) -> Result, String> { +pub fn passwords_from_files(files: &[String]) -> Result, String> { let passwords = files.iter().map(|filename| { let file = try!(File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename))); let reader = BufReader::new(&file); diff --git a/parity/params.rs b/parity/params.rs index 3ce07e889..97a5e7b08 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -204,6 +204,7 @@ pub struct MinerExtras { pub gas_floor_target: U256, pub gas_ceil_target: U256, pub transactions_limit: usize, + pub consensus_signer: Address, } impl Default for MinerExtras { @@ -214,6 +215,7 @@ impl Default for MinerExtras { gas_floor_target: U256::from(4_700_000), gas_ceil_target: U256::from(6_283_184), transactions_limit: 1024, + consensus_signer: Default::default(), } } } diff --git a/parity/run.rs b/parity/run.rs index 2509d1347..332f296c1 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -205,8 +205,10 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { sync_config.warp_sync = cmd.warp_sync; sync_config.download_old_blocks = cmd.download_old_blocks; + let passwords = try!(passwords_from_files(&cmd.acc_conf.password_files)); + // prepare account provider - let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf))); + let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf, &passwords))); // let the Engine access the accounts spec.engine.register_account_provider(account_provider.clone()); @@ -218,6 +220,10 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target); miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); + let consensus_signer = cmd.miner_extras.consensus_signer; + if passwords.into_iter().any(|p| miner.set_consensus_signer(consensus_signer, p).is_ok()) { + return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.consensus_signer)); + } // create client config let client_config = to_client_config( @@ -424,19 +430,17 @@ fn daemonize(_pid_file: String) -> Result<(), String> { Err("daemon is no supported on windows".into()) } -fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig) -> Result { +fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig, passwords: &[String]) -> Result { use ethcore::ethstore::EthStore; use ethcore::ethstore::dir::DiskDirectory; - let passwords = try!(passwords_from_files(cfg.password_files)); - let dir = Box::new(try!(DiskDirectory::create(dirs.keys.clone()).map_err(|e| format!("Could not open keys directory: {}", e)))); let account_service = AccountProvider::new(Box::new( try!(EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e))) )); for a in cfg.unlocked_accounts { - if passwords.iter().find(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()).is_none() { + if passwords.iter().any(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()) { return Err(format!("No password found to unlock account {}. Make sure valid password is present in files passed using `--password`.", a)); } } From 46dd2543e5b104a58bd4dd2aae32c1c4158aae62 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 19:27:24 +0000 Subject: [PATCH 12/14] rename rpc to match cli --- rpc/src/v1/tests/mocked/parity_set.rs | 2 +- rpc/src/v1/traits/parity_set.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index fdf3f2d0f..5c249f08b 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -114,7 +114,7 @@ fn rpc_parity_set_consensus_signer() { let io = IoHandler::new(); io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate()); - let request = r#"{"jsonrpc": "2.0", "method": "parity_setConsensusSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#; + let request = r#"{"jsonrpc": "2.0", "method": "parity_setEngineSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index e196a7d21..c41a88033 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -45,7 +45,7 @@ build_rpc_trait! { fn set_author(&self, H160) -> Result; /// Sets account for signing consensus messages. - #[rpc(name = "parity_setConsensusSigner")] + #[rpc(name = "parity_setEngineSigner")] fn set_consensus_signer(&self, H160, String) -> Result; /// Sets the limits for transaction queue. From 0a2ec319ac5be557493de6df53f381c09fde6108 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 21:31:38 +0000 Subject: [PATCH 13/14] rename to engine_signer --- ethcore/src/miner/miner.rs | 2 +- ethcore/src/miner/mod.rs | 2 +- parity/cli/config.full.toml | 2 +- parity/cli/config.toml | 2 +- parity/cli/mod.rs | 6 +++--- parity/configuration.rs | 4 ++-- parity/params.rs | 4 ++-- parity/run.rs | 6 +++--- rpc/src/v1/impls/parity_set.rs | 4 ++-- rpc/src/v1/tests/helpers/miner_service.rs | 2 +- rpc/src/v1/tests/mocked/parity_set.rs | 2 +- rpc/src/v1/traits/parity_set.rs | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 3b4223c68..8d1f55567 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -737,7 +737,7 @@ impl MinerService for Miner { *self.author.write() = author; } - fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + fn set_engine_signer(&self, address: Address, password: String) -> Result<(), AccountError> { if self.seals_internally { if let Some(ref ap) = self.accounts { try!(ap.sign(address.clone(), Some(password.clone()), Default::default())); diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 26cefb295..8c466581b 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -77,7 +77,7 @@ pub trait MinerService : Send + Sync { fn set_author(&self, author: Address); /// Set info necessary to sign consensus messages. - fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), ::account_provider::Error>; + fn set_engine_signer(&self, address: Address, password: String) -> Result<(), ::account_provider::Error>; /// Get the extra_data that we will seal blocks with. fn extra_data(&self) -> Bytes; diff --git a/parity/cli/config.full.toml b/parity/cli/config.full.toml index e2e4aeb5a..4f3e4fa07 100644 --- a/parity/cli/config.full.toml +++ b/parity/cli/config.full.toml @@ -61,7 +61,7 @@ pass = "test_pass" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" -consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" +engine_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/config.toml b/parity/cli/config.toml index b84c10b22..34bab5b46 100644 --- a/parity/cli/config.toml +++ b/parity/cli/config.toml @@ -40,7 +40,7 @@ pass = "password" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" -consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" +engine_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 8939b22e1..1f6a266b3 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -179,7 +179,7 @@ usage! { flag_author: Option = None, or |c: &Config| otry!(c.mining).author.clone().map(Some), flag_engine_signer: Option = None, - or |c: &Config| otry!(c.mining).consensus_signer.clone().map(Some), + or |c: &Config| otry!(c.mining).engine_signer.clone().map(Some), flag_force_sealing: bool = false, or |c: &Config| otry!(c.mining).force_sealing.clone(), flag_reseal_on_txs: String = "own", @@ -369,7 +369,7 @@ struct Dapps { #[derive(Default, Debug, PartialEq, RustcDecodable)] struct Mining { author: Option, - consensus_signer: Option, + engine_signer: Option, force_sealing: Option, reseal_on_txs: Option, reseal_min_period: Option, @@ -742,7 +742,7 @@ mod tests { }), mining: Some(Mining { author: Some("0xdeadbeefcafe0000000000000000000000000001".into()), - consensus_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), + engine_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), force_sealing: Some(true), reseal_on_txs: Some("all".into()), reseal_min_period: Some(4000), diff --git a/parity/configuration.rs b/parity/configuration.rs index 0ba084673..bcca3aa58 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -300,7 +300,7 @@ impl Configuration { gas_floor_target: try!(to_u256(&self.args.flag_gas_floor_target)), gas_ceil_target: try!(to_u256(&self.args.flag_gas_cap)), transactions_limit: self.args.flag_tx_queue_size, - consensus_signer: try!(self.consensus_signer()), + engine_signer: try!(self.engine_signer()), }; Ok(extras) @@ -310,7 +310,7 @@ impl Configuration { to_address(self.args.flag_etherbase.clone().or(self.args.flag_author.clone())) } - fn consensus_signer(&self) -> Result { + fn engine_signer(&self) -> Result { to_address(self.args.flag_engine_signer.clone()) } diff --git a/parity/params.rs b/parity/params.rs index 97a5e7b08..25ddc8814 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -204,7 +204,7 @@ pub struct MinerExtras { pub gas_floor_target: U256, pub gas_ceil_target: U256, pub transactions_limit: usize, - pub consensus_signer: Address, + pub engine_signer: Address, } impl Default for MinerExtras { @@ -215,7 +215,7 @@ impl Default for MinerExtras { gas_floor_target: U256::from(4_700_000), gas_ceil_target: U256::from(6_283_184), transactions_limit: 1024, - consensus_signer: Default::default(), + engine_signer: Default::default(), } } } diff --git a/parity/run.rs b/parity/run.rs index 332f296c1..774dd6271 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -220,9 +220,9 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target); miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); - let consensus_signer = cmd.miner_extras.consensus_signer; - if passwords.into_iter().any(|p| miner.set_consensus_signer(consensus_signer, p).is_ok()) { - return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.consensus_signer)); + let engine_signer = cmd.miner_extras.engine_signer; + if passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { + return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.engine_signer)); } // create client config diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index e28f9a573..92de99a1f 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -116,9 +116,9 @@ impl ParitySet for ParitySetClient where Ok(true) } - fn set_consensus_signer(&self, address: H160, password: String) -> Result { + fn set_engine_signer(&self, address: H160, password: String) -> Result { try!(self.active()); - try!(take_weak!(self.miner).set_consensus_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)); + try!(take_weak!(self.miner).set_engine_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)); Ok(true) } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 6037cdd4a..39fba8406 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -87,7 +87,7 @@ impl MinerService for TestMinerService { *self.author.write() = author; } - fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + fn set_engine_signer(&self, address: Address, password: String) -> Result<(), AccountError> { *self.author.write() = address; *self.password.write() = password; Ok(()) diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 5c249f08b..55f155693 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -107,7 +107,7 @@ fn rpc_parity_set_author() { } #[test] -fn rpc_parity_set_consensus_signer() { +fn rpc_parity_set_engine_signer() { let miner = miner_service(); let client = client_service(); let network = network_service(); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index c41a88033..c40abd01f 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -46,7 +46,7 @@ build_rpc_trait! { /// Sets account for signing consensus messages. #[rpc(name = "parity_setEngineSigner")] - fn set_consensus_signer(&self, H160, String) -> Result; + fn set_engine_signer(&self, H160, String) -> Result; /// Sets the limits for transaction queue. #[rpc(name = "parity_setTransactionsLimit")] From b089aa7a6b47d955a0d66503c98f239b6eb3dc62 Mon Sep 17 00:00:00 2001 From: keorn Date: Tue, 6 Dec 2016 08:38:41 +0000 Subject: [PATCH 14/14] fix password loading --- parity/run.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parity/run.rs b/parity/run.rs index 774dd6271..cd2392ae6 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -221,7 +221,7 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); let engine_signer = cmd.miner_extras.engine_signer; - if passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { + if !passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.engine_signer)); } @@ -440,7 +440,7 @@ fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig, passwords: )); for a in cfg.unlocked_accounts { - if passwords.iter().any(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()) { + if !passwords.iter().any(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()) { return Err(format!("No password found to unlock account {}. Make sure valid password is present in files passed using `--password`.", a)); } }