Forráskód Böngészése

Revert changes in sql-common

Cesar Rodas 4 napja
szülő
commit
37fba7c2c6

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

@@ -107,10 +107,10 @@ async fn test_correct_keyset() {
 /// should gracefully handle the duplicate and return a Duplicate error.
 #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
 async fn test_concurrent_duplicate_payment_handling() {
+    use cashu::PaymentMethod;
     use cdk::cdk_database::{MintDatabase, MintQuotesDatabase};
     use cdk::mint::MintQuote;
     use cdk::Amount;
-    use cashu::PaymentMethod;
     use cdk_common::payment::PaymentIdentifier;
     use tokio::task::JoinSet;
 

+ 42 - 40
crates/cdk-sql-common/src/mint/mod.rs

@@ -765,8 +765,25 @@ where
             return Err(Error::Duplicate);
         }
 
-        // Step 1: Lock the mint_quote row FIRST to prevent deadlocks
-        // This establishes a consistent lock ordering across all transactions
+        // Check if payment_id already exists in mint_quote_payments
+        let exists = query(
+            r#"
+            SELECT payment_id
+            FROM mint_quote_payments
+            WHERE payment_id = :payment_id
+            FOR UPDATE
+            "#,
+        )?
+        .bind("payment_id", payment_id.clone())
+        .fetch_one(&self.inner)
+        .await?;
+
+        if exists.is_some() {
+            tracing::error!("Payment ID already exists: {}", payment_id);
+            return Err(database::Error::Duplicate);
+        }
+
+        // Get current amount_paid from quote
         let current_amount = query(
             r#"
             SELECT amount_paid
@@ -779,7 +796,7 @@ where
         .fetch_one(&self.inner)
         .await
         .inspect_err(|err| {
-            tracing::error!("Could not get mint quote amount_paid: {}", err);
+            tracing::error!("SQLite could not get mint quote amount_paid: {}", err);
         })?;
 
         let current_amount_paid = if let Some(current_amount) = current_amount {
@@ -789,41 +806,7 @@ where
             Amount::ZERO
         };
 
-        // Step 2: Try to insert payment_id - this will fail fast if it's a duplicate
-        // The UNIQUE constraint on payment_id will prevent duplicate insertions atomically
-        let insert_result = query(
-            r#"
-            INSERT INTO mint_quote_payments
-            (quote_id, payment_id, amount, timestamp)
-            VALUES (:quote_id, :payment_id, :amount, :timestamp)
-            "#,
-        )?
-        .bind("quote_id", quote_id.to_string())
-        .bind("payment_id", payment_id.clone())
-        .bind("amount", amount_paid.to_i64())
-        .bind("timestamp", unix_time() as i64)
-        .execute(&self.inner)
-        .await;
-
-        // Check if insert failed due to duplicate payment_id
-        match insert_result {
-            Ok(_) => {
-                // Insert succeeded - now safe to update the amount
-            }
-            Err(err) => {
-                // Check if error is due to UNIQUE constraint violation
-                let err_msg = err.to_string().to_lowercase();
-                if err_msg.contains("unique") || err_msg.contains("duplicate") {
-                    tracing::debug!("Payment ID already processed: {}", payment_id);
-                    return Err(database::Error::Duplicate);
-                } else {
-                    tracing::error!("Could not insert payment ID: {}", err);
-                    return Err(err);
-                }
-            }
-        }
-
-        // Step 3: Calculate new amount_paid with overflow check
+        // Calculate new amount_paid with overflow check
         let new_amount_paid = current_amount_paid
             .checked_add(amount_paid)
             .ok_or_else(|| database::Error::AmountOverflow)?;
@@ -835,7 +818,7 @@ where
             new_amount_paid
         );
 
-        // Step 4: Update the amount_paid
+        // Update the amount_paid
         query(
             r#"
             UPDATE mint_quote
@@ -848,7 +831,26 @@ where
         .execute(&self.inner)
         .await
         .inspect_err(|err| {
-            tracing::error!("Could not update mint quote amount_paid: {}", err);
+            tracing::error!("SQLite could not update mint quote amount_paid: {}", err);
+        })?;
+
+        // Add payment_id to mint_quote_payments table
+        query(
+            r#"
+            INSERT INTO mint_quote_payments
+            (quote_id, payment_id, amount, timestamp)
+            VALUES (:quote_id, :payment_id, :amount, :timestamp)
+            "#,
+        )?
+        .bind("quote_id", quote_id.to_string())
+        .bind("payment_id", payment_id)
+        .bind("amount", amount_paid.to_i64())
+        .bind("timestamp", unix_time() as i64)
+        .execute(&self.inner)
+        .await
+        .map_err(|err| {
+            tracing::error!("SQLite could not insert payment ID: {}", err);
+            err
         })?;
 
         Ok(new_amount_paid)

+ 1 - 2
crates/cdk/src/mint/ln.rs

@@ -3,12 +3,11 @@ use std::sync::Arc;
 
 use cdk_common::amount::to_unit;
 use cdk_common::common::PaymentProcessorKey;
-use cdk_common::database;
 use cdk_common::database::DynMintDatabase;
 use cdk_common::mint::MintQuote;
 use cdk_common::payment::DynMintPayment;
 use cdk_common::util::unix_time;
-use cdk_common::{Amount, MintQuoteState, PaymentMethod};
+use cdk_common::{database, Amount, MintQuoteState, PaymentMethod};
 use tracing::instrument;
 
 use super::subscription::PubSubManager;