@@ -485,6 +485,62 @@ pub struct ChannelConfig {
485
485
/// [`PaymentClaimable::counterparty_skimmed_fee_msat`]: crate::events::Event::PaymentClaimable::counterparty_skimmed_fee_msat
486
486
// TODO: link to bLIP when it's merged
487
487
pub accept_underpaying_htlcs : bool ,
488
+ /// A multiplier on the on-chain fees (assuming the high priority feerate) setting the
489
+ /// threshold for an HTLC's value for which we will fail the HTLC early to prevent closing a
490
+ /// channel. This field is denoted in millionths.
491
+ ///
492
+ /// If we have forwarded an HTLC to a peer and they have not claimed it on or off-chain by the
493
+ /// time the previous hop's HTLC timeout expires, we can choose to fail back the HTLC to save
494
+ /// the upstream channel from closing on-chain, or we can risk the channel in hopes of getting
495
+ /// a last-minute preimage from downstream. The risk may or may not be worth it depending on
496
+ /// how large the HTLC is relative to how much we will lose in fees if the channel closes.
497
+ ///
498
+ /// This roughly translates to how much the HTLC value should be proportional to the amount
499
+ /// we'll pay on chain. So if the value of this flag is 1,500,000, it means we should only risk
500
+ /// going on-chain if the HTLC value is at least 1.5x the amount we'll pay on chain.
501
+ ///
502
+ /// Based on this multiplier, we will fail back HTLCs in the described situation if the HTLC's
503
+ /// value is below the following threshold:
504
+ /// `high_priority_feerate_per_kw * total_weight * early_fail_multiplier / 1,000,000,000` (we
505
+ /// divide by 1,000,000,000 because feerate is denoted by kiloweight units, and the multiplier
506
+ /// is denoted in millionths).
507
+ ///
508
+ /// Total weight is defined by the situation where we took the risk closing on-chain, and the
509
+ /// result was in our favor, i.e. we claimed with an HTLC-success transaction. So, we use the
510
+ /// sum of the weight of the commitment transaction (if we're the funder of the channel) and
511
+ /// the weight of an HTLC-success transaction, including one extra P2WPKH input and output
512
+ /// to account for fee-bumping. These weights are calculated as follows:
513
+ ///
514
+ /// [Commitment transaction weight](https://github.com/lightning/bolts/blob/master/03-transactions.md#expected-weight-of-the-commitment-transaction):
515
+ /// * (no option_anchors) 500 + 172 * num-htlc-outputs + 224 weight
516
+ /// * (option_anchors) 900 + 172 * num-htlc-outputs + 224 weight
517
+ ///
518
+ /// [HTLC-success weight](https://github.com/lightning/bolts/blob/master/03-transactions.md#expected-weight-of-htlc-timeout-and-htlc-success-transactions):
519
+ /// * HTLC-success weight: 703 (706 with anchors) weight
520
+ /// * 1 input + witness spending a P2WPKH output: 272 weight
521
+ /// * 1 P2WPKH output: 31 bytes * 4 = 124 weight
522
+ /// * Total: 1099 (1102 with anchors) weight
523
+ ///
524
+ /// Sample calculations:
525
+ /// * Total weight assuming we're the funder, on a non-anchor channel with 1 HTLC:
526
+ /// 500 + 172 * 1 + 224 + 1099 = 1995.
527
+ /// * Feerate: 1 sat/vbyte -> 253 sats/KW (250 sat/KW, although the minimum defaults to 253
528
+ /// sats/KW for rounding, see [`FeeEstimator`])
529
+ /// * Cost to claim-onchain: 1995 * 253 / 1000 = 504 sats.
530
+ /// * Minimum HTLC value required to risk going on-chain:
531
+ /// 1995 * 253 * 1,500,000 / 1,000 / 1,000,000 = 757 sats.
532
+ /// * Feerate: 30 sat/vbyte -> 7,500 sat/KW
533
+ /// * Cost to claim on-chain: 1995 * 7500 / 1000 = 14,962 sats.
534
+ /// * Minimum HTLC value required to risk going on-chain:
535
+ /// 1995 * 7500 * 1,500,000 / 1,000 / 1,000,000 = 22,443 sats.
536
+ ///
537
+ /// If you prefer to always let upstream HTLCs resolve on-chain in the event that your
538
+ /// downstream channel takes too long to confirm on-chain, just set this multiplier to 0.
539
+ ///
540
+ /// Default value: 1,500,000.
541
+ ///
542
+ /// [`FeeEstimator`]: crate::chain::chaininterface::FeeEstimator
543
+ pub early_fail_multiplier : u64 ,
488
544
}
489
545
490
546
impl ChannelConfig {
@@ -518,6 +574,7 @@ impl Default for ChannelConfig {
518
574
max_dust_htlc_exposure : MaxDustHTLCExposure :: FeeRateMultiplier ( 5000 ) ,
519
575
force_close_avoidance_max_fee_satoshis : 1000 ,
520
576
accept_underpaying_htlcs : false ,
577
+ early_fail_multiplier : 1_500_000 ,
521
578
}
522
579
}
523
580
}
@@ -534,6 +591,7 @@ impl crate::util::ser::Writeable for ChannelConfig {
534
591
( 2 , self . forwarding_fee_base_msat, required) ,
535
592
( 3 , self . max_dust_htlc_exposure, required) ,
536
593
( 4 , self . cltv_expiry_delta, required) ,
594
+ ( 5 , self . early_fail_multiplier, required) ,
537
595
( 6 , max_dust_htlc_exposure_msat_fixed_limit, required) ,
538
596
// ChannelConfig serialized this field with a required type of 8 prior to the introduction of
539
597
// LegacyChannelConfig. To make sure that serialization is not compatible with this one, we use
@@ -553,12 +611,14 @@ impl crate::util::ser::Readable for ChannelConfig {
553
611
let mut max_dust_htlc_exposure_msat = None ;
554
612
let mut max_dust_htlc_exposure_enum = None ;
555
613
let mut force_close_avoidance_max_fee_satoshis = 1000 ;
614
+ let mut early_fail_multiplier = 1_500_000 ;
556
615
read_tlv_fields ! ( reader, {
557
616
( 0 , forwarding_fee_proportional_millionths, required) ,
558
617
( 1 , accept_underpaying_htlcs, ( default_value, false ) ) ,
559
618
( 2 , forwarding_fee_base_msat, required) ,
560
619
( 3 , max_dust_htlc_exposure_enum, option) ,
561
620
( 4 , cltv_expiry_delta, required) ,
621
+ ( 5 , early_fail_multiplier, ( default_value, 1_500_000u64 ) ) ,
562
622
// Has always been written, but became optionally read in 0.0.116
563
623
( 6 , max_dust_htlc_exposure_msat, option) ,
564
624
( 10 , force_close_avoidance_max_fee_satoshis, required) ,
@@ -573,6 +633,7 @@ impl crate::util::ser::Readable for ChannelConfig {
573
633
cltv_expiry_delta,
574
634
max_dust_htlc_exposure : max_dust_htlc_exposure_msat,
575
635
force_close_avoidance_max_fee_satoshis,
636
+ early_fail_multiplier,
576
637
} )
577
638
}
578
639
}
@@ -585,6 +646,7 @@ pub struct ChannelConfigUpdate {
585
646
pub cltv_expiry_delta : Option < u16 > ,
586
647
pub max_dust_htlc_exposure_msat : Option < MaxDustHTLCExposure > ,
587
648
pub force_close_avoidance_max_fee_satoshis : Option < u64 > ,
649
+ pub early_fail_multiplier : Option < u64 > ,
588
650
}
589
651
590
652
impl Default for ChannelConfigUpdate {
@@ -595,6 +657,7 @@ impl Default for ChannelConfigUpdate {
595
657
cltv_expiry_delta : None ,
596
658
max_dust_htlc_exposure_msat : None ,
597
659
force_close_avoidance_max_fee_satoshis : None ,
660
+ early_fail_multiplier : None ,
598
661
}
599
662
}
600
663
}
@@ -607,6 +670,7 @@ impl From<ChannelConfig> for ChannelConfigUpdate {
607
670
cltv_expiry_delta : Some ( config. cltv_expiry_delta ) ,
608
671
max_dust_htlc_exposure_msat : Some ( config. max_dust_htlc_exposure ) ,
609
672
force_close_avoidance_max_fee_satoshis : Some ( config. force_close_avoidance_max_fee_satoshis ) ,
673
+ early_fail_multiplier : Some ( config. early_fail_multiplier ) ,
610
674
}
611
675
}
612
676
}
@@ -650,6 +714,7 @@ impl crate::util::ser::Writeable for LegacyChannelConfig {
650
714
( 4 , self . announced_channel, required) ,
651
715
( 5 , self . options. max_dust_htlc_exposure, required) ,
652
716
( 6 , self . commit_upfront_shutdown_pubkey, required) ,
717
+ ( 7 , self . options. early_fail_multiplier, required) ,
653
718
( 8 , self . options. forwarding_fee_base_msat, required) ,
654
719
} ) ;
655
720
Ok ( ( ) )
@@ -666,6 +731,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
666
731
let mut commit_upfront_shutdown_pubkey = false ;
667
732
let mut forwarding_fee_base_msat = 0 ;
668
733
let mut max_dust_htlc_exposure_enum = None ;
734
+ let mut early_fail_multiplier = 1_500_000 ;
669
735
read_tlv_fields ! ( reader, {
670
736
( 0 , forwarding_fee_proportional_millionths, required) ,
671
737
// Has always been written, but became optionally read in 0.0.116
@@ -674,6 +740,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
674
740
( 3 , force_close_avoidance_max_fee_satoshis, ( default_value, 1000u64 ) ) ,
675
741
( 4 , announced_channel, required) ,
676
742
( 5 , max_dust_htlc_exposure_enum, option) ,
743
+ ( 7 , early_fail_multiplier, ( default_value, 1_500_000u64 ) ) ,
677
744
( 6 , commit_upfront_shutdown_pubkey, required) ,
678
745
( 8 , forwarding_fee_base_msat, required) ,
679
746
} ) ;
@@ -689,6 +756,7 @@ impl crate::util::ser::Readable for LegacyChannelConfig {
689
756
force_close_avoidance_max_fee_satoshis,
690
757
forwarding_fee_base_msat,
691
758
accept_underpaying_htlcs : false ,
759
+ early_fail_multiplier,
692
760
} ,
693
761
announced_channel,
694
762
commit_upfront_shutdown_pubkey,
0 commit comments