Skip to content

Commit 9ac4080

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 c1fdd4f commit 9ac4080

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+.
@@ -881,7 +882,7 @@ impl OutboundPayments {
881882
route_params.max_total_routing_fee_msat = Some(max_fee_msat);
882883
}
883884
self.send_payment_for_bolt12_invoice_internal(
884-
payment_id, payment_hash, None, route_params, retry_strategy, router, first_hops,
885+
payment_id, payment_hash, None, None, route_params, retry_strategy, router, first_hops,
885886
inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
886887
logger, pending_events, send_payment_along_path
887888
)
@@ -891,10 +892,10 @@ impl OutboundPayments {
891892
R: Deref, ES: Deref, NS: Deref, NL: Deref, IH, SP, L: Deref
892893
>(
893894
&self, payment_id: PaymentId, payment_hash: PaymentHash,
894-
keysend_preimage: Option<PaymentPreimage>, mut route_params: RouteParameters,
895-
retry_strategy: Retry, router: &R, first_hops: Vec<ChannelDetails>, inflight_htlcs: IH,
896-
entropy_source: &ES, node_signer: &NS, node_id_lookup: &NL,
897-
secp_ctx: &Secp256k1<secp256k1::All>, best_block_height: u32, logger: &L,
895+
keysend_preimage: Option<PaymentPreimage>, mut invoice_request: Option<InvoiceRequest>,
896+
mut route_params: RouteParameters, retry_strategy: Retry, router: &R,
897+
first_hops: Vec<ChannelDetails>, inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS,
898+
node_id_lookup: &NL, secp_ctx: &Secp256k1<secp256k1::All>, best_block_height: u32, logger: &L,
898899
pending_events: &Mutex<VecDeque<(events::Event, Option<EventCompletionAction>)>>,
899900
send_payment_along_path: SP,
900901
) -> Result<(), Bolt12PaymentError>
@@ -949,8 +950,8 @@ impl OutboundPayments {
949950

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

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

@@ -1329,14 +1331,14 @@ impl OutboundPayments {
13291331
}
13301332
}
13311333
}
1332-
let (total_msat, recipient_onion, keysend_preimage, onion_session_privs) = {
1334+
let (total_msat, recipient_onion, keysend_preimage, onion_session_privs, invoice_request) = {
13331335
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
13341336
match outbounds.entry(payment_id) {
13351337
hash_map::Entry::Occupied(mut payment) => {
13361338
match payment.get() {
13371339
PendingOutboundPayment::Retryable {
13381340
total_msat, keysend_preimage, payment_secret, payment_metadata,
1339-
custom_tlvs, pending_amt_msat, ..
1341+
custom_tlvs, pending_amt_msat, invoice_request, ..
13401342
} => {
13411343
const RETRY_OVERFLOW_PERCENTAGE: u64 = 10;
13421344
let retry_amt_msat = route.get_total_amount();
@@ -1359,6 +1361,7 @@ impl OutboundPayments {
13591361
custom_tlvs: custom_tlvs.clone(),
13601362
};
13611363
let keysend_preimage = *keysend_preimage;
1364+
let invoice_request = invoice_request.clone();
13621365

13631366
let mut onion_session_privs = Vec::with_capacity(route.paths.len());
13641367
for _ in 0..route.paths.len() {
@@ -1371,7 +1374,7 @@ impl OutboundPayments {
13711374

13721375
payment.get_mut().increment_attempts();
13731376

1374-
(total_msat, recipient_onion, keysend_preimage, onion_session_privs)
1377+
(total_msat, recipient_onion, keysend_preimage, onion_session_privs, invoice_request)
13751378
},
13761379
PendingOutboundPayment::Legacy { .. } => {
13771380
log_error!(logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102");
@@ -1409,8 +1412,8 @@ impl OutboundPayments {
14091412
}
14101413
};
14111414
let res = self.pay_route_internal(&route, payment_hash, &recipient_onion, keysend_preimage,
1412-
None, payment_id, Some(total_msat), onion_session_privs, node_signer, best_block_height,
1413-
&send_payment_along_path);
1415+
invoice_request.as_ref(), payment_id, Some(total_msat), onion_session_privs, node_signer,
1416+
best_block_height, &send_payment_along_path);
14141417
log_info!(logger, "Result retrying payment id {}: {:?}", &payment_id, res);
14151418
if let Err(e) = res {
14161419
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);
@@ -1562,7 +1565,7 @@ impl OutboundPayments {
15621565
hash_map::Entry::Occupied(_) => Err(PaymentSendFailure::DuplicatePayment),
15631566
hash_map::Entry::Vacant(entry) => {
15641567
let (payment, onion_session_privs) = self.create_pending_payment(
1565-
payment_hash, recipient_onion, keysend_preimage, route, retry_strategy,
1568+
payment_hash, recipient_onion, keysend_preimage, None, route, retry_strategy,
15661569
payment_params, entropy_source, best_block_height
15671570
);
15681571
entry.insert(payment);
@@ -1573,8 +1576,9 @@ impl OutboundPayments {
15731576

15741577
fn create_pending_payment<ES: Deref>(
15751578
&self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
1576-
keysend_preimage: Option<PaymentPreimage>, route: &Route, retry_strategy: Option<Retry>,
1577-
payment_params: Option<PaymentParameters>, entropy_source: &ES, best_block_height: u32
1579+
keysend_preimage: Option<PaymentPreimage>, invoice_request: Option<InvoiceRequest>,
1580+
route: &Route, retry_strategy: Option<Retry>, payment_params: Option<PaymentParameters>,
1581+
entropy_source: &ES, best_block_height: u32
15781582
) -> (PendingOutboundPayment, Vec<[u8; 32]>)
15791583
where
15801584
ES::Target: EntropySource,
@@ -1595,6 +1599,7 @@ impl OutboundPayments {
15951599
payment_secret: recipient_onion.payment_secret,
15961600
payment_metadata: recipient_onion.payment_metadata,
15971601
keysend_preimage,
1602+
invoice_request,
15981603
custom_tlvs: recipient_onion.custom_tlvs,
15991604
starting_block_height: best_block_height,
16001605
total_msat: route.get_total_amount(),
@@ -2156,6 +2161,7 @@ impl OutboundPayments {
21562161
payment_secret: None, // only used for retries, and we'll never retry on startup
21572162
payment_metadata: None, // only used for retries, and we'll never retry on startup
21582163
keysend_preimage: None, // only used for retries, and we'll never retry on startup
2164+
invoice_request: None, // only used for retries, and we'll never retry on startup
21592165
custom_tlvs: Vec::new(), // only used for retries, and we'll never retry on startup
21602166
pending_amt_msat: path_amt,
21612167
pending_fee_msat: Some(path_fee),
@@ -2242,6 +2248,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22422248
(9, custom_tlvs, optional_vec),
22432249
(10, starting_block_height, required),
22442250
(11, remaining_max_total_routing_fee_msat, option),
2251+
(13, invoice_request, option),
22452252
(not_written, retry_strategy, (static_value, None)),
22462253
(not_written, attempts, (static_value, PaymentAttempts::new())),
22472254
},

0 commit comments

Comments
 (0)