Преглед на файлове

Fix SQLite race condition

Bug: https://github.com/crodas/cdk/actions/runs/15732950296/job/44339804072#step:5:1853

Reason: When melting in parallel, many update the melt status and attempt to
add proofs and they fail when adding the proof and the rollback code kicks in.
The loser process removes all the proofs, and the winner process has no proof
later on.

Fix: Modify `update_melt_quote_state` requirements and implementation to allow
only one winner.

This will be solved by design with a transaction writer trait
Cesar Rodas преди 1 седмица
родител
ревизия
a681c6e054
променени са 2 файла, в които са добавени 5 реда и са изтрити 1 реда
  1. 3 1
      crates/cdk-common/src/database/mint/mod.rs
  2. 2 0
      crates/cdk-sqlite/src/mint/mod.rs

+ 3 - 1
crates/cdk-common/src/database/mint/mod.rs

@@ -84,10 +84,12 @@ pub trait QuotesDatabase {
     /// Get [`mint::MeltQuote`]
     async fn get_melt_quote(&self, quote_id: &Uuid) -> Result<Option<mint::MeltQuote>, Self::Err>;
     /// Update [`mint::MeltQuote`] state
+    ///
+    /// It is expected for this function to fail if the state is already set to the new state
     async fn update_melt_quote_state(
         &self,
         quote_id: &Uuid,
-        state: MeltQuoteState,
+        new_state: MeltQuoteState,
     ) -> Result<(MeltQuoteState, mint::MeltQuote), Self::Err>;
     /// Get all [`mint::MeltQuote`]s
     async fn get_melt_quotes(&self) -> Result<Vec<mint::MeltQuote>, Self::Err>;

+ 2 - 0
crates/cdk-sqlite/src/mint/mod.rs

@@ -696,9 +696,11 @@ ON CONFLICT(request_lookup_id) DO UPDATE SET
                 melt_quote
             WHERE
                 id=:id
+                AND state != :state
             "#,
         )
         .bind(":id", quote_id.as_hyphenated().to_string())
+        .bind(":state", state.to_string())
         .fetch_one(&transaction)
         .await?
         .map(sqlite_row_to_melt_quote)