Skip to content

Commit 3591c49

Browse files
committed
f - move logic to be after on-chain claim checks
1 parent 9672456 commit 3591c49

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

lightning/src/chain/channelmonitor.rs

+57
Original file line numberDiff line numberDiff line change
@@ -3662,6 +3662,63 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36623662
}
36633663
}
36643664

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+
36653722
self.onchain_tx_handler.update_claims_view_from_requests(claimable_outpoints, conf_height, self.best_block.height(), broadcaster, fee_estimator, logger);
36663723
self.onchain_tx_handler.update_claims_view_from_matched_txn(&txn_matched, conf_height, conf_hash, self.best_block.height(), broadcaster, fee_estimator, logger);
36673724

0 commit comments

Comments
 (0)