@@ -15,7 +15,7 @@ use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
1515use crate :: chain:: channelmonitor:: { ANTI_REORG_DELAY , HTLC_FAIL_BACK_BUFFER , LATENCY_GRACE_PERIOD_BLOCKS } ;
1616use crate :: sign:: EntropySource ;
1717use crate :: chain:: transaction:: OutPoint ;
18- use crate :: events:: { ClosureReason , Event , HTLCDestination , MessageSendEvent , MessageSendEventsProvider , PathFailure , PaymentFailureReason } ;
18+ use crate :: events:: { ClosureReason , Event , HTLCDestination , MessageSendEvent , MessageSendEventsProvider , PathFailure , PaymentFailureReason , PaymentPurpose } ;
1919use crate :: ln:: channel:: EXPIRE_PREV_CONFIG_TICKS ;
2020use crate :: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , ChannelManager , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS , RecentPaymentDetails , RecipientOnionFields , HTLCForwardInfo , PendingHTLCRouting , PendingAddHTLCInfo } ;
2121use crate :: ln:: features:: Bolt11InvoiceFeatures ;
@@ -3385,6 +3385,170 @@ fn claim_from_closed_chan() {
33853385 do_claim_from_closed_chan ( false ) ;
33863386}
33873387
3388+ #[ test]
3389+ fn test_custom_tlvs ( ) {
3390+ do_test_custom_tlvs ( true ) ;
3391+ do_test_custom_tlvs ( false ) ;
3392+ }
3393+
3394+ fn do_test_custom_tlvs ( spontaneous : bool ) {
3395+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
3396+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
3397+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None ; 2 ] ) ;
3398+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
3399+
3400+ create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
3401+
3402+ let amt_msat = 100_000 ;
3403+ let ( mut route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash ! ( & nodes[ 0 ] , & nodes[ 1 ] , amt_msat) ;
3404+ let payment_id = PaymentId ( our_payment_hash. 0 ) ;
3405+ let custom_tlvs = vec ! [
3406+ ( 5482373483 , vec![ 1 , 2 , 3 , 4 ] ) ,
3407+ ( 5482373487 , vec![ 0x42u8 ; 16 ] ) ,
3408+ ] ;
3409+ let onion_fields = RecipientOnionFields {
3410+ payment_secret : if spontaneous { None } else { Some ( our_payment_secret) } ,
3411+ payment_metadata : None ,
3412+ custom_tlvs : custom_tlvs. clone ( )
3413+ } ;
3414+ if spontaneous {
3415+ nodes[ 0 ] . node . send_spontaneous_payment ( & route, Some ( our_payment_preimage) , onion_fields, payment_id) . unwrap ( ) ;
3416+ } else {
3417+ nodes[ 0 ] . node . send_payment_with_route ( & route, our_payment_hash, onion_fields, payment_id) . unwrap ( ) ;
3418+ }
3419+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
3420+
3421+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
3422+ let ev = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
3423+ let mut payment_event = SendEvent :: from_event ( ev) ;
3424+
3425+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
3426+ check_added_monitors ! ( & nodes[ 1 ] , 0 ) ;
3427+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , payment_event. commitment_msg, false ) ;
3428+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
3429+
3430+ let events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
3431+ assert_eq ! ( events. len( ) , 1 ) ;
3432+ match events[ 0 ] {
3433+ Event :: PaymentClaimable { ref purpose, amount_msat, ref onion_fields, .. } => {
3434+ match & purpose {
3435+ PaymentPurpose :: InvoicePayment { payment_secret, .. } => {
3436+ assert_eq ! ( our_payment_secret, * payment_secret) ;
3437+ assert_eq ! ( Some ( * payment_secret) , onion_fields. as_ref( ) . unwrap( ) . payment_secret) ;
3438+ } ,
3439+ PaymentPurpose :: SpontaneousPayment ( payment_preimage) => {
3440+ assert_eq ! ( our_payment_preimage, * payment_preimage) ;
3441+ } ,
3442+ }
3443+ assert_eq ! ( amount_msat, amt_msat) ;
3444+ assert_eq ! ( onion_fields. clone( ) . unwrap( ) . custom_tlvs( ) . clone( ) , custom_tlvs) ;
3445+ } ,
3446+ _ => panic ! ( "Unexpected event" ) ,
3447+ }
3448+
3449+ claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , our_payment_preimage) ;
3450+ }
3451+
3452+ #[ test]
3453+ fn test_retry_custom_tlvs ( ) {
3454+ // Test that custom TLVs are successfully sent on retries
3455+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
3456+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
3457+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , None , None ] ) ;
3458+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
3459+
3460+ create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
3461+ let ( chan_2_update, _, chan_2_id, _) = create_announced_chan_between_nodes ( & nodes, 2 , 1 ) ;
3462+
3463+ // Rebalance
3464+ send_payment ( & nodes[ 2 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 1_500_000 ) ;
3465+
3466+ let amt_msat = 1_000_000 ;
3467+ let ( route, payment_hash, payment_preimage, payment_secret) =
3468+ get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 2 ] , amt_msat) ;
3469+
3470+ // Initiate the payment
3471+ let payment_id = PaymentId ( payment_hash. 0 ) ;
3472+ let mut route_params = RouteParameters {
3473+ payment_params : route. payment_params . clone ( ) . unwrap ( ) ,
3474+ final_value_msat : amt_msat,
3475+ } ;
3476+
3477+ let custom_tlvs = vec ! [ ( ( 1 << 16 ) + 1 , vec![ 0x42u8 ; 16 ] ) ] ;
3478+ let onion_fields = RecipientOnionFields :: secret_only ( payment_secret) ;
3479+ let onion_fields = onion_fields. with_custom_tlvs ( custom_tlvs. clone ( ) ) . unwrap ( ) ;
3480+
3481+ nodes[ 0 ] . router . expect_find_route ( route_params. clone ( ) , Ok ( route. clone ( ) ) ) ;
3482+ nodes[ 0 ] . node . send_payment ( payment_hash, onion_fields,
3483+ payment_id, route_params. clone ( ) , Retry :: Attempts ( 1 ) ) . unwrap ( ) ;
3484+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ; // one monitor per path
3485+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
3486+ assert_eq ! ( events. len( ) , 1 ) ;
3487+
3488+ // Add the HTLC along the first hop.
3489+ let fail_path_msgs_1 = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
3490+ let ( update_add, commitment_signed) = match fail_path_msgs_1 {
3491+ MessageSendEvent :: UpdateHTLCs { node_id : _, updates : msgs:: CommitmentUpdate {
3492+ ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs,
3493+ ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed }
3494+ } => {
3495+ assert_eq ! ( update_add_htlcs. len( ) , 1 ) ;
3496+ assert ! ( update_fail_htlcs. is_empty( ) ) ;
3497+ assert ! ( update_fulfill_htlcs. is_empty( ) ) ;
3498+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
3499+ assert ! ( update_fee. is_none( ) ) ;
3500+ ( update_add_htlcs[ 0 ] . clone ( ) , commitment_signed. clone ( ) )
3501+ } ,
3502+ _ => panic ! ( "Unexpected event" ) ,
3503+ } ;
3504+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & update_add) ;
3505+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , commitment_signed, false ) ;
3506+
3507+ // Attempt to forward the payment and complete the path's failure.
3508+ expect_pending_htlcs_forwardable ! ( & nodes[ 1 ] ) ;
3509+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( & nodes[ 1 ] ,
3510+ vec![ HTLCDestination :: NextHopChannel {
3511+ node_id: Some ( nodes[ 2 ] . node. get_our_node_id( ) ) ,
3512+ channel_id: chan_2_id
3513+ } ] ) ;
3514+ let htlc_updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
3515+ assert ! ( htlc_updates. update_add_htlcs. is_empty( ) ) ;
3516+ assert_eq ! ( htlc_updates. update_fail_htlcs. len( ) , 1 ) ;
3517+ assert ! ( htlc_updates. update_fulfill_htlcs. is_empty( ) ) ;
3518+ assert ! ( htlc_updates. update_fail_malformed_htlcs. is_empty( ) ) ;
3519+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
3520+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) ,
3521+ & htlc_updates. update_fail_htlcs [ 0 ] ) ;
3522+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , htlc_updates. commitment_signed, false ) ;
3523+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
3524+ match events[ 1 ] {
3525+ Event :: PendingHTLCsForwardable { .. } => { } ,
3526+ _ => panic ! ( "Unexpected event" )
3527+ }
3528+ events. remove ( 1 ) ;
3529+ expect_payment_failed_conditions_event ( events, payment_hash, false ,
3530+ PaymentFailedConditions :: new ( ) . mpp_parts_remain ( ) ) ;
3531+
3532+ // Rebalance the channel so the retry of the payment can succeed.
3533+ send_payment ( & nodes[ 2 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 1_500_000 ) ;
3534+
3535+ // Retry the payment and make sure it succeeds
3536+ route_params. payment_params . previously_failed_channels . push ( chan_2_update. contents . short_channel_id ) ;
3537+ nodes[ 0 ] . router . expect_find_route ( route_params, Ok ( route) ) ;
3538+ nodes[ 0 ] . node . process_pending_htlc_forwards ( ) ;
3539+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
3540+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
3541+ assert_eq ! ( events. len( ) , 1 ) ;
3542+ let payment_claimable = pass_along_path ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , 1_000_000 ,
3543+ payment_hash, Some ( payment_secret) , events. pop ( ) . unwrap ( ) , true , None ) . unwrap ( ) ;
3544+ let onion_fields = match payment_claimable {
3545+ Event :: PaymentClaimable { onion_fields, .. } => onion_fields,
3546+ _ => panic ! ( "Unexpected event" ) ,
3547+ } ;
3548+ assert_eq ! ( onion_fields. unwrap( ) . custom_tlvs( ) , & custom_tlvs) ;
3549+ claim_payment_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 2 ] ] ] , false , payment_preimage) ;
3550+ }
3551+
33883552fn do_test_payment_metadata_consistency ( do_reload : bool , do_modify : bool ) {
33893553 // Check that a payment metadata received on one HTLC that doesn't match the one received on
33903554 // another results in the HTLC being rejected.
0 commit comments