update Signature and ipc usage

This commit is contained in:
keorn
2016-08-26 13:16:56 +02:00
parent e7a9bf4df8
commit a4ba7262ad
7 changed files with 32 additions and 41 deletions

View File

@@ -17,8 +17,9 @@
//! Voting on a hash, where each vote has to come from a set of addresses.
use std::sync::atomic::{AtomicBool, Ordering};
use common::{HashSet, RwLock, H256, Signature, Address, Error, ec, Hashable};
use common::{HashSet, RwLock, H256, Address, Error, Hashable};
use super::EngineError;
use ethkey::{recover, Signature};
/// Collect votes on a hash.
#[derive(Debug)]
@@ -57,7 +58,7 @@ impl ProposeCollect {
}
fn can_vote(&self, signature: &Signature) -> Result<(), Error> {
let signer = Address::from(try!(ec::recover(&signature, &self.hash)).sha3());
let signer = Address::from(try!(recover(&signature, &self.hash)).sha3());
match self.voters.contains(&signer) {
false => try!(Err(EngineError::UnauthorisedVoter)),
true => Ok(()),
@@ -108,18 +109,18 @@ mod tests {
// Unapproved voter.
let signature = tap.sign(addr3, bare_hash).unwrap();
assert!(!vote.vote(&signature.into()));
assert!(!vote.vote(&signature));
assert!(vote.winner().is_none());
// First good vote.
let signature = tap.sign(addr1, bare_hash).unwrap();
assert!(vote.vote(&signature.into()));
assert!(vote.vote(&signature));
assert_eq!(vote.winner().unwrap(), bare_hash);
// Voting again is ineffective.
let signature = tap.sign(addr1, bare_hash).unwrap();
assert!(!vote.vote(&signature.into()));
assert!(!vote.vote(&signature));
// Second valid vote.
let signature = tap.sign(addr2, bare_hash).unwrap();
assert!(vote.vote(&signature.into()));
assert!(vote.vote(&signature));
assert_eq!(vote.winner().unwrap(), bare_hash);
}
}

View File

@@ -17,7 +17,8 @@
//! Voting on hashes, where each vote has to come from a set of public keys.
use super::EngineError;
use common::{HashSet, HashMap, RwLock, H256, Signature, Address, Error, ec, Hashable};
use common::{HashSet, HashMap, RwLock, H256, Address, Error, Hashable};
use ethkey::{Signature, recover};
/// Signed voting on hashes.
#[derive(Debug)]
@@ -49,11 +50,11 @@ impl SignedVote {
}
/// Vote on hash using the signed hash, true if vote counted.
pub fn vote(&self, bare_hash: H256, signature: &Signature) -> bool {
if !self.can_vote(&bare_hash, signature).is_ok() { return false; }
pub fn vote(&self, bare_hash: H256, signature: Signature) -> bool {
if !self.can_vote(&bare_hash, &signature).is_ok() { return false; }
let mut guard = self.votes.try_write().unwrap();
let set = guard.entry(bare_hash.clone()).or_insert_with(|| HashSet::new());
if !set.insert(signature.clone()) { return false; }
if !set.insert(signature) { return false; }
// Set the winner if threshold is reached.
if set.len() >= self.threshold {
let mut guard = self.winner.try_write().unwrap();
@@ -63,7 +64,7 @@ impl SignedVote {
}
fn can_vote(&self, bare_hash: &H256, signature: &Signature) -> Result<(), Error> {
let signer = Address::from(try!(ec::recover(&signature, bare_hash)).sha3());
let signer = Address::from(try!(recover(&signature, bare_hash)).sha3());
match self.voters.contains(&signer) {
false => try!(Err(EngineError::UnauthorisedVoter)),
true => Ok(()),

View File

@@ -106,7 +106,10 @@ impl Tendermint {
}
fn prevote_message(&self, sender: Address, message: UntrustedRlp) -> Result<Bytes, Error> {
try!(Err(EngineError::WrongStep))
match *self.our_params.s.try_write().unwrap() {
Step::Prevote(ref mut vote) => try!(Err(EngineError::WrongStep)),
_ => try!(Err(EngineError::WrongStep)),
}
}
fn threshold(&self) -> usize {
@@ -167,7 +170,7 @@ impl Engine for Tendermint {
fn handle_message(&self, sender: Address, message: UntrustedRlp) -> Result<Bytes, Error> {
match try!(message.val_at(0)) {
0u8 if sender == self.proposer() => self.propose_message(try!(message.at(1))),
1 => self.prevote_message(sender, try!(message.at(1))),
1 if self.our_params.validators.contains(&sender) => self.prevote_message(sender, try!(message.at(1))),
_ => try!(Err(EngineError::UnknownStep)),
}
}
@@ -225,6 +228,7 @@ mod tests {
use account_provider::AccountProvider;
use spec::Spec;
use super::Step;
use ethkey::Signature;
/// Create a new test chain spec with `Tendermint` consensus engine.
/// Account "0".sha3() and "1".sha3() are a validators.
@@ -267,21 +271,6 @@ mod tests {
}
}
#[test]
fn can_do_signature_verification_fail() {
let engine = new_test_tendermint().engine;
let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&Signature::zero()).to_vec()]);
let verify_result = engine.verify_block_unordered(&header, None);
match verify_result {
Err(Error::Util(UtilError::Crypto(CryptoError::InvalidSignature))) => {},
Err(_) => { panic!("should be block difficulty error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); },
}
}
#[test]
fn can_generate_seal() {
let tap = AccountProvider::transient_provider();