@@ -406,7 +406,12 @@ pub(crate) const FUNDING_CONF_DEADLINE_BLOCKS: u32 = 2016;
406406/// size 2. However, if the number of concurrent update_add_htlc is higher, this still
407407/// leads to a channel force-close. Ultimately, this is an issue coming from the
408408/// 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 ;
410415
411416// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
412417// 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> {
712717
713718 let feerate = fee_estimator. get_est_sat_per_1000_weight ( ConfirmationTarget :: Normal ) ;
714719
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+
715726 let mut secp_ctx = Secp256k1 :: new ( ) ;
716727 secp_ctx. seeded_randomize ( & keys_provider. get_secure_random_bytes ( ) ) ;
717728
@@ -742,7 +753,7 @@ impl<Signer: Sign> Channel<Signer> {
742753
743754 cur_holder_commitment_transaction_number : INITIAL_COMMITMENT_NUMBER ,
744755 cur_counterparty_commitment_transaction_number : INITIAL_COMMITMENT_NUMBER ,
745- value_to_self_msat : channel_value_satoshis * 1000 - push_msat ,
756+ value_to_self_msat,
746757
747758 pending_inbound_htlcs : Vec :: new ( ) ,
748759 pending_outbound_htlcs : Vec :: new ( ) ,
@@ -957,8 +968,6 @@ impl<Signer: Sign> Channel<Signer> {
957968 // we either accept their preference or the preferences match
958969 local_config. announced_channel = announce;
959970
960- let background_feerate = fee_estimator. get_est_sat_per_1000_weight ( ConfirmationTarget :: Background ) ;
961-
962971 let holder_selected_channel_reserve_satoshis = Channel :: < Signer > :: get_holder_selected_channel_reserve_satoshis ( msg. funding_satoshis ) ;
963972 if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
964973 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> {
971980 }
972981
973982 // 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.
975984 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 ) ) ) ;
979988 }
980989
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 ( ) ) ) ;
985995 }
986996
987997 let counterparty_shutdown_scriptpubkey = if their_features. supports_upfront_shutdown_script ( ) {
@@ -2115,10 +2125,10 @@ impl<Signer: Sign> Channel<Signer> {
21152125
21162126 // Get the fee cost in MSATS of a commitment tx with a given number of HTLC outputs.
21172127 // 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 {
21192129 // Note that we need to divide before multiplying to round properly,
21202130 // 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
21222132 }
21232133
21242134 // 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> {
21922202 }
21932203
21942204 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) ;
21962206 #[ cfg( any( test, feature = "fuzztarget" ) ) ]
21972207 {
21982208 let mut fee = res;
21992209 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 ) ;
22012211 }
22022212 let total_pending_htlcs = self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( )
22032213 + self . holding_cell_htlc_updates . len ( ) ;
@@ -2270,12 +2280,12 @@ impl<Signer: Sign> Channel<Signer> {
22702280 }
22712281
22722282 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) ;
22742284 #[ cfg( any( test, feature = "fuzztarget" ) ) ]
22752285 {
22762286 let mut fee = res;
22772287 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 ) ;
22792289 }
22802290 let total_pending_htlcs = self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( ) ;
22812291 let commitment_tx_info = CommitmentTxInfoCached {
@@ -4902,7 +4912,7 @@ impl<Signer: Sign> Channel<Signer> {
49024912 && info. next_holder_htlc_id == self . next_holder_htlc_id
49034913 && info. next_counterparty_htlc_id == self . next_counterparty_htlc_id
49044914 && 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 ) ;
49064916 assert_eq ! ( actual_fee, info. fee) ;
49074917 }
49084918 }
@@ -5932,13 +5942,13 @@ mod tests {
59325942 // the dust limit check.
59335943 let htlc_candidate = HTLCCandidate :: new ( htlc_amount_msat, HTLCInitiator :: LocalOffered ) ;
59345944 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 ) ;
59365946 assert_eq ! ( local_commit_tx_fee, local_commit_fee_0_htlcs) ;
59375947
59385948 // Finally, make sure that when Node A calculates the remote's commitment transaction fees, all
59395949 // of the HTLCs are seen to be above the dust limit.
59405950 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 ) ;
59425952 let htlc_candidate = HTLCCandidate :: new ( htlc_amount_msat, HTLCInitiator :: LocalOffered ) ;
59435953 let remote_commit_tx_fee = node_a_chan. next_remote_commit_tx_fee_msat ( htlc_candidate, None ) ;
59445954 assert_eq ! ( remote_commit_tx_fee, remote_commit_fee_3_htlcs) ;
@@ -5960,8 +5970,8 @@ mod tests {
59605970 let config = UserConfig :: default ( ) ;
59615971 let mut chan = Channel :: < EnforcingSigner > :: new_outbound ( & & fee_est, & & keys_provider, node_id, & InitFeatures :: known ( ) , 10000000 , 100000 , 42 , & config, 0 ) . unwrap ( ) ;
59625972
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 ) ;
59655975
59665976 // If HTLC_SUCCESS_TX_WEIGHT and HTLC_TIMEOUT_TX_WEIGHT were swapped: then this HTLC would be
59675977 // counted as dust when it shouldn't be.
0 commit comments