@@ -426,12 +426,102 @@ fn do_mpp_receive_timeout(send_partial_mpp: bool) {
426426 }
427427}
428428
429+ fn do_keysend_mpp_receive_timeout ( ) {
430+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
431+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
432+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , None ] ) ;
433+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
434+
435+ let node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
436+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
437+ let node_c_id = nodes[ 2 ] . node . get_our_node_id ( ) ;
438+ let node_d_id = nodes[ 3 ] . node . get_our_node_id ( ) ;
439+
440+ let ( chan_1_update, _, _, _) = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
441+ let ( chan_2_update, _, _, _) = create_announced_chan_between_nodes ( & nodes, 0 , 2 ) ;
442+ let ( chan_3_update, _, chan_3_id, _) = create_announced_chan_between_nodes ( & nodes, 1 , 3 ) ;
443+ let ( chan_4_update, _, _, _) = create_announced_chan_between_nodes ( & nodes, 2 , 3 ) ;
444+
445+ let payment_params = PaymentParameters :: for_keysend ( node_d_id, TEST_FINAL_CLTV , true ) ;
446+ let ( mut route, hash, payment_preimage, payment_secret) =
447+ get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 3 ] , payment_params, 100_000 ) ;
448+ let path = route. paths [ 0 ] . clone ( ) ;
449+ route. paths . push ( path) ;
450+ route. paths [ 0 ] . hops [ 0 ] . pubkey = node_b_id;
451+ route. paths [ 0 ] . hops [ 0 ] . short_channel_id = chan_1_update. contents . short_channel_id ;
452+ route. paths [ 0 ] . hops [ 1 ] . short_channel_id = chan_3_update. contents . short_channel_id ;
453+ route. paths [ 1 ] . hops [ 0 ] . pubkey = node_c_id;
454+ route. paths [ 1 ] . hops [ 0 ] . short_channel_id = chan_2_update. contents . short_channel_id ;
455+ route. paths [ 1 ] . hops [ 1 ] . short_channel_id = chan_4_update. contents . short_channel_id ;
456+ route. route_params . as_mut ( ) . unwrap ( ) . final_value_msat *= 2 ;
457+
458+ // Initiate the MPP keysend and only relay the first half so the payment remains incomplete.
459+ let onion = RecipientOnionFields :: secret_only ( payment_secret, 200_000 ) ;
460+ let route_params = route. route_params . clone ( ) . unwrap ( ) ;
461+ nodes[ 0 ] . router . expect_find_route ( route_params. clone ( ) , Ok ( route. clone ( ) ) ) ;
462+ nodes[ 0 ]
463+ . node
464+ . send_spontaneous_payment (
465+ Some ( payment_preimage) ,
466+ onion,
467+ PaymentId ( hash. 0 ) ,
468+ route_params,
469+ Retry :: Attempts ( 0 ) ,
470+ )
471+ . unwrap ( ) ;
472+ check_added_monitors ( & nodes[ 0 ] , 2 ) ;
473+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
474+ assert_eq ! ( events. len( ) , 2 ) ;
475+
476+ let node_1_msgs = remove_first_msg_event_to_node ( & node_b_id, & mut events) ;
477+ let path = & [ & nodes[ 1 ] , & nodes[ 3 ] ] ;
478+ pass_along_path ( & nodes[ 0 ] , path, 200_000 , hash, Some ( payment_secret) , node_1_msgs, false , None ) ;
479+
480+ for _ in 0 ..MPP_TIMEOUT_TICKS {
481+ nodes[ 3 ] . node . timer_tick_occurred ( ) ;
482+ }
483+
484+ // This should mirror invoice-backed MPP handling: the incomplete keysend MPP should time out
485+ // and fail backward instead of remaining claimable until CLTV expiry.
486+ let fail = HTLCHandlingFailureType :: Receive { payment_hash : hash } ;
487+ expect_and_process_pending_htlcs_and_htlc_handling_failed ( & nodes[ 3 ] , & [ fail] ) ;
488+
489+ let htlc_fail_updates = get_htlc_update_msgs ( & nodes[ 3 ] , & node_b_id) ;
490+ assert_eq ! ( htlc_fail_updates. update_fail_htlcs. len( ) , 1 ) ;
491+ nodes[ 1 ] . node . handle_update_fail_htlc ( node_d_id, & htlc_fail_updates. update_fail_htlcs [ 0 ] ) ;
492+ check_added_monitors ( & nodes[ 3 ] , 1 ) ;
493+
494+ let commitment = & htlc_fail_updates. commitment_signed ;
495+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 3 ] , commitment, false , false ) ;
496+
497+ let fail_type =
498+ HTLCHandlingFailureType :: Forward { node_id : Some ( node_d_id) , channel_id : chan_3_id } ;
499+ expect_and_process_pending_htlcs_and_htlc_handling_failed ( & nodes[ 1 ] , & [ fail_type] ) ;
500+
501+ let htlc_fail_updates = get_htlc_update_msgs ( & nodes[ 1 ] , & node_a_id) ;
502+ assert_eq ! ( htlc_fail_updates. update_fail_htlcs. len( ) , 1 ) ;
503+ nodes[ 0 ] . node . handle_update_fail_htlc ( node_b_id, & htlc_fail_updates. update_fail_htlcs [ 0 ] ) ;
504+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
505+ let commitment = & htlc_fail_updates. commitment_signed ;
506+ do_commitment_signed_dance ( & nodes[ 0 ] , & nodes[ 1 ] , commitment, false , false ) ;
507+
508+ let mut conditions = PaymentFailedConditions :: new ( )
509+ . mpp_parts_remain ( )
510+ . expected_htlc_error_data ( LocalHTLCFailureReason :: MPPTimeout , & [ ] [ ..] ) ;
511+ expect_payment_failed_conditions ( & nodes[ 0 ] , hash, false , conditions) ;
512+ }
513+
429514#[ test]
430515fn mpp_receive_timeout ( ) {
431516 do_mpp_receive_timeout ( true ) ;
432517 do_mpp_receive_timeout ( false ) ;
433518}
434519
520+ #[ test]
521+ fn keysend_mpp_receive_timeout ( ) {
522+ do_keysend_mpp_receive_timeout ( ) ;
523+ }
524+
435525#[ test]
436526fn test_keysend_payments ( ) {
437527 do_test_keysend_payments ( false ) ;
0 commit comments