WIP: process timestamps
This commit is contained in:
@ -10,7 +10,7 @@ use signature::{KeyPair, PublicKey, Signature};
|
|||||||
use mint::Mint;
|
use mint::Mint;
|
||||||
use historian::{reserve_signature, Historian};
|
use historian::{reserve_signature, Historian};
|
||||||
use std::sync::mpsc::SendError;
|
use std::sync::mpsc::SendError;
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::result;
|
use std::result;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
|
|
||||||
@ -29,7 +29,9 @@ pub struct Accountant {
|
|||||||
pub balances: HashMap<PublicKey, i64>,
|
pub balances: HashMap<PublicKey, i64>,
|
||||||
pub first_id: Hash,
|
pub first_id: Hash,
|
||||||
pub last_id: Hash,
|
pub last_id: Hash,
|
||||||
pub pending: HashMap<Signature, Transaction<i64>>,
|
pending: HashMap<Signature, Transaction<i64>>,
|
||||||
|
time_sources: HashSet<PublicKey>,
|
||||||
|
last_time: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Accountant {
|
impl Accountant {
|
||||||
@ -51,6 +53,8 @@ impl Accountant {
|
|||||||
first_id: start_hash,
|
first_id: start_hash,
|
||||||
last_id: start_hash,
|
last_id: start_hash,
|
||||||
pending: HashMap::new(),
|
pending: HashMap::new(),
|
||||||
|
time_sources: HashSet::new(),
|
||||||
|
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 log is a special transaction where the to and from
|
||||||
@ -97,6 +101,16 @@ impl Accountant {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn complete_transaction(self: &mut Self, tr: &Transaction<i64>) {
|
||||||
|
if self.balances.contains_key(&tr.to) {
|
||||||
|
if let Some(x) = self.balances.get_mut(&tr.to) {
|
||||||
|
*x += tr.asset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.balances.insert(tr.to, tr.asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn process_verified_transaction(
|
fn process_verified_transaction(
|
||||||
self: &mut Self,
|
self: &mut Self,
|
||||||
tr: &Transaction<i64>,
|
tr: &Transaction<i64>,
|
||||||
@ -121,14 +135,7 @@ impl Accountant {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.balances.contains_key(&tr.to) {
|
self.complete_transaction(tr);
|
||||||
if let Some(x) = self.balances.get_mut(&tr.to) {
|
|
||||||
*x += tr.asset;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.balances.insert(tr.to, tr.asset);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +153,18 @@ impl Accountant {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_verified_timestamp(&mut self, _from: PublicKey, _dt: DateTime<Utc>) -> Result<()> {
|
fn process_verified_timestamp(&mut self, from: PublicKey, dt: DateTime<Utc>) -> Result<()> {
|
||||||
|
// If this is the first timestamp we've seen, it probably came from the genesis block,
|
||||||
|
// so we'll trust it.
|
||||||
|
if self.last_time == Utc.timestamp(0, 0) {
|
||||||
|
self.time_sources.insert(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.time_sources.contains(&from) {
|
||||||
|
if dt > self.last_time {
|
||||||
|
self.last_time = dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO: Lookup pending Transaction waiting on time, signed by a whitelisted PublicKey.
|
// TODO: Lookup pending Transaction waiting on time, signed by a whitelisted PublicKey.
|
||||||
|
|
||||||
// Expire:
|
// Expire:
|
||||||
@ -154,7 +172,7 @@ impl Accountant {
|
|||||||
// and remove the tx from this map.
|
// and remove the tx from this map.
|
||||||
|
|
||||||
// Process postponed:
|
// Process postponed:
|
||||||
// otherwise, if "Signature(from) is in if_all, remove it. If that causes that list
|
// otherwise, if "Timestamp(dt) >= self.last_time" is in if_all, remove it. If that causes that list
|
||||||
// to be empty, add the asset to to, and remove the tx from this map.
|
// to be empty, add the asset to to, and remove the tx from this map.
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
12
src/event.rs
12
src/event.rs
@ -1,6 +1,6 @@
|
|||||||
//! The `event` crate provides the data structures for log events.
|
//! The `event` crate provides the data structures for log events.
|
||||||
|
|
||||||
use signature::{PublicKey, Signature, SignatureUtil};
|
use signature::{KeyPair, KeyPairUtil, PublicKey, Signature, SignatureUtil};
|
||||||
use transaction::Transaction;
|
use transaction::Transaction;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
@ -27,6 +27,16 @@ pub enum Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Event {
|
impl Event {
|
||||||
|
pub fn new_timestamp(from: &KeyPair, dt: DateTime<Utc>) -> Self {
|
||||||
|
let sign_data = serialize(&dt).unwrap();
|
||||||
|
let sig = Signature::clone_from_slice(from.sign(&sign_data).as_ref());
|
||||||
|
Event::Timestamp {
|
||||||
|
from: from.pubkey(),
|
||||||
|
dt,
|
||||||
|
sig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Rename this to transaction_signature().
|
// TODO: Rename this to transaction_signature().
|
||||||
pub fn get_signature(&self) -> Option<Signature> {
|
pub fn get_signature(&self) -> Option<Signature> {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -42,7 +42,8 @@ impl Mint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_events(&self) -> Vec<Event> {
|
pub fn create_events(&self) -> Vec<Event> {
|
||||||
let tr = Transaction::new(&self.keypair(), self.pubkey(), self.tokens, self.seed());
|
let keypair = self.keypair();
|
||||||
|
let tr = Transaction::new(&keypair, self.pubkey(), self.tokens, self.seed());
|
||||||
vec![Event::Tick, Event::Transaction(tr)]
|
vec![Event::Tick, Event::Transaction(tr)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user