From e7da083c312b3d12f27eab68173644acfaadbd8f Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Sat, 17 Mar 2018 14:42:43 -0600 Subject: [PATCH] Move spending plans to their own crate --- src/accountant.rs | 3 +- src/lib.rs | 1 + src/mint.rs | 2 +- src/plan.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++ src/transaction.rs | 121 +------------------------------------------ 5 files changed, 129 insertions(+), 122 deletions(-) create mode 100644 src/plan.rs diff --git a/src/accountant.rs b/src/accountant.rs index 72b03eab9..2464f57dd 100644 --- a/src/accountant.rs +++ b/src/accountant.rs @@ -5,7 +5,8 @@ use hash::Hash; use entry::Entry; use event::Event; -use transaction::{Action, Plan, Transaction}; +use plan::{Action, Plan}; +use transaction::Transaction; use signature::{KeyPair, PublicKey, Signature}; use mint::Mint; use historian::{reserve_signature, Historian}; diff --git a/src/lib.rs b/src/lib.rs index 560a5fa57..089399a5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![cfg_attr(feature = "unstable", feature(test))] pub mod signature; pub mod hash; +pub mod plan; pub mod transaction; pub mod event; pub mod entry; diff --git a/src/mint.rs b/src/mint.rs index ff21fc3b5..2040b0948 100644 --- a/src/mint.rs +++ b/src/mint.rs @@ -58,7 +58,7 @@ impl Mint { mod tests { use super::*; use log::verify_slice; - use transaction::{Action, Plan}; + use plan::{Action, Plan}; #[test] fn test_create_events() { diff --git a/src/plan.rs b/src/plan.rs new file mode 100644 index 000000000..86ade7591 --- /dev/null +++ b/src/plan.rs @@ -0,0 +1,124 @@ +//! The `plan` crate provides functionality for creating spending plans. + +use signature::PublicKey; +use chrono::prelude::*; +use std::mem; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +pub enum Condition { + Timestamp(DateTime), + Signature(PublicKey), +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +pub enum Action { + Pay(Payment), +} + +impl Action { + pub fn spendable(&self) -> T { + match *self { + Action::Pay(ref payment) => payment.asset.clone(), + } + } +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +pub struct Payment { + pub asset: T, + pub to: PublicKey, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +pub enum Plan { + Action(Action), + After(Condition, Box>), + Race(Box>, Box>), +} + +impl Plan { + pub fn verify(&self, spendable_assets: &T) -> bool { + match *self { + Plan::Action(ref action) => action.spendable() == *spendable_assets, + Plan::Race(ref plan_a, ref plan_b) => { + plan_a.verify(spendable_assets) && plan_b.verify(spendable_assets) + } + Plan::After(_, ref plan) => plan.verify(spendable_assets), + } + } + + pub fn run_race(&mut self) -> bool { + let new_plan = if let Plan::Race(ref a, ref b) = *self { + if let Plan::Action(_) = **a { + Some((**a).clone()) + } else if let Plan::Action(_) = **b { + Some((**b).clone()) + } else { + None + } + } else { + None + }; + + if let Some(plan) = new_plan { + mem::replace(self, plan); + true + } else { + false + } + } + + pub fn process_verified_sig(&mut self, from: PublicKey) -> bool { + let mut new_plan = None; + match *self { + Plan::Action(_) => return true, + Plan::Race(ref mut plan_a, ref mut plan_b) => { + plan_a.process_verified_sig(from); + plan_b.process_verified_sig(from); + } + Plan::After(Condition::Signature(pubkey), ref plan) => { + if from == pubkey { + new_plan = Some((**plan).clone()); + } + } + _ => (), + } + if self.run_race() { + return true; + } + + if let Some(plan) = new_plan { + mem::replace(self, plan); + true + } else { + false + } + } + + pub fn process_verified_timestamp(&mut self, last_time: DateTime) -> bool { + let mut new_plan = None; + match *self { + Plan::Action(_) => return true, + Plan::Race(ref mut plan_a, ref mut plan_b) => { + plan_a.process_verified_timestamp(last_time); + plan_b.process_verified_timestamp(last_time); + } + Plan::After(Condition::Timestamp(dt), ref plan) => { + if dt <= last_time { + new_plan = Some((**plan).clone()); + } + } + _ => (), + } + if self.run_race() { + return true; + } + + if let Some(plan) = new_plan { + mem::replace(self, plan); + true + } else { + false + } + } +} diff --git a/src/transaction.rs b/src/transaction.rs index 0c42f1a15..b7e42b943 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -5,126 +5,7 @@ use serde::Serialize; use bincode::serialize; use hash::Hash; use chrono::prelude::*; -use std::mem; - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub enum Condition { - Timestamp(DateTime), - Signature(PublicKey), -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub enum Action { - Pay(Payment), -} - -impl Action { - pub fn spendable(&self) -> T { - match *self { - Action::Pay(ref payment) => payment.asset.clone(), - } - } -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub struct Payment { - pub asset: T, - pub to: PublicKey, -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub enum Plan { - Action(Action), - After(Condition, Box>), - Race(Box>, Box>), -} - -impl Plan { - pub fn verify(&self, spendable_assets: &T) -> bool { - match *self { - Plan::Action(ref action) => action.spendable() == *spendable_assets, - Plan::Race(ref plan_a, ref plan_b) => { - plan_a.verify(spendable_assets) && plan_b.verify(spendable_assets) - } - Plan::After(_, ref plan) => plan.verify(spendable_assets), - } - } - - pub fn run_race(&mut self) -> bool { - let new_plan = if let Plan::Race(ref a, ref b) = *self { - if let Plan::Action(_) = **a { - Some((**a).clone()) - } else if let Plan::Action(_) = **b { - Some((**b).clone()) - } else { - None - } - } else { - None - }; - - if let Some(plan) = new_plan { - mem::replace(self, plan); - true - } else { - false - } - } - - pub fn process_verified_sig(&mut self, from: PublicKey) -> bool { - let mut new_plan = None; - match *self { - Plan::Action(_) => return true, - Plan::Race(ref mut plan_a, ref mut plan_b) => { - plan_a.process_verified_sig(from); - plan_b.process_verified_sig(from); - } - Plan::After(Condition::Signature(pubkey), ref plan) => { - if from == pubkey { - new_plan = Some((**plan).clone()); - } - } - _ => (), - } - if self.run_race() { - return true; - } - - if let Some(plan) = new_plan { - mem::replace(self, plan); - true - } else { - false - } - } - - pub fn process_verified_timestamp(&mut self, last_time: DateTime) -> bool { - let mut new_plan = None; - match *self { - Plan::Action(_) => return true, - Plan::Race(ref mut plan_a, ref mut plan_b) => { - plan_a.process_verified_timestamp(last_time); - plan_b.process_verified_timestamp(last_time); - } - Plan::After(Condition::Timestamp(dt), ref plan) => { - if dt <= last_time { - new_plan = Some((**plan).clone()); - } - } - _ => (), - } - if self.run_race() { - return true; - } - - if let Some(plan) = new_plan { - mem::replace(self, plan); - true - } else { - false - } - } -} +use plan::{Action, Condition, Payment, Plan}; #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Transaction {