feat: add and remove proofs use vecs

This commit is contained in:
thesimplekid
2024-06-27 23:05:18 +01:00
parent bf9b4dfe54
commit b0bfaec94a
5 changed files with 118 additions and 88 deletions

View File

@@ -453,7 +453,7 @@ impl MintDatabase for MintRedbDatabase {
Ok(()) Ok(())
} }
async fn add_spent_proof(&self, proof: Proof) -> Result<(), Self::Err> { async fn add_spent_proofs(&self, proofs: Vec<Proof>) -> Result<(), Self::Err> {
let db = self.db.lock().await; let db = self.db.lock().await;
let write_txn = db.begin_write().map_err(Error::from)?; let write_txn = db.begin_write().map_err(Error::from)?;
@@ -462,6 +462,7 @@ impl MintDatabase for MintRedbDatabase {
let mut table = write_txn let mut table = write_txn
.open_table(SPENT_PROOFS_TABLE) .open_table(SPENT_PROOFS_TABLE)
.map_err(Error::from)?; .map_err(Error::from)?;
for proof in proofs {
let y: PublicKey = hash_to_curve(&proof.secret.to_bytes()).map_err(Error::from)?; let y: PublicKey = hash_to_curve(&proof.secret.to_bytes()).map_err(Error::from)?;
table table
.insert( .insert(
@@ -470,6 +471,7 @@ impl MintDatabase for MintRedbDatabase {
) )
.map_err(Error::from)?; .map_err(Error::from)?;
} }
}
write_txn.commit().map_err(Error::from)?; write_txn.commit().map_err(Error::from)?;
Ok(()) Ok(())
@@ -503,7 +505,7 @@ impl MintDatabase for MintRedbDatabase {
} }
} }
async fn add_pending_proof(&self, proof: Proof) -> Result<(), Self::Err> { async fn add_pending_proofs(&self, proofs: Vec<Proof>) -> Result<(), Self::Err> {
let db = self.db.lock().await; let db = self.db.lock().await;
let write_txn = db.begin_write().map_err(Error::from)?; let write_txn = db.begin_write().map_err(Error::from)?;
@@ -512,6 +514,7 @@ impl MintDatabase for MintRedbDatabase {
let mut table = write_txn let mut table = write_txn
.open_table(PENDING_PROOFS_TABLE) .open_table(PENDING_PROOFS_TABLE)
.map_err(Error::from)?; .map_err(Error::from)?;
for proof in proofs {
table table
.insert( .insert(
hash_to_curve(&proof.secret.to_bytes())?.to_bytes(), hash_to_curve(&proof.secret.to_bytes())?.to_bytes(),
@@ -519,6 +522,7 @@ impl MintDatabase for MintRedbDatabase {
) )
.map_err(Error::from)?; .map_err(Error::from)?;
} }
}
write_txn.commit().map_err(Error::from)?; write_txn.commit().map_err(Error::from)?;
Ok(()) Ok(())
@@ -555,7 +559,7 @@ impl MintDatabase for MintRedbDatabase {
} }
} }
async fn remove_pending_proof(&self, secret: &Secret) -> Result<(), Self::Err> { async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
let db = self.db.lock().await; let db = self.db.lock().await;
let write_txn = db.begin_write().map_err(Error::from)?; let write_txn = db.begin_write().map_err(Error::from)?;
@@ -564,9 +568,11 @@ impl MintDatabase for MintRedbDatabase {
let mut table = write_txn let mut table = write_txn
.open_table(PENDING_PROOFS_TABLE) .open_table(PENDING_PROOFS_TABLE)
.map_err(Error::from)?; .map_err(Error::from)?;
for secret in secrets {
let secret_hash = hash_to_curve(&secret.to_bytes()).map_err(Error::from)?; let secret_hash = hash_to_curve(&secret.to_bytes()).map_err(Error::from)?;
table.remove(secret_hash.to_bytes()).map_err(Error::from)?; table.remove(secret_hash.to_bytes()).map_err(Error::from)?;
} }
}
write_txn.commit().map_err(Error::from)?; write_txn.commit().map_err(Error::from)?;
Ok(()) Ok(())

View File

