Skip to content

add deterministic test reproducing asset lockup on crash during colored channel open - #154

Draft
dcorral wants to merge 1 commit into
RGB-Tools:masterfrom
dcorral:test/upstream-funding-crash
Draft

add deterministic test reproducing asset lockup on crash during colored channel open#154
dcorral wants to merge 1 commit into
RGB-Tools:masterfrom
dcorral:test/upstream-funding-crash

Conversation

@dcorral

@dcorral dcorral commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

When opening an RGB channel, the funder's FundingGenerationReady handler colors the funding transaction: it calls rgb_send_begin (sweeping the channel amount and the change into a batch transfer), consumes the resulting fascia into the stock (rgb_consume_fascia), and creates the consignments, all before the funding transaction is signed and handed to LDK (funding_transaction_generated).

If the process dies in that window, a restart is left in an inconsistent state:

  • LDK has no channel (funding was never handed off), so nothing resumes it.
  • The RGB wallet has already promoted the transition into the stock and moved every allocation into a batch transfer tied to a funding transaction that will never be broadcast.
  • There is no startup reconciliation to detect and undo this.
  • /failtransfers cannot release it either: the batch's fascia is already consumed, so the transfer is not in a failable state.

Net effect: after the crash the funder's entire spendable balance for that asset is stuck at 0, unrecoverable through any existing API. It needs only a local crash at an unlucky moment during any colored channel open.

How the test reproduces it

A debug-only crash checkpoint (funding_kill_checkpoint, #[cfg(debug_assertions)], gated behind the RLN_FUNDING_KILL_AT env var) is placed at exactly that point, after coloring, before the LDK handoff. The test:

  1. Starts the funder (node1) as a real daemon subprocess with the checkpoint armed, plus a normal counterparty (node2). A subprocess is required because in-process test nodes cannot model an OS crash.
  2. Funds both, issues an asset on node1, records node1's spendable balance.
  3. Fires an openchannel for part of the asset (funding is deliberately halted).
  4. node1 reaches the checkpoint (coloring done, stock promoted, not yet handed off), signals via a ready file, and parks.
  5. SIGKILLs node1, the exact on-disk state a crash leaves at that instant.
  6. Restarts node1 over the same data dir and asserts its spendable balance is fully restored.

On master, step 6 fails: spendable is 0, the whole balance stranded.

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.

1 participant