@@ -25,7 +25,8 @@ use ln::wire::Encode;
2525use util:: events:: { Event , MessageSendEvent , MessageSendEventsProvider } ;
2626use util:: ser:: { Writeable , Writer } ;
2727use util:: { byte_utils, test_utils} ;
28- use util:: config:: UserConfig ;
28+ use util:: config:: { UserConfig , HTLCRelayPolicyUpdate } ;
29+ use util:: errors:: APIError ;
2930
3031use bitcoin:: hash_types:: BlockHash ;
3132
@@ -506,8 +507,6 @@ fn test_onion_failure() {
506507 let preimage = send_along_route ( & nodes[ 0 ] , bogus_route, & [ & nodes[ 1 ] , & nodes[ 2 ] ] , amt_to_forward+1 ) . 0 ;
507508 claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , preimage) ;
508509
509- //TODO: with new config API, we will be able to generate both valid and
510- //invalid channel_update cases.
511510 let short_channel_id = channels[ 0 ] . 0 . contents . short_channel_id ;
512511 run_onion_failure_test ( "fee_insufficient" , 0 , & nodes, & route, & payment_hash, & payment_secret, |msg| {
513512 msg. amount_msat -= 1 ;
@@ -594,6 +593,93 @@ fn test_onion_failure() {
594593 } , true , Some ( 23 ) , None , None ) ;
595594}
596595
596+ #[ test]
597+ fn test_onion_failure_stale_channel_update ( ) {
598+ // Create a network of three nodes and two channels connecting them. We'll be updating the
599+ // second channel with insane HTLC relay parameters, causing forwarding failures at the first
600+ // hop.
601+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
602+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
603+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , None , None ] ) ;
604+ let mut nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
605+ create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
606+ let channel_to_update = create_announced_chan_between_nodes (
607+ & nodes, 1 , 2 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ,
608+ ) ;
609+
610+ // A test payment should succeed as the HTLC relay paramters have not been changed yet.
611+ const PAYMENT_AMT : u64 = 40000 ;
612+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , PAYMENT_AMT ) ;
613+
614+ // Closure to update and retrieve the latest ChannelUpdate.
615+ let update_and_get_channel_update =
616+ |updates : & [ HTLCRelayPolicyUpdate ] , expect_new_update : bool ,
617+ prev_update : Option < & msgs:: ChannelUpdate > | -> Option < msgs:: ChannelUpdate > {
618+ nodes[ 1 ] . node . update_htlc_relay_policy ( & [ channel_to_update. 2 ] , updates) . unwrap ( ) ;
619+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
620+ assert_eq ! ( events. len( ) , expect_new_update as usize ) ;
621+ if !expect_new_update {
622+ return None ;
623+ }
624+ let new_update = match & events[ 0 ] {
625+ MessageSendEvent :: BroadcastChannelUpdate { msg, .. } => msg. clone ( ) ,
626+ _ => panic ! ( "expected BroadcastChannelUpdate event" ) ,
627+ } ;
628+ if prev_update. is_some ( ) {
629+ assert ! ( new_update. contents. timestamp > prev_update. unwrap( ) . contents. timestamp)
630+ }
631+ Some ( new_update)
632+ } ;
633+
634+ // We'll be attempting to route payments using the default ChannelUpdate for channels. This will
635+ // lead to onion failures at the first hop once we update the HTLC relay parameters for the
636+ // second hop.
637+ let ( route, payment_hash, _, payment_secret) = get_route_and_payment_hash ! (
638+ nodes[ 0 ] , nodes[ 2 ] , PAYMENT_AMT
639+ ) ;
640+ let expect_onion_failure = |name : & str , error_code : u16 , channel_update : & msgs:: ChannelUpdate | {
641+ let short_channel_id = channel_to_update. 0 . contents . short_channel_id ;
642+ let network_update = NetworkUpdate :: ChannelUpdateMessage { msg : channel_update. clone ( ) } ;
643+ run_onion_failure_test (
644+ name, 0 , & nodes, & route, & payment_hash, & payment_secret, |_| { } , || { } , true ,
645+ Some ( error_code) , Some ( network_update) , Some ( short_channel_id) ,
646+ ) ;
647+ } ;
648+
649+ // Updates to cltv_expiry_delta below MIN_CLTV_EXPIRY_DELTA should fail with APIMisuseError.
650+ let updates = & [ HTLCRelayPolicyUpdate :: CltvExpiryDelta ( Some ( MIN_CLTV_EXPIRY_DELTA - 1 ) ) ] ;
651+ match nodes[ 1 ] . node . update_htlc_relay_policy ( & [ channel_to_update. 2 ] , updates) {
652+ Err ( APIError :: APIMisuseError { .. } ) => { } ,
653+ _ => panic ! ( "unexpected result applying invalid cltv_expiry_delta" ) ,
654+ }
655+
656+ // Increase the base fee which should trigger a new ChannelUpdate.
657+ let updates = & [ HTLCRelayPolicyUpdate :: ForwardingFeeBaseMsat ( Some ( u32:: MAX ) ) ] ;
658+ let msg = update_and_get_channel_update ( updates, true , None ) . unwrap ( ) ;
659+ expect_onion_failure ( "fee_insufficient" , UPDATE |12 , & msg) ;
660+
661+ // Redundant updates should not trigger a new ChannelUpdate.
662+ assert ! ( update_and_get_channel_update( updates, false , None ) . is_none( ) ) ;
663+
664+ // Reset the base fee to the default and increase the proportional fee which should trigger a
665+ // new ChannelUpdate.
666+ let updates = & [
667+ HTLCRelayPolicyUpdate :: ForwardingFeeBaseMsat ( None ) ,
668+ HTLCRelayPolicyUpdate :: CltvExpiryDelta ( Some ( u16:: MAX ) ) ,
669+ ] ;
670+ let msg = update_and_get_channel_update ( updates, true , Some ( & msg) ) . unwrap ( ) ;
671+ expect_onion_failure ( "incorrect_cltv_expiry" , UPDATE |13 , & msg) ;
672+
673+ // Reset the proportional fee and increase the CLTV expiry delta which should trigger a new
674+ // ChannelUpdate.
675+ let updates = & [
676+ HTLCRelayPolicyUpdate :: CltvExpiryDelta ( None ) ,
677+ HTLCRelayPolicyUpdate :: ForwardingFeeProportionalMillionths ( Some ( u32:: MAX ) ) ,
678+ ] ;
679+ let msg = update_and_get_channel_update ( updates, true , Some ( & msg) ) . unwrap ( ) ;
680+ expect_onion_failure ( "fee_insufficient" , UPDATE |12 , & msg) ;
681+ }
682+
597683#[ test]
598684fn test_default_to_onion_payload_tlv_format ( ) {
599685 // Tests that we default to creating tlv format onion payloads when no `NodeAnnouncementInfo`
0 commit comments