AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Low 43 Bitcoin

Add a new `ChannelMoniorUpdateStep::ReleasePaymentComplete`

Public commit record

What the developer wrote

Authored by Matt Corallo

85/100 · Strong
Add a new `ChannelMoniorUpdateStep::ReleasePaymentComplete`

`MonitorEvent`s aren't delivered to the `ChannelManager` in a
durable fasion - if the `ChannelManager` fetches the pending
`MonitorEvent`s, then the `ChannelMonitor` gets persisted (i.e. due
to a block update) then the node crashes, prior to persisting the
`ChannelManager` again, the `MonitorEvent` and its effects on the
`ChannelManger` will be lost. This isn't likely in a sync persist
environment, but in an async one this could be an issue.

Note that this is only an issue for closed channels -
`MonitorEvent`s only inform the `ChannelManager` that a channel is
closed (which the `ChannelManager` will learn on startup or when it
next tries to advance the channel state), that
`ChannelMonitorUpdate` writes completed (which the `ChannelManager`
will detect on startup), or that HTLCs resolved on-chain post
closure. Of the three, only the last is problematic to lose prior
to a reload.

In previous commits we ensured that HTLC resolutions which came to
`ChannelManager` via a `MonitorEvent` were replayed on startup if
the `MonitorEvent` was lost. However, in cases where the
`ChannelManager` was so stale that it didn't have the payment state
for an HTLC at all, we only re-add it in cases where
`ChannelMonitor::get_pending_or_resolved_outbound_htlcs` includes
it.

Because constantly re-adding a payment state and then failing it
would generate lots of noise for users on startup (not to mention
risk of confusing stale payment events for the latest state of a
payment when the `PaymentId` has been reused to retry a payment).
Thus, `get_pending_or_resolved_outbound_htlcs` does not include
state for HTLCs which were resolved on chain with a preimage or
HTLCs which were resolved on chain with a timeout after
`ANTI_REORG_DELAY` confirmations.

This critera matches the critera for generating a `MonitorEvent`,
and works great under the assumption that `MonitorEvent`s are
reliably delivered. However, if they are not, and our
`ChannelManager` is lost or substantially old (or, in a future
where we do not persist `ChannelManager` at all), we will not end
up seeing payment resolution events for an HTLC.

Instead, we really want to tell our `ChannelMonitor`s when the
resolution of an HTLC is complete. Note that we don't particularly
care about non-payment HTLCs, as there is no re-hydration of state
to do there - `ChannelManager` load ignores forwarded HTLCs coming
back from `get_pending_or_resolved_outbound_htlcs` as there's
nothing to do - we always attempt to replay the success/failure and
figure out if it mattered based on whether there was still an HTLC
to claim/fail.

Here we take the first step towards that notification, adding a new
`ChannelMonitorUpdateStep` for the completion notification, and
tracking HTLCs which make it to the `ChannelMonitor` in such
updates in a new map.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
The short version

What changed, and why it matters

This commit adds a new internal bookkeeping step in Lightning Dev Kit's channel monitor so that, after a channel is closed and an HTLC is resolved on-chain, the code can remember that the user has already been told the payment finished. The goal is to avoid repeatedly replaying the same 'your payment completed/failed' message every time the node restarts, especially in setups where monitor events might be lost between a channel monitor persist and a channel manager persist. It is a defensive correctness fix, not a remote exploit.

Recommended action

Treat as a defensive fix in a larger patch series. Review the follow-up commit(s) that actually generate ReleasePaymentComplete updates from ChannelManager to ensure the new step is emitted at the correct point and that race conditions between user event handling and monitor persistence are handled. Verify that htlcs_resolved_to_user is consulted when populating get_all_current_outbound_htlcs and get_onchain_failed_outbound_htlcs in subsequent patches.

Security signals we found

01

Durability gap between ChannelMonitor persist and ChannelManager persist can lose MonitorEvent effects

02

Lost MonitorEvent for closed-channel HTLC resolution could prevent payment resolution events from reaching user after restart

03

New ChannelMonitorUpdateStep ReleasePaymentComplete added to track user-resolved payments

04

New persisted htlcs_resolved_to_user set marks HTLCs whose resolution has been communicated to user

05

Serialization TLV 33 added for new field; backward-compatible option used during read

06

Update classified as post-close update alongside PaymentPreimage and ChannelForceClosed

Risk score

Why this scored 43/100

Our methodology →
Potential impact 12/30
Exploitability 5/25
Stealth signal 8/15
Affected reach 7/15
Confidence 7/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.