use EngineError instead of BlockError

This commit is contained in:
keorn 2016-11-29 12:51:27 +00:00
parent e784fa906e
commit 294e89e5c0
4 changed files with 29 additions and 55 deletions

View File

@ -25,7 +25,7 @@ use rlp::{UntrustedRlp, View, encode};
use account_provider::AccountProvider; use account_provider::AccountProvider;
use block::*; use block::*;
use spec::CommonParams; use spec::CommonParams;
use engines::Engine; use engines::{Engine, EngineError};
use header::Header; use header::Header;
use error::{Error, BlockError}; use error::{Error, BlockError};
use evm::Schedule; use evm::Schedule;
@ -283,7 +283,7 @@ impl Engine for AuthorityRound {
// Check if parent is from a previous step. // Check if parent is from a previous step.
if step == try!(header_step(parent)) { if step == try!(header_step(parent)) {
trace!(target: "poa", "Multiple blocks proposed for step {}.", step); 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. // Check difficulty is correct given the two timestamps.

View File

@ -48,18 +48,28 @@ use views::HeaderView;
/// Voting errors. /// Voting errors.
#[derive(Debug)] #[derive(Debug)]
pub enum EngineError { pub enum EngineError {
/// Voter is not in the voters set. /// Signature does not belong to an authority.
UnauthorisedVoter, NotAuthorized(H160),
/// Message pertaining incorrect consensus step. /// The same author issued different votes at the same step.
WrongStep, DoubleVote(H160),
/// Message pertaining unknown consensus step. /// The received block is from an incorrect proposer.
UnknownStep, NotProposer(Mismatch<H160>),
/// Message was not expected. /// Message was not expected.
UnexpectedMessage, UnexpectedMessage,
/// Received a vote for a different proposal. }
WrongVote,
/// Received message is from a different consensus round. impl fmt::Display for EngineError {
WrongRound 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. /// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based.

View File

@ -220,14 +220,14 @@ impl Tendermint {
} }
/// Round proposer switching. /// 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 ref p = self.our_params;
let proposer_nonce = self.proposer_nonce.load(AtomicOrdering::SeqCst); 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"); 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 { if proposer == address {
Ok(()) Ok(())
} else { } 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) { if self.votes.is_known(&message) {
let sender = public_to_address(&try!(recover(&message.signature.into(), &try!(rlp.at(1)).as_raw().sha3()))); let sender = public_to_address(&try!(recover(&message.signature.into(), &try!(rlp.at(1)).as_raw().sha3())));
if !self.is_authority(&sender) { if !self.is_authority(&sender) {
try!(Err(BlockError::NotAuthorized(sender))); try!(Err(EngineError::NotAuthorized(sender)));
} }
self.votes.vote(message.clone(), sender); self.votes.vote(message.clone(), sender);
@ -434,7 +434,7 @@ impl Engine for Tendermint {
let signature: H520 = try!(rlp.as_val()); let signature: H520 = try!(rlp.as_val());
let address = public_to_address(&try!(recover(&signature.into(), &block_info_hash))); let address = public_to_address(&try!(recover(&signature.into(), &block_info_hash)));
if !self.our_params.authorities.contains(&address) { if !self.our_params.authorities.contains(&address) {
try!(Err(BlockError::NotAuthorized(address))) try!(Err(EngineError::NotAuthorized(address)))
} }
signature_count += 1; signature_count += 1;
@ -494,7 +494,6 @@ mod tests {
use rlp::{UntrustedRlp, View}; use rlp::{UntrustedRlp, View};
use io::{IoContext, IoHandler}; use io::{IoContext, IoHandler};
use block::*; use block::*;
use state_db::StateDB;
use error::{Error, BlockError}; use error::{Error, BlockError};
use header::Header; use header::Header;
use env_info::EnvInfo; use env_info::EnvInfo;
@ -629,7 +628,7 @@ mod tests {
header.set_seal(seal); header.set_seal(seal);
// Bad proposer. // Bad proposer.
match engine.verify_block_unordered(&header, None) { match engine.verify_block_unordered(&header, None) {
Err(Error::Block(BlockError::NotProposer(_))) => {}, Err(Error::Engine(EngineError::NotProposer(_))) => {},
_ => panic!(), _ => panic!(),
} }
} }
@ -663,7 +662,7 @@ mod tests {
// One good and one bad signature. // One good and one bad signature.
match engine.verify_block_unordered(&header, None) { match engine.verify_block_unordered(&header, None) {
Err(Error::Block(BlockError::NotAuthorized(_))) => {}, Err(Error::Engine(EngineError::NotAuthorized(_))) => {},
_ => panic!(), _ => panic!(),
} }
} }
@ -714,29 +713,4 @@ mod tests {
::std::thread::sleep(::std::time::Duration::from_millis(500)); ::std::thread::sleep(::std::time::Duration::from_millis(500));
assert_eq!(test_io.received.read()[5], ClientIoMessage::SubmitSeal(proposal.unwrap(), seal)); 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");
}
} }

View File

@ -168,12 +168,6 @@ pub enum BlockError {
UnknownParent(H256), UnknownParent(H256),
/// Uncle parent given is unknown. /// Uncle parent given is unknown.
UnknownUncleParent(H256), UnknownUncleParent(H256),
/// The same author issued different votes at the same step.
DoubleVote(H160),
/// The received block is from an incorrect proposer.
NotProposer(Mismatch<H160>),
/// Signature does not belong to an authority.
NotAuthorized(H160)
} }
impl fmt::Display for BlockError { impl fmt::Display for BlockError {
@ -207,9 +201,6 @@ impl fmt::Display for BlockError {
RidiculousNumber(ref oob) => format!("Implausible block number. {}", oob), RidiculousNumber(ref oob) => format!("Implausible block number. {}", oob),
UnknownParent(ref hash) => format!("Unknown parent: {}", hash), UnknownParent(ref hash) => format!("Unknown parent: {}", hash),
UnknownUncleParent(ref hash) => format!("Unknown uncle 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)) 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::StdIo(ref err) => err.fmt(f),
Error::Snappy(ref err) => err.fmt(f), Error::Snappy(ref err) => err.fmt(f),
Error::Snapshot(ref err) => err.fmt(f), Error::Snapshot(ref err) => err.fmt(f),
Error::Engine(ref err) => Error::Engine(ref err) => err.fmt(f),
f.write_fmt(format_args!("Bad vote: {:?}", err)),
Error::Ethkey(ref err) => err.fmt(f), Error::Ethkey(ref err) => err.fmt(f),
} }
} }