mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-19 05:35:18 +01:00
Remove melt_request (#819)
* Fix SQLite race condition Bug: https://github.com/crodas/cdk/actions/runs/15732950296/job/44339804072#step:5:1853 Reason: When melting in parallel, many update the melt status and attempt to add proofs and they fail when adding the proof and the rollback code kicks in. The loser process removes all the proofs, and the winner process has no proof later on. Fix: Modify `update_melt_quote_state` requirements and implementation to allow only one winner. This will be solved by design with a transaction writer trait * Remove `melt_request` Fixes #809 * Remove `get_melt_request` from db trait
This commit is contained in:
@@ -1,14 +1,12 @@
|
||||
//! In-memory database that is provided by the `cdk-sqlite` crate, mainly for testing purposes.
|
||||
use std::collections::HashMap;
|
||||
|
||||
use cdk_common::common::PaymentProcessorKey;
|
||||
use cdk_common::database::{
|
||||
self, MintDatabase, MintKeysDatabase, MintProofsDatabase, MintQuotesDatabase,
|
||||
};
|
||||
use cdk_common::mint::{self, MintKeySetInfo, MintQuote};
|
||||
use cdk_common::nuts::{CurrencyUnit, Id, MeltRequest, Proofs};
|
||||
use cdk_common::nuts::{CurrencyUnit, Id, Proofs};
|
||||
use cdk_common::MintInfo;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::MintSqliteDatabase;
|
||||
|
||||
@@ -30,7 +28,6 @@ pub async fn new_with_state(
|
||||
melt_quotes: Vec<mint::MeltQuote>,
|
||||
pending_proofs: Proofs,
|
||||
spent_proofs: Proofs,
|
||||
melt_request: Vec<(MeltRequest<Uuid>, PaymentProcessorKey)>,
|
||||
mint_info: MintInfo,
|
||||
) -> Result<MintSqliteDatabase, database::Error> {
|
||||
let db = empty().await?;
|
||||
@@ -55,10 +52,6 @@ pub async fn new_with_state(
|
||||
db.add_proofs(pending_proofs, None).await?;
|
||||
db.add_proofs(spent_proofs, None).await?;
|
||||
|
||||
for (melt_request, ln_key) in melt_request {
|
||||
db.add_melt_request(melt_request, ln_key).await?;
|
||||
}
|
||||
|
||||
db.set_mint_info(mint_info).await?;
|
||||
|
||||
Ok(db)
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::str::FromStr;
|
||||
use async_rusqlite::{query, DatabaseExecutor};
|
||||
use async_trait::async_trait;
|
||||
use bitcoin::bip32::DerivationPath;
|
||||
use cdk_common::common::{PaymentProcessorKey, QuoteTTL};
|
||||
use cdk_common::common::QuoteTTL;
|
||||
use cdk_common::database::{
|
||||
self, MintDatabase, MintKeysDatabase, MintProofsDatabase, MintQuotesDatabase,
|
||||
MintSignaturesDatabase,
|
||||
@@ -20,8 +20,8 @@ use cdk_common::secret::Secret;
|
||||
use cdk_common::state::check_state_transition;
|
||||
use cdk_common::util::unix_time;
|
||||
use cdk_common::{
|
||||
Amount, BlindSignature, BlindSignatureDleq, CurrencyUnit, Id, MeltQuoteState, MeltRequest,
|
||||
MintInfo, MintQuoteState, PaymentMethod, Proof, Proofs, PublicKey, SecretKey, State,
|
||||
Amount, BlindSignature, BlindSignatureDleq, CurrencyUnit, Id, MeltQuoteState, MintInfo,
|
||||
MintQuoteState, Proof, Proofs, PublicKey, SecretKey, State,
|
||||
};
|
||||
use error::Error;
|
||||
use lightning_invoice::Bolt11Invoice;
|
||||
@@ -733,60 +733,6 @@ impl MintQuotesDatabase for MintSqliteDatabase {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_melt_request(
|
||||
&self,
|
||||
melt_request: MeltRequest<Uuid>,
|
||||
ln_key: PaymentProcessorKey,
|
||||
) -> Result<(), Self::Err> {
|
||||
query(
|
||||
r#"
|
||||
INSERT INTO melt_request
|
||||
(id, inputs, outputs, method, unit)
|
||||
VALUES
|
||||
(:id, :inputs, :outputs, :method, :unit)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
inputs = excluded.inputs,
|
||||
outputs = excluded.outputs,
|
||||
method = excluded.method,
|
||||
unit = excluded.unit
|
||||
"#,
|
||||
)
|
||||
.bind(":id", melt_request.quote().to_string())
|
||||
.bind(":inputs", serde_json::to_string(&melt_request.inputs())?)
|
||||
.bind(":outputs", serde_json::to_string(&melt_request.outputs())?)
|
||||
.bind(":method", ln_key.method.to_string())
|
||||
.bind(":unit", ln_key.unit.to_string())
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_melt_request(
|
||||
&self,
|
||||
quote_id: &Uuid,
|
||||
) -> Result<Option<(MeltRequest<Uuid>, PaymentProcessorKey)>, Self::Err> {
|
||||
Ok(query(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
inputs,
|
||||
outputs,
|
||||
method,
|
||||
unit
|
||||
FROM
|
||||
melt_request
|
||||
WHERE
|
||||
id=?;
|
||||
"#,
|
||||
)
|
||||
.bind(":id", quote_id.hyphenated().to_string())
|
||||
.fetch_one(&self.pool)
|
||||
.await?
|
||||
.map(sqlite_row_to_melt_request)
|
||||
.transpose()?)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -1353,35 +1299,6 @@ fn sqlite_row_to_blind_signature(row: Vec<Column>) -> Result<BlindSignature, Err
|
||||
})
|
||||
}
|
||||
|
||||
fn sqlite_row_to_melt_request(
|
||||
row: Vec<Column>,
|
||||
) -> Result<(MeltRequest<Uuid>, PaymentProcessorKey), Error> {
|
||||
unpack_into!(
|
||||
let (
|
||||
id,
|
||||
inputs,
|
||||
outputs,
|
||||
method,
|
||||
unit
|
||||
) = row
|
||||
);
|
||||
|
||||
let id = column_as_string!(id);
|
||||
|
||||
let melt_request = MeltRequest::new(
|
||||
Uuid::parse_str(&id).map_err(|_| Error::InvalidUuid(id))?,
|
||||
column_as_string!(&inputs, serde_json::from_str),
|
||||
column_as_nullable_string!(&outputs).and_then(|w| serde_json::from_str(&w).ok()),
|
||||
);
|
||||
|
||||
let ln_key = PaymentProcessorKey {
|
||||
unit: column_as_string!(&unit, CurrencyUnit::from_str),
|
||||
method: column_as_string!(&method, PaymentMethod::from_str),
|
||||
};
|
||||
|
||||
Ok((melt_request, ln_key))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::remove_file;
|
||||
|
||||
Reference in New Issue
Block a user