From 7b69aa966a510b6a756511bb8ca6eb0582213717 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Wed, 5 Feb 2025 10:48:33 +0000 Subject: [PATCH 1/4] feat: add remove proofs to mint db --- crates/cdk-common/src/database/mint.rs | 8 +++++- crates/cdk-redb/src/mint/mod.rs | 30 ++++++++++++++++++++++ crates/cdk-sqlite/src/mint/mod.rs | 27 +++++++++++++++++++ crates/cdk/src/cdk_database/mint_memory.rs | 21 +++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/crates/cdk-common/src/database/mint.rs b/crates/cdk-common/src/database/mint.rs index 3ce81f2e..5044853e 100644 --- a/crates/cdk-common/src/database/mint.rs +++ b/crates/cdk-common/src/database/mint.rs @@ -86,8 +86,14 @@ pub trait Database { /// Get [`MintKeySetInfo`]s async fn get_keyset_infos(&self) -> Result, Self::Err>; - /// Add spent [`Proofs`] + /// Add [`Proofs`] async fn add_proofs(&self, proof: Proofs, quote_id: Option) -> Result<(), Self::Err>; + /// Remove [`Proofs`] + async fn remove_proofs( + &self, + ys: &[PublicKey], + quote_id: Option, + ) -> Result<(), Self::Err>; /// Get [`Proofs`] by ys async fn get_proofs_by_ys(&self, ys: &[PublicKey]) -> Result>, Self::Err>; /// Get ys by quote id diff --git a/crates/cdk-redb/src/mint/mod.rs b/crates/cdk-redb/src/mint/mod.rs index 648caa4d..87d45e37 100644 --- a/crates/cdk-redb/src/mint/mod.rs +++ b/crates/cdk-redb/src/mint/mod.rs @@ -534,6 +534,36 @@ impl MintDatabase for MintRedbDatabase { Ok(()) } + async fn remove_proofs( + &self, + ys: &[PublicKey], + quote_id: Option, + ) -> 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)?; + } + } + + 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>, 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)?; diff --git a/crates/cdk-sqlite/src/mint/mod.rs b/crates/cdk-sqlite/src/mint/mod.rs index 65891d75..8ddb59d8 100644 --- a/crates/cdk-sqlite/src/mint/mod.rs +++ b/crates/cdk-sqlite/src/mint/mod.rs @@ -780,6 +780,33 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?); Ok(()) } + async fn remove_proofs( + &self, + ys: &[PublicKey], + _quote_id: Option, + ) -> 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::>() + .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>, Self::Err> { let mut transaction = self.pool.begin().await.map_err(Error::from)?; diff --git a/crates/cdk/src/cdk_database/mint_memory.rs b/crates/cdk/src/cdk_database/mint_memory.rs index 52bf4c70..464d8fd0 100644 --- a/crates/cdk/src/cdk_database/mint_memory.rs +++ b/crates/cdk/src/cdk_database/mint_memory.rs @@ -284,6 +284,27 @@ impl MintDatabase for MintMemoryDatabase { Ok(()) } + async fn remove_proofs( + &self, + ys: &[PublicKey], + quote_id: Option, + ) -> Result<(), Self::Err> { + { + let mut db_proofs = self.proofs.write().await; + + ys.iter().for_each(|y| { + db_proofs.remove(&y.to_bytes()); + }); + } + + if let Some(quote_id) = quote_id { + let mut quote_proofs = self.quote_proofs.lock().await; + quote_proofs.remove("e_id); + } + + Ok(()) + } + async fn get_proofs_by_ys(&self, ys: &[PublicKey]) -> Result>, Self::Err> { let spent_proofs = self.proofs.read().await; From 0e3f35b0dedc1ebd771a14b89575d69854f12151 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Wed, 5 Feb 2025 11:00:17 +0000 Subject: [PATCH 2/4] fix: delete proofs when unspent --- crates/cdk/src/mint/melt.rs | 2 +- crates/cdk/src/mint/swap.rs | 24 ++++++------------------ 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/crates/cdk/src/mint/melt.rs b/crates/cdk/src/mint/melt.rs index 7cd935f6..3b50f7c8 100644 --- a/crates/cdk/src/mint/melt.rs +++ b/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 diff --git a/crates/cdk/src/mint/swap.rs b/crates/cdk/src/mint/swap.rs index dba94ecc..915e6096 100644 --- a/crates/cdk/src/mint/swap.rs +++ b/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()); } } From 55c095c2ef8e38b885b7fca388ff999bb82875b1 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Wed, 5 Feb 2025 11:12:09 +0000 Subject: [PATCH 3/4] fix: mint mem delete proof state --- crates/cdk/src/cdk_database/mint_memory.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/cdk/src/cdk_database/mint_memory.rs b/crates/cdk/src/cdk_database/mint_memory.rs index 464d8fd0..c7bdabfb 100644 --- a/crates/cdk/src/cdk_database/mint_memory.rs +++ b/crates/cdk/src/cdk_database/mint_memory.rs @@ -297,6 +297,14 @@ impl MintDatabase for MintMemoryDatabase { }); } + { + 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("e_id); From a1681212b1d3eaa79e29f2b6dd961296f2322cbc Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Wed, 5 Feb 2025 11:32:04 +0000 Subject: [PATCH 4/4] fix: redb delete proof state --- crates/cdk-redb/src/mint/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/cdk-redb/src/mint/mod.rs b/crates/cdk-redb/src/mint/mod.rs index 87d45e37..0a5a7656 100644 --- a/crates/cdk-redb/src/mint/mod.rs +++ b/crates/cdk-redb/src/mint/mod.rs @@ -549,6 +549,17 @@ impl MintDatabase for MintRedbDatabase { } } + { + 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)