nayutaco/ptarmigan

a corner case after the HTLC has become irrevocably committed

Opened this issue · 1 comments

a corner case after the HTLC has become irrevocably committed

HTLCがirrevocably committed(以下IR)になるとき、つまりrevoke_and_ack送受信のタイミングで、以下の処理が行われる。

revoke_and_ack送信

  1. 先にRAM上をrevoke_and_ack送信状態に更新してDBに保存
  2. revoke_and_ack送信
  3. IRになったupdatesに対応するupdate_add_htlcの中継データをDBから削除
  4. IRになったHTLCsをRAMからクリアしてDBに保存

revoke_and_ack受信

  1. revoke_and_ack受信
  2. RAM上をrevoke_and_ack送信状態に更新してDBに保存
  3. update_add_htlcの中継または、update_fulfill/fail_htlcだったらupdate_add_htlcの中継データを削除
  4. IRになったHTLCsをRAMからクリアしてDBに保存

問題になるのはいずれも最初にDBに保存して状態を確定させてから、4が完了するまでにptarmdが終了してしまうと、再起動後当該HTLCsがクリアされていない。微妙なタイミングではあるが。

現時点で発生しうる問題は、

  1. closingが終わらない。HTLCが残っているから(あまり影響はないだろう)
  2. ptarmdが終了したタイミングが3の中継データがクリアされる前の状態の場合、再度revoke_and_ackの送受信が発生したとき、そのときは中継データが削除されず(この処理はnew_updateフラグを見て、そのタイミングでIR状態になったupdatesにしか行われない)当該HTLCsのみがクリアされる。そうなると再び同じ中継データがロードされてしまう。update_fulfill/fail_htlcは適用すべきHTLCが存在しないので破棄されるだろうが、update_add_htlcはロードされ、再送信されてしまう。
  3. 本来存在しないHTLCが数にカウントされる(あまり影響はないだろう)

対応策)
ptarmd起動時に、channelをロードするときIR状態のHTLCsについて中継データを削除した後、HTLCsをクリアしてDBに保存する。