@@ -1000,9 +1000,9 @@ impl OutboundPayments {
1000
1000
) ;
1001
1001
if let Err ( e) = result {
1002
1002
self . handle_pay_route_err (
1003
- e, payment_id, payment_hash, route, route_params, router, first_hops,
1004
- & inflight_htlcs, entropy_source, node_signer, best_block_height, logger,
1005
- pending_events , & send_payment_along_path
1003
+ e, payment_id, payment_hash, route, route_params, onion_session_privs , router, first_hops,
1004
+ & inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events ,
1005
+ & send_payment_along_path
1006
1006
) ;
1007
1007
}
1008
1008
Ok ( ( ) )
@@ -1281,7 +1281,11 @@ impl OutboundPayments {
1281
1281
log_info ! ( logger, "Sending payment with id {} and hash {} returned {:?}" ,
1282
1282
payment_id, payment_hash, res) ;
1283
1283
if let Err ( e) = res {
1284
- self . handle_pay_route_err ( e, payment_id, payment_hash, route, route_params, router, first_hops, & inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, & send_payment_along_path) ;
1284
+ self . handle_pay_route_err (
1285
+ e, payment_id, payment_hash, route, route_params, onion_session_privs, router, first_hops,
1286
+ & inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events,
1287
+ & send_payment_along_path
1288
+ ) ;
1285
1289
}
1286
1290
Ok ( ( ) )
1287
1291
}
@@ -1437,15 +1441,21 @@ impl OutboundPayments {
1437
1441
best_block_height, & send_payment_along_path) ;
1438
1442
log_info ! ( logger, "Result retrying payment id {}: {:?}" , & payment_id, res) ;
1439
1443
if let Err ( e) = res {
1440
- self . handle_pay_route_err ( e, payment_id, payment_hash, route, route_params, router, first_hops, inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, send_payment_along_path) ;
1444
+ self . handle_pay_route_err (
1445
+ e, payment_id, payment_hash, route, route_params, onion_session_privs, router, first_hops,
1446
+ inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events,
1447
+ send_payment_along_path
1448
+ ) ;
1441
1449
}
1442
1450
}
1443
1451
1444
1452
fn handle_pay_route_err < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1445
1453
& self , err : PaymentSendFailure , payment_id : PaymentId , payment_hash : PaymentHash , route : Route ,
1446
- mut route_params : RouteParameters , router : & R , first_hops : Vec < ChannelDetails > ,
1447
- inflight_htlcs : & IH , entropy_source : & ES , node_signer : & NS , best_block_height : u32 , logger : & L ,
1448
- pending_events : & Mutex < VecDeque < ( events:: Event , Option < EventCompletionAction > ) > > , send_payment_along_path : & SP ,
1454
+ mut route_params : RouteParameters , onion_session_privs : Vec < [ u8 ; 32 ] > , router : & R ,
1455
+ first_hops : Vec < ChannelDetails > , inflight_htlcs : & IH , entropy_source : & ES , node_signer : & NS ,
1456
+ best_block_height : u32 , logger : & L ,
1457
+ pending_events : & Mutex < VecDeque < ( events:: Event , Option < EventCompletionAction > ) > > ,
1458
+ send_payment_along_path : & SP ,
1449
1459
)
1450
1460
where
1451
1461
R :: Target : Router ,
@@ -1474,11 +1484,13 @@ impl OutboundPayments {
1474
1484
} ,
1475
1485
PaymentSendFailure :: PathParameterError ( results) => {
1476
1486
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) ;
1477
1488
Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut route_params, route. paths , results. into_iter ( ) , logger, pending_events) ;
1478
1489
self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
1479
1490
} ,
1480
1491
PaymentSendFailure :: ParameterError ( e) => {
1481
1492
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) ;
1482
1494
self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
1483
1495
} ,
1484
1496
PaymentSendFailure :: DuplicatePayment => debug_assert ! ( false ) , // unreachable
@@ -1518,6 +1530,21 @@ impl OutboundPayments {
1518
1530
}
1519
1531
}
1520
1532
1533
+ // If a payment fails after adding the pending payment but before any HTLCs are locked into
1534
+ // 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 ] >
1537
+ ) {
1538
+ 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) ) ;
1541
+ debug_assert ! ( removed, "This can't happen as the payment has an entry for this path added by callers" ) ;
1542
+ }
1543
+ } else {
1544
+ debug_assert ! ( false , "This can't happen as the payment was added by callers" ) ;
1545
+ }
1546
+ }
1547
+
1521
1548
pub ( super ) fn send_probe < ES : Deref , NS : Deref , F > (
1522
1549
& self , path : Path , probing_cookie_secret : [ u8 ; 32 ] , entropy_source : & ES , node_signer : & NS ,
1523
1550
best_block_height : u32 , send_payment_along_path : F
@@ -1791,7 +1818,7 @@ impl OutboundPayments {
1791
1818
let cur_height = best_block_height + 1 ;
1792
1819
let mut results = Vec :: new ( ) ;
1793
1820
debug_assert_eq ! ( route. paths. len( ) , onion_session_privs. len( ) ) ;
1794
- for ( path, session_priv_bytes) in route. paths . iter ( ) . zip ( onion_session_privs. into_iter ( ) ) {
1821
+ for ( path, session_priv_bytes) in route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) {
1795
1822
let mut path_res = send_payment_along_path ( SendAlongPathArgs {
1796
1823
path : & path, payment_hash : & payment_hash, recipient_onion, total_value,
1797
1824
cur_height, payment_id, keysend_preimage : & keysend_preimage, invoice_request,
@@ -1887,9 +1914,15 @@ impl OutboundPayments {
1887
1914
// If we failed to send any paths, remove the new PaymentId from the `pending_outbound_payments`
1888
1915
// map as the payment is free to be resent.
1889
1916
fn remove_outbound_if_all_failed ( & self , payment_id : PaymentId , err : & PaymentSendFailure ) {
1890
- if let & PaymentSendFailure :: AllFailedResendSafe ( _) = err {
1891
- let removed = self . pending_outbound_payments . lock ( ) . unwrap ( ) . remove ( & payment_id) . is_some ( ) ;
1892
- debug_assert ! ( removed, "We should always have a pending payment to remove here" ) ;
1917
+ match err {
1918
+ PaymentSendFailure :: AllFailedResendSafe ( _)
1919
+ | PaymentSendFailure :: ParameterError ( _)
1920
+ | PaymentSendFailure :: PathParameterError ( _) =>
1921
+ {
1922
+ let removed = self . pending_outbound_payments . lock ( ) . unwrap ( ) . remove ( & payment_id) . is_some ( ) ;
1923
+ debug_assert ! ( removed, "We should always have a pending payment to remove here" ) ;
1924
+ } ,
1925
+ PaymentSendFailure :: DuplicatePayment | PaymentSendFailure :: PartialFailure { .. } => { }
1893
1926
}
1894
1927
}
1895
1928
0 commit comments