Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

staticaddr/loopin: make canceled-invoice timeout unlock recoverable

オープン
#1,167 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 2 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
go
領域
backend, payments

調査の方向性

MonitorInvoiceAndHtlcTxAction と OnSwapTimedOut における MonitorInvoiceAndHtlcTx transition から始め、続いて UnlockState、OnRecover、unlockDeposits を調べます。PR #1161 の recovery と lifecycle に関する議論を確認します。完了条件は、確認なしの timeout が引き続き recoverable であり、deposits の unlock が完了した後、または不要であることが判明した後にのみ Failed に到達することです。

索引モデルが issue の本文から書いたものです。

説明

Problem

A static-address loop-in can reach the canceled-invoice recovery path without a durable guarantee that its deposits were unlocked.

Current monitor flow:

  1. the payment deadline path cancels the invoice and then unlocks deposits:

    cancelInvoice()
    err = f.unlockDeposits(ctx)
    
  2. those are separate side effects. If loopd shuts down, crashes, or the deposit transition fails after invoice cancellation succeeds but before deposits are moved back to Deposited, recovery sees LookupInvoice return ContractCanceled;

  3. in that recovered state no new deadlineChan is created, so the deadline unlock path is not retried;

  4. if the HTLC never confirmed and the CLTV height arrives, MonitorInvoiceAndHtlcTxAction returns OnSwapTimedOut and the loop-in moves to Failed, while deposits may remain stuck in LoopingIn.

This was discussed during PR #1161: https://github.com/lightninglabs/loop/pull/1161#discussion_r3539797010

The issue appears to predate PR #1161, but that PR touched the surrounding recovery/lifecycle code and made the invariant visible.

Potential fix

Route the no-HTLC-confirmation timeout path through a recoverable state-machine unlock state instead of transitioning directly to Failed.

One possible shape:

  • add a success event such as OnDepositsUnlocked;
  • route MonitorInvoiceAndHtlcTx -> OnSwapTimedOut -> UnlockState (or a more specific UnlockDepositsBeforeFail state);
  • make UnlockState retry on OnRecover;
  • only transition UnlockState -> OnDepositsUnlocked -> Failed after unlockDeposits succeeds;
  • if unlockDeposits fails, keep the loop-in in the unlock state so restart/recovery retries cleanup rather than marking the swap failed with deposits possibly still locked.

The important invariant is: a no-confirmation timeout should not become final Failed until deposit unlock has succeeded or is known to be unnecessary.

主要言語
Go
スター
593
フォーク
138
平均マージ
4日 18時間
マージ済み PR(30日)
20

環境構築

  • Dockerfile または Docker Compose ファイルあり
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

lightninglabs/loop のほかの issue

lightninglabs/loop の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。