mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-11 16:16:14 +01:00
refactor: move quote_ttl to database
This commit is contained in:
@@ -7,7 +7,7 @@ use cashu::MintInfo;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::Error;
|
||||
use crate::common::LnKey;
|
||||
use crate::common::{LnKey, QuoteTTL};
|
||||
use crate::mint::{self, MintKeySetInfo, MintQuote as MintMintQuote};
|
||||
use crate::nuts::{
|
||||
BlindSignature, CurrencyUnit, Id, MeltBolt11Request, MeltQuoteState, MintQuoteState, Proof,
|
||||
@@ -133,4 +133,9 @@ pub trait Database {
|
||||
async fn set_mint_info(&self, mint_info: MintInfo) -> Result<(), Self::Err>;
|
||||
/// Get [`MintInfo`]
|
||||
async fn get_mint_info(&self) -> Result<MintInfo, Self::Err>;
|
||||
|
||||
/// Set [`QuoteTTL`]
|
||||
async fn set_quote_ttl(&self, quote_ttl: QuoteTTL) -> Result<(), Self::Err>;
|
||||
/// Get [`QuoteTTL`]
|
||||
async fn get_quote_ttl(&self) -> Result<QuoteTTL, Self::Err>;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ async fn new_mint(fee: u64) -> Mint {
|
||||
|
||||
Mint::new(
|
||||
&mnemonic.to_seed_normalized(""),
|
||||
quote_ttl,
|
||||
Arc::new(localstore),
|
||||
HashMap::new(),
|
||||
supported_units,
|
||||
|
||||
@@ -52,6 +52,9 @@ pub enum Error {
|
||||
/// Unknown Mint Info
|
||||
#[error("Unknown mint info")]
|
||||
UnknownMintInfo,
|
||||
/// Unknown quote ttl
|
||||
#[error("Unknown quote ttl")]
|
||||
UnknownQuoteTTL,
|
||||
/// Unknown Proof Y
|
||||
#[error("Unknown proof Y")]
|
||||
UnknownY,
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cdk_common::common::LnKey;
|
||||
use cdk_common::common::{LnKey, QuoteTTL};
|
||||
use cdk_common::database::{self, MintDatabase};
|
||||
use cdk_common::dhke::hash_to_curve;
|
||||
use cdk_common::mint::{self, MintKeySetInfo, MintQuote};
|
||||
@@ -838,4 +838,30 @@ impl MintDatabase for MintRedbDatabase {
|
||||
|
||||
Err(Error::UnknownMintInfo.into())
|
||||
}
|
||||
|
||||
async fn set_quote_ttl(&self, quote_ttl: QuoteTTL) -> Result<(), Self::Err> {
|
||||
let write_txn = self.db.begin_write().map_err(Error::from)?;
|
||||
|
||||
{
|
||||
let mut table = write_txn.open_table(CONFIG_TABLE).map_err(Error::from)?;
|
||||
table
|
||||
.insert("quote_ttl", serde_json::to_string("e_ttl)?.as_str())
|
||||
.map_err(Error::from)?;
|
||||
}
|
||||
write_txn.commit().map_err(Error::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn get_quote_ttl(&self) -> Result<QuoteTTL, Self::Err> {
|
||||
let read_txn = self.db.begin_read().map_err(Error::from)?;
|
||||
let table = read_txn.open_table(CONFIG_TABLE).map_err(Error::from)?;
|
||||
|
||||
if let Some(quote_ttl) = table.get("quote_ttl").map_err(Error::from)? {
|
||||
let quote_ttl = serde_json::from_str(quote_ttl.value())?;
|
||||
|
||||
return Ok(quote_ttl);
|
||||
}
|
||||
|
||||
Err(Error::UnknownQuoteTTL.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ pub enum Error {
|
||||
/// Unknown Mint Info
|
||||
#[error("Unknown mint info")]
|
||||
UnknownMintInfo,
|
||||
/// Unknown quote TTL
|
||||
#[error("Unknown quote TTL")]
|
||||
UnknownQuoteTTL,
|
||||
}
|
||||
|
||||
impl From<Error> for cdk_common::database::Error {
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::time::Duration;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use bitcoin::bip32::DerivationPath;
|
||||
use cdk_common::common::LnKey;
|
||||
use cdk_common::common::{LnKey, QuoteTTL};
|
||||
use cdk_common::database::{self, MintDatabase};
|
||||
use cdk_common::mint::{self, MintKeySetInfo, MintQuote};
|
||||
use cdk_common::nut00::ProofsMethods;
|
||||
@@ -1291,6 +1291,77 @@ WHERE id=?;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn set_quote_ttl(&self, quote_ttl: QuoteTTL) -> Result<(), Self::Err> {
|
||||
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||
|
||||
let res = sqlx::query(
|
||||
r#"
|
||||
INSERT OR REPLACE INTO config
|
||||
(id, value)
|
||||
VALUES (?, ?);
|
||||
"#,
|
||||
)
|
||||
.bind("quote_ttl")
|
||||
.bind(serde_json::to_string("e_ttl)?)
|
||||
.execute(&mut transaction)
|
||||
.await;
|
||||
|
||||
match res {
|
||||
Ok(_) => {
|
||||
transaction.commit().await.map_err(Error::from)?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!("SQLite Could not update mint info");
|
||||
if let Err(err) = transaction.rollback().await {
|
||||
tracing::error!("Could not rollback sql transaction: {}", err);
|
||||
}
|
||||
|
||||
Err(Error::from(err).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn get_quote_ttl(&self) -> Result<QuoteTTL, Self::Err> {
|
||||
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||
|
||||
let rec = sqlx::query(
|
||||
r#"
|
||||
SELECT *
|
||||
FROM config
|
||||
WHERE id=?;
|
||||
"#,
|
||||
)
|
||||
.bind("quote_ttl")
|
||||
.fetch_one(&mut transaction)
|
||||
.await;
|
||||
|
||||
match rec {
|
||||
Ok(rec) => {
|
||||
transaction.commit().await.map_err(Error::from)?;
|
||||
|
||||
let value: String = rec.try_get("value").map_err(Error::from)?;
|
||||
|
||||
let quote_ttl = serde_json::from_str(&value)?;
|
||||
|
||||
Ok(quote_ttl)
|
||||
}
|
||||
Err(err) => match err {
|
||||
sqlx::Error::RowNotFound => {
|
||||
transaction.commit().await.map_err(Error::from)?;
|
||||
return Err(Error::UnknownQuoteTTL.into());
|
||||
}
|
||||
_ => {
|
||||
return {
|
||||
if let Err(err) = transaction.rollback().await {
|
||||
tracing::error!("Could not rollback sql transaction: {}", err);
|
||||
}
|
||||
Err(Error::SQLX(err).into())
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sqlite_row_to_keyset_info(row: SqliteRow) -> Result<MintKeySetInfo, Error> {
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cdk_common::common::QuoteTTL;
|
||||
use cdk_common::database::{Error, MintDatabase};
|
||||
use cdk_common::mint::MintKeySetInfo;
|
||||
use cdk_common::nut00::ProofsMethods;
|
||||
@@ -35,6 +36,7 @@ pub struct MintMemoryDatabase {
|
||||
quote_signatures: Arc<RwLock<HashMap<Uuid, Vec<BlindSignature>>>>,
|
||||
melt_requests: Arc<RwLock<HashMap<Uuid, (MeltBolt11Request<Uuid>, LnKey)>>>,
|
||||
mint_info: Arc<RwLock<MintInfo>>,
|
||||
quote_ttl: Arc<RwLock<QuoteTTL>>,
|
||||
}
|
||||
|
||||
impl MintMemoryDatabase {
|
||||
@@ -52,6 +54,7 @@ impl MintMemoryDatabase {
|
||||
quote_signatures: HashMap<Uuid, Vec<BlindSignature>>,
|
||||
melt_request: Vec<(MeltBolt11Request<Uuid>, LnKey)>,
|
||||
mint_info: MintInfo,
|
||||
quote_ttl: QuoteTTL,
|
||||
) -> Result<Self, Error> {
|
||||
let mut proofs = HashMap::new();
|
||||
let mut proof_states = HashMap::new();
|
||||
@@ -91,6 +94,7 @@ impl MintMemoryDatabase {
|
||||
quote_signatures: Arc::new(RwLock::new(quote_signatures)),
|
||||
melt_requests: Arc::new(RwLock::new(melt_requests)),
|
||||
mint_info: Arc::new(RwLock::new(mint_info)),
|
||||
quote_ttl: Arc::new(RwLock::new(quote_ttl)),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -429,4 +433,17 @@ impl MintDatabase for MintMemoryDatabase {
|
||||
|
||||
Ok(mint_info.clone())
|
||||
}
|
||||
|
||||
async fn set_quote_ttl(&self, quote_ttl: QuoteTTL) -> Result<(), Self::Err> {
|
||||
let mut current_quote_ttl = self.quote_ttl.write().await;
|
||||
|
||||
*current_quote_ttl = quote_ttl;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn get_quote_ttl(&self) -> Result<QuoteTTL, Self::Err> {
|
||||
let quote_ttl = self.quote_ttl.read().await;
|
||||
|
||||
Ok(quote_ttl.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,9 +224,12 @@ impl MintBuilder {
|
||||
.ok_or(anyhow!("Localstore not set"))?;
|
||||
localstore.set_mint_info(self.mint_info.clone()).await?;
|
||||
|
||||
localstore
|
||||
.set_quote_ttl(self.quote_ttl.ok_or(anyhow!("Quote ttl not set"))?)
|
||||
.await?;
|
||||
|
||||
Ok(Mint::new(
|
||||
self.seed.as_ref().ok_or(anyhow!("Mint seed not set"))?,
|
||||
self.quote_ttl.ok_or(anyhow!("Quote ttl not set"))?,
|
||||
localstore,
|
||||
self.ln.clone().ok_or(anyhow!("Ln backends not set"))?,
|
||||
self.supported_units.clone(),
|
||||
|
||||
@@ -7,14 +7,11 @@ use std::sync::Arc;
|
||||
use arc_swap::ArcSwap;
|
||||
|
||||
use super::{Id, MintKeySet};
|
||||
use crate::types::QuoteTTL;
|
||||
|
||||
/// Mint Inner configuration
|
||||
pub struct Config {
|
||||
/// Active Mint Keysets
|
||||
pub keysets: HashMap<Id, MintKeySet>,
|
||||
/// Quotes ttl
|
||||
pub quote_ttl: QuoteTTL,
|
||||
}
|
||||
|
||||
/// Mint configuration
|
||||
@@ -31,8 +28,8 @@ pub struct SwappableConfig {
|
||||
|
||||
impl SwappableConfig {
|
||||
/// Creates a new configuration instance
|
||||
pub fn new(quote_ttl: QuoteTTL, keysets: HashMap<Id, MintKeySet>) -> Self {
|
||||
let inner = Config { keysets, quote_ttl };
|
||||
pub fn new(keysets: HashMap<Id, MintKeySet>) -> Self {
|
||||
let inner = Config { keysets };
|
||||
|
||||
Self {
|
||||
config: Arc::new(ArcSwap::from_pointee(inner)),
|
||||
@@ -44,29 +41,9 @@ impl SwappableConfig {
|
||||
self.config.load().clone()
|
||||
}
|
||||
|
||||
/// Gets a copy of the quote ttl
|
||||
pub fn quote_ttl(&self) -> QuoteTTL {
|
||||
self.load().quote_ttl
|
||||
}
|
||||
|
||||
/// Replaces the current quote ttl with a new one
|
||||
pub fn set_quote_ttl(&self, quote_ttl: QuoteTTL) {
|
||||
let current_inner = self.load();
|
||||
let new_inner = Config {
|
||||
quote_ttl,
|
||||
keysets: current_inner.keysets.clone(),
|
||||
};
|
||||
|
||||
self.config.store(Arc::new(new_inner));
|
||||
}
|
||||
|
||||
/// Replaces the current keysets with a new one
|
||||
pub fn set_keysets(&self, keysets: HashMap<Id, MintKeySet>) {
|
||||
let current_inner = self.load();
|
||||
let new_inner = Config {
|
||||
quote_ttl: current_inner.quote_ttl,
|
||||
keysets,
|
||||
};
|
||||
let new_inner = Config { keysets };
|
||||
|
||||
self.config.store(Arc::new(new_inner));
|
||||
}
|
||||
|
||||
@@ -120,12 +120,14 @@ impl Mint {
|
||||
// or we want to ignore the amount and do an mpp payment
|
||||
let msats_to_pay = options.map(|opt| opt.amount_msat());
|
||||
|
||||
let melt_ttl = self.localstore.get_quote_ttl().await?.melt_ttl;
|
||||
|
||||
let quote = MeltQuote::new(
|
||||
request.to_string(),
|
||||
unit.clone(),
|
||||
payment_quote.amount,
|
||||
payment_quote.fee,
|
||||
unix_time() + self.config.quote_ttl().melt_ttl,
|
||||
unix_time() + melt_ttl,
|
||||
payment_quote.request_lookup_id.clone(),
|
||||
msats_to_pay,
|
||||
);
|
||||
|
||||
@@ -80,7 +80,9 @@ impl Mint {
|
||||
Error::UnitUnsupported
|
||||
})?;
|
||||
|
||||
let quote_expiry = unix_time() + self.config.quote_ttl().mint_ttl;
|
||||
let mint_ttl = self.localstore.get_quote_ttl().await?.mint_ttl;
|
||||
|
||||
let quote_expiry = unix_time() + mint_ttl;
|
||||
|
||||
if description.is_some() && !ln.get_settings().invoice_description {
|
||||
tracing::error!("Backend does not support invoice description");
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||
|
||||
use bitcoin::bip32::{ChildNumber, DerivationPath, Xpriv};
|
||||
use bitcoin::secp256k1::{self, Secp256k1};
|
||||
use cdk_common::common::{LnKey, QuoteTTL};
|
||||
use cdk_common::common::LnKey;
|
||||
use cdk_common::database::{self, MintDatabase};
|
||||
use cdk_common::mint::MintKeySetInfo;
|
||||
use config::SwappableConfig;
|
||||
@@ -58,7 +58,6 @@ impl Mint {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn new(
|
||||
seed: &[u8],
|
||||
quote_ttl: QuoteTTL,
|
||||
localstore: Arc<dyn MintDatabase<Err = database::Error> + Send + Sync>,
|
||||
ln: HashMap<LnKey, Arc<dyn MintLightning<Err = cdk_lightning::Error> + Send + Sync>>,
|
||||
// Hashmap where the key is the unit and value is (input fee ppk, max_order)
|
||||
@@ -178,7 +177,7 @@ impl Mint {
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
config: SwappableConfig::new(quote_ttl, active_keysets),
|
||||
config: SwappableConfig::new(active_keysets),
|
||||
pubsub_manager: Arc::new(localstore.clone().into()),
|
||||
secp_ctx,
|
||||
xpriv,
|
||||
@@ -687,13 +686,13 @@ mod tests {
|
||||
config.quote_signatures,
|
||||
config.melt_requests,
|
||||
config.mint_info,
|
||||
config.quote_ttl,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
Mint::new(
|
||||
config.seed,
|
||||
config.quote_ttl,
|
||||
localstore,
|
||||
HashMap::new(),
|
||||
config.supported_units,
|
||||
|
||||
Reference in New Issue
Block a user