From d1289b4a5af9ce757c009c027090529e5b57fef4 Mon Sep 17 00:00:00 2001 From: Ross Savage Date: Thu, 9 Nov 2023 13:54:07 +0100 Subject: [PATCH] Persist failed payment amount --- libs/sdk-core/src/breez_services.rs | 26 ++++++++++++++---- libs/sdk-core/src/persist/migrations.rs | 1 + libs/sdk-core/src/persist/sync.rs | 3 ++- libs/sdk-core/src/persist/transactions.rs | 32 ++++++++++++++++------- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index e6ae7f2bb..b8f38f64e 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -270,6 +270,7 @@ impl BreezServices { .on_payment_completed( parsed_invoice.payee_pubkey.clone(), Some(parsed_invoice), + req.amount_msat, payment_res, ) .await?; @@ -290,7 +291,7 @@ impl BreezServices { .map_err(Into::into) .await; let payment = self - .on_payment_completed(req.node_id, None, payment_res) + .on_payment_completed(req.node_id, None, Some(req.amount_msat), payment_res) .await?; Ok(SendPaymentResponse { payment }) } @@ -349,12 +350,13 @@ impl BreezServices { }; // Store SA (if available) + LN Address in separate table, associated to payment_hash - self.persister.insert_lnurl_payment_external_info( + self.persister.insert_payment_external_info( &details.payment_hash, maybe_sa_processed.as_ref(), Some(req.data.metadata_str), req.data.ln_address, None, + None, )?; Ok(LnUrlPayResult::EndpointSuccess { @@ -389,12 +391,13 @@ impl BreezServices { if let LnUrlWithdrawResult::Ok { ref data } = res { // If endpoint was successfully called, store the LNURL-withdraw endpoint URL as metadata linked to the invoice - self.persister.insert_lnurl_payment_external_info( + self.persister.insert_payment_external_info( &data.invoice.payment_hash, None, None, None, Some(lnurl_w_endpoint), + None, )?; } @@ -828,6 +831,7 @@ impl BreezServices { &self, node_id: String, invoice: Option, + amount_msat: Option, payment_res: Result, ) -> Result { self.do_sync(payment_res.is_ok()).await?; @@ -844,6 +848,16 @@ impl BreezServices { }), }, Err(e) => { + if let Some(inv) = invoice.clone() { + self.persister.insert_payment_external_info( + &inv.payment_hash, + None, + None, + None, + None, + amount_msat.or(inv.amount_msat), + )?; + } self.notify_event_listeners(BreezEvent::PaymentFailed { details: PaymentFailedData { error: e.to_string(), @@ -2041,19 +2055,21 @@ pub(crate) mod tests { let persister = Arc::new(create_test_persister(test_config.clone())); persister.init()?; persister.insert_or_update_payments(&dummy_transactions)?; - persister.insert_lnurl_payment_external_info( + persister.insert_payment_external_info( payment_hash_with_lnurl_success_action, Some(&sa), Some(lnurl_metadata.to_string()), Some(test_ln_address.to_string()), None, + None, )?; - persister.insert_lnurl_payment_external_info( + persister.insert_payment_external_info( payment_hash_lnurl_withdraw, None, None, None, Some(test_lnurl_withdraw_endpoint.to_string()), + None, )?; let mut builder = BreezServicesBuilder::new(test_config.clone()); diff --git a/libs/sdk-core/src/persist/migrations.rs b/libs/sdk-core/src/persist/migrations.rs index 6ad196f6c..1bf16c54b 100644 --- a/libs/sdk-core/src/persist/migrations.rs +++ b/libs/sdk-core/src/persist/migrations.rs @@ -530,5 +530,6 @@ pub(crate) fn current_sync_migrations() -> Vec<&'static str> { INSERT INTO sync_requests(changed_table) VALUES('payments_external_info'); END; ", + "ALTER TABLE payments_external_info ADD COLUMN failed_amount_msat INTEGER;", ] } diff --git a/libs/sdk-core/src/persist/sync.rs b/libs/sdk-core/src/persist/sync.rs index 5a13b6b85..55a2720a8 100644 --- a/libs/sdk-core/src/persist/sync.rs +++ b/libs/sdk-core/src/persist/sync.rs @@ -168,7 +168,8 @@ impl SqliteStorage { lnurl_success_action, ln_address, lnurl_metadata, - lnurl_withdraw_endpoint + lnurl_withdraw_endpoint, + failed_amount_msat FROM remote_sync.payments_external_info WHERE payment_id NOT IN (SELECT payment_id FROM sync.payments_external_info);", [], diff --git a/libs/sdk-core/src/persist/transactions.rs b/libs/sdk-core/src/persist/transactions.rs index d8669ab7b..9da247329 100644 --- a/libs/sdk-core/src/persist/transactions.rs +++ b/libs/sdk-core/src/persist/transactions.rs @@ -15,7 +15,7 @@ impl SqliteStorage { /// /// Note that, if a payment has details of type [LnPaymentDetails] which contain a [SuccessActionProcessed], /// then the [LnPaymentDetails] will NOT be persisted. In that case, the [SuccessActionProcessed] - /// can be inserted separately via [SqliteStorage::insert_lnurl_payment_external_info]. + /// can be inserted separately via [SqliteStorage::insert_payment_external_info]. pub fn insert_or_update_payments(&self, transactions: &[Payment]) -> PersistResult<()> { let deleted = self.delete_pending_lightning_payments()?; debug!("Deleted {deleted} pending payments"); @@ -60,14 +60,15 @@ impl SqliteStorage { )?) } - /// Inserts LNURL-related metadata associated with this payment - pub fn insert_lnurl_payment_external_info( + /// Inserts metadata associated with this payment + pub fn insert_payment_external_info( &self, payment_hash: &str, lnurl_pay_success_action: Option<&SuccessActionProcessed>, lnurl_metadata: Option, ln_address: Option, lnurl_withdraw_endpoint: Option, + failed_amount_msat: Option, ) -> PersistResult<()> { let con = self.get_connection()?; let mut prep_statement = con.prepare( @@ -77,9 +78,10 @@ impl SqliteStorage { lnurl_success_action, lnurl_metadata, ln_address, - lnurl_withdraw_endpoint + lnurl_withdraw_endpoint, + failed_amount_msat ) - VALUES (?1,?2,?3,?4,?5) + VALUES (?1,?2,?3,?4,?5,?6) ", )?; @@ -89,6 +91,7 @@ impl SqliteStorage { lnurl_metadata, ln_address, lnurl_withdraw_endpoint, + failed_amount_msat, ))?; Ok(()) @@ -154,6 +157,7 @@ impl SqliteStorage { e.lnurl_metadata, e.ln_address, e.lnurl_withdraw_endpoint, + e.failed_amount_msat, o.payer_amount_msat FROM payments p LEFT JOIN sync.payments_external_info e @@ -201,6 +205,7 @@ impl SqliteStorage { e.lnurl_metadata, e.ln_address, e.lnurl_withdraw_endpoint, + e.failed_amount_msat, o.payer_amount_msat FROM payments p LEFT JOIN sync.payments_external_info e @@ -233,13 +238,18 @@ impl SqliteStorage { fn sql_row_to_payment(&self, row: &Row) -> PersistResult { let payment_type_str: String = row.get(1)?; let amount_msat = row.get(3)?; + let status: PaymentStatus = row.get(5)?; + let failed_amount_msat: Option = row.get(12)?; let mut payment = Payment { id: row.get(0)?, payment_type: PaymentType::from_str(payment_type_str.as_str()).unwrap(), payment_time: row.get(2)?, - amount_msat, + amount_msat: match status { + PaymentStatus::Failed => failed_amount_msat.unwrap_or(amount_msat), + _ => amount_msat, + }, fee_msat: row.get(4)?, - status: row.get(5)?, + status, description: row.get(6)?, details: row.get(7)?, }; @@ -252,7 +262,7 @@ impl SqliteStorage { } // In case we have a record of the open channel fee, let's use it. - let payer_amount_msat: Option = row.get(12)?; + let payer_amount_msat: Option = row.get(13)?; if let Some(payer_amount) = payer_amount_msat { payment.fee_msat = payer_amount - amount_msat; } @@ -457,19 +467,21 @@ fn test_ln_transactions() -> PersistResult<(), Box> { storage.init()?; storage.insert_or_update_payments(&txs)?; storage.insert_or_update_payments(&failed_txs)?; - storage.insert_lnurl_payment_external_info( + storage.insert_payment_external_info( payment_hash_with_lnurl_success_action, Some(&sa), Some(lnurl_metadata.to_string()), Some(test_ln_address.to_string()), None, + None, )?; - storage.insert_lnurl_payment_external_info( + storage.insert_payment_external_info( payment_hash_with_lnurl_withdraw, None, None, None, Some(lnurl_withdraw_url.to_string()), + None, )?; // retrieve all