@@ -10,7 +10,7 @@ use cdk::cdk_database::{self, MintDatabase};
use cdk::mint::MintKeySetInfo; use cdk::mint::MintKeySetInfo;
use cdk::nuts::nut05::QuoteState; use cdk::nuts::nut05::QuoteState;
use cdk::nuts::{ use cdk::nuts::{
BlindSignature, CurrencyUnit, Id, MeltQuoteState, MintQuoteState, Proof, PublicKey, BlindSignature, CurrencyUnit, Id, MeltQuoteState, MintQuoteState, Proof, Proofs, PublicKey,
}; };
use cdk::secret::Secret; use cdk::secret::Secret;
use cdk::types::{MeltQuote, MintQuote}; use cdk::types::{MeltQuote, MintQuote};
@@ -405,7 +405,10 @@ FROM keyset;
.collect()) .collect())
} }
async fn add_spent_proof(&self, proof: Proof) -> Result<(), Self::Err> { async fn add_spent_proofs(&self, proofs: Proofs) -> Result<(), Self::Err> {
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
for proof in proofs {
sqlx::query( sqlx::query(
r#" r#"
INSERT OR REPLACE INTO proof INSERT OR REPLACE INTO proof
@@ -420,10 +423,11 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
.bind(proof.c.to_bytes().to_vec()) .bind(proof.c.to_bytes().to_vec())
.bind(proof.witness.map(|w| serde_json::to_string(&w).unwrap())) .bind(proof.witness.map(|w| serde_json::to_string(&w).unwrap()))
.bind("SPENT") .bind("SPENT")
.execute(&self.pool) .execute(&mut transaction)
.await .await
.map_err(Error::from)?; .map_err(Error::from)?;
}
transaction.commit().await.map_err(Error::from)?;
Ok(()) Ok(())
} }
async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err> { async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err> {
@@ -473,7 +477,9 @@ AND state="SPENT";
Ok(Some(sqlite_row_to_proof(rec)?)) Ok(Some(sqlite_row_to_proof(rec)?))
} }
async fn add_pending_proof(&self, proof: Proof) -> Result<(), Self::Err> { async fn add_pending_proofs(&self, proofs: Proofs) -> Result<(), Self::Err> {
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
for proof in proofs {
sqlx::query( sqlx::query(
r#" r#"
INSERT OR REPLACE INTO proof INSERT OR REPLACE INTO proof
@@ -488,9 +494,11 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
.bind(proof.c.to_bytes().to_vec()) .bind(proof.c.to_bytes().to_vec())
.bind(proof.witness.map(|w| serde_json::to_string(&w).unwrap())) .bind(proof.witness.map(|w| serde_json::to_string(&w).unwrap()))
.bind("PENDING") .bind("PENDING")
.execute(&self.pool) .execute(&mut transaction)
.await .await
.map_err(Error::from)?; .map_err(Error::from)?;
}
transaction.commit().await.map_err(Error::from)?;
Ok(()) Ok(())
} }
@@ -542,7 +550,9 @@ AND state="PENDING";
}; };
Ok(Some(sqlite_row_to_proof(rec)?)) Ok(Some(sqlite_row_to_proof(rec)?))
} }
async fn remove_pending_proof(&self, secret: &Secret) -> Result<(), Self::Err> { async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
for secret in secrets {
sqlx::query( sqlx::query(
r#" r#"
DELETE FROM proof DELETE FROM proof
@@ -551,9 +561,11 @@ AND state="PENDING";
"#, "#,
) )
.bind(secret.to_string()) .bind(secret.to_string())
.execute(&self.pool) .execute(&mut transaction)
.await .await
.map_err(Error::from)?; .map_err(Error::from)?;
}
transaction.commit().await.map_err(Error::from)?;
Ok(()) Ok(())
} }

View File

@@ -179,12 +179,13 @@ impl MintDatabase for MintMemoryDatabase {
Ok(()) Ok(())
} }
async fn add_spent_proof(&self, proof: Proof) -> Result<(), Self::Err> { async fn add_spent_proofs(&self, spent_proofs: Proofs) -> Result<(), Self::Err> {
let mut proofs = self.spent_proofs.write().await;
for proof in spent_proofs {
let secret_point = hash_to_curve(&proof.secret.to_bytes())?; let secret_point = hash_to_curve(&proof.secret.to_bytes())?;
self.spent_proofs proofs.insert(secret_point.to_bytes(), proof);
.write() }
.await
.insert(secret_point.to_bytes(), proof);
Ok(()) Ok(())
} }
@@ -201,11 +202,12 @@ impl MintDatabase for MintMemoryDatabase {
Ok(self.spent_proofs.read().await.get(&y.to_bytes()).cloned()) Ok(self.spent_proofs.read().await.get(&y.to_bytes()).cloned())
} }
async fn add_pending_proof(&self, proof: Proof) -> Result<(), Self::Err> { async fn add_pending_proofs(&self, pending_proofs: Proofs) -> Result<(), Self::Err> {
self.pending_proofs let mut proofs = self.pending_proofs.write().await;
.write()
.await for proof in pending_proofs {
.insert(hash_to_curve(&proof.secret.to_bytes())?.to_bytes(), proof); proofs.insert(hash_to_curve(&proof.secret.to_bytes())?.to_bytes(), proof);
}
Ok(()) Ok(())
} }
@@ -226,12 +228,14 @@ impl MintDatabase for MintMemoryDatabase {
Ok(self.pending_proofs.read().await.get(&y.to_bytes()).cloned()) Ok(self.pending_proofs.read().await.get(&y.to_bytes()).cloned())
} }
async fn remove_pending_proof(&self, secret: &Secret) -> Result<(), Self::Err> { async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
let mut proofs = self.pending_proofs.write().await;
for secret in secrets {
let secret_point = hash_to_curve(&secret.to_bytes())?; let secret_point = hash_to_curve(&secret.to_bytes())?;
self.pending_proofs proofs.remove(&secret_point.to_bytes());
.write() }
.await
.remove(&secret_point.to_bytes());
Ok(()) Ok(())
} }

