Merge pull request #29 from garious/simplify

Remove Discovery event
This commit is contained in:
Greg Fitzgerald 2018-03-01 18:53:25 -07:00 committed by GitHub
commit 662e10c3e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 61 deletions

View File

@ -45,7 +45,7 @@ use std::sync::mpsc::SendError;
fn create_log(hist: &Historian) -> Result<(), SendError<Event>> { fn create_log(hist: &Historian) -> Result<(), SendError<Event>> {
sleep(Duration::from_millis(15)); sleep(Duration::from_millis(15));
let data = Sha256Hash::default(); let data = Sha256Hash::default();
hist.sender.send(Event::Discovery { data })?; hist.sender.send(Event::Claim { data })?;
sleep(Duration::from_millis(10)); sleep(Duration::from_millis(10));
Ok(()) Ok(())
} }
@ -70,7 +70,7 @@ Running the program should produce a log similar to:
```rust ```rust
Entry { num_hashes: 0, end_hash: [0, ...], event: Tick } Entry { num_hashes: 0, end_hash: [0, ...], event: Tick }
Entry { num_hashes: 2, end_hash: [67, ...], event: Discovery { data: [37, ...] } } Entry { num_hashes: 2, end_hash: [67, ...], event: Claim { data: [37, ...] } }
Entry { num_hashes: 3, end_hash: [123, ...], event: Tick } Entry { num_hashes: 3, end_hash: [123, ...], event: Tick }
``` ```

View File

