@@ -3662,6 +3662,63 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3662
3662
}
3663
3663
}
3664
3664
3665
+ // Fail back HTLCs on backwards channels if they expire within `LATENCY_GRACE_PERIOD_BLOCKS`
3666
+ // blocks. If we haven't seen the preimage for an HTLC by the time the previous hop's
3667
+ // timeout expires, we've lost that HTLC, so we might as well fail it back instead of having our
3668
+ // counterparty force-close the channel.
3669
+ let current_holder_htlcs = self . current_holder_commitment_tx . htlc_outputs . iter ( )
3670
+ . map ( |& ( ref a, _, ref b) | ( a, b. as_ref ( ) ) ) ;
3671
+
3672
+ let current_counterparty_htlcs = if let Some ( txid) = self . current_counterparty_commitment_txid {
3673
+ if let Some ( htlc_outputs) = self . counterparty_claimable_outpoints . get ( & txid) {
3674
+ Some ( htlc_outputs. iter ( ) . map ( |& ( ref a, ref b) | ( a, b. as_ref ( ) . map ( |boxed| & * * boxed) ) ) )
3675
+ } else { None }
3676
+ } else { None } . into_iter ( ) . flatten ( ) ;
3677
+
3678
+ let prev_counterparty_htlcs = if let Some ( txid) = self . prev_counterparty_commitment_txid {
3679
+ if let Some ( htlc_outputs) = self . counterparty_claimable_outpoints . get ( & txid) {
3680
+ Some ( htlc_outputs. iter ( ) . map ( |& ( ref a, ref b) | ( a, b. as_ref ( ) . map ( |boxed| & * * boxed) ) ) )
3681
+ } else { None }
3682
+ } else { None } . into_iter ( ) . flatten ( ) ;
3683
+
3684
+ let htlcs = current_holder_htlcs
3685
+ . chain ( current_counterparty_htlcs)
3686
+ . chain ( prev_counterparty_htlcs) ;
3687
+
3688
+ let height = self . best_block . height ( ) ;
3689
+ for ( htlc, source_opt) in htlcs {
3690
+ // Only check forwarded HTLCs' previous hops
3691
+ let source = match source_opt {
3692
+ Some ( source) => source,
3693
+ None => continue ,
3694
+ } ;
3695
+ let ( cltv_expiry, htlc_id) = match source {
3696
+ HTLCSource :: PreviousHopData ( HTLCPreviousHopData {
3697
+ htlc_id, cltv_expiry : Some ( cltv_expiry) , ..
3698
+ } ) if !self . failed_back_htlc_ids . contains ( htlc_id) => ( * cltv_expiry, * htlc_id) ,
3699
+ _ => continue ,
3700
+ } ;
3701
+ if cltv_expiry <= height + LATENCY_GRACE_PERIOD_BLOCKS {
3702
+ let duplicate_event = self . pending_monitor_events . iter ( ) . any (
3703
+ |update| if let & MonitorEvent :: HTLCEvent ( ref upd) = update {
3704
+ upd. source == * source
3705
+ } else { false } ) ;
3706
+ if !duplicate_event {
3707
+ log_debug ! ( logger, "Failing back HTLC {} upstream to preserve the \
3708
+ channel as the forward HTLC hasn't resolved and our backward HTLC \
3709
+ expires soon at {}", log_bytes!( htlc. payment_hash. 0 ) , cltv_expiry) ;
3710
+ self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
3711
+ source : source. clone ( ) ,
3712
+ payment_preimage : None ,
3713
+ payment_hash : htlc. payment_hash ,
3714
+ htlc_value_satoshis : Some ( htlc. amount_msat / 1000 ) ,
3715
+ awaiting_downstream_confirmation : true ,
3716
+ } ) ) ;
3717
+ self . failed_back_htlc_ids . push ( htlc_id) ;
3718
+ }
3719
+ }
3720
+ }
3721
+
3665
3722
self . onchain_tx_handler . update_claims_view_from_requests ( claimable_outpoints, conf_height, self . best_block . height ( ) , broadcaster, fee_estimator, logger) ;
3666
3723
self . onchain_tx_handler . update_claims_view_from_matched_txn ( & txn_matched, conf_height, conf_hash, self . best_block . height ( ) , broadcaster, fee_estimator, logger) ;
3667
3724
0 commit comments