From 1637f3d324b35f1a22b176483f49f8427cf682bf Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 16 Jan 2017 19:27:32 +0100 Subject: [PATCH 1/3] remove register_account_provider --- ethcore/src/engines/authority_round.rs | 17 ++- ethcore/src/engines/basic_authority.rs | 37 +++--- ethcore/src/engines/mod.rs | 5 +- ethcore/src/engines/tendermint/mod.rs | 117 ++++++++---------- ethcore/src/engines/validator_set/contract.rs | 13 +- ethcore/src/miner/miner.rs | 24 ++-- parity/run.rs | 3 - sync/src/tests/consensus.rs | 28 ++--- sync/src/tests/helpers.rs | 5 +- 9 files changed, 105 insertions(+), 144 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 1a1462507c4..c3f28326524 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -234,7 +234,7 @@ impl Engine for AuthorityRound { let header = block.header(); let step = self.step.load(AtomicOrdering::SeqCst); if self.is_step_proposer(step, header.author()) { - let ref ap = *self.account_provider.lock(); + let ap = self.account_provider.lock(); if let Ok(signature) = ap.sign(*header.author(), self.password.read().clone(), header.bare_hash()) { trace!(target: "poa", "generate_seal: Issuing a block for step {}.", step); self.proposed.store(true, AtomicOrdering::SeqCst); @@ -329,12 +329,10 @@ impl Engine for AuthorityRound { self.validators.register_call_contract(client); } - fn set_signer(&self, _address: Address, password: String) { + fn set_signer(&self, ap: Arc, address: Address, password: String) { + *self.account_provider.lock() = ap; *self.password.write() = Some(password); - } - - fn register_account_provider(&self, account_provider: Arc) { - *self.account_provider.lock() = account_provider; + debug!(target: "poa", "Setting Engine signer to {}", address); } } @@ -401,13 +399,12 @@ mod tests { #[test] fn generates_seal_and_does_not_double_propose() { - let tap = AccountProvider::transient_provider(); + let tap = Arc::new(AccountProvider::transient_provider()); let addr1 = tap.insert_account(Secret::from_slice(&"1".sha3()).unwrap(), "1").unwrap(); let addr2 = tap.insert_account(Secret::from_slice(&"2".sha3()).unwrap(), "2").unwrap(); let spec = Spec::new_test_round(); let engine = &*spec.engine; - engine.register_account_provider(Arc::new(tap)); let genesis_header = spec.genesis_header(); let db1 = spec.ensure_db_good(get_temp_state_db().take(), &Default::default()).unwrap(); let db2 = spec.ensure_db_good(get_temp_state_db().take(), &Default::default()).unwrap(); @@ -417,14 +414,14 @@ 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(); - engine.set_signer(addr1, "1".into()); + engine.set_signer(tap.clone(), addr1, "1".into()); if let Seal::Regular(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()) == Seal::None); } - engine.set_signer(addr2, "2".into()); + engine.set_signer(tap, addr2, "2".into()); if let Seal::Regular(seal) = engine.generate_seal(b2.block()) { assert!(b2.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 1d8d92557e0..fbee7c811fd 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -56,7 +56,7 @@ pub struct BasicAuthority { params: CommonParams, gas_limit_bound_divisor: U256, builtins: BTreeMap, - account_provider: Mutex>>, + account_provider: Mutex>, password: RwLock>, validators: Box, } @@ -69,7 +69,7 @@ impl BasicAuthority { gas_limit_bound_divisor: our_params.gas_limit_bound_divisor, builtins: builtins, validators: new_validator_set(our_params.validators), - account_provider: Mutex::new(None), + account_provider: Mutex::new(Arc::new(AccountProvider::transient_provider())), password: RwLock::new(None), } } @@ -110,20 +110,17 @@ impl Engine for BasicAuthority { /// Attempt to seal the block internally. fn generate_seal(&self, block: &ExecutedBlock) -> Seal { - if let Some(ref ap) = *self.account_provider.lock() { - let header = block.header(); - let author = header.author(); - if self.validators.contains(author) { - let message = header.bare_hash(); - // account should be pernamently unlocked, otherwise sealing will fail - if let Ok(signature) = ap.sign(*author, self.password.read().clone(), message) { - return Seal::Regular(vec![::rlp::encode(&(&*signature as &[u8])).to_vec()]); - } else { - trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable"); - } + let ref ap = *self.account_provider.lock(); + let header = block.header(); + let author = header.author(); + if self.validators.contains(author) { + let message = header.bare_hash(); + // account should be pernamently unlocked, otherwise sealing will fail + if let Ok(signature) = ap.sign(*author, self.password.read().clone(), message) { + return Seal::Regular(vec![::rlp::encode(&(&*signature as &[u8])).to_vec()]); + } else { + trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable"); } - } else { - trace!(target: "basicauthority", "generate_seal: FAIL: accounts not provided"); } Seal::None } @@ -174,12 +171,9 @@ impl Engine for BasicAuthority { self.validators.register_call_contract(client); } - fn set_signer(&self, _address: Address, password: String) { + fn set_signer(&self, ap: Arc, _address: Address, password: String) { *self.password.write() = Some(password); - } - - fn register_account_provider(&self, ap: Arc) { - *self.account_provider.lock() = Some(ap); + *self.account_provider.lock() = ap; } } @@ -256,8 +250,7 @@ mod tests { let spec = new_test_authority(); let engine = &*spec.engine; - engine.set_signer(addr, "".into()); - engine.register_account_provider(Arc::new(tap)); + engine.set_signer(Arc::new(tap), addr, "".into()); let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let db = spec.ensure_db_good(db_result.take(), &Default::default()).unwrap(); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 85a45c3a3ac..86f51bf2b91 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -212,14 +212,11 @@ pub trait Engine : Sync + Send { fn is_proposal(&self, _verified_header: &Header) -> bool { false } /// Register an account which signs consensus messages. - fn set_signer(&self, _address: Address, _password: String) {} + fn set_signer(&self, _account_provider: Arc, _address: Address, _password: String) {} /// Add Client which can be used for sealing, querying the state and sending messages. fn register_client(&self, _client: Weak) {} - /// Add an account provider useful for Engines that sign stuff. - fn register_account_provider(&self, _account_provider: Arc) {} - /// Trigger next step of the consensus engine. fn step(&self) {} diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 9f44a9bcff1..aba86f0c72f 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -94,7 +94,7 @@ pub struct Tendermint { /// Vote accumulator. votes: VoteCollector, /// Used to sign messages and proposals. - account_provider: Mutex>>, + account_provider: Mutex>, /// Message for the last PoLC. lock_change: RwLock>, /// Last lock round. @@ -122,7 +122,7 @@ impl Tendermint { round: AtomicUsize::new(0), step: RwLock::new(Step::Propose), votes: VoteCollector::new(), - account_provider: Mutex::new(None), + account_provider: Mutex::new(Arc::new(AccountProvider::transient_provider())), lock_change: RwLock::new(None), last_lock: AtomicUsize::new(0), proposal: RwLock::new(None), @@ -158,30 +158,26 @@ impl Tendermint { } fn generate_message(&self, block_hash: Option) -> Option { - if let Some(ref ap) = *self.account_provider.lock() { - let h = self.height.load(AtomicOrdering::SeqCst); - let r = self.round.load(AtomicOrdering::SeqCst); - let s = self.step.read(); - let vote_info = message_info_rlp(&VoteStep::new(h, r, *s), block_hash); - let authority = self.authority.read(); - match ap.sign(*authority, self.password.read().clone(), vote_info.sha3()).map(Into::into) { - Ok(signature) => { - let message_rlp = message_full_rlp(&signature, &vote_info); - let message = ConsensusMessage::new(signature, h, r, *s, block_hash); - self.votes.vote(message.clone(), &*authority); - debug!(target: "poa", "Generated {:?} as {}.", message, *authority); - self.handle_valid_message(&message); - - Some(message_rlp) - }, - Err(e) => { - trace!(target: "poa", "Could not sign the message {}", e); - None - }, - } - } else { - warn!(target: "poa", "No AccountProvider available."); - None + let ref ap = *self.account_provider.lock(); + let h = self.height.load(AtomicOrdering::SeqCst); + let r = self.round.load(AtomicOrdering::SeqCst); + let s = self.step.read(); + let vote_info = message_info_rlp(&VoteStep::new(h, r, *s), block_hash); + let authority = self.authority.read(); + match ap.sign(*authority, self.password.read().clone(), vote_info.sha3()).map(Into::into) { + Ok(signature) => { + let message_rlp = message_full_rlp(&signature, &vote_info); + let message = ConsensusMessage::new(signature, h, r, *s, block_hash); + self.votes.vote(message.clone(), &*authority); + debug!(target: "poa", "Generated {:?} as {}.", message, *authority); + self.handle_valid_message(&message); + + Some(message_rlp) + }, + Err(e) => { + trace!(target: "poa", "Could not sign the message {}", e); + None + }, } } @@ -420,35 +416,31 @@ impl Engine for Tendermint { /// Attempt to seal generate a proposal seal. fn generate_seal(&self, block: &ExecutedBlock) -> Seal { - if let Some(ref ap) = *self.account_provider.lock() { - let header = block.header(); - let author = header.author(); - // Only proposer can generate seal if None was generated. - if self.is_proposer(author).is_err() || self.proposal.read().is_some() { - return Seal::None; - } + let ref ap = *self.account_provider.lock(); + let header = block.header(); + let author = header.author(); + // Only proposer can generate seal if None was generated. + if self.is_proposer(author).is_err() || self.proposal.read().is_some() { + return Seal::None; + } - let height = header.number() as Height; - let round = self.round.load(AtomicOrdering::SeqCst); - let bh = Some(header.bare_hash()); - let vote_info = message_info_rlp(&VoteStep::new(height, round, Step::Propose), bh.clone()); - if let Ok(signature) = ap.sign(*author, self.password.read().clone(), vote_info.sha3()).map(H520::from) { - // Insert Propose vote. - debug!(target: "poa", "Submitting proposal {} at height {} round {}.", header.bare_hash(), height, round); - self.votes.vote(ConsensusMessage::new(signature, height, round, Step::Propose, bh), author); - // Remember proposal for later seal submission. - *self.proposal.write() = bh; - Seal::Proposal(vec![ - ::rlp::encode(&round).to_vec(), - ::rlp::encode(&signature).to_vec(), - ::rlp::EMPTY_LIST_RLP.to_vec() - ]) - } else { - warn!(target: "poa", "generate_seal: FAIL: accounts secret key unavailable"); - Seal::None - } + let height = header.number() as Height; + let round = self.round.load(AtomicOrdering::SeqCst); + let bh = Some(header.bare_hash()); + let vote_info = message_info_rlp(&VoteStep::new(height, round, Step::Propose), bh.clone()); + if let Ok(signature) = ap.sign(*author, self.password.read().clone(), vote_info.sha3()).map(H520::from) { + // Insert Propose vote. + debug!(target: "poa", "Submitting proposal {} at height {} round {}.", header.bare_hash(), height, round); + self.votes.vote(ConsensusMessage::new(signature, height, round, Step::Propose, bh), author); + // Remember proposal for later seal submission. + *self.proposal.write() = bh; + Seal::Proposal(vec![ + ::rlp::encode(&round).to_vec(), + ::rlp::encode(&signature).to_vec(), + ::rlp::EMPTY_LIST_RLP.to_vec() + ]) } else { - warn!(target: "poa", "generate_seal: FAIL: accounts not provided"); + warn!(target: "poa", "generate_seal: FAIL: accounts secret key unavailable"); Seal::None } } @@ -563,9 +555,12 @@ impl Engine for Tendermint { Ok(()) } - fn set_signer(&self, address: Address, password: String) { - *self.authority.write() = address; - *self.password.write() = Some(password); + fn set_signer(&self, ap: Arc, address: Address, password: String) { + { + *self.authority.write() = address; + *self.password.write() = Some(password); + *self.account_provider.lock() = ap; + } self.to_step(Step::Propose); } @@ -651,10 +646,6 @@ impl Engine for Tendermint { *self.client.write() = Some(client.clone()); self.validators.register_call_contract(client); } - - fn register_account_provider(&self, account_provider: Arc) { - *self.account_provider.lock() = Some(account_provider); - } } #[cfg(test)] @@ -678,7 +669,6 @@ mod tests { fn setup() -> (Spec, Arc) { let tap = Arc::new(AccountProvider::transient_provider()); let spec = Spec::new_test_tendermint(); - spec.engine.register_account_provider(tap.clone()); (spec, tap) } @@ -722,7 +712,7 @@ mod tests { fn insert_and_register(tap: &Arc, engine: &Engine, acc: &str) -> Address { let addr = insert_and_unlock(tap, acc); - engine.set_signer(addr.clone(), acc.into()); + engine.set_signer(tap.clone(), addr.clone(), acc.into()); addr } @@ -924,7 +914,6 @@ mod tests { let v1 = insert_and_unlock(&tap, "1"); let notify = Arc::new(TestNotify::default()); - engine.register_account_provider(tap.clone()); client.add_notify(notify.clone()); engine.register_client(Arc::downgrade(&client)); @@ -939,7 +928,7 @@ mod tests { }.sign(keypair.secret(), None); client.miner().import_own_transaction(client.as_ref(), transaction.into()).unwrap(); - client.miner().set_engine_signer(v1.clone(), "1".into()).unwrap(); + client.engine().set_signer(tap.clone(), v1.clone(), "1".into()); // Propose let proposal = Some(client.miner().pending_block().unwrap().header.bare_hash()); diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 7efe668e62f..503178dd4e3 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -162,16 +162,11 @@ mod tests { let s0 = Secret::from_slice(&"1".sha3()).unwrap(); let v0 = tap.insert_account(s0.clone(), "").unwrap(); let v1 = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "").unwrap(); - let spec_factory = || { - let spec = Spec::new_validator_contract(); - spec.engine.register_account_provider(tap.clone()); - spec - }; - let client = generate_dummy_client_with_spec_and_data(spec_factory, 0, 0, &[]); + let client = generate_dummy_client_with_spec_and_data(Spec::new_validator_contract, 0, 0, &[]); client.engine().register_client(Arc::downgrade(&client)); let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); - client.miner().set_engine_signer(v1, "".into()).unwrap(); + client.engine().set_signer(tap.clone(), v1, "".into()); // Remove "1" validator. let tx = Transaction { nonce: 0.into(), @@ -199,11 +194,11 @@ mod tests { assert_eq!(client.chain_info().best_block_number, 1); // Switch to the validator that is still there. - client.miner().set_engine_signer(v0, "".into()).unwrap(); + client.engine().set_signer(tap.clone(), v0, "".into()); client.update_sealing(); assert_eq!(client.chain_info().best_block_number, 2); // Switch back to the added validator, since the state is updated. - client.miner().set_engine_signer(v1, "".into()).unwrap(); + client.engine().set_signer(tap.clone(), v1, "".into()); let tx = Transaction { nonce: 2.into(), gas_price: 0.into(), diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 2235e278f9c..180f0c2add6 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -760,19 +760,19 @@ impl MinerService for Miner { if self.seals_internally { if let Some(ref ap) = self.accounts { ap.sign(address.clone(), Some(password.clone()), Default::default())?; + // Limit the scope of the locks. + { + let mut sealing_work = self.sealing_work.lock(); + sealing_work.enabled = self.engine.is_sealer(&address).unwrap_or(false); + *self.author.write() = address; + } + // -------------------------------------------------------------------------- + // | NOTE Code below may require author and sealing_work locks | + // | (some `Engine`s call `EngineClient.update_sealing()`) |. + // | Make sure to release the locks before calling that method. | + // -------------------------------------------------------------------------- + self.engine.set_signer(ap.clone(), address, password); } - // Limit the scope of the locks. - { - let mut sealing_work = self.sealing_work.lock(); - sealing_work.enabled = self.engine.is_sealer(&address).unwrap_or(false); - *self.author.write() = address; - } - // -------------------------------------------------------------------------- - // | NOTE Code below may require author and sealing_work locks | - // | (some `Engine`s call `EngineClient.update_sealing()`) |. - // | Make sure to release the locks before calling that method. | - // -------------------------------------------------------------------------- - self.engine.set_signer(address, password); } Ok(()) } diff --git a/parity/run.rs b/parity/run.rs index 55a8bb8e642..3fc2a731710 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -232,9 +232,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R // prepare account provider let account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?); - // 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/sync/src/tests/consensus.rs b/sync/src/tests/consensus.rs index 82b990f4602..095a884bcc3 100644 --- a/sync/src/tests/consensus.rs +++ b/sync/src/tests/consensus.rs @@ -57,15 +57,11 @@ fn new_tx(secret: &Secret, nonce: U256) -> PendingTransaction { fn authority_round() { let s0 = KeyPair::from_secret_slice(&"1".sha3()).unwrap(); let s1 = KeyPair::from_secret_slice(&"0".sha3()).unwrap(); - let spec_factory = || { - let spec = Spec::new_test_round(); - let account_provider = AccountProvider::transient_provider(); - account_provider.insert_account(s0.secret().clone(), "").unwrap(); - account_provider.insert_account(s1.secret().clone(), "").unwrap(); - spec.engine.register_account_provider(Arc::new(account_provider)); - spec - }; - let mut net = TestNet::with_spec(2, SyncConfig::default(), spec_factory); + let ap = Arc::new(AccountProvider::transient_provider()); + ap.insert_account(s0.secret().clone(), "").unwrap(); + ap.insert_account(s1.secret().clone(), "").unwrap(); + + let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_round, Some(ap)); let mut net = &mut *net; let io_handler0: Arc> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() }); let io_handler1: Arc> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() }); @@ -120,15 +116,11 @@ fn authority_round() { fn tendermint() { let s0 = KeyPair::from_secret_slice(&"1".sha3()).unwrap(); let s1 = KeyPair::from_secret_slice(&"0".sha3()).unwrap(); - let spec_factory = || { - let spec = Spec::new_test_tendermint(); - let account_provider = AccountProvider::transient_provider(); - account_provider.insert_account(s0.secret().clone(), "").unwrap(); - account_provider.insert_account(s1.secret().clone(), "").unwrap(); - spec.engine.register_account_provider(Arc::new(account_provider)); - spec - }; - let mut net = TestNet::with_spec(2, SyncConfig::default(), spec_factory); + let ap = Arc::new(AccountProvider::transient_provider()); + ap.insert_account(s0.secret().clone(), "").unwrap(); + ap.insert_account(s1.secret().clone(), "").unwrap(); + + let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_tendermint, Some(ap)); let mut net = &mut *net; let io_handler0: Arc> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() }); let io_handler1: Arc> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() }); diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index b18b0cf6187..d741b61794f 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -21,6 +21,7 @@ use ethcore::client::{TestBlockChainClient, BlockChainClient, Client as EthcoreC use ethcore::header::BlockNumber; use ethcore::snapshot::SnapshotService; use ethcore::spec::Spec; +use ethcore::account_provider::AccountProvider; use ethcore::miner::Miner; use ethcore::db::NUM_COLUMNS; use sync_io::SyncIo; @@ -262,7 +263,7 @@ impl TestNet> { } impl TestNet> { - pub fn with_spec(n: usize, config: SyncConfig, spec_factory: F) -> GuardedTempResult + pub fn with_spec_and_accounts(n: usize, config: SyncConfig, spec_factory: F, accounts: Option>) -> GuardedTempResult where F: Fn() -> Spec { let mut net = TestNet { @@ -282,7 +283,7 @@ impl TestNet> { ClientConfig::default(), &spec, client_dir.as_path(), - Arc::new(Miner::with_spec(&spec)), + Arc::new(Miner::with_spec_and_accounts(&spec, accounts.clone())), IoChannel::disconnected(), &db_config ).unwrap(); From 77b8093e015b7aa97227e492d2bd9a19f0e14213 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 16 Jan 2017 20:43:29 +0100 Subject: [PATCH 2/3] build rpc module --- rpc/src/v1/tests/eth.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 154c700f916..e326e15705b 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -116,7 +116,6 @@ 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(); From a36d29942f7f9fc8f82bdc6e0c15c14feca2d3a4 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 16 Jan 2017 23:01:01 +0100 Subject: [PATCH 3/3] new dummy client --- ethcore/src/engines/tendermint/mod.rs | 11 +++++------ ethcore/src/engines/validator_set/contract.rs | 12 ++++++------ ethcore/src/tests/helpers.rs | 12 +++++++++++- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index aba86f0c72f..661044ddb87 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -874,7 +874,7 @@ mod tests { let v0 = insert_and_register(&tap, engine.as_ref(), "0"); let v1 = insert_and_register(&tap, engine.as_ref(), "1"); - let h = 0; + let h = 1; let r = 0; // Propose @@ -905,13 +905,14 @@ mod tests { use types::transaction::{Transaction, Action}; use client::BlockChainClient; - let client = generate_dummy_client_with_spec_and_data(Spec::new_test_tendermint, 0, 0, &[]); - let engine = client.engine(); let tap = Arc::new(AccountProvider::transient_provider()); - // Accounts for signing votes. let v0 = insert_and_unlock(&tap, "0"); let v1 = insert_and_unlock(&tap, "1"); + let client = generate_dummy_client_with_spec_and_accounts(Spec::new_test_tendermint, Some(tap.clone())); + let engine = client.engine(); + + client.miner().set_engine_signer(v1.clone(), "1".into()).unwrap(); let notify = Arc::new(TestNotify::default()); client.add_notify(notify.clone()); @@ -928,8 +929,6 @@ mod tests { }.sign(keypair.secret(), None); client.miner().import_own_transaction(client.as_ref(), transaction.into()).unwrap(); - client.engine().set_signer(tap.clone(), v1.clone(), "1".into()); - // Propose let proposal = Some(client.miner().pending_block().unwrap().header.bare_hash()); // Propose timeout diff --git a/ethcore/src/engines/validator_set/contract.rs b/ethcore/src/engines/validator_set/contract.rs index 503178dd4e3..fa7dbea41da 100644 --- a/ethcore/src/engines/validator_set/contract.rs +++ b/ethcore/src/engines/validator_set/contract.rs @@ -142,13 +142,13 @@ mod tests { use client::{BlockChainClient, EngineClient}; use ethkey::Secret; use miner::MinerService; - use tests::helpers::generate_dummy_client_with_spec_and_data; + use tests::helpers::generate_dummy_client_with_spec_and_accounts; use super::super::ValidatorSet; use super::ValidatorContract; #[test] fn fetches_validators() { - let client = generate_dummy_client_with_spec_and_data(Spec::new_validator_contract, 0, 0, &[]); + let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, None); let vc = Arc::new(ValidatorContract::new(Address::from_str("0000000000000000000000000000000000000005").unwrap())); vc.register_call_contract(Arc::downgrade(&client)); vc.update(); @@ -162,11 +162,11 @@ mod tests { let s0 = Secret::from_slice(&"1".sha3()).unwrap(); let v0 = tap.insert_account(s0.clone(), "").unwrap(); let v1 = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "").unwrap(); - let client = generate_dummy_client_with_spec_and_data(Spec::new_validator_contract, 0, 0, &[]); + let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap)); client.engine().register_client(Arc::downgrade(&client)); let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap(); - client.engine().set_signer(tap.clone(), v1, "".into()); + client.miner().set_engine_signer(v1, "".into()).unwrap(); // Remove "1" validator. let tx = Transaction { nonce: 0.into(), @@ -194,11 +194,11 @@ mod tests { assert_eq!(client.chain_info().best_block_number, 1); // Switch to the validator that is still there. - client.engine().set_signer(tap.clone(), v0, "".into()); + client.miner().set_engine_signer(v0, "".into()).unwrap(); client.update_sealing(); assert_eq!(client.chain_info().best_block_number, 2); // Switch back to the added validator, since the state is updated. - client.engine().set_signer(tap.clone(), v1, "".into()); + client.miner().set_engine_signer(v1, "".into()).unwrap(); let tx = Transaction { nonce: 2.into(), gas_price: 0.into(), diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 0af84a52887..80419d8060e 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -19,6 +19,7 @@ use io::*; use client::{BlockChainClient, Client, ClientConfig}; use util::*; use spec::*; +use account_provider::AccountProvider; use state_db::StateDB; use block::{OpenBlock, Drain}; use blockchain::{BlockChain, Config as BlockChainConfig}; @@ -140,7 +141,16 @@ pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, generate_dummy_client_with_spec_and_data(Spec::new_null, block_number, txs_per_block, tx_gas_prices) } + pub fn generate_dummy_client_with_spec_and_data(get_test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult> where F: Fn()->Spec { + generate_dummy_client_with_spec_accounts_and_data(get_test_spec, None, block_number, txs_per_block, tx_gas_prices) +} + +pub fn generate_dummy_client_with_spec_and_accounts(get_test_spec: F, accounts: Option>) -> GuardedTempResult> where F: Fn()->Spec { + generate_dummy_client_with_spec_accounts_and_data(get_test_spec, accounts, 0, 0, &[]) +} + +pub fn generate_dummy_client_with_spec_accounts_and_data(get_test_spec: F, accounts: Option>, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult> where F: Fn()->Spec { let dir = RandomTempPath::new(); let test_spec = get_test_spec(); let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); @@ -149,7 +159,7 @@ pub fn generate_dummy_client_with_spec_and_data(get_test_spec: F, block_numbe ClientConfig::default(), &test_spec, dir.as_path(), - Arc::new(Miner::with_spec(&test_spec)), + Arc::new(Miner::with_spec_and_accounts(&test_spec, accounts)), IoChannel::disconnected(), &db_config ).unwrap();