|
@@ -1,7 +1,9 @@
|
|
//! SQLite Wallet Database
|
|
//! SQLite Wallet Database
|
|
|
|
|
|
use std::collections::HashMap;
|
|
use std::collections::HashMap;
|
|
|
|
+use std::fmt::Debug;
|
|
use std::str::FromStr;
|
|
use std::str::FromStr;
|
|
|
|
+use std::sync::Arc;
|
|
|
|
|
|
use async_trait::async_trait;
|
|
use async_trait::async_trait;
|
|
use cdk_common::common::ProofInfo;
|
|
use cdk_common::common::ProofInfo;
|
|
@@ -17,7 +19,8 @@ use cdk_common::{
|
|
use tracing::instrument;
|
|
use tracing::instrument;
|
|
|
|
|
|
use crate::common::migrate;
|
|
use crate::common::migrate;
|
|
-use crate::database::DatabaseExecutor;
|
|
|
|
|
|
+use crate::database::{ConnectionWithTransaction, DatabaseExecutor};
|
|
|
|
+use crate::pool::{DatabasePool, Pool, PooledResource};
|
|
use crate::stmt::{query, Column};
|
|
use crate::stmt::{query, Column};
|
|
use crate::{
|
|
use crate::{
|
|
column_as_binary, column_as_nullable_binary, column_as_nullable_number,
|
|
column_as_binary, column_as_nullable_binary, column_as_nullable_number,
|
|
@@ -29,36 +32,43 @@ mod migrations;
|
|
|
|
|
|
/// Wallet SQLite Database
|
|
/// Wallet SQLite Database
|
|
#[derive(Debug, Clone)]
|
|
#[derive(Debug, Clone)]
|
|
-pub struct SQLWalletDatabase<T>
|
|
|
|
|
|
+pub struct SQLWalletDatabase<RM>
|
|
where
|
|
where
|
|
- T: DatabaseExecutor,
|
|
|
|
|
|
+ RM: DatabasePool + 'static,
|
|
{
|
|
{
|
|
- db: T,
|
|
|
|
|
|
+ pool: Arc<Pool<RM>>,
|
|
}
|
|
}
|
|
|
|
|
|
-impl<DB> SQLWalletDatabase<DB>
|
|
|
|
|
|
+impl<RM> SQLWalletDatabase<RM>
|
|
where
|
|
where
|
|
- DB: DatabaseExecutor,
|
|
|
|
|
|
+ RM: DatabasePool + 'static,
|
|
{
|
|
{
|
|
/// Creates a new instance
|
|
/// Creates a new instance
|
|
pub async fn new<X>(db: X) -> Result<Self, Error>
|
|
pub async fn new<X>(db: X) -> Result<Self, Error>
|
|
where
|
|
where
|
|
- X: Into<DB>,
|
|
|
|
|
|
+ X: Into<RM::Config>,
|
|
{
|
|
{
|
|
- let db = db.into();
|
|
|
|
- Self::migrate(&db).await?;
|
|
|
|
- Ok(Self { db })
|
|
|
|
|
|
+ let pool = Pool::new(db.into());
|
|
|
|
+ Self::migrate(pool.get().map_err(|e| Error::Database(Box::new(e)))?).await?;
|
|
|
|
+
|
|
|
|
+ Ok(Self { pool })
|
|
}
|
|
}
|
|
|
|
|
|
/// Migrate [`WalletSqliteDatabase`]
|
|
/// Migrate [`WalletSqliteDatabase`]
|
|
- async fn migrate(conn: &DB) -> Result<(), Error> {
|
|
|
|
- migrate(conn, DB::name(), migrations::MIGRATIONS).await?;
|
|
|
|
|
|
+ async fn migrate(conn: PooledResource<RM>) -> Result<(), Error> {
|
|
|
|
+ let tx = ConnectionWithTransaction::new(conn).await?;
|
|
|
|
+ migrate(&tx, RM::Connection::name(), migrations::MIGRATIONS).await?;
|
|
// Update any existing keys with missing keyset_u32 values
|
|
// Update any existing keys with missing keyset_u32 values
|
|
- Self::add_keyset_u32(conn).await?;
|
|
|
|
|
|
+ Self::add_keyset_u32(&tx).await?;
|
|
|
|
+ tx.commit().await?;
|
|
|
|
+
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
|
|
- async fn add_keyset_u32(conn: &DB) -> Result<(), Error> {
|
|
|
|
|
|
+ async fn add_keyset_u32<T>(conn: &T) -> Result<(), Error>
|
|
|
|
+ where
|
|
|
|
+ T: DatabaseExecutor,
|
|
|
|
+ {
|
|
// First get the keysets where keyset_u32 on key is null
|
|
// First get the keysets where keyset_u32 on key is null
|
|
let keys_without_u32: Vec<Vec<Column>> = query(
|
|
let keys_without_u32: Vec<Vec<Column>> = query(
|
|
r#"
|
|
r#"
|
|
@@ -126,14 +136,16 @@ where
|
|
}
|
|
}
|
|
|
|
|
|
#[async_trait]
|
|
#[async_trait]
|
|
-impl<T> WalletDatabase for SQLWalletDatabase<T>
|
|
|
|
|
|
+impl<RM> WalletDatabase for SQLWalletDatabase<RM>
|
|
where
|
|
where
|
|
- T: DatabaseExecutor,
|
|
|
|
|
|
+ RM: DatabasePool + 'static,
|
|
{
|
|
{
|
|
type Err = database::Error;
|
|
type Err = database::Error;
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn get_melt_quotes(&self) -> Result<Vec<wallet::MeltQuote>, Self::Err> {
|
|
async fn get_melt_quotes(&self) -> Result<Vec<wallet::MeltQuote>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -149,7 +161,7 @@ where
|
|
melt_quote
|
|
melt_quote
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
- .fetch_all(&self.db)
|
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
.await?
|
|
.await?
|
|
.into_iter()
|
|
.into_iter()
|
|
.map(sql_row_to_melt_quote)
|
|
.map(sql_row_to_melt_quote)
|
|
@@ -212,6 +224,8 @@ where
|
|
),
|
|
),
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
query(
|
|
query(
|
|
r#"
|
|
r#"
|
|
INSERT INTO mint
|
|
INSERT INTO mint
|
|
@@ -253,7 +267,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
.bind("motd", motd)
|
|
.bind("motd", motd)
|
|
.bind("mint_time", time.map(|v| v as i64))
|
|
.bind("mint_time", time.map(|v| v as i64))
|
|
.bind("tos_url", tos_url)
|
|
.bind("tos_url", tos_url)
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -261,9 +275,11 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn remove_mint(&self, mint_url: MintUrl) -> Result<(), Self::Err> {
|
|
async fn remove_mint(&self, mint_url: MintUrl) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
query(r#"DELETE FROM mint WHERE mint_url=:mint_url"#)?
|
|
query(r#"DELETE FROM mint WHERE mint_url=:mint_url"#)?
|
|
.bind("mint_url", mint_url.to_string())
|
|
.bind("mint_url", mint_url.to_string())
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -271,6 +287,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn get_mint(&self, mint_url: MintUrl) -> Result<Option<MintInfo>, Self::Err> {
|
|
async fn get_mint(&self, mint_url: MintUrl) -> Result<Option<MintInfo>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -292,7 +309,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("mint_url", mint_url.to_string())
|
|
.bind("mint_url", mint_url.to_string())
|
|
- .fetch_one(&self.db)
|
|
|
|
|
|
+ .fetch_one(&*conn)
|
|
.await?
|
|
.await?
|
|
.map(sql_row_to_mint_info)
|
|
.map(sql_row_to_mint_info)
|
|
.transpose()?)
|
|
.transpose()?)
|
|
@@ -300,6 +317,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn get_mints(&self) -> Result<HashMap<MintUrl, Option<MintInfo>>, Self::Err> {
|
|
async fn get_mints(&self) -> Result<HashMap<MintUrl, Option<MintInfo>>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -320,7 +338,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
mint
|
|
mint
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
- .fetch_all(&self.db)
|
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
.await?
|
|
.await?
|
|
.into_iter()
|
|
.into_iter()
|
|
.map(|mut row| {
|
|
.map(|mut row| {
|
|
@@ -340,6 +358,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
old_mint_url: MintUrl,
|
|
old_mint_url: MintUrl,
|
|
new_mint_url: MintUrl,
|
|
new_mint_url: MintUrl,
|
|
) -> Result<(), Self::Err> {
|
|
) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
let tables = ["mint_quote", "proof"];
|
|
let tables = ["mint_quote", "proof"];
|
|
|
|
|
|
for table in &tables {
|
|
for table in &tables {
|
|
@@ -352,7 +371,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
))?
|
|
))?
|
|
.bind("new_mint_url", new_mint_url.to_string())
|
|
.bind("new_mint_url", new_mint_url.to_string())
|
|
.bind("old_mint_url", old_mint_url.to_string())
|
|
.bind("old_mint_url", old_mint_url.to_string())
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -365,6 +384,8 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
mint_url: MintUrl,
|
|
mint_url: MintUrl,
|
|
keysets: Vec<KeySetInfo>,
|
|
keysets: Vec<KeySetInfo>,
|
|
) -> Result<(), Self::Err> {
|
|
) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
for keyset in keysets {
|
|
for keyset in keysets {
|
|
query(
|
|
query(
|
|
r#"
|
|
r#"
|
|
@@ -384,7 +405,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
.bind("input_fee_ppk", keyset.input_fee_ppk as i64)
|
|
.bind("input_fee_ppk", keyset.input_fee_ppk as i64)
|
|
.bind("final_expiry", keyset.final_expiry.map(|v| v as i64))
|
|
.bind("final_expiry", keyset.final_expiry.map(|v| v as i64))
|
|
.bind("keyset_u32", u32::from(keyset.id))
|
|
.bind("keyset_u32", u32::from(keyset.id))
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -396,6 +417,8 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
&self,
|
|
&self,
|
|
mint_url: MintUrl,
|
|
mint_url: MintUrl,
|
|
) -> Result<Option<Vec<KeySetInfo>>, Self::Err> {
|
|
) -> Result<Option<Vec<KeySetInfo>>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
let keysets = query(
|
|
let keysets = query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -410,7 +433,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("mint_url", mint_url.to_string())
|
|
.bind("mint_url", mint_url.to_string())
|
|
- .fetch_all(&self.db)
|
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
.await?
|
|
.await?
|
|
.into_iter()
|
|
.into_iter()
|
|
.map(sql_row_to_keyset)
|
|
.map(sql_row_to_keyset)
|
|
@@ -424,6 +447,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
async fn get_keyset_by_id(&self, keyset_id: &Id) -> Result<Option<KeySetInfo>, Self::Err> {
|
|
async fn get_keyset_by_id(&self, keyset_id: &Id) -> Result<Option<KeySetInfo>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -438,7 +462,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("id", keyset_id.to_string())
|
|
.bind("id", keyset_id.to_string())
|
|
- .fetch_one(&self.db)
|
|
|
|
|
|
+ .fetch_one(&*conn)
|
|
.await?
|
|
.await?
|
|
.map(sql_row_to_keyset)
|
|
.map(sql_row_to_keyset)
|
|
.transpose()?)
|
|
.transpose()?)
|
|
@@ -446,6 +470,7 @@ ON CONFLICT(mint_url) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip_all)]
|
|
#[instrument(skip_all)]
|
|
async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), Self::Err> {
|
|
async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
query(
|
|
query(
|
|
r#"
|
|
r#"
|
|
INSERT INTO mint_quote
|
|
INSERT INTO mint_quote
|
|
@@ -477,13 +502,14 @@ ON CONFLICT(id) DO UPDATE SET
|
|
.bind("payment_method", quote.payment_method.to_string())
|
|
.bind("payment_method", quote.payment_method.to_string())
|
|
.bind("amount_issued", quote.amount_issued.to_i64())
|
|
.bind("amount_issued", quote.amount_issued.to_i64())
|
|
.bind("amount_paid", quote.amount_paid.to_i64())
|
|
.bind("amount_paid", quote.amount_paid.to_i64())
|
|
- .execute(&self.db).await?;
|
|
|
|
|
|
+ .execute(&*conn).await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn get_mint_quote(&self, quote_id: &str) -> Result<Option<MintQuote>, Self::Err> {
|
|
async fn get_mint_quote(&self, quote_id: &str) -> Result<Option<MintQuote>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -505,7 +531,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("id", quote_id.to_string())
|
|
.bind("id", quote_id.to_string())
|
|
- .fetch_one(&self.db)
|
|
|
|
|
|
+ .fetch_one(&*conn)
|
|
.await?
|
|
.await?
|
|
.map(sql_row_to_mint_quote)
|
|
.map(sql_row_to_mint_quote)
|
|
.transpose()?)
|
|
.transpose()?)
|
|
@@ -513,6 +539,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, Self::Err> {
|
|
async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -528,7 +555,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
mint_quote
|
|
mint_quote
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
- .fetch_all(&self.db)
|
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
.await?
|
|
.await?
|
|
.into_iter()
|
|
.into_iter()
|
|
.map(sql_row_to_mint_quote)
|
|
.map(sql_row_to_mint_quote)
|
|
@@ -537,9 +564,10 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
|
async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
query(r#"DELETE FROM mint_quote WHERE id=:id"#)?
|
|
query(r#"DELETE FROM mint_quote WHERE id=:id"#)?
|
|
.bind("id", quote_id.to_string())
|
|
.bind("id", quote_id.to_string())
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -547,6 +575,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip_all)]
|
|
#[instrument(skip_all)]
|
|
async fn add_melt_quote(&self, quote: wallet::MeltQuote) -> Result<(), Self::Err> {
|
|
async fn add_melt_quote(&self, quote: wallet::MeltQuote) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
query(
|
|
query(
|
|
r#"
|
|
r#"
|
|
INSERT INTO melt_quote
|
|
INSERT INTO melt_quote
|
|
@@ -570,7 +599,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
.bind("fee_reserve", u64::from(quote.fee_reserve) as i64)
|
|
.bind("fee_reserve", u64::from(quote.fee_reserve) as i64)
|
|
.bind("state", quote.state.to_string())
|
|
.bind("state", quote.state.to_string())
|
|
.bind("expiry", quote.expiry as i64)
|
|
.bind("expiry", quote.expiry as i64)
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -578,6 +607,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<wallet::MeltQuote>, Self::Err> {
|
|
async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<wallet::MeltQuote>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -596,7 +626,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("id", quote_id.to_owned())
|
|
.bind("id", quote_id.to_owned())
|
|
- .fetch_one(&self.db)
|
|
|
|
|
|
+ .fetch_one(&*conn)
|
|
.await?
|
|
.await?
|
|
.map(sql_row_to_melt_quote)
|
|
.map(sql_row_to_melt_quote)
|
|
.transpose()?)
|
|
.transpose()?)
|
|
@@ -604,9 +634,10 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
|
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
query(r#"DELETE FROM melt_quote WHERE id=:id"#)?
|
|
query(r#"DELETE FROM melt_quote WHERE id=:id"#)?
|
|
.bind("id", quote_id.to_owned())
|
|
.bind("id", quote_id.to_owned())
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -614,6 +645,8 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip_all)]
|
|
#[instrument(skip_all)]
|
|
async fn add_keys(&self, keyset: KeySet) -> Result<(), Self::Err> {
|
|
async fn add_keys(&self, keyset: KeySet) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
// Recompute ID for verification
|
|
// Recompute ID for verification
|
|
keyset.verify_id()?;
|
|
keyset.verify_id()?;
|
|
|
|
|
|
@@ -631,7 +664,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
serde_json::to_string(&keyset.keys).map_err(Error::from)?,
|
|
serde_json::to_string(&keyset.keys).map_err(Error::from)?,
|
|
)
|
|
)
|
|
.bind("keyset_u32", u32::from(keyset.id))
|
|
.bind("keyset_u32", u32::from(keyset.id))
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -639,6 +672,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
async fn get_keys(&self, keyset_id: &Id) -> Result<Option<Keys>, Self::Err> {
|
|
async fn get_keys(&self, keyset_id: &Id) -> Result<Option<Keys>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -648,7 +682,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("id", keyset_id.to_string())
|
|
.bind("id", keyset_id.to_string())
|
|
- .pluck(&self.db)
|
|
|
|
|
|
+ .pluck(&*conn)
|
|
.await?
|
|
.await?
|
|
.map(|keys| {
|
|
.map(|keys| {
|
|
let keys = column_as_string!(keys);
|
|
let keys = column_as_string!(keys);
|
|
@@ -659,9 +693,10 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn remove_keys(&self, id: &Id) -> Result<(), Self::Err> {
|
|
async fn remove_keys(&self, id: &Id) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
query(r#"DELETE FROM key WHERE id = :id"#)?
|
|
query(r#"DELETE FROM key WHERE id = :id"#)?
|
|
.bind("id", id.to_string())
|
|
.bind("id", id.to_string())
|
|
- .pluck(&self.db)
|
|
|
|
|
|
+ .pluck(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -672,6 +707,10 @@ ON CONFLICT(id) DO UPDATE SET
|
|
added: Vec<ProofInfo>,
|
|
added: Vec<ProofInfo>,
|
|
removed_ys: Vec<PublicKey>,
|
|
removed_ys: Vec<PublicKey>,
|
|
) -> Result<(), Self::Err> {
|
|
) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
|
|
+ let tx = ConnectionWithTransaction::new(conn).await?;
|
|
|
|
+
|
|
// TODO: Use a transaction for all these operations
|
|
// TODO: Use a transaction for all these operations
|
|
for proof in added {
|
|
for proof in added {
|
|
query(
|
|
query(
|
|
@@ -729,7 +768,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"dleq_r",
|
|
"dleq_r",
|
|
proof.proof.dleq.as_ref().map(|dleq| dleq.r.to_secret_bytes().to_vec()),
|
|
proof.proof.dleq.as_ref().map(|dleq| dleq.r.to_secret_bytes().to_vec()),
|
|
)
|
|
)
|
|
- .execute(&self.db).await?;
|
|
|
|
|
|
+ .execute(&tx).await?;
|
|
}
|
|
}
|
|
|
|
|
|
query(r#"DELETE FROM proof WHERE y IN (:ys)"#)?
|
|
query(r#"DELETE FROM proof WHERE y IN (:ys)"#)?
|
|
@@ -737,9 +776,11 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"ys",
|
|
"ys",
|
|
removed_ys.iter().map(|y| y.to_bytes().to_vec()).collect(),
|
|
removed_ys.iter().map(|y| y.to_bytes().to_vec()).collect(),
|
|
)
|
|
)
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&tx)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
|
|
+ tx.commit().await?;
|
|
|
|
+
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
|
|
@@ -751,6 +792,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
state: Option<Vec<State>>,
|
|
state: Option<Vec<State>>,
|
|
spending_conditions: Option<Vec<SpendingConditions>>,
|
|
spending_conditions: Option<Vec<SpendingConditions>>,
|
|
) -> Result<Vec<ProofInfo>, Self::Err> {
|
|
) -> Result<Vec<ProofInfo>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -770,7 +812,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
FROM proof
|
|
FROM proof
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
- .fetch_all(&self.db)
|
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
.await?
|
|
.await?
|
|
.into_iter()
|
|
.into_iter()
|
|
.filter_map(|row| {
|
|
.filter_map(|row| {
|
|
@@ -786,10 +828,11 @@ ON CONFLICT(id) DO UPDATE SET
|
|
}
|
|
}
|
|
|
|
|
|
async fn update_proofs_state(&self, ys: Vec<PublicKey>, state: State) -> Result<(), Self::Err> {
|
|
async fn update_proofs_state(&self, ys: Vec<PublicKey>, state: State) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
query("UPDATE proof SET state = :state WHERE y IN (:ys)")?
|
|
query("UPDATE proof SET state = :state WHERE y IN (:ys)")?
|
|
.bind_vec("ys", ys.iter().map(|y| y.to_bytes().to_vec()).collect())
|
|
.bind_vec("ys", ys.iter().map(|y| y.to_bytes().to_vec()).collect())
|
|
.bind("state", state.to_string())
|
|
.bind("state", state.to_string())
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -797,6 +840,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
async fn increment_keyset_counter(&self, keyset_id: &Id, count: u32) -> Result<(), Self::Err> {
|
|
async fn increment_keyset_counter(&self, keyset_id: &Id, count: u32) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
query(
|
|
query(
|
|
r#"
|
|
r#"
|
|
UPDATE keyset
|
|
UPDATE keyset
|
|
@@ -806,7 +850,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
)?
|
|
)?
|
|
.bind("count", count)
|
|
.bind("count", count)
|
|
.bind("id", keyset_id.to_string())
|
|
.bind("id", keyset_id.to_string())
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -814,6 +858,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
#[instrument(skip(self), fields(keyset_id = %keyset_id))]
|
|
async fn get_keyset_counter(&self, keyset_id: &Id) -> Result<Option<u32>, Self::Err> {
|
|
async fn get_keyset_counter(&self, keyset_id: &Id) -> Result<Option<u32>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -825,7 +870,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("id", keyset_id.to_string())
|
|
.bind("id", keyset_id.to_string())
|
|
- .pluck(&self.db)
|
|
|
|
|
|
+ .pluck(&*conn)
|
|
.await?
|
|
.await?
|
|
.map(|n| Ok::<_, Error>(column_as_number!(n)))
|
|
.map(|n| Ok::<_, Error>(column_as_number!(n)))
|
|
.transpose()?)
|
|
.transpose()?)
|
|
@@ -833,6 +878,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn add_transaction(&self, transaction: Transaction) -> Result<(), Self::Err> {
|
|
async fn add_transaction(&self, transaction: Transaction) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
let mint_url = transaction.mint_url.to_string();
|
|
let mint_url = transaction.mint_url.to_string();
|
|
let direction = transaction.direction.to_string();
|
|
let direction = transaction.direction.to_string();
|
|
let unit = transaction.unit.to_string();
|
|
let unit = transaction.unit.to_string();
|
|
@@ -876,7 +922,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"metadata",
|
|
"metadata",
|
|
serde_json::to_string(&transaction.metadata).map_err(Error::from)?,
|
|
serde_json::to_string(&transaction.metadata).map_err(Error::from)?,
|
|
)
|
|
)
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -887,6 +933,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
&self,
|
|
&self,
|
|
transaction_id: TransactionId,
|
|
transaction_id: TransactionId,
|
|
) -> Result<Option<Transaction>, Self::Err> {
|
|
) -> Result<Option<Transaction>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -906,7 +953,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
.bind("id", transaction_id.as_slice().to_vec())
|
|
.bind("id", transaction_id.as_slice().to_vec())
|
|
- .fetch_one(&self.db)
|
|
|
|
|
|
+ .fetch_one(&*conn)
|
|
.await?
|
|
.await?
|
|
.map(sql_row_to_transaction)
|
|
.map(sql_row_to_transaction)
|
|
.transpose()?)
|
|
.transpose()?)
|
|
@@ -919,6 +966,8 @@ ON CONFLICT(id) DO UPDATE SET
|
|
direction: Option<TransactionDirection>,
|
|
direction: Option<TransactionDirection>,
|
|
unit: Option<CurrencyUnit>,
|
|
unit: Option<CurrencyUnit>,
|
|
) -> Result<Vec<Transaction>, Self::Err> {
|
|
) -> Result<Vec<Transaction>, Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
Ok(query(
|
|
Ok(query(
|
|
r#"
|
|
r#"
|
|
SELECT
|
|
SELECT
|
|
@@ -935,7 +984,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
transactions
|
|
transactions
|
|
"#,
|
|
"#,
|
|
)?
|
|
)?
|
|
- .fetch_all(&self.db)
|
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
.await?
|
|
.await?
|
|
.into_iter()
|
|
.into_iter()
|
|
.filter_map(|row| {
|
|
.filter_map(|row| {
|
|
@@ -952,9 +1001,11 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
|
|
|
#[instrument(skip(self))]
|
|
#[instrument(skip(self))]
|
|
async fn remove_transaction(&self, transaction_id: TransactionId) -> Result<(), Self::Err> {
|
|
async fn remove_transaction(&self, transaction_id: TransactionId) -> Result<(), Self::Err> {
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
+
|
|
query(r#"DELETE FROM transactions WHERE id=:id"#)?
|
|
query(r#"DELETE FROM transactions WHERE id=:id"#)?
|
|
.bind("id", transaction_id.as_slice().to_vec())
|
|
.bind("id", transaction_id.as_slice().to_vec())
|
|
- .execute(&self.db)
|
|
|
|
|
|
+ .execute(&*conn)
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|