@@ -576,8 +576,24 @@ pub enum Bolt12PaymentError {
576576pub 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