iOSのTestFlight機能ででテスト公開中のアプリケーションに、William Casarin (@jb55)氏の"LNLinkというものがあります。「ライトニングネットワーク越しに」ライトニングノードを管理できるアプリという触れ込みが面白かったので、実際にコードを見てどうなっているのかを調べてみました。

LN上のデータのやり取り

LN上で特定の相手にデータを送る方法は大別して2通りあります。1つ目は支払いにデータを付加する方法(TLVメッセージなど)、2つ目は相手に直接ピアとして接続してデータをやり取りする方法です。

支払いにデータを付加する方法の特徴としては匿名性が高いことが挙げられます。特にkeysendのように送信者が勝手に支払いを送りつけるような場合は、データを受け取った側には送信者の情報が一切ない上、送金を中継したノードにも最終的な送信者と宛先がわかりません。

一方、直接ピアとして接続してやり取りする方法はあえてLNのプロトコルに沿ってP2P通信しているだけなので、実現できることに理論上限界はありません。なんなら、LNチャネルすら必要ありません。その代わり、匿名性を求める場合は都度新しいノード公開鍵を使い、Torなどの別の方法で確保することになります。

LNLINKの仕組み

さて、本題のLNLinkというアプリケーションですが、依存するライブラリを含め完全にオープンソースで公開されています。具体的には、@jb55氏の開発したLNLinkとlnsocket、Christian Decker氏が作ったc-lightningプラグインのcommandoです。後ろから順に説明します。

まず、c-lightningには追加機能を開発できるプラグイン機能があり、commandoはその中の特異なものの1つです。具体的には、LN上のP2Pメッセージによって他のノードからライトニングノードを操作できるようにするというものです(!)。Runeという認証情報(Lndが採用するMacaroonに似てます)を生成し、その認証情報を持つ操作リクエストを受け取ったら実行し、その結果を返送するというプラグインです。

https://github.com/lightningd/plugins/tree/master/commando

lnsocketはC言語で書かれた軽量なLN P2P通信用ライブラリで、公開鍵とホスト名で指定したライトニングノードに対してBOLT # 8に沿ったP2Pメッセージを送信することができます。

http://git.jb55.com/lnsocket/file/README.html

最後にLNLinkはこれらを組み合わせたiOSアプリで、セットアップ時にはLNノードのホスト名とcommando用のRuneを表示したQRコードを読み込み、あとはlnsocketを用いて自分のノードにcommandoを使った操作指示を送信し、その結果を受信するだけのシンプルなものです。

https://github.com/jb55/lnlink

リモートのLNノードに接続する通常のウォレットはRESTやRPCのAPIを利用するのに対し、LNLinkはLNのP2Pメッセージ規格でcommandoのAPIを叩くという違いがあります。

汎用型通信ネットワークとしてのLN

この1~2年ほど、ライトニングネットワークを汎用型データ通信ネットワークとして使いたいという声がちらほら聞こえています。これはプラットフォーマーやネットインフラ企業による事実上の検閲(deplatforming)を受けて高まっている関心だと思います。

これに関しても、上で述べたデータをやり取りする2種類の方法について検討する必要があります。

まずはペイメントにデータを付加する方法からですが、実際に個々のペイメントとデータが関連し、かつLN上でやり取りする合理性がある用途にしか長期的にはワークしないと考えます。理由として、データの送信にもそれ相応の費用が将来的に要求されるようになる可能性があるからです。例えばウェブサイトやファイルなどの大きなデータのやり取りには向かないでしょうが、P2Pの取引などであれば関連情報をまとめて送受信することに合理性がありそうです。

ちなみに現時点では、わざと支払いを失敗させるというハッキーなやり方で大きなデータも分割してペイメントに付加し無料で送りつけることができてしまいます。わざと支払いを失敗させることにコストがかからないことはプロービングという形でプライバシーやノード運営者の負担にも影響があり、LNが抱える課題の1つです。

また、LNノード同士がピアとして接続してLN上のメッセージの規格を使ってP2P通信することもできると紹介しました。これなら中継者の負担の問題などはありません。しかし本来、P2Pで接続できるのであれば、わざわざ制約の厳しく開発の面倒なLN上のメッセージで通信するよりお互いに別のアプリケーションを実行し、その機能をアプリケーション層で実現すればよいのです。これで大半の用途は事足りるでしょう。

したがって個人的には汎用型ネットワークはLNの役割ではないと思います。インターネットが不安定な場合のバックアップとしてメッシュネットワークなどにも興味はありますが、LN自体とはまた別の問題です。

ちなみに「汎用型」というのは逃げで、特化型のものに絶対勝てないから負けパターンだよってスタートアップの友人が最近しみじみと言ってました。

LNLINKの存在意義

ここまで読んでいただければ、LNLinkがLNの特殊な通信方法を選んだメリットがあるかといえば「現時点では、ない」というのが理解できたかと思います。しかし、将来的にこのアプローチが無益ということではありません。実際に次々とLNのカスタムP2Pメッセージ機能を使ったアプリケーションが出てくると、思いもよらぬメリットが出てくる可能性があります。

例えばサブマリンスワップでチャネルをリバランスするPeerSwapや、デリバティブの取引、別のレイヤー2で使用する鍵の売買など支払いと少量のデータのやり取りを強く結びつけたい用途についてはLN上でデータをやり取りすることに合理性があります。

スマホなどからそのようなプロトコルに参加したい際、「LNノードとして通信できる」ことが重要であってLNノード自体は不要な場合などに超軽量なアプリケーションとして提供できるでしょう。カストディアルウォレットと併せて使ったり、カストディアルウォレットに統合されるケースも考えられます。

あるいはWASMにコンパイルして、ブラウザ上のWebアプリ内からライトニングノードと対話するクライアントを住ませる簡単な方法なのかもしれません。(WASMやブラウザには詳しくないのですが、Lightning LabsによるとブラウザにLndを住ませる上で課題が少し残っているようです。その問題を解決するものなのかはわかりません。)

結論としては、その手があったか!というような使い方につながる可能性のある実験なので、ぜひ他のライトニングアプリにどのような影響を与えるか見守っていきたいです。