diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index e55f1e5f9..9987ffd10 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -25,7 +25,7 @@ use rlp::{UntrustedRlp, View, encode}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; -use engines::Engine; +use engines::{Engine, EngineError}; use header::Header; use error::{Error, BlockError}; use evm::Schedule; @@ -283,7 +283,7 @@ impl Engine for AuthorityRound { // Check if parent is from a previous step. if step == try!(header_step(parent)) { trace!(target: "poa", "Multiple blocks proposed for step {}.", step); - try!(Err(BlockError::DoubleVote(header.author().clone()))); + try!(Err(EngineError::DoubleVote(header.author().clone()))); } // Check difficulty is correct given the two timestamps. diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index ab50ee9c9..91557f8c3 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -48,18 +48,28 @@ use views::HeaderView; /// Voting errors. #[derive(Debug)] pub enum EngineError { - /// Voter is not in the voters set. - UnauthorisedVoter, - /// Message pertaining incorrect consensus step. - WrongStep, - /// Message pertaining unknown consensus step. - UnknownStep, + /// Signature does not belong to an authority. + NotAuthorized(H160), + /// The same author issued different votes at the same step. + DoubleVote(H160), + /// The received block is from an incorrect proposer. + NotProposer(Mismatch), /// Message was not expected. UnexpectedMessage, - /// Received a vote for a different proposal. - WrongVote, - /// Received message is from a different consensus round. - WrongRound +} + +impl fmt::Display for EngineError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::EngineError::*; + let msg = match *self { + DoubleVote(ref address) => format!("Author {} issued too many blocks.", address), + NotProposer(ref mis) => format!("Author is not a current proposer: {}", mis), + NotAuthorized(ref address) => format!("Signer {} is not authorized.", address), + UnexpectedMessage => "This Engine should not be fed messages.".into(), + }; + + f.write_fmt(format_args!("Engine error ({})", msg)) + } } /// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 70e04e929..1168872c1 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -220,14 +220,14 @@ impl Tendermint { } /// Round proposer switching. - fn is_proposer(&self, address: &Address) -> Result<(), BlockError> { + fn is_proposer(&self, address: &Address) -> Result<(), EngineError> { let ref p = self.our_params; let proposer_nonce = self.proposer_nonce.load(AtomicOrdering::SeqCst); let proposer = p.authorities.get(proposer_nonce % p.authority_n).expect("There are authority_n authorities; taking number modulo authority_n gives number in authority_n range; qed"); if proposer == address { Ok(()) } else { - Err(BlockError::NotProposer(Mismatch { expected: proposer.clone(), found: address.clone() })) + Err(EngineError::NotProposer(Mismatch { expected: proposer.clone(), found: address.clone() })) } } @@ -357,7 +357,7 @@ impl Engine for Tendermint { if self.votes.is_known(&message) { let sender = public_to_address(&try!(recover(&message.signature.into(), &try!(rlp.at(1)).as_raw().sha3()))); if !self.is_authority(&sender) { - try!(Err(BlockError::NotAuthorized(sender))); + try!(Err(EngineError::NotAuthorized(sender))); } self.votes.vote(message.clone(), sender); @@ -434,7 +434,7 @@ impl Engine for Tendermint { let signature: H520 = try!(rlp.as_val()); let address = public_to_address(&try!(recover(&signature.into(), &block_info_hash))); if !self.our_params.authorities.contains(&address) { - try!(Err(BlockError::NotAuthorized(address))) + try!(Err(EngineError::NotAuthorized(address))) } signature_count += 1; @@ -494,7 +494,6 @@ mod tests { use rlp::{UntrustedRlp, View}; use io::{IoContext, IoHandler}; use block::*; - use state_db::StateDB; use error::{Error, BlockError}; use header::Header; use env_info::EnvInfo; @@ -629,7 +628,7 @@ mod tests { header.set_seal(seal); // Bad proposer. match engine.verify_block_unordered(&header, None) { - Err(Error::Block(BlockError::NotProposer(_))) => {}, + Err(Error::Engine(EngineError::NotProposer(_))) => {}, _ => panic!(), } } @@ -663,7 +662,7 @@ mod tests { // One good and one bad signature. match engine.verify_block_unordered(&header, None) { - Err(Error::Block(BlockError::NotAuthorized(_))) => {}, + Err(Error::Engine(EngineError::NotAuthorized(_))) => {}, _ => panic!(), } } @@ -714,29 +713,4 @@ mod tests { ::std::thread::sleep(::std::time::Duration::from_millis(500)); assert_eq!(test_io.received.read()[5], ClientIoMessage::SubmitSeal(proposal.unwrap(), seal)); } - - #[test] - #[ignore] - fn precommit_step() { - let (spec, tap) = setup(); - let engine = spec.engine.clone(); - - let not_authority_addr = insert_and_unlock(&tap, "101"); - let proposer_addr = insert_and_unlock(&tap, "0"); - propose_default(&spec, proposer_addr); - - let not_proposer_addr = insert_and_unlock(&tap, "1"); - - } - - #[test] - #[ignore] - fn timeout_switching() { - let tender = { - let engine = Spec::new_test_tendermint().engine; - Tendermint::new(engine.params().clone(), TendermintParams::default(), BTreeMap::new()) - }; - - println!("Waiting for timeout"); - } } diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index cadb4fb1f..5a0fc2167 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -168,12 +168,6 @@ pub enum BlockError { UnknownParent(H256), /// Uncle parent given is unknown. UnknownUncleParent(H256), - /// The same author issued different votes at the same step. - DoubleVote(H160), - /// The received block is from an incorrect proposer. - NotProposer(Mismatch), - /// Signature does not belong to an authority. - NotAuthorized(H160) } impl fmt::Display for BlockError { @@ -207,9 +201,6 @@ impl fmt::Display for BlockError { RidiculousNumber(ref oob) => format!("Implausible block number. {}", oob), UnknownParent(ref hash) => format!("Unknown parent: {}", hash), UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash), - DoubleVote(ref address) => format!("Author {} issued too many blocks.", address), - NotProposer(ref mis) => format!("Author is not a current proposer: {}", mis), - NotAuthorized(ref address) => format!("Signer {} is not authorized.", address), }; f.write_fmt(format_args!("Block error ({})", msg)) @@ -294,8 +285,7 @@ impl fmt::Display for Error { Error::StdIo(ref err) => err.fmt(f), Error::Snappy(ref err) => err.fmt(f), Error::Snapshot(ref err) => err.fmt(f), - Error::Engine(ref err) => - f.write_fmt(format_args!("Bad vote: {:?}", err)), + Error::Engine(ref err) => err.fmt(f), Error::Ethkey(ref err) => err.fmt(f), } }