Skip to content

Commit

Permalink
refactor: move quote_ttl to database
Browse files Browse the repository at this point in the history
  • Loading branch information
thesimplekid committed Jan 29, 2025
1 parent 5481286 commit c455809
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 37 deletions.
7 changes: 6 additions & 1 deletion crates/cdk-common/src/database/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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>;
}
1 change: 0 additions & 1 deletion crates/cdk-integration-tests/tests/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions crates/cdk-redb/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
28 changes: 27 additions & 1 deletion crates/cdk-redb/src/mint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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(&quote_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())
}
}
3 changes: 3 additions & 0 deletions crates/cdk-sqlite/src/mint/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
73 changes: 72 additions & 1 deletion crates/cdk-sqlite/src/mint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(&quote_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> {
Expand Down
17 changes: 17 additions & 0 deletions crates/cdk/src/cdk_database/mint_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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();
Expand Down Expand Up @@ -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)),
})
}
}
Expand Down Expand Up @@ -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())
}
}
5 changes: 4 additions & 1 deletion crates/cdk/src/mint/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
29 changes: 3 additions & 26 deletions crates/cdk/src/mint/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)),
Expand All @@ -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));
}
Expand Down
4 changes: 3 additions & 1 deletion crates/cdk/src/mint/melt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Expand Down
4 changes: 3 additions & 1 deletion crates/cdk/src/mint/mint_nut04.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
7 changes: 3 additions & 4 deletions crates/cdk/src/mint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit c455809

Please sign in to comment.