@@ -1467,10 +1467,22 @@ impl OutboundPayments {
1467
1467
{
1468
1468
match err {
1469
1469
PaymentSendFailure :: AllFailedResendSafe ( errs) => {
1470
+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
1470
1471
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) ;
1471
1472
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) ;
1472
1473
} ,
1473
1474
PaymentSendFailure :: PartialFailure { failed_paths_retry : Some ( mut retry) , results, .. } => {
1475
+ let filtered = results. iter ( ) . zip ( route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) )
1476
+ . filter_map ( |( path_res, ( path, session_priv) ) | {
1477
+ match path_res {
1478
+ // While a MonitorUpdateInProgress is an Err(_), the payment is still
1479
+ // considered "in flight" and we shouldn't remove it from the
1480
+ // PendingOutboundPayment set.
1481
+ Ok ( _) | Err ( APIError :: MonitorUpdateInProgress ) => None ,
1482
+ _ => Some ( ( path, session_priv) )
1483
+ }
1484
+ } ) ;
1485
+ self . remove_session_privs ( payment_id, filtered) ;
1474
1486
Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut retry, route. paths , results. into_iter ( ) , logger, pending_events) ;
1475
1487
// Some paths were sent, even if we failed to send the full MPP value our recipient may
1476
1488
// misbehave and claim the funds, at which point we have to consider the payment sent, so
@@ -1484,13 +1496,13 @@ impl OutboundPayments {
1484
1496
} ,
1485
1497
PaymentSendFailure :: PathParameterError ( results) => {
1486
1498
log_error ! ( logger, "Failed to send to route due to parameter error in a single path. Your router is buggy" ) ;
1487
- 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 ( ) ) ) ;
1488
1500
Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut route_params, route. paths , results. into_iter ( ) , logger, pending_events) ;
1489
1501
self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
1490
1502
} ,
1491
1503
PaymentSendFailure :: ParameterError ( e) => {
1492
1504
log_error ! ( logger, "Failed to send to route due to parameter error: {:?}. Your router is buggy" , e) ;
1493
- self . remove_session_privs ( payment_id, & route, onion_session_privs) ;
1505
+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
1494
1506
self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
1495
1507
} ,
1496
1508
PaymentSendFailure :: DuplicatePayment => debug_assert ! ( false ) , // unreachable
@@ -1532,12 +1544,12 @@ impl OutboundPayments {
1532
1544
1533
1545
// If a payment fails after adding the pending payment but before any HTLCs are locked into
1534
1546
// channels, we need to clear the session_privs in order for abandoning the payment to succeed.
1535
- fn remove_session_privs (
1536
- & self , payment_id : PaymentId , route : & Route , onion_session_privs : Vec < [ u8 ; 32 ] >
1547
+ fn remove_session_privs < ' a , I : Iterator < Item = ( & ' a Path , & ' a [ u8 ; 32 ] ) > > (
1548
+ & self , payment_id : PaymentId , path_session_priv : I
1537
1549
) {
1538
1550
if let Some ( payment) = self . pending_outbound_payments . lock ( ) . unwrap ( ) . get_mut ( & payment_id) {
1539
- for ( path, session_priv_bytes) in route . paths . iter ( ) . zip ( onion_session_privs . into_iter ( ) ) {
1540
- let removed = payment. remove ( & session_priv_bytes, Some ( path) ) ;
1551
+ for ( path, session_priv_bytes) in path_session_priv {
1552
+ let removed = payment. remove ( session_priv_bytes, Some ( path) ) ;
1541
1553
debug_assert ! ( removed, "This can't happen as the payment has an entry for this path added by callers" ) ;
1542
1554
}
1543
1555
} else {
@@ -1819,29 +1831,11 @@ impl OutboundPayments {
1819
1831
let mut results = Vec :: new ( ) ;
1820
1832
debug_assert_eq ! ( route. paths. len( ) , onion_session_privs. len( ) ) ;
1821
1833
for ( path, session_priv_bytes) in route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) {
1822
- let mut path_res = send_payment_along_path ( SendAlongPathArgs {
1834
+ let path_res = send_payment_along_path ( SendAlongPathArgs {
1823
1835
path : & path, payment_hash : & payment_hash, recipient_onion, total_value,
1824
1836
cur_height, payment_id, keysend_preimage : & keysend_preimage, invoice_request,
1825
1837
session_priv_bytes : * session_priv_bytes
1826
1838
} ) ;
1827
- match path_res {
1828
- Ok ( _) => { } ,
1829
- Err ( APIError :: MonitorUpdateInProgress ) => {
1830
- // While a MonitorUpdateInProgress is an Err(_), the payment is still
1831
- // considered "in flight" and we shouldn't remove it from the
1832
- // PendingOutboundPayment set.
1833
- } ,
1834
- Err ( _) => {
1835
- let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1836
- if let Some ( payment) = pending_outbounds. get_mut ( & payment_id) {
1837
- let removed = payment. remove ( & session_priv_bytes, Some ( path) ) ;
1838
- debug_assert ! ( removed, "This can't happen as the payment has an entry for this path added by callers" ) ;
1839
- } else {
1840
- debug_assert ! ( false , "This can't happen as the payment was added by callers" ) ;
1841
- path_res = Err ( APIError :: APIMisuseError { err : "Internal error: payment disappeared during processing. Please report this bug!" . to_owned ( ) } ) ;
1842
- }
1843
- }
1844
- }
1845
1839
results. push ( path_res) ;
1846
1840
}
1847
1841
let mut has_ok = false ;
0 commit comments