浏览代码

Address feedback left on code review

Cesar Rodas 1 周之前
父节点
当前提交
11adbf9f36

+ 13 - 1
crates/cdk/src/wallet/builder.rs

@@ -1,7 +1,9 @@
 use std::collections::HashMap;
 use std::sync::Arc;
+use std::time::Duration;
 
 use cdk_common::database;
+use cdk_common::parking_lot::Mutex;
 #[cfg(feature = "auth")]
 use cdk_common::AuthToken;
 #[cfg(feature = "auth")]
@@ -27,6 +29,7 @@ pub struct WalletBuilder {
     seed: Option<[u8; 64]>,
     use_http_subscription: bool,
     client: Option<Arc<dyn MintConnector + Send + Sync>>,
+    metadata_cache_ttl: Option<Duration>,
     metadata_cache: Option<Arc<MintMetadataCache>>,
     metadata_caches: HashMap<MintUrl, Arc<MintMetadataCache>>,
 }
@@ -42,6 +45,7 @@ impl Default for WalletBuilder {
             auth_wallet: None,
             seed: None,
             client: None,
+            metadata_cache_ttl: None,
             use_http_subscription: false,
             metadata_cache: None,
             metadata_caches: HashMap::new(),
@@ -61,6 +65,12 @@ impl WalletBuilder {
         self
     }
 
+    /// Set metadata_cache_ttl
+    pub fn set_metadata_cache_ttl(mut self, metadata_cache_ttl: Option<Duration>) -> Self {
+        self.metadata_cache_ttl = metadata_cache_ttl;
+        self
+    }
+
     /// If WS is preferred (with fallback to HTTP is it is not supported by the mint) for the wallet
     /// subscriptions to mint events
     pub fn prefer_ws_subscription(mut self) -> Self {
@@ -201,6 +211,8 @@ impl WalletBuilder {
             }
         };
 
+        let metadata_cache_ttl = self.metadata_cache_ttl;
+
         let metadata_cache = self.metadata_cache.unwrap_or_else(|| {
             // Check if we already have a cache for this mint in the HashMap
             if let Some(cache) = self.metadata_caches.get(&mint_url) {
@@ -216,7 +228,7 @@ impl WalletBuilder {
             unit,
             localstore,
             metadata_cache,
-            metadata_cache_ttl: None.into(),
+            metadata_cache_ttl: Arc::new(Mutex::new(metadata_cache_ttl)),
             target_proof_count: self.target_proof_count.unwrap_or(3),
             #[cfg(feature = "auth")]
             auth_wallet: Arc::new(RwLock::new(self.auth_wallet)),

+ 20 - 25
crates/cdk/src/wallet/keysets.rs

@@ -15,11 +15,10 @@ impl Wallet {
     #[instrument(skip(self))]
     pub async fn load_keyset_keys(&self, keyset_id: Id) -> Result<Keys, Error> {
         self.metadata_cache
-            .load(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?
             .keys
             .get(&keyset_id)
@@ -42,11 +41,10 @@ impl Wallet {
     pub async fn get_mint_keysets(&self) -> Result<Vec<KeySetInfo>, Error> {
         let keysets = self
             .metadata_cache
-            .load(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?
             .keysets
             .iter()
@@ -77,11 +75,10 @@ impl Wallet {
 
         let keysets = self
             .metadata_cache
-            .load_from_mint(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load_from_mint(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?
             .keysets
             .iter()
@@ -123,11 +120,10 @@ impl Wallet {
     #[instrument(skip(self))]
     pub async fn get_active_keyset(&self) -> Result<KeySetInfo, Error> {
         self.metadata_cache
-            .load(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?
             .active_keysets
             .iter()
@@ -143,11 +139,10 @@ impl Wallet {
     pub async fn get_keyset_fees_and_amounts(&self) -> Result<KeysetFeeAndAmounts, Error> {
         let metadata = self
             .metadata_cache
-            .load(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?;
 
         let mut fees = HashMap::new();

+ 9 - 8
crates/cdk/src/wallet/mint_metadata_cache.rs

@@ -44,9 +44,6 @@ use crate::wallet::MintConnector;
 use crate::wallet::{AuthMintConnector, AuthWallet};
 use crate::{Error, Wallet};
 
-/// Default TTL
-pub const DEFAULT_TTL: Duration = Duration::from_secs(300);
-
 /// Metadata freshness and versioning information
 ///
 /// Tracks when data was last fetched and which version is currently cached.
@@ -214,6 +211,7 @@ impl MintMetadataCache {
     ///
     /// * `storage` - Database to persist metadata to (async background write)
     /// * `client` - HTTP client for fetching from mint server
+    /// * `ttl` - Optional TTL, if not provided it is asumed that any cached data is good enough
     ///
     /// # Returns
     ///
@@ -233,14 +231,15 @@ impl MintMetadataCache {
         ttl: Option<Duration>,
     ) -> Result<Arc<MintMetadata>, Error> {
         // Acquire lock to ensure only one fetch at a time
-        let ttl = ttl.unwrap_or(DEFAULT_TTL);
         let current_version = self.metadata.load().status.version;
         let _guard = self.fetch_lock.lock().await;
 
         // Check if another caller already updated the cache while we waited
         let current_metadata = self.metadata.load().clone();
         if current_metadata.status.is_populated
-            && current_metadata.status.updated_at + ttl > Instant::now()
+            && ttl
+                .map(|ttl| current_metadata.status.updated_at + ttl > Instant::now())
+                .unwrap_or(true)
             && current_metadata.status.version > current_version
         {
             // Cache was just updated by another caller - return it
@@ -275,6 +274,7 @@ impl MintMetadataCache {
     ///
     /// * `storage` - Database to persist metadata to (if fetched or stale)
     /// * `client` - HTTP client for fetching from mint (only if cache empty)
+    /// * `ttl` - Optional TTL, if not provided it is asumed that any cached data is good enough
     ///
     /// # Returns
     ///
@@ -295,7 +295,6 @@ impl MintMetadataCache {
     ) -> Result<Arc<MintMetadata>, Error> {
         let cached_metadata = self.metadata.load().clone();
         let storage_id = Self::arc_pointer_id(storage);
-        let ttl = ttl.unwrap_or(DEFAULT_TTL);
 
         // Check what version of cache this database has seen
         let db_synced_version = self
@@ -306,7 +305,9 @@ impl MintMetadataCache {
             .unwrap_or_default();
 
         if cached_metadata.status.is_populated
-            && cached_metadata.status.updated_at + ttl > Instant::now()
+            && ttl
+                .map(|ttl| cached_metadata.status.updated_at + ttl > Instant::now())
+                .unwrap_or(true)
         {
             // Cache is ready - check if database needs updating
             if db_synced_version != cached_metadata.status.version {
@@ -319,7 +320,7 @@ impl MintMetadataCache {
         }
 
         // Cache not populated - fetch from mint
-        self.load_from_mint(storage, client, Some(ttl)).await
+        self.load_from_mint(storage, client, ttl).await
     }
 
     /// Load auth keysets and keys (auth feature only)

+ 9 - 59
crates/cdk/src/wallet/mod.rs

@@ -2,7 +2,6 @@
 
 use std::collections::HashMap;
 use std::fmt::Debug;
-use std::ops::Deref;
 use std::str::FromStr;
 use std::sync::atomic::AtomicBool;
 use std::sync::Arc;
@@ -79,53 +78,6 @@ pub use types::{MeltQuote, MintQuote, SendKind};
 
 use crate::nuts::nut00::ProofsMethods;
 
-/// Cloneable mutex
-///
-/// Each instance is independent from each other, that's why an Arc is not an option
-#[derive(Debug)]
-pub struct CloneableMutex<T>(Mutex<T>)
-where
-    T: Clone + Debug;
-
-impl<T> From<T> for CloneableMutex<T>
-where
-    T: Clone + Debug,
-{
-    fn from(value: T) -> Self {
-        Self(Mutex::new(value))
-    }
-}
-
-impl<T> CloneableMutex<T>
-where
-    T: Clone + Debug,
-{
-    /// Clone the inner guarded object
-    pub fn clone_inner(&self) -> T {
-        (*self.0.lock().deref()).clone()
-    }
-}
-
-impl<T> Clone for CloneableMutex<T>
-where
-    T: Clone + Debug,
-{
-    fn clone(&self) -> Self {
-        Self(Mutex::new(self.0.lock().clone()))
-    }
-}
-
-impl<T> Deref for CloneableMutex<T>
-where
-    T: Clone + Debug,
-{
-    type Target = Mutex<T>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
-
 /// CDK Wallet
 ///
 /// The CDK [`Wallet`] is a high level cashu wallet.
@@ -143,7 +95,7 @@ pub struct Wallet {
     pub metadata_cache: Arc<MintMetadataCache>,
     /// The targeted amount of proofs to have at each size
     pub target_proof_count: usize,
-    metadata_cache_ttl: CloneableMutex<Option<Duration>>,
+    metadata_cache_ttl: Arc<Mutex<Option<Duration>>>,
     #[cfg(feature = "auth")]
     auth_wallet: Arc<RwLock<Option<AuthWallet>>>,
     seed: [u8; 64],
@@ -275,11 +227,10 @@ impl Wallet {
         let mut fee_per_keyset = HashMap::new();
         let metadata = self
             .metadata_cache
-            .load(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?;
 
         for keyset_id in proofs_per_keyset.keys() {
@@ -300,11 +251,10 @@ impl Wallet {
     pub async fn get_keyset_count_fee(&self, keyset_id: &Id, count: u64) -> Result<Amount, Error> {
         let input_fee_ppk = self
             .metadata_cache
-            .load(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?
             .keysets
             .get(keyset_id)

+ 4 - 5
crates/cdk/src/wallet/swap.rs

@@ -49,11 +49,10 @@ impl Wallet {
 
         let active_keys = self
             .metadata_cache
-            .load(
-                &self.localstore,
-                &self.client,
-                self.metadata_cache_ttl.clone_inner(),
-            )
+            .load(&self.localstore, &self.client, {
+                let ttl = self.metadata_cache_ttl.lock();
+                *ttl
+            })
             .await?
             .keys
             .get(&active_keyset_id)