@@ -397,6 +397,21 @@ pub struct ChannelConfig {
397397 /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal
398398 /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background
399399 pub force_close_avoidance_max_fee_satoshis : u64 ,
400+ /// Similar to [`Self::max_dust_htlc_exposure_msat`], but instead of setting a fixed maximum,
401+ /// this sets a multiplier on the estimated high priority feerate (sats/KW, as obtained from
402+ /// [`FeeEstimator`]) to determine the maximum allowed dust exposure. If this field is set to
403+ /// `Some(value)`, then the maximum dust exposure in sats is calculated as:
404+ /// `high_priority_feerate_per_kw * value / 1000`.
405+ ///
406+ /// This allows the maximum dust exposure to automatically scale with fee rate changes. With
407+ /// a fixed maximum, if the feerate increases significantly, then without a manually increase
408+ /// to this maximum, the channel may be unable to send/receive HTLCs between the maximum dust
409+ /// exposure and the new minimum value for HTLCs to be economically viable to claim.
410+ ///
411+ /// Default value: `Some(5000)`.
412+ ///
413+ /// [`FeeEstimator`]: crate::chain::chaininterface::FeeEstimator
414+ pub max_dust_htlc_exposure_multiplier_thousandths : Option < u64 > ,
400415}
401416
402417impl ChannelConfig {
@@ -417,6 +432,9 @@ impl ChannelConfig {
417432 if let Some ( force_close_avoidance_max_fee_satoshis) = update. force_close_avoidance_max_fee_satoshis {
418433 self . force_close_avoidance_max_fee_satoshis = force_close_avoidance_max_fee_satoshis;
419434 }
435+ if let Some ( max_dust_htlc_exposure_multiplier_thousandths) = update. max_dust_htlc_exposure_multiplier_thousandths {
436+ self . max_dust_htlc_exposure_multiplier_thousandths = max_dust_htlc_exposure_multiplier_thousandths;
437+ }
420438 }
421439}
422440
@@ -429,6 +447,7 @@ impl Default for ChannelConfig {
429447 cltv_expiry_delta : 6 * 12 , // 6 blocks/hour * 12 hours
430448 max_dust_htlc_exposure_msat : 5_000_000 ,
431449 force_close_avoidance_max_fee_satoshis : 1000 ,
450+ max_dust_htlc_exposure_multiplier_thousandths : Some ( 5000 ) ,
432451 }
433452 }
434453}
@@ -442,6 +461,7 @@ impl_writeable_tlv_based!(ChannelConfig, {
442461 // LegacyChannelConfig. To make sure that serialization is not compatible with this one, we use
443462 // the next required type of 10, which if seen by the old serialization will always fail.
444463 ( 10 , force_close_avoidance_max_fee_satoshis, required) ,
464+ ( 12 , max_dust_htlc_exposure_multiplier_thousandths, required)
445465} ) ;
446466
447467/// A parallel struct to [`ChannelConfig`] to define partial updates.
@@ -452,6 +472,7 @@ pub struct ChannelConfigUpdate {
452472 pub cltv_expiry_delta : Option < u16 > ,
453473 pub max_dust_htlc_exposure_msat : Option < u64 > ,
454474 pub force_close_avoidance_max_fee_satoshis : Option < u64 > ,
475+ pub max_dust_htlc_exposure_multiplier_thousandths : Option < Option < u64 > > ,
455476}
456477
457478impl Default for ChannelConfigUpdate {
@@ -462,6 +483,7 @@ impl Default for ChannelConfigUpdate {
462483 cltv_expiry_delta : None ,
463484 max_dust_htlc_exposure_msat : None ,
464485 force_close_avoidance_max_fee_satoshis : None ,
486+ max_dust_htlc_exposure_multiplier_thousandths : None ,
465487 }
466488 }
467489}
@@ -474,6 +496,7 @@ impl From<ChannelConfig> for ChannelConfigUpdate {
474496 cltv_expiry_delta : Some ( config. cltv_expiry_delta ) ,
475497 max_dust_htlc_exposure_msat : Some ( config. max_dust_htlc_exposure_msat ) ,
476498 force_close_avoidance_max_fee_satoshis : Some ( config. force_close_avoidance_max_fee_satoshis ) ,
499+ max_dust_htlc_exposure_multiplier_thousandths : Some ( config. max_dust_htlc_exposure_multiplier_thousandths ) ,
477500 }
478501 }
479502}
@@ -513,6 +536,7 @@ impl crate::util::ser::Writeable for LegacyChannelConfig {
513536 ( 4 , self . announced_channel, required) ,
514537 ( 6 , self . commit_upfront_shutdown_pubkey, required) ,
515538 ( 8 , self . options. forwarding_fee_base_msat, required) ,
539+ ( 10 , self . options. max_dust_htlc_exposure_multiplier_thousandths, option) ,
516540 } ) ;
517541 Ok ( ( ) )
518542 }
@@ -527,6 +551,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
527551 let mut announced_channel = false ;
528552 let mut commit_upfront_shutdown_pubkey = false ;
529553 let mut forwarding_fee_base_msat = 0 ;
554+ let mut max_dust_htlc_exposure_multiplier_thousandths = None ;
530555 read_tlv_fields ! ( reader, {
531556 ( 0 , forwarding_fee_proportional_millionths, required) ,
532557 ( 1 , max_dust_htlc_exposure_msat, ( default_value, 5_000_000u64 ) ) ,
@@ -535,6 +560,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
535560 ( 4 , announced_channel, required) ,
536561 ( 6 , commit_upfront_shutdown_pubkey, required) ,
537562 ( 8 , forwarding_fee_base_msat, required) ,
563+ ( 10 , max_dust_htlc_exposure_multiplier_thousandths, option) ,
538564 } ) ;
539565 Ok ( Self {
540566 options : ChannelConfig {
@@ -543,6 +569,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
543569 cltv_expiry_delta,
544570 force_close_avoidance_max_fee_satoshis,
545571 forwarding_fee_base_msat,
572+ max_dust_htlc_exposure_multiplier_thousandths,
546573 } ,
547574 announced_channel,
548575 commit_upfront_shutdown_pubkey,
0 commit comments