From 5a44c36b1f704dc9701ebf37d5dd49c097b2eb9d Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Tue, 6 Mar 2018 17:20:37 -0700 Subject: [PATCH 1/3] Move hash into its own module --- src/accountant.rs | 3 ++- src/accountant_skel.rs | 3 ++- src/accountant_stub.rs | 3 ++- src/bin/demo.rs | 3 ++- src/genesis.rs | 3 ++- src/hash.rs | 19 +++++++++++++++++++ src/historian.rs | 3 ++- src/lib.rs | 1 + src/log.rs | 20 +------------------- src/logger.rs | 3 ++- src/transaction.rs | 4 ++-- 11 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 src/hash.rs diff --git a/src/accountant.rs b/src/accountant.rs index 3af3949652..61838382cf 100644 --- a/src/accountant.rs +++ b/src/accountant.rs @@ -2,7 +2,8 @@ //! event log to record transactions. Its users can deposit funds and //! transfer funds to other users. -use log::{Entry, Sha256Hash}; +use hash::Sha256Hash; +use log::Entry; use event::Event; use transaction::Transaction; use signature::{PublicKey, Signature}; diff --git a/src/accountant_skel.rs b/src/accountant_skel.rs index 4c6c12a981..9296b6a171 100644 --- a/src/accountant_skel.rs +++ b/src/accountant_skel.rs @@ -2,7 +2,8 @@ use std::io; use accountant::Accountant; use transaction::Transaction; use signature::PublicKey; -use log::{Entry, Sha256Hash}; +use hash::Sha256Hash; +use log::Entry; use std::net::UdpSocket; use bincode::{deserialize, serialize}; diff --git a/src/accountant_stub.rs b/src/accountant_stub.rs index ea713a9b5f..1bded971ec 100644 --- a/src/accountant_stub.rs +++ b/src/accountant_stub.rs @@ -7,7 +7,8 @@ use std::io; use bincode::{deserialize, serialize}; use transaction::Transaction; use signature::{PublicKey, Signature}; -use log::{Entry, Sha256Hash}; +use hash::Sha256Hash; +use log::Entry; use ring::signature::Ed25519KeyPair; use accountant_skel::{Request, Response}; diff --git a/src/bin/demo.rs b/src/bin/demo.rs index bdbad0ba23..76c27dc306 100644 --- a/src/bin/demo.rs +++ b/src/bin/demo.rs @@ -1,7 +1,8 @@ extern crate silk; use silk::historian::Historian; -use silk::log::{verify_slice, Entry, Sha256Hash}; +use silk::hash::Sha256Hash; +use silk::log::{verify_slice, Entry}; use silk::signature::{generate_keypair, get_pubkey}; use silk::transaction::Transaction; use silk::event::Event; diff --git a/src/genesis.rs b/src/genesis.rs index 01bcd1416d..6ef4151ad2 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -3,7 +3,8 @@ use event::Event; use transaction::Transaction; use signature::{generate_keypair, get_pubkey, PublicKey}; -use log::{create_entries, hash, Entry, Sha256Hash}; +use log::{create_entries, Entry}; +use hash::{hash, Sha256Hash}; use ring::rand::SystemRandom; use ring::signature::Ed25519KeyPair; use untrusted::Input; diff --git a/src/hash.rs b/src/hash.rs new file mode 100644 index 0000000000..5efb933f5f --- /dev/null +++ b/src/hash.rs @@ -0,0 +1,19 @@ +use generic_array::GenericArray; +use generic_array::typenum::U32; +use sha2::{Digest, Sha256}; + +pub type Sha256Hash = GenericArray; + +/// Return a Sha256 hash for the given data. +pub fn hash(val: &[u8]) -> Sha256Hash { + let mut hasher = Sha256::default(); + hasher.input(val); + hasher.result() +} + +/// Return the hash of the given hash extended with the given value. +pub fn extend_and_hash(id: &Sha256Hash, val: &[u8]) -> Sha256Hash { + let mut hash_data = id.to_vec(); + hash_data.extend_from_slice(val); + hash(&hash_data) +} diff --git a/src/historian.rs b/src/historian.rs index 03605a247c..f0683c8f7b 100644 --- a/src/historian.rs +++ b/src/historian.rs @@ -5,7 +5,8 @@ use std::thread::{spawn, JoinHandle}; use std::collections::HashSet; use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::time::Instant; -use log::{hash, Entry, Sha256Hash}; +use hash::{hash, Sha256Hash}; +use log::Entry; use logger::{ExitReason, Logger}; use signature::Signature; use event::Event; diff --git a/src/lib.rs b/src/lib.rs index 91cbf8b703..4551c6833b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(feature = "unstable", feature(test))] +pub mod hash; pub mod log; pub mod logger; pub mod event; diff --git a/src/log.rs b/src/log.rs index 1da66d778f..6a13f3abef 100644 --- a/src/log.rs +++ b/src/log.rs @@ -13,15 +13,11 @@ /// fastest processor. Duration should therefore be estimated by assuming that the hash /// was generated by the fastest processor at the time the entry was logged. -use generic_array::GenericArray; -use generic_array::typenum::U32; +use hash::{extend_and_hash, hash, Sha256Hash}; use serde::Serialize; use event::Event; -use sha2::{Digest, Sha256}; use rayon::prelude::*; -pub type Sha256Hash = GenericArray; - #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Entry { pub num_hashes: u64, @@ -50,20 +46,6 @@ impl Entry { } } -/// Return a Sha256 hash for the given data. -pub fn hash(val: &[u8]) -> Sha256Hash { - let mut hasher = Sha256::default(); - hasher.input(val); - hasher.result() -} - -/// Return the hash of the given hash extended with the given value. -pub fn extend_and_hash(id: &Sha256Hash, val: &[u8]) -> Sha256Hash { - let mut hash_data = id.to_vec(); - hash_data.extend_from_slice(val); - hash(&hash_data) -} - /// Creates the hash 'num_hashes' after start_hash. If the event contains /// signature, the final hash will be a hash of both the previous ID and /// the signature. diff --git a/src/logger.rs b/src/logger.rs index 8fcf101f6d..8f47bc97c5 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -7,7 +7,8 @@ use std::sync::mpsc::{Receiver, SyncSender, TryRecvError}; use std::time::{Duration, Instant}; -use log::{create_entry_mut, Entry, Sha256Hash}; +use hash::Sha256Hash; +use log::{create_entry_mut, Entry}; use event::Event; use serde::Serialize; use std::fmt::Debug; diff --git a/src/transaction.rs b/src/transaction.rs index f0be7c1d89..1193358668 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -4,7 +4,7 @@ use signature::{get_pubkey, verify_signature, PublicKey, Signature}; use ring::signature::Ed25519KeyPair; use serde::Serialize; use bincode::serialize; -use log::Sha256Hash; +use hash::Sha256Hash; #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Transaction { @@ -51,8 +51,8 @@ impl Transaction { mod tests { use super::*; use bincode::{deserialize, serialize}; - use log::*; use signature::*; + use hash::hash; #[test] fn test_claim() { From 1436bb1ff2f12228ecc69fc1d10197daf3638ce6 Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Tue, 6 Mar 2018 17:31:17 -0700 Subject: [PATCH 2/3] Move entry into its own module Hmm, Logger doesn't depend on log. --- src/accountant.rs | 2 +- src/accountant_skel.rs | 2 +- src/accountant_stub.rs | 2 +- src/bin/demo.rs | 3 +- src/entry.rs | 110 +++++++++++++++++++++++++++++++++++++++++ src/genesis.rs | 3 +- src/historian.rs | 2 +- src/lib.rs | 11 +++-- src/log.rs | 106 ++------------------------------------- src/logger.rs | 2 +- 10 files changed, 128 insertions(+), 115 deletions(-) create mode 100644 src/entry.rs diff --git a/src/accountant.rs b/src/accountant.rs index 61838382cf..0bc97f5a68 100644 --- a/src/accountant.rs +++ b/src/accountant.rs @@ -3,7 +3,7 @@ //! transfer funds to other users. use hash::Sha256Hash; -use log::Entry; +use entry::Entry; use event::Event; use transaction::Transaction; use signature::{PublicKey, Signature}; diff --git a/src/accountant_skel.rs b/src/accountant_skel.rs index 9296b6a171..9cd25dad08 100644 --- a/src/accountant_skel.rs +++ b/src/accountant_skel.rs @@ -3,7 +3,7 @@ use accountant::Accountant; use transaction::Transaction; use signature::PublicKey; use hash::Sha256Hash; -use log::Entry; +use entry::Entry; use std::net::UdpSocket; use bincode::{deserialize, serialize}; diff --git a/src/accountant_stub.rs b/src/accountant_stub.rs index 1bded971ec..61529642ae 100644 --- a/src/accountant_stub.rs +++ b/src/accountant_stub.rs @@ -8,7 +8,7 @@ use bincode::{deserialize, serialize}; use transaction::Transaction; use signature::{PublicKey, Signature}; use hash::Sha256Hash; -use log::Entry; +use entry::Entry; use ring::signature::Ed25519KeyPair; use accountant_skel::{Request, Response}; diff --git a/src/bin/demo.rs b/src/bin/demo.rs index 76c27dc306..75614d56a1 100644 --- a/src/bin/demo.rs +++ b/src/bin/demo.rs @@ -2,7 +2,8 @@ extern crate silk; use silk::historian::Historian; use silk::hash::Sha256Hash; -use silk::log::{verify_slice, Entry}; +use silk::entry::Entry; +use silk::log::verify_slice; use silk::signature::{generate_keypair, get_pubkey}; use silk::transaction::Transaction; use silk::event::Event; diff --git a/src/entry.rs b/src/entry.rs new file mode 100644 index 0000000000..f970bc0cab --- /dev/null +++ b/src/entry.rs @@ -0,0 +1,110 @@ +use hash::{extend_and_hash, hash, Sha256Hash}; +use serde::Serialize; +use event::Event; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +pub struct Entry { + pub num_hashes: u64, + pub id: Sha256Hash, + pub event: Event, +} + +impl Entry { + /// Creates a Entry from the number of hashes 'num_hashes' since the previous event + /// and that resulting 'id'. + pub fn new_tick(num_hashes: u64, id: &Sha256Hash) -> Self { + Entry { + num_hashes, + id: *id, + event: Event::Tick, + } + } + + /// Verifies self.id is the result of hashing a 'start_hash' 'self.num_hashes' times. + /// If the event is not a Tick, then hash that as well. + pub fn verify(&self, start_hash: &Sha256Hash) -> bool { + if !self.event.verify() { + return false; + } + self.id == next_hash(start_hash, self.num_hashes, &self.event) + } +} + +/// Creates the hash 'num_hashes' after start_hash. If the event contains +/// signature, the final hash will be a hash of both the previous ID and +/// the signature. +pub fn next_hash( + start_hash: &Sha256Hash, + num_hashes: u64, + event: &Event, +) -> Sha256Hash { + let mut id = *start_hash; + let sig = event.get_signature(); + let start_index = if sig.is_some() { 1 } else { 0 }; + for _ in start_index..num_hashes { + id = hash(&id); + } + if let Some(sig) = sig { + id = extend_and_hash(&id, &sig); + } + id +} + +/// Creates the next Entry 'num_hashes' after 'start_hash'. +pub fn create_entry( + start_hash: &Sha256Hash, + cur_hashes: u64, + event: Event, +) -> Entry { + let sig = event.get_signature(); + let num_hashes = cur_hashes + if sig.is_some() { 1 } else { 0 }; + let id = next_hash(start_hash, 0, &event); + Entry { + num_hashes, + id, + event, + } +} + +/// Creates the next Tick Entry 'num_hashes' after 'start_hash'. +pub fn create_entry_mut( + start_hash: &mut Sha256Hash, + cur_hashes: &mut u64, + event: Event, +) -> Entry { + let entry = create_entry(start_hash, *cur_hashes, event); + *start_hash = entry.id; + *cur_hashes = 0; + entry +} + +/// Creates the next Tick Entry 'num_hashes' after 'start_hash'. +pub fn next_tick(start_hash: &Sha256Hash, num_hashes: u64) -> Entry { + let event = Event::Tick; + Entry { + num_hashes, + id: next_hash(start_hash, num_hashes, &event), + event, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_event_verify() { + let zero = Sha256Hash::default(); + let one = hash(&zero); + assert!(Entry::::new_tick(0, &zero).verify(&zero)); // base case + assert!(!Entry::::new_tick(0, &zero).verify(&one)); // base case, bad + assert!(next_tick::(&zero, 1).verify(&zero)); // inductive step + assert!(!next_tick::(&zero, 1).verify(&one)); // inductive step, bad + } + + #[test] + fn test_next_tick() { + let zero = Sha256Hash::default(); + assert_eq!(next_tick::(&zero, 1).num_hashes, 1) + } +} diff --git a/src/genesis.rs b/src/genesis.rs index 6ef4151ad2..ef9df97726 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -3,7 +3,8 @@ use event::Event; use transaction::Transaction; use signature::{generate_keypair, get_pubkey, PublicKey}; -use log::{create_entries, Entry}; +use entry::Entry; +use log::create_entries; use hash::{hash, Sha256Hash}; use ring::rand::SystemRandom; use ring::signature::Ed25519KeyPair; diff --git a/src/historian.rs b/src/historian.rs index f0683c8f7b..7bf21d9c31 100644 --- a/src/historian.rs +++ b/src/historian.rs @@ -6,7 +6,7 @@ use std::collections::HashSet; use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::time::Instant; use hash::{hash, Sha256Hash}; -use log::Entry; +use entry::Entry; use logger::{ExitReason, Logger}; use signature::Signature; use event::Event; diff --git a/src/lib.rs b/src/lib.rs index 4551c6833b..e452859c99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,12 @@ #![cfg_attr(feature = "unstable", feature(test))] -pub mod hash; -pub mod log; -pub mod logger; -pub mod event; -pub mod transaction; pub mod signature; +pub mod hash; +pub mod transaction; +pub mod event; +pub mod entry; +pub mod log; pub mod genesis; +pub mod logger; pub mod historian; pub mod accountant; pub mod accountant_skel; diff --git a/src/log.rs b/src/log.rs index 6a13f3abef..6d319c1e14 100644 --- a/src/log.rs +++ b/src/log.rs @@ -13,97 +13,12 @@ /// fastest processor. Duration should therefore be estimated by assuming that the hash /// was generated by the fastest processor at the time the entry was logged. -use hash::{extend_and_hash, hash, Sha256Hash}; +use hash::Sha256Hash; use serde::Serialize; +use entry::{create_entry_mut, next_tick, Entry}; use event::Event; use rayon::prelude::*; -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub struct Entry { - pub num_hashes: u64, - pub id: Sha256Hash, - pub event: Event, -} - -impl Entry { - /// Creates a Entry from the number of hashes 'num_hashes' since the previous event - /// and that resulting 'id'. - pub fn new_tick(num_hashes: u64, id: &Sha256Hash) -> Self { - Entry { - num_hashes, - id: *id, - event: Event::Tick, - } - } - - /// Verifies self.id is the result of hashing a 'start_hash' 'self.num_hashes' times. - /// If the event is not a Tick, then hash that as well. - pub fn verify(&self, start_hash: &Sha256Hash) -> bool { - if !self.event.verify() { - return false; - } - self.id == next_hash(start_hash, self.num_hashes, &self.event) - } -} - -/// Creates the hash 'num_hashes' after start_hash. If the event contains -/// signature, the final hash will be a hash of both the previous ID and -/// the signature. -pub fn next_hash( - start_hash: &Sha256Hash, - num_hashes: u64, - event: &Event, -) -> Sha256Hash { - let mut id = *start_hash; - let sig = event.get_signature(); - let start_index = if sig.is_some() { 1 } else { 0 }; - for _ in start_index..num_hashes { - id = hash(&id); - } - if let Some(sig) = sig { - id = extend_and_hash(&id, &sig); - } - id -} - -/// Creates the next Entry 'num_hashes' after 'start_hash'. -pub fn create_entry( - start_hash: &Sha256Hash, - cur_hashes: u64, - event: Event, -) -> Entry { - let sig = event.get_signature(); - let num_hashes = cur_hashes + if sig.is_some() { 1 } else { 0 }; - let id = next_hash(start_hash, 0, &event); - Entry { - num_hashes, - id, - event, - } -} - -/// Creates the next Tick Entry 'num_hashes' after 'start_hash'. -pub fn create_entry_mut( - start_hash: &mut Sha256Hash, - cur_hashes: &mut u64, - event: Event, -) -> Entry { - let entry = create_entry(start_hash, *cur_hashes, event); - *start_hash = entry.id; - *cur_hashes = 0; - entry -} - -/// Creates the next Tick Entry 'num_hashes' after 'start_hash'. -pub fn next_tick(start_hash: &Sha256Hash, num_hashes: u64) -> Entry { - let event = Event::Tick; - Entry { - num_hashes, - id: next_hash(start_hash, num_hashes, &event), - event, - } -} - /// Verifies the hashes and counts of a slice of events are all consistent. pub fn verify_slice(events: &[Entry], start_hash: &Sha256Hash) -> bool { let genesis = [Entry::new_tick(Default::default(), start_hash)]; @@ -153,22 +68,7 @@ mod tests { use super::*; use signature::{generate_keypair, get_pubkey}; use transaction::Transaction; - - #[test] - fn test_event_verify() { - let zero = Sha256Hash::default(); - let one = hash(&zero); - assert!(Entry::::new_tick(0, &zero).verify(&zero)); // base case - assert!(!Entry::::new_tick(0, &zero).verify(&one)); // base case, bad - assert!(next_tick::(&zero, 1).verify(&zero)); // inductive step - assert!(!next_tick::(&zero, 1).verify(&one)); // inductive step, bad - } - - #[test] - fn test_next_tick() { - let zero = Sha256Hash::default(); - assert_eq!(next_tick::(&zero, 1).num_hashes, 1) - } + use hash::hash; fn verify_slice_generic(verify_slice: fn(&[Entry], &Sha256Hash) -> bool) { let zero = Sha256Hash::default(); diff --git a/src/logger.rs b/src/logger.rs index 8f47bc97c5..50fc1feea0 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -8,7 +8,7 @@ use std::sync::mpsc::{Receiver, SyncSender, TryRecvError}; use std::time::{Duration, Instant}; use hash::Sha256Hash; -use log::{create_entry_mut, Entry}; +use entry::{create_entry_mut, Entry}; use event::Event; use serde::Serialize; use std::fmt::Debug; From b725fdb09340aa1974d8e75827a0ccbf05bf1633 Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Tue, 6 Mar 2018 17:36:45 -0700 Subject: [PATCH 3/3] Sha256Hash -> Hash Because in Loom, there's just the one. Hopefully no worries that it shares a name with std::Hash. --- doc/historian.md | 10 +++++----- src/accountant.rs | 8 ++++---- src/accountant_skel.rs | 6 +++--- src/accountant_stub.rs | 10 +++++----- src/bin/demo.rs | 13 +++++-------- src/entry.rs | 30 +++++++++++------------------- src/genesis.rs | 4 ++-- src/hash.rs | 6 +++--- src/historian.rs | 14 +++++++------- src/log.rs | 23 ++++++++++------------- src/logger.rs | 6 +++--- src/transaction.rs | 19 +++++++------------ 12 files changed, 65 insertions(+), 84 deletions(-) diff --git a/doc/historian.md b/doc/historian.md index 8351645688..4f29267e02 100644 --- a/doc/historian.md +++ b/doc/historian.md @@ -11,15 +11,15 @@ with by verifying each entry's hash can be generated from the hash in the previo extern crate silk; use silk::historian::Historian; -use silk::log::{verify_slice, Entry, Sha256Hash}; +use silk::log::{verify_slice, Entry, Hash}; use silk::event::{generate_keypair, get_pubkey, sign_claim_data, Event}; use std::thread::sleep; use std::time::Duration; use std::sync::mpsc::SendError; -fn create_log(hist: &Historian) -> Result<(), SendError>> { +fn create_log(hist: &Historian) -> Result<(), SendError>> { sleep(Duration::from_millis(15)); - let asset = Sha256Hash::default(); + let asset = Hash::default(); let keypair = generate_keypair(); let event0 = Event::new_claim(get_pubkey(&keypair), asset, sign_claim_data(&asset, &keypair)); hist.sender.send(event0)?; @@ -28,11 +28,11 @@ fn create_log(hist: &Historian) -> Result<(), SendError> = hist.receiver.iter().collect(); + let entries: Vec> = hist.receiver.iter().collect(); for entry in &entries { println!("{:?}", entry); } diff --git a/src/accountant.rs b/src/accountant.rs index 0bc97f5a68..96bbb03366 100644 --- a/src/accountant.rs +++ b/src/accountant.rs @@ -2,7 +2,7 @@ //! event log to record transactions. Its users can deposit funds and //! transfer funds to other users. -use hash::Sha256Hash; +use hash::Hash; use entry::Entry; use event::Event; use transaction::Transaction; @@ -27,8 +27,8 @@ pub type Result = result::Result; pub struct Accountant { pub historian: Historian, pub balances: HashMap, - pub first_id: Sha256Hash, - pub last_id: Sha256Hash, + pub first_id: Hash, + pub last_id: Hash, } impl Accountant { @@ -67,7 +67,7 @@ impl Accountant { Self::new_from_entries(gen.create_entries(), ms_per_tick) } - pub fn sync(self: &mut Self) -> Sha256Hash { + pub fn sync(self: &mut Self) -> Hash { while let Ok(entry) = self.historian.receiver.try_recv() { self.last_id = entry.id; } diff --git a/src/accountant_skel.rs b/src/accountant_skel.rs index 9cd25dad08..c5afe6bc7b 100644 --- a/src/accountant_skel.rs +++ b/src/accountant_skel.rs @@ -2,7 +2,7 @@ use std::io; use accountant::Accountant; use transaction::Transaction; use signature::PublicKey; -use hash::Sha256Hash; +use hash::Hash; use entry::Entry; use std::net::UdpSocket; use bincode::{deserialize, serialize}; @@ -15,7 +15,7 @@ pub struct AccountantSkel { pub enum Request { Transaction(Transaction), GetBalance { key: PublicKey }, - GetEntries { last_id: Sha256Hash }, + GetEntries { last_id: Hash }, GetId { is_last: bool }, } @@ -23,7 +23,7 @@ pub enum Request { pub enum Response { Balance { key: PublicKey, val: Option }, Entries { entries: Vec> }, - Id { id: Sha256Hash, is_last: bool }, + Id { id: Hash, is_last: bool }, } impl AccountantSkel { diff --git a/src/accountant_stub.rs b/src/accountant_stub.rs index 61529642ae..f36e940480 100644 --- a/src/accountant_stub.rs +++ b/src/accountant_stub.rs @@ -7,7 +7,7 @@ use std::io; use bincode::{deserialize, serialize}; use transaction::Transaction; use signature::{PublicKey, Signature}; -use hash::Sha256Hash; +use hash::Hash; use entry::Entry; use ring::signature::Ed25519KeyPair; use accountant_skel::{Request, Response}; @@ -15,7 +15,7 @@ use accountant_skel::{Request, Response}; pub struct AccountantStub { pub addr: String, pub socket: UdpSocket, - pub last_id: Option, + pub last_id: Option, } impl AccountantStub { @@ -38,7 +38,7 @@ impl AccountantStub { n: i64, keypair: &Ed25519KeyPair, to: PublicKey, - last_id: &Sha256Hash, + last_id: &Hash, ) -> io::Result { let tr = Transaction::new(keypair, to, n, *last_id); let sig = tr.sig; @@ -59,7 +59,7 @@ impl AccountantStub { Ok(None) } - fn get_id(&self, is_last: bool) -> io::Result { + fn get_id(&self, is_last: bool) -> io::Result { let req = Request::GetId { is_last }; let data = serialize(&req).expect("serialize GetId"); self.socket.send_to(&data, &self.addr)?; @@ -72,7 +72,7 @@ impl AccountantStub { Ok(Default::default()) } - pub fn get_last_id(&self) -> io::Result { + pub fn get_last_id(&self) -> io::Result { self.get_id(true) } diff --git a/src/bin/demo.rs b/src/bin/demo.rs index 75614d56a1..4aad34f20c 100644 --- a/src/bin/demo.rs +++ b/src/bin/demo.rs @@ -1,7 +1,7 @@ extern crate silk; use silk::historian::Historian; -use silk::hash::Sha256Hash; +use silk::hash::Hash; use silk::entry::Entry; use silk::log::verify_slice; use silk::signature::{generate_keypair, get_pubkey}; @@ -11,12 +11,9 @@ use std::thread::sleep; use std::time::Duration; use std::sync::mpsc::SendError; -fn create_log( - hist: &Historian, - seed: &Sha256Hash, -) -> Result<(), SendError>> { +fn create_log(hist: &Historian, seed: &Hash) -> Result<(), SendError>> { sleep(Duration::from_millis(15)); - let asset = Sha256Hash::default(); + let asset = Hash::default(); let keypair = generate_keypair(); let tr = Transaction::new(&keypair, get_pubkey(&keypair), asset, *seed); let event0 = Event::Transaction(tr); @@ -26,11 +23,11 @@ fn create_log( } fn main() { - let seed = Sha256Hash::default(); + let seed = Hash::default(); let hist = Historian::new(&seed, Some(10)); create_log(&hist, &seed).expect("send error"); drop(hist.sender); - let entries: Vec> = hist.receiver.iter().collect(); + let entries: Vec> = hist.receiver.iter().collect(); for entry in &entries { println!("{:?}", entry); } diff --git a/src/entry.rs b/src/entry.rs index f970bc0cab..82b691087b 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -1,18 +1,18 @@ -use hash::{extend_and_hash, hash, Sha256Hash}; +use hash::{extend_and_hash, hash, Hash}; use serde::Serialize; use event::Event; #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Entry { pub num_hashes: u64, - pub id: Sha256Hash, + pub id: Hash, pub event: Event, } impl Entry { /// Creates a Entry from the number of hashes 'num_hashes' since the previous event /// and that resulting 'id'. - pub fn new_tick(num_hashes: u64, id: &Sha256Hash) -> Self { + pub fn new_tick(num_hashes: u64, id: &Hash) -> Self { Entry { num_hashes, id: *id, @@ -22,7 +22,7 @@ impl Entry { /// Verifies self.id is the result of hashing a 'start_hash' 'self.num_hashes' times. /// If the event is not a Tick, then hash that as well. - pub fn verify(&self, start_hash: &Sha256Hash) -> bool { + pub fn verify(&self, start_hash: &Hash) -> bool { if !self.event.verify() { return false; } @@ -33,11 +33,7 @@ impl Entry { /// Creates the hash 'num_hashes' after start_hash. If the event contains /// signature, the final hash will be a hash of both the previous ID and /// the signature. -pub fn next_hash( - start_hash: &Sha256Hash, - num_hashes: u64, - event: &Event, -) -> Sha256Hash { +pub fn next_hash(start_hash: &Hash, num_hashes: u64, event: &Event) -> Hash { let mut id = *start_hash; let sig = event.get_signature(); let start_index = if sig.is_some() { 1 } else { 0 }; @@ -51,11 +47,7 @@ pub fn next_hash( } /// Creates the next Entry 'num_hashes' after 'start_hash'. -pub fn create_entry( - start_hash: &Sha256Hash, - cur_hashes: u64, - event: Event, -) -> Entry { +pub fn create_entry(start_hash: &Hash, cur_hashes: u64, event: Event) -> Entry { let sig = event.get_signature(); let num_hashes = cur_hashes + if sig.is_some() { 1 } else { 0 }; let id = next_hash(start_hash, 0, &event); @@ -68,7 +60,7 @@ pub fn create_entry( /// Creates the next Tick Entry 'num_hashes' after 'start_hash'. pub fn create_entry_mut( - start_hash: &mut Sha256Hash, + start_hash: &mut Hash, cur_hashes: &mut u64, event: Event, ) -> Entry { @@ -79,7 +71,7 @@ pub fn create_entry_mut( } /// Creates the next Tick Entry 'num_hashes' after 'start_hash'. -pub fn next_tick(start_hash: &Sha256Hash, num_hashes: u64) -> Entry { +pub fn next_tick(start_hash: &Hash, num_hashes: u64) -> Entry { let event = Event::Tick; Entry { num_hashes, @@ -94,7 +86,7 @@ mod tests { #[test] fn test_event_verify() { - let zero = Sha256Hash::default(); + let zero = Hash::default(); let one = hash(&zero); assert!(Entry::::new_tick(0, &zero).verify(&zero)); // base case assert!(!Entry::::new_tick(0, &zero).verify(&one)); // base case, bad @@ -104,7 +96,7 @@ mod tests { #[test] fn test_next_tick() { - let zero = Sha256Hash::default(); - assert_eq!(next_tick::(&zero, 1).num_hashes, 1) + let zero = Hash::default(); + assert_eq!(next_tick::(&zero, 1).num_hashes, 1) } } diff --git a/src/genesis.rs b/src/genesis.rs index ef9df97726..4d95e24eb6 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -5,7 +5,7 @@ use transaction::Transaction; use signature::{generate_keypair, get_pubkey, PublicKey}; use entry::Entry; use log::create_entries; -use hash::{hash, Sha256Hash}; +use hash::{hash, Hash}; use ring::rand::SystemRandom; use ring::signature::Ed25519KeyPair; use untrusted::Input; @@ -44,7 +44,7 @@ impl Genesis { } } - pub fn get_seed(&self) -> Sha256Hash { + pub fn get_seed(&self) -> Hash { hash(&self.pkcs8) } diff --git a/src/hash.rs b/src/hash.rs index 5efb933f5f..181db33499 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -2,17 +2,17 @@ use generic_array::GenericArray; use generic_array::typenum::U32; use sha2::{Digest, Sha256}; -pub type Sha256Hash = GenericArray; +pub type Hash = GenericArray; /// Return a Sha256 hash for the given data. -pub fn hash(val: &[u8]) -> Sha256Hash { +pub fn hash(val: &[u8]) -> Hash { let mut hasher = Sha256::default(); hasher.input(val); hasher.result() } /// Return the hash of the given hash extended with the given value. -pub fn extend_and_hash(id: &Sha256Hash, val: &[u8]) -> Sha256Hash { +pub fn extend_and_hash(id: &Hash, val: &[u8]) -> Hash { let mut hash_data = id.to_vec(); hash_data.extend_from_slice(val); hash(&hash_data) diff --git a/src/historian.rs b/src/historian.rs index 7bf21d9c31..6d335819e0 100644 --- a/src/historian.rs +++ b/src/historian.rs @@ -5,7 +5,7 @@ use std::thread::{spawn, JoinHandle}; use std::collections::HashSet; use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::time::Instant; -use hash::{hash, Sha256Hash}; +use hash::{hash, Hash}; use entry::Entry; use logger::{ExitReason, Logger}; use signature::Signature; @@ -21,7 +21,7 @@ pub struct Historian { } impl Historian { - pub fn new(start_hash: &Sha256Hash, ms_per_tick: Option) -> Self { + pub fn new(start_hash: &Hash, ms_per_tick: Option) -> Self { let (sender, event_receiver) = sync_channel(1000); let (entry_sender, receiver) = sync_channel(1000); let thread_hdl = @@ -38,7 +38,7 @@ impl Historian { /// A background thread that will continue tagging received Event messages and /// sending back Entry messages until either the receiver or sender channel is closed. fn create_logger( - start_hash: Sha256Hash, + start_hash: Hash, ms_per_tick: Option, receiver: Receiver>, sender: SyncSender>, @@ -75,7 +75,7 @@ mod tests { #[test] fn test_historian() { - let zero = Sha256Hash::default(); + let zero = Hash::default(); let hist = Historian::new(&zero, None); hist.sender.send(Event::Tick).unwrap(); @@ -99,7 +99,7 @@ mod tests { #[test] fn test_historian_closed_sender() { - let zero = Sha256Hash::default(); + let zero = Hash::default(); let hist = Historian::::new(&zero, None); drop(hist.receiver); hist.sender.send(Event::Tick).unwrap(); @@ -119,12 +119,12 @@ mod tests { #[test] fn test_ticking_historian() { - let zero = Sha256Hash::default(); + let zero = Hash::default(); let hist = Historian::new(&zero, Some(20)); sleep(Duration::from_millis(30)); hist.sender.send(Event::Tick).unwrap(); drop(hist.sender); - let entries: Vec> = hist.receiver.iter().collect(); + let entries: Vec> = hist.receiver.iter().collect(); // Ensure one entry is sent back for each tick sent in. assert_eq!(entries.len(), 1); diff --git a/src/log.rs b/src/log.rs index 6d319c1e14..78f287c742 100644 --- a/src/log.rs +++ b/src/log.rs @@ -13,37 +13,34 @@ /// fastest processor. Duration should therefore be estimated by assuming that the hash /// was generated by the fastest processor at the time the entry was logged. -use hash::Sha256Hash; +use hash::Hash; use serde::Serialize; use entry::{create_entry_mut, next_tick, Entry}; use event::Event; use rayon::prelude::*; /// Verifies the hashes and counts of a slice of events are all consistent. -pub fn verify_slice(events: &[Entry], start_hash: &Sha256Hash) -> bool { +pub fn verify_slice(events: &[Entry], start_hash: &Hash) -> bool { let genesis = [Entry::new_tick(Default::default(), start_hash)]; let event_pairs = genesis.par_iter().chain(events).zip(events); event_pairs.all(|(x0, x1)| x1.verify(&x0.id)) } /// Verifies the hashes and counts of a slice of events are all consistent. -pub fn verify_slice_i64(events: &[Entry], start_hash: &Sha256Hash) -> bool { +pub fn verify_slice_i64(events: &[Entry], start_hash: &Hash) -> bool { let genesis = [Entry::new_tick(Default::default(), start_hash)]; let event_pairs = genesis.par_iter().chain(events).zip(events); event_pairs.all(|(x0, x1)| x1.verify(&x0.id)) } /// Verifies the hashes and events serially. Exists only for reference. -pub fn verify_slice_seq(events: &[Entry], start_hash: &Sha256Hash) -> bool { +pub fn verify_slice_seq(events: &[Entry], start_hash: &Hash) -> bool { let genesis = [Entry::new_tick(0, start_hash)]; let mut event_pairs = genesis.iter().chain(events).zip(events); event_pairs.all(|(x0, x1)| x1.verify(&x0.id)) } -pub fn create_entries( - start_hash: &Sha256Hash, - events: Vec>, -) -> Vec> { +pub fn create_entries(start_hash: &Hash, events: Vec>) -> Vec> { let mut id = *start_hash; events .into_iter() @@ -52,7 +49,7 @@ pub fn create_entries( } /// Create a vector of Ticks of length 'len' from 'start_hash' hash and 'num_hashes'. -pub fn next_ticks(start_hash: &Sha256Hash, num_hashes: u64, len: usize) -> Vec> { +pub fn next_ticks(start_hash: &Hash, num_hashes: u64, len: usize) -> Vec> { let mut id = *start_hash; let mut ticks = vec![]; for _ in 0..len { @@ -70,8 +67,8 @@ mod tests { use transaction::Transaction; use hash::hash; - fn verify_slice_generic(verify_slice: fn(&[Entry], &Sha256Hash) -> bool) { - let zero = Sha256Hash::default(); + fn verify_slice_generic(verify_slice: fn(&[Entry], &Hash) -> bool) { + let zero = Hash::default(); let one = hash(&zero); assert!(verify_slice(&vec![], &zero)); // base case assert!(verify_slice(&vec![Entry::new_tick(0, &zero)], &zero)); // singleton case 1 @@ -90,12 +87,12 @@ mod tests { #[test] fn test_verify_slice_seq() { - verify_slice_generic(verify_slice_seq::); + verify_slice_generic(verify_slice_seq::); } #[test] fn test_reorder_attack() { - let zero = Sha256Hash::default(); + let zero = Hash::default(); let one = hash(&zero); // First, verify entries diff --git a/src/logger.rs b/src/logger.rs index 50fc1feea0..2d839809a0 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -7,7 +7,7 @@ use std::sync::mpsc::{Receiver, SyncSender, TryRecvError}; use std::time::{Duration, Instant}; -use hash::Sha256Hash; +use hash::Hash; use entry::{create_entry_mut, Entry}; use event::Event; use serde::Serialize; @@ -23,7 +23,7 @@ pub enum ExitReason { pub struct Logger { pub sender: SyncSender>, pub receiver: Receiver>, - pub last_id: Sha256Hash, + pub last_id: Hash, pub num_hashes: u64, pub num_ticks: u64, } @@ -32,7 +32,7 @@ impl Logger { pub fn new( receiver: Receiver>, sender: SyncSender>, - start_hash: Sha256Hash, + start_hash: Hash, ) -> Self { Logger { receiver, diff --git a/src/transaction.rs b/src/transaction.rs index 1193358668..209a5dc7cb 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -4,24 +4,19 @@ use signature::{get_pubkey, verify_signature, PublicKey, Signature}; use ring::signature::Ed25519KeyPair; use serde::Serialize; use bincode::serialize; -use hash::Sha256Hash; +use hash::Hash; #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Transaction { pub from: PublicKey, pub to: PublicKey, pub asset: T, - pub last_id: Sha256Hash, + pub last_id: Hash, pub sig: Signature, } impl Transaction { - pub fn new( - from_keypair: &Ed25519KeyPair, - to: PublicKey, - asset: T, - last_id: Sha256Hash, - ) -> Self { + pub fn new(from_keypair: &Ed25519KeyPair, to: PublicKey, asset: T, last_id: Hash) -> Self { let mut tr = Transaction { from: get_pubkey(&from_keypair), to, @@ -58,14 +53,14 @@ mod tests { fn test_claim() { let keypair = generate_keypair(); let asset = hash(b"hello, world"); - let zero = Sha256Hash::default(); + let zero = Hash::default(); let tr0 = Transaction::new(&keypair, get_pubkey(&keypair), asset, zero); assert!(tr0.verify()); } #[test] fn test_transfer() { - let zero = Sha256Hash::default(); + let zero = Hash::default(); let keypair0 = generate_keypair(); let keypair1 = generate_keypair(); let pubkey1 = get_pubkey(&keypair1); @@ -90,7 +85,7 @@ mod tests { #[test] fn test_bad_event_signature() { - let zero = Sha256Hash::default(); + let zero = Hash::default(); let keypair = generate_keypair(); let pubkey = get_pubkey(&keypair); let mut tr = Transaction::new(&keypair, pubkey, hash(b"hello, world"), zero); @@ -105,7 +100,7 @@ mod tests { let keypair1 = generate_keypair(); let thief_keypair = generate_keypair(); let pubkey1 = get_pubkey(&keypair1); - let zero = Sha256Hash::default(); + let zero = Hash::default(); let mut tr = Transaction::new(&keypair0, pubkey1, hash(b"hello, world"), zero); tr.sign(&keypair0); tr.to = get_pubkey(&thief_keypair); // <-- attack!