@@ -37,7 +37,7 @@ use crate::ln::{PaymentHash, PaymentPreimage};
37
37
use crate :: ln:: msgs:: DecodeError ;
38
38
use crate :: ln:: chan_utils;
39
39
use crate :: ln:: chan_utils:: { CounterpartyCommitmentSecrets , HTLCOutputInCommitment , HTLCClaim , ChannelTransactionParameters , HolderCommitmentTransaction } ;
40
- use crate :: ln:: channelmanager:: { HTLCSource , SentHTLCId } ;
40
+ use crate :: ln:: channelmanager:: { HTLCSource , SentHTLCId , HTLCPreviousHopData } ;
41
41
use crate :: chain;
42
42
use crate :: chain:: { BestBlock , WatchedOutput } ;
43
43
use crate :: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator , LowerBoundedFeeEstimator } ;
@@ -236,6 +236,15 @@ pub const ANTI_REORG_DELAY: u32 = 6;
236
236
/// in a race condition between the user connecting a block (which would fail it) and the user
237
237
/// providing us the preimage (which would claim it).
238
238
pub ( crate ) const HTLC_FAIL_BACK_BUFFER : u32 = CLTV_CLAIM_BUFFER + LATENCY_GRACE_PERIOD_BLOCKS ;
239
+ /// Number of blocks before an inbound HTLC expires at which we fail it backwards.
240
+ ///
241
+ /// If we have forwarded an HTLC to a peer and they have not claimed it on or off-chain by the
242
+ /// time the previous hop's HTLC timeout expires, we're probably going to lose the inbound HTLC.
243
+ /// Instead of also losing the channel, we fail the HTLC backwards.
244
+ ///
245
+ /// To give us some buffer in case we're slow to process blocks, we fail a few blocks before the
246
+ /// timeout officially expires to ensure we fail back before our counterparty force closes.
247
+ pub ( crate ) const TIMEOUT_FAIL_BACK_BUFFER : u32 = 3 ;
239
248
240
249
// TODO(devrandom) replace this with HolderCommitmentTransaction
241
250
#[ derive( Clone , PartialEq , Eq ) ]
@@ -3309,6 +3318,60 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3309
3318
}
3310
3319
}
3311
3320
3321
+ // Fail back HTLCs on backwards channels if they expire within `TIMEOUT_FAIL_BACK_BUFFER`
3322
+ // blocks. If we haven't seen the preimage for an HTLC by the time the previous hop's
3323
+ // timeout expires, we've lost that HTLC, so we might as well fail it back instead of having our
3324
+ // counterparty force-close the channel.
3325
+ let height = self . best_block . height ( ) ;
3326
+ macro_rules! fail_soon_to_expire_htlcs {
3327
+ ( $htlcs: expr) => { {
3328
+ for ( htlc, source_opt) in $htlcs {
3329
+ // Only check forwarded HTLCs' previous hops
3330
+ let source = match source_opt {
3331
+ Some ( source) => source,
3332
+ None => continue ,
3333
+ } ;
3334
+ let cltv_expiry = match source {
3335
+ HTLCSource :: PreviousHopData ( HTLCPreviousHopData { cltv_expiry: Some ( cltv_expiry) , .. } ) => * cltv_expiry,
3336
+ _ => continue ,
3337
+ } ;
3338
+ if cltv_expiry <= height + TIMEOUT_FAIL_BACK_BUFFER {
3339
+ let duplicate_event = self . pending_monitor_events. iter( ) . any(
3340
+ |update| if let & MonitorEvent :: HTLCEvent ( ref upd) = update {
3341
+ upd. source == * source
3342
+ } else { false } ) ;
3343
+ if !duplicate_event {
3344
+ log_debug!( logger, "Failing back HTLC {} upstream to preserve the \
3345
+ channel as the forward HTLC hasn't resolved and our backward HTLC \
3346
+ expires soon at {}", log_bytes!( htlc. payment_hash. 0 ) , cltv_expiry) ;
3347
+ self . pending_monitor_events. push( MonitorEvent :: HTLCEvent ( HTLCUpdate {
3348
+ source: source. clone( ) ,
3349
+ payment_preimage: None ,
3350
+ payment_hash: htlc. payment_hash,
3351
+ htlc_value_satoshis: Some ( htlc. amount_msat / 1000 ) ,
3352
+ } ) ) ;
3353
+ }
3354
+ }
3355
+ }
3356
+ } }
3357
+ }
3358
+
3359
+ let current_holder_htlcs = self . current_holder_commitment_tx . htlc_outputs . iter ( )
3360
+ . map ( |& ( ref a, _, ref b) | ( a, b. as_ref ( ) ) ) ;
3361
+ fail_soon_to_expire_htlcs ! ( current_holder_htlcs) ;
3362
+
3363
+ if let Some ( ref txid) = self . current_counterparty_commitment_txid {
3364
+ if let Some ( ref htlc_outputs) = self . counterparty_claimable_outpoints . get ( txid) {
3365
+ fail_soon_to_expire_htlcs ! ( htlc_outputs. iter( ) . map( |& ( ref a, ref b) | ( a, ( b. as_ref( ) . clone( ) ) . map( |boxed| & * * boxed) ) ) ) ;
3366
+ }
3367
+ } ;
3368
+
3369
+ if let Some ( ref txid) = self . prev_counterparty_commitment_txid {
3370
+ if let Some ( ref htlc_outputs) = self . counterparty_claimable_outpoints . get ( txid) {
3371
+ fail_soon_to_expire_htlcs ! ( htlc_outputs. iter( ) . map( |& ( ref a, ref b) | ( a, ( b. as_ref( ) . clone( ) ) . map( |boxed| & * * boxed) ) ) ) ;
3372
+ }
3373
+ } ;
3374
+
3312
3375
// Find which on-chain events have reached their confirmation threshold.
3313
3376
let onchain_events_awaiting_threshold_conf =
3314
3377
self . onchain_events_awaiting_threshold_conf . drain ( ..) . collect :: < Vec < _ > > ( ) ;
@@ -3353,20 +3416,24 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3353
3416
matured_htlcs. push ( source. clone ( ) ) ;
3354
3417
}
3355
3418
3356
- log_debug ! ( logger, "HTLC {} failure update in {} has got enough confirmations to be passed upstream" ,
3357
- log_bytes!( payment_hash. 0 ) , entry. txid) ;
3358
- self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
3359
- payment_hash,
3360
- payment_preimage : None ,
3361
- source : source. clone ( ) ,
3362
- htlc_value_satoshis,
3363
- } ) ) ;
3364
- self . htlcs_resolved_on_chain . push ( IrrevocablyResolvedHTLC {
3365
- commitment_tx_output_idx,
3366
- resolving_txid : Some ( entry. txid ) ,
3367
- resolving_tx : entry. transaction ,
3368
- payment_preimage : None ,
3369
- } ) ;
3419
+ let duplicate_event = self . pending_monitor_events . iter ( ) . any (
3420
+ |update| if let & MonitorEvent :: HTLCEvent ( ref upd) = update { upd. source == * source } else { false } ) ;
3421
+ if !duplicate_event {
3422
+ log_debug ! ( logger, "HTLC {} failure update in {} has got enough confirmations to be passed upstream" ,
3423
+ log_bytes!( payment_hash. 0 ) , entry. txid) ;
3424
+ self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
3425
+ payment_hash,
3426
+ payment_preimage : None ,
3427
+ source : source. clone ( ) ,
3428
+ htlc_value_satoshis,
3429
+ } ) ) ;
3430
+ self . htlcs_resolved_on_chain . push ( IrrevocablyResolvedHTLC {
3431
+ commitment_tx_output_idx,
3432
+ resolving_txid : Some ( entry. txid ) ,
3433
+ resolving_tx : entry. transaction ,
3434
+ payment_preimage : None ,
3435
+ } ) ;
3436
+ }
3370
3437
} ,
3371
3438
OnchainEvent :: MaturingOutput { descriptor } => {
3372
3439
log_debug ! ( logger, "Descriptor {} has got enough confirmations to be passed upstream" , log_spendable!( descriptor) ) ;
0 commit comments