Skip to content

server: fix corner case shutdown hang#2110

Merged
jtobin merged 2 commits into
lightninglabs:mainfrom
jtobin:ioproofs-clean-shutdown
May 18, 2026
Merged

server: fix corner case shutdown hang#2110
jtobin merged 2 commits into
lightninglabs:mainfrom
jtobin:ioproofs-clean-shutdown

Conversation

@jtobin
Copy link
Copy Markdown
Member

@jtobin jtobin commented Apr 30, 2026

Resolves #2109. This is a borderline-overfitting issue identified by Opus while diagnosing #2108, but the fix is simple, and does marginally improve the daemon's stability, so IMO it's worth making.

Previously an unresponsive proof courier could cause importOutputProofs to block indefinitely while a co-op close was in flight, preventing tapd from shutting down cleanly. The fix simply wires up AuxChanCloser with a ContextGuard lifecycle in the same manner as other Aux components (AuxFundingController, AuxSweeper, etc.), also threading a cancellable context through importOutputProofs.

(Shutting down the daemon in this situation is safe in terms of ultimately handling the coop close; the retry logic is handled by lnd.)

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a potential shutdown hang in the daemon by improving the lifecycle management of the auxiliary channel closer component. By integrating the component into the server's start/stop sequence and ensuring that proof import operations are context-aware, the system can now cleanly shut down even if a proof courier becomes unresponsive during a cooperative channel close.

Highlights

  • Lifecycle Management: Integrated AuxChanCloser into the server lifecycle by adding Start and Stop methods, ensuring it is properly managed during daemon startup and shutdown.
  • Context Propagation: Updated importOutputProofs to accept a cancellable context, allowing it to respect shutdown signals and prevent indefinite blocking.
  • Stability Improvement: Ensured that the AuxChanCloser uses a ContextGuard, allowing for graceful termination even when proof courier operations are in progress.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces lifecycle management for the AuxChanCloser component by implementing Start and Stop methods and integrating them into the server's initialization and shutdown sequences. It also refactors importOutputProofs to accept a context.Context, replacing context.Background() to allow for proper cancellation during asset-aware channel closures. I have no feedback to provide.

@lightninglabs-deploy
Copy link
Copy Markdown

@GeorgeTsagk: review reminder
@jtobin, remember to re-request review from reviewers when ready

Copy link
Copy Markdown
Member

@GeorgeTsagk GeorgeTsagk left a comment

Choose a reason for hiding this comment

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

Lgtm

needs a rebase to resolve a conflict

also would be nice to add a test, although setup might be tricky (non-blocking, leaving it up to you)

@github-project-automation github-project-automation Bot moved this from 🆕 New to 👀 In review in Taproot-Assets Project Board May 18, 2026
jtobin added 2 commits May 18, 2026 11:10
Thread a context.Context through importOutputProofs so callers
can control cancellation. The importCommitTx call site passes
its existing context.Background(), preserving current behavior.
Embed a ContextGuard in AuxChanCloser and add Start/Stop methods
so the daemon can cleanly cancel in-flight importOutputProofs
calls on shutdown. FinalizeClose now creates a quit-cancellable
context via WithCtxQuitNoTimeout, which propagates through the
proof courier's BackoffHandler.wait select on ctx.Done().

FinalizeClose brackets the import call with Wg.Add/Done so that
Stop() waits for in-flight calls to fully unwind before
returning, preventing use-after-close on downstream dependencies.

AuxChanCloser.Stop is called early in the server shutdown
sequence, before other Aux* components, so cancellation fires
before dependencies like ChainBridge or ProofArchive are torn
down.
@jtobin
Copy link
Copy Markdown
Member Author

jtobin commented May 18, 2026

also would be nice to add a test, although setup might be tricky (non-blocking, leaving it up to you)

Yeah, I looked into this but it's indeed difficult to set up an actually-good one.

I think the best proof of functionality here, verifiable by direct inspection of the diff, is that this simply brings AuxChanCloser in line with the way other aux components are handled (and they don't have any similar tests either, presumably for the same reason).

@jtobin jtobin force-pushed the ioproofs-clean-shutdown branch from 0e0dd08 to 2b8bc30 Compare May 18, 2026 16:45
@jtobin jtobin added this pull request to the merge queue May 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
@jtobin jtobin added this pull request to the merge queue May 18, 2026
Merged via the queue into lightninglabs:main with commit a441139 May 18, 2026
40 checks passed
@github-project-automation github-project-automation Bot moved this from 👀 In review to ✅ Done in Taproot-Assets Project Board May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

Unreachable proof courier can block daemon shutdown

3 participants