@@ -689,3 +689,115 @@ fn fail_blinded_payment() {
689
689
_ => panic ! ( "Unexpected event" ) ,
690
690
}
691
691
}
692
+
693
+ #[ test]
694
+ fn outbound_checks_failure ( ) {
695
+ do_outbound_checks_failure ( true ) ;
696
+ do_outbound_checks_failure ( false ) ;
697
+ }
698
+
699
+ fn do_outbound_checks_failure ( intro_node_fails : bool ) {
700
+ // Ensure we'll fail backwards properly if a forwarding check fails on initial update_add
701
+ // receipt.
702
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
703
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
704
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , None ] ) ;
705
+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
706
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
707
+ let chan_upd_1_2 = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) . 0 . contents ;
708
+ let chan_upd_2_3 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) . 0 . contents ;
709
+
710
+ let amt_msat = 5000 ;
711
+ let ( _, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 3 ] , Some ( amt_msat) , None ) ;
712
+ let intermediate_nodes = vec ! [ ( nodes[ 1 ] . node. get_our_node_id( ) , ForwardTlvs {
713
+ short_channel_id: chan_upd_1_2. short_channel_id,
714
+ payment_relay: PaymentRelay {
715
+ cltv_expiry_delta: chan_upd_1_2. cltv_expiry_delta,
716
+ fee_proportional_millionths: chan_upd_1_2. fee_proportional_millionths,
717
+ fee_base_msat: chan_upd_1_2. fee_base_msat,
718
+ } ,
719
+ payment_constraints: PaymentConstraints {
720
+ max_cltv_expiry: u32 :: max_value( ) ,
721
+ htlc_minimum_msat: chan_upd_1_2. htlc_minimum_msat,
722
+ } ,
723
+ features: BlindedHopFeatures :: empty( ) ,
724
+ } ) , ( nodes[ 2 ] . node. get_our_node_id( ) , ForwardTlvs {
725
+ short_channel_id: chan_upd_2_3. short_channel_id,
726
+ payment_relay: PaymentRelay {
727
+ cltv_expiry_delta: chan_upd_2_3. cltv_expiry_delta,
728
+ fee_proportional_millionths: chan_upd_2_3. fee_proportional_millionths,
729
+ fee_base_msat: chan_upd_2_3. fee_base_msat,
730
+ } ,
731
+ payment_constraints: PaymentConstraints {
732
+ max_cltv_expiry: u32 :: max_value( ) ,
733
+ htlc_minimum_msat: chan_upd_2_3. htlc_minimum_msat,
734
+ } ,
735
+ features: BlindedHopFeatures :: empty( ) ,
736
+ } ) ] ;
737
+ let payee_tlvs = ReceiveTlvs {
738
+ payment_secret,
739
+ payment_constraints : PaymentConstraints {
740
+ max_cltv_expiry : u32:: max_value ( ) ,
741
+ htlc_minimum_msat : chan_upd_2_3. htlc_minimum_msat ,
742
+ } ,
743
+ } ;
744
+ let mut secp_ctx = Secp256k1 :: new ( ) ;
745
+ let blinded_path = BlindedPath :: new_for_payment (
746
+ & intermediate_nodes[ ..] , nodes[ 3 ] . node . get_our_node_id ( ) , payee_tlvs,
747
+ chan_upd_2_3. htlc_maximum_msat , & chanmon_cfgs[ 3 ] . keys_manager , & secp_ctx
748
+ ) . unwrap ( ) ;
749
+
750
+ let route_params = RouteParameters {
751
+ payment_params : PaymentParameters :: blinded ( vec ! [ blinded_path] ) ,
752
+ final_value_msat : amt_msat
753
+ } ;
754
+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) ,
755
+ PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
756
+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
757
+
758
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
759
+ assert_eq ! ( events. len( ) , 1 ) ;
760
+ let ev = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
761
+ let payment_event = SendEvent :: from_event ( ev) ;
762
+
763
+ if intro_node_fails {
764
+ // The intro node will see that the next-hop peer is disconnected and fail the HTLC backwards.
765
+ nodes[ 1 ] . node . peer_disconnected ( & nodes[ 2 ] . node . get_our_node_id ( ) ) ;
766
+ }
767
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
768
+ check_added_monitors ! ( nodes[ 1 ] , 0 ) ;
769
+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 0 ] , & payment_event. commitment_msg , true , true ) ;
770
+
771
+ if intro_node_fails {
772
+ let mut updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
773
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & updates. update_fail_htlcs [ 0 ] ) ;
774
+ do_commitment_signed_dance ( & nodes[ 0 ] , & nodes[ 1 ] , & updates. commitment_signed , false , false ) ;
775
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false ,
776
+ PaymentFailedConditions :: new ( ) . expected_htlc_error_data ( INVALID_ONION_BLINDING , & [ 0 ; 32 ] ) ) ;
777
+ return
778
+ }
779
+
780
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
781
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
782
+ let mut events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
783
+ assert_eq ! ( events. len( ) , 1 ) ;
784
+ let ev = remove_first_msg_event_to_node ( & nodes[ 2 ] . node . get_our_node_id ( ) , & mut events) ;
785
+ let payment_event = SendEvent :: from_event ( ev) ;
786
+
787
+ nodes[ 2 ] . node . peer_disconnected ( & nodes[ 3 ] . node . get_our_node_id ( ) ) ;
788
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
789
+ check_added_monitors ! ( nodes[ 2 ] , 0 ) ;
790
+ do_commitment_signed_dance ( & nodes[ 2 ] , & nodes[ 1 ] , & payment_event. commitment_msg , true , true ) ;
791
+
792
+ let mut updates = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
793
+ assert_eq ! ( updates. update_fail_malformed_htlcs[ 0 ] . failure_code, INVALID_ONION_BLINDING ) ;
794
+ assert_eq ! ( updates. update_fail_malformed_htlcs[ 0 ] . sha256_of_onion, [ 0 ; 32 ] ) ;
795
+ nodes[ 1 ] . node . handle_update_fail_malformed_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & updates. update_fail_malformed_htlcs [ 0 ] ) ;
796
+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 2 ] , & updates. commitment_signed , true , false ) ;
797
+
798
+ let mut updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
799
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & updates. update_fail_htlcs [ 0 ] ) ;
800
+ do_commitment_signed_dance ( & nodes[ 0 ] , & nodes[ 1 ] , & updates. commitment_signed , false , false ) ;
801
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false ,
802
+ PaymentFailedConditions :: new ( ) . expected_htlc_error_data ( INVALID_ONION_BLINDING , & [ 0 ; 32 ] ) ) ;
803
+ }
0 commit comments