Sfoglia il codice sorgente

Move all keys and keysets to an ArcSwap.

Since the keys and keysets exist in RAM, most wrapping functions are infallible
and synchronous, improving performance and adding breaking API changes.

The signatory will provide this information on the boot and update when the
`rotate_keyset` is executed.

Todo: Implement a subscription key to reload the keys when the GRPC server
changes the keys. For the embedded mode, that makes no sense since there is a
single way to rotate keys, and that bit is already covered.
Cesar Rodas 1 mese fa
parent
commit
d699a09130

+ 2 - 7
crates/cdk-axum/src/auth.rs

@@ -103,12 +103,7 @@ where
 pub async fn get_auth_keysets(
 pub async fn get_auth_keysets(
     State(state): State<MintState>,
     State(state): State<MintState>,
 ) -> Result<Json<KeysetResponse>, Response> {
 ) -> Result<Json<KeysetResponse>, Response> {
-    let keysets = state.mint.auth_keysets().await.map_err(|err| {
-        tracing::error!("Could not get keysets: {}", err);
-        into_response(err)
-    })?;
-
-    Ok(Json(keysets))
+    Ok(Json(state.mint.auth_keysets()))
 }
 }
 
 
 #[cfg_attr(feature = "swagger", utoipa::path(
 #[cfg_attr(feature = "swagger", utoipa::path(
