@@ -56,7 +56,7 @@ use crate::ln::outbound_payment;
5656use crate :: ln:: outbound_payment:: { OutboundPayments , PaymentAttempts , PendingOutboundPayment } ;
5757use crate :: ln:: wire:: Encode ;
5858use crate :: sign:: { EntropySource , KeysManager , NodeSigner , Recipient , SignerProvider , ChannelSigner , WriteableEcdsaChannelSigner } ;
59- use crate :: util:: config:: { UserConfig , ChannelConfig } ;
59+ use crate :: util:: config:: { UserConfig , ChannelConfig , ChannelConfigUpdate } ;
6060use crate :: util:: wakers:: { Future , Notifier } ;
6161use crate :: util:: scid_utils:: fake_scid;
6262use crate :: util:: string:: UntrustedString ;
@@ -3228,7 +3228,7 @@ where
32283228 } )
32293229 }
32303230
3231- /// Atomically updates the [`ChannelConfig`] for the given channels.
3231+ /// Atomically applies partial updates to the [`ChannelConfig`] of the given channels.
32323232 ///
32333233 /// Once the updates are applied, each eligible channel (advertised with a known short channel
32343234 /// ID and a change in [`forwarding_fee_proportional_millionths`], [`forwarding_fee_base_msat`],
@@ -3250,10 +3250,10 @@ where
32503250 /// [`ChannelUpdate`]: msgs::ChannelUpdate
32513251 /// [`ChannelUnavailable`]: APIError::ChannelUnavailable
32523252 /// [`APIMisuseError`]: APIError::APIMisuseError
3253- pub fn update_channel_config (
3254- & self , counterparty_node_id : & PublicKey , channel_ids : & [ [ u8 ; 32 ] ] , config : & ChannelConfig ,
3253+ pub fn update_partial_channel_config (
3254+ & self , counterparty_node_id : & PublicKey , channel_ids : & [ [ u8 ; 32 ] ] , config_update : & ChannelConfigUpdate ,
32553255 ) -> Result < ( ) , APIError > {
3256- if config . cltv_expiry_delta < MIN_CLTV_EXPIRY_DELTA {
3256+ if config_update . cltv_expiry_delta . map ( |delta| delta < MIN_CLTV_EXPIRY_DELTA ) . unwrap_or ( false ) {
32573257 return Err ( APIError :: APIMisuseError {
32583258 err : format ! ( "The chosen CLTV expiry delta is below the minimum of {}" , MIN_CLTV_EXPIRY_DELTA ) ,
32593259 } ) ;
@@ -3274,7 +3274,9 @@ where
32743274 }
32753275 for channel_id in channel_ids {
32763276 let channel = peer_state. channel_by_id . get_mut ( channel_id) . unwrap ( ) ;
3277- if !channel. update_config ( config) {
3277+ let mut config = channel. config ( ) ;
3278+ config. apply ( config_update) ;
3279+ if !channel. update_config ( & config) {
32783280 continue ;
32793281 }
32803282 if let Ok ( msg) = self . get_channel_update_for_broadcast ( channel) {
@@ -3289,6 +3291,34 @@ where
32893291 Ok ( ( ) )
32903292 }
32913293
3294+ /// Atomically updates the [`ChannelConfig`] for the given channels.
3295+ ///
3296+ /// Once the updates are applied, each eligible channel (advertised with a known short channel
3297+ /// ID and a change in [`forwarding_fee_proportional_millionths`], [`forwarding_fee_base_msat`],
3298+ /// or [`cltv_expiry_delta`]) has a [`BroadcastChannelUpdate`] event message generated
3299+ /// containing the new [`ChannelUpdate`] message which should be broadcast to the network.
3300+ ///
3301+ /// Returns [`ChannelUnavailable`] when a channel is not found or an incorrect
3302+ /// `counterparty_node_id` is provided.
3303+ ///
3304+ /// Returns [`APIMisuseError`] when a [`cltv_expiry_delta`] update is to be applied with a value
3305+ /// below [`MIN_CLTV_EXPIRY_DELTA`].
3306+ ///
3307+ /// If an error is returned, none of the updates should be considered applied.
3308+ ///
3309+ /// [`forwarding_fee_proportional_millionths`]: ChannelConfig::forwarding_fee_proportional_millionths
3310+ /// [`forwarding_fee_base_msat`]: ChannelConfig::forwarding_fee_base_msat
3311+ /// [`cltv_expiry_delta`]: ChannelConfig::cltv_expiry_delta
3312+ /// [`BroadcastChannelUpdate`]: events::MessageSendEvent::BroadcastChannelUpdate
3313+ /// [`ChannelUpdate`]: msgs::ChannelUpdate
3314+ /// [`ChannelUnavailable`]: APIError::ChannelUnavailable
3315+ /// [`APIMisuseError`]: APIError::APIMisuseError
3316+ pub fn update_channel_config (
3317+ & self , counterparty_node_id : & PublicKey , channel_ids : & [ [ u8 ; 32 ] ] , config : & ChannelConfig ,
3318+ ) -> Result < ( ) , APIError > {
3319+ return self . update_partial_channel_config ( counterparty_node_id, channel_ids, & ( * config) . into ( ) ) ;
3320+ }
3321+
32923322 /// Attempts to forward an intercepted HTLC over the provided channel id and with the provided
32933323 /// amount to forward. Should only be called in response to an [`HTLCIntercepted`] event.
32943324 ///
@@ -8578,7 +8608,7 @@ mod tests {
85788608 use crate :: routing:: router:: { PaymentParameters , RouteParameters , find_route} ;
85798609 use crate :: util:: errors:: APIError ;
85808610 use crate :: util:: test_utils;
8581- use crate :: util:: config:: ChannelConfig ;
8611+ use crate :: util:: config:: { ChannelConfig , ChannelConfigUpdate } ;
85828612 use crate :: sign:: EntropySource ;
85838613
85848614 #[ test]
@@ -9489,6 +9519,62 @@ mod tests {
94899519
94909520 check_closed_event ! ( nodes[ 1 ] , 1 , ClosureReason :: HolderForceClosed ) ;
94919521 }
9522+
9523+ #[ test]
9524+ fn test_update_channel_config ( ) {
9525+ let chanmon_cfg = create_chanmon_cfgs ( 2 ) ;
9526+ let node_cfg = create_node_cfgs ( 2 , & chanmon_cfg) ;
9527+ let mut user_config = test_default_channel_config ( ) ;
9528+ let node_chanmgr = create_node_chanmgrs ( 2 , & node_cfg, & [ Some ( user_config) , Some ( user_config) ] ) ;
9529+ let nodes = create_network ( 2 , & node_cfg, & node_chanmgr) ;
9530+ let _ = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
9531+ let channel = & nodes[ 0 ] . node . list_channels ( ) [ 0 ] ;
9532+
9533+ nodes[ 0 ] . node . update_channel_config ( & channel. counterparty . node_id , & [ channel. channel_id ] , & user_config. channel_config ) . unwrap ( ) ;
9534+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
9535+ assert_eq ! ( events. len( ) , 0 ) ;
9536+
9537+ user_config. channel_config . forwarding_fee_base_msat += 10 ;
9538+ nodes[ 0 ] . node . update_channel_config ( & channel. counterparty . node_id , & [ channel. channel_id ] , & user_config. channel_config ) . unwrap ( ) ;
9539+ assert_eq ! ( nodes[ 0 ] . node. list_channels( ) [ 0 ] . config. unwrap( ) . forwarding_fee_base_msat, user_config. channel_config. forwarding_fee_base_msat) ;
9540+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
9541+ assert_eq ! ( events. len( ) , 1 ) ;
9542+ match & events[ 0 ] {
9543+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
9544+ _ => panic ! ( "expected BroadcastChannelUpdate event" ) ,
9545+ }
9546+
9547+ nodes[ 0 ] . node . update_partial_channel_config ( & channel. counterparty . node_id , & [ channel. channel_id ] , & ChannelConfigUpdate :: default ( ) ) . unwrap ( ) ;
9548+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
9549+ assert_eq ! ( events. len( ) , 0 ) ;
9550+
9551+ let new_cltv_expiry_delta = user_config. channel_config . cltv_expiry_delta + 6 ;
9552+ nodes[ 0 ] . node . update_partial_channel_config ( & channel. counterparty . node_id , & [ channel. channel_id ] , & ChannelConfigUpdate {
9553+ cltv_expiry_delta : Some ( new_cltv_expiry_delta) ,
9554+ ..Default :: default ( )
9555+ } ) . unwrap ( ) ;
9556+ assert_eq ! ( nodes[ 0 ] . node. list_channels( ) [ 0 ] . config. unwrap( ) . cltv_expiry_delta, new_cltv_expiry_delta) ;
9557+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
9558+ assert_eq ! ( events. len( ) , 1 ) ;
9559+ match & events[ 0 ] {
9560+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
9561+ _ => panic ! ( "expected BroadcastChannelUpdate event" ) ,
9562+ }
9563+
9564+ let new_fee = user_config. channel_config . forwarding_fee_proportional_millionths + 100 ;
9565+ nodes[ 0 ] . node . update_partial_channel_config ( & channel. counterparty . node_id , & [ channel. channel_id ] , & ChannelConfigUpdate {
9566+ forwarding_fee_proportional_millionths : Some ( new_fee) ,
9567+ ..Default :: default ( )
9568+ } ) . unwrap ( ) ;
9569+ assert_eq ! ( nodes[ 0 ] . node. list_channels( ) [ 0 ] . config. unwrap( ) . cltv_expiry_delta, new_cltv_expiry_delta) ;
9570+ assert_eq ! ( nodes[ 0 ] . node. list_channels( ) [ 0 ] . config. unwrap( ) . forwarding_fee_proportional_millionths, new_fee) ;
9571+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
9572+ assert_eq ! ( events. len( ) , 1 ) ;
9573+ match & events[ 0 ] {
9574+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
9575+ _ => panic ! ( "expected BroadcastChannelUpdate event" ) ,
9576+ }
9577+ }
94929578}
94939579
94949580#[ cfg( ldk_bench) ]
0 commit comments