@@ -17,13 +17,13 @@ use crate::sign::EntropySource;
17
17
use crate :: chain:: transaction:: OutPoint ;
18
18
use crate :: events:: { ClosureReason , Event , HTLCDestination , MessageSendEvent , MessageSendEventsProvider , PathFailure , PaymentFailureReason } ;
19
19
use crate :: ln:: channel:: EXPIRE_PREV_CONFIG_TICKS ;
20
- use crate :: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , ChannelManager , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS , RecentPaymentDetails , RecipientOnionFields } ;
20
+ use crate :: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , ChannelManager , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS , RecentPaymentDetails , RecipientOnionFields , HTLCForwardInfo , PendingHTLCRouting , PendingAddHTLCInfo } ;
21
21
use crate :: ln:: features:: InvoiceFeatures ;
22
- use crate :: ln:: msgs;
22
+ use crate :: ln:: { msgs, PaymentSecret , PaymentPreimage } ;
23
23
use crate :: ln:: msgs:: ChannelMessageHandler ;
24
24
use crate :: ln:: outbound_payment:: Retry ;
25
25
use crate :: routing:: gossip:: { EffectiveCapacity , RoutingFees } ;
26
- use crate :: routing:: router:: { get_route, Path , PaymentParameters , Route , Router , RouteHint , RouteHintHop , RouteHop , RouteParameters } ;
26
+ use crate :: routing:: router:: { get_route, Path , PaymentParameters , Route , Router , RouteHint , RouteHintHop , RouteHop , RouteParameters , find_route } ;
27
27
use crate :: routing:: scoring:: ChannelUsage ;
28
28
use crate :: util:: test_utils;
29
29
use crate :: util:: errors:: APIError ;
@@ -236,6 +236,177 @@ fn mpp_receive_timeout() {
236
236
do_mpp_receive_timeout ( false ) ;
237
237
}
238
238
239
+ #[ test]
240
+ fn test_mpp_keysend ( ) {
241
+ let mut mpp_keysend_config = test_default_channel_config ( ) ;
242
+ mpp_keysend_config. accept_mpp_keysend = true ;
243
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
244
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
245
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , Some ( mpp_keysend_config) ] ) ;
246
+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
247
+
248
+ create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
249
+ create_announced_chan_between_nodes ( & nodes, 0 , 2 ) ;
250
+ create_announced_chan_between_nodes ( & nodes, 1 , 3 ) ;
251
+ create_announced_chan_between_nodes ( & nodes, 2 , 3 ) ;
252
+ let network_graph = nodes[ 0 ] . network_graph . clone ( ) ;
253
+
254
+ let payer_pubkey = nodes[ 0 ] . node . get_our_node_id ( ) ;
255
+ let payee_pubkey = nodes[ 3 ] . node . get_our_node_id ( ) ;
256
+ let recv_value = 15_000_000 ;
257
+ let route_params = RouteParameters {
258
+ payment_params : PaymentParameters :: for_keysend ( payee_pubkey, 40 , true ) ,
259
+ final_value_msat : recv_value,
260
+ } ;
261
+ let scorer = test_utils:: TestScorer :: new ( ) ;
262
+ let random_seed_bytes = chanmon_cfgs[ 0 ] . keys_manager . get_secure_random_bytes ( ) ;
263
+ let route = find_route ( & payer_pubkey, & route_params, & network_graph, None , nodes[ 0 ] . logger ,
264
+ & scorer, & ( ) , & random_seed_bytes) . unwrap ( ) ;
265
+
266
+ let payment_preimage = PaymentPreimage ( [ 42 ; 32 ] ) ;
267
+ let payment_secret = PaymentSecret ( payment_preimage. 0 ) ;
268
+ let payment_hash = nodes[ 0 ] . node . send_spontaneous_payment ( & route, Some ( payment_preimage) ,
269
+ RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_preimage. 0 ) ) . unwrap ( ) ;
270
+ check_added_monitors ! ( nodes[ 0 ] , 2 ) ;
271
+
272
+ let expected_route: & [ & [ & Node ] ] = & [ & [ & nodes[ 1 ] , & nodes[ 3 ] ] , & [ & nodes[ 2 ] , & nodes[ 3 ] ] ] ;
273
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
274
+ assert_eq ! ( events. len( ) , 2 ) ;
275
+
276
+ let ev = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
277
+ pass_along_path ( & nodes[ 0 ] , expected_route[ 0 ] , recv_value, payment_hash. clone ( ) ,
278
+ Some ( payment_secret) , ev. clone ( ) , false , Some ( payment_preimage) ) ;
279
+
280
+ let ev = remove_first_msg_event_to_node ( & nodes[ 2 ] . node . get_our_node_id ( ) , & mut events) ;
281
+ pass_along_path ( & nodes[ 0 ] , expected_route[ 1 ] , recv_value, payment_hash. clone ( ) ,
282
+ Some ( payment_secret) , ev. clone ( ) , true , Some ( payment_preimage) ) ;
283
+ claim_payment_along_route ( & nodes[ 0 ] , expected_route, false , payment_preimage) ;
284
+ }
285
+
286
+ #[ test]
287
+ fn test_reject_mpp_keysend_htlc ( ) {
288
+ // This test enforces that we reject MPP keysend HTLCs if our config states we don't support
289
+ // MPP keysend. When receiving a payment, if we don't support MPP keysend we'll reject the
290
+ // payment if it's keysend and has a payment secret, never reaching our payment validation
291
+ // logic. To check that we enforce rejecting MPP keysends in our payment logic, here we send
292
+ // keysend payments without payment secrets, then modify them by adding payment secrets in the
293
+ // final node in between receiving the HTLCs and actually processing them.
294
+ let mut reject_mpp_keysend_cfg = test_default_channel_config ( ) ;
295
+ reject_mpp_keysend_cfg. accept_mpp_keysend = false ;
296
+
297
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
298
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
299
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , Some ( reject_mpp_keysend_cfg) ] ) ;
300
+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
301
+ let chan_1_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) . 0 . contents . short_channel_id ;
302
+ let chan_2_id = create_announced_chan_between_nodes ( & nodes, 0 , 2 ) . 0 . contents . short_channel_id ;
303
+ let chan_3_id = create_announced_chan_between_nodes ( & nodes, 1 , 3 ) . 0 . contents . short_channel_id ;
304
+ let ( update_a, _, chan_4_channel_id, _) = create_announced_chan_between_nodes ( & nodes, 2 , 3 ) ;
305
+ let chan_4_id = update_a. contents . short_channel_id ;
306
+ let amount = 40_000 ;
307
+ let ( mut route, payment_hash, payment_preimage, _) = get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 3 ] , amount) ;
308
+
309
+ // Pay along nodes[1]
310
+ route. paths [ 0 ] . hops [ 0 ] . pubkey = nodes[ 1 ] . node . get_our_node_id ( ) ;
311
+ route. paths [ 0 ] . hops [ 0 ] . short_channel_id = chan_1_id;
312
+ route. paths [ 0 ] . hops [ 1 ] . short_channel_id = chan_3_id;
313
+
314
+ let payment_id_0 = PaymentId ( nodes[ 0 ] . keys_manager . backing . get_secure_random_bytes ( ) ) ;
315
+ nodes[ 0 ] . node . send_spontaneous_payment ( & route, Some ( payment_preimage) , RecipientOnionFields :: spontaneous_empty ( ) , payment_id_0) . unwrap ( ) ;
316
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
317
+
318
+ let update_0 = get_htlc_update_msgs ! ( nodes[ 0 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
319
+ let update_add_0 = update_0. update_add_htlcs [ 0 ] . clone ( ) ;
320
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & update_add_0) ;
321
+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , & update_0. commitment_signed, false , true ) ;
322
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
323
+
324
+ check_added_monitors ! ( & nodes[ 1 ] , 1 ) ;
325
+ let update_1 = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 3 ] . node. get_our_node_id( ) ) ;
326
+ let update_add_1 = update_1. update_add_htlcs [ 0 ] . clone ( ) ;
327
+ nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & update_add_1) ;
328
+ commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 1 ] , update_1. commitment_signed, false , true ) ;
329
+
330
+ assert ! ( nodes[ 3 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
331
+ for ( _, pending_forwards) in nodes[ 3 ] . node . forward_htlcs . lock ( ) . unwrap ( ) . iter_mut ( ) {
332
+ for f in pending_forwards. iter_mut ( ) {
333
+ match f {
334
+ & mut HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo { ref mut forward_info, .. } ) => {
335
+ match forward_info. routing {
336
+ PendingHTLCRouting :: ReceiveKeysend { ref mut payment_data, .. } => {
337
+ * payment_data = Some ( msgs:: FinalOnionHopData {
338
+ payment_secret : PaymentSecret ( [ 42 ; 32 ] ) ,
339
+ total_msat : amount * 2 ,
340
+ } ) ;
341
+ } ,
342
+ _ => panic ! ( "Expected PendingHTLCRouting::ReceiveKeysend" ) ,
343
+ }
344
+ } ,
345
+ _ => { } ,
346
+ }
347
+ }
348
+ }
349
+ expect_pending_htlcs_forwardable ! ( nodes[ 3 ] ) ;
350
+
351
+ // Pay along nodes[2]
352
+ route. paths [ 0 ] . hops [ 0 ] . pubkey = nodes[ 2 ] . node . get_our_node_id ( ) ;
353
+ route. paths [ 0 ] . hops [ 0 ] . short_channel_id = chan_2_id;
354
+ route. paths [ 0 ] . hops [ 1 ] . short_channel_id = chan_4_id;
355
+
356
+ let payment_id_1 = PaymentId ( nodes[ 0 ] . keys_manager . backing . get_secure_random_bytes ( ) ) ;
357
+ nodes[ 0 ] . node . send_spontaneous_payment ( & route, Some ( payment_preimage) , RecipientOnionFields :: spontaneous_empty ( ) , payment_id_1) . unwrap ( ) ;
358
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
359
+
360
+ let update_2 = get_htlc_update_msgs ! ( nodes[ 0 ] , nodes[ 2 ] . node. get_our_node_id( ) ) ;
361
+ let update_add_2 = update_2. update_add_htlcs [ 0 ] . clone ( ) ;
362
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & update_add_2) ;
363
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 0 ] , & update_2. commitment_signed, false , true ) ;
364
+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
365
+
366
+ check_added_monitors ! ( & nodes[ 2 ] , 1 ) ;
367
+ let update_3 = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 3 ] . node. get_our_node_id( ) ) ;
368
+ let update_add_3 = update_3. update_add_htlcs [ 0 ] . clone ( ) ;
369
+ nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & update_add_3) ;
370
+ commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 2 ] , update_3. commitment_signed, false , true ) ;
371
+
372
+ assert ! ( nodes[ 3 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
373
+ for ( _, pending_forwards) in nodes[ 3 ] . node . forward_htlcs . lock ( ) . unwrap ( ) . iter_mut ( ) {
374
+ for f in pending_forwards. iter_mut ( ) {
375
+ match f {
376
+ & mut HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo { ref mut forward_info, .. } ) => {
377
+ match forward_info. routing {
378
+ PendingHTLCRouting :: ReceiveKeysend { ref mut payment_data, .. } => {
379
+ * payment_data = Some ( msgs:: FinalOnionHopData {
380
+ payment_secret : PaymentSecret ( [ 42 ; 32 ] ) ,
381
+ total_msat : amount * 2 ,
382
+ } ) ;
383
+ } ,
384
+ _ => panic ! ( "Expected PendingHTLCRouting::ReceiveKeysend" ) ,
385
+ }
386
+ } ,
387
+ _ => { } ,
388
+ }
389
+ }
390
+ }
391
+ expect_pending_htlcs_forwardable ! ( nodes[ 3 ] ) ;
392
+ check_added_monitors ! ( nodes[ 3 ] , 1 ) ;
393
+
394
+ // Fail back along nodes[2]
395
+ let update_fail_0 = get_htlc_update_msgs ! ( & nodes[ 3 ] , & nodes[ 2 ] . node. get_our_node_id( ) ) ;
396
+ nodes[ 2 ] . node . handle_update_fail_htlc ( & nodes[ 3 ] . node . get_our_node_id ( ) , & update_fail_0. update_fail_htlcs [ 0 ] ) ;
397
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 3 ] , update_fail_0. commitment_signed, false ) ;
398
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 2 ] , vec![ HTLCDestination :: NextHopChannel { node_id: Some ( nodes[ 3 ] . node. get_our_node_id( ) ) , channel_id: chan_4_channel_id } ] ) ;
399
+ check_added_monitors ! ( nodes[ 2 ] , 1 ) ;
400
+
401
+ let update_fail_1 = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
402
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & update_fail_1. update_fail_htlcs [ 0 ] ) ;
403
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 2 ] , update_fail_1. commitment_signed, false ) ;
404
+
405
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, true , PaymentFailedConditions :: new ( ) ) ;
406
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 3 ] , vec![ HTLCDestination :: FailedPayment { payment_hash } ] ) ;
407
+ }
408
+
409
+
239
410
#[ test]
240
411
fn no_pending_leak_on_initial_send_failure ( ) {
241
412
// In an earlier version of our payment tracking, we'd have a retry entry even when the initial
0 commit comments