simplify messages

This commit is contained in:
keorn 2016-11-15 10:20:14 +00:00
parent 4e36550890
commit 55a5402bf5
3 changed files with 41 additions and 33 deletions

View File

@ -1172,19 +1172,11 @@ impl BlockChainClient for Client {
// TODO: Make it an actual queue, return errors. // TODO: Make it an actual queue, return errors.
fn queue_infinity_message(&self, message: Bytes) { fn queue_infinity_message(&self, message: Bytes) {
let full_rlp = UntrustedRlp::new(&message); if let Ok(new_message) = self.engine.handle_message(UntrustedRlp::new(&message)) {
if let Ok(signature) = full_rlp.val_at::<H520>(0) {
if let Ok(message) = full_rlp.at(1) {
if let Ok(pub_key) = recover(&signature.into(), &message.as_raw().sha3()) {
if let Ok(new_message) = self.engine.handle_message(pub_key.sha3().into(), signature, message)
{
self.notify(|notify| notify.broadcast(new_message.clone())); self.notify(|notify| notify.broadcast(new_message.clone()));
} }
} }
} }
}
}
}
impl MiningBlockChainClient for Client { impl MiningBlockChainClient for Client {

View File

@ -151,7 +151,7 @@ pub trait Engine : Sync + Send {
/// Handle any potential consensus messages; /// Handle any potential consensus messages;
/// updating consensus state and potentially issuing a new one. /// updating consensus state and potentially issuing a new one.
fn handle_message(&self, _sender: Address, _signature: H520, _message: UntrustedRlp) -> Result<Bytes, Error> { Err(EngineError::UnexpectedMessage.into()) } fn handle_message(&self, _message: UntrustedRlp) -> Result<Bytes, Error> { Err(EngineError::UnexpectedMessage.into()) }
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic // TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
// from Spec into here and removing the Spec::builtins field. // from Spec into here and removing the Spec::builtins field.

View File

@ -16,23 +16,31 @@
//! Tendermint message handling. //! Tendermint message handling.
use std::cmp::Ordering; use util::*;
use super::{Height, Round, BlockHash, Step}; use super::{Height, Round, BlockHash, Step};
use rlp::{View, DecoderError, Decodable, Decoder, Encodable, RlpStream, Stream}; use rlp::{View, DecoderError, Decodable, Decoder, Encodable, RlpStream, Stream};
#[derive(Debug, PartialEq, Eq)]
pub enum Step {
Prevote,
Precommit
}
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct ConsensusMessage { pub struct ConsensusMessage {
signature: H520, pub signature: H520,
height: Height, height: Height,
round: Round, round: Round,
step: Step, pub step: Step,
block_hash: BlockHash block_hash: Option<BlockHash>
}
impl ConsensusMessage {
fn is_round(&self, height: Height, round: Round) -> bool {
self.height == height && self.round == round
}
fn is_step(&self, height: Height, round: Round, step: Step) -> bool {
self.height == height && self.round == round && self.step == step
}
pub fn is_aligned(&self, height: Height, round: Round, block_hash: Option<H256>) -> bool {
self.height == height && self.round == round && self.block_hash == block_hash
}
} }
impl PartialOrd for ConsensusMessage { impl PartialOrd for ConsensusMessage {
@ -41,6 +49,17 @@ impl PartialOrd for ConsensusMessage {
} }
} }
impl Step {
fn number(&self) -> i8 {
match *self {
Step::Propose => -1,
Step::Prevote => 0,
Step::Precommit => 1,
Step::Commit => 2,
}
}
}
impl Ord for ConsensusMessage { impl Ord for ConsensusMessage {
fn cmp(&self, m: &ConsensusMessage) -> Ordering { fn cmp(&self, m: &ConsensusMessage) -> Ordering {
if self.height != m.height { if self.height != m.height {
@ -48,10 +67,7 @@ impl Ord for ConsensusMessage {
} else if self.round != m.round { } else if self.round != m.round {
self.round.cmp(&m.round) self.round.cmp(&m.round)
} else if self.step != m.step { } else if self.step != m.step {
match self.step { self.step.number().cmp(&m.step.number())
Step::Prevote => Ordering::Less,
Step::Precommit => Ordering::Greater,
}
} else { } else {
self.block_hash.cmp(&m.block_hash) self.block_hash.cmp(&m.block_hash)
} }
@ -71,11 +87,7 @@ impl Decodable for Step {
impl Encodable for Step { impl Encodable for Step {
fn rlp_append(&self, s: &mut RlpStream) { fn rlp_append(&self, s: &mut RlpStream) {
match *self { s.append(&(self.number() as u8));
Step::Prevote => s.append(&0u8),
Step::Precommit => s.append(&1u8),
_ => panic!("No encoding needed for other steps"),
};
} }
} }
@ -86,13 +98,17 @@ impl Decodable for ConsensusMessage {
if decoder.as_raw().len() != try!(rlp.payload_info()).total() { if decoder.as_raw().len() != try!(rlp.payload_info()).total() {
return Err(DecoderError::RlpIsTooBig); return Err(DecoderError::RlpIsTooBig);
} }
let m = rlp.at(1); let m = try!(rlp.at(1));
let block_message: H256 = try!(m.val_at(3));
Ok(ConsensusMessage { Ok(ConsensusMessage {
signature: try!(rlp.val_at(0)), signature: try!(rlp.val_at(0)),
height: try!(m.val_at(0)), height: try!(m.val_at(0)),
round: try!(m.val_at(1)), round: try!(m.val_at(1)),
step: try!(m.val_at(2)), step: try!(m.val_at(2)),
block_hash: try!(m.val_at(3)) block_hash: match block_message.is_zero() {
true => None,
false => Some(block_message),
}
}) })
} }
} }
@ -105,6 +121,6 @@ impl Encodable for ConsensusMessage {
s.append(&self.height); s.append(&self.height);
s.append(&self.round); s.append(&self.round);
s.append(&self.step); s.append(&self.step);
s.append(&self.block_hash); s.append(&self.block_hash.unwrap_or(H256::zero()));
} }
} }