View File

@@ -15,9 +15,9 @@ use crate::nuts::State;
#[cfg(feature = "mint")] #[cfg(feature = "mint")]
use crate::nuts::{BlindSignature, MeltQuoteState, MintQuoteState, Proof}; use crate::nuts::{BlindSignature, MeltQuoteState, MintQuoteState, Proof};
#[cfg(any(feature = "wallet", feature = "mint"))] #[cfg(any(feature = "wallet", feature = "mint"))]
use crate::nuts::{CurrencyUnit, Id, PublicKey}; use crate::nuts::{CurrencyUnit, Id, Proofs, PublicKey};
#[cfg(feature = "wallet")] #[cfg(feature = "wallet")]
use crate::nuts::{KeySetInfo, Keys, MintInfo, Proofs, SpendingConditions}; use crate::nuts::{KeySetInfo, Keys, MintInfo, SpendingConditions};
#[cfg(feature = "mint")] #[cfg(feature = "mint")]
use crate::secret::Secret; use crate::secret::Secret;
#[cfg(feature = "wallet")] #[cfg(feature = "wallet")]
@@ -150,17 +150,17 @@ pub trait MintDatabase {
async fn get_keyset_info(&self, id: &Id) -> Result<Option<MintKeySetInfo>, Self::Err>; async fn get_keyset_info(&self, id: &Id) -> Result<Option<MintKeySetInfo>, Self::Err>;
async fn get_keyset_infos(&self) -> Result<Vec<MintKeySetInfo>, Self::Err>; async fn get_keyset_infos(&self) -> Result<Vec<MintKeySetInfo>, Self::Err>;
async fn add_spent_proof(&self, proof: Proof) -> Result<(), Self::Err>; async fn add_spent_proofs(&self, proof: Proofs) -> Result<(), Self::Err>;
async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err>; async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err>;
async fn get_spent_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err>; async fn get_spent_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err>;
async fn add_pending_proof(&self, proof: Proof) -> Result<(), Self::Err>; async fn add_pending_proofs(&self, proof: Proofs) -> Result<(), Self::Err>;
async fn get_pending_proof_by_secret( async fn get_pending_proof_by_secret(
&self, &self,
secret: &Secret, secret: &Secret,
) -> Result<Option<Proof>, Self::Err>; ) -> Result<Option<Proof>, Self::Err>;
async fn get_pending_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err>; async fn get_pending_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err>;
async fn remove_pending_proof(&self, secret: &Secret) -> Result<(), Self::Err>; async fn remove_pending_proofs(&self, secret: Vec<&Secret>) -> Result<(), Self::Err>;
async fn add_blinded_signature( async fn add_blinded_signature(
&self, &self,

View File

@@ -493,9 +493,9 @@ impl Mint {
} }
} }
for proof in swap_request.inputs { self.localstore
self.localstore.add_spent_proof(proof).await?; .add_spent_proofs(swap_request.inputs)
} .await?;
let mut promises = Vec::with_capacity(swap_request.outputs.len()); let mut promises = Vec::with_capacity(swap_request.outputs.len());
@@ -583,6 +583,14 @@ impl Mint {
&self, &self,
melt_request: &MeltBolt11Request, melt_request: &MeltBolt11Request,
) -> Result<MeltQuote, Error> { ) -> Result<MeltQuote, Error> {
for proof in &melt_request.inputs {
self.verify_proof(proof).await?;
}
self.localstore
.add_pending_proofs(melt_request.inputs.clone())
.await?;
let state = self let state = self
.localstore .localstore
.update_melt_quote_state(&melt_request.quote, MeltQuoteState::Pending) .update_melt_quote_state(&melt_request.quote, MeltQuoteState::Pending)
@@ -681,10 +689,6 @@ impl Mint {
return Err(Error::DuplicateProofs); return Err(Error::DuplicateProofs);
} }
for proof in &melt_request.inputs {
self.verify_proof(proof).await?;
}
Ok(quote) Ok(quote)
} }
@@ -714,9 +718,9 @@ impl Mint {
} }
} }
for input in &melt_request.inputs { self.localstore
self.localstore.add_spent_proof(input.clone()).await?; .add_spent_proofs(melt_request.inputs.clone())
} .await?;
let mut change = None; let mut change = None;
@@ -760,6 +764,10 @@ impl Mint {
); );
} }
self.localstore
.remove_pending_proofs(melt_request.inputs.iter().map(|p| &p.secret).collect())
.await?;
self.localstore self.localstore
.update_melt_quote_state(&melt_request.quote, MeltQuoteState::Paid) .update_melt_quote_state(&melt_request.quote, MeltQuoteState::Paid)
.await?; .await?;