Skip to content

Commit f6b6880

Browse files
committed
Convert HTLC_{SUCCESS,TIMEOUT}_TX_WEIGHT to anchor-aware functions
1 parent adc7ec4 commit f6b6880

File tree

3 files changed

+28
-27
lines changed

3 files changed

+28
-27
lines changed

lightning/src/ln/chan_utils.rs

+2-3
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

+20-20
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};
@@ -1221,7 +1221,7 @@ impl<Signer: Sign> Channel<Signer> {
12211221
($htlc: expr, $outbound: expr, $source: expr, $state_name: expr) => {
12221222
if $outbound == local { // "offered HTLC output"
12231223
let htlc_in_tx = get_htlc_in_commitment!($htlc, true);
1224-
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) {
1224+
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * htlc_timeout_tx_weight(self.opt_anchors()) / 1000) {
12251225
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);
12261226
included_non_dust_htlcs.push((htlc_in_tx, $source));
12271227
} else {
@@ -1230,7 +1230,7 @@ impl<Signer: Sign> Channel<Signer> {
12301230
}
12311231
} else {
12321232
let htlc_in_tx = get_htlc_in_commitment!($htlc, false);
1233-
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) {
1233+
if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_satoshis + (feerate_per_kw as u64 * htlc_success_tx_weight(self.opt_anchors()) / 1000) {
12341234
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);
12351235
included_non_dust_htlcs.push((htlc_in_tx, $source));
12361236
} else {
@@ -2069,8 +2069,8 @@ impl<Signer: Sign> Channel<Signer> {
20692069
on_holder_tx_holding_cell_htlcs_count: 0,
20702070
};
20712071

2072-
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;
2073-
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;
2072+
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;
2073+
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;
20742074
for ref htlc in self.pending_inbound_htlcs.iter() {
20752075
stats.pending_htlcs_value_msat += htlc.amount_msat;
20762076
if htlc.amount_msat / 1000 < counterparty_dust_limit_timeout_sat {
@@ -2094,8 +2094,8 @@ impl<Signer: Sign> Channel<Signer> {
20942094
on_holder_tx_holding_cell_htlcs_count: 0,
20952095
};
20962096

2097-
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;
2098-
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;
2097+
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;
2098+
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;
20992099
for ref htlc in self.pending_outbound_htlcs.iter() {
21002100
stats.pending_htlcs_value_msat += htlc.amount_msat;
21012101
if htlc.amount_msat / 1000 < counterparty_dust_limit_success_sat {
@@ -2179,8 +2179,8 @@ impl<Signer: Sign> Channel<Signer> {
21792179
fn next_local_commit_tx_fee_msat(&self, htlc: HTLCCandidate, fee_spike_buffer_htlc: Option<()>) -> u64 {
21802180
assert!(self.is_outbound());
21812181

2182-
let real_dust_limit_success_sat = (self.feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2183-
let real_dust_limit_timeout_sat = (self.feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2182+
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;
2183+
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;
21842184

21852185
let mut addl_htlcs = 0;
21862186
if fee_spike_buffer_htlc.is_some() { addl_htlcs += 1; }
@@ -2270,8 +2270,8 @@ impl<Signer: Sign> Channel<Signer> {
22702270
fn next_remote_commit_tx_fee_msat(&self, htlc: HTLCCandidate, fee_spike_buffer_htlc: Option<()>) -> u64 {
22712271
assert!(!self.is_outbound());
22722272

2273-
let real_dust_limit_success_sat = (self.feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2274-
let real_dust_limit_timeout_sat = (self.feerate_per_kw as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2273+
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;
2274+
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;
22752275

22762276
let mut addl_htlcs = 0;
22772277
if fee_spike_buffer_htlc.is_some() { addl_htlcs += 1; }
@@ -2394,7 +2394,7 @@ impl<Signer: Sign> Channel<Signer> {
23942394
}
23952395
}
23962396

2397-
let exposure_dust_limit_timeout_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
2397+
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;
23982398
if msg.amount_msat / 1000 < exposure_dust_limit_timeout_sats {
23992399
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;
24002400
if on_counterparty_tx_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -2404,7 +2404,7 @@ impl<Signer: Sign> Channel<Signer> {
24042404
}
24052405
}
24062406

2407-
let exposure_dust_limit_success_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
2407+
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;
24082408
if msg.amount_msat / 1000 < exposure_dust_limit_success_sats {
24092409
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;
24102410
if on_holder_tx_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -4761,7 +4761,7 @@ impl<Signer: Sign> Channel<Signer> {
47614761
}
47624762
}
47634763

4764-
let exposure_dust_limit_success_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000) + self.counterparty_dust_limit_satoshis;
4764+
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;
47654765
if amount_msat / 1000 < exposure_dust_limit_success_sats {
47664766
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;
47674767
if on_counterparty_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -4770,7 +4770,7 @@ impl<Signer: Sign> Channel<Signer> {
47704770
}
47714771
}
47724772

4773-
let exposure_dust_limit_timeout_sats = (self.get_dust_buffer_feerate(None) as u64 * HTLC_TIMEOUT_TX_WEIGHT / 1000) + self.holder_dust_limit_satoshis;
4773+
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;
47744774
if amount_msat / 1000 < exposure_dust_limit_timeout_sats {
47754775
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;
47764776
if on_holder_dust_htlc_exposure_msat > self.get_max_dust_htlc_exposure_msat() {
@@ -5815,7 +5815,7 @@ mod tests {
58155815
use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate};
58165816
use ln::script::ShutdownScript;
58175817
use ln::chan_utils;
5818-
use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT};
5818+
use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters, htlc_success_tx_weight, htlc_timeout_tx_weight};
58195819
use chain::BestBlock;
58205820
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
58215821
use chain::keysinterface::{InMemorySigner, KeyMaterial, KeysInterface, BaseSign};
@@ -6027,27 +6027,27 @@ mod tests {
60276027

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

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

60416041
chan.channel_transaction_parameters.is_outbound_from_holder = false;
60426042

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

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

lightning/src/ln/functional_tests.rs

+6-4
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};
@@ -1597,9 +1597,10 @@ fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() {
15971597
push_amt -= commit_tx_fee_msat(feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT as u64);
15981598
push_amt -= Channel::<EnforcingSigner>::get_holder_selected_channel_reserve_satoshis(100_000) * 1000;
15991599
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, push_amt, InitFeatures::known(), InitFeatures::known());
1600+
let opt_anchors = false; // FIXME - should be based on InitFeatures
16001601

16011602
let dust_amt = crate::ln::channel::MIN_CHAN_DUST_LIMIT_SATOSHIS * 1000
1602-
+ feerate_per_kw as u64 * HTLC_SUCCESS_TX_WEIGHT / 1000 * 1000 - 1;
1603+
+ feerate_per_kw as u64 * htlc_success_tx_weight(opt_anchors) / 1000 * 1000 - 1;
16031604
// In the previous code, routing this dust payment would cause nodes[0] to perceive a channel
16041605
// reserve violation even though it's a dust HTLC and therefore shouldn't count towards the
16051606
// commitment transaction fee.
@@ -9365,6 +9366,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
93659366
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_channel);
93669367
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
93679368
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel);
9369+
let opt_anchors = false; // FIXME - should be based on InitFeatures
93689370

93699371
let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 1_000_000, 42);
93709372

@@ -9390,10 +9392,10 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
93909392
let chan = chan_lock.by_id.get(&channel_id).unwrap();
93919393
chan.get_dust_buffer_feerate(None) as u64
93929394
};
9393-
let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * HTLC_TIMEOUT_TX_WEIGHT / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
9395+
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;
93949396
let dust_outbound_htlc_on_holder_tx: u64 = config.channel_options.max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
93959397

9396-
let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * HTLC_SUCCESS_TX_WEIGHT / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
9398+
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;
93979399
let dust_inbound_htlc_on_holder_tx: u64 = config.channel_options.max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
93989400

93999401
let dust_htlc_on_counterparty_tx: u64 = 25;

0 commit comments

Comments
 (0)