Reset historian's hasher between events

Hasher will generate different hashes for the same input if it
had already generated a hash.

Also add a binary to ensure the example in the README works.
This commit is contained in:
Greg Fitzgerald 2018-02-19 12:00:56 -07:00
parent a7186328e0
commit d88d1b2a09
4 changed files with 84 additions and 20 deletions

View File

@ -11,6 +11,10 @@ authors = [
] ]
license = "Apache-2.0" license = "Apache-2.0"
[[bin]]
name = "silk-demo"
path = "src/bin/demo.rs"
[badges] [badges]
codecov = { repository = "loomprotocol/silk", branch = "master", service = "github" } codecov = { repository = "loomprotocol/silk", branch = "master", service = "github" }

View File

@ -25,22 +25,45 @@ is tagged with the historian's latest *hash*. Then ensure the order of events wa
with by verifying each entry's hash can be generated from the hash in the previous entry: with by verifying each entry's hash can be generated from the hash in the previous entry:
```rust ```rust
use historian::Historian; extern crate silk;
use log::{Event, verify_slice};
use silk::historian::Historian;
use silk::log::{verify_slice, Entry, Event};
use std::{thread, time};
fn create_log(hist: &Historian) -> Vec<Entry> {
hist.sender.send(Event::Tick).unwrap();
thread::sleep(time::Duration::new(0, 100_000));
hist.sender.send(Event::UserDataKey(0xdeadbeef)).unwrap();
thread::sleep(time::Duration::new(0, 100_000));
hist.sender.send(Event::Tick).unwrap();
let entry0 = hist.receiver.recv().unwrap();
let entry1 = hist.receiver.recv().unwrap();
let entry2 = hist.receiver.recv().unwrap();
vec![entry0, entry1, entry2]
}
fn main() { fn main() {
let hist = Historian::new(0); let seed = 0;
let hist = Historian::new(seed);
hist.sender.send(Event::Tick).unwrap(); let entries = create_log(&hist);
let entry0 = hist.receiver.recv().unwrap(); for entry in &entries {
println!("{:?}", entry);
hist.sender.send(Event::UserDataKey(0xdeadbeef)).unwrap(); }
let entry1 = hist.receiver.recv().unwrap(); assert!(verify_slice(&entries, seed));
assert!(verify_slice(&[entry0, entry1], 0));
} }
``` ```
Running the program should produce a log similar to:
```
Entry { num_hashes: 0, end_hash: 0, event: Tick }
Entry { num_hashes: 245, end_hash: 11504657626326377539, event: UserDataKey(3735928559) }
Entry { num_hashes: 154, end_hash: 13410333856574024888, event: Tick }
```
# Developing # Developing
Building Building

28
src/bin/demo.rs Normal file
View File

@ -0,0 +1,28 @@
extern crate silk;
use silk::historian::Historian;
use silk::log::{verify_slice, Entry, Event};
use std::{thread, time};
fn create_log(hist: &Historian) -> Vec<Entry> {
hist.sender.send(Event::Tick).unwrap();
thread::sleep(time::Duration::new(0, 100_000));
hist.sender.send(Event::UserDataKey(0xdeadbeef)).unwrap();
thread::sleep(time::Duration::new(0, 100_000));
hist.sender.send(Event::Tick).unwrap();
let entry0 = hist.receiver.recv().unwrap();
let entry1 = hist.receiver.recv().unwrap();
let entry2 = hist.receiver.recv().unwrap();
vec![entry0, entry1, entry2]
}
fn main() {
let seed = 0;
let hist = Historian::new(seed);
let entries = create_log(&hist);
for entry in &entries {
println!("{:?}", entry);
}
assert!(verify_slice(&entries, seed));
}

View File

@ -73,7 +73,11 @@ pub fn create_logger(
let mut num_hashes = 0; let mut num_hashes = 0;
loop { loop {
match log_events(&receiver, &sender, num_hashes, end_hash) { match log_events(&receiver, &sender, num_hashes, end_hash) {
Ok(n) => num_hashes = n, Ok(0) => {
num_hashes = 0;
hasher = DefaultHasher::new();
}
Ok(_) => {}
Err(err) => return err, Err(err) => return err,
} }
end_hash.hash(&mut hasher); end_hash.hash(&mut hasher);
@ -104,17 +108,22 @@ mod tests {
#[test] #[test]
fn test_historian() { fn test_historian() {
use std::thread::sleep;
use std::time::Duration;
let hist = Historian::new(0); let hist = Historian::new(0);
let event = Event::Tick; hist.sender.send(Event::Tick).unwrap();
hist.sender.send(event.clone()).unwrap(); sleep(Duration::new(0, 100_000));
let entry0 = hist.receiver.recv().unwrap(); hist.sender.send(Event::UserDataKey(0xdeadbeef)).unwrap();
assert_eq!(entry0.event, event); sleep(Duration::new(0, 100_000));
hist.sender.send(Event::Tick).unwrap();
let event = Event::UserDataKey(0xdeadbeef); let entry0 = hist.receiver.recv().unwrap();
hist.sender.send(event.clone()).unwrap();
let entry1 = hist.receiver.recv().unwrap(); let entry1 = hist.receiver.recv().unwrap();
assert_eq!(entry1.event, event); let entry2 = hist.receiver.recv().unwrap();
assert!(entry1.num_hashes != 0);
assert!(entry2.num_hashes != 0);
drop(hist.sender); drop(hist.sender);
assert_eq!( assert_eq!(
@ -122,7 +131,7 @@ mod tests {
ExitReason::RecvDisconnected ExitReason::RecvDisconnected
); );
assert!(verify_slice(&[entry0, entry1], 0)); assert!(verify_slice(&[entry0, entry1, entry2], 0));
} }
#[test] #[test]