Bläddra i källkod

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 vecka sedan
förälder
incheckning
a681c6e054
2 ändrade filer med 5 tillägg och 1 borttagningar
  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)