Skip to content

Commit fa3dc77

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 3911bc6 commit fa3dc77

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>,
@@ -1003,7 +1004,7 @@ impl OutboundPayments {
10031004
}
10041005

10051006
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
1006-
hash_map::Entry::Occupied(mut entry) => match entry.get() {
1007+
hash_map::Entry::Occupied(mut entry) => match entry.get_mut() {
10071008
PendingOutboundPayment::AwaitingInvoice {
10081009
retry_strategy, retryable_invoice_request, max_total_routing_fee_msat, ..
10091010
} => {
@@ -1047,6 +1048,11 @@ impl OutboundPayments {
10471048
keysend_preimage,
10481049
retry_strategy: *retry_strategy,
10491050
route_params,
1051+
invoice_request:
1052+
retryable_invoice_request
1053+
.take()
1054+
.ok_or(Bolt12PaymentError::UnexpectedInvoice)?
1055+
.invoice_request,
10501056
};
10511057
return Ok(())
10521058
},
@@ -2250,32 +2256,37 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22502256
(2, keysend_preimage, required),
22512257
(4, retry_strategy, required),
22522258
(6, route_params, required),
2259+
(8, invoice_request, required),
22532260
},
22542261
);
22552262

22562263
#[cfg(test)]
22572264
mod tests {
2265+
use bitcoin::hex::FromHex;
22582266
use bitcoin::network::Network;
22592267
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
22602268

22612269
use core::time::Duration;
22622270

22632271
use crate::blinded_path::EmptyNodeIdLookUp;
22642272
use crate::events::{Event, PathFailure, PaymentFailureReason};
2273+
use crate::io::Cursor;
22652274
use crate::ln::types::{PaymentHash, PaymentPreimage};
22662275
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
22672276
use crate::ln::features::{Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures};
22682277
use crate::ln::msgs::{ErrorAction, LightningError};
22692278
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PendingOutboundPayment, Retry, RetryableSendFailure, StaleExpiration};
22702279
#[cfg(feature = "std")]
22712280
use crate::offers::invoice::DEFAULT_RELATIVE_EXPIRY;
2281+
use crate::offers::invoice_request::InvoiceRequest;
22722282
use crate::offers::offer::OfferBuilder;
22732283
use crate::offers::test_utils::*;
22742284
use crate::routing::gossip::NetworkGraph;
22752285
use crate::routing::router::{InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters};
22762286
use crate::sync::{Arc, Mutex, RwLock};
22772287
use crate::util::errors::APIError;
22782288
use crate::util::hash_tables::new_hash_map;
2289+
use crate::util::ser::Readable;
22792290
use crate::util::test_utils;
22802291

22812292
use alloc::collections::VecDeque;
@@ -2817,6 +2828,11 @@ mod tests {
28172828
assert!(pending_events.lock().unwrap().is_empty());
28182829
}
28192830

2831+
fn invoice_request() -> InvoiceRequest {
2832+
let invreq_bytes = <Vec<u8>>::from_hex("00200101010101010101010101010101010101010101010101010101010101010101080203e80a00162102bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f25821035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42cf040a31d68198578a5aa1fe57de5f6d33f89c1556752cb333dbb56ac727f751893804d3a26b42909f1952fb1db8080238f9476b829160387692df35ff85dfe72e2ed").unwrap();
2833+
Readable::read(&mut Cursor::new(&invreq_bytes[..])).unwrap()
2834+
}
2835+
28202836
#[test]
28212837
fn time_out_unreleased_async_payments() {
28222838
let pending_events = Mutex::new(VecDeque::new());
@@ -2838,6 +2854,7 @@ mod tests {
28382854
keysend_preimage: PaymentPreimage([0; 32]),
28392855
retry_strategy: Retry::Attempts(0),
28402856
route_params,
2857+
invoice_request: invoice_request(),
28412858
};
28422859
outbounds.insert(payment_id, outbound);
28432860
core::mem::drop(outbounds);
@@ -2884,6 +2901,7 @@ mod tests {
28842901
keysend_preimage: PaymentPreimage([0; 32]),
28852902
retry_strategy: Retry::Attempts(0),
28862903
route_params,
2904+
invoice_request: invoice_request(),
28872905
};
28882906
outbounds.insert(payment_id, outbound);
28892907
core::mem::drop(outbounds);

0 commit comments

Comments
 (0)