Răsfoiți Sursa

Merge pull request #577 from thesimplekid/fix_mint_delete_unspent

Fix mint delete unspent
thesimplekid 1 lună în urmă
părinte
comite
609840a0df

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

@@ -86,8 +86,14 @@ pub trait Database {
     /// Get [`MintKeySetInfo`]s
     async fn get_keyset_infos(&self) -> Result<Vec<MintKeySetInfo>, Self::Err>;
 
-    /// Add spent [`Proofs`]
+    /// Add  [`Proofs`]
     async fn add_proofs(&self, proof: Proofs, quote_id: Option<Uuid>) -> Result<(), Self::Err>;
+    /// Remove [`Proofs`]
+    async fn remove_proofs(
+        &self,
+        ys: &[PublicKey],
+        quote_id: Option<Uuid>,
+    ) -> Result<(), Self::Err>;
     /// Get [`Proofs`] by ys
     async fn get_proofs_by_ys(&self, ys: &[PublicKey]) -> Result<Vec<Option<Proof>>, Self::Err>;
     /// Get ys by quote id

+ 41 - 0
crates/cdk-redb/src/mint/mod.rs

@@ -534,6 +534,47 @@ impl MintDatabase for MintRedbDatabase {
         Ok(())
     }
 
+    async fn remove_proofs(
+        &self,
+        ys: &[PublicKey],
+        quote_id: Option<Uuid>,
+    ) -> Result<(), Self::Err> {
+        let write_txn = self.db.begin_write().map_err(Error::from)?;
+
+        {
+            let mut proofs_table = write_txn.open_table(PROOFS_TABLE).map_err(Error::from)?;
+
+            for y in ys {
+                proofs_table.remove(&y.to_bytes()).map_err(Error::from)?;
+            }
+        }
+
+        {
+            let mut proof_state_table = write_txn
+                .open_table(PROOFS_STATE_TABLE)
+                .map_err(Error::from)?;
+            for y in ys {
+                proof_state_table
+                    .remove(&y.to_bytes())
+                    .map_err(Error::from)?;
+            }
+        }
+
+        if let Some(quote_id) = quote_id {
+            let mut quote_proofs_table = write_txn
+                .open_multimap_table(QUOTE_PROOFS_TABLE)
+                .map_err(Error::from)?;
+
+            quote_proofs_table
+                .remove_all(quote_id.as_bytes())
+                .map_err(Error::from)?;
+        }
+
+        write_txn.commit().map_err(Error::from)?;
+
+        Ok(())
+    }
+
     async fn get_proofs_by_ys(&self, ys: &[PublicKey]) -> Result<Vec<Option<Proof>>, Self::Err> {
         let read_txn = self.db.begin_read().map_err(Error::from)?;
         let table = read_txn.open_table(PROOFS_TABLE).map_err(Error::from)?;

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

@@ -780,6 +780,33 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?);
         Ok(())
     }
 
