From d4c9493b00642a89c3c8d09237ce8b92c7a303e6 Mon Sep 17 00:00:00 2001 From: keorn Date: Sun, 11 Dec 2016 17:50:12 +0100 Subject: [PATCH] verification cache retrieval --- ethcore/src/engines/authority_round.rs | 1 + ethcore/src/engines/tendermint/message.rs | 10 ++++++++++ ethcore/src/engines/tendermint/mod.rs | 19 +++++++++++-------- .../src/engines/tendermint/vote_collector.rs | 7 ++++++- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 44627103d..ff300078c 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -348,6 +348,7 @@ mod tests { use tests::helpers::*; use account_provider::AccountProvider; use spec::Spec; + use engines::Seal; #[test] fn has_valid_metadata() { diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index 5b88a66ca..ab6bdb04c 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -59,6 +59,16 @@ impl ConsensusMessage { }) } + pub fn new_commit(proposal: &ConsensusMessage, signature: H520) -> Self { + ConsensusMessage { + signature: signature, + height: proposal.height, + round: proposal.round, + step: Step::Precommit, + block_hash: proposal.block_hash, + } + } + pub fn is_height(&self, height: Height) -> bool { self.height == height } diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 2b779950a..ff5cd69e0 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -166,10 +166,9 @@ impl Tendermint { match ap.sign(*authority, self.password.read().clone(), vote_info.sha3()).map(Into::into) { Ok(signature) => { let message_rlp = message_full_rlp(&signature, &vote_info); - // TODO: memoize the rlp for consecutive broadcasts let message = ConsensusMessage::new(signature, h, r, *s, block_hash); self.votes.vote(message.clone(), *authority); - debug!(target: "poa", "Generated a message for height {:?}.", message); + debug!(target: "poa", "Generated a message: {:?}.", message); self.handle_valid_message(&message); Some(message_rlp) @@ -462,7 +461,7 @@ impl Engine for Tendermint { trace!(target: "poa", "Handling a valid message: {:?}", message); self.handle_valid_message(&message); } else { - trace!(target: "poa", "handle_message: Old or known message ignored {:?}.", message); + trace!(target: "poa", "handle_message: Old or known message ignored: {:?}.", message); } Ok(()) } @@ -496,15 +495,17 @@ impl Engine for Tendermint { } let precommit_hash = proposal.precommit_hash(); - // TODO: use addresses recovered during precommit vote let ref signatures_field = header.seal()[2]; let mut signature_count = 0; let mut origins = HashSet::new(); for rlp in UntrustedRlp::new(signatures_field).iter() { - let signature: H520 = try!(rlp.as_val()); - let address = public_to_address(&try!(recover(&signature.into(), &precommit_hash))); + let precommit: ConsensusMessage = ConsensusMessage::new_commit(&proposal, try!(rlp.as_val())); + let address = match self.votes.get(&precommit) { + Some(a) => a, + None => public_to_address(&try!(recover(&precommit.signature.into(), &precommit_hash))), + }; if !self.our_params.authorities.contains(&address) { - try!(Err(EngineError::NotAuthorized(address))) + try!(Err(EngineError::NotAuthorized(address.to_owned()))) } if origins.insert(address) { @@ -946,9 +947,11 @@ mod tests { // Prevote. vote(&engine, |mh| tap.sign(v1, None, mh).map(H520::from), h, r, Step::Prevote, proposal); - + println!("sending second prevote"); vote(&engine, |mh| tap.sign(v0, None, mh).map(H520::from), h, r, Step::Prevote, proposal); + println!("sending first precommit"); vote(&engine, |mh| tap.sign(v1, None, mh).map(H520::from), h, r, Step::Precommit, proposal); + println!("sending last precommit"); vote(&engine, |mh| tap.sign(v0, None, mh).map(H520::from), h, r, Step::Precommit, proposal); // Wait a bit for async stuff. diff --git a/ethcore/src/engines/tendermint/vote_collector.rs b/ethcore/src/engines/tendermint/vote_collector.rs index 6b717651b..f52fc5738 100644 --- a/ethcore/src/engines/tendermint/vote_collector.rs +++ b/ethcore/src/engines/tendermint/vote_collector.rs @@ -137,6 +137,11 @@ impl VoteCollector { .map(|m| ::rlp::encode(m).to_vec()) .collect() } + + pub fn get(&self, message: &ConsensusMessage) -> Option
{ + let guard = self.votes.read(); + guard.get(message).cloned() + } } #[cfg(test)] @@ -166,7 +171,7 @@ mod tests { } // Wrong height proposal. random_vote(&collector, signatures[4].clone(), h - 1, r, Step::Propose, bh.clone()); - // Good proposal. + // Good proposal random_vote(&collector, signatures[0].clone(), h, r, Step::Propose, bh.clone()); // Wrong block proposal. random_vote(&collector, signatures[0].clone(), h, r, Step::Propose, Some("0".sha3()));