logger -> recorder
Free up namespace for a traditional runtime logger.
This commit is contained in:
parent
9f9b79f30b
commit
64af37e0cd
|
@ -1,7 +1,7 @@
|
||||||
The Historian
|
The Historian
|
||||||
===
|
===
|
||||||
|
|
||||||
Create a *Historian* and send it *events* to generate an *event log*, where each log *entry*
|
Create a *Historian* and send it *events* to generate an *event log*, where each *entry*
|
||||||
is tagged with the historian's latest *hash*. Then ensure the order of events was not tampered
|
is tagged with the historian's latest *hash*. Then ensure the order of events was not tampered
|
||||||
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:
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ with by verifying each entry's hash can be generated from the hash in the previo
|
||||||
extern crate silk;
|
extern crate silk;
|
||||||
|
|
||||||
use silk::historian::Historian;
|
use silk::historian::Historian;
|
||||||
use silk::log::{verify_slice, Entry, Hash};
|
use silk::ledger::{verify_slice, Entry, Hash};
|
||||||
use silk::event::{generate_keypair, get_pubkey, sign_claim_data, Event};
|
use silk::event::{generate_keypair, get_pubkey, sign_claim_data, Event};
|
||||||
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;
|
||||||
|
|
||||||
fn create_log(hist: &Historian<Hash>) -> Result<(), SendError<Event<Hash>>> {
|
fn create_ledger(hist: &Historian<Hash>) -> Result<(), SendError<Event<Hash>>> {
|
||||||
sleep(Duration::from_millis(15));
|
sleep(Duration::from_millis(15));
|
||||||
let asset = Hash::default();
|
let asset = Hash::default();
|
||||||
let keypair = generate_keypair();
|
let keypair = generate_keypair();
|
||||||
|
@ -30,7 +30,7 @@ fn create_log(hist: &Historian<Hash>) -> Result<(), SendError<Event<Hash>>> {
|
||||||
fn main() {
|
fn main() {
|
||||||
let seed = Hash::default();
|
let seed = Hash::default();
|
||||||
let hist = Historian::new(&seed, Some(10));
|
let hist = Historian::new(&seed, Some(10));
|
||||||
create_log(&hist).expect("send error");
|
create_ledger(&hist).expect("send error");
|
||||||
drop(hist.sender);
|
drop(hist.sender);
|
||||||
let entries: Vec<Entry<Hash>> = hist.receiver.iter().collect();
|
let entries: Vec<Entry<Hash>> = hist.receiver.iter().collect();
|
||||||
for entry in &entries {
|
for entry in &entries {
|
||||||
|
@ -42,7 +42,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Running the program should produce a log similar to:
|
Running the program should produce a ledger similar to:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
Entry { num_hashes: 0, id: [0, ...], event: Tick }
|
Entry { num_hashes: 0, id: [0, ...], event: Tick }
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
msc {
|
msc {
|
||||||
client,historian,logger;
|
client,historian,recorder;
|
||||||
|
|
||||||
logger=>historian [ label = "e0 = Entry{id: h0, n: 0, event: Tick}" ] ;
|
recorder=>historian [ label = "e0 = Entry{id: h0, n: 0, event: Tick}" ] ;
|
||||||
logger=>logger [ label = "h1 = hash(h0)" ] ;
|
recorder=>recorder [ label = "h1 = hash(h0)" ] ;
|
||||||
logger=>logger [ label = "h2 = hash(h1)" ] ;
|
recorder=>recorder [ label = "h2 = hash(h1)" ] ;
|
||||||
client=>historian [ label = "Transaction(d0)" ] ;
|
client=>historian [ label = "Transaction(d0)" ] ;
|
||||||
historian=>logger [ label = "Transaction(d0)" ] ;
|
historian=>recorder [ label = "Transaction(d0)" ] ;
|
||||||
logger=>logger [ label = "h3 = hash(h2 + d0)" ] ;
|
recorder=>recorder [ label = "h3 = hash(h2 + d0)" ] ;
|
||||||
logger=>historian [ label = "e1 = Entry{id: hash(h3), n: 3, event: Transaction(d0)}" ] ;
|
recorder=>historian [ label = "e1 = Entry{id: hash(h3), n: 3, event: Transaction(d0)}" ] ;
|
||||||
logger=>logger [ label = "h4 = hash(h3)" ] ;
|
recorder=>recorder [ label = "h4 = hash(h3)" ] ;
|
||||||
logger=>logger [ label = "h5 = hash(h4)" ] ;
|
recorder=>recorder [ label = "h5 = hash(h4)" ] ;
|
||||||
logger=>logger [ label = "h6 = hash(h5)" ] ;
|
recorder=>recorder [ label = "h6 = hash(h5)" ] ;
|
||||||
logger=>historian [ label = "e2 = Entry{id: h6, n: 3, event: Tick}" ] ;
|
recorder=>historian [ label = "e2 = Entry{id: h6, n: 3, event: Tick}" ] ;
|
||||||
client=>historian [ label = "collect()" ] ;
|
client=>historian [ label = "collect()" ] ;
|
||||||
historian=>client [ label = "entries = [e0, e1, e2]" ] ;
|
historian=>client [ label = "entries = [e0, e1, e2]" ] ;
|
||||||
client=>client [ label = "verify_slice(entries, h0)" ] ;
|
client=>client [ label = "verify_slice(entries, h0)" ] ;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use transaction::Transaction;
|
||||||
use signature::{KeyPair, PublicKey, Signature};
|
use signature::{KeyPair, PublicKey, Signature};
|
||||||
use mint::Mint;
|
use mint::Mint;
|
||||||
use historian::{reserve_signature, Historian};
|
use historian::{reserve_signature, Historian};
|
||||||
use logger::Signal;
|
use recorder::Signal;
|
||||||
use std::sync::mpsc::SendError;
|
use std::sync::mpsc::SendError;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::result;
|
use std::result;
|
||||||
|
@ -43,8 +43,8 @@ impl Accountant {
|
||||||
{
|
{
|
||||||
let mut entries = entries.into_iter();
|
let mut entries = entries.into_iter();
|
||||||
|
|
||||||
// The first item in the log is required to be an entry with zero num_hashes,
|
// The first item in the ledger is required to be an entry with zero num_hashes,
|
||||||
// which implies its id can be used as the log's seed.
|
// which implies its id can be used as the ledger's seed.
|
||||||
let entry0 = entries.next().unwrap();
|
let entry0 = entries.next().unwrap();
|
||||||
let start_hash = entry0.id;
|
let start_hash = entry0.id;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ impl Accountant {
|
||||||
last_time: Utc.timestamp(0, 0),
|
last_time: Utc.timestamp(0, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
// The second item in the log is a special transaction where the to and from
|
// The second item in the ledger is a special transaction where the to and from
|
||||||
// fields are the same. That entry should be treated as a deposit, not a
|
// fields are the same. That entry should be treated as a deposit, not a
|
||||||
// transfer to oneself.
|
// transfer to oneself.
|
||||||
let entry1 = entries.next().unwrap();
|
let entry1 = entries.next().unwrap();
|
||||||
|
@ -240,7 +240,7 @@ impl Accountant {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use signature::KeyPairUtil;
|
use signature::KeyPairUtil;
|
||||||
use logger::ExitReason;
|
use recorder::ExitReason;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_accountant() {
|
fn test_accountant() {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use silk::historian::Historian;
|
||||||
use silk::hash::Hash;
|
use silk::hash::Hash;
|
||||||
use silk::entry::Entry;
|
use silk::entry::Entry;
|
||||||
use silk::ledger::verify_slice;
|
use silk::ledger::verify_slice;
|
||||||
use silk::logger::Signal;
|
use silk::recorder::Signal;
|
||||||
use silk::signature::{KeyPair, KeyPairUtil};
|
use silk::signature::{KeyPair, KeyPairUtil};
|
||||||
use silk::transaction::Transaction;
|
use silk::transaction::Transaction;
|
||||||
use silk::event::Event;
|
use silk::event::Event;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use hash::{hash, Hash};
|
use hash::{hash, Hash};
|
||||||
use entry::Entry;
|
use entry::Entry;
|
||||||
use logger::{ExitReason, Logger, Signal};
|
use recorder::{ExitReason, Recorder, Signal};
|
||||||
use signature::Signature;
|
use signature::Signature;
|
||||||
|
|
||||||
pub struct Historian {
|
pub struct Historian {
|
||||||
|
@ -22,7 +22,7 @@ impl Historian {
|
||||||
let (sender, event_receiver) = sync_channel(1000);
|
let (sender, event_receiver) = sync_channel(1000);
|
||||||
let (entry_sender, receiver) = sync_channel(1000);
|
let (entry_sender, receiver) = sync_channel(1000);
|
||||||
let thread_hdl =
|
let thread_hdl =
|
||||||
Historian::create_logger(*start_hash, ms_per_tick, event_receiver, entry_sender);
|
Historian::create_recorder(*start_hash, ms_per_tick, event_receiver, entry_sender);
|
||||||
let signatures = HashSet::new();
|
let signatures = HashSet::new();
|
||||||
Historian {
|
Historian {
|
||||||
sender,
|
sender,
|
||||||
|
@ -34,22 +34,22 @@ impl Historian {
|
||||||
|
|
||||||
/// A background thread that will continue tagging received Event messages and
|
/// A background thread that will continue tagging received Event messages and
|
||||||
/// sending back Entry messages until either the receiver or sender channel is closed.
|
/// sending back Entry messages until either the receiver or sender channel is closed.
|
||||||
fn create_logger(
|
fn create_recorder(
|
||||||
start_hash: Hash,
|
start_hash: Hash,
|
||||||
ms_per_tick: Option<u64>,
|
ms_per_tick: Option<u64>,
|
||||||
receiver: Receiver<Signal>,
|
receiver: Receiver<Signal>,
|
||||||
sender: SyncSender<Entry>,
|
sender: SyncSender<Entry>,
|
||||||
) -> JoinHandle<ExitReason> {
|
) -> JoinHandle<ExitReason> {
|
||||||
spawn(move || {
|
spawn(move || {
|
||||||
let mut logger = Logger::new(receiver, sender, start_hash);
|
let mut recorder = Recorder::new(receiver, sender, start_hash);
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
loop {
|
loop {
|
||||||
if let Err(err) = logger.process_events(now, ms_per_tick) {
|
if let Err(err) = recorder.process_events(now, ms_per_tick) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if ms_per_tick.is_some() {
|
if ms_per_tick.is_some() {
|
||||||
logger.last_id = hash(&logger.last_id);
|
recorder.last_id = hash(&recorder.last_id);
|
||||||
logger.num_hashes += 1;
|
recorder.num_hashes += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub mod event;
|
||||||
pub mod entry;
|
pub mod entry;
|
||||||
pub mod ledger;
|
pub mod ledger;
|
||||||
pub mod mint;
|
pub mod mint;
|
||||||
pub mod logger;
|
pub mod recorder;
|
||||||
pub mod historian;
|
pub mod historian;
|
||||||
pub mod streamer;
|
pub mod streamer;
|
||||||
pub mod accountant;
|
pub mod accountant;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! The `logger` crate provides an object for generating a Proof-of-History.
|
//! The `recorder` crate provides an object for generating a Proof-of-History.
|
||||||
//! It logs Event items on behalf of its users. It continuously generates
|
//! It records Event items on behalf of its users. It continuously generates
|
||||||
//! new hashes, only stopping to check if it has been sent an Event item. It
|
//! new hashes, only stopping to check if it has been sent an Event item. It
|
||||||
//! tags each Event with an Entry and sends it back. The Entry includes the
|
//! tags each Event with an Entry and sends it back. The Entry includes the
|
||||||
//! Event, the latest hash, and the number of hashes since the last event.
|
//! Event, the latest hash, and the number of hashes since the last event.
|
||||||
|
@ -24,7 +24,7 @@ pub enum ExitReason {
|
||||||
SendDisconnected,
|
SendDisconnected,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Logger {
|
pub struct Recorder {
|
||||||
pub sender: SyncSender<Entry>,
|
pub sender: SyncSender<Entry>,
|
||||||
pub receiver: Receiver<Signal>,
|
pub receiver: Receiver<Signal>,
|
||||||
pub last_id: Hash,
|
pub last_id: Hash,
|
||||||
|
@ -33,9 +33,9 @@ pub struct Logger {
|
||||||
pub num_ticks: u64,
|
pub num_ticks: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Logger {
|
impl Recorder {
|
||||||
pub fn new(receiver: Receiver<Signal>, sender: SyncSender<Entry>, start_hash: Hash) -> Self {
|
pub fn new(receiver: Receiver<Signal>, sender: SyncSender<Entry>, start_hash: Hash) -> Self {
|
||||||
Logger {
|
Recorder {
|
||||||
receiver,
|
receiver,
|
||||||
sender,
|
sender,
|
||||||
last_id: start_hash,
|
last_id: start_hash,
|
||||||
|
@ -45,7 +45,7 @@ impl Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_entry(&mut self) -> Result<Entry, ExitReason> {
|
pub fn record_entry(&mut self) -> Result<Entry, ExitReason> {
|
||||||
let events = mem::replace(&mut self.events, vec![]);
|
let events = mem::replace(&mut self.events, vec![]);
|
||||||
let entry = create_entry_mut(&mut self.last_id, &mut self.num_hashes, events);
|
let entry = create_entry_mut(&mut self.last_id, &mut self.num_hashes, events);
|
||||||
println!("{}", serde_json::to_string(&entry).unwrap());
|
println!("{}", serde_json::to_string(&entry).unwrap());
|
||||||
|
@ -60,7 +60,7 @@ impl Logger {
|
||||||
loop {
|
loop {
|
||||||
if let Some(ms) = ms_per_tick {
|
if let Some(ms) = ms_per_tick {
|
||||||
if epoch.elapsed() > Duration::from_millis((self.num_ticks + 1) * ms) {
|
if epoch.elapsed() > Duration::from_millis((self.num_ticks + 1) * ms) {
|
||||||
self.log_entry()?;
|
self.record_entry()?;
|
||||||
self.num_ticks += 1;
|
self.num_ticks += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ impl Logger {
|
||||||
match self.receiver.try_recv() {
|
match self.receiver.try_recv() {
|
||||||
Ok(signal) => match signal {
|
Ok(signal) => match signal {
|
||||||
Signal::Tick => {
|
Signal::Tick => {
|
||||||
let entry = self.log_entry()?;
|
let entry = self.record_entry()?;
|
||||||
self.sender
|
self.sender
|
||||||
.send(entry)
|
.send(entry)
|
||||||
.or(Err(ExitReason::SendDisconnected))?;
|
.or(Err(ExitReason::SendDisconnected))?;
|
Loading…
Reference in New Issue