@@ -782,13 +782,13 @@ impl OutboundPayments {
782
782
debug_assert_eq ! ( paths. len( ) , path_results. len( ) ) ;
783
783
for ( path, path_res) in paths. into_iter ( ) . zip ( path_results) {
784
784
if let Err ( e) = path_res {
785
- let failed_scid = if let APIError :: InvalidRoute { .. } = e {
786
- None
787
- } else {
785
+ if let APIError :: MonitorUpdateInProgress = e { continue }
786
+ let mut failed_scid = None ;
787
+ if let APIError :: ChannelUnavailable { .. } = e {
788
788
let scid = path[ 0 ] . short_channel_id ;
789
+ failed_scid = Some ( scid) ;
789
790
route_params. payment_params . previously_failed_channels . push ( scid) ;
790
- Some ( scid)
791
- } ;
791
+ }
792
792
events. push ( events:: Event :: PaymentPathFailed {
793
793
payment_id : Some ( payment_id) ,
794
794
payment_hash,
@@ -1353,12 +1353,14 @@ mod tests {
1353
1353
1354
1354
use crate :: ln:: PaymentHash ;
1355
1355
use crate :: ln:: channelmanager:: PaymentId ;
1356
+ use crate :: ln:: features:: { ChannelFeatures , NodeFeatures } ;
1356
1357
use crate :: ln:: msgs:: { ErrorAction , LightningError } ;
1357
1358
use crate :: ln:: outbound_payment:: { OutboundPayments , Retry , RetryableSendFailure } ;
1358
1359
use crate :: routing:: gossip:: NetworkGraph ;
1359
- use crate :: routing:: router:: { InFlightHtlcs , PaymentParameters , Route , RouteParameters } ;
1360
+ use crate :: routing:: router:: { InFlightHtlcs , PaymentParameters , Route , RouteHop , RouteParameters } ;
1360
1361
use crate :: sync:: { Arc , Mutex } ;
1361
- use crate :: util:: events:: Event ;
1362
+ use crate :: util:: errors:: APIError ;
1363
+ use crate :: util:: events:: { Event , PathFailure } ;
1362
1364
use crate :: util:: test_utils;
1363
1365
1364
1366
#[ test]
@@ -1455,4 +1457,92 @@ mod tests {
1455
1457
} else { panic ! ( "Unexpected error" ) ; }
1456
1458
}
1457
1459
}
1460
+
1461
+ #[ test]
1462
+ fn initial_send_payment_path_failed_evs ( ) {
1463
+ let outbound_payments = OutboundPayments :: new ( ) ;
1464
+ let logger = test_utils:: TestLogger :: new ( ) ;
1465
+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
1466
+ let network_graph = Arc :: new ( NetworkGraph :: new ( genesis_hash, & logger) ) ;
1467
+ let scorer = Mutex :: new ( test_utils:: TestScorer :: new ( ) ) ;
1468
+ let router = test_utils:: TestRouter :: new ( network_graph, & scorer) ;
1469
+ let secp_ctx = Secp256k1 :: new ( ) ;
1470
+ let keys_manager = test_utils:: TestKeysInterface :: new ( & [ 0 ; 32 ] , Network :: Testnet ) ;
1471
+
1472
+ let sender_pk = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
1473
+ let receiver_pk = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 43 ; 32 ] ) . unwrap ( ) ) ;
1474
+ let payment_params = PaymentParameters :: from_node_id ( sender_pk, 0 ) ;
1475
+ let route_params = RouteParameters {
1476
+ payment_params : payment_params. clone ( ) ,
1477
+ final_value_msat : 0 ,
1478
+ final_cltv_expiry_delta : 0 ,
1479
+ } ;
1480
+ let failed_scid = 42 ;
1481
+ let route = Route {
1482
+ paths : vec ! [ vec![ RouteHop {
1483
+ pubkey: receiver_pk,
1484
+ node_features: NodeFeatures :: empty( ) ,
1485
+ short_channel_id: failed_scid,
1486
+ channel_features: ChannelFeatures :: empty( ) ,
1487
+ fee_msat: 0 ,
1488
+ cltv_expiry_delta: 0 ,
1489
+ } ] ] ,
1490
+ payment_params : Some ( payment_params) ,
1491
+ } ;
1492
+ router. expect_find_route ( route_params. clone ( ) , Ok ( route. clone ( ) ) ) ;
1493
+ let mut route_params_w_failed_scid = route_params. clone ( ) ;
1494
+ route_params_w_failed_scid. payment_params . previously_failed_channels . push ( failed_scid) ;
1495
+ router. expect_find_route ( route_params_w_failed_scid, Ok ( route. clone ( ) ) ) ;
1496
+ router. expect_find_route ( route_params. clone ( ) , Ok ( route. clone ( ) ) ) ;
1497
+ router. expect_find_route ( route_params. clone ( ) , Ok ( route. clone ( ) ) ) ;
1498
+
1499
+ // Ensure that a ChannelUnavailable error will result in blaming an scid in the
1500
+ // PaymentPathFailed event.
1501
+ let pending_events = Mutex :: new ( Vec :: new ( ) ) ;
1502
+ outbound_payments. send_payment (
1503
+ PaymentHash ( [ 0 ; 32 ] ) , & None , PaymentId ( [ 0 ; 32 ] ) , Retry :: Attempts ( 0 ) , route_params. clone ( ) ,
1504
+ & & router, vec ! [ ] , || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger,
1505
+ & pending_events,
1506
+ |_, _, _, _, _, _, _, _, _| Err ( APIError :: ChannelUnavailable { err : "test" . to_owned ( ) } ) )
1507
+ . unwrap ( ) ;
1508
+ let mut events = pending_events. lock ( ) . unwrap ( ) ;
1509
+ assert_eq ! ( events. len( ) , 2 ) ;
1510
+ if let Event :: PaymentPathFailed {
1511
+ short_channel_id,
1512
+ failure : PathFailure :: InitialSend { err : APIError :: ChannelUnavailable { .. } } , .. } = events[ 0 ]
1513
+ {
1514
+ assert_eq ! ( short_channel_id, Some ( failed_scid) ) ;
1515
+ } else { panic ! ( "Unexpected event" ) ; }
1516
+ if let Event :: PaymentFailed { .. } = events[ 1 ] { } else { panic ! ( "Unexpected event" ) ; }
1517
+ events. clear ( ) ;
1518
+ core:: mem:: drop ( events) ;
1519
+
1520
+ // Ensure that a MonitorUpdateInProgress "error" will not result in a PaymentPathFailed event.
1521
+ outbound_payments. send_payment (
1522
+ PaymentHash ( [ 0 ; 32 ] ) , & None , PaymentId ( [ 0 ; 32 ] ) , Retry :: Attempts ( 0 ) , route_params. clone ( ) ,
1523
+ & & router, vec ! [ ] , || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger,
1524
+ & pending_events, |_, _, _, _, _, _, _, _, _| Err ( APIError :: MonitorUpdateInProgress ) )
1525
+ . unwrap ( ) ;
1526
+ {
1527
+ let events = pending_events. lock ( ) . unwrap ( ) ;
1528
+ assert_eq ! ( events. len( ) , 0 ) ;
1529
+ }
1530
+
1531
+ // Ensure that any other error will result in a PaymentPathFailed event but no blamed scid.
1532
+ outbound_payments. send_payment (
1533
+ PaymentHash ( [ 0 ; 32 ] ) , & None , PaymentId ( [ 1 ; 32 ] ) , Retry :: Attempts ( 0 ) , route_params. clone ( ) ,
1534
+ & & router, vec ! [ ] , || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger,
1535
+ & pending_events,
1536
+ |_, _, _, _, _, _, _, _, _| Err ( APIError :: APIMisuseError { err : "test" . to_owned ( ) } ) )
1537
+ . unwrap ( ) ;
1538
+ let events = pending_events. lock ( ) . unwrap ( ) ;
1539
+ assert_eq ! ( events. len( ) , 2 ) ;
1540
+ if let Event :: PaymentPathFailed {
1541
+ short_channel_id,
1542
+ failure : PathFailure :: InitialSend { err : APIError :: APIMisuseError { .. } } , .. } = events[ 0 ]
1543
+ {
1544
+ assert_eq ! ( short_channel_id, None ) ;
1545
+ } else { panic ! ( "Unexpected event" ) ; }
1546
+ if let Event :: PaymentFailed { .. } = events[ 1 ] { } else { panic ! ( "Unexpected event" ) ; }
1547
+ }
1458
1548
}
0 commit comments