Skip to content

Commit bed00a7

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 267f10c commit bed00a7

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
},
@@ -2255,32 +2261,37 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22552261
(2, keysend_preimage, required),
22562262
(4, retry_strategy, required),
22572263
(6, route_params, required),
2264+
(8, invoice_request, required),
22582265
},
22592266
);
22602267

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

22662274
use core::time::Duration;
22672275

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

22862297
use alloc::collections::VecDeque;
@@ -2822,6 +2833,11 @@ mod tests {
28222833
assert!(pending_events.lock().unwrap().is_empty());
28232834
}
28242835

2836+
fn invoice_request() -> InvoiceRequest {
2837+
let invreq_bytes = <Vec<u8>>::from_hex("00200101010101010101010101010101010101010101010101010101010101010101080203e80a00162102bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f25821035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42cf040a31d68198578a5aa1fe57de5f6d33f89c1556752cb333dbb56ac727f751893804d3a26b42909f1952fb1db8080238f9476b829160387692df35ff85dfe72e2ed").unwrap();
2838+
Readable::read(&mut Cursor::new(&invreq_bytes[..])).unwrap()
2839+
}
2840+
28252841
#[test]
28262842
fn time_out_unreleased_async_payments() {
28272843
let pending_events = Mutex::new(VecDeque::new());
@@ -2843,6 +2859,7 @@ mod tests {
28432859
keysend_preimage: PaymentPreimage([0; 32]),
28442860
retry_strategy: Retry::Attempts(0),
28452861
route_params,
2862+
invoice_request: invoice_request(),
28462863
};
28472864
outbounds.insert(payment_id, outbound);
28482865
core::mem::drop(outbounds);
@@ -2889,6 +2906,7 @@ mod tests {
28892906
keysend_preimage: PaymentPreimage([0; 32]),
28902907
retry_strategy: Retry::Attempts(0),
28912908
route_params,
2909+
invoice_request: invoice_request(),
28922910
};
28932911
outbounds.insert(payment_id, outbound);
28942912
core::mem::drop(outbounds);

0 commit comments

Comments
 (0)