Skip to content

chainbackends: consume real reorg depth and Done from lndclient#834

Draft
ellemouton wants to merge 8 commits into
reorg-observefrom
ellemouton/lndclient-reorg-depth-done
Draft

chainbackends: consume real reorg depth and Done from lndclient#834
ellemouton wants to merge 8 commits into
reorg-observefrom
ellemouton/lndclient-reorg-depth-done

Conversation

@ellemouton

Copy link
Copy Markdown
Member

Summary

Upgrades the lndclient chain-notifier adapter introduced in #422 to consume the
real re-org depth and finality (Done) signals, replacing the two
client-side workarounds that #422 had to use because lnd's gRPC transport
dropped that information.

This addresses the lndclient-related review feedback on #422, tracked in #827.

Changes

  • chainbackends/lndclient_adapters.go:
    • Forward the real re-org depth on NegativeConf (was a sentinel 0),
      via lndclient's new WithReOrgDepthChan.
    • Wire a real Done straight through to the ConfirmationEvent /
      SpendEvent Done channels via WithDoneChan (was allocated-but-never-
      written, forcing height-based synthesis as the only finality source).
  • chainbackends/lndclient_ordering_test.go: assert the forwarded depth;
    make the ordering tests use unbuffered downstream channels so the forwarder
    cannot run ahead of the in-order consumer (removes a latent parallel-run
    flake).
  • go.mod / .golangci.yml: temporary replace pins onto the lnd + lndclient
    fork branches, allow-listed in gomoddirectives.

Notes

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

Copy link
Copy Markdown

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 integrates temporary forks of lnd and lndclient to surface chain-notifier reorganization depth and terminal Done events over gRPC. Specifically, RegisterConfirmationsNtfn now tracks and forwards the actual reorganization depth using WithReOrgDepthChan and handles the terminal safety signal via WithDoneChan. Similarly, RegisterSpendNtfn has been updated to utilize WithDoneChan. Unit tests have been adjusted to accommodate these channel and signature changes, using unbuffered downstream channels to prevent race conditions. No review comments were provided, so there is no additional feedback.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@ellemouton
ellemouton force-pushed the ellemouton/lndclient-reorg-depth-done branch from 521cc46 to 841afe1 Compare June 30, 2026 21:16
@ellemouton
ellemouton force-pushed the reorg-safe-chainsource branch from 3eb6f61 to 449b6cf Compare July 1, 2026 16:09
@levmi levmi added enhancement New feature or request P1 Priority 1 — high reorg safety Fund-safety: stuck, lost, or mis-counted funds labels Jul 6, 2026
@ellemouton
ellemouton force-pushed the reorg-safe-chainsource branch 2 times, most recently from 32871de to 4a1f9b1 Compare July 8, 2026 20:41
Add the reorg-aware chain-observation substrate the rest of the
reorg-safety stack consumes: a seq-ordered conf/spend watch lifecycle
(Confirmed -> Reorged -> re-Confirmed -> Done) with height-based
finality synthesis for backends that cannot deliver a native Done
(gRPC lndclient and lwwallet).

Finality synthesis is armed off the select loop, tied to the
sub-actor's long-lived context (a per-attempt timeout would tear the
in-process block-epoch forwarder down the instant it armed), retried
with a capped exponential backoff until it succeeds or the watch's
context is cancelled (a single-confirmation tx has no later event to
piggy-back a retry on), and evaluated against the best height captured
at arm time so a tx already buried past FinalityDepth when the watch
arms finalizes immediately instead of hanging for the next block.
Deliver the full TxConfirmed/TxReorged/re-TxConfirmed/TxFinalized/
TxFailed cycle on confirmation watches, with a terminal seal guarding
the reversible fire-and-forget deliveries and a catch-up TxReorged when
a reorg lands while a subscriber's initial TxConfirmed is still parked
on the async notify path.
Forward the lnd and lndclient chain-notifier reorg/finality signals
(NegativeConf -> reorg) into the reorg-aware chainsource lifecycle with
buffered forwarding.
Reorg-aware lwwallet/Esplora backend: TipPoller same-height and deeper
reorg detection via PrevBlock continuity, a unified ChainEvent stream,
and BlockDisconnected emission to btcwallet before connecting the
replacement tip.
Forward Neutrino chain-notifier reorg signals into the reorg-aware
chainsource lifecycle.
Consume the reorg-aware substrate at the edges: make the wallet
boarding sweep reorg-aware, enable height-based finality on the darepod
chainsource actor, add the harness GetRawTransaction / SignedV3Tx
helpers, and add the end-to-end reorg systests for chainsource and
txconfirm.
Temporary replaces onto the lnd and lndclient branches that add the
reorg depth and Done events to the chain notifier, now rebased onto
btcd v2 so they resolve against the current module graph. Allow-listed
in the gomoddirectives linter config. Drop all three once those changes
land upstream and tag (tracked in darepo-client#827).
The lndclient adapter previously forwarded a sentinel reorg depth of 0
on NegativeConf and never wrote the Done channel, because lnd's gRPC
notifier dropped the depth and surfaced its past-reorg-safety-depth
signal only by closing the stream.

With the forked lndclient now exposing both via WithReOrgDepthChan and
WithDoneChan, forward the real reorg depth through the ordered
confirmation bridge and wire the terminal Done straight through to the
ConfirmationEvent/SpendEvent Done channels. The spend path has no depth
(lnd does not track one) so its bare reorg ping is unchanged.
@ellemouton
ellemouton force-pushed the ellemouton/lndclient-reorg-depth-done branch from 841afe1 to 246992e Compare July 14, 2026 21:07
@ellemouton
ellemouton changed the base branch from reorg-safe-chainsource to reorg-observe July 14, 2026 21:07
@ellemouton
ellemouton force-pushed the reorg-observe branch 5 times, most recently from 292394e to 233abdd Compare July 16, 2026 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request P1 Priority 1 — high reorg safety Fund-safety: stuck, lost, or mis-counted funds

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants