fix: Improve spending conditions validation in ProofInfo (#654)

This commit is contained in:
thesimplekid
2025-03-13 09:14:37 +00:00
committed by GitHub

View File

@@ -127,7 +127,11 @@ impl ProofInfo {
if let Some(spending_conditions) = spending_conditions {
match &self.spending_condition {
None => return false,
None => {
if !spending_conditions.is_empty() {
return false;
}
}
Some(s) => {
if !spending_conditions.contains(s) {
return false;
@@ -177,8 +181,11 @@ impl QuoteTTL {
mod tests {
use std::str::FromStr;
use super::Melted;
use crate::nuts::{Id, Proof, PublicKey};
use cashu::SecretKey;
use super::{Melted, ProofInfo};
use crate::mint_url::MintUrl;
use crate::nuts::{CurrencyUnit, Id, Proof, PublicKey, SpendingConditions, State};
use crate::secret::Secret;
use crate::Amount;
@@ -240,6 +247,90 @@ mod tests {
assert_eq!(melted.fee_paid, Amount::from(1));
assert_eq!(melted.total_amount(), Amount::from(32));
}
#[test]
fn test_matches_conditions() {
let keyset_id = Id::from_str("00deadbeef123456").unwrap();
let proof = Proof::new(
Amount::from(64),
keyset_id,
Secret::new("test_secret"),
PublicKey::from_hex(
"02deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
)
.unwrap(),
);
let mint_url = MintUrl::from_str("https://example.com").unwrap();
let proof_info =
ProofInfo::new(proof, mint_url.clone(), State::Unspent, CurrencyUnit::Sat).unwrap();
// Test matching mint_url
assert!(proof_info.matches_conditions(&Some(mint_url.clone()), &None, &None, &None));
assert!(!proof_info.matches_conditions(
&Some(MintUrl::from_str("https://different.com").unwrap()),
&None,
&None,
&None
));
// Test matching unit
assert!(proof_info.matches_conditions(&None, &Some(CurrencyUnit::Sat), &None, &None));
assert!(!proof_info.matches_conditions(&None, &Some(CurrencyUnit::Msat), &None, &None));
// Test matching state
assert!(proof_info.matches_conditions(&None, &None, &Some(vec![State::Unspent]), &None));
assert!(proof_info.matches_conditions(
&None,
&None,
&Some(vec![State::Unspent, State::Spent]),
&None
));
assert!(!proof_info.matches_conditions(&None, &None, &Some(vec![State::Spent]), &None));
// Test with no conditions (should match)
assert!(proof_info.matches_conditions(&None, &None, &None, &None));
// Test with multiple conditions
assert!(proof_info.matches_conditions(
&Some(mint_url),
&Some(CurrencyUnit::Sat),
&Some(vec![State::Unspent]),
&None
));
}
#[test]
fn test_matches_conditions_with_spending_conditions() {
// This test would need to be expanded with actual SpendingConditions
// implementation, but we can test the basic case where no spending
// conditions are present
let keyset_id = Id::from_str("00deadbeef123456").unwrap();
let proof = Proof::new(
Amount::from(64),
keyset_id,
Secret::new("test_secret"),
PublicKey::from_hex(
"02deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
)
.unwrap(),
);
let mint_url = MintUrl::from_str("https://example.com").unwrap();
let proof_info =
ProofInfo::new(proof, mint_url, State::Unspent, CurrencyUnit::Sat).unwrap();
// Test with empty spending conditions (should match when proof has none)
assert!(proof_info.matches_conditions(&None, &None, &None, &Some(vec![])));
// Test with non-empty spending conditions (should not match when proof has none)
let dummy_condition = SpendingConditions::P2PKConditions {
data: SecretKey::generate().public_key(),
conditions: None,
};
assert!(!proof_info.matches_conditions(&None, &None, &None, &Some(vec![dummy_condition])));
}
}
/// Mint Fee Reserve