@ -4,10 +4,10 @@ msc {
logger=>historian [ label = "e0 = Entry{hash: h0, n: 0, event: Tick}" ] ; logger=>historian [ label = "e0 = Entry{hash: h0, n: 0, event: Tick}" ] ;
logger=>logger [ label = "h1 = hash(h0)" ] ; logger=>logger [ label = "h1 = hash(h0)" ] ;
logger=>logger [ label = "h2 = hash(h1)" ] ; logger=>logger [ label = "h2 = hash(h1)" ] ;
client=>historian [ label = "Discovery(d0)" ] ; client=>historian [ label = "Claim(d0)" ] ;
historian=>logger [ label = "Discovery(d0)" ] ; historian=>logger [ label = "Claim(d0)" ] ;
logger=>logger [ label = "h3 = hash(h2 + d0)" ] ; logger=>logger [ label = "h3 = hash(h2 + d0)" ] ;
logger=>historian [ label = "e1 = Entry{hash: hash(h3), n: 2, event: Discovery(d0)}" ] ; logger=>historian [ label = "e1 = Entry{hash: hash(h3), n: 2, event: Claim(d0)}" ] ;
logger=>logger [ label = "h4 = hash(h3)" ] ; logger=>logger [ label = "h4 = hash(h3)" ] ;
logger=>logger [ label = "h5 = hash(h4)" ] ; logger=>logger [ label = "h5 = hash(h4)" ] ;
logger=>logger [ label = "h6 = hash(h5)" ] ; logger=>logger [ label = "h6 = hash(h5)" ] ;

View File

@ -11,7 +11,6 @@ use std::collections::HashMap;
pub struct Accountant { pub struct Accountant {
pub historian: Historian<u64>, pub historian: Historian<u64>,
pub balances: HashMap<PublicKey, u64>, pub balances: HashMap<PublicKey, u64>,
pub signatures: HashMap<Signature, bool>,
pub end_hash: Sha256Hash, pub end_hash: Sha256Hash,
} }
@ -21,19 +20,13 @@ impl Accountant {
Accountant { Accountant {
historian: hist, historian: hist,
balances: HashMap::new(), balances: HashMap::new(),
signatures: HashMap::new(),
end_hash: *start_hash, end_hash: *start_hash,
} }
} }
pub fn process_event(self: &mut Self, event: &Event<u64>) { pub fn process_event(self: &mut Self, event: &Event<u64>) {
match *event { match *event {
Event::Claim { key, data, sig } => { Event::Claim { key, data, .. } => {
if self.signatures.contains_key(&sig) {
return;
}
self.signatures.insert(sig, true);
if self.balances.contains_key(&key) { if self.balances.contains_key(&key) {
if let Some(x) = self.balances.get_mut(&key) { if let Some(x) = self.balances.get_mut(&key) {
*x += data; *x += data;
@ -42,16 +35,7 @@ impl Accountant {
self.balances.insert(key, data); self.balances.insert(key, data);
} }
} }
Event::Transaction { Event::Transaction { from, to, data, .. } => {
from,
to,
data,
sig,
} => {
if self.signatures.contains_key(&sig) {
return;
}
self.signatures.insert(sig, true);
if let Some(x) = self.balances.get_mut(&from) { if let Some(x) = self.balances.get_mut(&from) {
*x -= data; *x -= data;
} }

View File

@ -1,7 +1,8 @@
extern crate silk; extern crate silk;
use silk::historian::Historian; use silk::historian::Historian;
use silk::log::{verify_slice, Entry, Event, Sha256Hash}; use silk::log::{generate_keypair, get_pubkey, sign_serialized, verify_slice, Entry, Event,
Sha256Hash};
use std::thread::sleep; use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use std::sync::mpsc::SendError; use std::sync::mpsc::SendError;
@ -9,7 +10,13 @@ use std::sync::mpsc::SendError;
fn create_log(hist: &Historian<Sha256Hash>) -> Result<(), SendError<Event<Sha256Hash>>> { fn create_log(hist: &Historian<Sha256Hash>) -> Result<(), SendError<Event<Sha256Hash>>> {
sleep(Duration::from_millis(15)); sleep(Duration::from_millis(15));
let data = Sha256Hash::default(); let data = Sha256Hash::default();
hist.sender.send(Event::Discovery { data })?; let keypair = generate_keypair();
let event0 = Event::Claim {
key: get_pubkey(&keypair),
data,
sig: sign_serialized(&data, &keypair),
};
hist.sender.send(event0)?;
sleep(Duration::from_millis(10)); sleep(Duration::from_millis(10));
Ok(()) Ok(())
} }

View File

@ -6,9 +6,10 @@
//! The resulting stream of entries represents ordered events in time. //! The resulting stream of entries represents ordered events in time.
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::collections::HashMap;
use std::sync::mpsc::{Receiver, SyncSender}; use std::sync::mpsc::{Receiver, SyncSender};
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use log::{hash, hash_event, verify_event, Entry, Event, Sha256Hash}; use log::{get_signature, hash, hash_event, verify_event, Entry, Event, Sha256Hash, Signature};
use serde::Serialize; use serde::Serialize;
use std::fmt::Debug; use std::fmt::Debug;
@ -45,6 +46,7 @@ fn log_event<T: Serialize + Clone + Debug>(
fn log_events<T: Serialize + Clone + Debug>( fn log_events<T: Serialize + Clone + Debug>(
receiver: &Receiver<Event<T>>, receiver: &Receiver<Event<T>>,
sender: &SyncSender<Entry<T>>, sender: &SyncSender<Entry<T>>,
signatures: &mut HashMap<Signature, bool>,
num_hashes: &mut u64, num_hashes: &mut u64,
end_hash: &mut Sha256Hash, end_hash: &mut Sha256Hash,
epoch: SystemTime, epoch: SystemTime,
@ -63,6 +65,12 @@ fn log_events<T: Serialize + Clone + Debug>(
match receiver.try_recv() { match receiver.try_recv() {
Ok(event) => { Ok(event) => {
if verify_event(&event) { if verify_event(&event) {
if let Some(sig) = get_signature(&event) {
if signatures.contains_key(&sig) {
continue;
}
signatures.insert(sig, true);
}
log_event(sender, num_hashes, end_hash, event)?; log_event(sender, num_hashes, end_hash, event)?;
} }
} }
@ -94,11 +102,13 @@ pub fn create_logger<T: 'static + Serialize + Clone + Debug + Send>(
let mut end_hash = start_hash; let mut end_hash = start_hash;
let mut num_hashes = 0; let mut num_hashes = 0;
let mut num_ticks = 0; let mut num_ticks = 0;
let mut signatures = HashMap::new();
let epoch = SystemTime::now(); let epoch = SystemTime::now();
loop { loop {
if let Err(err) = log_events( if let Err(err) = log_events(
&receiver, &receiver,
&sender, &sender,
&mut signatures,
&mut num_hashes, &mut num_hashes,
&mut end_hash, &mut end_hash,
epoch, epoch,
@ -141,7 +151,7 @@ mod tests {
hist.sender.send(Event::Tick).unwrap(); hist.sender.send(Event::Tick).unwrap();
sleep(Duration::new(0, 1_000_000)); sleep(Duration::new(0, 1_000_000));
hist.sender.send(Event::Discovery { data: zero }).unwrap(); hist.sender.send(Event::Tick).unwrap();
sleep(Duration::new(0, 1_000_000)); sleep(Duration::new(0, 1_000_000));
hist.sender.send(Event::Tick).unwrap(); hist.sender.send(Event::Tick).unwrap();
@ -175,7 +185,7 @@ mod tests {
let zero = Sha256Hash::default(); let zero = Sha256Hash::default();
let hist = Historian::new(&zero, Some(20)); let hist = Historian::new(&zero, Some(20));
sleep(Duration::from_millis(30)); sleep(Duration::from_millis(30));
hist.sender.send(Event::Discovery { data: zero }).unwrap(); hist.sender.send(Event::Tick).unwrap();
sleep(Duration::from_millis(15)); sleep(Duration::from_millis(15));
drop(hist.sender); drop(hist.sender);
assert_eq!( assert_eq!(

View File

@ -37,9 +37,6 @@ pub struct Entry<T> {
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum Event<T> { pub enum Event<T> {
Tick, Tick,
Discovery {
data: T,
},
Claim { Claim {
key: PublicKey, key: PublicKey,
data: T, data: T,
@ -104,36 +101,24 @@ pub fn hash(val: &[u8]) -> Sha256Hash {
} }
/// Return the hash of the given hash extended with the given value. /// Return the hash of the given hash extended with the given value.
pub fn extend_and_hash(end_hash: &Sha256Hash, ty: u8, val: &[u8]) -> Sha256Hash { pub fn extend_and_hash(end_hash: &Sha256Hash, val: &[u8]) -> Sha256Hash {
let mut hash_data = end_hash.to_vec(); let mut hash_data = end_hash.to_vec();
hash_data.push(ty);
hash_data.extend_from_slice(val); hash_data.extend_from_slice(val);
hash(&hash_data) hash(&hash_data)
} }
pub fn hash_event<T: Serialize>(end_hash: &Sha256Hash, event: &Event<T>) -> Sha256Hash { pub fn get_signature<T>(event: &Event<T>) -> Option<Signature> {
use bincode::serialize;
match *event { match *event {
Event::Tick => *end_hash, Event::Tick => None,
Event::Discovery { ref data } => extend_and_hash(end_hash, 1, &serialize(&data).unwrap()), Event::Claim { sig, .. } => Some(sig),
Event::Claim { key, ref data, sig } => { Event::Transaction { sig, .. } => Some(sig),
let mut event_data = serialize(&data).unwrap();
event_data.extend_from_slice(&sig);
event_data.extend_from_slice(&key);
extend_and_hash(end_hash, 2, &event_data)
}
Event::Transaction {
from,
to,
ref data,
sig,
} => {
let mut event_data = serialize(&data).unwrap();
event_data.extend_from_slice(&sig);
event_data.extend_from_slice(&from);
event_data.extend_from_slice(&to);
extend_and_hash(end_hash, 2, &event_data)
} }
}
pub fn hash_event<T>(end_hash: &Sha256Hash, event: &Event<T>) -> Sha256Hash {
match get_signature(event) {
None => *end_hash,
Some(sig) => extend_and_hash(end_hash, &sig),
} }
} }
@ -318,15 +303,24 @@ mod tests {
let zero = Sha256Hash::default(); let zero = Sha256Hash::default();
let one = hash(&zero); let one = hash(&zero);
// First, verify Discovery events // First, verify Claim events
let events = vec![ let keypair = generate_keypair();
Event::Discovery { data: zero }, let event0 = Event::Claim {
Event::Discovery { data: one }, key: get_pubkey(&keypair),
]; data: zero,
sig: sign_serialized(&zero, &keypair),
};
let event1 = Event::Claim {
key: get_pubkey(&keypair),
data: one,
sig: sign_serialized(&one, &keypair),
};
let events = vec![event0, event1];
let mut entries = create_entries(&zero, 0, events); let mut entries = create_entries(&zero, 0, events);
assert!(verify_slice(&entries, &zero)); assert!(verify_slice(&entries, &zero));
// Next, swap two Discovery events and ensure verification fails. // Next, swap two Claim events and ensure verification fails.
let event0 = entries[0].event.clone(); let event0 = entries[0].event.clone();
let event1 = entries[1].event.clone(); let event1 = entries[1].event.clone();
entries[0].event = event1; entries[0].event = event1;