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 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.

View File

@ -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<H160>),
/// 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.

View File

@ -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");
}
}

View File

@ -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<H160>),
/// 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),
}
}