Skip to content

Commit f80b0e9

Browse files
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 <lightning/bolts#1149>, 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.
1 parent 4ed3ec6 commit f80b0e9

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

lightning/src/ln/outbound_payment.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub(crate) enum PendingOutboundPayment {
8383
keysend_preimage: PaymentPreimage,
8484
retry_strategy: Retry,
8585
route_params: RouteParameters,
86+
invoice_request: InvoiceRequest,
8687
},
8788
Retryable {
8889
retry_strategy: Option<Retry>,
@@ -1004,7 +1005,7 @@ impl OutboundPayments {
10041005
}
10051006

10061007
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
1007-
hash_map::Entry::Occupied(mut entry) => match entry.get() {
1008+
hash_map::Entry::Occupied(mut entry) => match entry.get_mut() {
10081009
PendingOutboundPayment::AwaitingInvoice {
10091010
retry_strategy, retryable_invoice_request, max_total_routing_fee_msat, ..
10101011
} => {
@@ -1048,6 +1049,11 @@ impl OutboundPayments {
10481049
keysend_preimage,
10491050
retry_strategy: *retry_strategy,
10501051
route_params,
1052+
invoice_request:
1053+
retryable_invoice_request
1054+
.take()
1055+
.ok_or(Bolt12PaymentError::UnexpectedInvoice)?
1056+
.invoice_request,
10511057
};
10521058
return Ok(())
10531059
},
@@ -2256,32 +2262,37 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22562262
(2, keysend_preimage, required),
22572263
(4, retry_strategy, required),
22582264
(6, route_params, required),
2265+
(8, invoice_request, required),
22592266
},
22602267
);
22612268

22622269
#[cfg(test)]
22632270
mod tests {
2271+
use bitcoin::hex::FromHex;
22642272
use bitcoin::network::Network;
22652273
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
22662274

22672275
use core::time::Duration;
22682276

22692277
use crate::blinded_path::EmptyNodeIdLookUp;
22702278
use crate::events::{Event, PathFailure, PaymentFailureReason};
2279+
use crate::io::Cursor;
22712280
use crate::types::payment::{PaymentHash, PaymentPreimage};
22722281
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
22732282
use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures};
22742283
use crate::ln::msgs::{ErrorAction, LightningError};
22752284
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PendingOutboundPayment, Retry, RetryableSendFailure, StaleExpiration};
22762285
#[cfg(feature = "std")]
22772286
use crate::offers::invoice::DEFAULT_RELATIVE_EXPIRY;
2287+
use crate::offers::invoice_request::InvoiceRequest;
22782288
use crate::offers::offer::OfferBuilder;
22792289
use crate::offers::test_utils::*;
22802290
use crate::routing::gossip::NetworkGraph;
22812291
use crate::routing::router::{InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters};
22822292
use crate::sync::{Arc, Mutex, RwLock};
22832293
use crate::util::errors::APIError;
22842294
use crate::util::hash_tables::new_hash_map;
2295+
use crate::util::ser::Readable;
22852296
use crate::util::test_utils;
22862297

22872298
use alloc::collections::VecDeque;
@@ -2823,6 +2834,11 @@ mod tests {
28232834
assert!(pending_events.lock().unwrap().is_empty());
28242835
}
28252836

2837+
fn invoice_request() -> InvoiceRequest {
2838+
let invreq_bytes = <Vec<u8>>::from_hex("00200101010101010101010101010101010101010101010101010101010101010101080203e80a00162102bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f25821035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42cf040a31d68198578a5aa1fe57de5f6d33f89c1556752cb333dbb56ac727f751893804d3a26b42909f1952fb1db8080238f9476b829160387692df35ff85dfe72e2ed").unwrap();
2839+
Readable::read(&mut Cursor::new(&invreq_bytes[..])).unwrap()
2840+
}
2841+
28262842
#[test]
28272843
fn time_out_unreleased_async_payments() {
28282844
let pending_events = Mutex::new(VecDeque::new());
@@ -2844,6 +2860,7 @@ mod tests {
28442860
keysend_preimage: PaymentPreimage([0; 32]),
28452861
retry_strategy: Retry::Attempts(0),
28462862
route_params,
2863+
invoice_request: invoice_request(),
28472864
};
28482865
outbounds.insert(payment_id, outbound);
28492866
core::mem::drop(outbounds);
@@ -2890,6 +2907,7 @@ mod tests {
28902907
keysend_preimage: PaymentPreimage([0; 32]),
28912908
retry_strategy: Retry::Attempts(0),
28922909
route_params,
2910+
invoice_request: invoice_request(),
28932911
};
28942912
outbounds.insert(payment_id, outbound);
28952913
core::mem::drop(outbounds);

0 commit comments

Comments
 (0)