@@ -3013,3 +3013,151 @@ fn claim_from_closed_chan() {
3013
3013
do_claim_from_closed_chan ( true ) ;
3014
3014
do_claim_from_closed_chan ( false ) ;
3015
3015
}
3016
+
3017
+ fn do_test_payment_metadata_consistency ( do_reload : bool , do_modify : bool ) {
3018
+ // Check that a payment metadata received on one HTLC that doesn't match the one received on
3019
+ // another results in the HTLC being rejected.
3020
+ //
3021
+ // We first set up a diamond shaped network, allowing us to split a payment into two HTLCs, the
3022
+ // first of which we'll deliver and the second of which we'll fail and then re-send with
3023
+ // modified payment metadata, which will in turn result in it being failed by the recipient.
3024
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
3025
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
3026
+ let mut config = test_default_channel_config ( ) ;
3027
+ config. channel_handshake_config . max_inbound_htlc_value_in_flight_percent_of_channel = 50 ;
3028
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , Some ( config) , Some ( config) , Some ( config) ] ) ;
3029
+
3030
+ let persister;
3031
+ let new_chain_monitor;
3032
+ let nodes_0_deserialized;
3033
+
3034
+ let mut nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
3035
+
3036
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
3037
+ let chan_id_bd = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 3 , 1_000_000 , 0 ) . 2 ;
3038
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 2 , 1_000_000 , 0 ) ;
3039
+ let chan_id_cd = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) . 2 ;
3040
+
3041
+ // Pay more than half of each channel's max, requiring MPP
3042
+ let amt_msat = 750_000_000 ;
3043
+ let ( payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash ! ( nodes[ 3 ] , Some ( amt_msat) ) ;
3044
+ let payment_id = PaymentId ( payment_hash. 0 ) ;
3045
+ let payment_metadata = vec ! [ 44 , 49 , 52 , 142 ] ;
3046
+
3047
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 3 ] . node . get_our_node_id ( ) , TEST_FINAL_CLTV )
3048
+ . with_features ( nodes[ 1 ] . node . invoice_features ( ) ) ;
3049
+ let mut route_params = RouteParameters {
3050
+ payment_params,
3051
+ final_value_msat : amt_msat,
3052
+ } ;
3053
+
3054
+ // Send the MPP payment, delivering the updated commitment state to nodes[1].
3055
+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields {
3056
+ payment_secret : Some ( payment_secret) , payment_metadata : Some ( payment_metadata) ,
3057
+ } , payment_id, route_params. clone ( ) , Retry :: Attempts ( 1 ) ) . unwrap ( ) ;
3058
+ check_added_monitors ! ( nodes[ 0 ] , 2 ) ;
3059
+
3060
+ let mut send_events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
3061
+ assert_eq ! ( send_events. len( ) , 2 ) ;
3062
+ let first_send = SendEvent :: from_event ( send_events. pop ( ) . unwrap ( ) ) ;
3063
+ let second_send = SendEvent :: from_event ( send_events. pop ( ) . unwrap ( ) ) ;
3064
+
3065
+ let ( b_recv_ev, c_recv_ev) = if first_send. node_id == nodes[ 1 ] . node . get_our_node_id ( ) {
3066
+ ( & first_send, & second_send)
3067
+ } else {
3068
+ ( & second_send, & first_send)
3069
+ } ;
3070
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & b_recv_ev. msgs [ 0 ] ) ;
3071
+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , b_recv_ev. commitment_msg, false , true ) ;
3072
+
3073
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
3074
+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
3075
+ let b_forward_ev = SendEvent :: from_node ( & nodes[ 1 ] ) ;
3076
+ nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & b_forward_ev. msgs [ 0 ] ) ;
3077
+ commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 1 ] , b_forward_ev. commitment_msg, false , true ) ;
3078
+
3079
+ expect_pending_htlcs_forwardable ! ( nodes[ 3 ] ) ;
3080
+
3081
+ // Before delivering the second MPP HTLC to nodes[2], disconnect nodes[2] and nodes[3], which
3082
+ // will result in nodes[2] failing the HTLC back.
3083
+ nodes[ 2 ] . node . peer_disconnected ( & nodes[ 3 ] . node . get_our_node_id ( ) ) ;
3084
+ nodes[ 3 ] . node . peer_disconnected ( & nodes[ 2 ] . node . get_our_node_id ( ) ) ;
3085
+
3086
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & c_recv_ev. msgs [ 0 ] ) ;
3087
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 0 ] , c_recv_ev. commitment_msg, false , true ) ;
3088
+
3089
+ let cs_fail = get_htlc_update_msgs ( & nodes[ 2 ] , & nodes[ 0 ] . node . get_our_node_id ( ) ) ;
3090
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & cs_fail. update_fail_htlcs [ 0 ] ) ;
3091
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 2 ] , cs_fail. commitment_signed, false , true ) ;
3092
+
3093
+ let payment_fail_retryable_evs = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
3094
+ assert_eq ! ( payment_fail_retryable_evs. len( ) , 2 ) ;
3095
+ if let Event :: PaymentPathFailed { .. } = payment_fail_retryable_evs[ 0 ] { } else { panic ! ( ) ; }
3096
+ if let Event :: PendingHTLCsForwardable { .. } = payment_fail_retryable_evs[ 1 ] { } else { panic ! ( ) ; }
3097
+
3098
+ // Before we allow the HTLC to be retried, optionally change the payment_metadata we have
3099
+ // stored for our payment.
3100
+ if do_modify {
3101
+ nodes[ 0 ] . node . test_set_payment_metadata ( payment_id, Some ( Vec :: new ( ) ) ) ;
3102
+ }
3103
+
3104
+ // Optionally reload nodes[3] to check that the payment_metadata is properly serialized with
3105
+ // the payment state.
3106
+ if do_reload {
3107
+ let mon_bd = get_monitor ! ( nodes[ 3 ] , chan_id_bd) . encode ( ) ;
3108
+ let mon_cd = get_monitor ! ( nodes[ 3 ] , chan_id_cd) . encode ( ) ;
3109
+ reload_node ! ( nodes[ 3 ] , config, & nodes[ 3 ] . node. encode( ) , & [ & mon_bd, & mon_cd] ,
3110
+ persister, new_chain_monitor, nodes_0_deserialized) ;
3111
+ nodes[ 1 ] . node . peer_disconnected ( & nodes[ 3 ] . node . get_our_node_id ( ) ) ;
3112
+ reconnect_nodes ( & nodes[ 1 ] , & nodes[ 3 ] , ( false , false ) , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , false ) ) ;
3113
+ }
3114
+ reconnect_nodes ( & nodes[ 2 ] , & nodes[ 3 ] , ( true , true ) , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , false ) ) ;
3115
+
3116
+ // Create a new channel between C and D as A will refuse to retry on the existing one because
3117
+ // it just failed.
3118
+ let chan_id_cd_2 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) . 2 ;
3119
+
3120
+ // Now retry the failed HTLC.
3121
+ nodes[ 0 ] . node . process_pending_htlc_forwards ( ) ;
3122
+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
3123
+ let as_resend = SendEvent :: from_node ( & nodes[ 0 ] ) ;
3124
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_resend. msgs [ 0 ] ) ;
3125
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 0 ] , as_resend. commitment_msg, false , true ) ;
3126
+
3127
+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
3128
+ check_added_monitors ( & nodes[ 2 ] , 1 ) ;
3129
+ let cs_forward = SendEvent :: from_node ( & nodes[ 2 ] ) ;
3130
+ nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & cs_forward. msgs [ 0 ] ) ;
3131
+ commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 2 ] , cs_forward. commitment_msg, false , true ) ;
3132
+
3133
+ // Finally, check that nodes[3] does the correct thing - either accepting the payment or, if
3134
+ // the payment metadata was modified, failing only the one modified HTLC and retaining the
3135
+ // other.
3136
+ if do_modify {
3137
+ expect_pending_htlcs_forwardable_ignore ! ( nodes[ 3 ] ) ;
3138
+ nodes[ 3 ] . node . process_pending_htlc_forwards ( ) ;
3139
+ expect_pending_htlcs_forwardable_conditions ( nodes[ 3 ] . node . get_and_clear_pending_events ( ) ,
3140
+ & [ HTLCDestination :: FailedPayment { payment_hash} ] ) ;
3141
+ nodes[ 3 ] . node . process_pending_htlc_forwards ( ) ;
3142
+
3143
+ check_added_monitors ( & nodes[ 3 ] , 1 ) ;
3144
+ let ds_fail = get_htlc_update_msgs ( & nodes[ 3 ] , & nodes[ 2 ] . node . get_our_node_id ( ) ) ;
3145
+
3146
+ nodes[ 2 ] . node . handle_update_fail_htlc ( & nodes[ 3 ] . node . get_our_node_id ( ) , & ds_fail. update_fail_htlcs [ 0 ] ) ;
3147
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 3 ] , ds_fail. commitment_signed, false , true ) ;
3148
+ expect_pending_htlcs_forwardable_conditions ( nodes[ 2 ] . node . get_and_clear_pending_events ( ) ,
3149
+ & [ HTLCDestination :: NextHopChannel { node_id : Some ( nodes[ 3 ] . node . get_our_node_id ( ) ) , channel_id : chan_id_cd_2 } ] ) ;
3150
+ } else {
3151
+ expect_pending_htlcs_forwardable ! ( nodes[ 3 ] ) ;
3152
+ expect_payment_claimable ! ( nodes[ 3 ] , payment_hash, payment_secret, amt_msat) ;
3153
+ claim_payment_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 3 ] ] , & [ & nodes[ 2 ] , & nodes[ 3 ] ] ] , false , payment_preimage) ;
3154
+ }
3155
+ }
3156
+
3157
+ #[ test]
3158
+ fn test_payment_metadata_consistency ( ) {
3159
+ do_test_payment_metadata_consistency ( true , true ) ;
3160
+ do_test_payment_metadata_consistency ( true , false ) ;
3161
+ do_test_payment_metadata_consistency ( false , true ) ;
3162
+ do_test_payment_metadata_consistency ( false , false ) ;
3163
+ }
0 commit comments