Skip to content

Commit d30d599

Browse files
committed
Drop non-anchor channel fee upper bound limit entirely
Quite a while ago we added checks for the total current dust exposure on a channel to explicitly limit dust inflation attacks. When we did this, we kept the existing upper bound on the channel's feerate in place. However, these two things are redundant - the point of the feerate upper bound is to prevent dust inflation, and it does so in a crude way that can cause spurious force-closures. Here we simply drop the upper bound entirely, relying on the dust inflation limit to prevent dust inflation instead.
1 parent b6f3d0a commit d30d599

File tree

5 files changed

+7
-58
lines changed

5 files changed

+7
-58
lines changed

fuzz/src/chanmon_consistency.rs

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ impl FeeEstimator for FuzzEstimator {
8080
// always return a HighPriority feerate here which is >= the maximum Normal feerate and a
8181
// Background feerate which is <= the minimum Normal feerate.
8282
match conf_target {
83-
ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee => MAX_FEE * 10,
8483
ConfirmationTarget::OnChainSweep => MAX_FEE,
8584
ConfirmationTarget::ChannelCloseMinimum|ConfirmationTarget::AnchorChannelFee|ConfirmationTarget::MinAllowedAnchorChannelRemoteFee|ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee => 253,
8685
ConfirmationTarget::NonAnchorChannelFee => cmp::min(self.ret_val.load(atomic::Ordering::Acquire), MAX_FEE),

fuzz/src/full_stack.rs

+2-2
Large diffs are not rendered by default.

lightning/src/chain/chaininterface.rs

-17
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,6 @@ pub enum ConfirmationTarget {
5353
/// to low hundreds of blocks to get our transaction on-chain, but we shouldn't risk too low a
5454
/// fee - this should be a relatively high priority feerate.
5555
OnChainSweep,
56-
/// The highest feerate we will allow our channel counterparty to have in a non-anchor channel.
57-
///
58-
/// This is the feerate on the transaction which we (or our counterparty) will broadcast in
59-
/// order to close the channel unilaterally. Because our counterparty must ensure they can
60-
/// always broadcast the latest state, this value being too low will cause immediate
61-
/// force-closures.
62-
///
63-
/// Allowing this value to be too high can allow our counterparty to burn our HTLC outputs to
64-
/// dust, which can result in HTLCs failing or force-closures (when the dust HTLCs exceed
65-
/// [`ChannelConfig::max_dust_htlc_exposure`]).
66-
///
67-
/// Because most nodes use a feerate estimate which is based on a relatively high priority
68-
/// transaction entering the current mempool, setting this to a small multiple of your current
69-
/// high priority feerate estimate should suffice.
70-
///
71-
/// [`ChannelConfig::max_dust_htlc_exposure`]: crate::util::config::ChannelConfig::max_dust_htlc_exposure
72-
MaxAllowedNonAnchorChannelRemoteFee,
7356
/// This is the lowest feerate we will allow our channel counterparty to have in an anchor
7457
/// channel in order to close the channel if a channel party goes away.
7558
///

lightning/src/ln/channel.rs

+3-31
Original file line numberDiff line numberDiff line change
@@ -2162,20 +2162,6 @@ impl<SP: Deref> Channel<SP> where
21622162
feerate_per_kw: u32, cur_feerate_per_kw: Option<u32>, logger: &L
21632163
) -> Result<(), ChannelError> where F::Target: FeeEstimator, L::Target: Logger,
21642164
{
2165-
// We only bound the fee updates on the upper side to prevent completely absurd feerates,
2166-
// always accepting up to 25 sat/vByte or 10x our fee estimator's "High Priority" fee.
2167-
// We generally don't care too much if they set the feerate to something very high, but it
2168-
// could result in the channel being useless due to everything being dust. This doesn't
2169-
// apply to channels supporting anchor outputs since HTLC transactions are pre-signed with a
2170-
// zero fee, so their fee is no longer considered to determine dust limits.
2171-
if !channel_type.supports_anchors_zero_fee_htlc_tx() {
2172-
let upper_limit =
2173-
fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee) as u64;
2174-
if feerate_per_kw as u64 > upper_limit {
2175-
return Err(ChannelError::Close(format!("Peer's feerate much too high. Actual: {}. Our expected upper limit: {}", feerate_per_kw, upper_limit)));
2176-
}
2177-
}
2178-
21792165
let lower_limit_conf_target = if channel_type.supports_anchors_zero_fee_htlc_tx() {
21802166
ConfirmationTarget::MinAllowedAnchorChannelRemoteFee
21812167
} else {
@@ -3872,14 +3858,11 @@ impl<SP: Deref> Channel<SP> where
38723858
return Err(ChannelError::Close("Peer sent update_fee when we needed a channel_reestablish".to_owned()));
38733859
}
38743860
Channel::<SP>::check_remote_fee(&self.context.channel_type, fee_estimator, msg.feerate_per_kw, Some(self.context.feerate_per_kw), logger)?;
3875-
let feerate_over_dust_buffer = msg.feerate_per_kw > self.context.get_dust_buffer_feerate(None);
38763861

38773862
self.context.pending_update_fee = Some((msg.feerate_per_kw, FeeUpdateState::RemoteAnnounced));
38783863
self.context.update_time_counter += 1;
3879-
// If the feerate has increased over the previous dust buffer (note that
3880-
// `get_dust_buffer_feerate` considers the `pending_update_fee` status), check that we
3881-
// won't be pushed over our dust exposure limit by the feerate increase.
3882-
if feerate_over_dust_buffer {
3864+
// Check that we won't be pushed over our dust exposure limit by the feerate increase.
3865+
if !self.context.channel_type.supports_anchors_zero_fee_htlc_tx() {
38833866
let inbound_stats = self.context.get_inbound_pending_htlc_stats(None);
38843867
let outbound_stats = self.context.get_outbound_pending_htlc_stats(None);
38853868
let holder_tx_dust_exposure = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat;
@@ -7684,7 +7667,7 @@ mod tests {
76847667
use crate::ln::PaymentHash;
76857668
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
76867669
use crate::ln::channel::InitFeatures;
7687-
use crate::ln::channel::{Channel, ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, commit_tx_fee_msat};
7670+
use crate::ln::channel::{ChannelState, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, commit_tx_fee_msat};
76887671
use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
76897672
use crate::ln::features::ChannelTypeFeatures;
76907673
use crate::ln::msgs::{ChannelUpdate, DecodeError, UnsignedChannelUpdate, MAX_VALUE_MSAT};
@@ -7726,17 +7709,6 @@ mod tests {
77267709
"MAX_FUNDING_SATOSHIS_NO_WUMBO is greater than all satoshis in existence");
77277710
}
77287711

7729-
#[test]
7730-
fn test_no_fee_check_overflow() {
7731-
// Previously, calling `check_remote_fee` with a fee of 0xffffffff would overflow in
7732-
// arithmetic, causing a panic with debug assertions enabled.
7733-
let fee_est = TestFeeEstimator { fee_est: 42 };
7734-
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_est);
7735-
assert!(Channel::<&TestKeysInterface>::check_remote_fee(
7736-
&ChannelTypeFeatures::only_static_remote_key(), &bounded_fee_estimator,
7737-
u32::max_value(), None, &&test_utils::TestLogger::new()).is_err());
7738-
}
7739-
77407712
struct Keys {
77417713
signer: InMemorySigner,
77427714
}

lightning/src/util/test_utils.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,8 @@ pub struct TestFeeEstimator {
9494
pub sat_per_kw: Mutex<u32>,
9595
}
9696
impl chaininterface::FeeEstimator for TestFeeEstimator {
97-
fn get_est_sat_per_1000_weight(&self, confirmation_target: ConfirmationTarget) -> u32 {
98-
match confirmation_target {
99-
ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee => {
100-
core::cmp::max(25 * 250, *self.sat_per_kw.lock().unwrap() * 10)
101-
}
102-
_ => *self.sat_per_kw.lock().unwrap(),
103-
}
97+
fn get_est_sat_per_1000_weight(&self, _confirmation_target: ConfirmationTarget) -> u32 {
98+
*self.sat_per_kw.lock().unwrap()
10499
}
105100
}
106101

0 commit comments

Comments
 (0)