@@ -562,3 +562,115 @@ fn fail_blinded_payment() {
562
562
_ => panic ! ( "Unexpected event" ) ,
563
563
}
564
564
}
565
+
566
+ #[ test]
567
+ fn outbound_checks_failure ( ) {
568
+ do_outbound_checks_failure ( true ) ;
569
+ do_outbound_checks_failure ( false ) ;
570
+ }
571
+
572
+ fn do_outbound_checks_failure ( intro_node_fails : bool ) {
573
+ // Ensure we'll fail backwards properly if a forwarding check fails on initial update_add
574
+ // receipt.
575
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
576
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
577
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , None ] ) ;
578
+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
579
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
580
+ let chan_upd_1_2 = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) . 0 . contents ;
581
+ let chan_upd_2_3 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) . 0 . contents ;
582
+
583
+ let amt_msat = 5000 ;
584
+ let ( _, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 3 ] , Some ( amt_msat) , None ) ;
585
+ let intermediate_nodes = vec ! [ ( nodes[ 1 ] . node. get_our_node_id( ) , ForwardTlvs {
586
+ short_channel_id: chan_upd_1_2. short_channel_id,
587
+ payment_relay: PaymentRelay {
588
+ cltv_expiry_delta: chan_upd_1_2. cltv_expiry_delta,
589
+ fee_proportional_millionths: chan_upd_1_2. fee_proportional_millionths,
590
+ fee_base_msat: chan_upd_1_2. fee_base_msat,
591
+ } ,
592
+ payment_constraints: PaymentConstraints {
593
+ max_cltv_expiry: u32 :: max_value( ) ,
594
+ htlc_minimum_msat: chan_upd_1_2. htlc_minimum_msat,
595
+ } ,
596
+ features: BlindedHopFeatures :: empty( ) ,
597
+ } ) , ( nodes[ 2 ] . node. get_our_node_id( ) , ForwardTlvs {
598
+ short_channel_id: chan_upd_2_3. short_channel_id,
599
+ payment_relay: PaymentRelay {
600
+ cltv_expiry_delta: chan_upd_2_3. cltv_expiry_delta,
601
+ fee_proportional_millionths: chan_upd_2_3. fee_proportional_millionths,
602
+ fee_base_msat: chan_upd_2_3. fee_base_msat,
603
+ } ,
604
+ payment_constraints: PaymentConstraints {
605
+ max_cltv_expiry: u32 :: max_value( ) ,
606
+ htlc_minimum_msat: chan_upd_2_3. htlc_minimum_msat,
607
+ } ,
608
+ features: BlindedHopFeatures :: empty( ) ,
609
+ } ) ] ;
610
+ let payee_tlvs = ReceiveTlvs {
611
+ payment_secret,
612
+ payment_constraints : PaymentConstraints {
613
+ max_cltv_expiry : u32:: max_value ( ) ,
614
+ htlc_minimum_msat : chan_upd_2_3. htlc_minimum_msat ,
615
+ } ,
616
+ } ;
617
+ let mut secp_ctx = Secp256k1 :: new ( ) ;
618
+ let blinded_path = BlindedPath :: new_for_payment (
619
+ & intermediate_nodes[ ..] , nodes[ 3 ] . node . get_our_node_id ( ) , payee_tlvs,
620
+ chan_upd_2_3. htlc_maximum_msat , & chanmon_cfgs[ 3 ] . keys_manager , & secp_ctx
621
+ ) . unwrap ( ) ;
622
+
623
+ let route_params = RouteParameters {
624
+ payment_params : PaymentParameters :: blinded ( vec ! [ blinded_path] ) ,
625
+ final_value_msat : amt_msat
626
+ } ;
627
+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) ,
628
+ PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
629
+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
630
+
631
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
632
+ assert_eq ! ( events. len( ) , 1 ) ;
633
+ let ev = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
634
+ let payment_event = SendEvent :: from_event ( ev) ;
635
+
636
+ if intro_node_fails {
637
+ // The intro node will see that the next-hop peer is disconnected and fail the HTLC backwards.
638
+ nodes[ 1 ] . node . peer_disconnected ( & nodes[ 2 ] . node . get_our_node_id ( ) ) ;
639
+ }
640
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
641
+ check_added_monitors ! ( nodes[ 1 ] , 0 ) ;
642
+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 0 ] , & payment_event. commitment_msg , true , true ) ;
643
+
644
+ if intro_node_fails {
645
+ let mut updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
646
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & updates. update_fail_htlcs [ 0 ] ) ;
647
+ do_commitment_signed_dance ( & nodes[ 0 ] , & nodes[ 1 ] , & updates. commitment_signed , false , false ) ;
648
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false ,
649
+ PaymentFailedConditions :: new ( ) . expected_htlc_error_data ( INVALID_ONION_BLINDING , & [ 0 ; 32 ] ) ) ;
650
+ return
651
+ }
652
+
653
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
654
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
655
+ let mut events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
656
+ assert_eq ! ( events. len( ) , 1 ) ;
657
+ let ev = remove_first_msg_event_to_node ( & nodes[ 2 ] . node . get_our_node_id ( ) , & mut events) ;
658
+ let payment_event = SendEvent :: from_event ( ev) ;
659
+
660
+ nodes[ 2 ] . node . peer_disconnected ( & nodes[ 3 ] . node . get_our_node_id ( ) ) ;
661
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
662
+ check_added_monitors ! ( nodes[ 2 ] , 0 ) ;
663
+ do_commitment_signed_dance ( & nodes[ 2 ] , & nodes[ 1 ] , & payment_event. commitment_msg , true , true ) ;
664
+
665
+ let mut updates = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
666
+ assert_eq ! ( updates. update_fail_malformed_htlcs[ 0 ] . failure_code, INVALID_ONION_BLINDING ) ;
667
+ assert_eq ! ( updates. update_fail_malformed_htlcs[ 0 ] . sha256_of_onion, [ 0 ; 32 ] ) ;
668
+ nodes[ 1 ] . node . handle_update_fail_malformed_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & updates. update_fail_malformed_htlcs [ 0 ] ) ;
669
+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 2 ] , & updates. commitment_signed , true , false ) ;
670
+
671
+ let mut updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
672
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & updates. update_fail_htlcs [ 0 ] ) ;
673
+ do_commitment_signed_dance ( & nodes[ 0 ] , & nodes[ 1 ] , & updates. commitment_signed , false , false ) ;
674
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false ,
675
+ PaymentFailedConditions :: new ( ) . expected_htlc_error_data ( INVALID_ONION_BLINDING , & [ 0 ; 32 ] ) ) ;
676
+ }
0 commit comments