+    async fn remove_proofs(
+        &self,
+        ys: &[PublicKey],
+        _quote_id: Option<Uuid>,
+    ) -> Result<(), Self::Err> {
+        let mut transaction = self.pool.begin().await.map_err(Error::from)?;
+
+        let sql = format!(
+            "DELETE FROM proof WHERE y IN ({})",
+            std::iter::repeat("?")
+                .take(ys.len())
+                .collect::<Vec<_>>()
+                .join(",")
+        );
+
+        ys.iter()
+            .fold(sqlx::query(&sql), |query, y| {
+                query.bind(y.to_bytes().to_vec())
+            })
+            .execute(&mut transaction)
+            .await
+            .map_err(Error::from)?;
+
+        transaction.commit().await.map_err(Error::from)?;
+        Ok(())
+    }
+
     async fn get_proofs_by_ys(&self, ys: &[PublicKey]) -> Result<Vec<Option<Proof>>, Self::Err> {
         let mut transaction = self.pool.begin().await.map_err(Error::from)?;
 

+ 29 - 0
crates/cdk/src/cdk_database/mint_memory.rs

@@ -284,6 +284,35 @@ impl MintDatabase for MintMemoryDatabase {
         Ok(())
     }
 
+    async fn remove_proofs(
+        &self,
+        ys: &[PublicKey],
+        quote_id: Option<Uuid>,
+    ) -> Result<(), Self::Err> {
+        {
+            let mut db_proofs = self.proofs.write().await;
+
+            ys.iter().for_each(|y| {
+                db_proofs.remove(&y.to_bytes());
+            });
+        }
+
+        {
+            let mut db_proofs_state = self.proof_state.lock().await;
+
+            ys.iter().for_each(|y| {
+                db_proofs_state.remove(&y.to_bytes());
+            });
+        }
+
+        if let Some(quote_id) = quote_id {
+            let mut quote_proofs = self.quote_proofs.lock().await;
+            quote_proofs.remove(&quote_id);
+        }
+
+        Ok(())
+    }
+
     async fn get_proofs_by_ys(&self, ys: &[PublicKey]) -> Result<Vec<Option<Proof>>, Self::Err> {
         let spent_proofs = self.proofs.read().await;
 

+ 1 - 1
crates/cdk/src/mint/melt.rs

@@ -385,7 +385,7 @@ impl Mint {
         let input_ys = melt_request.inputs.ys()?;
 
         self.localstore
-            .update_proofs_states(&input_ys, State::Unspent)
+            .remove_proofs(&input_ys, Some(melt_request.quote))
             .await?;
 
         self.localstore

+ 6 - 18
crates/cdk/src/mint/swap.rs

@@ -72,18 +72,14 @@ impl Mint {
             .len()
             .ne(&proof_count)
         {
-            self.localstore
-                .update_proofs_states(&input_ys, State::Unspent)
-                .await?;
+            self.localstore.remove_proofs(&input_ys, None).await?;
             return Err(Error::DuplicateProofs);
         }
 
         for proof in &swap_request.inputs {
             if let Err(err) = self.verify_proof(proof).await {
                 tracing::info!("Error verifying proof in swap");
-                self.localstore
-                    .update_proofs_states(&input_ys, State::Unspent)
-                    .await?;
+                self.localstore.remove_proofs(&input_ys, None).await?;
                 return Err(err);
             }
         }
@@ -100,9 +96,7 @@ impl Mint {
                 }
                 None => {
                     tracing::info!("Swap request with unknown keyset in inputs");
-                    self.localstore
-                        .update_proofs_states(&input_ys, State::Unspent)
-                        .await?;
+                    self.localstore.remove_proofs(&input_ys, None).await?;
                 }
             }
         }
@@ -117,9 +111,7 @@ impl Mint {
                 }
                 None => {
                     tracing::info!("Swap request with unknown keyset in outputs");
-                    self.localstore
-                        .update_proofs_states(&input_ys, State::Unspent)
-                        .await?;
+                    self.localstore.remove_proofs(&input_ys, None).await?;
                 }
             }
         }
@@ -129,9 +121,7 @@ impl Mint {
         // now
         if keyset_units.len().gt(&1) {
             tracing::error!("Only one unit is allowed in request: {:?}", keyset_units);
-            self.localstore
-                .update_proofs_states(&input_ys, State::Unspent)
-                .await?;
+            self.localstore.remove_proofs(&input_ys, None).await?;
             return Err(Error::UnsupportedUnit);
         }
 
@@ -146,9 +136,7 @@ impl Mint {
             for blinded_message in &swap_request.outputs {
                 if let Err(err) = blinded_message.verify_p2pk(&pubkeys, sigs_required) {
                     tracing::info!("Could not verify p2pk in swap request");
-                    self.localstore
-                        .update_proofs_states(&input_ys, State::Unspent)
-                        .await?;
+                    self.localstore.remove_proofs(&input_ys, None).await?;
                     return Err(err.into());
                 }
             }