2018-03-19 10:16:16 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//! The `recorder` crate provides an object for generating a Proof-of-History.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//! It records Event items on behalf of its users. It continuously generates
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//! 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
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//! Event, the latest hash, and the number of hashes since the last event.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//! The resulting stream of entries represents ordered events in time.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-04 07:28:51 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use std::sync::mpsc::{Receiver, SyncSender, TryRecvError};
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use std::time::{Duration, Instant};
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 16:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use std::mem;
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-20 23:15:44 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use hash::{hash, Hash};
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-06 17:31:17 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use entry::{create_entry_mut, Entry};
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-04 22:26:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use event::Event;
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 17:22:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								pub enum Signal {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Tick,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Event(Event),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[derive(Debug, PartialEq, Eq)]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								pub enum ExitReason {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    RecvDisconnected,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    SendDisconnected,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-19 10:16:16 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								pub struct Recorder {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-20 23:15:44 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    sender: SyncSender<Entry>,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    receiver: Receiver<Signal>,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    last_hash: Hash,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    events: Vec<Event>,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    num_hashes: u64,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    num_ticks: u64,
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-19 10:16:16 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								impl Recorder {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 17:22:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    pub fn new(receiver: Receiver<Signal>, sender: SyncSender<Entry>, start_hash: Hash) -> Self {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-19 10:16:16 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        Recorder {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            receiver,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            sender,
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-20 23:15:44 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            last_hash: start_hash,
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 16:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            events: vec![],
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            num_hashes: 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            num_ticks: 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-20 23:15:44 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    pub fn hash(&mut self) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.last_hash = hash(&self.last_hash);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.num_hashes += 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    pub fn record_entry(&mut self) -> Result<(), ExitReason> {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 16:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        let events = mem::replace(&mut self.events, vec![]);
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-20 23:15:44 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        let entry = create_entry_mut(&mut self.last_hash, &mut self.num_hashes, events);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.sender
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            .send(entry)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            .or(Err(ExitReason::SendDisconnected))?;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Ok(())
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-05 10:30:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    pub fn process_events(
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        &mut self,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        epoch: Instant,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ms_per_tick: Option<u64>,
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-05 10:30:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    ) -> Result<(), ExitReason> {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        loop {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if let Some(ms) = ms_per_tick {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if epoch.elapsed() > Duration::from_millis((self.num_ticks + 1) * ms) {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-19 10:16:16 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    self.record_entry()?;
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    self.num_ticks += 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-05 10:30:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            match self.receiver.try_recv() {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 17:22:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                Ok(signal) => match signal {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    Signal::Tick => {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-20 23:15:44 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        self.record_entry()?;
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 17:22:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    Signal::Event(event) => {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 16:16:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        self.events.push(event);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    }
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-09 17:22:14 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                },
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-05 10:30:05 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                Err(TryRecvError::Empty) => return Ok(()),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                Err(TryRecvError::Disconnected) => return Err(ExitReason::RecvDisconnected),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            };
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-03 14:24:32 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |