ソースを参照

Introduce MintKeysTransaction

This trait will let the mint have a copy of the keysets
Cesar Rodas 2 ヶ月 前
コミット
b2f72ad803

+ 18 - 0
crates/cdk-common/src/database/mint/mod.rs

@@ -364,6 +364,23 @@ pub trait SignaturesDatabase {
     async fn get_total_issued(&self) -> Result<HashMap<Id, Amount>, Self::Err>;
     async fn get_total_issued(&self) -> Result<HashMap<Id, Amount>, Self::Err>;
 }
 }
 
 
+/// Mint Keys transaction
+///
+/// This trait is used to call everytime the mint has new information from the Signatory, so the
+/// mint can prepare their database for the known keysets
+#[async_trait]
+pub trait MintKeysTransaction<'a> {
+    /// Database Error
+    type Err: Into<Error> + From<Error>;
+
+    /// Function to call everytime the signatory pushes information towards the mint
+    async fn set_signatory_keysets(
+        &mut self,
+        pubkey: &PublicKey,
+        keysets: &[MintKeySetInfo],
+    ) -> Result<(), Self::Err>;
+}
+
 #[async_trait]
 #[async_trait]
 /// Saga Transaction trait
 /// Saga Transaction trait
 pub trait SagaTransaction<'a> {
 pub trait SagaTransaction<'a> {
@@ -460,6 +477,7 @@ pub trait Transaction<'a, Error>:
     + ProofsTransaction<'a, Err = Error>
     + ProofsTransaction<'a, Err = Error>
     + KVStoreTransaction<'a, Error>
     + KVStoreTransaction<'a, Error>
     + SagaTransaction<'a, Err = Error>
     + SagaTransaction<'a, Err = Error>
+    + MintKeysTransaction<'a, Err = Error>
 {
 {
 }
 }
 
 

+ 4 - 3
crates/cdk-common/src/database/mod.rs

@@ -10,9 +10,10 @@ pub use mint::{
     Database as MintDatabase, DbTransactionFinalizer as MintDbWriterFinalizer, DynMintDatabase,
     Database as MintDatabase, DbTransactionFinalizer as MintDbWriterFinalizer, DynMintDatabase,
     KVStore as MintKVStore, KVStoreDatabase as MintKVStoreDatabase,
     KVStore as MintKVStore, KVStoreDatabase as MintKVStoreDatabase,
     KVStoreTransaction as MintKVStoreTransaction, KeysDatabase as MintKeysDatabase,
     KVStoreTransaction as MintKVStoreTransaction, KeysDatabase as MintKeysDatabase,
-    KeysDatabaseTransaction as MintKeyDatabaseTransaction, ProofsDatabase as MintProofsDatabase,
-    ProofsTransaction as MintProofsTransaction, QuotesDatabase as MintQuotesDatabase,
-    QuotesTransaction as MintQuotesTransaction, SignaturesDatabase as MintSignaturesDatabase,
+    KeysDatabaseTransaction as MintKeyDatabaseTransaction, MintKeysTransaction,
+    ProofsDatabase as MintProofsDatabase, ProofsTransaction as MintProofsTransaction,
+    QuotesDatabase as MintQuotesDatabase, QuotesTransaction as MintQuotesTransaction,
+    SignaturesDatabase as MintSignaturesDatabase,
     SignaturesTransaction as MintSignatureTransaction, Transaction as MintTransaction,
     SignaturesTransaction as MintSignatureTransaction, Transaction as MintTransaction,
 };
 };
 #[cfg(all(feature = "mint", feature = "auth"))]
 #[cfg(all(feature = "mint", feature = "auth"))]

+ 42 - 51
crates/cdk-sql-common/src/mint/mod.rs

@@ -129,6 +129,48 @@ where
 }
 }
 
 
 #[async_trait]
 #[async_trait]
