Sfoglia il codice sorgente

Don't accept db transactions from external

Cesar Rodas 4 settimane fa
parent
commit
e93189911c

+ 4 - 1
crates/cdk-cli/src/sub_commands/check_pending.rs

@@ -28,7 +28,10 @@ pub async fn check_pending(multi_mint_wallet: &MultiMintWallet) -> Result<()> {
         );
 
         // Try to reclaim any proofs that are no longer pending
-        match wallet.reclaim_unspent(&mut tx, pending_proofs).await {
+        match wallet
+            .reclaim_unspent_with_tx(&mut tx, pending_proofs)
+            .await
+        {
             Ok(()) => println!("Successfully reclaimed pending proofs"),
             Err(e) => println!("Error reclaimed pending proofs: {e}"),
         }

+ 3 - 1
crates/cdk-ffi/src/database.rs

@@ -364,7 +364,9 @@ impl<'a> cdk::cdk_database::WalletDatabaseTransaction<'a, cdk::cdk_database::Err
             .into_iter()
             .map(|info| {
                 Ok::<cdk::types::ProofInfo, cdk::cdk_database::Error>(cdk::types::ProofInfo {
-                    proof: info.proof.inner.clone(),
+                    proof: info.proof.try_into().map_err(|e: FfiError| {
+                        cdk::cdk_database::Error::Database(e.to_string().into())
+                    })?,
                     y: info.y.try_into().map_err(|e: FfiError| {
                         cdk::cdk_database::Error::Database(e.to_string().into())
                     })?,

+ 2 - 3
crates/cdk-ffi/src/wallet.rs

@@ -126,9 +126,9 @@ impl Wallet {
         let mut tx = self.inner.localstore.begin_db_transaction().await?;
         let amount = self
             .inner
-            .receive_proofs(&mut tx, cdk_proofs, options.into(), memo)
+            .receive_proofs_with_tx(&mut tx, cdk_proofs, options.into(), memo)
             .await?;
-        Box::new(tx).commit().await?;
+        tx.commit().await?;
         Ok(amount.into())
     }
 
@@ -255,7 +255,6 @@ impl Wallet {
         let result = self
             .inner
             .swap(
-                None,
                 amount.map(Into::into),
                 amount_split_target.into(),
                 cdk_proofs,

+ 0 - 1
crates/cdk-integration-tests/src/lib.rs

@@ -79,7 +79,6 @@ pub async fn attempt_to_swap_pending(wallet: &Wallet) -> Result<()> {
     let swap = wallet
         .swap(
             None,
-            None,
             SplitTarget::None,
             pending.into_iter().map(|p| p.proof).collect(),
             None,

+ 3 - 13
crates/cdk-integration-tests/tests/bolt12.rs

@@ -325,11 +325,7 @@ async fn test_regtest_bolt12_mint_extra() -> Result<()> {
     // Create a single-use BOLT12 quote
     let mint_quote = wallet.mint_bolt12_quote(None, None).await?;
 
-    let mut tx = wallet.localstore.begin_db_transaction().await?;
-    let state = wallet
-        .mint_bolt12_quote_state(&mut tx, &mint_quote.id)
-        .await?;
-    tx.commit().await?;
+    let state = wallet.mint_bolt12_quote_state(&mint_quote.id).await?;
 
     assert_eq!(state.amount_paid, Amount::ZERO);
     assert_eq!(state.amount_issued, Amount::ZERO);
@@ -350,11 +346,7 @@ async fn test_regtest_bolt12_mint_extra() -> Result<()> {
         .await?
         .unwrap();
 
-    let mut tx = wallet.localstore.begin_db_transaction().await?;
-    let state = wallet
-        .mint_bolt12_quote_state(&mint_quote.id, &mut tx)
-        .await?;
-    tx.commit().await?;
+    let state = wallet.mint_bolt12_quote_state(&mint_quote.id).await?;
 
     assert_eq!(payment, state.amount_paid);
     assert_eq!(state.amount_paid, (pay_amount_msats / 1_000).into());
@@ -444,12 +436,10 @@ async fn test_attempt_to_mint_unpaid() {
         .await
         .unwrap();
 
-    let mut tx = wallet.localstore.begin_db_transaction().await.expect("tx");
     let state = wallet
-        .mint_bolt12_quote_state(&mut tx, &mint_quote.id)
+        .mint_bolt12_quote_state(&mint_quote.id)
         .await
         .unwrap();
-    tx.commit().await.expect("commit");
 
     assert!(state.amount_paid == Amount::ZERO);
 

+ 0 - 1
crates/cdk-integration-tests/tests/fake_auth.rs

@@ -373,7 +373,6 @@ async fn test_swap_with_auth() {
 
     let swapped_proofs = wallet
         .swap(
-            None,
             Some(proofs.total_amount().unwrap()),
             SplitTarget::default(),
             proofs.clone(),

+ 1 - 1
crates/cdk-integration-tests/tests/happy_path_mint_wallet.rs

@@ -324,7 +324,7 @@ async fn test_restore() {
 
     let expected_fee = wallet.get_proofs_fee(None, &proofs).await.unwrap();
     wallet_2
-        .swap(None, None, SplitTarget::default(), proofs, None, false)
+        .swap(None, SplitTarget::default(), proofs, None, false)
         .await
         .unwrap();
 

+ 2 - 2
crates/cdk-integration-tests/tests/integration_tests_pure.rs

@@ -132,7 +132,7 @@ async fn test_swap_to_send() {
         .await
         .expect("valid begin tx");
     let received_amount = wallet_carol
-        .receive_proofs(
+        .receive_proofs_with_tx(
             &mut tx,
             token_proofs.clone(),
             ReceiveOptions::default(),
@@ -778,7 +778,7 @@ async fn test_mint_change_with_fee_melt() {
         .await
         .unwrap();
     let w = wallet_alice
-        .melt_proofs_with_metadata(&mut tx, &melt_quote.id, proofs, HashMap::new())
+        .melt_proofs_with_metadata_with_tx(&mut tx, &melt_quote.id, proofs, HashMap::new())
         .await
         .unwrap();
     tx.commit().await.unwrap();

+ 1 - 3
crates/cdk-integration-tests/tests/test_fees.rs

@@ -110,12 +110,10 @@ async fn test_fake_melt_change_in_quote() {
 
     let fee = wallet.get_proofs_fee(None, &proofs).await.unwrap();
 
-    let mut tx = wallet.localstore.begin_db_transaction().await.unwrap();
     let melt = wallet
-        .melt_proofs_with_metadata(&mut tx, &melt_quote.id, proofs, HashMap::new())
+        .melt_proofs_with_metadata(&melt_quote.id, proofs, HashMap::new())
         .await
         .unwrap();
-    tx.commit().await.unwrap();
 
     let change = melt.change.unwrap().total_amount().unwrap();
     let idk = proofs_total - Amount::from(invoice_amount) - change;

+ 17 - 2
crates/cdk/src/wallet/issue/issue_bolt12.rs

@@ -114,7 +114,9 @@ impl Wallet {
             None => {
                 // If an amount it not supplied with check the status of the quote
                 // The mint will tell us how much can be minted
-                let state = self.mint_bolt12_quote_state(&mut tx, quote_id).await?;
+                let state = self
+                    .mint_bolt12_quote_state_with_tx(&mut tx, quote_id)
+                    .await?;
 
                 state.amount_paid - state.amount_issued
             }
@@ -248,9 +250,22 @@ impl Wallet {
     }
 
     /// Check mint quote status
-    #[instrument(skip(self, tx, quote_id))]
     pub async fn mint_bolt12_quote_state(
         &self,
+        quote_id: &str,
+    ) -> Result<MintQuoteBolt12Response<String>, Error> {
+        let mut tx = self.localstore.begin_db_transaction().await?;
+        let result = self
+            .mint_bolt12_quote_state_with_tx(&mut tx, quote_id)
+            .await?;
+        tx.commit().await?;
+        Ok(result)
+    }
+
+    /// Check mint quote status with transaction
+    #[instrument(skip(self, tx, quote_id))]
+    pub async fn mint_bolt12_quote_state_with_tx(
+        &self,
         tx: &mut Tx<'_, '_>,
         quote_id: &str,
     ) -> Result<MintQuoteBolt12Response<String>, Error> {

+ 20 - 5
crates/cdk/src/wallet/melt/melt_bolt11.rs

@@ -132,9 +132,24 @@ impl Wallet {
     }
 
     /// Melt specific proofs
-    #[instrument(skip(self, tx, proofs))]
     pub async fn melt_proofs_with_metadata(
         &self,
+        quote_id: &str,
+        proofs: Proofs,
+        metadata: HashMap<String, String>,
+    ) -> Result<Melted, Error> {
+        let mut tx = self.localstore.begin_db_transaction().await?;
+        let result = self
+            .melt_proofs_with_metadata_with_tx(&mut tx, quote_id, proofs, metadata)
+            .await?;
+        tx.commit().await?;
+        Ok(result)
+    }
+
+    /// Melt specific proofs with transaction
+    #[instrument(skip(self, tx, proofs))]
+    pub async fn melt_proofs_with_metadata_with_tx(
+        &self,
         tx: &mut Tx<'_, '_>,
         quote_id: &str,
         proofs: Proofs,
@@ -211,7 +226,7 @@ impl Wallet {
                 tracing::error!("Could not melt: {}", err);
                 tracing::info!("Checking status of input proofs.");
 
-                self.reclaim_unspent(tx, proofs).await?;
+                self.reclaim_unspent_with_tx(tx, proofs).await?;
 
                 return Err(err);
             }
@@ -399,8 +414,8 @@ impl Wallet {
 
         if let Some((proof, exact_amount)) = exchange.take() {
             let new_proofs = self
-                .swap(
-                    Some(&mut tx),
+                .swap_with_tx(
+                    &mut tx,
                     Some(exact_amount),
                     SplitTarget::None,
                     vec![proof],
@@ -417,7 +432,7 @@ impl Wallet {
         }
 
         let melted = self
-            .melt_proofs_with_metadata(&mut tx, quote_id, input_proofs, metadata)
+            .melt_proofs_with_metadata_with_tx(&mut tx, quote_id, input_proofs, metadata)
             .await?;
 
         tx.commit().await?;

+ 2 - 10
crates/cdk/src/wallet/multi_mint_wallet.rs

@@ -1176,7 +1176,7 @@ impl MultiMintWallet {
         let mut tx = self.localstore.begin_db_transaction().await?;
 
         match wallet
-            .receive_proofs(
+            .receive_proofs_with_tx(
                 &mut tx,
                 proofs,
                 opts.receive_options,
@@ -1544,14 +1544,7 @@ impl MultiMintWallet {
                 let proofs = wallet.get_unspent_proofs().await?;
                 if !proofs.is_empty() {
                     return wallet
-                        .swap(
-                            None,
-                            amount,
-                            SplitTarget::default(),
-                            proofs,
-                            conditions,
-                            false,
-                        )
+                        .swap(amount, SplitTarget::default(), proofs, conditions, false)
                         .await;
                 }
             }
@@ -1577,7 +1570,6 @@ impl MultiMintWallet {
                 // Swap for optimized proof set
                 match wallet
                     .swap(
-                        None,
                         Some(proofs_amount),
                         SplitTarget::default(),
                         proofs,

+ 16 - 2
crates/cdk/src/wallet/proofs.rs

@@ -92,8 +92,22 @@ impl Wallet {
     /// Reclaim unspent proofs
     ///
     /// Checks the stats of [`Proofs`] swapping for a new [`Proof`] if unspent
+    pub async fn reclaim_unspent(&self, proofs: Proofs) -> Result<(), Error> {
+        let mut tx = self.localstore.begin_db_transaction().await?;
+        self.reclaim_unspent_with_tx(&mut tx, proofs).await?;
+        tx.commit().await?;
+        Ok(())
+    }
+
+    /// Reclaim unspent proofs with transaction
+    ///
+    /// Checks the stats of [`Proofs`] swapping for a new [`Proof`] if unspent
     #[instrument(skip(self, tx, proofs))]
-    pub async fn reclaim_unspent(&self, tx: &mut Tx<'_, '_>, proofs: Proofs) -> Result<(), Error> {
+    pub async fn reclaim_unspent_with_tx(
+        &self,
+        tx: &mut Tx<'_, '_>,
+        proofs: Proofs,
+    ) -> Result<(), Error> {
         let proof_ys = proofs.ys()?;
 
         let transaction_id = TransactionId::new(proof_ys.clone());
@@ -110,7 +124,7 @@ impl Wallet {
             .filter_map(|(p, s)| (s.state == State::Unspent).then_some(p))
             .collect();
 
-        self.swap(Some(tx), None, SplitTarget::default(), unspent, None, false)
+        self.swap_with_tx(tx, None, SplitTarget::default(), unspent, None, false)
             .await?;
 
         match tx.remove_transaction(transaction_id).await {

+ 18 - 3
crates/cdk/src/wallet/receive.rs

@@ -20,9 +20,24 @@ use crate::{ensure_cdk, Amount, Error, Wallet, SECP256K1};
 
 impl Wallet {
     /// Receive proofs
-    #[instrument(skip_all)]
     pub async fn receive_proofs(
         &self,
+        proofs: Proofs,
+        opts: ReceiveOptions,
+        memo: Option<String>,
+    ) -> Result<Amount, Error> {
+        let mut tx = self.localstore.begin_db_transaction().await?;
+        let result = self
+            .receive_proofs_with_tx(&mut tx, proofs, opts, memo)
+            .await?;
+        tx.commit().await?;
+        Ok(result)
+    }
+
+    /// Receive proofs with transaction
+    #[instrument(skip_all)]
+    pub async fn receive_proofs_with_tx(
+        &self,
         tx: &mut Tx<'_, '_>,
         proofs: Proofs,
         opts: ReceiveOptions,
@@ -117,7 +132,7 @@ impl Wallet {
         tx.update_proofs(proofs_info.clone(), vec![]).await?;
 
         let mut pre_swap = self
-            .create_swap(tx, None, opts.amount_split_target, proofs, None, false)
+            .create_swap_with_tx(tx, None, opts.amount_split_target, proofs, None, false)
             .await?;
 
         if sig_flag.eq(&SigFlag::SigAll) {
@@ -222,7 +237,7 @@ impl Wallet {
         let mut tx = self.localstore.begin_db_transaction().await?;
 
         let amount = self
-            .receive_proofs(&mut tx, proofs, opts, token.memo().clone())
+            .receive_proofs_with_tx(&mut tx, proofs, opts, token.memo().clone())
             .await?;
 
         tx.commit().await?;

+ 2 - 2
crates/cdk/src/wallet/send.rs

@@ -291,8 +291,8 @@ impl PreparedSend {
             tracing::debug!("Swapping proofs; swap_amount={:?}", swap_amount);
             if let Some(proofs) = self
                 .wallet
-                .swap(
-                    Some(&mut tx),
+                .swap_with_tx(
+                    &mut tx,
                     Some(swap_amount),
                     SplitTarget::None,
                     self.proofs_to_swap,

+ 57 - 25
crates/cdk/src/wallet/swap.rs

@@ -28,7 +28,7 @@ impl Wallet {
         let unit = &self.unit;
 
         let pre_swap = self
-            .create_swap(
+            .create_swap_with_tx(
                 tx,
                 amount,
                 amount_split_target.clone(),
@@ -140,43 +140,51 @@ impl Wallet {
     }
 
     /// Swap
-    #[instrument(skip(self, tx, input_proofs))]
     pub async fn swap(
         &self,
-        tx: Option<&mut Tx<'_, '_>>,
         amount: Option<Amount>,
         amount_split_target: SplitTarget,
         input_proofs: Proofs,
         spending_conditions: Option<SpendingConditions>,
         include_fees: bool,
     ) -> Result<Option<Proofs>, Error> {
-        if let Some(tx) = tx {
-            self.swap_inner(
-                tx,
+        let mut tx = self.localstore.begin_db_transaction().await?;
+        let ret = self
+            .swap_with_tx(
+                &mut tx,
                 amount,
                 amount_split_target,
                 input_proofs,
                 spending_conditions,
                 include_fees,
             )
-            .await
-        } else {
-            let mut tx = self.localstore.begin_db_transaction().await?;
-            let ret = self
-                .swap_inner(
-                    &mut tx,
-                    amount,
-                    amount_split_target,
-                    input_proofs,
-                    spending_conditions,
-                    include_fees,
-                )
-                .await?;
+            .await?;
 
-            tx.commit().await?;
+        tx.commit().await?;
 
-            Ok(ret)
-        }
+        Ok(ret)
+    }
+
+    /// Swap with transaction
+    #[instrument(skip(self, tx, input_proofs))]
+    pub async fn swap_with_tx(
+        &self,
+        tx: &mut Tx<'_, '_>,
+        amount: Option<Amount>,
+        amount_split_target: SplitTarget,
+        input_proofs: Proofs,
+        spending_conditions: Option<SpendingConditions>,
+        include_fees: bool,
+    ) -> Result<Option<Proofs>, Error> {
+        self.swap_inner(
+            tx,
+            amount,
+            amount_split_target,
+            input_proofs,
+            spending_conditions,
+            include_fees,
+        )
+        .await
     }
 
     /// Swap from unspent proofs in db
@@ -225,8 +233,8 @@ impl Wallet {
         )?;
 
         let to_return = self
-            .swap(
-                Some(&mut tx),
+            .swap_with_tx(
+                &mut tx,
                 Some(amount),
                 SplitTarget::default(),
                 proofs,
@@ -242,9 +250,33 @@ impl Wallet {
     }
 
     /// Create Swap Payload
-    #[instrument(skip(self, tx, proofs))]
     pub async fn create_swap(
         &self,
+        amount: Option<Amount>,
+        amount_split_target: SplitTarget,
+        proofs: Proofs,
+        spending_conditions: Option<SpendingConditions>,
+        include_fees: bool,
+    ) -> Result<PreSwap, Error> {
+        let mut tx = self.localstore.begin_db_transaction().await?;
+        let result = self
+            .create_swap_with_tx(
+                &mut tx,
+                amount,
+                amount_split_target,
+                proofs,
+                spending_conditions,
+                include_fees,
+            )
+            .await?;
+        tx.commit().await?;
+        Ok(result)
+    }
+
+    /// Create Swap Payload with transaction
+    #[instrument(skip(self, tx, proofs))]
+    pub async fn create_swap_with_tx(
+        &self,
         tx: &mut Tx<'_, '_>,
         amount: Option<Amount>,
         amount_split_target: SplitTarget,

+ 1 - 1
crates/cdk/src/wallet/transactions.rs

@@ -53,7 +53,7 @@ impl Wallet {
             })
             .collect::<Vec<_>>();
 
-        self.reclaim_unspent(&mut db_tx, pending_spent_proofs)
+        self.reclaim_unspent_with_tx(&mut db_tx, pending_spent_proofs)
             .await?;
 
         db_tx.commit().await?;