From 32fadc9c30a2091cb44c56e775a80a81ca0494e8 Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Wed, 17 Oct 2018 22:04:22 -0600 Subject: [PATCH] Merge debits and credits Debits no longer need to be applied before credits. Instead, we lock any accounts we'd debit and so error out on the second attempt to lock the same account. --- src/budget_program.rs | 40 ++++++---------------------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/src/budget_program.rs b/src/budget_program.rs index 144e1c7c08..ab75868c07 100644 --- a/src/budget_program.rs +++ b/src/budget_program.rs @@ -100,43 +100,16 @@ impl BudgetState { Ok(()) } - /// Deduct tokens from the source account if it has sufficient funds and the contract isn't - /// pending fn apply_debits_to_budget_state( - accounts: &mut [&mut Account], - instruction: &Instruction, - ) -> Result<(), BudgetError> { - { - // if the source account userdata is not empty, this is a pending contract - if !accounts[0].userdata.is_empty() { - trace!("source is pending"); - return Err(BudgetError::SourceIsPendingContract); - } - if let Instruction::NewBudget(tokens, _) = instruction { - if *tokens < 0 { - trace!("negative tokens"); - return Err(BudgetError::NegativeTokens); - } - - if accounts[0].tokens < *tokens { - trace!("insufficient funds"); - return Err(BudgetError::InsufficientFunds); - } else { - accounts[0].tokens -= *tokens; - } - }; - } - Ok(()) - } - - /// Apply only a transaction's credits. - /// Note: It is safe to apply credits from multiple transactions in parallel. - fn apply_credits_to_budget_state( tx: &Transaction, instruction_index: usize, accounts: &mut [&mut Account], instruction: &Instruction, ) -> Result<(), BudgetError> { + if !accounts[0].userdata.is_empty() { + trace!("source is pending"); + return Err(BudgetError::SourceIsPendingContract); + } match instruction { Instruction::NewBudget(tokens, budget) => { let budget = budget.clone(); @@ -151,6 +124,7 @@ impl BudgetState { } else { let mut state = BudgetState::default(); state.pending_budget = Some(budget); + accounts[0].tokens -= tokens; accounts[1].tokens += tokens; state.initialized = true; state.serialize(&mut accounts[1].userdata) @@ -246,9 +220,7 @@ impl BudgetState { ) -> Result<(), BudgetError> { if let Ok(instruction) = deserialize(tx.userdata(instruction_index)) { trace!("process_transaction: {:?}", instruction); - Self::apply_debits_to_budget_state(accounts, &instruction).and_then(|_| { - Self::apply_credits_to_budget_state(tx, instruction_index, accounts, &instruction) - }) + Self::apply_debits_to_budget_state(tx, instruction_index, accounts, &instruction) } else { info!( "Invalid transaction userdata: {:?}",