Skip to content

feat: one-time stale channel monitor recovery (v2)#501

Closed
jvsena42 wants to merge 1 commit intomasterfrom
fix/stale-monitor-recovery-v2
Closed

feat: one-time stale channel monitor recovery (v2)#501
jvsena42 wants to merge 1 commit intomasterfrom
fix/stale-monitor-recovery-v2

Conversation

@jvsena42
Copy link
Member

Description

This PR adds automatic one-time recovery for users affected by stale channel monitors caused by the RN migration overwrite bug (#462, #495).

On BuildError.ReadFailed, the app automatically retries the LDK node build once with accept_stale_channel_monitors enabled. A persisted staleMonitorRecoveryAttempted UserDefaults flag ensures this only happens once — the flag is set on any successful build, so unaffected users see zero impact.

This is a clean cherry-pick of the recovery logic from #500 onto release-2.1.1, without the unrelated pubky work that was in the original branch.

Linked Issues/Tasks

Screenshot / Video

N/A - backend logic change

QA Notes

  1. Reproduce the stale monitor state (overwrite a channel monitor in VSS with an older update_id)
  2. Launch the app — first build fails with ReadFailed
  3. Verify the retry succeeds and the node starts
  4. Check logs for "Stale monitor recovery: build succeeded with accept_stale"
  5. Kill and relaunch — verify normal startup (no retry triggered)

🤖 Generated with Claude Code

On BuildError.ReadFailed (likely stale ChannelMonitor from migration
overwrite), automatically retry once with accept_stale_channel_monitors
enabled. The ldk-node recovery flag force-syncs the monitor's update_id
and heals commitment state via a delayed chain sync + keysend round-trip.

A persisted UserDefaults flag ensures this only triggers once — set on
any successful build (affected or not), preventing future retries.

Depends on: synonymdev/ldk-node#76

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jvsena42 jvsena42 marked this pull request as draft March 18, 2026 16:39
@jvsena42
Copy link
Member Author

on draft to wait for bindings

throw error
}

// Build failed with ReadFailed — likely a stale ChannelMonitor (DangerousValue).
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with specific exception

context: "Recovery"
)
Self.staleMonitorRecoveryAttempted = true
builder.setAcceptStaleChannelMonitors(accept: true)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing dependency: setAcceptStaleChannelMonitors not in pinned ldk-node revision

This call references builder.setAcceptStaleChannelMonitors(accept: true), but the method does not exist in the currently pinned synonymdev/ldk-node revision (c5698d0, set in Bitkit.xcodeproj). As a result, this branch will not compile until the project.pbxproj is updated to a commit that includes synonymdev/ldk-node#76 (which the PR description already calls out as a requirement).

)
Self.staleMonitorRecoveryAttempted = true
builder.setAcceptStaleChannelMonitors(accept: true)
if !lnurlAuthServerUrl.isEmpty {

@ovitrif
Copy link
Collaborator

ovitrif commented Mar 18, 2026

best to align this with the android counterpart:

Base automatically changed from release-2.1.1 to master March 19, 2026 08:18
@jvsena42
Copy link
Member Author

replaced by #502

@jvsena42 jvsena42 closed this Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants