@@ -3013,3 +3013,151 @@ fn claim_from_closed_chan() {
30133013 do_claim_from_closed_chan ( true ) ;
30143014 do_claim_from_closed_chan ( false ) ;
30153015}
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