@@ -406,7 +406,12 @@ pub(crate) const FUNDING_CONF_DEADLINE_BLOCKS: u32 = 2016;
406
406
/// size 2. However, if the number of concurrent update_add_htlc is higher, this still
407
407
/// leads to a channel force-close. Ultimately, this is an issue coming from the
408
408
/// design of LN state machines, allowing asynchronous updates.
409
- const CONCURRENT_INBOUND_HTLC_FEE_BUFFER : u32 = 2 ;
409
+ pub ( crate ) const CONCURRENT_INBOUND_HTLC_FEE_BUFFER : u32 = 2 ;
410
+
411
+ /// When a channel is opened, we check that the funding amount is enough to pay for relevant
412
+ /// commitment transaction fees, with at least this many HTLCs present on the commitment
413
+ /// transaction (not counting the value of the HTLCs themselves).
414
+ pub ( crate ) const MIN_AFFORDABLE_HTLC_COUNT : usize = 4 ;
410
415
411
416
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
412
417
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
@@ -712,6 +717,12 @@ impl<Signer: Sign> Channel<Signer> {
712
717
713
718
let feerate = fee_estimator. get_est_sat_per_1000_weight ( ConfirmationTarget :: Normal ) ;
714
719
720
+ let value_to_self_msat = channel_value_satoshis * 1000 - push_msat;
721
+ let commitment_tx_fee = Self :: commit_tx_fee_msat ( feerate, MIN_AFFORDABLE_HTLC_COUNT ) ;
722
+ if value_to_self_msat < commitment_tx_fee {
723
+ return Err ( APIError :: APIMisuseError { err : format ! ( "Funding amount ({}) can't even pay fee for initial commitment transaction fee of {}." , value_to_self_msat / 1000 , commitment_tx_fee / 1000 ) } ) ;
724
+ }
725
+
715
726
let mut secp_ctx = Secp256k1 :: new ( ) ;
716
727
secp_ctx. seeded_randomize ( & keys_provider. get_secure_random_bytes ( ) ) ;
717
728
@@ -742,7 +753,7 @@ impl<Signer: Sign> Channel<Signer> {
742
753
743
754
cur_holder_commitment_transaction_number : INITIAL_COMMITMENT_NUMBER ,
744
755
cur_counterparty_commitment_transaction_number : INITIAL_COMMITMENT_NUMBER ,
745
- value_to_self_msat : channel_value_satoshis * 1000 - push_msat ,
756
+ value_to_self_msat,
746
757
747
758
pending_inbound_htlcs : Vec :: new ( ) ,
748
759
pending_outbound_htlcs : Vec :: new ( ) ,
@@ -957,8 +968,6 @@ impl<Signer: Sign> Channel<Signer> {
957
968
// we either accept their preference or the preferences match
958
969
local_config. announced_channel = announce;
959
970
960
- let background_feerate = fee_estimator. get_est_sat_per_1000_weight ( ConfirmationTarget :: Background ) ;
961
-
962
971
let holder_selected_channel_reserve_satoshis = Channel :: < Signer > :: get_holder_selected_channel_reserve_satoshis ( msg. funding_satoshis ) ;
963
972
if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
964
973
return Err ( ChannelError :: Close ( format ! ( "Suitable channel reserve not found. remote_channel_reserve was ({}). dust_limit_satoshis is ({})." , holder_selected_channel_reserve_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS ) ) ) ;
@@ -971,17 +980,18 @@ impl<Signer: Sign> Channel<Signer> {
971
980
}
972
981
973
982
// check if the funder's amount for the initial commitment tx is sufficient
974
- // for full fee payment
983
+ // for full fee payment plus a few HTLCs to ensure the channel will be useful.
975
984
let funders_amount_msat = msg. funding_satoshis * 1000 - msg. push_msat ;
976
- let lower_limit = background_feerate as u64 * COMMITMENT_TX_BASE_WEIGHT ;
977
- if funders_amount_msat < lower_limit {
978
- return Err ( ChannelError :: Close ( format ! ( "Insufficient funding amount ({}) for initial commitment. Must be at least {} " , funders_amount_msat, lower_limit ) ) ) ;
985
+ let commitment_tx_fee = Self :: commit_tx_fee_msat ( msg . feerate_per_kw , MIN_AFFORDABLE_HTLC_COUNT ) / 1000 ;
986
+ if funders_amount_msat / 1000 < commitment_tx_fee {
987
+ return Err ( ChannelError :: Close ( format ! ( "Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats. " , funders_amount_msat / 1000 , commitment_tx_fee ) ) ) ;
979
988
}
980
989
981
- let to_local_msat = msg. push_msat ;
982
- let to_remote_msat = funders_amount_msat - background_feerate as u64 * COMMITMENT_TX_BASE_WEIGHT ;
983
- if to_local_msat <= msg. channel_reserve_satoshis * 1000 && to_remote_msat <= holder_selected_channel_reserve_satoshis * 1000 {
984
- return Err ( ChannelError :: Close ( "Insufficient funding amount for initial commitment" . to_owned ( ) ) ) ;
990
+ let to_remote_satoshis = funders_amount_msat / 1000 - commitment_tx_fee;
991
+ // While it's reasonable for us to not meet the channel reserve initially (if they don't
992
+ // want to push much to us), our counterparty should always have more than our reserve.
993
+ if to_remote_satoshis < holder_selected_channel_reserve_satoshis {
994
+ return Err ( ChannelError :: Close ( "Insufficient funding amount for initial reserve" . to_owned ( ) ) ) ;
985
995
}
986
996
987
997
let counterparty_shutdown_scriptpubkey = if their_features. supports_upfront_shutdown_script ( ) {
@@ -2115,10 +2125,10 @@ impl<Signer: Sign> Channel<Signer> {
2115
2125
2116
2126
// Get the fee cost in MSATS of a commitment tx with a given number of HTLC outputs.
2117
2127
// Note that num_htlcs should not include dust HTLCs.
2118
- fn commit_tx_fee_msat ( & self , num_htlcs : usize ) -> u64 {
2128
+ fn commit_tx_fee_msat ( feerate_per_kw : u32 , num_htlcs : usize ) -> u64 {
2119
2129
// Note that we need to divide before multiplying to round properly,
2120
2130
// since the lowest denomination of bitcoin on-chain is the satoshi.
2121
- ( COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) * self . feerate_per_kw as u64 / 1000 * 1000
2131
+ ( COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) * feerate_per_kw as u64 / 1000 * 1000
2122
2132
}
2123
2133
2124
2134
// Get the fee cost in SATS of a commitment tx with a given number of HTLC outputs.
@@ -2192,12 +2202,12 @@ impl<Signer: Sign> Channel<Signer> {
2192
2202
}
2193
2203
2194
2204
let num_htlcs = included_htlcs + addl_htlcs;
2195
- let res = self . commit_tx_fee_msat ( num_htlcs) ;
2205
+ let res = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs) ;
2196
2206
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
2197
2207
{
2198
2208
let mut fee = res;
2199
2209
if fee_spike_buffer_htlc. is_some ( ) {
2200
- fee = self . commit_tx_fee_msat ( num_htlcs - 1 ) ;
2210
+ fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs - 1 ) ;
2201
2211
}
2202
2212
let total_pending_htlcs = self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( )
2203
2213
+ self . holding_cell_htlc_updates . len ( ) ;
@@ -2270,12 +2280,12 @@ impl<Signer: Sign> Channel<Signer> {
2270
2280
}
2271
2281
2272
2282
let num_htlcs = included_htlcs + addl_htlcs;
2273
- let res = self . commit_tx_fee_msat ( num_htlcs) ;
2283
+ let res = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs) ;
2274
2284
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
2275
2285
{
2276
2286
let mut fee = res;
2277
2287
if fee_spike_buffer_htlc. is_some ( ) {
2278
- fee = self . commit_tx_fee_msat ( num_htlcs - 1 ) ;
2288
+ fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs - 1 ) ;
2279
2289
}
2280
2290
let total_pending_htlcs = self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( ) ;
2281
2291
let commitment_tx_info = CommitmentTxInfoCached {
@@ -4902,7 +4912,7 @@ impl<Signer: Sign> Channel<Signer> {
4902
4912
&& info. next_holder_htlc_id == self . next_holder_htlc_id
4903
4913
&& info. next_counterparty_htlc_id == self . next_counterparty_htlc_id
4904
4914
&& info. feerate == self . feerate_per_kw {
4905
- let actual_fee = self . commit_tx_fee_msat ( commitment_stats. num_nondust_htlcs ) ;
4915
+ let actual_fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , commitment_stats. num_nondust_htlcs ) ;
4906
4916
assert_eq ! ( actual_fee, info. fee) ;
4907
4917
}
4908
4918
}
@@ -5932,13 +5942,13 @@ mod tests {
5932
5942
// the dust limit check.
5933
5943
let htlc_candidate = HTLCCandidate :: new ( htlc_amount_msat, HTLCInitiator :: LocalOffered ) ;
5934
5944
let local_commit_tx_fee = node_a_chan. next_local_commit_tx_fee_msat ( htlc_candidate, None ) ;
5935
- let local_commit_fee_0_htlcs = node_a_chan . commit_tx_fee_msat ( 0 ) ;
5945
+ let local_commit_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( node_a_chan . feerate_per_kw , 0 ) ;
5936
5946
assert_eq ! ( local_commit_tx_fee, local_commit_fee_0_htlcs) ;
5937
5947
5938
5948
// Finally, make sure that when Node A calculates the remote's commitment transaction fees, all
5939
5949
// of the HTLCs are seen to be above the dust limit.
5940
5950
node_a_chan. channel_transaction_parameters . is_outbound_from_holder = false ;
5941
- let remote_commit_fee_3_htlcs = node_a_chan . commit_tx_fee_msat ( 3 ) ;
5951
+ let remote_commit_fee_3_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( node_a_chan . feerate_per_kw , 3 ) ;
5942
5952
let htlc_candidate = HTLCCandidate :: new ( htlc_amount_msat, HTLCInitiator :: LocalOffered ) ;
5943
5953
let remote_commit_tx_fee = node_a_chan. next_remote_commit_tx_fee_msat ( htlc_candidate, None ) ;
5944
5954
assert_eq ! ( remote_commit_tx_fee, remote_commit_fee_3_htlcs) ;
@@ -5960,8 +5970,8 @@ mod tests {
5960
5970
let config = UserConfig :: default ( ) ;
5961
5971
let mut chan = Channel :: < EnforcingSigner > :: new_outbound ( & & fee_est, & & keys_provider, node_id, & InitFeatures :: known ( ) , 10000000 , 100000 , 42 , & config, 0 ) . unwrap ( ) ;
5962
5972
5963
- let commitment_tx_fee_0_htlcs = chan . commit_tx_fee_msat ( 0 ) ;
5964
- let commitment_tx_fee_1_htlc = chan . commit_tx_fee_msat ( 1 ) ;
5973
+ let commitment_tx_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan . feerate_per_kw , 0 ) ;
5974
+ let commitment_tx_fee_1_htlc = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan . feerate_per_kw , 1 ) ;
5965
5975
5966
5976
// If HTLC_SUCCESS_TX_WEIGHT and HTLC_TIMEOUT_TX_WEIGHT were swapped: then this HTLC would be
5967
5977
// counted as dust when it shouldn't be.
0 commit comments