From f80b0e9dbb07471aa9a216e8148ae7ce997f38d8 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Fri, 28 Jun 2024 14:03:46 -0400 Subject: [PATCH] Store invreqs in StaticInvoiceReceived outbound payments When transitioning outbound payments from AwaitingInvoice to StaticInvoiceReceived, include the invreq in the new state's outbound payment storage for future inclusion in an async payment onion. Per , when paying a static invoice we need to include our original invoice request in the HTLC onion since the recipient wouldn't have received it previously. --- lightning/src/ln/outbound_payment.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index bf1fedd8a4b..88374906eee 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -83,6 +83,7 @@ pub(crate) enum PendingOutboundPayment { keysend_preimage: PaymentPreimage, retry_strategy: Retry, route_params: RouteParameters, + invoice_request: InvoiceRequest, }, Retryable { retry_strategy: Option, @@ -1004,7 +1005,7 @@ impl OutboundPayments { } match self.pending_outbound_payments.lock().unwrap().entry(payment_id) { - hash_map::Entry::Occupied(mut entry) => match entry.get() { + hash_map::Entry::Occupied(mut entry) => match entry.get_mut() { PendingOutboundPayment::AwaitingInvoice { retry_strategy, retryable_invoice_request, max_total_routing_fee_msat, .. } => { @@ -1048,6 +1049,11 @@ impl OutboundPayments { keysend_preimage, retry_strategy: *retry_strategy, route_params, + invoice_request: + retryable_invoice_request + .take() + .ok_or(Bolt12PaymentError::UnexpectedInvoice)? + .invoice_request, }; return Ok(()) }, @@ -2256,11 +2262,13 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment, (2, keysend_preimage, required), (4, retry_strategy, required), (6, route_params, required), + (8, invoice_request, required), }, ); #[cfg(test)] mod tests { + use bitcoin::hex::FromHex; use bitcoin::network::Network; use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; @@ -2268,6 +2276,7 @@ mod tests { use crate::blinded_path::EmptyNodeIdLookUp; use crate::events::{Event, PathFailure, PaymentFailureReason}; + use crate::io::Cursor; use crate::types::payment::{PaymentHash, PaymentPreimage}; use crate::ln::channelmanager::{PaymentId, RecipientOnionFields}; use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures}; @@ -2275,6 +2284,7 @@ mod tests { use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PendingOutboundPayment, Retry, RetryableSendFailure, StaleExpiration}; #[cfg(feature = "std")] use crate::offers::invoice::DEFAULT_RELATIVE_EXPIRY; + use crate::offers::invoice_request::InvoiceRequest; use crate::offers::offer::OfferBuilder; use crate::offers::test_utils::*; use crate::routing::gossip::NetworkGraph; @@ -2282,6 +2292,7 @@ mod tests { use crate::sync::{Arc, Mutex, RwLock}; use crate::util::errors::APIError; use crate::util::hash_tables::new_hash_map; + use crate::util::ser::Readable; use crate::util::test_utils; use alloc::collections::VecDeque; @@ -2823,6 +2834,11 @@ mod tests { assert!(pending_events.lock().unwrap().is_empty()); } + fn invoice_request() -> InvoiceRequest { + let invreq_bytes = >::from_hex("00200101010101010101010101010101010101010101010101010101010101010101080203e80a00162102bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f25821035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42cf040a31d68198578a5aa1fe57de5f6d33f89c1556752cb333dbb56ac727f751893804d3a26b42909f1952fb1db8080238f9476b829160387692df35ff85dfe72e2ed").unwrap(); + Readable::read(&mut Cursor::new(&invreq_bytes[..])).unwrap() + } + #[test] fn time_out_unreleased_async_payments() { let pending_events = Mutex::new(VecDeque::new()); @@ -2844,6 +2860,7 @@ mod tests { keysend_preimage: PaymentPreimage([0; 32]), retry_strategy: Retry::Attempts(0), route_params, + invoice_request: invoice_request(), }; outbounds.insert(payment_id, outbound); core::mem::drop(outbounds); @@ -2890,6 +2907,7 @@ mod tests { keysend_preimage: PaymentPreimage([0; 32]), retry_strategy: Retry::Attempts(0), route_params, + invoice_request: invoice_request(), }; outbounds.insert(payment_id, outbound); core::mem::drop(outbounds);