|
|
@@ -5,13 +5,14 @@ use std::ops::DerefMut;
|
|
|
use std::path::Path;
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
-use async_rusqlite::{query, DatabaseExecutor};
|
|
|
+use async_rusqlite::{query, DatabaseExecutor, Transaction};
|
|
|
use async_trait::async_trait;
|
|
|
use bitcoin::bip32::DerivationPath;
|
|
|
use cdk_common::common::QuoteTTL;
|
|
|
+use cdk_common::database::mint::DbWriter;
|
|
|
use cdk_common::database::{
|
|
|
- self, MintDatabase, MintKeysDatabase, MintProofsDatabase, MintQuotesDatabase,
|
|
|
- MintSignaturesDatabase,
|
|
|
+ self, MintDatabase, MintDbWriterFinalizer, MintKeyDatabaseWriter, MintKeysDatabase,
|
|
|
+ MintProofsDatabase, MintQuotesDatabase, MintSignaturesDatabase,
|
|
|
};
|
|
|
use cdk_common::mint::{self, MintKeySetInfo, MintQuote};
|
|
|
use cdk_common::nut00::ProofsMethods;
|
|
|
@@ -135,28 +136,101 @@ impl MintSqliteDatabase {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/// Sqlite Writer
|
|
|
+pub struct SqliteWriter<'a> {
|
|
|
+ transaction: Transaction<'a>,
|
|
|
+}
|
|
|
+
|
|
|
#[async_trait]
|
|
|
-impl MintKeysDatabase for MintSqliteDatabase {
|
|
|
+impl<'a> MintDbWriterFinalizer for SqliteWriter<'a> {
|
|
|
type Err = database::Error;
|
|
|
|
|
|
- async fn set_active_keyset(&self, unit: CurrencyUnit, id: Id) -> Result<(), Self::Err> {
|
|
|
- let transaction = self.pool.begin().await?;
|
|
|
+ async fn commit(self: Box<Self>) -> Result<(), database::Error> {
|
|
|
+ Ok(self.transaction.commit().await?)
|
|
|
+ }
|
|
|
|
|
|
+ async fn rollback(self: Box<Self>) -> Result<(), database::Error> {
|
|
|
+ Ok(self.transaction.rollback().await?)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[async_trait]
|
|
|
+impl<'a> MintKeyDatabaseWriter<'a, database::Error> for SqliteWriter<'a> {
|
|
|
+ async fn add_keyset_info(&mut self, keyset: MintKeySetInfo) -> Result<(), database::Error> {
|
|
|
+ query(
|
|
|
+ r#"
|
|
|
+ INSERT INTO
|
|
|
+ keyset (
|
|
|
+ id, unit, active, valid_from, valid_to, derivation_path,
|
|
|
+ max_order, input_fee_ppk, derivation_path_index
|
|
|
+ )
|
|
|
+ VALUES (
|
|
|
+ :id, :unit, :active, :valid_from, :valid_to, :derivation_path,
|
|
|
+ :max_order, :input_fee_ppk, :derivation_path_index
|
|
|
+ )
|
|
|
+ ON CONFLICT(id) DO UPDATE SET
|
|
|
+ unit = excluded.unit,
|
|
|
+ active = excluded.active,
|
|
|
+ valid_from = excluded.valid_from,
|
|
|
+ valid_to = excluded.valid_to,
|
|
|
+ derivation_path = excluded.derivation_path,
|
|
|
+ max_order = excluded.max_order,
|
|
|
+ input_fee_ppk = excluded.input_fee_ppk,
|
|
|
+ derivation_path_index = excluded.derivation_path_index
|
|
|
+ "#,
|
|
|
+ )
|
|
|
+ .bind(":id", keyset.id.to_string())
|
|
|
+ .bind(":unit", keyset.unit.to_string())
|
|
|
+ .bind(":active", keyset.active)
|
|
|
+ .bind(":valid_from", keyset.valid_from as i64)
|
|
|
+ .bind(":valid_to", keyset.final_expiry.map(|v| v as i64))
|
|
|
+ .bind(":derivation_path", keyset.derivation_path.to_string())
|
|
|
+ .bind(":max_order", keyset.max_order)
|
|
|
+ .bind(":input_fee_ppk", keyset.input_fee_ppk as i64)
|
|
|
+ .bind(":derivation_path_index", keyset.derivation_path_index)
|
|
|
+ .execute(&self.transaction)
|
|
|
+ .await?;
|
|
|
+
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn set_active_keyset(
|
|
|
+ &mut self,
|
|
|
+ unit: CurrencyUnit,
|
|
|
+ id: Id,
|
|
|
+ ) -> Result<(), database::Error> {
|
|
|
query(r#"UPDATE keyset SET active=FALSE WHERE unit IS :unit"#)
|
|
|
.bind(":unit", unit.to_string())
|
|
|
- .execute(&transaction)
|
|
|
+ .execute(&self.transaction)
|
|
|
.await?;
|
|
|
|
|
|
query(r#"UPDATE keyset SET active=TRUE WHERE unit IS :unit AND id IS :id"#)
|
|
|
.bind(":unit", unit.to_string())
|
|
|
.bind(":id", id.to_string())
|
|
|
- .execute(&transaction)
|
|
|
+ .execute(&self.transaction)
|
|
|
.await?;
|
|
|
|
|
|
- transaction.commit().await?;
|
|
|
-
|
|
|
Ok(())
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+#[async_trait]
|
|
|
+impl<'a> DbWriter<'a, database::Error> for SqliteWriter<'a> {}
|
|
|
+
|
|
|
+#[async_trait]
|
|
|
+impl MintKeysDatabase for MintSqliteDatabase {
|
|
|
+ type Err = database::Error;
|
|
|
+
|
|
|
+ async fn begin_transaction<'a>(
|
|
|
+ &'a self,
|
|
|
+ ) -> Result<
|
|
|
+ Box<dyn MintKeyDatabaseWriter<'a, database::Error> + Send + Sync + 'a>,
|
|
|
+ database::Error,
|
|
|
+ > {
|
|
|
+ Ok(Box::new(SqliteWriter {
|
|
|
+ transaction: self.pool.begin().await?,
|
|
|
+ }))
|
|
|
+ }
|
|
|
|
|
|
async fn get_active_keyset_id(&self, unit: &CurrencyUnit) -> Result<Option<Id>, Self::Err> {
|
|
|
Ok(
|
|
|
@@ -187,44 +261,6 @@ impl MintKeysDatabase for MintSqliteDatabase {
|
|
|
.collect::<Result<HashMap<_, _>, Error>>()?)
|
|
|
}
|
|
|
|
|
|
- async fn add_keyset_info(&self, keyset: MintKeySetInfo) -> Result<(), Self::Err> {
|
|
|
- query(
|
|
|
- r#"
|
|
|
- INSERT INTO
|
|
|
- keyset (
|
|
|
- id, unit, active, valid_from, valid_to, derivation_path,
|
|
|
- max_order, input_fee_ppk, derivation_path_index
|
|
|
- )
|
|
|
- VALUES (
|
|
|
- :id, :unit, :active, :valid_from, :valid_to, :derivation_path,
|
|
|
- :max_order, :input_fee_ppk, :derivation_path_index
|
|
|
- )
|
|
|
- ON CONFLICT(id) DO UPDATE SET
|
|
|
- unit = excluded.unit,
|
|
|
- active = excluded.active,
|
|
|
- valid_from = excluded.valid_from,
|
|
|
- valid_to = excluded.valid_to,
|
|
|
- derivation_path = excluded.derivation_path,
|
|
|
- max_order = excluded.max_order,
|
|
|
- input_fee_ppk = excluded.input_fee_ppk,
|
|
|
- derivation_path_index = excluded.derivation_path_index
|
|
|
- "#,
|
|
|
- )
|
|
|
- .bind(":id", keyset.id.to_string())
|
|
|
- .bind(":unit", keyset.unit.to_string())
|
|
|
- .bind(":active", keyset.active)
|
|
|
- .bind(":valid_from", keyset.valid_from as i64)
|
|
|
- .bind(":valid_to", keyset.final_expiry.map(|v| v as i64))
|
|
|
- .bind(":derivation_path", keyset.derivation_path.to_string())
|
|
|
- .bind(":max_order", keyset.max_order)
|
|
|
- .bind(":input_fee_ppk", keyset.input_fee_ppk as i64)
|
|
|
- .bind(":derivation_path_index", keyset.derivation_path_index)
|
|
|
- .execute(&self.pool)
|
|
|
- .await?;
|
|
|
-
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-
|
|
|
async fn get_keyset_info(&self, id: &Id) -> Result<Option<MintKeySetInfo>, Self::Err> {
|
|
|
Ok(query(
|
|
|
r#"SELECT
|
|
|
@@ -1097,6 +1133,14 @@ impl MintSignaturesDatabase for MintSqliteDatabase {
|
|
|
|
|
|
#[async_trait]
|
|
|
impl MintDatabase<database::Error> for MintSqliteDatabase {
|
|
|
+ async fn begin_transaction<'a>(
|
|
|
+ &'a self,
|
|
|
+ ) -> Result<Box<dyn DbWriter<'a, database::Error> + Send + Sync + 'a>, database::Error> {
|
|
|
+ Ok(Box::new(SqliteWriter {
|
|
|
+ transaction: self.pool.begin().await?,
|
|
|
+ }))
|
|
|
+ }
|
|
|
+
|
|
|
async fn set_mint_info(&self, mint_info: MintInfo) -> Result<(), database::Error> {
|
|
|
Ok(self.set_to_config("mint_info", &mint_info).await?)
|
|
|
}
|
|
|
@@ -1325,7 +1369,9 @@ mod tests {
|
|
|
input_fee_ppk: 0,
|
|
|
final_expiry: None,
|
|
|
};
|
|
|
- db.add_keyset_info(keyset_info).await.unwrap();
|
|
|
+ let mut tx = MintKeysDatabase::begin_transaction(&db).await.unwrap();
|
|
|
+ tx.add_keyset_info(keyset_info).await.unwrap();
|
|
|
+ tx.commit().await.unwrap();
|
|
|
|
|
|
let proofs = vec![
|
|
|
Proof {
|
|
|
@@ -1393,7 +1439,11 @@ mod tests {
|
|
|
input_fee_ppk: 0,
|
|
|
final_expiry: None,
|
|
|
};
|
|
|
- db.add_keyset_info(keyset_info).await.unwrap();
|
|
|
+ let mut tx = MintKeysDatabase::begin_transaction(&db)
|
|
|
+ .await
|
|
|
+ .expect("begin");
|
|
|
+ tx.add_keyset_info(keyset_info).await.unwrap();
|
|
|
+ tx.commit().await.expect("commit");
|
|
|
|
|
|
let proofs = vec![
|
|
|
Proof {
|