@@ -56,7 +56,7 @@ use crate::ln::outbound_payment;
56
56
use crate :: ln:: outbound_payment:: { OutboundPayments , PaymentAttempts , PendingOutboundPayment } ;
57
57
use crate :: ln:: wire:: Encode ;
58
58
use crate :: sign:: { EntropySource , KeysManager , NodeSigner , Recipient , SignerProvider , ChannelSigner , WriteableEcdsaChannelSigner } ;
59
- use crate :: util:: config:: { UserConfig , ChannelConfig } ;
59
+ use crate :: util:: config:: { UserConfig , ChannelConfig , ChannelConfigUpdate } ;
60
60
use crate :: util:: wakers:: { Future , Notifier } ;
61
61
use crate :: util:: scid_utils:: fake_scid;
62
62
use crate :: util:: string:: UntrustedString ;
@@ -3228,7 +3228,7 @@ where
3228
3228
} )
3229
3229
}
3230
3230
3231
- /// Atomically updates the [`ChannelConfig`] for the given channels.
3231
+ /// Atomically applies partial updates to the [`ChannelConfig`] of the given channels.
3232
3232
///
3233
3233
/// Once the updates are applied, each eligible channel (advertised with a known short channel
3234
3234
/// ID and a change in [`forwarding_fee_proportional_millionths`], [`forwarding_fee_base_msat`],
@@ -3250,10 +3250,10 @@ where
3250
3250
/// [`ChannelUpdate`]: msgs::ChannelUpdate
3251
3251
/// [`ChannelUnavailable`]: APIError::ChannelUnavailable
3252
3252
/// [`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 ,
3255
3255
) -> 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 ) {
3257
3257
return Err ( APIError :: APIMisuseError {
3258
3258
err : format ! ( "The chosen CLTV expiry delta is below the minimum of {}" , MIN_CLTV_EXPIRY_DELTA ) ,
3259
3259
} ) ;
@@ -3274,7 +3274,9 @@ where
3274
3274
}
3275
3275
for channel_id in channel_ids {
3276
3276
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) {
3278
3280
continue ;
3279
3281
}
3280
3282
if let Ok ( msg) = self . get_channel_update_for_broadcast ( channel) {
@@ -3289,6 +3291,34 @@ where
3289
3291
Ok ( ( ) )
3290
3292
}
3291
3293
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
+
3292
3322
/// Attempts to forward an intercepted HTLC over the provided channel id and with the provided
3293
3323
/// amount to forward. Should only be called in response to an [`HTLCIntercepted`] event.
3294
3324
///
@@ -8578,7 +8608,7 @@ mod tests {
8578
8608
use crate :: routing:: router:: { PaymentParameters , RouteParameters , find_route} ;
8579
8609
use crate :: util:: errors:: APIError ;
8580
8610
use crate :: util:: test_utils;
8581
- use crate :: util:: config:: ChannelConfig ;
8611
+ use crate :: util:: config:: { ChannelConfig , ChannelConfigUpdate } ;
8582
8612
use crate :: sign:: EntropySource ;
8583
8613
8584
8614
#[ test]
@@ -9489,6 +9519,62 @@ mod tests {
9489
9519
9490
9520
check_closed_event ! ( nodes[ 1 ] , 1 , ClosureReason :: HolderForceClosed ) ;
9491
9521
}
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
+ }
9492
9578
}
9493
9579
9494
9580
#[ cfg( ldk_bench) ]
0 commit comments