@@ -51,7 +51,7 @@ use ln::onion_utils;
5151use ln:: msgs:: { ChannelMessageHandler , DecodeError , LightningError , MAX_VALUE_MSAT , OptionalField } ;
5252use ln:: wire:: Encode ;
5353use chain:: keysinterface:: { Sign , KeysInterface , KeysManager , InMemorySigner , Recipient } ;
54- use util:: config:: UserConfig ;
54+ use util:: config:: { UserConfig , ChannelConfig } ;
5555use util:: events:: { EventHandler , EventsProvider , MessageSendEvent , MessageSendEventsProvider , ClosureReason } ;
5656use util:: { byte_utils, events} ;
5757use util:: scid_utils:: fake_scid;
@@ -1101,6 +1101,10 @@ pub struct ChannelDetails {
11011101 pub inbound_htlc_minimum_msat : Option < u64 > ,
11021102 /// The largest value HTLC (in msat) we currently will accept, for this channel.
11031103 pub inbound_htlc_maximum_msat : Option < u64 > ,
1104+ /// Set of configurable parameters that affect channel operation.
1105+ ///
1106+ /// This field is only `None` for `ChannelDetails` objects serialized prior to LDK 0.0.109.
1107+ pub config : Option < ChannelConfig > ,
11041108}
11051109
11061110impl ChannelDetails {
@@ -1765,7 +1769,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
17651769 is_usable : channel. is_live ( ) ,
17661770 is_public : channel. should_announce ( ) ,
17671771 inbound_htlc_minimum_msat : Some ( channel. get_holder_htlc_minimum_msat ( ) ) ,
1768- inbound_htlc_maximum_msat : channel. get_holder_htlc_maximum_msat ( )
1772+ inbound_htlc_maximum_msat : channel. get_holder_htlc_maximum_msat ( ) ,
1773+ config : Some ( channel. config ( ) ) ,
17691774 } ) ;
17701775 }
17711776 }
@@ -2231,7 +2236,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
22312236 } ,
22322237 Some ( id) => Some ( id. clone ( ) ) ,
22332238 } ;
2234- let ( chan_update_opt, forwardee_cltv_expiry_delta ) = if let Some ( forwarding_id) = forwarding_id_opt {
2239+ let chan_update_opt = if let Some ( forwarding_id) = forwarding_id_opt {
22352240 let chan = channel_state. as_mut ( ) . unwrap ( ) . by_id . get_mut ( & forwarding_id) . unwrap ( ) ;
22362241 if !chan. should_announce ( ) && !self . default_configuration . accept_forwards_to_priv_channels {
22372242 // Note that the behavior here should be identical to the above block - we
@@ -2258,18 +2263,20 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
22582263 if * amt_to_forward < chan. get_counterparty_htlc_minimum_msat ( ) { // amount_below_minimum
22592264 break Some ( ( "HTLC amount was below the htlc_minimum_msat" , 0x1000 | 11 , chan_update_opt) ) ;
22602265 }
2261- let fee = amt_to_forward. checked_mul ( chan. get_fee_proportional_millionths ( ) as u64 )
2262- . and_then ( |prop_fee| { ( prop_fee / 1000000 )
2263- . checked_add ( chan. get_outbound_forwarding_fee_base_msat ( ) as u64 ) } ) ;
2264- if fee. is_none ( ) || msg. amount_msat < fee. unwrap ( ) || ( msg. amount_msat - fee. unwrap ( ) ) < * amt_to_forward { // fee_insufficient
2265- break Some ( ( "Prior hop has deviated from specified fees parameters or origin node has obsolete ones" , 0x1000 | 12 , chan_update_opt) ) ;
2266+ if let Err ( ( err, code) ) = chan. htlc_satisfies_config ( & msg, * amt_to_forward, * outgoing_cltv_value) {
2267+ break Some ( ( err, code, chan_update_opt) ) ;
2268+ }
2269+ chan_update_opt
2270+ } else {
2271+ if ( msg. cltv_expiry as u64 ) < ( * outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 { // incorrect_cltv_expiry
2272+ break Some ( (
2273+ "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta" ,
2274+ 0x1000 | 13 , None ,
2275+ ) ) ;
22662276 }
2267- ( chan_update_opt , chan . get_cltv_expiry_delta ( ) )
2268- } else { ( None , MIN_CLTV_EXPIRY_DELTA ) } ;
2277+ None
2278+ } ;
22692279
2270- if ( msg. cltv_expiry as u64 ) < ( * outgoing_cltv_value) as u64 + forwardee_cltv_expiry_delta as u64 { // incorrect_cltv_expiry
2271- break Some ( ( "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta" , 0x1000 | 13 , chan_update_opt) ) ;
2272- }
22732280 let cur_height = self . best_block . read ( ) . unwrap ( ) . height ( ) + 1 ;
22742281 // Theoretically, channel counterparty shouldn't send us a HTLC expiring now,
22752282 // but we want to be robust wrt to counterparty packet sanitization (see
@@ -2940,6 +2947,73 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
29402947 }
29412948 }
29422949
2950+ /// Atomically updates the [`ChannelConfig`] for the given channels.
2951+ ///
2952+ /// Once the updates are applied, each eligible channel (advertised with a known short channel
2953+ /// ID and a change in [`forwarding_fee_proportional_millionths`], [`forwarding_fee_base_msat`],
2954+ /// or [`cltv_expiry_delta`]) has a [`BroadcastChannelUpdate`] event message generated
2955+ /// containing the new [`ChannelUpdate`] message which should be broadcast to the network.
2956+ ///
2957+ /// Returns [`ChannelUnavailable`] when a channel is not found or an incorrect
2958+ /// `counterparty_node_id` is provided.
2959+ ///
2960+ /// Returns [`APIMisuseError`] when a [`cltv_expiry_delta`] update is to be applied with a value
2961+ /// below [`MIN_CLTV_EXPIRY_DELTA`].
2962+ ///
2963+ /// If an error is returned, none of the updates should be considered applied.
2964+ ///
2965+ /// [`forwarding_fee_proportional_millionths`]: ChannelConfig::forwarding_fee_proportional_millionths
2966+ /// [`forwarding_fee_base_msat`]: ChannelConfig::forwarding_fee_base_msat
2967+ /// [`cltv_expiry_delta`]: ChannelConfig::cltv_expiry_delta
2968+ /// [`BroadcastChannelUpdate`]: events::MessageSendEvent::BroadcastChannelUpdate
2969+ /// [`ChannelUpdate`]: msgs::ChannelUpdate
2970+ /// [`ChannelUnavailable`]: APIError::ChannelUnavailable
2971+ /// [`APIMisuseError`]: APIError::APIMisuseError
2972+ pub fn update_channel_config (
2973+ & self , counterparty_node_id : & PublicKey , channel_ids : & [ [ u8 ; 32 ] ] , config : & ChannelConfig ,
2974+ ) -> Result < ( ) , APIError > {
2975+ if config. cltv_expiry_delta < MIN_CLTV_EXPIRY_DELTA {
2976+ return Err ( APIError :: APIMisuseError {
2977+ err : format ! ( "The chosen CLTV expiry delta is below the minimum of {}" , MIN_CLTV_EXPIRY_DELTA ) ,
2978+ } ) ;
2979+ }
2980+
2981+ let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop (
2982+ & self . total_consistency_lock , & self . persistence_notifier ,
2983+ ) ;
2984+ {
2985+ let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
2986+ let channel_state = & mut * channel_state_lock;
2987+ for channel_id in channel_ids {
2988+ let channel_counterparty_node_id = channel_state. by_id . get ( channel_id)
2989+ . ok_or ( APIError :: ChannelUnavailable {
2990+ err : format ! ( "Channel with ID {} was not found" , log_bytes!( * channel_id) ) ,
2991+ } ) ?
2992+ . get_counterparty_node_id ( ) ;
2993+ if channel_counterparty_node_id != * counterparty_node_id {
2994+ return Err ( APIError :: APIMisuseError {
2995+ err : "counterparty node id mismatch" . to_owned ( ) ,
2996+ } ) ;
2997+ }
2998+ }
2999+ for channel_id in channel_ids {
3000+ let channel = channel_state. by_id . get_mut ( channel_id) . unwrap ( ) ;
3001+ if !channel. update_config ( config) {
3002+ continue ;
3003+ }
3004+ if let Ok ( msg) = self . get_channel_update_for_broadcast ( channel) {
3005+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: BroadcastChannelUpdate { msg } ) ;
3006+ } else if let Ok ( msg) = self . get_channel_update_for_unicast ( channel) {
3007+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendChannelUpdate {
3008+ node_id : channel. get_counterparty_node_id ( ) ,
3009+ msg,
3010+ } ) ;
3011+ }
3012+ }
3013+ }
3014+ Ok ( ( ) )
3015+ }
3016+
29433017 /// Processes HTLCs which are pending waiting on random forward delay.
29443018 ///
29453019 /// Should only really ever be called in response to a PendingHTLCsForwardable event.
@@ -3465,6 +3539,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
34653539 /// * Broadcasting `ChannelUpdate` messages if we've been disconnected from our peer for more
34663540 /// than a minute, informing the network that they should no longer attempt to route over
34673541 /// the channel.
3542+ /// * Expiring a channel's previous `ChannelConfig` if necessary to only allow forwarding HTLCs
3543+ /// with the current `ChannelConfig`.
34683544 ///
34693545 /// Note that this may cause reentrancy through `chain::Watch::update_channel` calls or feerate
34703546 /// estimate fetches.
@@ -3523,6 +3599,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
35233599 _ => { } ,
35243600 }
35253601
3602+ chan. maybe_expire_prev_config ( ) ;
3603+
35263604 true
35273605 } ) ;
35283606
@@ -6115,6 +6193,7 @@ impl_writeable_tlv_based!(ChannelDetails, {
61156193 ( 4 , counterparty, required) ,
61166194 ( 5 , outbound_scid_alias, option) ,
61176195 ( 6 , funding_txo, option) ,
6196+ ( 7 , config, option) ,
61186197 ( 8 , short_channel_id, option) ,
61196198 ( 10 , channel_value_satoshis, required) ,
61206199 ( 12 , unspendable_punishment_reserve, option) ,
0 commit comments