Deprecate account management (#10213)

* Extract accounts from ethcore.

* Fix ethcore.

* Get rid of AccountProvider in test_helpers

* Fix rest of the code.

* Re-use EngineSigner, fix tests.

* Simplify EngineSigner to always have an Address.

* Fix RPC tests.

* Add deprecation notice to RPCs.

* Feature to disable accounts.

* extract accounts in RPC

* Run with accounts in tests.

* Fix RPC compilation and tests.

* Fix compilation of the binary.

* Fix compilation of the binary.

* Fix compilation with accounts enabled.

* Fix tests.

* Update submodule.

* Remove android.

* Use derive for Default

* Don't build secretstore by default.

* Add link to issue.

* Refresh Cargo.lock.

* Fix miner tests.

* Update rpc/Cargo.toml

Co-Authored-By: tomusdrw <tomusdrw@users.noreply.github.com>

* Fix private tests.
This commit is contained in:
Tomasz Drwięga
2019-02-07 14:34:24 +01:00
committed by Afri Schoedon
parent 8fa56add47
commit d5c19f8719
102 changed files with 3222 additions and 2393 deletions

View File

@@ -24,7 +24,6 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::sync::{Weak, Arc};
use std::time::{UNIX_EPOCH, SystemTime, Duration};
use account_provider::AccountProvider;
use block::*;
use client::EngineClient;
use engines::{Engine, Seal, EngineError, ConstructedVerifier};
@@ -37,7 +36,7 @@ use hash::keccak;
use super::signer::EngineSigner;
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
use self::finality::RollingFinality;
use ethkey::{self, Password, Signature};
use ethkey::{self, Signature};
use io::{IoContext, IoHandler, TimerToken, IoService};
use itertools::{self, Itertools};
use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp};
@@ -412,7 +411,7 @@ pub struct AuthorityRound {
transition_service: IoService<()>,
step: Arc<PermissionedStep>,
client: Arc<RwLock<Option<Weak<EngineClient>>>>,
signer: RwLock<EngineSigner>,
signer: RwLock<Option<Box<EngineSigner>>>,
validators: Box<ValidatorSet>,
validate_score_transition: u64,
validate_step_transition: u64,
@@ -665,7 +664,7 @@ impl AuthorityRound {
can_propose: AtomicBool::new(true),
}),
client: Arc::new(RwLock::new(None)),
signer: Default::default(),
signer: RwLock::new(None),
validators: our_params.validators,
validate_score_transition: our_params.validate_score_transition,
validate_step_transition: our_params.validate_step_transition,
@@ -788,7 +787,7 @@ impl AuthorityRound {
return;
}
if let (true, Some(me)) = (current_step > parent_step + 1, self.signer.read().address()) {
if let (true, Some(me)) = (current_step > parent_step + 1, self.signer.read().as_ref().map(|s| s.address())) {
debug!(target: "engine", "Author {} built block with step gap. current step: {}, parent step: {}",
header.author(), current_step, parent_step);
let mut reported = HashSet::new();
@@ -1492,12 +1491,16 @@ impl Engine<EthereumMachine> for AuthorityRound {
self.validators.register_client(client);
}
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: Password) {
self.signer.write().set(ap, address, password);
fn set_signer(&self, signer: Box<EngineSigner>) {
*self.signer.write() = Some(signer);
}
fn sign(&self, hash: H256) -> Result<Signature, Error> {
Ok(self.signer.read().sign(hash)?)
Ok(self.signer.read()
.as_ref()
.ok_or(ethkey::Error::InvalidAddress)?
.sign(hash)?
)
}
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
@@ -1532,16 +1535,16 @@ mod tests {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use hash::keccak;
use accounts::AccountProvider;
use ethereum_types::{Address, H520, H256, U256};
use ethkey::Signature;
use types::header::Header;
use rlp::encode;
use block::*;
use test_helpers::{
generate_dummy_client_with_spec_and_accounts, get_temp_state_db,
generate_dummy_client_with_spec, get_temp_state_db,
TestNotify
};
use account_provider::AccountProvider;
use spec::Spec;
use types::transaction::{Action, Transaction};
use engines::{Seal, Engine, EngineError, EthEngine};
@@ -1620,14 +1623,14 @@ mod tests {
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b2 = b2.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) {
assert!(b1.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden.
assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None);
}
engine.set_signer(tap, addr2, "2".into());
engine.set_signer(Box::new((tap, addr2, "2".into())));
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) {
assert!(b2.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden.
@@ -1654,13 +1657,13 @@ mod tests {
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b2 = b2.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
match engine.generate_seal(b1.block(), &genesis_header) {
Seal::None | Seal::Proposal(_) => panic!("wrong seal"),
Seal::Regular(_) => {
engine.step();
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
match engine.generate_seal(b2.block(), &genesis_header) {
Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"),
Seal::None => {}
@@ -1768,7 +1771,7 @@ mod tests {
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 0);
aura.set_signer(Arc::new(AccountProvider::transient_provider()), Default::default(), "".into());
aura.set_signer(Box::new((Arc::new(AccountProvider::transient_provider()), Default::default(), "".into())));
// Do not report on steps skipped between genesis and first block.
header.set_number(1);
@@ -1878,12 +1881,12 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
let notify = Arc::new(TestNotify::default());
client.add_notify(notify.clone());
engine.register_client(Arc::downgrade(&client) as _);
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b1 = b1.close_and_lock().unwrap();
@@ -1917,7 +1920,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
let notify = Arc::new(TestNotify::default());
client.add_notify(notify.clone());
engine.register_client(Arc::downgrade(&client) as _);
@@ -1927,7 +1930,7 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
@@ -1944,9 +1947,9 @@ mod tests {
let b2 = b2.close_and_lock().unwrap();
// we will now seal a block with 1tx and include the accumulated empty step message
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) {
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash());
let empty_steps = ::rlp::encode_list(&vec![empty_step2]);
@@ -1970,7 +1973,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
let notify = Arc::new(TestNotify::default());
client.add_notify(notify.clone());
engine.register_client(Arc::downgrade(&client) as _);
@@ -1980,14 +1983,14 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
// step 3
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b2 = b2.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
assert_eq!(engine.generate_seal(b2.block(), &genesis_header), Seal::None);
engine.step();
@@ -1996,10 +1999,10 @@ mod tests {
let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, &mut Vec::new().into_iter()).unwrap();
let b3 = b3.close_and_lock().unwrap();
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
if let Seal::Regular(seal) = engine.generate_seal(b3.block(), &genesis_header) {
let empty_step2 = sealed_empty_step(engine, 2, &genesis_header.hash());
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
let empty_step3 = sealed_empty_step(engine, 3, &genesis_header.hash());
let empty_steps = ::rlp::encode_list(&vec![empty_step2, empty_step3]);
@@ -2022,7 +2025,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_round_empty_steps, None);
let client = generate_dummy_client_with_spec(Spec::new_test_round_empty_steps);
engine.register_client(Arc::downgrade(&client) as _);
// step 2
@@ -2030,7 +2033,7 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
@@ -2084,7 +2087,7 @@ mod tests {
);
// empty step with valid signature from incorrect proposer for step
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let empty_steps = vec![sealed_empty_step(engine, 1, &parent_header.hash())];
set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
@@ -2094,9 +2097,9 @@ mod tests {
);
// valid empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let empty_step2 = sealed_empty_step(engine, 2, &parent_header.hash());
engine.set_signer(tap.clone(), addr2, "0".into());
engine.set_signer(Box::new((tap.clone(), addr2, "0".into())));
let empty_step3 = sealed_empty_step(engine, 3, &parent_header.hash());
let empty_steps = vec![empty_step2, empty_step3];
@@ -2121,10 +2124,7 @@ mod tests {
let last_hashes = Arc::new(vec![genesis_header.hash()]);
let client = generate_dummy_client_with_spec_and_accounts(
Spec::new_test_round_block_reward_contract,
None,
);
let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract);
engine.register_client(Arc::downgrade(&client) as _);
// step 2
@@ -2144,7 +2144,7 @@ mod tests {
let b1 = b1.close_and_lock().unwrap();
// since the block is empty it isn't sealed and we generate empty steps
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
assert_eq!(engine.generate_seal(b1.block(), &genesis_header), Seal::None);
engine.step();
@@ -2182,7 +2182,7 @@ mod tests {
let engine = &*spec.engine;
let addr1 = accounts[0];
engine.set_signer(tap.clone(), addr1, "1".into());
engine.set_signer(Box::new((tap.clone(), addr1, "1".into())));
let mut header: Header = Header::default();
let empty_step = empty_step(engine, 1, &header.parent_hash());
@@ -2263,7 +2263,7 @@ mod tests {
header.set_author(accounts[0]);
// when
engine.set_signer(tap.clone(), accounts[1], "0".into());
engine.set_signer(Box::new((tap.clone(), accounts[1], "0".into())));
let empty_steps = vec![
sealed_empty_step(&*engine, 1, &parent.hash()),
sealed_empty_step(&*engine, 1, &parent.hash()),
@@ -2300,9 +2300,9 @@ mod tests {
header.set_author(accounts[0]);
// when
engine.set_signer(tap.clone(), accounts[1], "0".into());
engine.set_signer(Box::new((tap.clone(), accounts[1], "0".into())));
let es1 = sealed_empty_step(&*engine, 1, &parent.hash());
engine.set_signer(tap.clone(), accounts[0], "1".into());
engine.set_signer(Box::new((tap.clone(), accounts[0], "1".into())));
let es2 = sealed_empty_step(&*engine, 2, &parent.hash());
let mut empty_steps = vec![es2, es1];

View File

@@ -16,19 +16,18 @@
//! A blockchain engine that supports a basic, non-BFT proof-of-authority.
use std::sync::{Weak, Arc};
use ethereum_types::{H256, H520, Address};
use std::sync::Weak;
use ethereum_types::{H256, H520};
use parking_lot::RwLock;
use ethkey::{self, Password, Signature};
use account_provider::AccountProvider;
use ethkey::{self, Signature};
use block::*;
use engines::{Engine, Seal, ConstructedVerifier, EngineError};
use engines::signer::EngineSigner;
use error::{BlockError, Error};
use ethjson;
use client::EngineClient;
use machine::{AuxiliaryData, Call, EthereumMachine};
use types::header::{Header, ExtendedHeader};
use super::signer::EngineSigner;
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
/// `BasicAuthority` params.
@@ -76,7 +75,7 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err
/// Engine using `BasicAuthority`, trivial proof-of-authority consensus.
pub struct BasicAuthority {
machine: EthereumMachine,
signer: RwLock<EngineSigner>,
signer: RwLock<Option<Box<EngineSigner>>>,
validators: Box<ValidatorSet>,
}
@@ -85,7 +84,7 @@ impl BasicAuthority {
pub fn new(our_params: BasicAuthorityParams, machine: EthereumMachine) -> Self {
BasicAuthority {
machine: machine,
signer: Default::default(),
signer: RwLock::new(None),
validators: new_validator_set(our_params.validators),
}
}
@@ -190,12 +189,16 @@ impl Engine<EthereumMachine> for BasicAuthority {
self.validators.register_client(client);
}
fn set_signer(&self, ap: Arc<AccountProvider>, address: Address, password: Password) {
self.signer.write().set(ap, address, password);
fn set_signer(&self, signer: Box<EngineSigner>) {
*self.signer.write() = Some(signer);
}
fn sign(&self, hash: H256) -> Result<Signature, Error> {
Ok(self.signer.read().sign(hash)?)
Ok(self.signer.read()
.as_ref()
.ok_or_else(|| ethkey::Error::InvalidAddress)?
.sign(hash)?
)
}
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
@@ -214,7 +217,7 @@ mod tests {
use ethereum_types::H520;
use block::*;
use test_helpers::get_temp_state_db;
use account_provider::AccountProvider;
use accounts::AccountProvider;
use types::header::Header;
use spec::Spec;
use engines::Seal;
@@ -257,7 +260,7 @@ mod tests {
let spec = new_test_authority();
let engine = &*spec.engine;
engine.set_signer(Arc::new(tap), addr, "".into());
engine.set_signer(Box::new((Arc::new(tap), addr, "".into())));
let genesis_header = spec.genesis_header();
let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
let last_hashes = Arc::new(vec![genesis_header.hash()]);
@@ -275,7 +278,7 @@ mod tests {
let engine = new_test_authority().engine;
assert!(!engine.seals_internally().unwrap());
engine.set_signer(Arc::new(tap), authority, "".into());
engine.set_signer(Box::new((Arc::new(tap), authority, "".into())));
assert!(engine.seals_internally().unwrap());
}
}

View File

@@ -170,17 +170,14 @@ mod test {
use client::PrepareOpenBlock;
use ethereum_types::U256;
use spec::Spec;
use test_helpers::generate_dummy_client_with_spec_and_accounts;
use test_helpers::generate_dummy_client_with_spec;
use engines::SystemOrCodeCallKind;
use super::{BlockRewardContract, RewardKind};
#[test]
fn block_reward_contract() {
let client = generate_dummy_client_with_spec_and_accounts(
Spec::new_test_round_block_reward_contract,
None,
);
let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract);
let machine = Spec::new_test_machine();

View File

@@ -20,16 +20,17 @@ mod authority_round;
mod basic_authority;
mod instant_seal;
mod null_engine;
mod signer;
mod validator_set;
pub mod block_reward;
pub mod signer;
pub use self::authority_round::AuthorityRound;
pub use self::basic_authority::BasicAuthority;
pub use self::epoch::{EpochVerifier, Transition as EpochTransition};
pub use self::instant_seal::{InstantSeal, InstantSealParams};
pub use self::null_engine::NullEngine;
pub use self::signer::EngineSigner;
// TODO [ToDr] Remove re-export (#10130)
pub use types::engines::ForkChoice;
@@ -39,7 +40,6 @@ use std::sync::{Weak, Arc};
use std::collections::{BTreeMap, HashMap};
use std::{fmt, error};
use account_provider::AccountProvider;
use builtin::Builtin;
use vm::{EnvInfo, Schedule, CreateContractAddress, CallType, ActionValue};
use error::Error;
@@ -49,7 +49,7 @@ use snapshot::SnapshotComponents;
use spec::CommonParams;
use types::transaction::{self, UnverifiedTransaction, SignedTransaction};
use ethkey::{Password, Signature};
use ethkey::{Signature};
use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader};
use ethereum_types::{H256, U256, Address};
use unexpected::{Mismatch, OutOfBounds};
@@ -380,8 +380,8 @@ pub trait Engine<M: Machine>: Sync + Send {
/// Takes a header of a fully verified block.
fn is_proposal(&self, _verified_header: &M::Header) -> bool { false }
/// Register an account which signs consensus messages.
fn set_signer(&self, _account_provider: Arc<AccountProvider>, _address: Address, _password: Password) {}
/// Register a component which signs consensus messages.
fn set_signer(&self, _signer: Box<EngineSigner>) {}
/// Sign using the EngineSigner, to be used for consensus tx signing.
fn sign(&self, _hash: H256) -> Result<Signature, M::Error> { unimplemented!() }

View File

@@ -16,49 +16,68 @@
//! A signer used by Engines which need to sign messages.
use std::sync::Arc;
use ethereum_types::{H256, Address};
use ethkey::{Password, Signature};
use account_provider::{self, AccountProvider};
use ethkey::{self, Signature};
/// Everything that an Engine needs to sign messages.
pub struct EngineSigner {
account_provider: Arc<AccountProvider>,
address: Option<Address>,
password: Option<Password>,
pub trait EngineSigner: Send + Sync {
/// Sign a consensus message hash.
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error>;
/// Signing address
fn address(&self) -> Address;
}
impl Default for EngineSigner {
fn default() -> Self {
EngineSigner {
account_provider: Arc::new(AccountProvider::transient_provider()),
address: Default::default(),
password: Default::default(),
/// Creates a new `EngineSigner` from given key pair.
pub fn from_keypair(keypair: ethkey::KeyPair) -> Box<EngineSigner> {
Box::new(Signer(keypair))
}
struct Signer(ethkey::KeyPair);
impl EngineSigner for Signer {
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error> {
ethkey::sign(self.0.secret(), &hash)
}
fn address(&self) -> Address {
self.0.address()
}
}
#[cfg(test)]
mod test_signer {
use std::sync::Arc;
use ethkey::Password;
use accounts::{self, AccountProvider, SignError};
use super::*;
impl EngineSigner for (Arc<AccountProvider>, Address, Password) {
fn sign(&self, hash: H256) -> Result<Signature, ethkey::Error> {
match self.0.sign(self.1, Some(self.2.clone()), hash) {
Err(SignError::NotUnlocked) => unreachable!(),
Err(SignError::NotFound) => Err(ethkey::Error::InvalidAddress),
Err(SignError::Hardware(err)) => {
warn!("Error using hardware wallet for engine: {:?}", err);
Err(ethkey::Error::InvalidSecret)
},
Err(SignError::SStore(accounts::Error::EthKey(err))) => Err(err),
Err(SignError::SStore(accounts::Error::EthKeyCrypto(err))) => {
warn!("Low level crypto error: {:?}", err);
Err(ethkey::Error::InvalidSecret)
},
Err(SignError::SStore(err)) => {
warn!("Error signing for engine: {:?}", err);
Err(ethkey::Error::InvalidSignature)
},
Ok(ok) => Ok(ok),
}
}
fn address(&self) -> Address {
self.1
}
}
}
impl EngineSigner {
/// Set up the signer to sign with given address and password.
pub fn set(&mut self, ap: Arc<AccountProvider>, address: Address, password: Password) {
self.account_provider = ap;
self.address = Some(address);
self.password = Some(password);
debug!(target: "poa", "Setting Engine signer to {}", address);
}
/// Sign a consensus message hash.
pub fn sign(&self, hash: H256) -> Result<Signature, account_provider::SignError> {
self.account_provider.sign(self.address.unwrap_or_else(Default::default), self.password.clone(), hash)
}
/// Signing address.
pub fn address(&self) -> Option<Address> {
self.address.clone()
}
/// Check if the signing address was set.
pub fn is_some(&self) -> bool {
self.address.is_some()
}
}

View File

@@ -141,10 +141,10 @@ mod tests {
use rlp::encode;
use spec::Spec;
use types::header::Header;
use account_provider::AccountProvider;
use miner::MinerService;
use accounts::AccountProvider;
use miner::{self, MinerService};
use types::ids::BlockId;
use test_helpers::generate_dummy_client_with_spec_and_accounts;
use test_helpers::generate_dummy_client_with_spec;
use call_contract::CallContract;
use client::{BlockChainClient, ChainInfo, BlockInfo};
use super::super::ValidatorSet;
@@ -152,7 +152,7 @@ mod tests {
#[test]
fn fetches_validators() {
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_contract);
let vc = Arc::new(ValidatorContract::new("0000000000000000000000000000000000000005".parse::<Address>().unwrap()));
vc.register_client(Arc::downgrade(&client) as _);
let last_hash = client.best_block_header().hash();
@@ -164,13 +164,14 @@ mod tests {
fn reports_validators() {
let tap = Arc::new(AccountProvider::transient_provider());
let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone()));
let client = generate_dummy_client_with_spec(Spec::new_validator_contract);
client.engine().register_client(Arc::downgrade(&client) as _);
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
// Make sure reporting can be done.
client.miner().set_gas_range_target((1_000_000.into(), 1_000_000.into()));
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
// Check a block that is a bit in future, reject it but don't report the validator.
let mut header = Header::default();

View File

@@ -150,15 +150,15 @@ mod tests {
use std::sync::Arc;
use std::collections::BTreeMap;
use hash::keccak;
use account_provider::AccountProvider;
use accounts::AccountProvider;
use client::{BlockChainClient, ChainInfo, BlockInfo, ImportBlock};
use engines::EpochChange;
use engines::validator_set::ValidatorSet;
use ethkey::Secret;
use types::header::Header;
use miner::MinerService;
use miner::{self, MinerService};
use spec::Spec;
use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data};
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
use types::ids::BlockId;
use ethereum_types::Address;
use verification::queue::kind::blocks::Unverified;
@@ -171,26 +171,29 @@ mod tests {
let s0: Secret = keccak("0").into();
let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap();
let v1 = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_multi, Some(tap));
let client = generate_dummy_client_with_spec(Spec::new_validator_multi);
client.engine().register_client(Arc::downgrade(&client) as _);
// Make sure txs go through.
client.miner().set_gas_range_target((1_000_000.into(), 1_000_000.into()));
// Wrong signer for the first block.
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
client.transact_contract(Default::default(), Default::default()).unwrap();
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 0);
// Right signer for the first block.
client.miner().set_author(v0, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v0, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 1);
// This time v0 is wrong.
client.transact_contract(Default::default(), Default::default()).unwrap();
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 1);
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 2);
// v1 is still good.

View File

@@ -445,19 +445,19 @@ mod tests {
use ethereum_types::Address;
use types::ids::BlockId;
use spec::Spec;
use account_provider::AccountProvider;
use accounts::AccountProvider;
use types::transaction::{Transaction, Action};
use client::{ChainInfo, BlockInfo, ImportBlock};
use ethkey::Secret;
use miner::MinerService;
use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data};
use miner::{self, MinerService};
use test_helpers::{generate_dummy_client_with_spec, generate_dummy_client_with_spec_and_data};
use super::super::ValidatorSet;
use super::{ValidatorSafeContract, EVENT_NAME_HASH};
use verification::queue::kind::blocks::Unverified;
#[test]
fn fetches_validators() {
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
let vc = Arc::new(ValidatorSafeContract::new("0000000000000000000000000000000000000005".parse::<Address>().unwrap()));
vc.register_client(Arc::downgrade(&client) as _);
let last_hash = client.best_block_header().hash();
@@ -472,11 +472,12 @@ mod tests {
let v0 = tap.insert_account(s0.clone(), &"".into()).unwrap();
let v1 = tap.insert_account(keccak("0").into(), &"".into()).unwrap();
let chain_id = Spec::new_validator_safe_contract().chain_id();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
client.engine().register_client(Arc::downgrade(&client) as _);
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(v1, Some("".into())).unwrap();
client.miner().set_author(miner::Author::Sealer(signer));
// Remove "1" validator.
let tx = Transaction {
nonce: 0.into(),
@@ -504,11 +505,13 @@ mod tests {
assert_eq!(client.chain_info().best_block_number, 1);
// Switch to the validator that is still there.
client.miner().set_author(v0, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v0, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
::client::EngineClient::update_sealing(&*client);
assert_eq!(client.chain_info().best_block_number, 2);
// Switch back to the added validator, since the state is updated.
client.miner().set_author(v1, Some("".into())).unwrap();
let signer = Box::new((tap.clone(), v1, "".into()));
client.miner().set_author(miner::Author::Sealer(signer));
let tx = Transaction {
nonce: 2.into(),
gas_price: 0.into(),
@@ -539,7 +542,7 @@ mod tests {
use types::header::Header;
use types::log_entry::LogEntry;
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
let engine = client.engine().clone();
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
@@ -576,7 +579,7 @@ mod tests {
use types::header::Header;
use engines::{EpochChange, Proof};
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let client = generate_dummy_client_with_spec(Spec::new_validator_safe_contract);
let engine = client.engine().clone();
let mut new_header = Header::default();