From 996b7b4ca7d423b288ff00011316fa8511a6934b Mon Sep 17 00:00:00 2001 From: benthecarman Date: Wed, 19 Jun 2024 16:10:42 -0500 Subject: [PATCH 1/2] Set preimage for fedimint invoices --- mutiny-core/src/federation.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mutiny-core/src/federation.rs b/mutiny-core/src/federation.rs index 7c0e63296..35b0e5436 100644 --- a/mutiny-core/src/federation.rs +++ b/mutiny-core/src/federation.rs @@ -507,7 +507,7 @@ impl FederationClient { let desc = Description::new(String::new()).expect("empty string is valid"); let gateway = self.gateway.read().await; - let (id, invoice, _) = lightning_module + let (id, invoice, preimage) = lightning_module .create_bolt11_invoice( Amount::from_sats(amount), Bolt11InvoiceDescription::Direct(&desc), @@ -524,6 +524,7 @@ impl FederationClient { let mut stored_payment: MutinyInvoice = invoice.clone().into(); stored_payment.inbound = inbound; stored_payment.labels = labels; + stored_payment.preimage = Some(preimage.to_lower_hex_string()); log_trace!(self.logger, "Persisting payment"); let hash = stored_payment.payment_hash.into_32(); From bd17605b5f6a19e03f86517007ffe03a7aa1f732 Mon Sep 17 00:00:00 2001 From: benthecarman Date: Wed, 19 Jun 2024 17:07:59 -0500 Subject: [PATCH 2/2] Don't overwrite fedimint invoices in storage --- mutiny-core/src/federation.rs | 47 +++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/mutiny-core/src/federation.rs b/mutiny-core/src/federation.rs index 35b0e5436..01fd74016 100644 --- a/mutiny-core/src/federation.rs +++ b/mutiny-core/src/federation.rs @@ -1,3 +1,4 @@ +use crate::storage::get_invoice_by_hash; use crate::utils::{ convert_from_fedimint_invoice, convert_to_fedimint_invoice, fetch_with_timeout, now, spawn, }; @@ -642,7 +643,7 @@ impl FederationClient { stored_payment.labels = labels; stored_payment.status = HTLCStatus::InFlight; let hash = stored_payment.payment_hash.into_32(); - let payment_info = PaymentInfo::from(stored_payment); + let payment_info = PaymentInfo::from(stored_payment.clone()); persist_payment_info(&self.storage, &hash, &payment_info, inbound)?; // Subscribe and process outcome based on payment type @@ -653,8 +654,7 @@ impl FederationClient { let o = process_ln_outcome( o, process_pay_state_internal, - invoice.clone(), - inbound, + stored_payment, Some(DEFAULT_PAYMENT_TIMEOUT * 1_000), self.stop.clone(), Arc::clone(&self.logger), @@ -671,8 +671,7 @@ impl FederationClient { let o = process_ln_outcome( o, process_pay_state_ln, - invoice.clone(), - inbound, + stored_payment, Some(DEFAULT_PAYMENT_TIMEOUT * 1_000), self.stop.clone(), Arc::clone(&self.logger), @@ -1158,15 +1157,23 @@ async fn process_operation_until_timeout( let updated_invoice = match lightning_meta.variant { LightningOperationMetaVariant::Pay(pay_meta) => { let hash = pay_meta.invoice.payment_hash().into_inner(); - let invoice = convert_from_fedimint_invoice(&pay_meta.invoice); - if invoice.payment_hash().into_32() == hash { + let bolt11 = convert_from_fedimint_invoice(&pay_meta.invoice); + let invoice = match get_invoice_by_hash(bolt11.payment_hash(), &storage, &logger) { + Ok(invoice) => invoice, + Err(_) => { + // if we can't find the invoice, we should just create MutinyInvoice from the bolt11 + let mut invoice: MutinyInvoice = bolt11.into(); + invoice.inbound = false; + invoice + } + }; + if invoice.payment_hash.into_32() == hash { match lightning_module.subscribe_ln_pay(operation_id).await { Ok(o) => Some( process_ln_outcome( o, process_pay_state_ln, invoice, - false, timeout, stop, logger.clone(), @@ -1177,7 +1184,7 @@ async fn process_operation_until_timeout( log_error!(logger, "Error trying to process stream outcome: {e}"); // return the latest status of the invoice even if it fails - Some(invoice.into()) + Some(invoice) } } } else { @@ -1186,15 +1193,23 @@ async fn process_operation_until_timeout( } LightningOperationMetaVariant::Receive { invoice, .. } => { let hash = invoice.payment_hash().into_inner(); - let invoice = convert_from_fedimint_invoice(&invoice); - if invoice.payment_hash().into_32() == hash { + let bolt11 = convert_from_fedimint_invoice(&invoice); + let invoice = match get_invoice_by_hash(bolt11.payment_hash(), &storage, &logger) { + Ok(invoice) => invoice, + Err(_) => { + // if we can't find the invoice, we should just create MutinyInvoice from the bolt11 + let mut invoice: MutinyInvoice = bolt11.into(); + invoice.inbound = true; + invoice + } + }; + if invoice.payment_hash.into_32() == hash { match lightning_module.subscribe_ln_receive(operation_id).await { Ok(o) => Some( process_ln_outcome( o, process_receive_state, invoice, - true, timeout, stop, logger.clone(), @@ -1205,7 +1220,7 @@ async fn process_operation_until_timeout( log_error!(logger, "Error trying to process stream outcome: {e}"); // return the latest status of the invoice even if it fails - Some(invoice.into()) + Some(invoice) } } } else { @@ -1337,8 +1352,7 @@ fn process_receive_state(receive_state: LnReceiveState, invoice: &mut MutinyInvo async fn process_ln_outcome( stream_or_outcome: UpdateStreamOrOutcome, process_fn: F, - invoice: Bolt11Invoice, - inbound: bool, + mut invoice: MutinyInvoice, timeout: Option, stop: Arc, logger: Arc, @@ -1354,9 +1368,6 @@ where + 'static, F: Fn(U, &mut MutinyInvoice), { - let mut invoice: MutinyInvoice = invoice.into(); - invoice.inbound = inbound; - match stream_or_outcome { UpdateStreamOrOutcome::Outcome(outcome) => { invoice.status = outcome.into();