diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index f7cf5fecc..44bd0a743 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1172,16 +1172,8 @@ impl BlockChainClient for Client { // TODO: Make it an actual queue, return errors. fn queue_infinity_message(&self, message: Bytes) { - let full_rlp = UntrustedRlp::new(&message); - if let Ok(signature) = full_rlp.val_at::(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())); - } - } - } + if let Ok(new_message) = self.engine.handle_message(UntrustedRlp::new(&message)) { + self.notify(|notify| notify.broadcast(new_message.clone())); } } } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index f03e765a9..d7f0796a5 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -151,7 +151,7 @@ pub trait Engine : Sync + Send { /// Handle any potential consensus messages; /// updating consensus state and potentially issuing a new one. - fn handle_message(&self, _sender: Address, _signature: H520, _message: UntrustedRlp) -> Result { Err(EngineError::UnexpectedMessage.into()) } + fn handle_message(&self, _message: UntrustedRlp) -> Result { Err(EngineError::UnexpectedMessage.into()) } // 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. diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index 69f414ec8..4563c683e 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -16,23 +16,31 @@ //! Tendermint message handling. -use std::cmp::Ordering; +use util::*; use super::{Height, Round, BlockHash, Step}; use rlp::{View, DecoderError, Decodable, Decoder, Encodable, RlpStream, Stream}; -#[derive(Debug, PartialEq, Eq)] -pub enum Step { - Prevote, - Precommit -} - #[derive(Debug, PartialEq, Eq)] pub struct ConsensusMessage { - signature: H520, + pub signature: H520, height: Height, round: Round, - step: Step, - block_hash: BlockHash + pub step: Step, + block_hash: Option +} + +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) -> bool { + self.height == height && self.round == round && self.block_hash == block_hash + } } 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 { fn cmp(&self, m: &ConsensusMessage) -> Ordering { if self.height != m.height { @@ -48,10 +67,7 @@ impl Ord for ConsensusMessage { } else if self.round != m.round { self.round.cmp(&m.round) } else if self.step != m.step { - match self.step { - Step::Prevote => Ordering::Less, - Step::Precommit => Ordering::Greater, - } + self.step.number().cmp(&m.step.number()) } else { self.block_hash.cmp(&m.block_hash) } @@ -71,11 +87,7 @@ impl Decodable for Step { impl Encodable for Step { fn rlp_append(&self, s: &mut RlpStream) { - match *self { - Step::Prevote => s.append(&0u8), - Step::Precommit => s.append(&1u8), - _ => panic!("No encoding needed for other steps"), - }; + s.append(&(self.number() as u8)); } } @@ -86,13 +98,17 @@ impl Decodable for ConsensusMessage { if decoder.as_raw().len() != try!(rlp.payload_info()).total() { 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 { signature: try!(rlp.val_at(0)), height: try!(m.val_at(0)), round: try!(m.val_at(1)), 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.round); s.append(&self.step); - s.append(&self.block_hash); + s.append(&self.block_hash.unwrap_or(H256::zero())); } }