Skip to content

Commit 653ee5b

Browse files
author
Antoine Riard
committed
Add funder anchor affordance checks
This commit modifies the fee-on-funder checks at any update of a commitment transaction, including `update_fee`. The funder must always be able to pay for both anchor outputs even if one of them doesn't materialize in practice due to the lack of a party's balance/pending HTLCs. The cost of an anchor output is covering both the output weight (`COMMITMENT_TX_WEIGHT_PER_ANCHOR`) and the minimal above-dust ouput amount (`ANCHOR_OUTPUT_VALUE`)
1 parent 7bf4380 commit 653ee5b

File tree

2 files changed

+53
-35
lines changed

2 files changed

+53
-35
lines changed

lightning/src/ln/channel.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,13 @@ const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
410410
#[cfg(test)]
411411
pub const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
412412

413+
#[cfg(not(test))]
414+
const COMMITMENT_TX_WEIGHT_PER_ANCHOR: u64 = 172;
415+
#[cfg(test)]
416+
pub const COMMITMENT_TX_WEIGHT_PER_ANCHOR: u64 = 172;
417+
418+
pub const ANCHOR_OUTPUT_VALUE: u64 = 330;
419+
413420
/// Maximmum `funding_satoshis` value, according to the BOLT #2 specification
414421
/// it's 2^24.
415422
pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24;
@@ -1700,7 +1707,10 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
17001707
fn commit_tx_fee_msat(&self, num_htlcs: usize) -> u64 {
17011708
// Note that we need to divide before multiplying to round properly,
17021709
// since the lowest denomination of bitcoin on-chain is the satoshi.
1703-
(COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC) * self.feerate_per_kw as u64 / 1000 * 1000
1710+
// Note that if `option_anchor_output` applies there always a dual-pair
1711+
// of anchor output weight to account for, even if one of them doesn't
1712+
// materialize in practice.
1713+
(COMMITMENT_TX_BASE_WEIGHT + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC + 2 * COMMITMENT_TX_WEIGHT_PER_ANCHOR) * self.feerate_per_kw as u64 / 1000 * 1000
17041714
}
17051715

17061716
// Get the commitment tx fee for the local (i.e our) next commitment transaction
@@ -1828,7 +1838,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18281838
// feerate_per_kw, while maintaining their channel reserve (as required by the spec).
18291839
let remote_commit_tx_fee_msat = if self.channel_outbound { 0 } else {
18301840
// +1 for this HTLC.
1831-
self.next_remote_commit_tx_fee_msat(1)
1841+
// If `option_anchor_output` funder must be able to afford 2 anchor output value
1842+
self.next_remote_commit_tx_fee_msat(1) + (2 * ANCHOR_OUTPUT_VALUE * 1000)
18321843
};
18331844
if pending_remote_value_msat - msg.amount_msat < remote_commit_tx_fee_msat {
18341845
return Err(ChannelError::Close("Remote HTLC add would not leave enough to pay for fees".to_owned()));
@@ -1848,7 +1859,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18481859
// we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep the extra +1
18491860
// as we should still be able to afford adding this HTLC plus one more future HTLC, regardless of
18501861
// being sensitive to fee spikes.
1851-
let remote_fee_cost_incl_stuck_buffer_msat = 2 * self.next_remote_commit_tx_fee_msat(1 + 1);
1862+
// If `option_anchor_output` funder must be able to afford 2 anchor output value
1863+
let remote_fee_cost_incl_stuck_buffer_msat = 2 * self.next_remote_commit_tx_fee_msat(1 + 1) + (2 * ANCHOR_OUTPUT_VALUE * 1000);
18521864
if pending_remote_value_msat - msg.amount_msat - chan_reserve_msat < remote_fee_cost_incl_stuck_buffer_msat {
18531865
// Note that if the pending_forward_status is not updated here, then it's because we're already failing
18541866
// the HTLC, i.e. its status is already set to failing.
@@ -1860,7 +1872,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
18601872

18611873
// +1 for this HTLC.
18621874
let local_commit_tx_fee_msat = self.next_local_commit_tx_fee_msat(1);
1863-
if self.value_to_self_msat < self.counterparty_selected_channel_reserve_satoshis * 1000 + local_commit_tx_fee_msat {
1875+
// If `option_anchor_output` funder must be able to afford 2 anchor output value
1876+
if self.value_to_self_msat < self.counterparty_selected_channel_reserve_satoshis * 1000 + local_commit_tx_fee_msat + (2 * ANCHOR_OUTPUT_VALUE * 1000) {
18641877
return Err(ChannelError::Close("Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_owned()));
18651878
}
18661879
}
@@ -1993,10 +2006,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
19932006
//If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction
19942007
if update_fee {
19952008
let num_htlcs = commitment_tx.1;
1996-
let total_fee = feerate_per_kw as u64 * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000;
2009+
let total_fee = feerate_per_kw as u64 * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC + 2 * COMMITMENT_TX_WEIGHT_PER_ANCHOR) / 1000;
19972010

19982011
let counterparty_reserve_we_require = Channel::<ChanSigner>::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis);
1999-
if self.channel_value_satoshis - self.value_to_self_msat / 1000 < total_fee + counterparty_reserve_we_require {
2012+
log_trace!(logger, "channel value satoshis {} holder balance {} total fee {} counterparty reserve {} anchor value {}", self.channel_value_satoshis, self.value_to_self_msat / 1000, total_fee, counterparty_reserve_we_require, 2 * ANCHOR_OUTPUT_VALUE);
2013+
if self.channel_value_satoshis - self.value_to_self_msat / 1000 < total_fee + counterparty_reserve_we_require + 2 * ANCHOR_OUTPUT_VALUE {
20002014
return Err((None, ChannelError::Close("Funding remote cannot afford proposed new fee".to_owned())));
20012015
}
20022016
}
@@ -3711,7 +3725,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37113725
let holder_selected_chan_reserve_msat = Channel::<ChanSigner>::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis);
37123726
// 1 additional HTLC corresponding to this HTLC.
37133727
let counterparty_commit_tx_fee_msat = self.next_remote_commit_tx_fee_msat(1);
3714-
if counterparty_balance_msat < holder_selected_chan_reserve_msat + counterparty_commit_tx_fee_msat {
3728+
// If `option_anchor_output` funder must be able to afford 2 anchor output value
3729+
if counterparty_balance_msat < holder_selected_chan_reserve_msat + counterparty_commit_tx_fee_msat + (2 * ANCHOR_OUTPUT_VALUE * 1000) {
37153730
return Err(ChannelError::Ignore("Cannot send value that would put counterparty balance under holder-announced channel reserve value".to_owned()));
37163731
}
37173732
}
@@ -3724,7 +3739,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
37243739
// The `+1` is for the HTLC currently being added to the commitment tx and
37253740
// the `2 *` and `+1` are for the fee spike buffer.
37263741
let commit_tx_fee_msat = if self.channel_outbound {
3727-
2 * self.next_local_commit_tx_fee_msat(1 + 1)
3742+
// If `option_anchor_output` funder must be able to afford 2 anchor output value
3743+
2 * self.next_local_commit_tx_fee_msat(1 + 1) + (2 * ANCHOR_OUTPUT_VALUE * 1000)
37283744
} else { 0 };
37293745
if pending_value_to_self_msat - amount_msat < commit_tx_fee_msat {
37303746
return Err(ChannelError::Ignore(format!("Cannot send value that would not leave enough to pay for fees. Pending value to self: {}. local_commit_tx_fee {}", pending_value_to_self_msat, commit_tx_fee_msat)));

0 commit comments

Comments
 (0)