@@ -811,7 +811,7 @@ impl OutboundPayments {
811
811
{
812
812
let onion_session_privs = self . add_new_pending_payment ( payment_hash, recipient_onion. clone ( ) , payment_id, None , route, None , None , entropy_source, best_block_height) ?;
813
813
self . pay_route_internal ( route, payment_hash, & recipient_onion, None , None , payment_id, None ,
814
- onion_session_privs, node_signer, best_block_height, & send_payment_along_path)
814
+ & onion_session_privs, node_signer, best_block_height, & send_payment_along_path)
815
815
. map_err ( |e| { self . remove_outbound_if_all_failed ( payment_id, & e) ; e } )
816
816
}
817
817
@@ -991,7 +991,7 @@ impl OutboundPayments {
991
991
992
992
let result = self . pay_route_internal (
993
993
& route, payment_hash, & recipient_onion, keysend_preimage, invoice_request, payment_id,
994
- Some ( route_params. final_value_msat ) , onion_session_privs, node_signer, best_block_height,
994
+ Some ( route_params. final_value_msat ) , & onion_session_privs, node_signer, best_block_height,
995
995
& send_payment_along_path
996
996
) ;
997
997
log_info ! (
@@ -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 ( ( ) )
@@ -1276,12 +1276,16 @@ impl OutboundPayments {
1276
1276
} ) ?;
1277
1277
1278
1278
let res = self . pay_route_internal ( & route, payment_hash, & recipient_onion,
1279
- keysend_preimage, None , payment_id, None , onion_session_privs, node_signer,
1279
+ keysend_preimage, None , payment_id, None , & onion_session_privs, node_signer,
1280
1280
best_block_height, & send_payment_along_path) ;
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
}
@@ -1433,19 +1437,25 @@ impl OutboundPayments {
1433
1437
}
1434
1438
} ;
1435
1439
let res = self . pay_route_internal ( & route, payment_hash, & recipient_onion, keysend_preimage,
1436
- invoice_request. as_ref ( ) , payment_id, Some ( total_msat) , onion_session_privs, node_signer,
1440
+ invoice_request. as_ref ( ) , payment_id, Some ( total_msat) , & onion_session_privs, node_signer,
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 ,
@@ -1457,10 +1467,24 @@ impl OutboundPayments {
1457
1467
{
1458
1468
match err {
1459
1469
PaymentSendFailure :: AllFailedResendSafe ( errs) => {
1470
+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
1460
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) ;
1461
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) ;
1462
1473
} ,
1463
1474
PaymentSendFailure :: PartialFailure { failed_paths_retry : Some ( mut retry) , results, .. } => {
1475
+ debug_assert_eq ! ( results. len( ) , route. paths. len( ) ) ;
1476
+ debug_assert_eq ! ( results. len( ) , onion_session_privs. len( ) ) ;
1477
+ let failed_paths = results. iter ( ) . zip ( route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) )
1478
+ . filter_map ( |( path_res, ( path, session_priv) ) | {
1479
+ match path_res {
1480
+ // While a MonitorUpdateInProgress is an Err(_), the payment is still
1481
+ // considered "in flight" and we shouldn't remove it from the
1482
+ // PendingOutboundPayment set.
1483
+ Ok ( _) | Err ( APIError :: MonitorUpdateInProgress ) => None ,
1484
+ _ => Some ( ( path, session_priv) )
1485
+ }
1486
+ } ) ;
1487
+ self . remove_session_privs ( payment_id, failed_paths) ;
1464
1488
Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut retry, route. paths , results. into_iter ( ) , logger, pending_events) ;
1465
1489
// Some paths were sent, even if we failed to send the full MPP value our recipient may
1466
1490
// misbehave and claim the funds, at which point we have to consider the payment sent, so
@@ -1474,11 +1498,13 @@ impl OutboundPayments {
1474
1498
} ,
1475
1499
PaymentSendFailure :: PathParameterError ( results) => {
1476
1500
log_error ! ( logger, "Failed to send to route due to parameter error in a single path. Your router is buggy" ) ;
1501
+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
1477
1502
Self :: push_path_failed_evs_and_scids ( payment_id, payment_hash, & mut route_params, route. paths , results. into_iter ( ) , logger, pending_events) ;
1478
1503
self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
1479
1504
} ,
1480
1505
PaymentSendFailure :: ParameterError ( e) => {
1481
1506
log_error ! ( logger, "Failed to send to route due to parameter error: {:?}. Your router is buggy" , e) ;
1507
+ self . remove_session_privs ( payment_id, route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) ) ;
1482
1508
self . abandon_payment ( payment_id, PaymentFailureReason :: UnexpectedError , pending_events) ;
1483
1509
} ,
1484
1510
PaymentSendFailure :: DuplicatePayment => debug_assert ! ( false ) , // unreachable
@@ -1518,6 +1544,21 @@ impl OutboundPayments {
1518
1544
}
1519
1545
}
1520
1546
1547
+ // If a payment fails after adding the pending payment but before any HTLCs are locked into
1548
+ // channels, we need to clear the session_privs in order for abandoning the payment to succeed.
1549
+ fn remove_session_privs < ' a , I : Iterator < Item = ( & ' a Path , & ' a [ u8 ; 32 ] ) > > (
1550
+ & self , payment_id : PaymentId , path_session_priv : I
1551
+ ) {
1552
+ if let Some ( payment) = self . pending_outbound_payments . lock ( ) . unwrap ( ) . get_mut ( & payment_id) {
1553
+ for ( path, session_priv_bytes) in path_session_priv {
1554
+ let removed = payment. remove ( session_priv_bytes, Some ( path) ) ;
1555
+ debug_assert ! ( removed, "This can't happen as the payment has an entry for this path added by callers" ) ;
1556
+ }
1557
+ } else {
1558
+ debug_assert ! ( false , "This can't happen as the payment was added by callers" ) ;
1559
+ }
1560
+ }
1561
+
1521
1562
pub ( super ) fn send_probe < ES : Deref , NS : Deref , F > (
1522
1563
& self , path : Path , probing_cookie_secret : [ u8 ; 32 ] , entropy_source : & ES , node_signer : & NS ,
1523
1564
best_block_height : u32 , send_payment_along_path : F
@@ -1549,7 +1590,7 @@ impl OutboundPayments {
1549
1590
1550
1591
let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
1551
1592
match self . pay_route_internal ( & route, payment_hash, & recipient_onion_fields,
1552
- None , None , payment_id, None , onion_session_privs, node_signer, best_block_height,
1593
+ None , None , payment_id, None , & onion_session_privs, node_signer, best_block_height,
1553
1594
& send_payment_along_path
1554
1595
) {
1555
1596
Ok ( ( ) ) => Ok ( ( payment_hash, payment_id) ) ,
@@ -1740,7 +1781,7 @@ impl OutboundPayments {
1740
1781
fn pay_route_internal < NS : Deref , F > (
1741
1782
& self , route : & Route , payment_hash : PaymentHash , recipient_onion : & RecipientOnionFields ,
1742
1783
keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
1743
- payment_id : PaymentId , recv_value_msat : Option < u64 > , onion_session_privs : Vec < [ u8 ; 32 ] > ,
1784
+ payment_id : PaymentId , recv_value_msat : Option < u64 > , onion_session_privs : & Vec < [ u8 ; 32 ] > ,
1744
1785
node_signer : & NS , best_block_height : u32 , send_payment_along_path : & F
1745
1786
) -> Result < ( ) , PaymentSendFailure >
1746
1787
where
@@ -1791,30 +1832,12 @@ impl OutboundPayments {
1791
1832
let cur_height = best_block_height + 1 ;
1792
1833
let mut results = Vec :: new ( ) ;
1793
1834
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 ( ) ) {
1795
- let mut path_res = send_payment_along_path ( SendAlongPathArgs {
1835
+ for ( path, session_priv_bytes) in route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) {
1836
+ let path_res = send_payment_along_path ( SendAlongPathArgs {
1796
1837
path : & path, payment_hash : & payment_hash, recipient_onion, total_value,
1797
1838
cur_height, payment_id, keysend_preimage : & keysend_preimage, invoice_request,
1798
- session_priv_bytes
1839
+ session_priv_bytes : * session_priv_bytes
1799
1840
} ) ;
1800
- match path_res {
1801
- Ok ( _) => { } ,
1802
- Err ( APIError :: MonitorUpdateInProgress ) => {
1803
- // While a MonitorUpdateInProgress is an Err(_), the payment is still
1804
- // considered "in flight" and we shouldn't remove it from the
1805
- // PendingOutboundPayment set.
1806
- } ,
1807
- Err ( _) => {
1808
- let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1809
- if let Some ( payment) = pending_outbounds. get_mut ( & payment_id) {
1810
- let removed = payment. remove ( & session_priv_bytes, Some ( path) ) ;
1811
- debug_assert ! ( removed, "This can't happen as the payment has an entry for this path added by callers" ) ;
1812
- } else {
1813
- debug_assert ! ( false , "This can't happen as the payment was added by callers" ) ;
1814
- path_res = Err ( APIError :: APIMisuseError { err : "Internal error: payment disappeared during processing. Please report this bug!" . to_owned ( ) } ) ;
1815
- }
1816
- }
1817
- }
1818
1841
results. push ( path_res) ;
1819
1842
}
1820
1843
let mut has_ok = false ;
@@ -1879,17 +1902,23 @@ impl OutboundPayments {
1879
1902
F : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
1880
1903
{
1881
1904
self . pay_route_internal ( route, payment_hash, & recipient_onion,
1882
- keysend_preimage, None , payment_id, recv_value_msat, onion_session_privs,
1905
+ keysend_preimage, None , payment_id, recv_value_msat, & onion_session_privs,
1883
1906
node_signer, best_block_height, & send_payment_along_path)
1884
1907
. map_err ( |e| { self . remove_outbound_if_all_failed ( payment_id, & e) ; e } )
1885
1908
}
1886
1909
1887
1910
// If we failed to send any paths, remove the new PaymentId from the `pending_outbound_payments`
1888
1911
// map as the payment is free to be resent.
1889
1912
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" ) ;
1913
+ match err {
1914
+ PaymentSendFailure :: AllFailedResendSafe ( _)
1915
+ | PaymentSendFailure :: ParameterError ( _)
1916
+ | PaymentSendFailure :: PathParameterError ( _) =>
1917
+ {
1918
+ let removed = self . pending_outbound_payments . lock ( ) . unwrap ( ) . remove ( & payment_id) . is_some ( ) ;
1919
+ debug_assert ! ( removed, "We should always have a pending payment to remove here" ) ;
1920
+ } ,
1921
+ PaymentSendFailure :: DuplicatePayment | PaymentSendFailure :: PartialFailure { .. } => { }
1893
1922
}
1894
1923
}
1895
1924
0 commit comments