فهرست منبع

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

thesimplekid 1 ماه پیش
والد
کامیت
110245e6c8
1فایلهای تغییر یافته به همراه94 افزوده شده و 3 حذف شده
  1. 94 3
      crates/cdk-common/src/common.rs

+ 94 - 3
crates/cdk-common/src/common.rs

@@ -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