diff --git a/src/accountant.rs b/src/accountant.rs index 57284cac0c..a6685924e0 100644 --- a/src/accountant.rs +++ b/src/accountant.rs @@ -135,17 +135,6 @@ impl Accountant { } } - /// Return funds to the 'from' party. - fn cancel_transaction(self: &mut Self, plan: &Plan) { - if let Plan::Race(_, ref cancel_plan) = *plan { - if let Plan::After(_, Action::Pay(ref payment)) = **cancel_plan { - if let Some(x) = self.balances.get_mut(&payment.to) { - *x += payment.asset; - } - } - } - } - // TODO: Move this to transaction.rs fn all_satisfied(&self, plan: &Plan) -> bool { match *plan { @@ -183,30 +172,18 @@ impl Accountant { } fn process_verified_sig(&mut self, from: PublicKey, tx_sig: Signature) -> Result<()> { - let mut cancel = false; - if let Some(plan) = self.pending.get(&tx_sig) { - // Cancel: - // if Signature(from) is in unless_any, return funds to tx.from, and remove the tx from this map. + let actionable = if let Some(plan) = self.pending.get_mut(&tx_sig) { + plan.process_verified_sig(from) + } else { + false + }; - // TODO: Use find(). - if let Plan::Race(_, ref plan_b) = *plan { - if let Plan::After(Condition::Signature(pubkey), _) = **plan_b { - if from == pubkey { - cancel = true; - } - } - } - } - - if cancel { + if actionable { if let Some(plan) = self.pending.remove(&tx_sig) { - self.cancel_transaction(&plan); + self.complete_transaction(&plan); } } - // 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(()) } @@ -224,11 +201,6 @@ impl Accountant { } else { return Ok(()); } - // 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. // Check to see if any timelocked transactions can be completed. let mut completed = vec![]; @@ -244,11 +216,6 @@ impl Accountant { } } } - // TODO: Add this in once we start removing constraints - //if tr.plan.if_all.0.is_empty() { - // // TODO: Remove tr from pending - // self.complete_transaction(plan); - //} } for key in completed { diff --git a/src/transaction.rs b/src/transaction.rs index f606c4b3ac..8593991382 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -5,6 +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 { @@ -30,6 +31,55 @@ pub enum Plan { Race(Box>, Box>), } +impl Plan { + 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::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 action) => { + if from == pubkey { + new_plan = Some(Plan::Action(action.clone())); + } + } + _ => (), + } + if self.run_race() { + return true; + } + + if let Some(plan) = new_plan { + mem::replace(self, plan); + true + } else { + false + } + } +} + #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Transaction { pub from: PublicKey,