cashu-sdk/mint: improve: check proofs are unique melt/split

This commit is contained in:
thesimplekid
2023-09-04 22:58:09 +01:00
parent fd955f22cb
commit 9ddd36fc19
2 changed files with 25 additions and 9 deletions

View File

@@ -108,10 +108,17 @@ impl Mint {
return Err(Error::Amount);
}
let mut secrets = Vec::with_capacity(split_request.proofs.len());
for proof in &split_request.proofs {
secrets.push(self.verify_proof(proof)?);
self.spent_secrets.insert(proof.secret.clone());
let proof_count = split_request.proofs.len();
let secrets: HashSet<String> = split_request.proofs.into_iter().map(|p| p.secret).collect();
// Check that there are no duplicate proofs in request
if secrets.len().ne(&proof_count) {
return Err(Error::DuplicateProofs);
}
for secret in secrets {
self.spent_secrets.insert(secret);
}
match &split_request.amount {
@@ -146,7 +153,7 @@ impl Mint {
}
}
pub fn verify_proof(&self, proof: &Proof) -> Result<String, Error> {
pub fn verify_proof(&self, proof: &Proof) -> Result<(), Error> {
if self.spent_secrets.contains(&proof.secret) {
return Err(Error::TokenSpent);
}
@@ -172,7 +179,7 @@ impl Mint {
&proof.secret,
)?;
Ok(proof.secret.clone())
Ok(())
}
pub fn check_spendable(
@@ -202,9 +209,15 @@ impl Mint {
return Err(Error::Amount);
}
let mut secrets = Vec::with_capacity(melt_request.proofs.len());
for proof in &melt_request.proofs {
secrets.push(self.verify_proof(proof)?);
let secrets: HashSet<&str> = melt_request
.proofs
.iter()
.map(|p| p.secret.as_str())
.collect();
// Ensure proofs are unique and not being double spent
if melt_request.proofs.len().ne(&secrets.len()) {
return Err(Error::DuplicateProofs);
}
Ok(())

View File

@@ -162,6 +162,8 @@ pub mod mint {
EllipticError(k256::elliptic_curve::Error),
TokenNotVerifed,
InvoiceAmountUndefined,
/// Duplicate Proofs sent in request
DuplicateProofs,
CustomError(String),
}
@@ -177,6 +179,7 @@ pub mod mint {
Error::CustomError(err) => write!(f, "{}", err),
Error::TokenNotVerifed => write!(f, "Token Not Verified"),
Error::InvoiceAmountUndefined => write!(f, "Invoice without amount"),
Error::DuplicateProofs => write!(f, "Request has duplicate proofs"),
}
}
}