Skip to content

Commit 557a830

Browse files
committed
Convert HTLC_{SUCCESS,TIMEOUT}_TX_WEIGHT to anchor-aware functions
1 parent 9566795 commit 557a830

File tree

3 files changed

+28
-27
lines changed

3 files changed

+28
-27
lines changed

lightning/src/ln/chan_utils.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,18 @@ use chain;
4242

4343
pub(crate) const MAX_HTLCS: u16 = 483;
4444

45-
pub(super) const HTLC_SUCCESS_TX_WEIGHT: u64 = 703;
46-
pub(super) const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663;
47-
4845
/// Gets the weight for an HTLC-Success transaction.
4946
#[inline]
5047
pub fn htlc_success_tx_weight(opt_anchors: bool) -> u64 {
48+
const HTLC_SUCCESS_TX_WEIGHT: u64 = 703;
5149
const HTLC_SUCCESS_ANCHOR_TX_WEIGHT: u64 = 706;
5250
if opt_anchors { HTLC_SUCCESS_ANCHOR_TX_WEIGHT } else { HTLC_SUCCESS_TX_WEIGHT }
5351
}
5452

5553
/// Gets the weight for an HTLC-Timeout transaction.
5654
#[inline]
5755
pub fn htlc_timeout_tx_weight(opt_anchors: bool) -> u64 {
56+
const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663;
5857
const HTLC_TIMEOUT_ANCHOR_TX_WEIGHT: u64 = 666;
5958
if opt_anchors { HTLC_TIMEOUT_ANCHOR_TX_WEIGHT } else { HTLC_TIMEOUT_TX_WEIGHT }
6059
}

