Skip to content

Commit b16e613

Browse files
Include invreq in payment onion when retrying async payments
While in the last commit we began including invoice requests in async payment onions on initial send, further work is needed to include them on retry. Here we begin storing invreqs in our retry data, and pass them along for inclusion in the onion on payment retry. 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 a1d7412 commit b16e613

File tree

1 file changed

+28
-21
lines changed

1 file changed

+28
-21
lines changed

lightning/src/ln/outbound_payment.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub(crate) enum PendingOutboundPayment {
9494
payment_secret: Option<PaymentSecret>,
9595
payment_metadata: Option<Vec<u8>>,
9696
keysend_preimage: Option<PaymentPreimage>,
97+
invoice_request: Option<InvoiceRequest>,
9798
custom_tlvs: Vec<(u64, Vec<u8>)>,
9899
pending_amt_msat: u64,
99100
/// Used to track the fee paid. Present iff the payment was serialized on 0.0.103+.
@@ -880,7 +881,7 @@ impl OutboundPayments {
880881
route_params.max_total_routing_fee_msat = Some(max_fee_msat);
881882
}
882883
self.send_payment_for_bolt12_invoice_internal(
883-
payment_id, payment_hash, None, route_params, retry_strategy, router, first_hops,
884+
payment_id, payment_hash, None, None, route_params, retry_strategy, router, first_hops,
884885
inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
885886
logger, pending_events, send_payment_along_path
886887
)
@@ -890,10 +891,10 @@ impl OutboundPayments {
890891
R: Deref, ES: Deref, NS: Deref, NL: Deref, IH, SP, L: Deref
891892
>(
892893
&self, payment_id: PaymentId, payment_hash: PaymentHash,
893-
keysend_preimage: Option<PaymentPreimage>, mut route_params: RouteParameters,
894-
retry_strategy: Retry, router: &R, first_hops: Vec<ChannelDetails>, inflight_htlcs: IH,
895-
entropy_source: &ES, node_signer: &NS, node_id_lookup: &NL,
896-
secp_ctx: &Secp256k1<secp256k1::All>, best_block_height: u32, logger: &L,
894+
keysend_preimage: Option<PaymentPreimage>, mut invoice_request: Option<InvoiceRequest>,
895+
mut route_params: RouteParameters, retry_strategy: Retry, router: &R,
896+
first_hops: Vec<ChannelDetails>, inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS,
897+
node_id_lookup: &NL, secp_ctx: &Secp256k1<secp256k1::All>, best_block_height: u32, logger: &L,
897898
pending_events: &Mutex<VecDeque<(events::Event, Option<EventCompletionAction>)>>,
898899
send_payment_along_path: SP,
899900
) -> Result<(), Bolt12PaymentError>
@@ -948,8 +949,8 @@ impl OutboundPayments {
948949

949950
let payment_params = Some(route_params.payment_params.clone());
950951
let (retryable_payment, onion_session_privs) = self.create_pending_payment(
951-
payment_hash, recipient_onion.clone(), keysend_preimage, &route, Some(retry_strategy),
952-
payment_params, entropy_source, best_block_height
952+
payment_hash, recipient_onion.clone(), keysend_preimage, invoice_request.take(), &route,
953+
Some(retry_strategy), payment_params, entropy_source, best_block_height
953954
);
954955
let mut invoice_request_opt = None;
955956
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
@@ -1087,23 +1088,24 @@ impl OutboundPayments {
10871088
IH: Fn() -> InFlightHtlcs,
10881089
SP: Fn(SendAlongPathArgs) -> Result<(), APIError>,
10891090
{
1090-
let (payment_hash, keysend_preimage, route_params, retry_strategy) =
1091+
let (payment_hash, keysend_preimage, route_params, retry_strategy, invoice_request) =
10911092
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
10921093
hash_map::Entry::Occupied(entry) => match entry.get() {
10931094
PendingOutboundPayment::StaticInvoiceReceived {
1094-
payment_hash, route_params, retry_strategy, keysend_preimage, ..
1095+
payment_hash, route_params, retry_strategy, keysend_preimage, invoice_request, ..
10951096
} => {
1096-
(*payment_hash, *keysend_preimage, route_params.clone(), *retry_strategy)
1097+
(*payment_hash, *keysend_preimage, route_params.clone(), *retry_strategy,
1098+
invoice_request.clone())
10971099
},
10981100
_ => return Err(Bolt12PaymentError::DuplicateInvoice),
10991101
},
11001102
hash_map::Entry::Vacant(_) => return Err(Bolt12PaymentError::UnexpectedInvoice),
11011103
};
11021104

11031105
self.send_payment_for_bolt12_invoice_internal(
1104-
payment_id, payment_hash, Some(keysend_preimage), route_params, retry_strategy, router,
1105-
first_hops, inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx,
1106-
best_block_height, logger, pending_events, send_payment_along_path
1106+
payment_id, payment_hash, Some(keysend_preimage), Some(invoice_request), route_params,
1107+
retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
1108+
node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
11071109
)
11081110
}
11091111

@@ -1323,14 +1325,14 @@ impl OutboundPayments {
13231325
}
13241326
}
13251327
}
1326-
let (total_msat, recipient_onion, keysend_preimage, onion_session_privs) = {
1328+
let (total_msat, recipient_onion, keysend_preimage, onion_session_privs, invoice_request) = {
13271329
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
13281330
match outbounds.entry(payment_id) {
13291331
hash_map::Entry::Occupied(mut payment) => {
13301332
match payment.get() {
13311333
PendingOutboundPayment::Retryable {
13321334
total_msat, keysend_preimage, payment_secret, payment_metadata,
1333-
custom_tlvs, pending_amt_msat, ..
1335+
custom_tlvs, pending_amt_msat, invoice_request, ..
13341336
} => {
13351337
const RETRY_OVERFLOW_PERCENTAGE: u64 = 10;
13361338
let retry_amt_msat = route.get_total_amount();
@@ -1353,6 +1355,7 @@ impl OutboundPayments {
13531355
custom_tlvs: custom_tlvs.clone(),
13541356
};
13551357
let keysend_preimage = *keysend_preimage;
1358+
let invoice_request = invoice_request.clone();
13561359

13571360
let mut onion_session_privs = Vec::with_capacity(route.paths.len());
13581361
for _ in 0..route.paths.len() {
@@ -1365,7 +1368,7 @@ impl OutboundPayments {
13651368

13661369
payment.get_mut().increment_attempts();
13671370

1368-
(total_msat, recipient_onion, keysend_preimage, onion_session_privs)
1371+
(total_msat, recipient_onion, keysend_preimage, onion_session_privs, invoice_request)
13691372
},
13701373
PendingOutboundPayment::Legacy { .. } => {
13711374
log_error!(logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102");
@@ -1403,8 +1406,8 @@ impl OutboundPayments {
14031406
}
14041407
};
14051408
let res = self.pay_route_internal(&route, payment_hash, &recipient_onion, keysend_preimage,
1406-
None, payment_id, Some(total_msat), onion_session_privs, node_signer, best_block_height,
1407-
&send_payment_along_path);
1409+
invoice_request.as_ref(), payment_id, Some(total_msat), onion_session_privs, node_signer,
1410+
best_block_height, &send_payment_along_path);
14081411
log_info!(logger, "Result retrying payment id {}: {:?}", &payment_id, res);
14091412
if let Err(e) = res {
14101413
self.handle_pay_route_err(e, payment_id, payment_hash, route, route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path);
@@ -1556,7 +1559,7 @@ impl OutboundPayments {
15561559
hash_map::Entry::Occupied(_) => Err(PaymentSendFailure::DuplicatePayment),
15571560
hash_map::Entry::Vacant(entry) => {
15581561
let (payment, onion_session_privs) = self.create_pending_payment(
1559-
payment_hash, recipient_onion, keysend_preimage, route, retry_strategy,
1562+
payment_hash, recipient_onion, keysend_preimage, None, route, retry_strategy,
15601563
payment_params, entropy_source, best_block_height
15611564
);
15621565
entry.insert(payment);
@@ -1567,8 +1570,9 @@ impl OutboundPayments {
15671570

15681571
fn create_pending_payment<ES: Deref>(
15691572
&self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
1570-
keysend_preimage: Option<PaymentPreimage>, route: &Route, retry_strategy: Option<Retry>,
1571-
payment_params: Option<PaymentParameters>, entropy_source: &ES, best_block_height: u32
1573+
keysend_preimage: Option<PaymentPreimage>, invoice_request: Option<InvoiceRequest>,
1574+
route: &Route, retry_strategy: Option<Retry>, payment_params: Option<PaymentParameters>,
1575+
entropy_source: &ES, best_block_height: u32
15721576
) -> (PendingOutboundPayment, Vec<[u8; 32]>)
15731577
where
15741578
ES::Target: EntropySource,
@@ -1589,6 +1593,7 @@ impl OutboundPayments {
15891593
payment_secret: recipient_onion.payment_secret,
15901594
payment_metadata: recipient_onion.payment_metadata,
15911595
keysend_preimage,
1596+
invoice_request,
15921597
custom_tlvs: recipient_onion.custom_tlvs,
15931598
starting_block_height: best_block_height,
15941599
total_msat: route.get_total_amount(),
@@ -2150,6 +2155,7 @@ impl OutboundPayments {
21502155
payment_secret: None, // only used for retries, and we'll never retry on startup
21512156
payment_metadata: None, // only used for retries, and we'll never retry on startup
21522157
keysend_preimage: None, // only used for retries, and we'll never retry on startup
2158+
invoice_request: None, // only used for retries, and we'll never retry on startup
21532159
custom_tlvs: Vec::new(), // only used for retries, and we'll never retry on startup
21542160
pending_amt_msat: path_amt,
21552161
pending_fee_msat: Some(path_fee),
@@ -2236,6 +2242,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22362242
(9, custom_tlvs, optional_vec),
22372243
(10, starting_block_height, required),
22382244
(11, remaining_max_total_routing_fee_msat, option),
2245+
(13, invoice_request, option),
22392246
(not_written, retry_strategy, (static_value, None)),
22402247
(not_written, attempts, (static_value, PaymentAttempts::new())),
22412248
},

0 commit comments

Comments
 (0)