@@ -387,6 +387,57 @@ impl OutboundPayments {
387387 }
388388 }
389389
390+ pub ( super ) fn send_payment < R : Deref , K : Deref , L : Deref , F > ( & self , payment_hash : PaymentHash ,
391+ payment_secret : & Option < PaymentSecret > , payment_id : PaymentId , retry_strategy : Retry ,
392+ route_params : RouteParameters , router : & R , first_hops : Vec < ChannelDetails > ,
393+ inflight_htlcs : InFlightHtlcs , keys_manager : & K , best_block_height : u32 , logger : & L ,
394+ send_payment_along_path : F )
395+ -> Result < ( ) , PaymentSendFailure >
396+ where
397+ R :: Target : Router ,
398+ K :: Target : KeysInterface ,
399+ F : Fn ( & Vec < RouteHop > , & Option < PaymentParameters > , & PaymentHash , & Option < PaymentSecret > , u64 ,
400+ u32 , PaymentId , & Option < PaymentPreimage > , [ u8 ; 32 ] ) -> Result < ( ) , APIError > ,
401+ L :: Target : Logger ,
402+ {
403+ #[ cfg( feature = "std" ) ] {
404+ if has_expired ( & route_params) {
405+ log_trace ! ( logger, "Invoice expired prior to send for payment {}" , log_bytes!( payment_hash. 0 ) ) ;
406+ return Err ( PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError { err : format ! ( "Invoice expired prior to send for payment {}" , log_bytes!( payment_hash. 0 ) ) } ) ) ;
407+ }
408+ }
409+
410+ let route = router. find_route (
411+ & keys_manager. get_node_id ( Recipient :: Node ) . unwrap ( ) , & route_params,
412+ Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) , & inflight_htlcs
413+ ) . map_err ( |e| PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError {
414+ err : format ! ( "Failed to find a route for payment {}: {:?}" , log_bytes!( payment_id. 0 ) , e) , // TODO: add APIError::RouteNotFound
415+ } ) ) ?;
416+
417+ log_trace ! ( logger, "Attempting to send payment with id {} and hash {} over route {}" , log_bytes!( payment_id. 0 ) , log_bytes!( payment_hash. 0 ) , log_route!( route) ) ;
418+ let onion_session_privs = self . add_new_pending_payment ( payment_hash, * payment_secret, payment_id, & route, retry_strategy, keys_manager, best_block_height) ?;
419+ match self . send_payment_internal ( & route, payment_hash, payment_secret, None , payment_id, None , onion_session_privs, keys_manager, best_block_height, & send_payment_along_path) {
420+ Err ( PaymentSendFailure :: AllFailedResendSafe ( _) ) => {
421+ self . retry_payment ( payment_id, route_params, router, first_hops, inflight_htlcs, keys_manager, best_block_height, & send_payment_along_path)
422+ } ,
423+ Err ( PaymentSendFailure :: PartialFailure { failed_paths_retry, .. } ) => {
424+ if let Some ( retry) = failed_paths_retry {
425+ // Some paths were sent, even if we failed to send the full MPP value our recipient may
426+ // misbehave and claim the funds, at which point we have to consider the payment sent, so
427+ // return `Ok()` here, ignoring any retry errors.
428+ let _ = self . retry_payment ( payment_id, retry, router, first_hops, inflight_htlcs, keys_manager, best_block_height, & send_payment_along_path) ;
429+ Ok ( ( ) )
430+ } else {
431+ // This may happen if we send a payment and some paths fail, but only due to a temporary
432+ // monitor failure or the like, implying they're really in-flight, but we haven't sent the
433+ // initial HTLC-Add messages yet.
434+ Ok ( ( ) )
435+ }
436+ } ,
437+ res => res,
438+ }
439+ }
440+
390441 pub ( super ) fn send_payment_with_route < K : Deref , F > ( & self , route : & Route , payment_hash : PaymentHash ,
391442 payment_secret : & Option < PaymentSecret > , payment_id : PaymentId , keys_manager : & K ,
392443 best_block_height : u32 , send_payment_along_path : F )
@@ -397,7 +448,7 @@ impl OutboundPayments {
397448 u32 , PaymentId , & Option < PaymentPreimage > , [ u8 ; 32 ] ) -> Result < ( ) , APIError >
398449 {
399450 let onion_session_privs = self . add_new_pending_payment ( payment_hash, * payment_secret, payment_id, route, Retry :: Attempts ( 0 ) , keys_manager, best_block_height) ?;
400- self . send_payment_internal ( route, payment_hash, payment_secret, None , payment_id, None , onion_session_privs, keys_manager, best_block_height, send_payment_along_path)
451+ self . send_payment_internal ( route, payment_hash, payment_secret, None , payment_id, None , onion_session_privs, keys_manager, best_block_height, & send_payment_along_path)
401452 }
402453
403454 pub ( super ) fn send_spontaneous_payment < K : Deref , F > ( & self , route : & Route ,
@@ -416,7 +467,7 @@ impl OutboundPayments {
416467 let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . into_inner ( ) ) ;
417468 let onion_session_privs = self . add_new_pending_payment ( payment_hash, None , payment_id, & route, Retry :: Attempts ( 0 ) , keys_manager, best_block_height) ?;
418469
419- match self . send_payment_internal ( route, payment_hash, & None , Some ( preimage) , payment_id, None , onion_session_privs, keys_manager, best_block_height, send_payment_along_path) {
470+ match self . send_payment_internal ( route, payment_hash, & None , Some ( preimage) , payment_id, None , onion_session_privs, keys_manager, best_block_height, & send_payment_along_path) {
420471 Ok ( ( ) ) => Ok ( payment_hash) ,
421472 Err ( e) => Err ( e)
422473 }
@@ -425,7 +476,7 @@ impl OutboundPayments {
425476 pub ( super ) fn retry_payment < R : Deref , K : Deref , F > ( & self , payment_id : PaymentId ,
426477 route_params : RouteParameters , router : & R , first_hops : Vec < ChannelDetails > ,
427478 inflight_htlcs : InFlightHtlcs , keys_manager : & K , best_block_height : u32 ,
428- send_payment_along_path : F ) -> Result < ( ) , PaymentSendFailure >
479+ send_payment_along_path : & F ) -> Result < ( ) , PaymentSendFailure >
429480 where
430481 R :: Target : Router ,
431482 K :: Target : KeysInterface ,
@@ -456,11 +507,12 @@ impl OutboundPayments {
456507 err : format ! ( "Failed to find a route for payment {}: {:?}" , log_bytes!( payment_id. 0 ) , e) , // TODO: add APIError::RouteNotFound
457508 } ) ) ?;
458509
459- match self . retry_payment_with_route ( & route, payment_id, keys_manager, best_block_height, & send_payment_along_path) {
510+ match self . retry_payment_with_route ( & route, payment_id, keys_manager, best_block_height, send_payment_along_path) {
460511 Err ( PaymentSendFailure :: AllFailedResendSafe ( _) ) => {
461512 self . retry_payment ( payment_id, route_params, router, first_hops, inflight_htlcs, keys_manager, best_block_height, send_payment_along_path)
462513 } ,
463514 Err ( PaymentSendFailure :: PartialFailure { failed_paths_retry : Some ( retry) , .. } ) => {
515+ // Always return Ok for the same reason as noted in send_payment.
464516 let _ = self . retry_payment ( payment_id, retry, router, first_hops, inflight_htlcs, keys_manager, best_block_height, send_payment_along_path) ;
465517 Ok ( ( ) )
466518 } ,
@@ -557,7 +609,7 @@ impl OutboundPayments {
557609 let route = Route { paths : vec ! [ hops] , payment_params : None } ;
558610 let onion_session_privs = self . add_new_pending_payment ( payment_hash, None , payment_id, & route, Retry :: Attempts ( 0 ) , keys_manager, best_block_height) ?;
559611
560- match self . send_payment_internal ( & route, payment_hash, & None , None , payment_id, None , onion_session_privs, keys_manager, best_block_height, send_payment_along_path) {
612+ match self . send_payment_internal ( & route, payment_hash, & None , None , payment_id, None , onion_session_privs, keys_manager, best_block_height, & send_payment_along_path) {
561613 Ok ( ( ) ) => Ok ( ( payment_hash, payment_id) ) ,
562614 Err ( e) => Err ( e)
563615 }
@@ -601,7 +653,7 @@ impl OutboundPayments {
601653 ( & self , route : & Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > ,
602654 keysend_preimage : Option < PaymentPreimage > , payment_id : PaymentId , recv_value_msat : Option < u64 > ,
603655 onion_session_privs : Vec < [ u8 ; 32 ] > , keys_manager : & K , best_block_height : u32 ,
604- send_payment_along_path : F ) -> Result < ( ) , PaymentSendFailure >
656+ send_payment_along_path : & F ) -> Result < ( ) , PaymentSendFailure >
605657 where
606658 K :: Target : KeysInterface ,
607659 F : Fn ( & Vec < RouteHop > , & Option < PaymentParameters > , & PaymentHash , & Option < PaymentSecret > , u64 ,
@@ -724,7 +776,7 @@ impl OutboundPayments {
724776 {
725777 self . send_payment_internal ( route, payment_hash, payment_secret, keysend_preimage, payment_id,
726778 recv_value_msat, onion_session_privs, keys_manager, best_block_height,
727- send_payment_along_path)
779+ & send_payment_along_path)
728780 }
729781
730782 pub ( super ) fn claim_htlc < L : Deref > ( & self , payment_id : PaymentId ,
0 commit comments