@@ -576,8 +576,24 @@ pub enum Bolt12PaymentError {
576
576
pub enum ProbeSendFailure {
577
577
/// We were unable to find a route to the destination.
578
578
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 ,
581
597
}
582
598
583
599
/// Information which is provided, encrypted, to the payment recipient when sending HTLCs.
@@ -1497,7 +1513,7 @@ impl OutboundPayments {
1497
1513
pub ( super ) fn send_probe < ES : Deref , NS : Deref , F > (
1498
1514
& self , path : Path , probing_cookie_secret : [ u8 ; 32 ] , entropy_source : & ES , node_signer : & NS ,
1499
1515
best_block_height : u32 , send_payment_along_path : F
1500
- ) -> Result < ( PaymentHash , PaymentId ) , PaymentSendFailure >
1516
+ ) -> Result < ( PaymentHash , PaymentId ) , ProbeSendFailure >
1501
1517
where
1502
1518
ES :: Target : EntropySource ,
1503
1519
NS :: Target : NodeSigner ,
@@ -1509,15 +1525,19 @@ impl OutboundPayments {
1509
1525
let payment_hash = probing_cookie_from_id ( & payment_id, probing_cookie_secret) ;
1510
1526
1511
1527
if path. hops . len ( ) < 2 && path. blinded_tail . is_none ( ) {
1512
- return Err ( PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError {
1528
+ return Err ( ProbeSendFailure :: ParameterError ( APIError :: APIMisuseError {
1513
1529
err : "No need probing a path with less than two hops" . to_string ( )
1514
1530
} ) )
1515
1531
}
1516
1532
1517
1533
let route = Route { paths : vec ! [ path] , route_params : None } ;
1518
1534
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1519
1535
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
+ } ) ?;
1521
1541
1522
1542
let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
1523
1543
match self . pay_route_internal ( & route, payment_hash, & recipient_onion_fields,
@@ -1527,7 +1547,26 @@ impl OutboundPayments {
1527
1547
Ok ( ( ) ) => Ok ( ( payment_hash, payment_id) ) ,
1528
1548
Err ( e) => {
1529
1549
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
+ }
1531
1570
}
1532
1571
}
1533
1572
}
0 commit comments