Skip to content

Commit 9de59ca

Browse files
Stop using PaymentSendFailure within ProbeSendFailure
Removes the final usage of PaymentSendFailure from public API. This (confusing) error matched with prior versions of LDK where users had to handle payment retries themselves. Since auto-retry was introduced, the only non-deprecated use remaining was for probe send errors. Probes only have one path, though, so refactor ProbeSendFailure to omit usage of PaymentSendFailure. We don't make this error private yet because it's still used by some fuzzing code as well as internally to outbound_payments, but it isn't returned by any public functions anymore.
1 parent addc4b6 commit 9de59ca

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

lightning/src/ln/channelmanager.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4812,7 +4812,7 @@ where
48124812
/// Send a payment that is probing the given route for liquidity. We calculate the
48134813
/// [`PaymentHash`] of probes based on a static secret and a random [`PaymentId`], which allows
48144814
/// us to easily discern them from real payments.
4815-
pub fn send_probe(&self, path: Path) -> Result<(PaymentHash, PaymentId), PaymentSendFailure> {
4815+
pub fn send_probe(&self, path: Path) -> Result<(PaymentHash, PaymentId), ProbeSendFailure> {
48164816
let best_block_height = self.best_block.read().unwrap().height;
48174817
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
48184818
self.pending_outbound_payments.send_probe(path, self.probing_cookie_secret,
@@ -4930,7 +4930,7 @@ where
49304930

49314931
res.push(self.send_probe(path).map_err(|e| {
49324932
log_error!(self.logger, "Failed to send pre-flight probe: {:?}", e);
4933-
ProbeSendFailure::SendingFailed(e)
4933+
e
49344934
})?);
49354935
}
49364936

lightning/src/ln/outbound_payment.rs

+45-6
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,24 @@ pub enum Bolt12PaymentError {
576576
pub enum ProbeSendFailure {
577577
/// We were unable to find a route to the destination.
578578
RouteNotFound,
579-
/// We failed to send the payment probes.
580-
SendingFailed(PaymentSendFailure),
579+
/// A parameter which was passed to [`ChannelManager::send_probe`] was invalid, preventing us from
580+
/// attempting to send the probe at all.
581+
///
582+
/// You can freely resend the probe (with the parameter error fixed).
583+
///
584+
/// Because the probe failed outright, no payment tracking is done and no
585+
/// [`Event::ProbeFailed`] events will be generated.
586+
///
587+
/// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe
588+
/// [`Event::ProbeFailed`]: crate::events::Event::ProbeFailed
589+
ParameterError(APIError),
590+
/// Indicates that a payment for the provided [`PaymentId`] is already in-flight and has not
591+
/// yet completed (i.e. generated an [`Event::ProbeSuccessful`] or [`Event::ProbeFailed`]).
592+
///
593+
/// [`PaymentId`]: crate::ln::channelmanager::PaymentId
594+
/// [`Event::ProbeSuccessful`]: crate::events::Event::ProbeSuccessful
595+
/// [`Event::ProbeFailed`]: crate::events::Event::ProbeFailed
596+
DuplicateProbe,
581597
}
582598

583599
/// Information which is provided, encrypted, to the payment recipient when sending HTLCs.
@@ -1497,7 +1513,7 @@ impl OutboundPayments {
14971513
pub(super) fn send_probe<ES: Deref, NS: Deref, F>(
14981514
&self, path: Path, probing_cookie_secret: [u8; 32], entropy_source: &ES, node_signer: &NS,
14991515
best_block_height: u32, send_payment_along_path: F
1500-
) -> Result<(PaymentHash, PaymentId), PaymentSendFailure>
1516+
) -> Result<(PaymentHash, PaymentId), ProbeSendFailure>
15011517
where
15021518
ES::Target: EntropySource,
15031519
NS::Target: NodeSigner,
@@ -1509,15 +1525,19 @@ impl OutboundPayments {
15091525
let payment_hash = probing_cookie_from_id(&payment_id, probing_cookie_secret);
15101526

15111527
if path.hops.len() < 2 && path.blinded_tail.is_none() {
1512-
return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
1528+
return Err(ProbeSendFailure::ParameterError(APIError::APIMisuseError {
15131529
err: "No need probing a path with less than two hops".to_string()
15141530
}))
15151531
}
15161532

15171533
let route = Route { paths: vec![path], route_params: None };
15181534
let onion_session_privs = self.add_new_pending_payment(payment_hash,
15191535
RecipientOnionFields::secret_only(payment_secret), payment_id, None, &route, None, None,
1520-
entropy_source, best_block_height)?;
1536+
entropy_source, best_block_height
1537+
).map_err(|e| {
1538+
debug_assert!(matches!(e, PaymentSendFailure::DuplicatePayment));
1539+
ProbeSendFailure::DuplicateProbe
1540+
})?;
15211541

15221542
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
15231543
match self.pay_route_internal(&route, payment_hash, &recipient_onion_fields,
@@ -1527,7 +1547,26 @@ impl OutboundPayments {
15271547
Ok(()) => Ok((payment_hash, payment_id)),
15281548
Err(e) => {
15291549
self.remove_outbound_if_all_failed(payment_id, &e);
1530-
Err(e)
1550+
match e {
1551+
PaymentSendFailure::DuplicatePayment => Err(ProbeSendFailure::DuplicateProbe),
1552+
PaymentSendFailure::ParameterError(err) => Err(ProbeSendFailure::ParameterError(err)),
1553+
PaymentSendFailure::PartialFailure { results, .. }
1554+
| PaymentSendFailure::PathParameterError(results) => {
1555+
debug_assert_eq!(results.len(), 1);
1556+
let err = results.into_iter()
1557+
.find(|res| res.is_err())
1558+
.map(|err| err.unwrap_err())
1559+
.unwrap_or(APIError::APIMisuseError { err: "Unexpected error".to_owned() });
1560+
Err(ProbeSendFailure::ParameterError(err))
1561+
},
1562+
PaymentSendFailure::AllFailedResendSafe(mut errors) => {
1563+
debug_assert_eq!(errors.len(), 1);
1564+
let err = errors
1565+
.pop()
1566+
.unwrap_or(APIError::APIMisuseError { err: "Unexpected error".to_owned() });
1567+
Err(ProbeSendFailure::ParameterError(err))
1568+
}
1569+
}
15311570
}
15321571
}
15331572
}

0 commit comments

Comments
 (0)