Remove previous holder HTLC data on splice locked when necessary
What changed, and why it matters
This change fixes a bookkeeping error in Lightning Dev Kit's channel monitor after a splice (a way to resize a Lightning channel's on-chain funding). If a channel had HTLCs (pending payments) in an older commitment state but no new commitment was negotiated during the splice, the monitor could keep stale HTLC data for a commitment transaction that never existed for the new funding transaction. The patch clears that stale data once the splice is locked. The main risk is that stale data might cause incorrect behavior when claiming or revoking funds if an old commitment were somehow broadcast, but the commit message frames this as a correctness fix rather than an active exploit.
Treat as a correctness and defensive-security fix. Review related splice code paths for other stale-state leaks, add regression tests covering the no-commitment-update-during-splice scenario, and consider whether `prev_holder_commitment_tx` being None should also invalidate other derived state.
Security signals we found
Stale HTLC state retained across funding transaction transitions
Splice-locked channel monitor state inconsistency
Potential incorrect claim/revocation behavior if old commitment data is referenced
Defensive cleanup of holder commitment metadata
Evidence from the diff
In ChannelMonitorImpl::funding_splice_locked, after promoting a pending splice’s FundingScope, the code now checks whether self.funding.prev_holder_commitment_tx is None. If so, it calls self.prev_holder_htlc_data.take() to discard any previously stored holder HTLC data. The rationale is that prev_holder_htlc_data is only meaningful when there is a previous holder commitment transaction for the current funding scope. When no commitment updates occurred during the pending splice’s lifecycle, that previous commitment data is invalid for the new funding transaction. The patch prevents the monitor from retaining HTLC tracking state that does not correspond to a broadcastable previous commitment.
Changed components
lightning/src/chain/channelmonitor.rsChannelMonitorImpl::funding_splice_lockedHolder HTLC tracking during splice lifecycleInspect captured patch +8 / −0
diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs
index 5c26fd0..0cf208a 100644
--- a/lightning/src/chain/channelmonitor.rs
+++ b/lightning/src/chain/channelmonitor.rs
@@ -4118,6 +4118,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
self.funding.prev_holder_commitment_tx.clone(),
);
+ // It's possible that no commitment updates happened during the lifecycle of the pending
+ // splice's `FundingScope` that was promoted. If so, our `prev_holder_htlc_data` is
+ // now irrelevant, since there's no valid previous commitment that exists for the current
+ // funding transaction that could be broadcast.
+ if self.funding.prev_holder_commitment_tx.is_none() {
+ self.prev_holder_htlc_data.take();
+ }
+
let no_further_updates_allowed = self.no_further_updates_allowed();
// The swap above places the previous `FundingScope` into `pending_funding`.
Why this scored 55/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.