From e69be670de55187a31e47fb12b8b6f9a1dd15dd0 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 21 Nov 2016 11:36:07 +0000 Subject: [PATCH] message serialization --- ethcore/src/engines/tendermint/message.rs | 30 +++++++++++------------ ethcore/src/engines/tendermint/mod.rs | 15 ++++++------ 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index 4fcbd3e52..26e4716c1 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -30,21 +30,6 @@ pub struct ConsensusMessage { } impl ConsensusMessage { - pub fn new_rlp(signer: F, height: Height, round: Round, step: Step, block_hash: Option) -> Option where F: FnOnce(H256) -> Option { - let mut s = RlpStream::new_list(4); - s.append(&height); - s.append(&round); - s.append(&step); - s.append(&block_hash.unwrap_or(H256::zero())); - let block_info = s.out(); - signer(block_info.sha3()).map(|ref signature| { - let mut s = RlpStream::new_list(2); - s.append(signature); - s.append(&block_info); - s.out() - }) - } - pub fn is_height(&self, height: Height) -> bool { self.height == height } @@ -143,3 +128,18 @@ impl Encodable for ConsensusMessage { s.append(&self.block_hash.unwrap_or(H256::zero())); } } + +pub fn message_info_rlp(height: Height, round: Round, step: Step, block_hash: Option) -> Bytes { + let mut s = RlpStream::new_list(4); + s.append(&height).append(&round).append(&step).append(&block_hash.unwrap_or(H256::zero())); + s.out() +} + +pub fn message_full_rlp(signer: F, height: Height, round: Round, step: Step, block_hash: Option) -> Option where F: FnOnce(H256) -> Option { + let vote_info = message_info_rlp(height, round, step, block_hash); + signer(vote_info.sha3()).map(|ref signature| { + let mut s = RlpStream::new_list(2); + s.append(signature).append(&vote_info); + s.out() + }) +} diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 1974858e5..81b764de7 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -40,7 +40,7 @@ use views::HeaderView; use evm::Schedule; use io::{IoService, IoChannel}; use service::ClientIoMessage; -use self::message::ConsensusMessage; +use self::message::{ConsensusMessage, message_info_rlp, message_full_rlp}; use self::transition::TransitionHandler; use self::params::TendermintParams; use self::vote_collector::VoteCollector; @@ -148,7 +148,7 @@ impl Tendermint { fn generate_message(&self, block_hash: Option) -> Option { if let Some(ref ap) = *self.account_provider.lock() { - ConsensusMessage::new_rlp( + message_full_rlp( |mh| ap.sign(*self.authority.read(), None, mh).ok().map(H520::from), self.height.load(AtomicOrdering::SeqCst), self.round.load(AtomicOrdering::SeqCst), @@ -335,7 +335,8 @@ impl Engine for Tendermint { if let Some(ref ap) = *self.account_provider.lock() { let header = block.header(); let author = header.author(); - if let Ok(signature) = ap.sign(*author, None, block_hash(header)) { + let vote_info = message_info_rlp(header.number() as Height, self.round.load(AtomicOrdering::SeqCst), Step::Propose, Some(block_hash(header))); + if let Ok(signature) = ap.sign(*author, None, vote_info.sha3()) { *self.proposal.write() = Some(header.bare_hash()); Some(vec![ ::rlp::encode(&self.round.load(AtomicOrdering::SeqCst)).to_vec(), @@ -418,10 +419,6 @@ impl Engine for Tendermint { /// Also transitions to Prevote if verifying Proposal. fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { let signature = try!(proposer_signature(header)); - let proposer = public_to_address(&try!(recover(&signature.into(), &block_hash(header)))); - if !self.is_proposer(&proposer) { - try!(Err(BlockError::InvalidSeal)) - } let proposal = ConsensusMessage { signature: signature, height: header.number() as Height, @@ -429,6 +426,10 @@ impl Engine for Tendermint { step: Step::Propose, block_hash: Some(block_hash(header)) }; + let proposer = public_to_address(&try!(recover(&signature.into(), &::rlp::encode(&proposal)))); + if !self.is_proposer(&proposer) { + try!(Err(BlockError::InvalidSeal)) + } self.votes.vote(proposal, proposer); let votes_rlp = UntrustedRlp::new(&header.seal()[2]); for rlp in votes_rlp.iter() {