浏览代码

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)