Skip to content

Commit

Permalink
Add Cancel and Timestamp events
Browse files Browse the repository at this point in the history
Fixes #31, #34, #39
  • Loading branch information
garious committed Mar 8, 2018
1 parent 2379792 commit 94daf4c
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
39 changes: 39 additions & 0 deletions src/accountant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct Accountant {
pub balances: HashMap<PublicKey, i64>,
pub first_id: Hash,
pub last_id: Hash,
pub pending: HashMap<Signature, Transaction<i64>>,
}

impl Accountant {
Expand All @@ -49,6 +50,7 @@ impl Accountant {
balances: HashMap::new(),
first_id: start_hash,
last_id: start_hash,
pending: HashMap::new(),
};

// The second item in the log is a special transaction where the to and from
Expand Down Expand Up @@ -104,12 +106,20 @@ impl Accountant {
return Err(AccountingError::InvalidTransferSignature);
}

if !tr.unless_any.is_empty() {
// TODO: Check to see if the transaction is expired.
}

if !Self::is_deposit(allow_deposits, &tr.from, &tr.to) {
if let Some(x) = self.balances.get_mut(&tr.from) {
*x -= tr.asset;
}
}

if !tr.if_all.is_empty() {
self.pending.insert(tr.sig, tr.clone());
}

if self.balances.contains_key(&tr.to) {
if let Some(x) = self.balances.get_mut(&tr.to) {
*x += tr.asset;
Expand All @@ -121,10 +131,39 @@ impl Accountant {
Ok(())
}

fn process_verified_sig(&mut self, _from: PublicKey, tx_sig: Signature) -> Result<()> {
if self.pending.contains_key(&tx_sig) {
if let Some(_tx) = self.pending.get_mut(&tx_sig) {
// Cancel:
// if Signature(from) is in unless_any, return funds to tx.from, and remove the tx from this map.

// Process Multisig:
// otherwise, if "Signature(from) 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.
}
}
Ok(())
}

fn process_verified_timestamp(&mut self, _from: PublicKey, _dt: DateTime<Utc>) -> Result<()> {
// TODO: Lookup pending Transaction waiting on time, signed by a whitelisted PublicKey.

// Expire:
// if a Timestamp after this DateTime is in unless_any, return funds to tx.from,
// and remove the tx from this map.

// Process postponed:
// otherwise, if "Signature(from) 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.
Ok(())
}

fn process_verified_event(self: &mut Self, event: &Event, allow_deposits: bool) -> Result<()> {
match *event {
Event::Tick => Ok(()),
Event::Transaction(ref tr) => self.process_verified_transaction(tr, allow_deposits),
Event::Signature { from, tx_sig, .. } => self.process_verified_sig(from, tx_sig),
Event::Timestamp { from, dt, .. } => self.process_verified_timestamp(from, dt),
}
}

Expand Down
19 changes: 18 additions & 1 deletion src/event.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! The `event` crate provides the data structures for log events.
use signature::Signature;
use signature::{PublicKey, Signature, SignatureUtil};
use transaction::Transaction;
use chrono::prelude::*;
use bincode::serialize;

/// When 'event' is Tick, the event represents a simple clock tick, and exists for the
/// sole purpose of improving the performance of event log verification. A tick can
Expand All @@ -12,20 +14,35 @@ use transaction::Transaction;
pub enum Event {
Tick,
Transaction(Transaction<i64>),
Signature {
from: PublicKey,
tx_sig: Signature,
sig: Signature,
},
Timestamp {
from: PublicKey,
dt: DateTime<Utc>,
sig: Signature,
},
}

impl Event {
// TODO: Rename this to transaction_signature().
pub fn get_signature(&self) -> Option<Signature> {
match *self {
Event::Tick => None,
Event::Transaction(ref tr) => Some(tr.sig),
Event::Signature { .. } => None,
Event::Timestamp { .. } => None,
}
}

pub fn verify(&self) -> bool {
match *self {
Event::Tick => true,
Event::Transaction(ref tr) => tr.verify(),
Event::Signature { from, tx_sig, sig } => sig.verify(&from, &tx_sig),
Event::Timestamp { from, dt, sig } => sig.verify(&from, &serialize(&dt).unwrap()),
}
}
}
11 changes: 6 additions & 5 deletions src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use chrono::prelude::*;

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum Condition {
DateTime(DateTime<Utc>),
Cancel,
Timestamp(DateTime<Utc>),
Signature(PublicKey),
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
Expand Down Expand Up @@ -45,11 +45,12 @@ impl<T: Serialize> Transaction<T> {
asset: T,
last_id: Hash,
) -> Self {
let from = from_keypair.pubkey();
let mut tr = Transaction {
from: from_keypair.pubkey(),
from,
to,
if_all: vec![Condition::DateTime(dt)],
unless_any: vec![Condition::Cancel],
if_all: vec![Condition::Timestamp(dt)],
unless_any: vec![Condition::Signature(from)],
asset,
last_id,
sig: Signature::default(),
Expand Down

0 comments on commit 94daf4c

Please sign in to comment.