lightning/src/ln/channel.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use ln::msgs;
2828
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
2929
use ln::script::{self, ShutdownScript};
3030
use ln::channelmanager::{CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
31-
use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction};
31+
use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, htlc_success_tx_weight, htlc_timeout_tx_weight, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction};
3232
use ln::chan_utils;
3333
use chain::BestBlock;
3434
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
@@ -1227,7 +1227,7 @@ impl<Signer: Sign> Channel<Signer> {
12271227
($htlc: expr, $outbound: expr, $source: expr, $state_name: expr) => {
12281228
if $outbound == local { // "offered HTLC output"
12291229
let htlc_in_tx = get_htlc_in_commitment!($htlc, true);
1230-
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) {
1230+
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) {
12311231
log_trace!(logger, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, log_bytes!($htlc.payment_hash.0), $htlc.amount_msat);
12321232
included_non_dust_htlcs.push((htlc_in_tx, $source));
12331233
} else {
@@ -1236,7 +1236,7 @@ impl<Signer: Sign> Channel<Signer> {
12361236
}
12371237
} else {
12381238
let htlc_in_tx = get_htlc_in_commitment!($htlc, false);
1239-
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) {
1239+
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) {
12401240
log_trace!(logger, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, log_bytes!($htlc.payment_hash.0), $htlc.amount_msat);
12411241
included_non_dust_htlcs.push((htlc_in_tx, $source));
12421242
} else {
@@ -2074,8 +2074,8 @@ impl<Signer: Sign> Channel<Signer> {
20742074
on_holder_tx_holding_cell_htlcs_count: 0,
20752075
};
20762076

2077-
let counterparty_dust_limit_timeout_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2078-
let holder_dust_limit_success_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2077+
let counterparty_dust_limit_timeout_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) + self.counterparty_dust_limit_satoshis;
2078+
let holder_dust_limit_success_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) + self.holder_dust_limit_satoshis;
20792079
for ref htlc in self.pending_inbound_htlcs.iter() {
20802080
stats.pending_htlcs_value_msat += htlc.amount_msat;
20812081
if htlc.amount_msat / 1000 < counterparty_dust_limit_timeout_sat {
@@ -2099,8 +2099,8 @@ impl<Signer: Sign> Channel<Signer> {
20992099
on_holder_tx_holding_cell_htlcs_count: 0,
21002100
};
21012101

2102-
let counterparty_dust_limit_success_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2103-
let holder_dust_limit_timeout_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2102+
let counterparty_dust_limit_success_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) + self.counterparty_dust_limit_satoshis;
2103+
let holder_dust_limit_timeout_sat = (self.get_dust_buffer_feerate(outbound_feerate_update) as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) + self.holder_dust_limit_satoshis;
21042104
for ref htlc in self.pending_outbound_htlcs.iter() {
21052105
stats.pending_htlcs_value_msat += htlc.amount_msat;
21062106
if htlc.amount_msat / 1000 < counterparty_dust_limit_success_sat {
@@ -2184,8 +2184,8 @@ impl<Signer: Sign> Channel<Signer> {
21842184
fn next_local_commit_tx_fee_msat(&self, htlc: HTLCCandidate, fee_spike_buffer_htlc: Option<()>) -> u64 {
21852185
assert!(self.is_outbound());
21862186

2187-
let real_dust_limit_success_sat = (self.feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2188-
let real_dust_limit_timeout_sat = (self.feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2187+
let real_dust_limit_success_sat = (self.feerate_per_kw as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) + self.holder_dust_limit_satoshis;
2188+
let real_dust_limit_timeout_sat = (self.feerate_per_kw as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) + self.holder_dust_limit_satoshis;
21892189

21902190
let mut addl_htlcs = 0;
21912191
if fee_spike_buffer_htlc.is_some() { addl_htlcs += 1; }
@@ -2275,8 +2275,8 @@ impl<Signer: Sign> Channel<Signer> {
22752275
fn next_remote_commit_tx_fee_msat(&self, htlc: HTLCCandidate, fee_spike_buffer_htlc: Option<()>) -> u64 {
22762276
assert!(!self.is_outbound());
22772277

2278-
let real_dust_limit_success_sat = (self.feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2279-
let real_dust_limit_timeout_sat = (self.feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2278+
let real_dust_limit_success_sat = (self.feerate_per_kw as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) + self.counterparty_dust_limit_satoshis;
2279+
let real_dust_limit_timeout_sat = (self.feerate_per_kw as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) + self.counterparty_dust_limit_satoshis;
22802280

22812281
let mut addl_htlcs = 0;
22822282
if fee_spike_buffer_htlc.is_some() { addl_htlcs += 1; }
@@ -2399,7 +2399,7 @@ impl<Signer: Sign> Channel<Signer> {
23992399
}
24002400
}
24012401

2402-
let exposure_dust_limit_timeout_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2402+
let exposure_dust_limit_timeout_sats = (self.get_dust_buffer_feerate(None) as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) + self.counterparty_dust_limit_satoshis;
24032403
if msg.amount_msat / 1000 < exposure_dust_limit_timeout_sats {
24042404
let on_counterparty_tx_dust_htlc_exposure_msat = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat + msg.amount_msat;
24052405
if on_counterparty_tx_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -2409,7 +2409,7 @@ impl<Signer: Sign> Channel<Signer> {
24092409
}
24102410
}
24112411

2412-
let exposure_dust_limit_success_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2412+
let exposure_dust_limit_success_sats = (self.get_dust_buffer_feerate(None) as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) + self.holder_dust_limit_satoshis;
24132413
if msg.amount_msat / 1000 < exposure_dust_limit_success_sats {
24142414
let on_holder_tx_dust_htlc_exposure_msat = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat + msg.amount_msat;
24152415
if on_holder_tx_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -4766,7 +4766,7 @@ impl<Signer: Sign> Channel<Signer> {
47664766
}
47674767
}
47684768

4769-
let exposure_dust_limit_success_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
4769+
let exposure_dust_limit_success_sats = (self.get_dust_buffer_feerate(None) as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) + self.counterparty_dust_limit_satoshis;
47704770
if amount_msat / 1000 < exposure_dust_limit_success_sats {
47714771
let on_counterparty_dust_htlc_exposure_msat = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat + amount_msat;
47724772
if on_counterparty_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -4775,7 +4775,7 @@ impl<Signer: Sign> Channel<Signer> {
47754775
}
47764776
}
47774777

4778-
let exposure_dust_limit_timeout_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
4778+
let exposure_dust_limit_timeout_sats = (self.get_dust_buffer_feerate(None) as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) + self.holder_dust_limit_satoshis;
47794779
if amount_msat / 1000 < exposure_dust_limit_timeout_sats {
47804780
let on_holder_dust_htlc_exposure_msat = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat + amount_msat;
47814781
if on_holder_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -5820,7 +5820,7 @@ mod tests {
58205820
use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate};
58215821
use ln::script::ShutdownScript;
58225822
use ln::chan_utils;
5823-
use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT};
5823+
use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters, htlc_success_tx_weight, htlc_timeout_tx_weight};
58245824
use chain::BestBlock;
58255825
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
58265826
use chain::keysinterface::{InMemorySigner, KeyMaterial, KeysInterface, BaseSign};
@@ -6032,27 +6032,27 @@ mod tests {
60326032

60336033
// If HTLC_SUCCESS_TX_WEIGHT and HTLC_TIMEOUT_TX_WEIGHT were swapped: then this HTLC would be
60346034
// counted as dust when it shouldn't be.
6035-
let htlc_amt_above_timeout = ((253 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + chan.holder_dust_limit_satoshis + 1) * 1000;
6035+
let htlc_amt_above_timeout = ((253 * htlc_timeout_tx_weight(chan.opt_anchors()) / 1000) + chan.holder_dust_limit_satoshis + 1) * 1000;
60366036
let htlc_candidate = HTLCCandidate::new(htlc_amt_above_timeout, HTLCInitiator::LocalOffered);
60376037
let commitment_tx_fee = chan.next_local_commit_tx_fee_msat(htlc_candidate, None);
60386038
assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);
60396039

60406040
// If swapped: this HTLC would be counted as non-dust when it shouldn't be.
6041-
let dust_htlc_amt_below_success = ((253 * HTLC_SUCCESS_TX_WEIGHT / 1000) + chan.holder_dust_limit_satoshis - 1) * 1000;
6041+
let dust_htlc_amt_below_success = ((253 * htlc_success_tx_weight(chan.opt_anchors()) / 1000) + chan.holder_dust_limit_satoshis - 1) * 1000;
60426042
let htlc_candidate = HTLCCandidate::new(dust_htlc_amt_below_success, HTLCInitiator::RemoteOffered);
60436043
let commitment_tx_fee = chan.next_local_commit_tx_fee_msat(htlc_candidate, None);
60446044
assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
60456045

60466046
chan.channel_transaction_parameters.is_outbound_from_holder = false;
60476047

60486048
// If swapped: this HTLC would be counted as non-dust when it shouldn't be.
6049-
let dust_htlc_amt_above_timeout = ((253 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + chan.counterparty_dust_limit_satoshis + 1) * 1000;
6049+
let dust_htlc_amt_above_timeout = ((253 * htlc_timeout_tx_weight(chan.opt_anchors()) / 1000) + chan.counterparty_dust_limit_satoshis + 1) * 1000;
60506050
let htlc_candidate = HTLCCandidate::new(dust_htlc_amt_above_timeout, HTLCInitiator::LocalOffered);
60516051
let commitment_tx_fee = chan.next_remote_commit_tx_fee_msat(htlc_candidate, None);
60526052
assert_eq!(commitment_tx_fee, commitment_tx_fee_0_htlcs);
60536053

60546054
// If swapped: this HTLC would be counted as dust when it shouldn't be.
6055-
let htlc_amt_below_success = ((253 * HTLC_SUCCESS_TX_WEIGHT / 1000) + chan.counterparty_dust_limit_satoshis - 1) * 1000;
6055+
let htlc_amt_below_success = ((253 * htlc_success_tx_weight(chan.opt_anchors()) / 1000) + chan.counterparty_dust_limit_satoshis - 1) * 1000;
60566056
let htlc_candidate = HTLCCandidate::new(htlc_amt_below_success, HTLCInitiator::RemoteOffered);
60576057
let commitment_tx_fee = chan.next_remote_commit_tx_fee_msat(htlc_candidate, None);
60586058
assert_eq!(commitment_tx_fee, commitment_tx_fee_1_htlc);

lightning/src/ln/functional_tests.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONC
2222
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, PAYMENT_EXPIRY_BLOCKS };
2323
use ln::channel::{Channel, ChannelError};
2424
use ln::{chan_utils, onion_utils};
25-
use ln::chan_utils::{HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, HTLCOutputInCommitment};
25+
use ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight, HTLCOutputInCommitment};
2626
use routing::network_graph::RoutingFees;
2727
use routing::router::{Payee, Route, RouteHop, RouteHint, RouteHintHop, RouteParameters, find_route, get_route};
2828
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
@@ -1608,7 +1608,7 @@ fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() {
16081608
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, push_amt, InitFeatures::known(), InitFeatures::known());
16091609

16101610
let dust_amt = crate::ln::channel::MIN_CHAN_DUST_LIMIT_SATOSHIS * 1000
1611-
+ feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 * 1000 - 1;
1611+
+ feerate_per_kw as u64 * htlc_success_tx_weight(opt_anchors) / 1000 * 1000 - 1;
16121612
// In the previous code, routing this dust payment would cause nodes[0] to perceive a channel
16131613
// reserve violation even though it's a dust HTLC and therefore shouldn't count towards the
16141614
// commitment transaction fee.
@@ -9383,6 +9383,8 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
93839383
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
93849384
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel);
93859385

9386+
let opt_anchors = false;
9387+
93869388
let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 1_000_000, 42);
93879389

93889390
if on_holder_tx {
@@ -9407,10 +9409,10 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
94079409
let chan = chan_lock.by_id.get(&channel_id).unwrap();
94089410
chan.get_dust_buffer_feerate(None) as u64
94099411
};
9410-
let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * HTLC_TIMEOUT_TX_WEIGHT / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
9412+
let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(opt_anchors) / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
94119413
let dust_outbound_htlc_on_holder_tx: u64 = config.channel_options.max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
94129414

9413-
let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * HTLC_SUCCESS_TX_WEIGHT / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
9415+
let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(opt_anchors) / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
94149416
let dust_inbound_htlc_on_holder_tx: u64 = config.channel_options.max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
94159417

94169418
let dust_htlc_on_counterparty_tx: u64 = 25;

0 commit comments

Comments
 (0)