@@ -3491,6 +3491,167 @@ fn test_retry_custom_tlvs() {
3491
3491
claim_payment_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 2 ] ] ] , false , payment_preimage) ;
3492
3492
}
3493
3493
3494
+ #[ test]
3495
+ fn test_custom_tlvs_consistency ( ) {
3496
+ let even_type_1 = 1 << 16 ;
3497
+ let odd_type_1 = ( 1 << 16 ) + 1 ;
3498
+ let even_type_2 = ( 1 << 16 ) + 2 ;
3499
+ let odd_type_2 = ( 1 << 16 ) + 3 ;
3500
+ let value_1 = || vec ! [ 1 , 2 , 3 , 4 ] ;
3501
+ let differing_value_1 = || vec ! [ 1 , 2 , 3 , 5 ] ;
3502
+ let value_2 = || vec ! [ 42u8 ; 16 ] ;
3503
+
3504
+ // Drop missing odd tlvs
3505
+ do_test_custom_tlvs_consistency (
3506
+ vec ! [ ( odd_type_1, value_1( ) ) , ( odd_type_2, value_2( ) ) ] ,
3507
+ vec ! [ ( odd_type_1, value_1( ) ) ] ,
3508
+ Some ( vec ! [ ( odd_type_1, value_1( ) ) ] ) ,
3509
+ ) ;
3510
+ // Drop non-matching odd tlvs
3511
+ do_test_custom_tlvs_consistency (
3512
+ vec ! [ ( odd_type_1, value_1( ) ) , ( odd_type_2, value_2( ) ) ] ,
3513
+ vec ! [ ( odd_type_1, differing_value_1( ) ) , ( odd_type_2, value_2( ) ) ] ,
3514
+ Some ( vec ! [ ( odd_type_2, value_2( ) ) ] ) ,
3515
+ ) ;
3516
+ // Fail missing even tlvs
3517
+ do_test_custom_tlvs_consistency (
3518
+ vec ! [ ( odd_type_1, value_1( ) ) , ( even_type_2, value_2( ) ) ] ,
3519
+ vec ! [ ( odd_type_1, value_1( ) ) ] ,
3520
+ None ,
3521
+ ) ;
3522
+ // Fail non-matching even tlvs
3523
+ do_test_custom_tlvs_consistency (
3524
+ vec ! [ ( even_type_1, value_1( ) ) , ( odd_type_2, value_2( ) ) ] ,
3525
+ vec ! [ ( even_type_1, differing_value_1( ) ) , ( odd_type_2, value_2( ) ) ] ,
3526
+ None ,
3527
+ ) ;
3528
+ }
3529
+
3530
+ fn do_test_custom_tlvs_consistency ( first_tlvs : Vec < ( u64 , Vec < u8 > ) > , second_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
3531
+ expected_receive_tlvs : Option < Vec < ( u64 , Vec < u8 > ) > > ) {
3532
+
3533
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
3534
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
3535
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , None ] ) ;
3536
+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
3537
+
3538
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 100_000 , 0 ) ;
3539
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 2 , 100_000 , 0 ) ;
3540
+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 3 , 100_000 , 0 ) ;
3541
+ let chan_2_3 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 100_000 , 0 ) ;
3542
+
3543
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 3 ] . node . get_our_node_id ( ) , TEST_FINAL_CLTV )
3544
+ . with_bolt11_features ( nodes[ 3 ] . node . invoice_features ( ) ) . unwrap ( ) ;
3545
+ let mut route = get_route ! ( nodes[ 0 ] , payment_params, 15_000_000 ) . unwrap ( ) ;
3546
+ assert_eq ! ( route. paths. len( ) , 2 ) ;
3547
+ route. paths . sort_by ( |path_a, _| {
3548
+ // Sort the path so that the path through nodes[1] comes first
3549
+ if path_a. hops [ 0 ] . pubkey == nodes[ 1 ] . node . get_our_node_id ( ) {
3550
+ core:: cmp:: Ordering :: Less } else { core:: cmp:: Ordering :: Greater }
3551
+ } ) ;
3552
+
3553
+ let ( our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash ! ( & nodes[ 3 ] ) ;
3554
+ let payment_id = PaymentId ( [ 42 ; 32 ] ) ;
3555
+ let amt_msat = 15_000_000 ;
3556
+
3557
+ // Send first part
3558
+ let onion_fields = RecipientOnionFields {
3559
+ payment_secret : Some ( our_payment_secret) ,
3560
+ payment_metadata : None ,
3561
+ custom_tlvs : first_tlvs
3562
+ } ;
3563
+ let session_privs = nodes[ 0 ] . node . test_add_new_pending_payment ( our_payment_hash,
3564
+ onion_fields. clone ( ) , payment_id, & route) . unwrap ( ) ;
3565
+ let cur_height = nodes[ 0 ] . best_block_info ( ) . 1 ;
3566
+ nodes[ 0 ] . node . test_send_payment_along_path ( & route. paths [ 0 ] , & our_payment_hash,
3567
+ onion_fields. clone ( ) , amt_msat, cur_height, payment_id,
3568
+ & None , session_privs[ 0 ] ) . unwrap ( ) ;
3569
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
3570
+
3571
+ {
3572
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
3573
+ assert_eq ! ( events. len( ) , 1 ) ;
3574
+ pass_along_path ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 3 ] ] , amt_msat, our_payment_hash, Some ( our_payment_secret) , events. pop ( ) . unwrap ( ) , false , None ) ;
3575
+ }
3576
+ assert ! ( nodes[ 3 ] . node. get_and_clear_pending_events( ) . is_empty( ) ) ;
3577
+
3578
+ // Send second part
3579
+ let onion_fields = RecipientOnionFields {
3580
+ payment_secret : Some ( our_payment_secret) ,
3581
+ payment_metadata : None ,
3582
+ custom_tlvs : second_tlvs
3583
+ } ;
3584
+ nodes[ 0 ] . node . test_send_payment_along_path ( & route. paths [ 1 ] , & our_payment_hash,
3585
+ onion_fields. clone ( ) , amt_msat, cur_height, payment_id, & None , session_privs[ 1 ] ) . unwrap ( ) ;
3586
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
3587
+
3588
+ {
3589
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
3590
+ assert_eq ! ( events. len( ) , 1 ) ;
3591
+ let payment_event = SendEvent :: from_event ( events. pop ( ) . unwrap ( ) ) ;
3592
+
3593
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
3594
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 0 ] , payment_event. commitment_msg, false ) ;
3595
+
3596
+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
3597
+ check_added_monitors ! ( nodes[ 2 ] , 1 ) ;
3598
+
3599
+ let mut events = nodes[ 2 ] . node . get_and_clear_pending_msg_events ( ) ;
3600
+ assert_eq ! ( events. len( ) , 1 ) ;
3601
+ let payment_event = SendEvent :: from_event ( events. pop ( ) . unwrap ( ) ) ;
3602
+
3603
+ nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
3604
+ check_added_monitors ! ( nodes[ 3 ] , 0 ) ;
3605
+ commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 2 ] , payment_event. commitment_msg, true , true ) ;
3606
+ }
3607
+ expect_pending_htlcs_forwardable_ignore ! ( nodes[ 3 ] ) ;
3608
+ nodes[ 3 ] . node . process_pending_htlc_forwards ( ) ;
3609
+
3610
+ if let Some ( expected_tlvs) = expected_receive_tlvs {
3611
+ // Claim and match expected
3612
+ let events = nodes[ 3 ] . node . get_and_clear_pending_events ( ) ;
3613
+ println ! ( "events: {:?}" , events) ;
3614
+ assert_eq ! ( events. len( ) , 1 ) ;
3615
+ match events[ 0 ] {
3616
+ Event :: PaymentClaimable { ref purpose, amount_msat, ref onion_fields, .. } => {
3617
+ match & purpose {
3618
+ PaymentPurpose :: InvoicePayment { payment_secret, .. } => {
3619
+ assert_eq ! ( our_payment_secret, * payment_secret) ;
3620
+ assert_eq ! ( Some ( * payment_secret) , onion_fields. as_ref( ) . unwrap( ) . payment_secret) ;
3621
+ } ,
3622
+ PaymentPurpose :: SpontaneousPayment ( payment_preimage) => {
3623
+ assert_eq ! ( our_payment_preimage, * payment_preimage) ;
3624
+ } ,
3625
+ }
3626
+ assert_eq ! ( amount_msat, amt_msat) ;
3627
+ assert_eq ! ( onion_fields. clone( ) . unwrap( ) . custom_tlvs, expected_tlvs) ;
3628
+ } ,
3629
+ _ => panic ! ( "Unexpected event" ) ,
3630
+ }
3631
+
3632
+ do_claim_payment_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 3 ] ] , & [ & nodes[ 2 ] , & nodes[ 3 ] ] ] , false , our_payment_preimage) ;
3633
+ expect_payment_sent ( & nodes[ 0 ] , our_payment_preimage, Some ( Some ( 2000 ) ) , true ) ;
3634
+ } else {
3635
+ // Expect fail back
3636
+ let expected_destinations = vec ! [ HTLCDestination :: FailedPayment { payment_hash: our_payment_hash } ] ;
3637
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 3 ] , expected_destinations) ;
3638
+ check_added_monitors ! ( nodes[ 3 ] , 1 ) ;
3639
+
3640
+ let fail_updates_1 = get_htlc_update_msgs ! ( nodes[ 3 ] , nodes[ 2 ] . node. get_our_node_id( ) ) ;
3641
+ nodes[ 2 ] . node . handle_update_fail_htlc ( & nodes[ 3 ] . node . get_our_node_id ( ) , & fail_updates_1. update_fail_htlcs [ 0 ] ) ;
3642
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 3 ] , fail_updates_1. commitment_signed, false ) ;
3643
+
3644
+ 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_2_3. 2 } ] ) ;
3645
+ check_added_monitors ! ( nodes[ 2 ] , 1 ) ;
3646
+
3647
+ let fail_updates_2 = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
3648
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & fail_updates_2. update_fail_htlcs [ 0 ] ) ;
3649
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 2 ] , fail_updates_2. commitment_signed, false ) ;
3650
+
3651
+ expect_payment_failed_conditions ( & nodes[ 0 ] , our_payment_hash, true , PaymentFailedConditions :: new ( ) . mpp_parts_remain ( ) ) ;
3652
+ }
3653
+ }
3654
+
3494
3655
fn do_test_payment_metadata_consistency ( do_reload : bool , do_modify : bool ) {
3495
3656
// Check that a payment metadata received on one HTLC that doesn't match the one received on
3496
3657
// another results in the HTLC being rejected.
0 commit comments