ledger_mempool.rs (3690B)
1 use anyhow::{Result, bail}; 2 3 use super::ledger_ops::{ 4 apply_transaction, spend_blinded_inputs, spend_inputs, transaction_has_missing_inputs, 5 }; 6 use super::transaction::{ 7 BlindedReveal, BlindedTransaction, Transaction, blinded_transaction_inputs_spent_by, 8 transaction_inputs_spent_by, transaction_inputs_spent_by_inputs, 9 }; 10 use super::{Ledger, MAX_ORPHAN_TRANSACTIONS, MAX_PENDING_TRANSACTIONS, TransactionSubmitOutcome}; 11 12 impl Ledger { 13 pub fn submit_transaction(&mut self, transaction: Transaction) -> Result<bool> { 14 Ok(self.submit_transaction_with_outcome(transaction)?.added()) 15 } 16 17 pub(crate) fn reserve_transaction_inputs(&mut self, transaction: &Transaction) -> Result<()> { 18 self.validate_new_transaction(transaction)?; 19 let mut utxos = self.utxos.clone(); 20 spend_inputs(transaction, &mut utxos)?; 21 self.utxos = utxos; 22 Ok(()) 23 } 24 25 pub fn submit_blinded_transaction(&mut self, transaction: BlindedTransaction) -> Result<bool> { 26 if self.has_blinded_transaction(&transaction.commitment) { 27 return Ok(false); 28 } 29 self.validate_blinded_transaction(&transaction)?; 30 if blinded_transaction_inputs_spent_by(&transaction, &self.pending_blinded) 31 || transaction_inputs_spent_by_inputs(&transaction.inputs, &self.pending) 32 || transaction_inputs_spent_by_inputs(&transaction.inputs, &self.orphans) 33 { 34 bail!("blinded transaction conflicts with pending inputs"); 35 } 36 let mut utxos = self.utxos_after_valid_pending_and_blinded()?; 37 spend_blinded_inputs(&transaction, &mut utxos)?; 38 if self.pending_blinded.len() >= MAX_PENDING_TRANSACTIONS { 39 bail!("blinded mempool is full"); 40 } 41 self.pending_blinded.push(transaction); 42 Ok(true) 43 } 44 45 pub fn submit_blinded_reveal(&mut self, reveal: BlindedReveal) -> Result<bool> { 46 if self.has_blinded_reveal(&reveal.commitment) { 47 return Ok(false); 48 } 49 self.validate_blinded_reveal_terms(&reveal)?; 50 if self.pending_reveals.len() >= MAX_PENDING_TRANSACTIONS { 51 bail!("blinded reveal pool is full"); 52 } 53 self.pending_reveals.push(reveal); 54 Ok(true) 55 } 56 57 pub fn submit_transaction_with_outcome( 58 &mut self, 59 transaction: Transaction, 60 ) -> Result<TransactionSubmitOutcome> { 61 if self.has_transaction(transaction.signature()) { 62 return Ok(TransactionSubmitOutcome::AlreadyKnown); 63 } 64 65 transaction.verify_signature()?; 66 self.validate_transaction_terms(&transaction)?; 67 self.validate_mine_anchor_available(&transaction)?; 68 69 if transaction_inputs_spent_by(&transaction, &self.pending) { 70 return Ok(TransactionSubmitOutcome::ConflictsWithPending); 71 } 72 if transaction_inputs_spent_by(&transaction, &self.orphans) { 73 return Ok(TransactionSubmitOutcome::ConflictsWithPending); 74 } 75 76 if self.pending.len() >= MAX_PENDING_TRANSACTIONS { 77 bail!("mempool is full"); 78 } 79 80 let mut utxos = self.utxos_after_valid_pending_and_blinded()?; 81 if transaction_has_missing_inputs(&transaction, &utxos) { 82 if self.orphans.len() >= MAX_ORPHAN_TRANSACTIONS { 83 bail!("orphan transaction pool is full"); 84 } 85 self.orphans.push(transaction); 86 return Ok(TransactionSubmitOutcome::Added); 87 } 88 apply_transaction(&transaction, &mut utxos)?; 89 self.pending.push(transaction); 90 self.promote_orphan_transactions()?; 91 Ok(TransactionSubmitOutcome::Added) 92 } 93 }