インボイスの二重支払い
ライトニング決済では、通常のビットコインオンチェーン決済とは異なり、決済毎に受取り側がインボイスを発行し、支払い側がそこへ送金する形式となっています。このインボイスは使い捨てのようなもので、基本的には一度支払いが完了したらそのインボイスは使用しません。
通常のビットコインアドレスの場合は、そのアドレスに対して何回も送金ができます。例えば、以下のビットコインアドレスを確認すると分かりますが、何回も同じアドレスに対して送金がされているのが分かります。
16ftSEQ4ctQFDtVZiUBusQUjRrGhM3JYwe
では、ライトニング決済のインボイスを見てみましょう。以下はSpotlightの入金時に作られるインボイスですが、このインボイスはすでに支払い済みなので、今この記事を読んでいるあなたが自分のウォレットから支払おうとしても失敗するはずです。
ではなぜ送金が失敗するのでしょうか?それは受取り側が、一度支払いが完了したインボイスへの支払いを拒否するためです。その為、例えば支払い済みのインボイスを第三者へ渡しても、そのインボイスへの送金はエラーとなります。
ここで、もし支払い済みのインボイスに対して、再度支払いがあっても受取り側が拒否しなかった場合はどうなるのでしょうか?
今までこのようなケースを軽視していましたが、今回ライトニング決済をした時、同じインボイスに対して異なるウォレットで同時に支払いをしたところ、二重支払いができてしまいました。ここで言う二重支払いとは、オンチェーンビットコインの二重支払いとは別ものです。正当な支払いを自分が2回しただけなので、自分の財布から2倍の金額が差し引かれたことを意味します。幸い、受取り側の店主がそれに気付いて教えてくれたので、今回の事象に気がつきました。その後、僕が払いすぎた分のインボイスを店主へ送って、店主から払い戻しをしてもらったので無事ことが済みました。基本的にはウォレット側で一度支払いが済んだインボイスは無効するのですが、なぜ今回このような現象が起きたのこは不明です。一応、店主とも連絡を取りながら原因究明ができたらなと思いますが。
このような事象はプロトコルレベルでの回避は難しく、ウォレットの実装に依存するような感じみたいです。以下のサイトにもその旨が記載されていました。ただ、BOLTとよばれるライトニングネットワークの仕様書をざっとみましたが、そのような記載はみつけられませんでした。もし、何かご存知の方はコメント欄で教えていただけると幸いです。
さて、今回起きたような1つのインボイスに対して複数の支払いをする、という事象、実はMPP(Multi Path Payment)とよばれる、1つのインボイスに対して複数ルート経由での送金を可能とする技術についても関連する話なのですが、この話は以下の勉強会で解説がされているので、興味のある方は見てみてください。個人的にも分かりやすいスライドが作成できたら公開したいと思います。
まとめ
今回起きたような二重支払いを回避するには、異なるウォレットで同じインボイスへの支払いを極力さけ、支払いが処理中・ペンディング状態であれば、その処理が失敗・キャンセルされるまで待つという運用をするのが良さそうです。ただし、支払いが途中で詰まってしまうPayment Stuckという状態になる場合もあり、この場合は、処理状態が更新(失敗・キャンセル)されるまでに時間がかかるので、そうなったら気長に待つしかなさそうです。といっても、このようなエッジケースはほぼ起こらないと思うので、そこまで気にしなくても良いかな、というのが個人的な感想です。