@@ -1460,10 +1460,23 @@ impl OutboundPayments {
14601460 {
14611461 match err {
14621462 PaymentSendFailure :: AllFailedResendSafe ( errs) => {
1463+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
14631464 Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut route_params, route. paths , errs. into_iter ( ) . map ( |e| Err ( e) ) , logger, pending_events) ;
14641465 self . find_route_and_send_payment ( payment_hash, payment_id, route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path) ;
14651466 } ,
14661467 PaymentSendFailure :: PartialFailure { failed_paths_retry : Some ( mut retry) , results, .. } => {
1468+ let filtered = results. iter ( ) . zip ( route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) )
1469+ . filter ( |( path_res, ( _, _) ) | {
1470+ match path_res {
1471+ // While a MonitorUpdateInProgress is an Err(_), the payment is still
1472+ // considered "in flight" and we shouldn't remove it from the
1473+ // PendingOutboundPayment set.
1474+ Ok ( _) | Err ( APIError :: MonitorUpdateInProgress ) => false ,
1475+ _ => true
1476+ }
1477+ } )
1478+ . map ( |( _, ( path, session_priv) ) | ( path, session_priv) ) ;
1479+ self . remove_session_privs ( payment_id, filtered) ;
14671480 Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut retry, route. paths , results. into_iter ( ) , logger, pending_events) ;
14681481 // Some paths were sent, even if we failed to send the full MPP value our recipient may
14691482 // misbehave and claim the funds, at which point we have to consider the payment sent, so
@@ -1477,13 +1490,13 @@ impl OutboundPayments {
14771490 } ,
14781491 PaymentSendFailure :: PathParameterError ( results) => {
14791492 log_error ! ( logger, "Failed to send to route due to parameter error in a single path. Your router is buggy" ) ;
1480- self . remove_session_privs ( payment_id, & route, onion_session_privs) ;
1493+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
14811494 Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut route_params, route. paths , results. into_iter ( ) , logger, pending_events) ;
14821495 self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
14831496 } ,
14841497 PaymentSendFailure :: ParameterError ( e) => {
14851498 log_error ! ( logger, "Failed to send to route due to parameter error: {:?}. Your router is buggy" , e) ;
1486- self . remove_session_privs ( payment_id, & route, onion_session_privs) ;
1499+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
14871500 self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
14881501 } ,
14891502 PaymentSendFailure :: DuplicatePayment => debug_assert ! ( false ) , // unreachable
@@ -1525,12 +1538,12 @@ impl OutboundPayments {
15251538
15261539 // If a payment fails after adding the pending payment but before any HTLCs are locked into
15271540 // channels, we need to clear the session_privs in order for abandoning the payment to succeed.
1528- fn remove_session_privs (
1529- & self , payment_id : PaymentId , route : & Route , onion_session_privs : Vec < [ u8 ; 32 ] >
1541+ fn remove_session_privs < ' a , I : Iterator < Item = ( & ' a Path , & ' a [ u8 ; 32 ] ) > > (
1542+ & self , payment_id : PaymentId , path_session_priv : I
15301543 ) {
15311544 if let Some ( payment) = self . pending_outbound_payments . lock ( ) . unwrap ( ) . get_mut ( & payment_id) {
1532- for ( path, session_priv_bytes) in route . paths . iter ( ) . zip ( onion_session_privs . into_iter ( ) ) {
1533- let removed = payment. remove ( & session_priv_bytes, Some ( path) ) ;
1545+ for ( path, session_priv_bytes) in path_session_priv {
1546+ let removed = payment. remove ( session_priv_bytes, Some ( path) ) ;
15341547 debug_assert ! ( removed, "This can't happen as the payment has an entry for this path added by callers" ) ;
15351548 }
15361549 } else {
@@ -1812,29 +1825,11 @@ impl OutboundPayments {
18121825 let mut results = Vec :: new ( ) ;
18131826 debug_assert_eq ! ( route. paths. len( ) , onion_session_privs. len( ) ) ;
18141827 for ( path, session_priv_bytes) in route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) {
1815- let mut path_res = send_payment_along_path ( SendAlongPathArgs {
1828+ let path_res = send_payment_along_path ( SendAlongPathArgs {
18161829 path : & path, payment_hash : & payment_hash, recipient_onion, total_value,
18171830 cur_height, payment_id, keysend_preimage : & keysend_preimage, invoice_request,
18181831 session_priv_bytes : * session_priv_bytes
18191832 } ) ;
1820- match path_res {
1821- Ok ( _) => { } ,
1822- Err ( APIError :: MonitorUpdateInProgress ) => {
1823- // While a MonitorUpdateInProgress is an Err(_), the payment is still
1824- // considered "in flight" and we shouldn't remove it from the
1825- // PendingOutboundPayment set.
1826- } ,
1827- Err ( _) => {
1828- let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1829- if let Some ( payment) = pending_outbounds. get_mut ( & payment_id) {
1830- let removed = payment. remove ( & session_priv_bytes, Some ( path) ) ;
1831- debug_assert ! ( removed, "This can't happen as the payment has an entry for this path added by callers" ) ;
1832- } else {
1833- debug_assert ! ( false , "This can't happen as the payment was added by callers" ) ;
1834- path_res = Err ( APIError :: APIMisuseError { err : "Internal error: payment disappeared during processing. Please report this bug!" . to_owned ( ) } ) ;
1835- }
1836- }
1837- }
18381833 results. push ( path_res) ;
18391834 }
18401835 let mut has_ok = false ;
0 commit comments