From 448b8b1c175e0b728e800c1172a80163e92528ce Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 1 Aug 2018 12:23:52 -0600 Subject: [PATCH] Add Hash wrapper and supporting traits --- benches/ledger.rs | 2 +- src/bank.rs | 2 +- src/entry.rs | 6 +++--- src/hash.rs | 26 +++++++++++++++++++++++--- src/ledger.rs | 6 +++--- src/recorder.rs | 2 +- src/tvu.rs | 6 +++--- src/vote_stage.rs | 2 +- 8 files changed, 36 insertions(+), 16 deletions(-) diff --git a/benches/ledger.rs b/benches/ledger.rs index 4d31bc31f3..8172c0319d 100644 --- a/benches/ledger.rs +++ b/benches/ledger.rs @@ -12,7 +12,7 @@ use std::collections::VecDeque; fn bench_block_to_blobs_to_block(bencher: &mut Bencher) { let zero = Hash::default(); - let one = hash(&zero); + let one = hash(&zero.as_ref()); let keypair = KeyPair::new(); let tx0 = Transaction::new(&keypair, keypair.pubkey(), 1, one); let transactions = vec![tx0; 10]; diff --git a/src/bank.rs b/src/bank.rs index b732e82cb4..31be14aa66 100644 --- a/src/bank.rs +++ b/src/bank.rs @@ -268,7 +268,7 @@ impl Bank { let _ = self.apply_signature(tx.from, *tx_sig); } Instruction::NewVote(_vote) => { - info!("GOT VOTE! last_id={:?}", &tx.last_id[..8]); + info!("GOT VOTE! last_id={:?}", &tx.last_id.as_ref()[..8]); // TODO: record the vote in the stake table... } } diff --git a/src/entry.rs b/src/entry.rs index 6192da0e82..4a9393a3b6 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -149,7 +149,7 @@ fn add_transaction_data(hash_data: &mut Vec, tx: &Transaction) { fn next_hash(start_hash: &Hash, num_hashes: u64, transactions: &[Transaction]) -> Hash { let mut id = *start_hash; for _ in 1..num_hashes { - id = hash(&id); + id = hash(&id.as_ref()); } // Hash all the transaction data @@ -161,7 +161,7 @@ fn next_hash(start_hash: &Hash, num_hashes: u64, transactions: &[Transaction]) - if !hash_data.is_empty() { extend_and_hash(&id, &hash_data) } else if num_hashes != 0 { - hash(&id) + hash(&id.as_ref()) } else { id } @@ -191,7 +191,7 @@ mod tests { #[test] fn test_entry_verify() { let zero = Hash::default(); - let one = hash(&zero); + let one = hash(&zero.as_ref()); assert!(Entry::new_tick(0, &zero).verify(&zero)); // base case assert!(!Entry::new_tick(0, &zero).verify(&one)); // base case, bad assert!(next_entry(&zero, 1, vec![]).verify(&zero)); // inductive step diff --git a/src/hash.rs b/src/hash.rs index 832db5130d..bdf21889c9 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -1,11 +1,31 @@ //! The `hash` module provides functions for creating SHA-256 hashes. +use bs58; use generic_array::typenum::U32; use generic_array::GenericArray; use sha2::{Digest, Sha256}; +use std::fmt; -pub type Hash = GenericArray; +#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct Hash(GenericArray); +impl AsRef<[u8]> for Hash { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl fmt::Debug for Hash { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", bs58::encode(self.0).into_string()) + } +} + +impl fmt::Display for Hash { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", bs58::encode(self.0).into_string()) + } +} /// Return a Sha256 hash for the given data. pub fn hash(val: &[u8]) -> Hash { let mut hasher = Sha256::default(); @@ -13,12 +33,12 @@ pub fn hash(val: &[u8]) -> Hash { // At the time of this writing, the sha2 library is stuck on an old version // of generic_array (0.9.0). Decouple ourselves with a clone to our version. - GenericArray::clone_from_slice(hasher.result().as_slice()) + Hash(GenericArray::clone_from_slice(hasher.result().as_slice())) } /// Return the hash of the given hash extended with the given value. pub fn extend_and_hash(id: &Hash, val: &[u8]) -> Hash { - let mut hash_data = id.to_vec(); + let mut hash_data = id.as_ref().to_vec(); hash_data.extend_from_slice(val); hash(&hash_data) } diff --git a/src/ledger.rs b/src/ledger.rs index e3e48fdbb4..9a66f57628 100644 --- a/src/ledger.rs +++ b/src/ledger.rs @@ -324,7 +324,7 @@ mod tests { #[test] fn test_verify_slice() { let zero = Hash::default(); - let one = hash(&zero); + let one = hash(&zero.as_ref()); assert!(vec![][..].verify(&zero)); // base case assert!(vec![Entry::new_tick(0, &zero)][..].verify(&zero)); // singleton case 1 assert!(!vec![Entry::new_tick(0, &zero)][..].verify(&one)); // singleton case 2, bad @@ -337,7 +337,7 @@ mod tests { fn make_test_entries() -> Vec { let zero = Hash::default(); - let one = hash(&zero); + let one = hash(&zero.as_ref()); let keypair = KeyPair::new(); let tx0 = Transaction::new_vote( &keypair, @@ -388,7 +388,7 @@ mod tests { use logger; logger::setup(); let id = Hash::default(); - let next_id = hash(&id); + let next_id = hash(&id.as_ref()); let keypair = KeyPair::new(); let tx_small = Transaction::new_vote( &keypair, diff --git a/src/recorder.rs b/src/recorder.rs index 8e5f465609..85135c4086 100644 --- a/src/recorder.rs +++ b/src/recorder.rs @@ -23,7 +23,7 @@ impl Recorder { } pub fn hash(&mut self) { - self.last_hash = hash(&self.last_hash); + self.last_hash = hash(&self.last_hash.as_ref()); self.num_hashes += 1; } diff --git a/src/tvu.rs b/src/tvu.rs index 1b54e8f648..eb421f432e 100644 --- a/src/tvu.rs +++ b/src/tvu.rs @@ -251,7 +251,7 @@ pub mod tests { for i in 0..num_transfers { let entry0 = Entry::new(&cur_hash, i, vec![], false); bank.register_entry_id(&cur_hash); - cur_hash = hash(&cur_hash); + cur_hash = hash(&cur_hash.as_ref()); let tx0 = Transaction::new( &mint.keypair(), @@ -260,10 +260,10 @@ pub mod tests { cur_hash, ); bank.register_entry_id(&cur_hash); - cur_hash = hash(&cur_hash); + cur_hash = hash(&cur_hash.as_ref()); let entry1 = Entry::new(&cur_hash, i + num_transfers, vec![tx0], false); bank.register_entry_id(&cur_hash); - cur_hash = hash(&cur_hash); + cur_hash = hash(&cur_hash.as_ref()); alice_ref_balance -= transfer_amount; diff --git a/src/vote_stage.rs b/src/vote_stage.rs index 6a4277ef77..b664cf3707 100644 --- a/src/vote_stage.rs +++ b/src/vote_stage.rs @@ -34,7 +34,7 @@ pub fn create_vote_tx_and_blob( let (vote, addr) = { let mut wcrdt = crdt.write().unwrap(); //TODO: doesn't seem like there is a synchronous call to get height and id - info!("voting on {:?}", &last_id[..8]); + info!("voting on {:?}", &last_id.as_ref()[..8]); wcrdt.new_vote(last_id) }?; let tx = Transaction::new_vote(&keypair, vote, last_id, 0);