Develop with pleasure!

福岡でCloudとかBlockchainとか。

LNのゴシッププロトコルを使った流動性の提供

最近、C-Lightningで実験的にLNのチャネルの流動性(インバウンドキャパシティの提供)をLNのゴシッププロトコルを使って配信する機能がマージされた↓

https://github.com/ElementsProject/lightning/pull/4639

LNの支払いを受ける場合、チャネルにインバウンドキャパシティが必要になる。手数料を支払うことでこのインバウンドキャパシティを提供してくれるLNBIGのようなサービスもある(LNBIGは何で小額でインバウンドキャパシティ提供してくれてるのか不思議だ)。

今回C-Lightningが実装したのは、まだマージされていないけどBOLTにも提案されている機能で↓

https://github.com/lightningnetwork/lightning-rfc/issues/878

LNのゴシッププロトコルを使って、流動性の提供をアナウンスし、リース料をもらいインバウンドキャパシティを一定期間提供するチャネル開設を可能にしようというアプローチ。これが普及すると、チャネルのリバランスも自動化できるようになるかも。

ZmnSCPxjの提案

LNで流動性マーケットを提供する仕組みについては、2018年にZmnSCPxjがLightning-Devメーリングリストで提案している↓

[Lightning-dev] Towards a Market for Liquidity Providers -- Enforcing Minimum Channel Lifetime

流動性を購入する際には、以下の2つが重要なパラメーターになる:

  • 提供されるインバウンドキャパシティ
  • 提供される期間

流動性の提供期間の保証

せっかく購入したキャパシティも、すぐにチャネルが閉じられてしまうと損するだけなので、購入したキャパシティは一定期間利用できる状態にする必要がある。

単純にこの期間を担保する方法として考えられるのは、コミットメントトランザクションnLocktimeにリース期間を加味したブロック高を設定するという方法。ただ、この場合、支払いをルーティングする際のHTLCのタイムロックと競合してしまう。

そこで、コミットメントトランザクション自体にnLocktimeを設定するのではなく、コミットメントトランザクション流動性提供側のアウトプットにCLTVを設定するアプローチが提案されている。

流動性提供者をLicky、流動性の購入者をMercyとした場合、

Licky側のコミットメントトランザクションのアウトプットは:

  1. Mercyの残高:Mercyの鍵 && CSV
  2. Lickyの残高: Revocation || (Lickyの鍵 && CSV && CLTV)

Mercy側のコミットメントトランザクションのアウトプットは:

  1. Lickyの残高:Lickyの鍵 && CSV && CLTV
  2. Mercyの残高: Revocation || (Mercyの鍵 && CSV)

という構成になる。ここでCLTVは、流動性が提供される期間=ライフタイム。既存のコミットメントトランザクションは対称的な構成になるが、流動性のライフタイム(CLTV)が常にLicky側に付くため、トランザクションは非対称な構成になる。

この場合、コミットメントトランザクションをブロードキャストして一方的にチャネルを閉じた場合、どちらがブロードキャストしたとしてもLicky側の残高は流動性のライフタイムが過ぎるまでは動かせなくなる。この仕組みで、購入した流動性の提供期間を保証させる。

もちろん、Lickyがコミットメントトランザクションをブロードキャストするのを防止する方法は無いけど、ブロードキャストしても資金がロックされるだけで、チャネルを維持していれば得られたかもしれないルーティング手数料も手に入らないので、提供側がそのような行為をする経済的なインセンティブはない。

支払いの循環を利用した資金移動

↑の方法で、流動性提供者のインセンティブが設計されるが、例えば、

Licky → Mercy → Randy → Licky

のような経路が存在した場合、Lickyは自分の資金をRandyを経由した自分に送ることで、Licky → Mercy間の流動性を移動することができてしまう。この場合、流動性を購入したMercyにとっては、その流動性が移動してしまうという攻撃が考えられる。

ただ、Mercy → Randy間でも資金が移動していることになるので、逆側から見た場合、流動性は減っていないことになる。そのため、Mercy → Randy間のチャネルにもチャネルのライフタイムを課すことで、この攻撃は緩和できるとしている。

デュアル・ファンディング

流動性の提供者に対して、上記のコミットメントトランザクションを作成しインバウンドキャパシティを購入するが、その際に提供と支払いを同時に行うため、デュアル・ファンディングチャネルを前提としている。

つまり、チャネルを構築する際に、流動性の提供者と購入者それぞれがUTXOを持ち合い、初期残高は、

  • 提供者の残高:拠出額+流動性の購入費用
  • 購入者の残高:拠出額 - 流動性の購入費用

になる。正確には、オンチェーン手数料がこれに加味される。

BOLTの提案内容

BOLTでは、さらに流動性の提供をLNのゴシッププロトコルで配信できるようにする仕組みが(まだドラフトだけど)提案されている(冒頭に書いたC-Lightningに実験的に実装された機能)↓

https://github.com/lightningnetwork/lightning-rfc/blob/04843175f05e7fdcea8fa1cd730857f3d42c4ca3/proposals/010-will-fund-for-food.md

デュアル・ファンディングを可能にするv2 channelプロトコル上に構築され、流動性を提供したいユーザーは、node_announcementに資金提供するレートをセットして配信できるようになる。

これらの配信情報を見て、インバウンドキャパシティが欲しいユーザーは、request_fundstlvを含むopen_channel2リクエストをノードに送信して、チャネル開設のネゴシエーションを始め、提供側はwill_fundを含むメッセージでこれに応答する。

現状の提案では、流動性の貸出は4032ブロック、つまり約28日間とされてる。資金を貸出用にロックする期間であって、それが経過したらチャネルを閉じなければならないというものではない。

CSVを使ったロック

↑のZmnSCPxjの提案ではCLTVを使ったロックだったが、BOLTの定義では、CSVの使用に置き換わってる。具体的には流動性提供者の残高のCSVに、貸出金のライフタイムの期間分が加算される。

CLTV→CSVにすると、絶対時間指定がコミットメントトランザクションがブロックに入ってからの相対時間指定になるから、リース期間の指定にならないんじゃ?と疑問に思ったけど、別途update_blockheightというメッセージが定義されている。

update_blockheightメッセージは、チャネルの開設者のみが相手に送信できるメッセージで、文字通りブロック高を通知するメッセージになる。このメッセージを受け取ると、チャネルにセットされている流動性を提供しているアウトプットのCSVのタイムロックがブロック数に応じてデクリメントされる。

つまり、チャネル開設当初は、流動性を提供しているコミットメントトランザクションのアウトプット(Licky側のアウトプットには)通常のCSV値に加えて、4032ブロック分のCSV値が加算された値が設定されているが、チャネル開設後、ブロックチェーン上で新しいブロックが作られると、update_blockheightメッセージでそのブロック高を通知し、コミットメントトランザクションCSV値をデクリメントした状態で更新する。これにより、CSVによる相対時間だけど、CLTVによる絶対時間による流動性の貸出期間の制限と同様の制限を課すようにしたっぽい。なんでCLTV→CSVに変更されたのかは謎。

P2P環境で流動性を提供する試みが始まるという点で興味深い。またこういうオンチェーンに裏付け資産がある状態で、貸出をベースにした金融商品やサービスのアイディアも広がってくるかもしれない。