Skip to content

Commit 61e8d3d

Browse files
committed
Add max dust exposure multiplier config knob
With fee rates rising dramatically in mid-April 2023, thresholds for what is considered dust have risen, often exceeding our previous dust exposure threshold of 5k sats. This causes all payments and HTLC forwards between 5k sats and new dust thresholds to fail. This commit adds a config knob that will allow us to implement setting our max dust exposure limit to the product of a multiplier and the high priority feerate.
1 parent 0f2c4c0 commit 61e8d3d

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

lightning/src/util/config.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,21 @@ pub struct ChannelConfig {
436436
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`]: crate::events::Event::PaymentClaimable::counterparty_skimmed_fee_msat
437437
// TODO: link to bLIP when it's merged
438438
pub accept_underpaying_htlcs: bool,
439+
/// Similar to [`Self::max_dust_htlc_exposure_msat`], but instead of setting a fixed maximum,
440+
/// this sets a multiplier on the estimated high priority feerate (sats/KW, as obtained from
441+
/// [`FeeEstimator`]) to determine the maximum allowed dust exposure. If this field is set to
442+
/// `Some(value)`, then the maximum dust exposure in sats is calculated as:
443+
/// `high_priority_feerate_per_kw * value / 1000`.
444+
///
445+
/// This allows the maximum dust exposure to automatically scale with fee rate changes. With
446+
/// a fixed maximum, if the feerate increases significantly, then without a manually increase
447+
/// to this maximum, the channel may be unable to send/receive HTLCs between the maximum dust
448+
/// exposure and the new minimum value for HTLCs to be economically viable to claim.
449+
///
450+
/// Default value: `Some(5000)`.
451+
///
452+
/// [`FeeEstimator`]: crate::chain::chaininterface::FeeEstimator
453+
pub max_dust_htlc_exposure_multiplier_thousandths: Option<u64>,
439454
}
440455

441456
impl ChannelConfig {
@@ -456,6 +471,9 @@ impl ChannelConfig {
456471
if let Some(force_close_avoidance_max_fee_satoshis) = update.force_close_avoidance_max_fee_satoshis {
457472
self.force_close_avoidance_max_fee_satoshis = force_close_avoidance_max_fee_satoshis;
458473
}
474+
if let Some(max_dust_htlc_exposure_multiplier_thousandths) = update.max_dust_htlc_exposure_multiplier_thousandths {
475+
self.max_dust_htlc_exposure_multiplier_thousandths = max_dust_htlc_exposure_multiplier_thousandths;
476+
}
459477
}
460478
}
461479

@@ -469,6 +487,7 @@ impl Default for ChannelConfig {
469487
max_dust_htlc_exposure_msat: 5_000_000,
470488
force_close_avoidance_max_fee_satoshis: 1000,
471489
accept_underpaying_htlcs: false,
490+
max_dust_htlc_exposure_multiplier_thousandths: Some(5000),
472491
}
473492
}
474493
}
@@ -483,6 +502,7 @@ impl_writeable_tlv_based!(ChannelConfig, {
483502
// LegacyChannelConfig. To make sure that serialization is not compatible with this one, we use
484503
// the next required type of 10, which if seen by the old serialization will always fail.
485504
(10, force_close_avoidance_max_fee_satoshis, required),
505+
(12, max_dust_htlc_exposure_multiplier_thousandths, required)
486506
});
487507

488508
/// A parallel struct to [`ChannelConfig`] to define partial updates.
@@ -493,6 +513,7 @@ pub struct ChannelConfigUpdate {
493513
pub cltv_expiry_delta: Option<u16>,
494514
pub max_dust_htlc_exposure_msat: Option<u64>,
495515
pub force_close_avoidance_max_fee_satoshis: Option<u64>,
516+
pub max_dust_htlc_exposure_multiplier_thousandths: Option<Option<u64>>,
496517
}
497518

498519
impl Default for ChannelConfigUpdate {
@@ -503,6 +524,7 @@ impl Default for ChannelConfigUpdate {
503524
cltv_expiry_delta: None,
504525
max_dust_htlc_exposure_msat: None,
505526
force_close_avoidance_max_fee_satoshis: None,
527+
max_dust_htlc_exposure_multiplier_thousandths: None,
506528
}
507529
}
508530
}
@@ -515,6 +537,7 @@ impl From<ChannelConfig> for ChannelConfigUpdate {
515537
cltv_expiry_delta: Some(config.cltv_expiry_delta),
516538
max_dust_htlc_exposure_msat: Some(config.max_dust_htlc_exposure_msat),
517539
force_close_avoidance_max_fee_satoshis: Some(config.force_close_avoidance_max_fee_satoshis),
540+
max_dust_htlc_exposure_multiplier_thousandths: Some(config.max_dust_htlc_exposure_multiplier_thousandths),
518541
}
519542
}
520543
}
@@ -554,6 +577,7 @@ impl crate::util::ser::Writeable for LegacyChannelConfig {
554577
(4, self.announced_channel, required),
555578
(6, self.commit_upfront_shutdown_pubkey, required),
556579
(8, self.options.forwarding_fee_base_msat, required),
580+
(10, self.options.max_dust_htlc_exposure_multiplier_thousandths, option),
557581
});
558582
Ok(())
559583
}
@@ -568,6 +592,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
568592
let mut announced_channel = false;
569593
let mut commit_upfront_shutdown_pubkey = false;
570594
let mut forwarding_fee_base_msat = 0;
595+
let mut max_dust_htlc_exposure_multiplier_thousandths = None;
571596
read_tlv_fields!(reader, {
572597
(0, forwarding_fee_proportional_millionths, required),
573598
(1, max_dust_htlc_exposure_msat, (default_value, 5_000_000u64)),
@@ -576,6 +601,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
576601
(4, announced_channel, required),
577602
(6, commit_upfront_shutdown_pubkey, required),
578603
(8, forwarding_fee_base_msat, required),
604+
(10, max_dust_htlc_exposure_multiplier_thousandths, option),
579605
});
580606
Ok(Self {
581607
options: ChannelConfig {
@@ -585,6 +611,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
585611
force_close_avoidance_max_fee_satoshis,
586612
forwarding_fee_base_msat,
587613
accept_underpaying_htlcs: false,
614+
max_dust_htlc_exposure_multiplier_thousandths,
588615
},
589616
announced_channel,
590617
commit_upfront_shutdown_pubkey,

0 commit comments

Comments
 (0)