@@ -789,8 +789,13 @@ macro_rules! secp_check {
789
789
790
790
impl < Signer : Sign > Channel < Signer > {
791
791
// Convert constants + channel value to limits:
792
- fn get_holder_max_htlc_value_in_flight_msat ( channel_value_satoshis : u64 ) -> u64 {
793
- channel_value_satoshis * 1000 / 10 //TODO
792
+ fn get_holder_max_htlc_value_in_flight_msat ( channel_value_satoshis : u64 , config : ChannelConfig ) -> u64 {
793
+ channel_value_satoshis * 10 * u64:: from ( config. holder_max_htlc_value_in_flight_msat_channel_value_percent )
794
+ }
795
+
796
+ fn config_htlc_in_flight_value_is_valid ( config : ChannelConfig ) -> bool {
797
+ let htlc_in_flight_value = config. holder_max_htlc_value_in_flight_msat_channel_value_percent ;
798
+ htlc_in_flight_value >= 1 && htlc_in_flight_value <= 100
794
799
}
795
800
796
801
/// Returns a minimum channel reserve value the remote needs to maintain,
@@ -865,6 +870,13 @@ impl<Signer: Sign> Channel<Signer> {
865
870
return Err ( APIError :: APIMisuseError { err : format ! ( "Holder selected channel reserve below implemention limit dust_limit_satoshis {}" , holder_selected_channel_reserve_satoshis) } ) ;
866
871
}
867
872
873
+ // Check that config has valid values set
874
+ if !Self :: config_htlc_in_flight_value_is_valid ( config. channel_options ) {
875
+ return Err ( APIError :: APIMisuseError { err : format ! (
876
+ "UserConfig::channel_options::holder_max_htlc_value_in_flight_msat_channel_value_percent must be set to a value between 1-100. Current value set ({})" ,
877
+ config. channel_options. holder_max_htlc_value_in_flight_msat_channel_value_percent) } ) ;
878
+ }
879
+
868
880
let feerate = fee_estimator. get_est_sat_per_1000_weight ( ConfirmationTarget :: Normal ) ;
869
881
870
882
let value_to_self_msat = channel_value_satoshis * 1000 - push_msat;
@@ -946,7 +958,7 @@ impl<Signer: Sign> Channel<Signer> {
946
958
counterparty_dust_limit_satoshis : 0 ,
947
959
holder_dust_limit_satoshis : MIN_CHAN_DUST_LIMIT_SATOSHIS ,
948
960
counterparty_max_htlc_value_in_flight_msat : 0 ,
949
- holder_max_htlc_value_in_flight_msat : Self :: get_holder_max_htlc_value_in_flight_msat ( channel_value_satoshis) ,
961
+ holder_max_htlc_value_in_flight_msat : Self :: get_holder_max_htlc_value_in_flight_msat ( channel_value_satoshis, config . channel_options ) ,
950
962
counterparty_selected_channel_reserve_satoshis : None , // Filled in in accept_channel
951
963
holder_selected_channel_reserve_satoshis,
952
964
counterparty_htlc_minimum_msat : 0 ,
@@ -1129,6 +1141,13 @@ impl<Signer: Sign> Channel<Signer> {
1129
1141
return Err ( ChannelError :: Close ( format ! ( "dust_limit_satoshis ({}) is greater than the implementation limit ({})" , msg. dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS ) ) ) ;
1130
1142
}
1131
1143
1144
+ // Check that config has valid values set
1145
+ if !Self :: config_htlc_in_flight_value_is_valid ( config. channel_options ) {
1146
+ return Err ( ChannelError :: Close ( format ! (
1147
+ "UserConfig::channel_options::holder_max_htlc_value_in_flight_msat_channel_value_percent must be set to a value between 1-100. Current value set ({})" ,
1148
+ config. channel_options. holder_max_htlc_value_in_flight_msat_channel_value_percent) ) ) ;
1149
+ }
1150
+
1132
1151
// Convert things into internal flags and prep our state:
1133
1152
1134
1153
if config. peer_channel_config_limits . force_announced_channel_preference {
@@ -1259,7 +1278,7 @@ impl<Signer: Sign> Channel<Signer> {
1259
1278
counterparty_dust_limit_satoshis : msg. dust_limit_satoshis ,
1260
1279
holder_dust_limit_satoshis : MIN_CHAN_DUST_LIMIT_SATOSHIS ,
1261
1280
counterparty_max_htlc_value_in_flight_msat : cmp:: min ( msg. max_htlc_value_in_flight_msat , msg. funding_satoshis * 1000 ) ,
1262
- holder_max_htlc_value_in_flight_msat : Self :: get_holder_max_htlc_value_in_flight_msat ( msg. funding_satoshis ) ,
1281
+ holder_max_htlc_value_in_flight_msat : Self :: get_holder_max_htlc_value_in_flight_msat ( msg. funding_satoshis , config . channel_options ) ,
1263
1282
counterparty_selected_channel_reserve_satoshis : Some ( msg. channel_reserve_satoshis ) ,
1264
1283
holder_selected_channel_reserve_satoshis,
1265
1284
counterparty_htlc_minimum_msat : msg. htlc_minimum_msat ,
@@ -5855,13 +5874,14 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
5855
5874
let chan_type = if self . channel_type != ChannelTypeFeatures :: only_static_remote_key ( ) {
5856
5875
Some ( & self . channel_type ) } else { None } ;
5857
5876
5858
- // The same logic applies for `holder_selected_channel_reserve_satoshis` and
5859
- // `holder_max_htlc_value_in_flight_msat` values other than the defaults.
5877
+ // The same logic applies for `holder_selected_channel_reserve_satoshis` values other than
5878
+ // the default, and when `holder_max_htlc_value_in_flight_msat` has a different value then
5879
+ // the result of `get_holder_max_htlc_value_in_flight_msat` with the set channel `config`.
5860
5880
let serialized_holder_selected_reserve =
5861
5881
if self . holder_selected_channel_reserve_satoshis != Self :: get_holder_selected_channel_reserve_satoshis ( self . channel_value_satoshis )
5862
5882
{ Some ( self . holder_selected_channel_reserve_satoshis ) } else { None } ;
5863
5883
let serialized_holder_htlc_max_in_flight =
5864
- if self . holder_max_htlc_value_in_flight_msat != Self :: get_holder_max_htlc_value_in_flight_msat ( self . channel_value_satoshis )
5884
+ if self . holder_max_htlc_value_in_flight_msat != Self :: get_holder_max_htlc_value_in_flight_msat ( self . channel_value_satoshis , self . config )
5865
5885
{ Some ( self . holder_max_htlc_value_in_flight_msat ) } else { None } ;
5866
5886
5867
5887
write_tlv_fields ! ( writer, {
@@ -6131,7 +6151,6 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6131
6151
let mut target_closing_feerate_sats_per_kw = None ;
6132
6152
let mut monitor_pending_finalized_fulfills = Some ( Vec :: new ( ) ) ;
6133
6153
let mut holder_selected_channel_reserve_satoshis = Some ( Self :: get_holder_selected_channel_reserve_satoshis ( channel_value_satoshis) ) ;
6134
- let mut holder_max_htlc_value_in_flight_msat = Some ( Self :: get_holder_max_htlc_value_in_flight_msat ( channel_value_satoshis) ) ;
6135
6154
// Prior to supporting channel type negotiation, all of our channels were static_remotekey
6136
6155
// only, so we default to that if none was written.
6137
6156
let mut channel_type = Some ( ChannelTypeFeatures :: only_static_remote_key ( ) ) ;
@@ -6143,6 +6162,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6143
6162
let mut announcement_sigs_state = Some ( AnnouncementSigsState :: NotSent ) ;
6144
6163
let mut latest_inbound_scid_alias = None ;
6145
6164
let mut outbound_scid_alias = None ;
6165
+ let mut tlv_holder_max_htlc_value_in_flight_msat = None ;
6146
6166
6147
6167
read_tlv_fields ! ( reader, {
6148
6168
( 0 , announcement_sigs, option) ,
@@ -6151,7 +6171,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6151
6171
( 3 , counterparty_selected_channel_reserve_satoshis, option) ,
6152
6172
( 4 , holder_selected_channel_reserve_satoshis, option) ,
6153
6173
( 5 , config, option) , // Note that if none is provided we will *not* overwrite the existing one.
6154
- ( 6 , holder_max_htlc_value_in_flight_msat , option) ,
6174
+ ( 6 , tlv_holder_max_htlc_value_in_flight_msat , option) ,
6155
6175
( 7 , shutdown_scriptpubkey, option) ,
6156
6176
( 9 , target_closing_feerate_sats_per_kw, option) ,
6157
6177
( 11 , monitor_pending_finalized_fulfills, vec_type) ,
@@ -6162,6 +6182,18 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6162
6182
( 21 , outbound_scid_alias, option) ,
6163
6183
} ) ;
6164
6184
6185
+ // Note that we need to call `get_holder_max_htlc_value_in_flight_msat` after the tlv
6186
+ // fields have been read, as
6187
+ // `config.holder_max_htlc_value_in_flight_msat_channel_value_percent` always will have the
6188
+ // default value prior to that.
6189
+ // If `tlv_holder_max_htlc_value_in_flight_msat` was set in the tlv fields, the
6190
+ // `holder_max_htlc_value_in_flight_msat` was written with a different value then result of
6191
+ // `get_holder_max_htlc_value_in_flight_msat` with the channel `config`, and the written
6192
+ // value should therefore be used.
6193
+ let holder_max_htlc_value_in_flight_msat = tlv_holder_max_htlc_value_in_flight_msat
6194
+ . map ( |max_htlc_value_in_flight| max_htlc_value_in_flight)
6195
+ . or ( Some ( Self :: get_holder_max_htlc_value_in_flight_msat ( channel_value_satoshis, config. unwrap ( ) ) ) ) ;
6196
+
6165
6197
if let Some ( preimages) = preimages_opt {
6166
6198
let mut iter = preimages. into_iter ( ) ;
6167
6199
for htlc in pending_outbound_htlcs. iter_mut ( ) {
0 commit comments