+impl<RM> database::MintKeysTransaction<'_> for SQLTransaction<RM>
+where
+    RM: DatabasePool + 'static,
+{
+    /// Database Error
+    type Err = Error;
+
+    /// Function to call everytime the signatory pushes information towards the mint
+    async fn set_signatory_keysets(
+        &mut self,
+        _pubkey: &PublicKey,
+        keysets: &[MintKeySetInfo],
+    ) -> Result<(), Self::Err> {
+        let known_keysets = query("SELECT keyset_id FROM keyset_amounts")?
+            .fetch_all(&self.inner)
+            .await?
+            .into_iter()
+            .map(|mut row| {
+                Ok(column_as_string!(
+                    row.remove(0),
+                    Id::from_str,
+                    Id::from_bytes
+                ))
+            })
+            .collect::<Result<HashSet<_>, Error>>()?;
+
+        for keyset in keysets {
+            if known_keysets.contains(&keyset.id) || keyset.unit == CurrencyUnit::Auth {
+                continue;
+            }
+
+            query(r#"INSERT INTO keyset_amounts VALUES(:keyset_id, 0, 0)"#)?
+                .bind("keyset_id", keyset.id.to_string())
+                .execute(&self.inner)
+                .await?;
+        }
+
+        Ok(())
+    }
+}
+
+#[async_trait]
 impl<RM> database::MintProofsTransaction<'_> for SQLTransaction<RM>
 impl<RM> database::MintProofsTransaction<'_> for SQLTransaction<RM>
 where
 where
     RM: DatabasePool + 'static,
     RM: DatabasePool + 'static,
@@ -222,26 +264,6 @@ where
         if new_state == State::Spent {
         if new_state == State::Spent {
             query(
             query(
                 r#"
                 r#"
-                INSERT INTO keyset_amounts (keyset_id, total_issued, total_redeemed)
-                SELECT p.keyset_id, 0, 0
-                FROM (
-                  SELECT DISTINCT keyset_id
-                  FROM proof
-                  WHERE y IN (:ys)
-                ) AS p
-                WHERE NOT EXISTS (
-                  SELECT 1
-                  FROM keyset_amounts ka
-                  WHERE ka.keyset_id = p.keyset_id
-                )
-            "#,
-            )?
-            .bind_vec("ys", ys.iter().map(|y| y.to_bytes().to_vec()).collect())
-            .execute(&self.inner)
-            .await?;
-
-            query(
-                r#"
                 UPDATE keyset_amounts
                 UPDATE keyset_amounts
                 SET total_redeemed = total_redeemed + amounts.total
                 SET total_redeemed = total_redeemed + amounts.total
                 FROM (
                 FROM (
@@ -1726,37 +1748,6 @@ where
         })
         })
         .collect::<Result<HashMap<_, _>, Error>>()?;
         .collect::<Result<HashMap<_, _>, Error>>()?;
 
 
-        let mut keysets = query("SELECT keyset_id FROM keyset_amounts")?
-            .fetch_all(&self.inner)
-            .await?
-            .into_iter()
-            .map(|mut row| {
-                Ok(column_as_string!(
-                    &row.remove(0),
-                    Id::from_str,
-                    Id::from_bytes
-                ))
-            })
-            .collect::<Result<HashSet<_>, Error>>()?;
-
-        for s in blind_signatures.iter() {
-            if keysets.contains(&s.keyset_id) {
-                continue;
-            }
-
-            keysets.insert(s.keyset_id);
-
-            query(
-                r#"
-                INSERT INTO keyset_amounts (keyset_id, total_issued, total_redeemed)
-                VALUES (:keyset, 0, 0)
-            "#,
-            )?
-            .bind("keyset", s.keyset_id.to_string())
-            .execute(&self.inner)
-            .await?;
-        }
-
         // Iterate over the provided blinded messages and signatures
         // Iterate over the provided blinded messages and signatures
         for (message, signature) in blinded_messages.iter().zip(blind_signatures) {
         for (message, signature) in blinded_messages.iter().zip(blind_signatures) {
             match existing_rows.remove(message) {
             match existing_rows.remove(message) {

+ 13 - 1
crates/cdk/src/mint/keysets/mod.rs

@@ -88,7 +88,19 @@ impl Mint {
             .await?;
             .await?;
 
 
         let new_keyset = self.signatory.keysets().await?;
         let new_keyset = self.signatory.keysets().await?;
-        self.keysets.store(new_keyset.keysets.into());
+        self.keysets.store(new_keyset.keysets.clone().into());
+
+        let mut tx = self.localstore.begin_transaction().await?;
+        tx.set_signatory_keysets(
+            &new_keyset.pubkey,
+            &new_keyset
+                .keysets
+                .iter()
+                .map(|x| x.into())
+                .collect::<Vec<_>>(),
+        )
+        .await?;
+        tx.commit().await?;
 
 
         Ok(result.into())
         Ok(result.into())
     }
     }

+ 13 - 21
crates/cdk/src/mint/mod.rs

@@ -144,6 +144,14 @@ impl Mint {
             return Err(Error::NoActiveKeyset);
             return Err(Error::NoActiveKeyset);
         }
         }
 
 
+        let mut tx = localstore.begin_transaction().await?;
+        tx.set_signatory_keysets(
+            &keysets.pubkey,
+            &keysets.keysets.iter().map(|x| x.into()).collect::<Vec<_>>(),
+        )
+        .await?;
+        tx.commit().await?;
+
         tracing::info!(
         tracing::info!(
             "Using Signatory {} with {} active keys",
             "Using Signatory {} with {} active keys",
             signatory.name(),
             signatory.name(),
@@ -950,16 +958,7 @@ impl Mint {
         #[cfg(feature = "prometheus")]
         #[cfg(feature = "prometheus")]
         global::inc_in_flight_requests("total_issued");
         global::inc_in_flight_requests("total_issued");
 
 
-        let result = async {
-            let keysets = self.keysets().keysets;
-            let mut total_issued = self.localstore.get_total_issued().await?;
-            for keyset in keysets.into_iter().filter(|x| x.unit != CurrencyUnit::Auth) {
-                let _ = total_issued.entry(keyset.id).or_default();
-            }
-
-            Ok(total_issued)
-        }
-        .await;
+        let result = async { Ok(self.localstore.get_total_issued().await?) }.await;
 
 
         #[cfg(feature = "prometheus")]
         #[cfg(feature = "prometheus")]
         {
         {
@@ -976,21 +975,12 @@ impl Mint {
         #[cfg(feature = "prometheus")]
         #[cfg(feature = "prometheus")]
         global::inc_in_flight_requests("total_redeemed");
         global::inc_in_flight_requests("total_redeemed");
 
 
-        let keysets = self.signatory.keysets().await?;
-        let mut total_redeemed = self.localstore.get_total_redeemed().await?;
-
-        for keyset in keysets
-            .keysets
-            .into_iter()
-            .filter(|x| x.unit != CurrencyUnit::Auth)
-        {
-            let _ = total_redeemed.entry(keyset.id).or_default();
-        }
+        let total_redeemed = async { Ok(self.localstore.get_total_redeemed().await?) }.await;
 
 
         #[cfg(feature = "prometheus")]
         #[cfg(feature = "prometheus")]
         global::dec_in_flight_requests("total_redeemed");
         global::dec_in_flight_requests("total_redeemed");
 
 
-        Ok(total_redeemed)
+        total_redeemed
     }
     }
 }
 }
 
 
@@ -1057,6 +1047,8 @@ mod tests {
         };
         };
         let mint = create_mint(config).await;
         let mint = create_mint(config).await;
 
 
+        println!("{:?}", mint.total_issued().await);
+
         assert_eq!(
         assert_eq!(
             mint.total_issued()
             mint.total_issued()
                 .await
                 .await