Skip to content

Commit 42537f3

Browse files
Store keysend preimage in outbound payments
This sets us up for spontaneous payment retries in ChannelManager. Currently, retrying spontaneous payments is broken in InvoicePayer because it does not include the keysend preimage on retry.
1 parent 172241a commit 42537f3

File tree

2 files changed

+14
-10
lines changed

2 files changed

+14
-10
lines changed

lightning/src/ln/channelmanager.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7367,6 +7367,7 @@ where
73677367
session_privs: [session_priv_bytes].iter().map(|a| *a).collect(),
73687368
payment_hash: htlc.payment_hash,
73697369
payment_secret,
7370+
keysend_preimage: None, // only used for retries, and we'll never retry on startup
73707371
pending_amt_msat: path_amt,
73717372
pending_fee_msat: Some(path_fee),
73727373
total_msat: path_amt,

lightning/src/ln/outbound_payment.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub(crate) enum PendingOutboundPayment {
4848
session_privs: HashSet<[u8; 32]>,
4949
payment_hash: PaymentHash,
5050
payment_secret: Option<PaymentSecret>,
51+
keysend_preimage: Option<PaymentPreimage>,
5152
pending_amt_msat: u64,
5253
/// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+.
5354
pending_fee_msat: Option<u64>,
@@ -432,7 +433,7 @@ impl OutboundPayments {
432433
F: Fn(&Vec<RouteHop>, &Option<PaymentParameters>, &PaymentHash, &Option<PaymentSecret>, u64,
433434
u32, PaymentId, &Option<PaymentPreimage>, [u8; 32]) -> Result<(), APIError>
434435
{
435-
let onion_session_privs = self.add_new_pending_payment(payment_hash, *payment_secret, payment_id, route, None, None, entropy_source, best_block_height)?;
436+
let onion_session_privs = self.add_new_pending_payment(payment_hash, *payment_secret, payment_id, None, route, None, None, entropy_source, best_block_height)?;
436437
self.pay_route_internal(route, payment_hash, payment_secret, None, payment_id, None,
437438
onion_session_privs, node_signer, best_block_height, &send_payment_along_path)
438439
.map_err(|e| { self.remove_outbound_if_all_failed(payment_id, &e); e })
@@ -453,7 +454,7 @@ impl OutboundPayments {
453454
None => PaymentPreimage(entropy_source.get_secure_random_bytes()),
454455
};
455456
let payment_hash = PaymentHash(Sha256::hash(&preimage.0).into_inner());
456-
let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, &route, None, None, entropy_source, best_block_height)?;
457+
let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, Some(preimage), &route, None, None, entropy_source, best_block_height)?;
457458

458459
match self.pay_route_internal(route, payment_hash, &None, Some(preimage), payment_id, None, onion_session_privs, node_signer, best_block_height, &send_payment_along_path) {
459460
Ok(()) => Ok(payment_hash),
@@ -540,7 +541,7 @@ impl OutboundPayments {
540541
}))?;
541542

542543
let res = if let Some((payment_hash, payment_secret, retry_strategy)) = initial_send_info {
543-
let onion_session_privs = self.add_new_pending_payment(payment_hash, *payment_secret, payment_id, &route, Some(retry_strategy), Some(route_params.payment_params.clone()), entropy_source, best_block_height)?;
544+
let onion_session_privs = self.add_new_pending_payment(payment_hash, *payment_secret, payment_id, None, &route, Some(retry_strategy), Some(route_params.payment_params.clone()), entropy_source, best_block_height)?;
544545
self.pay_route_internal(&route, payment_hash, payment_secret, None, payment_id, None, onion_session_privs, node_signer, best_block_height, send_payment_along_path)
545546
} else {
546547
self.retry_payment_with_route(&route, payment_id, entropy_source, node_signer, best_block_height, send_payment_along_path)
@@ -669,7 +670,7 @@ impl OutboundPayments {
669670
}
670671

671672
let route = Route { paths: vec![hops], payment_params: None };
672-
let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, &route, None, None, entropy_source, best_block_height)?;
673+
let onion_session_privs = self.add_new_pending_payment(payment_hash, None, payment_id, None, &route, None, None, entropy_source, best_block_height)?;
673674

674675
match self.pay_route_internal(&route, payment_hash, &None, None, payment_id, None, onion_session_privs, node_signer, best_block_height, &send_payment_along_path) {
675676
Ok(()) => Ok((payment_hash, payment_id)),
@@ -685,13 +686,13 @@ impl OutboundPayments {
685686
&self, payment_hash: PaymentHash, payment_secret: Option<PaymentSecret>, payment_id: PaymentId,
686687
route: &Route, retry_strategy: Option<Retry>, entropy_source: &ES, best_block_height: u32
687688
) -> Result<Vec<[u8; 32]>, PaymentSendFailure> where ES::Target: EntropySource {
688-
self.add_new_pending_payment(payment_hash, payment_secret, payment_id, route, retry_strategy, None, entropy_source, best_block_height)
689+
self.add_new_pending_payment(payment_hash, payment_secret, payment_id, None, route, retry_strategy, None, entropy_source, best_block_height)
689690
}
690691

691692
pub(super) fn add_new_pending_payment<ES: Deref>(
692693
&self, payment_hash: PaymentHash, payment_secret: Option<PaymentSecret>, payment_id: PaymentId,
693-
route: &Route, retry_strategy: Option<Retry>, payment_params: Option<PaymentParameters>,
694-
entropy_source: &ES, best_block_height: u32
694+
keysend_preimage: Option<PaymentPreimage>, route: &Route, retry_strategy: Option<Retry>,
695+
payment_params: Option<PaymentParameters>, entropy_source: &ES, best_block_height: u32
695696
) -> Result<Vec<[u8; 32]>, PaymentSendFailure> where ES::Target: EntropySource {
696697
let mut onion_session_privs = Vec::with_capacity(route.paths.len());
697698
for _ in 0..route.paths.len() {
@@ -711,6 +712,7 @@ impl OutboundPayments {
711712
pending_fee_msat: Some(0),
712713
payment_hash,
713714
payment_secret,
715+
keysend_preimage,
714716
starting_block_height: best_block_height,
715717
total_msat: route.get_total_amount(),
716718
});
@@ -1158,6 +1160,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
11581160
(10, starting_block_height, required),
11591161
(not_written, retry_strategy, (static_value, None)),
11601162
(not_written, attempts, (static_value, PaymentAttempts::new())),
1163+
(not_written, keysend_preimage, (static_value, None)),
11611164
},
11621165
(3, Abandoned) => {
11631166
(0, session_privs, required),
@@ -1247,9 +1250,9 @@ mod tests {
12471250
Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }));
12481251

12491252
let err = if on_retry {
1250-
outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), None, PaymentId([0; 32]),
1251-
&Route { paths: vec![], payment_params: None }, Some(Retry::Attempts(1)), Some(route_params.payment_params.clone()),
1252-
&&keys_manager, 0).unwrap();
1253+
outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), None, PaymentId([0; 32]), None,
1254+
&Route { paths: vec![], payment_params: None }, Some(Retry::Attempts(1)),
1255+
Some(route_params.payment_params.clone()), &&keys_manager, 0).unwrap();
12531256
outbound_payments.pay_internal(
12541257
PaymentId([0; 32]), None, route_params, &&router, vec![], InFlightHtlcs::new(),
12551258
&&keys_manager, &&keys_manager, 0, &&logger, &|_, _, _, _, _, _, _, _, _| Ok(())).unwrap_err()

0 commit comments

Comments
 (0)