@@ -447,17 +447,20 @@ where
447
447
mod tests {
448
448
use super :: * ;
449
449
use crate :: { DEFAULT_EXPIRY_TIME , InvoiceBuilder , Currency } ;
450
+ use utils:: create_invoice_from_channelmanager;
450
451
use bitcoin_hashes:: sha256:: Hash as Sha256 ;
451
452
use lightning:: ln:: PaymentPreimage ;
452
- use lightning:: ln:: features:: { ChannelFeatures , NodeFeatures } ;
453
+ use lightning:: ln:: features:: { ChannelFeatures , NodeFeatures , InitFeatures } ;
454
+ use lightning:: ln:: functional_test_utils:: * ;
453
455
use lightning:: ln:: msgs:: { ErrorAction , LightningError } ;
454
456
use lightning:: routing:: network_graph:: NodeId ;
455
457
use lightning:: routing:: router:: { Payee , Route , RouteHop } ;
456
458
use lightning:: util:: test_utils:: TestLogger ;
457
459
use lightning:: util:: errors:: APIError ;
458
- use lightning:: util:: events:: Event ;
460
+ use lightning:: util:: events:: { Event , MessageSendEventsProvider } ;
459
461
use secp256k1:: { SecretKey , PublicKey , Secp256k1 } ;
460
462
use std:: cell:: RefCell ;
463
+ use std:: collections:: VecDeque ;
461
464
use std:: time:: { SystemTime , Duration } ;
462
465
463
466
fn invoice ( payment_preimage : PaymentPreimage ) -> Invoice {
@@ -1048,13 +1051,13 @@ mod tests {
1048
1051
}
1049
1052
1050
1053
struct TestScorer {
1051
- expectations : std :: collections :: VecDeque < u64 > ,
1054
+ expectations : VecDeque < u64 > ,
1052
1055
}
1053
1056
1054
1057
impl TestScorer {
1055
1058
fn new ( ) -> Self {
1056
1059
Self {
1057
- expectations : std :: collections :: VecDeque :: new ( ) ,
1060
+ expectations : VecDeque :: new ( ) ,
1058
1061
}
1059
1062
}
1060
1063
@@ -1089,15 +1092,15 @@ mod tests {
1089
1092
}
1090
1093
1091
1094
struct TestPayer {
1092
- expectations : core:: cell:: RefCell < std :: collections :: VecDeque < u64 > > ,
1095
+ expectations : core:: cell:: RefCell < VecDeque < u64 > > ,
1093
1096
attempts : core:: cell:: RefCell < usize > ,
1094
1097
failing_on_attempt : Option < usize > ,
1095
1098
}
1096
1099
1097
1100
impl TestPayer {
1098
1101
fn new ( ) -> Self {
1099
1102
Self {
1100
- expectations : core:: cell:: RefCell :: new ( std :: collections :: VecDeque :: new ( ) ) ,
1103
+ expectations : core:: cell:: RefCell :: new ( VecDeque :: new ( ) ) ,
1101
1104
attempts : core:: cell:: RefCell :: new ( 0 ) ,
1102
1105
failing_on_attempt : None ,
1103
1106
}
@@ -1182,4 +1185,78 @@ mod tests {
1182
1185
}
1183
1186
}
1184
1187
}
1188
+
1189
+ // *** Full Featured Functional Tests with a Real ChannelManager ***
1190
+ struct ManualRouter ( RefCell < VecDeque < Result < Route , LightningError > > > ) ;
1191
+
1192
+ impl < S : routing:: Score > Router < S > for ManualRouter {
1193
+ fn find_route ( & self , _payer : & PublicKey , _params : & RouteParameters , _first_hops : Option < & [ & ChannelDetails ] > , _scorer : & S )
1194
+ -> Result < Route , LightningError > {
1195
+ self . 0 . borrow_mut ( ) . pop_front ( ) . unwrap ( )
1196
+ }
1197
+ }
1198
+ impl ManualRouter {
1199
+ fn expect_find_route ( & self , result : Result < Route , LightningError > ) {
1200
+ self . 0 . borrow_mut ( ) . push_back ( result) ;
1201
+ }
1202
+ }
1203
+ impl Drop for ManualRouter {
1204
+ fn drop ( & mut self ) {
1205
+ if std:: thread:: panicking ( ) {
1206
+ return ;
1207
+ }
1208
+ assert ! ( self . 0 . borrow_mut( ) . is_empty( ) ) ;
1209
+ }
1210
+ }
1211
+
1212
+ #[ test]
1213
+ fn retry_multi_path_single_failed_payment ( ) {
1214
+ // Tests that we can/will retry after a single path of an MPP payment failed immediately
1215
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
1216
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
1217
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None , None ] ) ;
1218
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1219
+
1220
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
1221
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
1222
+ let chans = nodes[ 0 ] . node . list_usable_channels ( ) ;
1223
+ let mut route = Route {
1224
+ paths : vec ! [
1225
+ vec![ RouteHop {
1226
+ pubkey: nodes[ 1 ] . node. get_our_node_id( ) ,
1227
+ node_features: NodeFeatures :: known( ) ,
1228
+ short_channel_id: chans[ 0 ] . short_channel_id. unwrap( ) ,
1229
+ channel_features: ChannelFeatures :: known( ) ,
1230
+ fee_msat: 10_000 ,
1231
+ cltv_expiry_delta: 100 ,
1232
+ } ] ,
1233
+ vec![ RouteHop {
1234
+ pubkey: nodes[ 1 ] . node. get_our_node_id( ) ,
1235
+ node_features: NodeFeatures :: known( ) ,
1236
+ short_channel_id: chans[ 1 ] . short_channel_id. unwrap( ) ,
1237
+ channel_features: ChannelFeatures :: known( ) ,
1238
+ fee_msat: 100_000_001 , // Our default max-HTLC-value is 10% of the channel value, which this is one more than
1239
+ cltv_expiry_delta: 100 ,
1240
+ } ] ,
1241
+ ] ,
1242
+ payee : Some ( Payee :: new ( nodes[ 1 ] . node . get_our_node_id ( ) ) ) ,
1243
+ } ;
1244
+ let router = ManualRouter ( RefCell :: new ( VecDeque :: new ( ) ) ) ;
1245
+ router. expect_find_route ( Ok ( route. clone ( ) ) ) ;
1246
+ // On retry, split the payment across both channels.
1247
+ route. paths [ 0 ] [ 0 ] . fee_msat = 50_000_001 ;
1248
+ route. paths [ 1 ] [ 0 ] . fee_msat = 50_000_000 ;
1249
+ router. expect_find_route ( Ok ( route. clone ( ) ) ) ;
1250
+
1251
+ let event_handler = |_: & _ | { panic ! ( ) ; } ;
1252
+ let scorer = RefCell :: new ( TestScorer :: new ( ) ) ;
1253
+ let invoice_payer = InvoicePayer :: new ( nodes[ 0 ] . node , router, & scorer, nodes[ 0 ] . logger , event_handler, RetryAttempts ( 1 ) ) ;
1254
+
1255
+ assert ! ( invoice_payer. pay_invoice( & create_invoice_from_channelmanager(
1256
+ & nodes[ 1 ] . node, nodes[ 1 ] . keys_manager, Currency :: Bitcoin , Some ( 100_010_000 ) , "Invoice" . to_string( ) ) . unwrap( ) )
1257
+ . is_ok( ) ) ;
1258
+ let htlc_msgs = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
1259
+ assert_eq ! ( htlc_msgs. len( ) , 2 ) ;
1260
+ check_added_monitors ! ( nodes[ 0 ] , 2 ) ;
1261
+ }
1185
1262
}
0 commit comments