mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-23 15:44:50 +01:00
feat: add and remove proofs use vecs
This commit is contained in:
@@ -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,13 +462,15 @@ 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)?;
|
||||||
let y: PublicKey = hash_to_curve(&proof.secret.to_bytes()).map_err(Error::from)?;
|
for proof in proofs {
|
||||||
table
|
let y: PublicKey = hash_to_curve(&proof.secret.to_bytes()).map_err(Error::from)?;
|
||||||
.insert(
|
table
|
||||||
y.to_bytes(),
|
.insert(
|
||||||
serde_json::to_string(&proof).map_err(Error::from)?.as_str(),
|
y.to_bytes(),
|
||||||
)
|
serde_json::to_string(&proof).map_err(Error::from)?.as_str(),
|
||||||
.map_err(Error::from)?;
|
)
|
||||||
|
.map_err(Error::from)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
write_txn.commit().map_err(Error::from)?;
|
write_txn.commit().map_err(Error::from)?;
|
||||||
|
|
||||||
@@ -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,12 +514,14 @@ 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)?;
|
||||||
table
|
for proof in proofs {
|
||||||
.insert(
|
table
|
||||||
hash_to_curve(&proof.secret.to_bytes())?.to_bytes(),
|
.insert(
|
||||||
serde_json::to_string(&proof).map_err(Error::from)?.as_str(),
|
hash_to_curve(&proof.secret.to_bytes())?.to_bytes(),
|
||||||
)
|
serde_json::to_string(&proof).map_err(Error::from)?.as_str(),
|
||||||
.map_err(Error::from)?;
|
)
|
||||||
|
.map_err(Error::from)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
write_txn.commit().map_err(Error::from)?;
|
write_txn.commit().map_err(Error::from)?;
|
||||||
|
|
||||||
@@ -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,8 +568,10 @@ 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)?;
|
||||||
let secret_hash = hash_to_curve(&secret.to_bytes()).map_err(Error::from)?;
|
for secret in secrets {
|
||||||
table.remove(secret_hash.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)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
write_txn.commit().map_err(Error::from)?;
|
write_txn.commit().map_err(Error::from)?;
|
||||||
|
|
||||||
|
|||||||
@@ -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,25 +405,29 @@ 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> {
|
||||||
sqlx::query(
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
r#"
|
|
||||||
|
for proof in proofs {
|
||||||
|
sqlx::query(
|
||||||
|
r#"
|
||||||
INSERT OR REPLACE INTO proof
|
INSERT OR REPLACE INTO proof
|
||||||
(y, amount, keyset_id, secret, c, witness, state)
|
(y, amount, keyset_id, secret, c, witness, state)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?);
|
VALUES (?, ?, ?, ?, ?, ?, ?);
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(proof.y()?.to_bytes().to_vec())
|
.bind(proof.y()?.to_bytes().to_vec())
|
||||||
.bind(u64::from(proof.amount) as i64)
|
.bind(u64::from(proof.amount) as i64)
|
||||||
.bind(proof.keyset_id.to_string())
|
.bind(proof.keyset_id.to_string())
|
||||||
.bind(proof.secret.to_string())
|
.bind(proof.secret.to_string())
|
||||||
.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,24 +477,28 @@ 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> {
|
||||||
sqlx::query(
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
r#"
|
for proof in proofs {
|
||||||
|
sqlx::query(
|
||||||
|
r#"
|
||||||
INSERT OR REPLACE INTO proof
|
INSERT OR REPLACE INTO proof
|
||||||
(y, amount, keyset_id, secret, c, witness, spent, pending)
|
(y, amount, keyset_id, secret, c, witness, spent, pending)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?);
|
VALUES (?, ?, ?, ?, ?, ?, ?);
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(proof.y()?.to_bytes().to_vec())
|
.bind(proof.y()?.to_bytes().to_vec())
|
||||||
.bind(u64::from(proof.amount) as i64)
|
.bind(u64::from(proof.amount) as i64)
|
||||||
.bind(proof.keyset_id.to_string())
|
.bind(proof.keyset_id.to_string())
|
||||||
.bind(proof.secret.to_string())
|
.bind(proof.secret.to_string())
|
||||||
.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,18 +550,22 @@ 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> {
|
||||||
sqlx::query(
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
r#"
|
for secret in secrets {
|
||||||
|
sqlx::query(
|
||||||
|
r#"
|
||||||
DELETE FROM proof
|
DELETE FROM proof
|
||||||
WHERE secret=?
|
WHERE secret=?
|
||||||
AND state="PENDING";
|
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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 secret_point = hash_to_curve(&proof.secret.to_bytes())?;
|
let mut proofs = self.spent_proofs.write().await;
|
||||||
self.spent_proofs
|
|
||||||
.write()
|
for proof in spent_proofs {
|
||||||
.await
|
let secret_point = hash_to_curve(&proof.secret.to_bytes())?;
|
||||||
.insert(secret_point.to_bytes(), proof);
|
proofs.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 secret_point = hash_to_curve(&secret.to_bytes())?;
|
let mut proofs = self.pending_proofs.write().await;
|
||||||
self.pending_proofs
|
|
||||||
.write()
|
for secret in secrets {
|
||||||
.await
|
let secret_point = hash_to_curve(&secret.to_bytes())?;
|
||||||
.remove(&secret_point.to_bytes());
|
proofs.remove(&secret_point.to_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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?;
|
||||||
|
|||||||
Reference in New Issue
Block a user