@@ -622,10 +622,12 @@ struct CommitmentTxInfoCached {
622
622
623
623
pub const OUR_MAX_HTLCS : u16 = 50 ; //TODO
624
624
625
- #[ cfg( not( test) ) ]
626
- const COMMITMENT_TX_BASE_WEIGHT : u64 = 724 ;
627
- #[ cfg( test) ]
628
- pub const COMMITMENT_TX_BASE_WEIGHT : u64 = 724 ;
625
+ pub ( crate ) fn commitment_tx_base_weight ( opt_anchors : bool ) -> u64 {
626
+ const COMMITMENT_TX_BASE_WEIGHT : u64 = 724 ;
627
+ const COMMITMENT_TX_BASE_ANCHOR_WEIGHT : u64 = 1124 ;
628
+ if opt_anchors { COMMITMENT_TX_BASE_ANCHOR_WEIGHT } else { COMMITMENT_TX_BASE_WEIGHT }
629
+ }
630
+
629
631
#[ cfg( not( test) ) ]
630
632
const COMMITMENT_TX_WEIGHT_PER_HTLC : u64 = 172 ;
631
633
#[ cfg( test) ]
@@ -717,6 +719,8 @@ impl<Signer: Sign> Channel<Signer> {
717
719
where K :: Target : KeysInterface < Signer = Signer > ,
718
720
F :: Target : FeeEstimator ,
719
721
{
722
+ let opt_anchors = false ; // TODO - should be based on features
723
+
720
724
let holder_selected_contest_delay = config. own_channel_config . our_to_self_delay ;
721
725
let holder_signer = keys_provider. get_channel_signer ( false , channel_value_satoshis) ;
722
726
let pubkeys = holder_signer. pubkeys ( ) . clone ( ) ;
@@ -739,7 +743,7 @@ impl<Signer: Sign> Channel<Signer> {
739
743
let feerate = fee_estimator. get_est_sat_per_1000_weight ( ConfirmationTarget :: Normal ) ;
740
744
741
745
let value_to_self_msat = channel_value_satoshis * 1000 - push_msat;
742
- let commitment_tx_fee = Self :: commit_tx_fee_msat ( feerate, MIN_AFFORDABLE_HTLC_COUNT ) ;
746
+ let commitment_tx_fee = Self :: commit_tx_fee_msat ( feerate, MIN_AFFORDABLE_HTLC_COUNT , opt_anchors ) ;
743
747
if value_to_self_msat < commitment_tx_fee {
744
748
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 ) } ) ;
745
749
}
@@ -829,7 +833,7 @@ impl<Signer: Sign> Channel<Signer> {
829
833
is_outbound_from_holder : true ,
830
834
counterparty_parameters : None ,
831
835
funding_outpoint : None ,
832
- opt_anchors : None ,
836
+ opt_anchors : if opt_anchors { Some ( ( ) ) } else { None } ,
833
837
} ,
834
838
funding_transaction : None ,
835
839
@@ -896,6 +900,8 @@ impl<Signer: Sign> Channel<Signer> {
896
900
F :: Target : FeeEstimator ,
897
901
L :: Target : Logger ,
898
902
{
903
+ let opt_anchors = false ; // TODO - should be based on features
904
+
899
905
// First check the channel type is known, failing before we do anything else if we don't
900
906
// support this channel type.
901
907
let channel_type = if let Some ( channel_type) = & msg. channel_type {
@@ -1008,7 +1014,7 @@ impl<Signer: Sign> Channel<Signer> {
1008
1014
// check if the funder's amount for the initial commitment tx is sufficient
1009
1015
// for full fee payment plus a few HTLCs to ensure the channel will be useful.
1010
1016
let funders_amount_msat = msg. funding_satoshis * 1000 - msg. push_msat ;
1011
- let commitment_tx_fee = Self :: commit_tx_fee_msat ( msg. feerate_per_kw , MIN_AFFORDABLE_HTLC_COUNT ) / 1000 ;
1017
+ let commitment_tx_fee = Self :: commit_tx_fee_msat ( msg. feerate_per_kw , MIN_AFFORDABLE_HTLC_COUNT , opt_anchors ) / 1000 ;
1012
1018
if funders_amount_msat / 1000 < commitment_tx_fee {
1013
1019
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) ) ) ;
1014
1020
}
@@ -1128,7 +1134,7 @@ impl<Signer: Sign> Channel<Signer> {
1128
1134
pubkeys : counterparty_pubkeys,
1129
1135
} ) ,
1130
1136
funding_outpoint : None ,
1131
- opt_anchors : None
1137
+ opt_anchors : if opt_anchors { Some ( ( ) ) } else { None } ,
1132
1138
} ,
1133
1139
funding_transaction : None ,
1134
1140
@@ -1320,7 +1326,7 @@ impl<Signer: Sign> Channel<Signer> {
1320
1326
broadcaster_max_commitment_tx_output. 1 = cmp:: max ( broadcaster_max_commitment_tx_output. 1 , value_to_remote_msat as u64 ) ;
1321
1327
}
1322
1328
1323
- let total_fee_sat = Channel :: < Signer > :: commit_tx_fee_sat ( feerate_per_kw, included_non_dust_htlcs. len ( ) ) ;
1329
+ let total_fee_sat = Channel :: < Signer > :: commit_tx_fee_sat ( feerate_per_kw, included_non_dust_htlcs. len ( ) , self . channel_transaction_parameters . opt_anchors . is_some ( ) ) ;
1324
1330
let ( value_to_self, value_to_remote) = if self . is_outbound ( ) {
1325
1331
( value_to_self_msat / 1000 - total_fee_sat as i64 , value_to_remote_msat / 1000 )
1326
1332
} else {
@@ -2158,17 +2164,17 @@ impl<Signer: Sign> Channel<Signer> {
2158
2164
2159
2165
// Get the fee cost in MSATS of a commitment tx with a given number of HTLC outputs.
2160
2166
// Note that num_htlcs should not include dust HTLCs.
2161
- fn commit_tx_fee_msat ( feerate_per_kw : u32 , num_htlcs : usize ) -> u64 {
2167
+ fn commit_tx_fee_msat ( feerate_per_kw : u32 , num_htlcs : usize , opt_anchors : bool ) -> u64 {
2162
2168
// Note that we need to divide before multiplying to round properly,
2163
2169
// since the lowest denomination of bitcoin on-chain is the satoshi.
2164
- ( COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) * feerate_per_kw as u64 / 1000 * 1000
2170
+ ( commitment_tx_base_weight ( opt_anchors ) + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) * feerate_per_kw as u64 / 1000 * 1000
2165
2171
}
2166
2172
2167
2173
// Get the fee cost in SATS of a commitment tx with a given number of HTLC outputs.
2168
2174
// Note that num_htlcs should not include dust HTLCs.
2169
2175
#[ inline]
2170
- fn commit_tx_fee_sat ( feerate_per_kw : u32 , num_htlcs : usize ) -> u64 {
2171
- feerate_per_kw as u64 * ( COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000
2176
+ fn commit_tx_fee_sat ( feerate_per_kw : u32 , num_htlcs : usize , opt_anchors : bool ) -> u64 {
2177
+ feerate_per_kw as u64 * ( commitment_tx_base_weight ( opt_anchors ) + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000
2172
2178
}
2173
2179
2174
2180
// Get the commitment tx fee for the local's (i.e. our) next commitment transaction based on the
@@ -2235,12 +2241,12 @@ impl<Signer: Sign> Channel<Signer> {
2235
2241
}
2236
2242
2237
2243
let num_htlcs = included_htlcs + addl_htlcs;
2238
- let res = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs) ;
2244
+ let res = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs, self . opt_anchors ( ) ) ;
2239
2245
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
2240
2246
{
2241
2247
let mut fee = res;
2242
2248
if fee_spike_buffer_htlc. is_some ( ) {
2243
- fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs - 1 ) ;
2249
+ fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs - 1 , self . opt_anchors ( ) ) ;
2244
2250
}
2245
2251
let total_pending_htlcs = self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( )
2246
2252
+ self . holding_cell_htlc_updates . len ( ) ;
@@ -2313,12 +2319,12 @@ impl<Signer: Sign> Channel<Signer> {
2313
2319
}
2314
2320
2315
2321
let num_htlcs = included_htlcs + addl_htlcs;
2316
- let res = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs) ;
2322
+ let res = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs, self . opt_anchors ( ) ) ;
2317
2323
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
2318
2324
{
2319
2325
let mut fee = res;
2320
2326
if fee_spike_buffer_htlc. is_some ( ) {
2321
- fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs - 1 ) ;
2327
+ fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , num_htlcs - 1 , self . opt_anchors ( ) ) ;
2322
2328
}
2323
2329
let total_pending_htlcs = self . pending_inbound_htlcs . len ( ) + self . pending_outbound_htlcs . len ( ) ;
2324
2330
let commitment_tx_info = CommitmentTxInfoCached {
@@ -3151,7 +3157,7 @@ impl<Signer: Sign> Channel<Signer> {
3151
3157
let outbound_stats = self . get_outbound_pending_htlc_stats ( Some ( feerate_per_kw) ) ;
3152
3158
let keys = if let Ok ( keys) = self . build_holder_transaction_keys ( self . cur_holder_commitment_transaction_number ) { keys } else { return None ; } ;
3153
3159
let commitment_stats = self . build_commitment_transaction ( self . cur_holder_commitment_transaction_number , & keys, true , true , logger) ;
3154
- let buffer_fee_msat = Channel :: < Signer > :: commit_tx_fee_sat ( feerate_per_kw, commitment_stats. num_nondust_htlcs + outbound_stats. on_holder_tx_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize ) * 1000 ;
3160
+ let buffer_fee_msat = Channel :: < Signer > :: commit_tx_fee_sat ( feerate_per_kw, commitment_stats. num_nondust_htlcs + outbound_stats. on_holder_tx_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize , self . opt_anchors ( ) ) * 1000 ;
3155
3161
let holder_balance_msat = commitment_stats. local_balance_msat - outbound_stats. holding_cell_msat ;
3156
3162
if holder_balance_msat < buffer_fee_msat + self . counterparty_selected_channel_reserve_satoshis . unwrap ( ) * 1000 {
3157
3163
//TODO: auto-close after a number of failures?
@@ -4944,7 +4950,7 @@ impl<Signer: Sign> Channel<Signer> {
4944
4950
&& info. next_holder_htlc_id == self . next_holder_htlc_id
4945
4951
&& info. next_counterparty_htlc_id == self . next_counterparty_htlc_id
4946
4952
&& info. feerate == self . feerate_per_kw {
4947
- let actual_fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , commitment_stats. num_nondust_htlcs ) ;
4953
+ let actual_fee = Self :: commit_tx_fee_msat ( self . feerate_per_kw , commitment_stats. num_nondust_htlcs , self . opt_anchors ( ) ) ;
4948
4954
assert_eq ! ( actual_fee, info. fee) ;
4949
4955
}
4950
4956
}
@@ -5993,13 +5999,13 @@ mod tests {
5993
5999
// the dust limit check.
5994
6000
let htlc_candidate = HTLCCandidate :: new ( htlc_amount_msat, HTLCInitiator :: LocalOffered ) ;
5995
6001
let local_commit_tx_fee = node_a_chan. next_local_commit_tx_fee_msat ( htlc_candidate, None ) ;
5996
- let local_commit_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( node_a_chan. feerate_per_kw , 0 ) ;
6002
+ let local_commit_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( node_a_chan. feerate_per_kw , 0 , node_a_chan . opt_anchors ( ) ) ;
5997
6003
assert_eq ! ( local_commit_tx_fee, local_commit_fee_0_htlcs) ;
5998
6004
5999
6005
// Finally, make sure that when Node A calculates the remote's commitment transaction fees, all
6000
6006
// of the HTLCs are seen to be above the dust limit.
6001
6007
node_a_chan. channel_transaction_parameters . is_outbound_from_holder = false ;
6002
- let remote_commit_fee_3_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( node_a_chan. feerate_per_kw , 3 ) ;
6008
+ let remote_commit_fee_3_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( node_a_chan. feerate_per_kw , 3 , node_a_chan . opt_anchors ( ) ) ;
6003
6009
let htlc_candidate = HTLCCandidate :: new ( htlc_amount_msat, HTLCInitiator :: LocalOffered ) ;
6004
6010
let remote_commit_tx_fee = node_a_chan. next_remote_commit_tx_fee_msat ( htlc_candidate, None ) ;
6005
6011
assert_eq ! ( remote_commit_tx_fee, remote_commit_fee_3_htlcs) ;
@@ -6021,8 +6027,8 @@ mod tests {
6021
6027
let config = UserConfig :: default ( ) ;
6022
6028
let mut chan = Channel :: < EnforcingSigner > :: new_outbound ( & & fee_est, & & keys_provider, node_id, & InitFeatures :: known ( ) , 10000000 , 100000 , 42 , & config, 0 ) . unwrap ( ) ;
6023
6029
6024
- let commitment_tx_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan. feerate_per_kw , 0 ) ;
6025
- let commitment_tx_fee_1_htlc = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan. feerate_per_kw , 1 ) ;
6030
+ let commitment_tx_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan. feerate_per_kw , 0 , chan . opt_anchors ( ) ) ;
6031
+ let commitment_tx_fee_1_htlc = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan. feerate_per_kw , 1 , chan . opt_anchors ( ) ) ;
6026
6032
6027
6033
// If HTLC_SUCCESS_TX_WEIGHT and HTLC_TIMEOUT_TX_WEIGHT were swapped: then this HTLC would be
6028
6034
// counted as dust when it shouldn't be.
0 commit comments