@@ -125,7 +120,7 @@ pub async fn get_auth_keysets(
 pub async fn get_blind_auth_keys(
 pub async fn get_blind_auth_keys(
     State(state): State<MintState>,
     State(state): State<MintState>,
 ) -> Result<Json<KeysResponse>, Response> {
 ) -> Result<Json<KeysResponse>, Response> {
-    let pubkeys = state.mint.auth_pubkeys().await.map_err(|err| {
+    let pubkeys = state.mint.auth_pubkeys().map_err(|err| {
         tracing::error!("Could not get keys: {}", err);
         tracing::error!("Could not get keys: {}", err);
         into_response(err)
         into_response(err)
     })?;
     })?;

+ 3 - 13
crates/cdk-axum/src/router_handlers.rs

@@ -86,12 +86,7 @@ post_cache_wrapper!(
 pub(crate) async fn get_keys(
 pub(crate) async fn get_keys(
     State(state): State<MintState>,
     State(state): State<MintState>,
 ) -> Result<Json<KeysResponse>, Response> {
 ) -> Result<Json<KeysResponse>, Response> {
-    let pubkeys = state.mint.pubkeys().await.map_err(|err| {
-        tracing::error!("Could not get keys: {}", err);
-        into_response(err)
-    })?;
-
-    Ok(Json(pubkeys))
+    Ok(Json(state.mint.pubkeys()))
 }
 }
 
 
 #[cfg_attr(feature = "swagger", utoipa::path(
 #[cfg_attr(feature = "swagger", utoipa::path(
@@ -114,7 +109,7 @@ pub(crate) async fn get_keyset_pubkeys(
     State(state): State<MintState>,
     State(state): State<MintState>,
     Path(keyset_id): Path<Id>,
     Path(keyset_id): Path<Id>,
 ) -> Result<Json<KeysResponse>, Response> {
 ) -> Result<Json<KeysResponse>, Response> {
-    let pubkeys = state.mint.keyset_pubkeys(&keyset_id).await.map_err(|err| {
+    let pubkeys = state.mint.keyset_pubkeys(&keyset_id).map_err(|err| {
         tracing::error!("Could not get keyset pubkeys: {}", err);
         tracing::error!("Could not get keyset pubkeys: {}", err);
         into_response(err)
         into_response(err)
     })?;
     })?;
@@ -138,12 +133,7 @@ pub(crate) async fn get_keyset_pubkeys(
 pub(crate) async fn get_keysets(
 pub(crate) async fn get_keysets(
     State(state): State<MintState>,
     State(state): State<MintState>,
 ) -> Result<Json<KeysetResponse>, Response> {
 ) -> Result<Json<KeysetResponse>, Response> {
-    let keysets = state.mint.keysets().await.map_err(|err| {
-        tracing::error!("Could not get keysets: {}", err);
-        into_response(err)
-    })?;
-
-    Ok(Json(keysets))
+    Ok(Json(state.mint.keysets()))
 }
 }
 
 
 #[cfg_attr(feature = "swagger", utoipa::path(
 #[cfg_attr(feature = "swagger", utoipa::path(

+ 3 - 6
crates/cdk-integration-tests/src/init_pure_tests.rs

@@ -56,18 +56,15 @@ impl Debug for DirectMintConnection {
 #[async_trait]
 #[async_trait]
 impl MintConnector for DirectMintConnection {
 impl MintConnector for DirectMintConnection {
     async fn get_mint_keys(&self) -> Result<Vec<KeySet>, Error> {
     async fn get_mint_keys(&self) -> Result<Vec<KeySet>, Error> {
-        self.mint.pubkeys().await.map(|pks| pks.keysets)
+        Ok(self.mint.pubkeys().keysets)
     }
     }
 
 
     async fn get_mint_keyset(&self, keyset_id: Id) -> Result<KeySet, Error> {
     async fn get_mint_keyset(&self, keyset_id: Id) -> Result<KeySet, Error> {
-        self.mint
-            .keyset(&keyset_id)
-            .await
-            .and_then(|res| res.ok_or(Error::UnknownKeySet))
+        self.mint.keyset(&keyset_id).ok_or(Error::UnknownKeySet)
     }
     }
 
 
     async fn get_mint_keysets(&self) -> Result<KeysetResponse, Error> {
     async fn get_mint_keysets(&self) -> Result<KeysetResponse, Error> {
-        self.mint.keysets().await
+        Ok(self.mint.keysets())
     }
     }
 
 
     async fn post_mint_quote(
     async fn post_mint_quote(

+ 6 - 54
crates/cdk-integration-tests/tests/integration_tests_pure.rs

@@ -237,15 +237,7 @@ async fn test_mint_double_spend() {
         .await
         .await
         .expect("Could not get proofs");
         .expect("Could not get proofs");
 
 
-    let keys = mint_bob
-        .pubkeys()
-        .await
-        .unwrap()
-        .keysets
-        .first()
-        .unwrap()
-        .clone()
-        .keys;
+    let keys = mint_bob.pubkeys().keysets.first().unwrap().clone().keys;
     let keyset_id = Id::from(&keys);
     let keyset_id = Id::from(&keys);
 
 
     let preswap = PreMintSecrets::random(
     let preswap = PreMintSecrets::random(
@@ -302,15 +294,7 @@ async fn test_attempt_to_swap_by_overflowing() {
 
 
     let amount = 2_u64.pow(63);
     let amount = 2_u64.pow(63);
 
 
-    let keys = mint_bob
-        .pubkeys()
-        .await
-        .unwrap()
-        .keysets
-        .first()
-        .unwrap()
-        .clone()
-        .keys;
+    let keys = mint_bob.pubkeys().keysets.first().unwrap().clone().keys;
     let keyset_id = Id::from(&keys);
     let keyset_id = Id::from(&keys);
 
 
     let pre_mint_amount =
     let pre_mint_amount =
@@ -431,15 +415,7 @@ pub async fn test_p2pk_swap() {
 
 
     let swap_request = SwapRequest::new(proofs.clone(), pre_swap.blinded_messages());
     let swap_request = SwapRequest::new(proofs.clone(), pre_swap.blinded_messages());
 
 
-    let keys = mint_bob
-        .pubkeys()
-        .await
-        .unwrap()
-        .keysets
-        .first()
-        .cloned()
-        .unwrap()
-        .keys;
+    let keys = mint_bob.pubkeys().keysets.first().cloned().unwrap().keys;
 
 
     let post_swap = mint_bob.process_swap_request(swap_request).await.unwrap();
     let post_swap = mint_bob.process_swap_request(swap_request).await.unwrap();
 
 
@@ -555,15 +531,7 @@ async fn test_swap_overpay_underpay_fee() {
         .await
         .await
         .expect("Could not get proofs");
         .expect("Could not get proofs");
 
 
-    let keys = mint_bob
-        .pubkeys()
-        .await
-        .unwrap()
-        .keysets
-        .first()
-        .unwrap()
-        .clone()
-        .keys;
+    let keys = mint_bob.pubkeys().keysets.first().unwrap().clone().keys;
     let keyset_id = Id::from(&keys);
     let keyset_id = Id::from(&keys);
 
 
     let preswap = PreMintSecrets::random(keyset_id, 9998.into(), &SplitTarget::default()).unwrap();
     let preswap = PreMintSecrets::random(keyset_id, 9998.into(), &SplitTarget::default()).unwrap();
@@ -629,15 +597,7 @@ async fn test_mint_enforce_fee() {
         .await
         .await
         .expect("Could not get proofs");
         .expect("Could not get proofs");
 
 
-    let keys = mint_bob
-        .pubkeys()
-        .await
-        .unwrap()
-        .keysets
-        .first()
-        .unwrap()
-        .clone()
-        .keys;
+    let keys = mint_bob.pubkeys().keysets.first().unwrap().clone().keys;
     let keyset_id = Id::from(&keys);
     let keyset_id = Id::from(&keys);
 
 
     let five_proofs: Vec<_> = proofs.drain(..5).collect();
     let five_proofs: Vec<_> = proofs.drain(..5).collect();
@@ -924,14 +884,6 @@ async fn test_concurrent_double_spend_melt() {
 }
 }
 
 
 async fn get_keyset_id(mint: &Mint) -> Id {
 async fn get_keyset_id(mint: &Mint) -> Id {
-    let keys = mint
-        .pubkeys()
-        .await
-        .unwrap()
-        .keysets
-        .first()
-        .unwrap()
-        .clone()
-        .keys;
+    let keys = mint.pubkeys().keysets.first().unwrap().clone().keys;
     Id::from(&keys)
     Id::from(&keys)
 }
 }

+ 5 - 13
crates/cdk-integration-tests/tests/mint.rs

@@ -66,33 +66,25 @@ async fn test_correct_keyset() {
         .await
         .await
         .unwrap();
         .unwrap();
 
 
-    let active = mint.get_active_keysets().await.expect("get_active_keysets");
+    let active = mint.get_active_keysets();
 
 
     let active = active
     let active = active
         .get(&CurrencyUnit::Sat)
         .get(&CurrencyUnit::Sat)
         .expect("There is a keyset for unit");
         .expect("There is a keyset for unit");
 
 
-    let keyset_info = mint
-        .get_keyset_info(active)
-        .await
-        .unwrap()
-        .expect("There is keyset");
+    let keyset_info = mint.get_keyset_info(active).expect("There is keyset");
 
 
-    assert!(keyset_info.derivation_path_index == Some(2));
+    assert_eq!(keyset_info.derivation_path_index, Some(2));
 
 
     let mint = mint_builder.build().await.unwrap();
     let mint = mint_builder.build().await.unwrap();
 
 
-    let active = mint.get_active_keysets().await.expect("get_active_keysets");
+    let active = mint.get_active_keysets();
 
 
     let active = active
     let active = active
         .get(&CurrencyUnit::Sat)
         .get(&CurrencyUnit::Sat)
         .expect("There is a keyset for unit");
         .expect("There is a keyset for unit");
 
 
-    let keyset_info = mint
-        .get_keyset_info(active)
-        .await
-        .unwrap()
-        .expect("There is keyset");
+    let keyset_info = mint.get_keyset_info(active).expect("There is keyset");
 
 
     assert!(keyset_info.derivation_path_index == Some(2));
     assert!(keyset_info.derivation_path_index == Some(2));
 }
 }

+ 1 - 0
crates/cdk/Cargo.toml

@@ -45,6 +45,7 @@ jsonwebtoken = { workspace = true, optional = true }
 # -Z minimal-versions
 # -Z minimal-versions
 sync_wrapper = "0.1.2"
 sync_wrapper = "0.1.2"
 bech32 = "0.9.1"
 bech32 = "0.9.1"
+arc-swap = "1.7.1"
 
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 tokio = { workspace = true, features = [
 tokio = { workspace = true, features = [

+ 13 - 14
crates/cdk/src/mint/keysets/auth.rs

@@ -10,14 +10,14 @@ impl Mint {
     /// Retrieve the auth public keys of the active keyset for distribution to wallet
     /// Retrieve the auth public keys of the active keyset for distribution to wallet
     /// clients
     /// clients
     #[instrument(skip_all)]
     #[instrument(skip_all)]
-    pub async fn auth_pubkeys(&self) -> Result<KeysResponse, Error> {
+    pub fn auth_pubkeys(&self) -> Result<KeysResponse, Error> {
         let key = self
         let key = self
-            .signatory
-            .keysets()
-            .await?
-            .into_iter()
+            .keysets
+            .load()
+            .iter()
             .find(|key| key.info.unit == CurrencyUnit::Auth)
             .find(|key| key.info.unit == CurrencyUnit::Auth)
-            .ok_or(Error::NoActiveKeyset)?;
+            .ok_or(Error::NoActiveKeyset)?
+            .clone();
 
 
         Ok(KeysResponse {
         Ok(KeysResponse {
             keysets: vec![key.key],
             keysets: vec![key.key],
@@ -26,21 +26,20 @@ impl Mint {
 
 
     /// Return a list of auth keysets
     /// Return a list of auth keysets
     #[instrument(skip_all)]
     #[instrument(skip_all)]
-    pub async fn auth_keysets(&self) -> Result<KeysetResponse, Error> {
-        Ok(KeysetResponse {
+    pub fn auth_keysets(&self) -> KeysetResponse {
+        KeysetResponse {
             keysets: self
             keysets: self
-                .signatory
-                .keysets()
-                .await?
-                .into_iter()
+                .keysets
+                .load()
+                .iter()
                 .filter_map(|key| {
                 .filter_map(|key| {
                     if key.info.unit == CurrencyUnit::Auth {
                     if key.info.unit == CurrencyUnit::Auth {
-                        Some(key.info.into())
+                        Some(key.info.clone().into())
                     } else {
                     } else {
                         None
                         None
                     }
                     }
                 })
                 })
                 .collect(),
                 .collect(),
-        })
+        }
     }
     }
 }
 }

+ 48 - 41
crates/cdk/src/mint/keysets/mod.rs

@@ -13,64 +13,59 @@ impl Mint {
     /// Retrieve the public keys of the active keyset for distribution to wallet
     /// Retrieve the public keys of the active keyset for distribution to wallet
     /// clients
     /// clients
     #[instrument(skip(self))]
     #[instrument(skip(self))]
-    pub async fn keyset_pubkeys(&self, keyset_id: &Id) -> Result<KeysResponse, Error> {
-        self.signatory
-            .keysets()
-            .await?
-            .into_iter()
+    pub fn keyset_pubkeys(&self, keyset_id: &Id) -> Result<KeysResponse, Error> {
+        self.keysets
+            .load()
+            .iter()
             .find(|keyset| &keyset.key.id == keyset_id)
             .find(|keyset| &keyset.key.id == keyset_id)
             .ok_or(Error::UnknownKeySet)
             .ok_or(Error::UnknownKeySet)
             .map(|key| KeysResponse {
             .map(|key| KeysResponse {
-                keysets: vec![key.key],
+                keysets: vec![key.key.clone()],
             })
             })
     }
     }
 
 
     /// Retrieve the public keys of the active keyset for distribution to wallet
     /// Retrieve the public keys of the active keyset for distribution to wallet
     /// clients
     /// clients
     #[instrument(skip_all)]
     #[instrument(skip_all)]
-    pub async fn pubkeys(&self) -> Result<KeysResponse, Error> {
-        Ok(KeysResponse {
+    pub fn pubkeys(&self) -> KeysResponse {
+        KeysResponse {
             keysets: self
             keysets: self
-                .signatory
-                .keysets()
-                .await?
-                .into_iter()
+                .keysets
+                .load()
+                .iter()
                 .filter(|keyset| keyset.info.active && keyset.info.unit != CurrencyUnit::Auth)
                 .filter(|keyset| keyset.info.active && keyset.info.unit != CurrencyUnit::Auth)
-                .map(|key| key.key)
+                .map(|key| key.key.clone())
                 .collect::<Vec<_>>(),
                 .collect::<Vec<_>>(),
-        })
+        }
     }
     }
 
 
     /// Return a list of all supported keysets
     /// Return a list of all supported keysets
     #[instrument(skip_all)]
     #[instrument(skip_all)]
-    pub async fn keysets(&self) -> Result<KeysetResponse, Error> {
-        let keysets = self
-            .signatory
-            .keysets()
-            .await?
-            .into_iter()
-            .filter(|k| k.key.unit != CurrencyUnit::Auth)
-            .map(|k| KeySetInfo {
-                id: k.key.id,
-                unit: k.key.unit,
-                active: k.info.active,
-                input_fee_ppk: k.info.input_fee_ppk,
-            })
-            .collect();
-
-        Ok(KeysetResponse { keysets })
+    pub fn keysets(&self) -> KeysetResponse {
+        KeysetResponse {
+            keysets: self
+                .keysets
+                .load()
+                .iter()
+                .filter(|k| k.key.unit != CurrencyUnit::Auth)
+                .map(|k| KeySetInfo {
+                    id: k.key.id,
+                    unit: k.key.unit.clone(),
+                    active: k.info.active,
+                    input_fee_ppk: k.info.input_fee_ppk,
+                })
+                .collect(),
+        }
     }
     }
 
 
     /// Get keysets
     /// Get keysets
     #[instrument(skip(self))]
     #[instrument(skip(self))]
-    pub async fn keyset(&self, id: &Id) -> Result<Option<KeySet>, Error> {
-        Ok(self
-            .signatory
-            .keysets()
-            .await?
-            .into_iter()
+    pub fn keyset(&self, id: &Id) -> Option<KeySet> {
+        self.keysets
+            .load()
+            .iter()
             .find(|key| &key.key.id == id)
             .find(|key| &key.key.id == id)
-            .map(|x| x.key))
+            .map(|x| x.key.clone())
     }
     }
 
 
     /// Add current keyset to inactive keysets
     /// Add current keyset to inactive keysets
@@ -83,14 +78,20 @@ impl Mint {
         max_order: u8,
         max_order: u8,
         input_fee_ppk: u64,
         input_fee_ppk: u64,
     ) -> Result<MintKeySetInfo, Error> {
     ) -> Result<MintKeySetInfo, Error> {
-        self.signatory
+        let result = self
+            .signatory
             .rotate_keyset(RotateKeyArguments {
             .rotate_keyset(RotateKeyArguments {
                 unit,
                 unit,
                 derivation_path_index: Some(derivation_path_index),
                 derivation_path_index: Some(derivation_path_index),
                 max_order,
                 max_order,
                 input_fee_ppk,
                 input_fee_ppk,
             })
             })
-            .await
+            .await?;
+
+        let new_keyset = self.signatory.keysets().await?;
+        self.keysets.store(new_keyset.into());
+
+        Ok(result)
     }
     }
 
 
     /// Rotate to next keyset for unit
     /// Rotate to next keyset for unit
@@ -101,13 +102,19 @@ impl Mint {
         max_order: u8,
         max_order: u8,
         input_fee_ppk: u64,
         input_fee_ppk: u64,
     ) -> Result<MintKeySetInfo, Error> {
     ) -> Result<MintKeySetInfo, Error> {
-        self.signatory
+        let result = self
+            .signatory
             .rotate_keyset(RotateKeyArguments {
             .rotate_keyset(RotateKeyArguments {
                 unit,
                 unit,
                 max_order,
                 max_order,
                 derivation_path_index: None,
                 derivation_path_index: None,
                 input_fee_ppk,
                 input_fee_ppk,
             })
             })
-            .await
+            .await?;
+
+        let new_keyset = self.signatory.keysets().await?;
+        self.keysets.store(new_keyset.into());
+
+        Ok(result)
     }
     }
 }
 }

+ 25 - 24
crates/cdk/src/mint/mod.rs

@@ -3,6 +3,7 @@
 use std::collections::HashMap;
 use std::collections::HashMap;
 use std::sync::Arc;
 use std::sync::Arc;
 
 
+use arc_swap::ArcSwap;
 use bitcoin::bip32::{DerivationPath, Xpriv};
 use bitcoin::bip32::{DerivationPath, Xpriv};
 use bitcoin::secp256k1;
 use bitcoin::secp256k1;
 use cdk_common::common::{PaymentProcessorKey, QuoteTTL};
 use cdk_common::common::{PaymentProcessorKey, QuoteTTL};
@@ -13,7 +14,7 @@ use cdk_common::nuts::{
     self, BlindSignature, BlindedMessage, CurrencyUnit, Id, Kind, MintKeySet, Proof,
     self, BlindSignature, BlindedMessage, CurrencyUnit, Id, Kind, MintKeySet, Proof,
 };
 };
 use cdk_common::secret;
 use cdk_common::secret;
-use cdk_signatory::signatory::Signatory;
+use cdk_signatory::signatory::{Signatory, SignatoryKeySet};
 use futures::StreamExt;
 use futures::StreamExt;
 #[cfg(feature = "auth")]
 #[cfg(feature = "auth")]
 use nut21::ProtectedEndpoint;
 use nut21::ProtectedEndpoint;
@@ -69,6 +70,8 @@ pub struct Mint {
     pub pubsub_manager: Arc<PubSubManager>,
     pub pubsub_manager: Arc<PubSubManager>,
     #[cfg(feature = "auth")]
     #[cfg(feature = "auth")]
     oidc_client: Option<OidcClient>,
     oidc_client: Option<OidcClient>,
+    /// In-memory keyset
+    keysets: Arc<ArcSwap<Vec<SignatoryKeySet>>>,
 }
 }
 
 
 impl Mint {
 impl Mint {
@@ -150,6 +153,8 @@ impl Mint {
         let oidc_client =
         let oidc_client =
             open_id_discovery.map(|openid_discovery| OidcClient::new(openid_discovery.clone()));
             open_id_discovery.map(|openid_discovery| OidcClient::new(openid_discovery.clone()));
 
 
+        let keysets = signatory.keysets().await?;
+
         Ok(Self {
         Ok(Self {
             signatory,
             signatory,
             pubsub_manager: Arc::new(localstore.clone().into()),
             pubsub_manager: Arc::new(localstore.clone().into()),
@@ -159,6 +164,7 @@ impl Mint {
             ln,
             ln,
             #[cfg(feature = "auth")]
             #[cfg(feature = "auth")]
             auth_localstore,
             auth_localstore,
+            keysets: Arc::new(ArcSwap::new(keysets.into())),
         })
         })
     }
     }
 
 
@@ -292,7 +298,6 @@ impl Mint {
             {
             {
                 let mint_keyset_info = self
                 let mint_keyset_info = self
                     .get_keyset_info(&proof.keyset_id)
                     .get_keyset_info(&proof.keyset_id)
-                    .await?
                     .ok_or(Error::UnknownKeySet)?;
                     .ok_or(Error::UnknownKeySet)?;
                 e.insert(mint_keyset_info.input_fee_ppk);
                 e.insert(mint_keyset_info.input_fee_ppk);
             }
             }
@@ -309,12 +314,10 @@ impl Mint {
     }
     }
 
 
     /// Get active keysets
     /// Get active keysets
-    pub async fn get_active_keysets(&self) -> Result<HashMap<CurrencyUnit, Id>, Error> {
-        Ok(self
-            .signatory
-            .keysets()
-            .await?
-            .into_iter()
+    pub fn get_active_keysets(&self) -> HashMap<CurrencyUnit, Id> {
+        self.keysets
+            .load()
+            .iter()
             .filter_map(|keyset| {
             .filter_map(|keyset| {
                 if keyset.info.active {
                 if keyset.info.active {
                     Some((keyset.info.unit.clone(), keyset.info.id))
                     Some((keyset.info.unit.clone(), keyset.info.id))
@@ -322,24 +325,22 @@ impl Mint {
                     None
                     None
                 }
                 }
             })
             })
-            .collect())
+            .collect()
     }
     }
 
 
     /// Get keyset info
     /// Get keyset info
-    pub async fn get_keyset_info(&self, id: &Id) -> Result<Option<MintKeySetInfo>, Error> {
-        Ok(self
-            .signatory
-            .keysets()
-            .await?
-            .into_iter()
+    pub fn get_keyset_info(&self, id: &Id) -> Option<MintKeySetInfo> {
+        self.keysets
+            .load()
+            .iter()
             .filter_map(|keyset| {
             .filter_map(|keyset| {
                 if keyset.info.id == *id {
                 if keyset.info.id == *id {
-                    Some(keyset.info)
+                    Some(keyset.info.clone())
                 } else {
                 } else {
                     None
                     None
                 }
                 }
             })
             })
-            .next())
+            .next()
     }
     }
 
 
     /// Blind Sign
     /// Blind Sign
@@ -467,7 +468,7 @@ impl Mint {
     /// Get the total amount issed by keyset
     /// Get the total amount issed by keyset
     #[instrument(skip_all)]
     #[instrument(skip_all)]
     pub async fn total_issued(&self) -> Result<HashMap<Id, Amount>, Error> {
     pub async fn total_issued(&self) -> Result<HashMap<Id, Amount>, Error> {
-        let keysets = self.keysets().await?.keysets;
+        let keysets = self.keysets().keysets;
 
 
         let mut total_issued = HashMap::new();
         let mut total_issued = HashMap::new();
 
 
@@ -488,7 +489,7 @@ impl Mint {
     /// Total redeemed for keyset
     /// Total redeemed for keyset
     #[instrument(skip_all)]
     #[instrument(skip_all)]
     pub async fn total_redeemed(&self) -> Result<HashMap<Id, Amount>, Error> {
     pub async fn total_redeemed(&self) -> Result<HashMap<Id, Amount>, Error> {
-        let keysets = self.keysets().await?.keysets;
+        let keysets = self.keysets().keysets;
 
 
         let mut total_redeemed = HashMap::new();
         let mut total_redeemed = HashMap::new();
 
 
@@ -606,14 +607,14 @@ mod tests {
         let mint = create_mint(config).await;
         let mint = create_mint(config).await;
 
 
         assert_eq!(
         assert_eq!(
-            mint.pubkeys().await.unwrap(),
+            mint.pubkeys(),
             KeysResponse {
             KeysResponse {
                 keysets: Vec::new()
                 keysets: Vec::new()
             }
             }
         );
         );
 
 
         assert_eq!(
         assert_eq!(
-            mint.keysets().await.unwrap(),
+            mint.keysets(),
             KeysetResponse {
             KeysetResponse {
                 keysets: Vec::new()
                 keysets: Vec::new()
             }
             }
@@ -637,7 +638,7 @@ mod tests {
         };
         };
         let mint = create_mint(config).await;
         let mint = create_mint(config).await;
 
 
-        let keysets = mint.keysets().await.unwrap();
+        let keysets = mint.keysets();
         assert!(keysets.keysets.is_empty());
         assert!(keysets.keysets.is_empty());
 
 
         // generate the first keyset and set it to active
         // generate the first keyset and set it to active
@@ -645,7 +646,7 @@ mod tests {
             .await
             .await
             .expect("test");
             .expect("test");
 
 
-        let keysets = mint.keysets().await.unwrap();
+        let keysets = mint.keysets();
         assert!(keysets.keysets.len().eq(&1));
         assert!(keysets.keysets.len().eq(&1));
         assert!(keysets.keysets[0].active);
         assert!(keysets.keysets[0].active);
         let first_keyset_id = keysets.keysets[0].id;
         let first_keyset_id = keysets.keysets[0].id;
@@ -655,7 +656,7 @@ mod tests {
             .await
             .await
             .expect("test");
             .expect("test");
 
 
-        let keysets = mint.keysets().await.unwrap();
+        let keysets = mint.keysets();
 
 
         assert_eq!(2, keysets.keysets.len());
         assert_eq!(2, keysets.keysets.len());
         for keyset in &keysets.keysets {
         for keyset in &keysets.keysets {

+ 2 - 2
crates/cdk/src/mint/verification.rs

@@ -66,7 +66,7 @@ impl Mint {
         let output_keyset_ids: HashSet<Id> = outputs.iter().map(|p| p.keyset_id).collect();
         let output_keyset_ids: HashSet<Id> = outputs.iter().map(|p| p.keyset_id).collect();
 
 
         for id in &output_keyset_ids {
         for id in &output_keyset_ids {
-            match self.get_keyset_info(id).await? {
+            match self.get_keyset_info(id) {
                 Some(keyset) => {
                 Some(keyset) => {
                     if !keyset.active {
                     if !keyset.active {
                         tracing::debug!(
                         tracing::debug!(
@@ -114,7 +114,7 @@ impl Mint {
         let inputs_keyset_ids: HashSet<Id> = inputs.iter().map(|p| p.keyset_id).collect();
         let inputs_keyset_ids: HashSet<Id> = inputs.iter().map(|p| p.keyset_id).collect();
 
 
         for id in &inputs_keyset_ids {
         for id in &inputs_keyset_ids {
-            match self.get_keyset_info(id).await? {
+            match self.get_keyset_info(id) {
                 Some(keyset) => {
                 Some(keyset) => {
                     keyset_units.insert(keyset.unit);
                     keyset_units.insert(keyset.unit);
                 }
                 }

+ 1 - 1
justfile

@@ -57,7 +57,7 @@ test-pure db="memory": build
   fi
   fi
 
 
   # Run pure integration tests
   # Run pure integration tests
-  CDK_TEST_DB_TYPE={{db}} cargo test -p cdk-integration-tests --test integration_tests_pure
+  CDK_TEST_DB_TYPE={{db}} cargo test -p cdk-integration-tests --test integration_tests_pure -- --test-threads 1
 
 
 test-all db="memory":
 test-all db="memory":
     #!/usr/bin/env bash
     #!/usr/bin/env bash