7
7
// You may not use this file except in accordance with one or both of these
8
8
// licenses.
9
9
10
+ use std:: cmp:: PartialEq ;
10
11
use bitcoin:: hashes:: hex:: FromHex ;
11
12
use bitcoin:: hex:: DisplayHex ;
12
13
use bitcoin:: secp256k1:: { PublicKey , Scalar , Secp256k1 , SecretKey , schnorr} ;
@@ -2497,7 +2498,14 @@ fn test_trampoline_constraint_enforcement() {
2497
2498
}
2498
2499
}
2499
2500
2500
- fn do_test_unblinded_trampoline_forward ( success : bool ) {
2501
+ #[ derive( PartialEq ) ]
2502
+ enum TrampolineForwardFailureScenario {
2503
+ NoRoute ,
2504
+ InvalidRecipientOnion ,
2505
+ InvalidInterTrampolineOnion ,
2506
+ }
2507
+
2508
+ fn do_test_unblinded_trampoline_forward ( failure_scenario : Option < TrampolineForwardFailureScenario > ) {
2501
2509
// Simulate a payment of A (0) -> B (1) -> C(Trampoline) (2) -> D(Trampoline(receive)) (3)
2502
2510
// trampoline hops C -> T0 (4) -> D
2503
2511
// make it fail at B, then at C's outer onion, then at C's inner onion
@@ -2511,7 +2519,7 @@ fn do_test_unblinded_trampoline_forward(success: bool) {
2511
2519
2512
2520
let ( _, _, chan_id_alice_bob, _) = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
2513
2521
let ( _, _, chan_id_bob_carol, _) = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) ;
2514
- if success {
2522
+ if failure_scenario != Some ( TrampolineForwardFailureScenario :: NoRoute ) {
2515
2523
let ( _, _, _, _) = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 1_000_000 , 0 ) ;
2516
2524
}
2517
2525
let ( _, _, _, _) = create_announced_chan_between_nodes_with_value ( & nodes, 4 , 3 , 1_000_000 , 0 ) ;
@@ -2641,59 +2649,195 @@ fn do_test_unblinded_trampoline_forward(success: bool) {
2641
2649
let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
2642
2650
assert_eq ! ( events. len( ) , 1 ) ;
2643
2651
let mut first_message_event = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
2644
- let mut update_message = match first_message_event {
2645
- MessageSendEvent :: UpdateHTLCs { ref mut updates, .. } => {
2646
- assert_eq ! ( updates. update_add_htlcs. len( ) , 1 ) ;
2647
- updates. update_add_htlcs . get_mut ( 0 )
2648
- } ,
2649
- _ => panic ! ( )
2650
- } ;
2651
- update_message. map ( |msg| {
2652
- msg. onion_routing_packet = replacement_onion. clone ( ) ;
2653
- } ) ;
2654
-
2655
- let success_route = [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 4 ] , & nodes[ 3 ] ] ;
2656
- let failure_route = [ & nodes[ 1 ] , & nodes[ 2 ] ] ;
2657
- let route: & [ & Node ] = if success { & success_route } else { & failure_route } ;
2658
- let args = PassAlongPathArgs :: new ( & nodes[ 0 ] , route, amt_msat, payment_hash, first_message_event) ;
2659
- let args = if success {
2660
- args. with_payment_secret ( payment_secret)
2661
- } else {
2662
- args. with_payment_preimage ( payment_preimage)
2663
- . without_claimable_event ( )
2664
- . expect_failure ( HTLCDestination :: FailedTrampolineForward { requested_next_node_id : dave_node_id, forward_scid : None } )
2665
- } ;
2666
- do_pass_along_path ( args) ;
2652
+ {
2653
+ let mut update_message_alice_bob = match first_message_event {
2654
+ MessageSendEvent :: UpdateHTLCs { ref mut updates, .. } => {
2655
+ assert_eq ! ( updates. update_add_htlcs. len( ) , 1 ) ;
2656
+ updates. update_add_htlcs . get_mut ( 0 )
2657
+ }
2658
+ _ => panic ! ( )
2659
+ } ;
2660
+ update_message_alice_bob. map ( |msg| {
2661
+ msg. onion_routing_packet = replacement_onion. clone ( ) ;
2662
+ } ) ;
2663
+ }
2667
2664
2668
- if success {
2669
- claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 4 ] , & nodes[ 3 ] ] , payment_preimage) ;
2670
- } else {
2671
- {
2672
- let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
2673
- nodes[ 1 ] . node . handle_update_fail_htlc (
2674
- nodes[ 2 ] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ]
2675
- ) ;
2676
- do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 2 ] , & unblinded_node_updates. commitment_signed , true , false ) ;
2665
+ match failure_scenario {
2666
+ None => {
2667
+ let route: & [ & Node ] = & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 4 ] , & nodes[ 3 ] ] ;
2668
+ let args = PassAlongPathArgs :: new ( & nodes[ 0 ] , route, amt_msat, payment_hash, first_message_event)
2669
+ . with_payment_secret ( payment_secret) ;
2670
+ do_pass_along_path ( args) ;
2671
+ claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 4 ] , & nodes[ 3 ] ] , payment_preimage) ;
2677
2672
}
2678
- {
2679
- let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2680
- nodes[ 0 ] . node . handle_update_fail_htlc (
2681
- nodes[ 1 ] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ]
2682
- ) ;
2683
- do_commitment_signed_dance ( & nodes[ 0 ] , & nodes[ 1 ] , & unblinded_node_updates. commitment_signed , false , false ) ;
2673
+ Some ( TrampolineForwardFailureScenario :: NoRoute ) => {
2674
+ let route = & [ & nodes[ 1 ] , & nodes[ 2 ] ] ;
2675
+ let args = PassAlongPathArgs :: new ( & nodes[ 0 ] , route, amt_msat, payment_hash, first_message_event)
2676
+ . with_payment_preimage ( payment_preimage)
2677
+ . without_claimable_event ( )
2678
+ . expect_failure ( HTLCDestination :: FailedTrampolineForward { requested_next_node_id : dave_node_id, forward_scid : None } ) ;
2679
+ do_pass_along_path ( args) ;
2680
+
2681
+ {
2682
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
2683
+ nodes[ 1 ] . node . handle_update_fail_htlc (
2684
+ nodes[ 2 ] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ] ,
2685
+ ) ;
2686
+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 2 ] , & unblinded_node_updates. commitment_signed , true , false ) ;
2687
+ }
2688
+ {
2689
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2690
+ nodes[ 0 ] . node . handle_update_fail_htlc (
2691
+ nodes[ 1 ] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ] ,
2692
+ ) ;
2693
+ do_commitment_signed_dance ( & nodes[ 0 ] , & nodes[ 1 ] , & unblinded_node_updates. commitment_signed , false , false ) ;
2694
+ }
2695
+ {
2696
+ let payment_failed_conditions = PaymentFailedConditions :: new ( )
2697
+ . expected_htlc_error_data ( 0x2000 | 25 , & [ 0 ; 0 ] ) ;
2698
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false , payment_failed_conditions) ;
2699
+ }
2684
2700
}
2685
- {
2686
- let payment_failed_conditions = PaymentFailedConditions :: new ( )
2687
- . expected_htlc_error_data ( 0x2000 | 25 , & [ 0 ; 0 ] ) ;
2688
- expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false , payment_failed_conditions) ;
2701
+ Some ( TrampolineForwardFailureScenario :: InvalidRecipientOnion ) => {
2702
+ let route_alice_t0: & [ & Node ] = & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 4 ] ] ;
2703
+ pass_along_path ( & nodes[ 0 ] , route_alice_t0, amt_msat, payment_hash. clone ( ) ,
2704
+ None , first_message_event. clone ( ) , false , Some ( payment_preimage) ) ;
2705
+
2706
+ check_added_monitors ! ( & nodes[ 4 ] , 1 ) ;
2707
+ let mut events = nodes[ 4 ] . node . get_and_clear_pending_msg_events ( ) ;
2708
+ assert_eq ! ( events. len( ) , 1 ) ;
2709
+
2710
+ let mut update_message_t0_dave = remove_first_msg_event_to_node ( & nodes[ 3 ] . node . get_our_node_id ( ) , & mut events) ;
2711
+ {
2712
+ let mut update_message = match update_message_t0_dave {
2713
+ MessageSendEvent :: UpdateHTLCs { ref mut updates, .. } => {
2714
+ assert_eq ! ( updates. update_add_htlcs. len( ) , 1 ) ;
2715
+ updates. update_add_htlcs . get_mut ( 0 )
2716
+ }
2717
+ _ => panic ! ( )
2718
+ } ;
2719
+ update_message. map ( |msg| {
2720
+ // corrupt the onion packet
2721
+ msg. onion_routing_packet . hmac = [ 1 ; 32 ] ;
2722
+ } ) ;
2723
+ }
2724
+
2725
+ let route_to_dave: & [ & Node ] = & [ & nodes[ 3 ] ] ;
2726
+ let args = PassAlongPathArgs :: new ( & nodes[ 4 ] , route_to_dave, amt_msat, payment_hash, update_message_t0_dave. clone ( ) ) . expect_failure ( HTLCDestination :: InvalidOnion ) ;
2727
+ do_pass_along_path ( args) ;
2728
+
2729
+ {
2730
+ let downstream_id = 3 ;
2731
+ let upstream_id = 4 ;
2732
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ downstream_id] , nodes[ upstream_id] . node. get_our_node_id( ) ) ;
2733
+ nodes[ upstream_id] . node . handle_update_fail_malformed_htlc (
2734
+ nodes[ downstream_id] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_malformed_htlcs [ 0 ]
2735
+ ) ;
2736
+ do_commitment_signed_dance ( & nodes[ upstream_id] , & nodes[ downstream_id] , & unblinded_node_updates. commitment_signed , true , false ) ;
2737
+ }
2738
+ {
2739
+ let downstream_id = 4 ;
2740
+ let upstream_id = 2 ;
2741
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ downstream_id] , nodes[ upstream_id] . node. get_our_node_id( ) ) ;
2742
+ nodes[ upstream_id] . node . handle_update_fail_htlc (
2743
+ nodes[ downstream_id] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ]
2744
+ ) ;
2745
+ do_commitment_signed_dance ( & nodes[ upstream_id] , & nodes[ downstream_id] , & unblinded_node_updates. commitment_signed , true , false ) ;
2746
+ }
2747
+ {
2748
+ let downstream_id = 2 ;
2749
+ let upstream_id = 1 ;
2750
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ downstream_id] , nodes[ upstream_id] . node. get_our_node_id( ) ) ;
2751
+ nodes[ upstream_id] . node . handle_update_fail_htlc (
2752
+ nodes[ downstream_id] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ]
2753
+ ) ;
2754
+ do_commitment_signed_dance ( & nodes[ upstream_id] , & nodes[ downstream_id] , & unblinded_node_updates. commitment_signed , true , false ) ;
2755
+ }
2756
+ {
2757
+ let downstream_id = 1 ;
2758
+ let upstream_id = 0 ;
2759
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ downstream_id] , nodes[ upstream_id] . node. get_our_node_id( ) ) ;
2760
+ nodes[ upstream_id] . node . handle_update_fail_htlc (
2761
+ nodes[ downstream_id] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ]
2762
+ ) ;
2763
+ do_commitment_signed_dance ( & nodes[ upstream_id] , & nodes[ downstream_id] , & unblinded_node_updates. commitment_signed , false , false ) ;
2764
+ }
2765
+ {
2766
+ let payment_failed_conditions = PaymentFailedConditions :: new ( )
2767
+ . expected_htlc_error_data ( 0x2000 | 25 , & [ 0 ; 0 ] ) ;
2768
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false , payment_failed_conditions) ;
2769
+ }
2770
+ }
2771
+ Some ( TrampolineForwardFailureScenario :: InvalidInterTrampolineOnion ) => {
2772
+ let route_alice_carol: & [ & Node ] = & [ & nodes[ 1 ] , & nodes[ 2 ] ] ;
2773
+ pass_along_path ( & nodes[ 0 ] , route_alice_carol, amt_msat, payment_hash. clone ( ) ,
2774
+ None , first_message_event. clone ( ) , false , Some ( payment_preimage) ) ;
2775
+
2776
+ check_added_monitors ! ( & nodes[ 2 ] , 1 ) ;
2777
+ let mut events = nodes[ 2 ] . node . get_and_clear_pending_msg_events ( ) ;
2778
+ assert_eq ! ( events. len( ) , 1 ) ;
2779
+
2780
+ let mut update_message_carol_t0 = remove_first_msg_event_to_node ( & nodes[ 4 ] . node . get_our_node_id ( ) , & mut events) ;
2781
+ {
2782
+ let mut update_message = match update_message_carol_t0 {
2783
+ MessageSendEvent :: UpdateHTLCs { ref mut updates, .. } => {
2784
+ assert_eq ! ( updates. update_add_htlcs. len( ) , 1 ) ;
2785
+ updates. update_add_htlcs . get_mut ( 0 )
2786
+ }
2787
+ _ => panic ! ( )
2788
+ } ;
2789
+ update_message. map ( |msg| {
2790
+ // corrupt the onion packet
2791
+ msg. onion_routing_packet . hmac = [ 1 ; 32 ] ;
2792
+ } ) ;
2793
+ }
2794
+
2795
+ let route_carol_t0: & [ & Node ] = & [ & nodes[ 4 ] ] ;
2796
+ let args = PassAlongPathArgs :: new ( & nodes[ 2 ] , route_carol_t0, amt_msat, payment_hash, update_message_carol_t0. clone ( ) ) . expect_failure ( HTLCDestination :: InvalidOnion ) ;
2797
+ do_pass_along_path ( args) ;
2798
+
2799
+ {
2800
+ let downstream_id = 4 ;
2801
+ let upstream_id = 2 ;
2802
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ downstream_id] , nodes[ upstream_id] . node. get_our_node_id( ) ) ;
2803
+ nodes[ upstream_id] . node . handle_update_fail_malformed_htlc (
2804
+ nodes[ downstream_id] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_malformed_htlcs [ 0 ]
2805
+ ) ;
2806
+ do_commitment_signed_dance ( & nodes[ upstream_id] , & nodes[ downstream_id] , & unblinded_node_updates. commitment_signed , true , false ) ;
2807
+ }
2808
+ {
2809
+ let downstream_id = 2 ;
2810
+ let upstream_id = 1 ;
2811
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ downstream_id] , nodes[ upstream_id] . node. get_our_node_id( ) ) ;
2812
+ nodes[ upstream_id] . node . handle_update_fail_htlc (
2813
+ nodes[ downstream_id] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ]
2814
+ ) ;
2815
+ do_commitment_signed_dance ( & nodes[ upstream_id] , & nodes[ downstream_id] , & unblinded_node_updates. commitment_signed , true , false ) ;
2816
+ }
2817
+ {
2818
+ let downstream_id = 1 ;
2819
+ let upstream_id = 0 ;
2820
+ let unblinded_node_updates = get_htlc_update_msgs ! ( nodes[ downstream_id] , nodes[ upstream_id] . node. get_our_node_id( ) ) ;
2821
+ nodes[ upstream_id] . node . handle_update_fail_htlc (
2822
+ nodes[ downstream_id] . node . get_our_node_id ( ) , & unblinded_node_updates. update_fail_htlcs [ 0 ]
2823
+ ) ;
2824
+ do_commitment_signed_dance ( & nodes[ upstream_id] , & nodes[ downstream_id] , & unblinded_node_updates. commitment_signed , false , false ) ;
2825
+ }
2826
+ {
2827
+ let payment_failed_conditions = PaymentFailedConditions :: new ( )
2828
+ . expected_htlc_error_data ( 0x2000 | 25 , & [ 0 ; 0 ] ) ;
2829
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false , payment_failed_conditions) ;
2830
+ }
2689
2831
}
2690
2832
}
2691
2833
}
2692
2834
2693
2835
#[ test]
2694
2836
fn test_unblinded_trampoline_forward ( ) {
2695
- do_test_unblinded_trampoline_forward ( true ) ;
2696
- do_test_unblinded_trampoline_forward ( false ) ;
2837
+ do_test_unblinded_trampoline_forward ( None ) ;
2838
+ do_test_unblinded_trampoline_forward ( Some ( TrampolineForwardFailureScenario :: NoRoute ) ) ;
2839
+ do_test_unblinded_trampoline_forward ( Some ( TrampolineForwardFailureScenario :: InvalidInterTrampolineOnion ) ) ;
2840
+ do_test_unblinded_trampoline_forward ( Some ( TrampolineForwardFailureScenario :: InvalidRecipientOnion ) ) ;
2697
2841
}
2698
2842
2699
2843
#[ test]
0 commit comments