ピアのチャネルプロトコルには3つのフェーズ(確立・通常操作・クローズ)がある。
channel_id
チャネルを特定するために channel_id
が使用される。channel_id
は funding_txid
と funding_output_index
を結合することで資産トランザクションから作られる。チャネルを確立する前は、temporary_channel_id
(ランダムなナンス)が使われる。異なるピア間において重複した temporary_channel_id
が存在する可能性があるため、資産トランザクションが作成される前にそれらのチャネルを参照する API は固有に危険である。funding_created
が交換される前にチャネルに対してプロトコルが提供する識別子は(source_id, destination_id, temporary_channel_id)のタプルである。
接続の認証と初期化の後、チャネル確立が開始する。チャネルの確立はファンディングノード(funder)が open_channel
メッセージを送信し、応答ノード(fundee)が channel_accept
を送信することで構成される。チャネルパラメタがロックされることでファンディングノードは資産トランザクションと両バージョンのコミットメントトランザクションを作成できるようになる。そして、応答ノードバージョンのコミットメントトランザクションに署名を加えて、funding_created
メッセージで資産出力のアウトポイントを送信する。一度、応答ノードが資産のアウトポイントを得ると、ファンディングノードバージョンのコミットメントトランザクション署名を作成することができ、funding_signed
メッセージでそれを送ることができる。
ファンディングノードが一度 funding_sgned
メッセージを受け取ると、資産トランザクションを Bitcoin ネットワークにブロードキャストしなければならない。両者は funding_signed
メッセージを送信した(受信した)後、資産トランザクションがブロックチェーンに入り、特定の深さまで到達するまで待つ。両者が funding_locked
メッセージを送った後にチャネルは確立され、通常操作が始まる。funding_locked
メッセージはチャネル認証証明を構築するために使われる情報を含んでいる。
+-------+ +-------+
| |--(1)--- open_channel ----->| |
| |<-(2)-- accept_channel -----| |
| | | |
| A |--(3)-- funding_created --->| B |
| |<-(4)-- funding_signed -----| |
| | | |
| |--(5)--- funding_locked ---->| |
| |<-(6)--- funding_locked -----| |
+-------+ +-------+
- where node A is 'funder' and node B is 'fundee'
open_channel
Messageこのメッセージはノードについての情報や新しいチャネルを設定する要望を含んでいる。これは資産トランザクションや両バージョンのコミットメントトランザクションを作成する最初のステップである。
<TYPE>
chain_hash
の値は、オープンされたチャンネルが存在する正確なブロックチェーンを示す。これは通常、各ブロックチェーンのジェネシスハッシュである。chain_hash
の存在により、ノードは多くの異なるブロックチェーンをまたいでチャネルをオープンさせたり、同じピアで複数のブロックチェーンのチャネルをオープンすることができる(サポートされていれば)。temporary_channel_id
は資産トランザクションが確立されるまで、このチャネルを特定するために使用され、その後、資産トランザクションから作られる channel_id
によって置き換えられる。
funding_satoshis
は送信者がチャネルに入金している量を示している。put_msat
は受信者に無条件に与える初期投資の量を示している。dust_limit_satoshis
は、このノードのコミットメントまたはHTLCトランザクションのために出力を生成してはならないしきい値である(この金額以下のHTLCとHTLCトランザクションの手数料はオンチェーンでは強制できない)。これは小さい出力は通常のトランザクションとして見なされず、Bitcoin ネットワークを通してブロードキャストされない現実を反映している。channel_reserve_satoshis
は、他のノードが直接支払いとして保持する最低額である。htlc_minimum_msat
はこのノードが受け付ける HTLC の最小値を示している。
max_htlc_value_in_flight_msat
は未解決の HTLC の最大値、つまりノードが許す HTLC の影響を表す。同様に、max_accepted_htlcs
は他のノードが要求できる未解決 HTLC の制限値である。
feerate_per_kw
は 1000-weight ごとの初期手数料を示す(BOLT #3 参照)。
to_self_delay
は他のノードの自身への出力は遅延されなければならないブロックの数を示している。故障が発生した場合に自己資金を償還する前にどれくらい待たなければならないかを表す。
funding_pubkey
は資産トランザクション出力の 2-of-2 マルチシグスクリプトでの公開鍵である。
様々な **_basepoint
フィールドは各コミットメントトランザクションのための一意の鍵を作るために使われる。これらの鍵を変化させることで、たとえ1つのコミットメントトランザクションが見られたとしても、各コミットメントトランザクションのトランザクションIDが外部のオブザーバーには予測不可能であることを保証する。この特性は、ペナルティトランザクションを第三者にアウトソーシングする際にプライバシーを保護するために非常に有用である。
first_per_commitment_point
は最初のコミットメントトランザクションで使われるプレコミットメントポイントである。現在定義されているのは、channel_flags
の最下位ビットのみである(announce_channel
)。これはファンディングフローの発案者がこのチャネルをネットワークに公に広告したいかどうかを示している(BOLT #7 参照)。
shutdown_scriptpubkey
は送信ノードが相互クローズ時に資金がどこに行くかをコミットすることができ、後にノードが危殆化してもリモートノードが強制する必要がある。
option_support_large_channel
はみんなにこのノードは $s^{24}$ 以上の funding_satoshis
を受け入れることを知らせるために使われている特徴である。これは node_announcement
メッセージの中でブロードキャストされるので、他のノードは init
メッセージを交換する前でも、大きいチャネルを受け入れる意思のあるピアを識別するためにこれを使用することができる。
送信ノード(MUST):
chain_hash
がオープンしたいチャネルを特定することを保証しているtemporary_channel_id
は同じピアで他のチャネルIDと異なる一意の値であるoption_support_large_channel
を広告した場合:funding_satoshis
をセットする場合があるfunding_satoshis
をセットしなければならないfunding_satoshis
よりも小さい値を put_msat
にセットしなければならないfunding_pubkey
, revocation_basepoint
, htlc_basepoint
, payment_basepoint
, delayed_payment_basepoint
を圧縮形式で有効な secp256k1 公開鍵に設定しなければならないfirst_per_commitment_point
を設定しなければならないchannel_reserve_satoshi
は dust_limit_satoshis
以上の値を設定しなければならないchannel_flags
の未定義ビットにはゼロを設定しておくoption_upfront_shutdown_script
機能を広告した場合:shutdown scriptpubkey
によって要求される有効な shutdown_scriptpubkey
、または長さ0の shutdown_scriptpubkey
(例: 0x0000)のいずれかを持つ upfront_shutdown_script
を含まなければならないupfront_shutdown_script
が含まれる場合があるopen_channel_tlvs
を含む場合:upfront_shutdown_script
を含まなければならない送信ノード(SHOULD):
to_self_delay
を設定するべきであるfeerate_per_kw
を設定するdust_limit_satoshis
設定するhtlc_minimum_msat
を設定する受信ノード(MUST):
channel_flag
を無視するopen_channel
を受け取った後に、その接続が再確立された場合(ただし、funding_created
メッセージを受け取る前):open_channel
メッセージを受理するopen_channel
メッセージを廃棄する受信ノードは以下の場合、チャネルを失敗する可能性がある:
announce_channel
が false
(0)であっても、チャネルを公に広告したい場合funding_satoshi
が小さすぎる場合htlc_minimum_msat
が大きすぎると見なす場合max_htlc_value_in_flight_msat
が小さすぎると見なす場合channel_reserve_satoshis
が大きすぎると見なす場合max_accepted_htlcs
が小さすぎると見なす場合dust_limit_satoshis
が小さすぎて、データを失うイベントでそのコミットメントトランザクションを公開する受信ノードは以下の場合、チャネルを失敗させなければならない:
chain_hash
値を受け取った場合push_msat
が funding_satoshis
* 1000 よりも大きい場合to_self_delay
が不合理に大きい場合max_accepted_htlcs
が 483 より大きい場合feerate_per_kw
が時間的処理にとても小さい、もしくは不合理に大きい場合funding_pubkey
, revocation_basepoint
, htlc_basepoint
, payment_basepoint
, delayed_payment_basepoint
が圧縮方式での secp256k1 公開鍵で有効でない場合dust_limit_satoshis
が channel_reserve_satoshis
よりも大きいば場合to_local
と to_remote
量が channel_reserve_satoshis
以下の場合(BOLT #3 参照)funding_satoshis
が $2^24$ 以上であり、受信者が option_support_large_channel
をサポートしていない場合受信ノード(MUST NOT):
put_msat
を使用して受け取った資産を考慮してはいけないaccept_channel
Messagetemporary_channel_id
は open_channel
メッセージのチャネルIDと同じでなければならない。
送信者:
minimum_depth
でセットすべきであるfunding_satoshis
が $2^24 satoshi$ 以下であるという条件は、実装がまだ固定されていないなかでの一時的な自己制約であり、option_support_large_channel
を広告することで引き上げることができる。チャネル予備金はピアの channel_reserve_satoshis
(チャネルの1%が提案されている)によって特定される。チャネルの両者はこの予備金を管理しているため、もし古い、取りトランザクションをブロードキャストしようとした場合には、常に失うものがある。最初は、片方だけが資産を持っているためこの予備金は満たさない可能性がある。しかし、プロトコルはこの予備金に向かって常に処理を進めることを保証しており、一度入るとそれは維持される。
送信者は非ゼロ push_msat
を用いて初期資産を無条件で受信者に与えることができるが、この場合でも、出資者が手数料を支払うのに十分な残金を持っていることと、一方の側が支出できる金額を持っていることを保証する。feerate_per_kw
は通常、送信者にのみ関係する。しかし、HTLC トランザクションによる手数料率も存在するため、不合理に大きな手数料は受信者を罰することができる。
dust_limit_satoshis
に応じて channel_reserve_satoshis
がゴミとみなされないという要件は、すべての出力がゴミとして排除されてしまうようなケースを排除しています。
accept_channel
Messageこのメッセージはノードについての情報を含み、新しいチャネルの受理を示している。これは資産トランザクションと両者バージョンのコミットメントトランザクションの作成に向けての第二ステップである。
<TYPE2>
temporary_channel_id
は open_channel
メッセージのチャネルIDと同じでなければならない。
送信者:
minimum_depth
でセットすべきであるopen_channel
メッセージより、dust_limit_satoshis
以上の channel_reserve_satoshis
を設定しなければならないopen_channel
メッセージより、channel_reserve_satoshis
以下の channel_reserve_satoshis
を設定しなければならない受信者:
minimum_depth
が不合理に大きい場合:channel_reserve_satoshis
が open_channel
メッセージの dust_limit_satoshis
以下の場合:open_channel
メッセージの channel_reserve_satoshis
が dust_limit_satoshis
以下の場合:open_channel
の対応するフィールドと同じ要件を持つfunding_created
Messageこのメッセージは出資者が作った最初のコミットメントトランザクションの概要を説明するものである。funding_signed
を通してピアからの署名を受け取った後、資産トランザクションをブロードキャストする。
<TYPE3>
送信者(MUST):
temporary_channel_id
は open_channel
メッセージと同じ値を設定funding_txid
は非展性トランザクションの ID を設定funding_output_index
は資産トランザクション出力と一致するトランザクションの出力番号を設定(BOLT #3 参照)signature
は最初のコミットメントトランザクションの funding_pubkey
を使用した署名を設定(BOLT #3 参照)送信者(SHOULD):
受信者:
signature
が’正しくない場合:funding_output_index
は、それがchannel_id
に詰め込まれゴシッププロトコルを通して使用されるので、2 バイトにしかならない。65535 出力の制限は過度に重荷にならないはずだ。全て Segregated Witness 入力のトランザクションは非展性であるため、資産トランザクションの推奨事項となる。
funding_signed
Messageこのメッセージは出資者に最初のコミットメントトランザクションに必要な署名を与える。そのため、必要ならばそのトランザクションをブロードキャストして資産を払い戻すことができる。このメッセージはチャネルを特定するために channel_id
を含んでいる。それは、ビッグエンディアンと排他的論理和を用いて funding_txid
と funding_output_index
を結合させることで作成される(つまり、funding_output_index
は最後 2 バイトのみを変える)。
<TYPE4?>
両方のピア:
option_static_remotekey
や option_anchor_outputs
が交渉された場合:option_static_remotekey
や option_anchor_outputs
が全てのコミットメントトランザクションに適応される送信者(MUST)設定:
channel_id
は funding_created
メッセージより funding_txid
と funding_output_index
の排他的論理和受信者:
signature
が正当でない場合:funding_signed
を受け取る前に資産トランザクションをブロードキャストしてはいけないfunding_signed
を受け取った場合:最初にコミットメントトランザクションを生成する必要があるときに、この時点で option_static_remotekey
か option_anchor_outputs
を決定する。現在の接続のinit
メッセージ交換で通信された特徴ビットは、チャネルの全ライフタイムのチャネルコミットメントフォーマットを決定する。 後の再接続でこのパラメータがネゴシエートされなかった場合でも、このチャネルは option_static_remotekey
または option_anchor_outputs
を使用し続ける。
funding_locked
Messageこのメッセージは資産トランザクションが accept_channel
で要求された minimum_depth
に達成したことを示している。両ノードがこれを送信すると、チャネルは通常操作モードに入る。
<TYPE5?>
送信者(MUST):
funding_created
メッセージ内の funding_txid
と funding_output_index
によって与えられたアウトポイントが正確に funding_satoshis
を scriptpubkey
に支払う場合を除き、funding_locked
を送信しないminimum_depth
に達するまで待つ必要があるnext_per_commitment_point
を設定する(BOLT #3 参照)出資しないノード(fundee):
funding_locked
のさらに先のために待つ観点から、どちらかのノードは相手から合理的なタイムアウトの後に要求した応答が得られない場合、そのチャネルを失敗する可能性がある。
非出資者は資産のリスクがないため、これまでに実在したチャネルを単に忘れることができる。もし、チャネルを永遠に記憶している場合、DoS リスクが生まれる。従って、忘れることが推奨されている。
ノードは接続の相互にクローズを交渉することができ、彼らは自分らの資産を即座にアクセスでき、低い手数料で交渉することができる。
クローズは2つのステップからなる:
+-------+ +-------+
| |--(1)----- shutdown ------->| |
| |<-(2)----- shutdown --------| |
| | | |
| | <complete all pending HTLCs> | |
| A | ... | B |
| | | |
| |--(3)-- closing_signed F1--->| |
| |<-(4)-- closing_signed F2----| |
| | ... | |
| |--(?)-- closing_signed Fn--->| |
| |<-(?)-- closing_signed Fn----| |
+-------+ +-------+
shutdown
どちらかのノード(もしくは両方)はクローズを開始するために shutdown
メッセージを送ることができる(支払いたい scriptpubkey
を加えて)。
<TYPE6?>
送信者ノード:
funding_created
(出資者の場合)や funding_signed
(非出資者の場合)を送信しなかった場合:shutdown
を送信してはいけないfunding_locked
の前に shutdown
を送信する可能性がある(資産トランザクションが minimum_depth
に達する前)shutdown
を送信してはいけないshutdown
の後に update_add_htlc
を送信してはいけないshutdown
の後に更新メッセージを送信してはいけないshutdown
を送信した後の HTLC のルーティングは失敗するべきであるopen_channel
もしくは accept_channel
で非ゼロ長の shutdown_scriptpubkey
を送信した場合:scriptpubkey
で同じ値を送信する必要があるscriptpubkey
を設定する必要があるOP_DUP
OP_HASH160
20
20-bytes OP_EQUALVERIFY
OP_CHECKSIG
(pay to pubkey hash)OP_HASH160
20
20-bytes OP_EQUAL
(pay to script hash)OP_0
20
20-bytes (version 0 pay to witness pubkey)OP_0
32
32-bytes (version 0 pay to witness script hash)受信ノード:
funding_signed
(出資者の場合)もしくは funding_created
(非出資者の場合)を受信しなかった場合:scriptpubkey
が上記のフォームに当てはまらなかった場合:funding_locked
を送信していない場合:shutdown
メッセージに shutdown
で応答する可能性があるshutdown
を送信していない限り、ピアに目立った更新がなかった場合:shutdown
メッセージに shutdown
で応答しなければならないoption_upfront_script
特徴を広告し open_channel
もしくは accept_channel
での非ゼロ長の shutdown_scriptpubgkey
を受信ノードが受け取って、shutdown_scriptpubkey
が scriptpubkey
と等しくない場合:シャットダウンが開始されたときにチャネルの状態が常に "クリーン"(保留中の変更がない)であれば、そうでなかった場合にどのように振る舞うかという問題は回避される(送信者は常に最初に commitment_signed
を送信する)。一度 HTLC がクリアされると、ピアは即座にクローズ交渉を始める可能性があるため、そのコミットメントトランザクションへのさらなる更新を禁止する。
scriptpubkey
フォームは Bitcoin ネットワークによって有効な標準フォームのみを含んでいる。
option_upfront_shutdown_script
特徴は、ノードが何らかの形で侵害された場合に備えて、shutdown_scriptpubkey
に事前にコミットしておきたかったことを意味する。これは弱いコミットメントであるが、scriptpubkey
を変更するために受信ノードの協力を要求することによってセキュリティの定期的向上を提供する。
shutdown
応答要求は、ノードが応答する前に未処理の変更をコミットするために commitment_signed
を送信することを意味しているが、理論的には代わりに再接続することも可能である。
closing_signed
一度シャットダウンが完了し、チャネルが HTLC の空になると、最終的なカレントコミットメントトランザクションは HTLC がなくなり、クローズ手数料交渉が始まる。出資者は公平と思う手数料を選択し、shutdown
メッセージの scriptpubkey
フィールドでクローズトランザクションに署名を行い、その署名を送信する。他のノードも公平と思う手数料を使って同様に応答する。この交換は、両者が同じ手数料に合意するかどちらかがチャネルを失敗するまで続ける。
<TYPE7>
出資ノード:
shutdown
を受け取り、HTLC がどちらかのコミットメントトランザクションに残っていない場合:closing_signed
メッセージを送信するべきである送信ノード:
fee_satoshis
は最終コミットメントトランザクションの基本手数料以下を設定しなければならないfee_satoshis
はブロックに含まれるコストの推定に従って設定するべきであるsignature
を設定しなければならない(BOLT #3 参照)受信ノード:
signature
が正当でなかった場合:fee_satoshis
が前に送った fee_satoshis
と等しい場合:fee_satoshis
が最終コミットメントトランザクションの基本手数料よりも大きい場合:fee_satoshis
が正確に最後に送った fee_satoshis
と前に受け取った fee_satoshis
の間ではなかった場合:fee_satoshis
と同じ値の closing_signed
で応答するべきである"正確な中間" の要求は、たとえ一度に1つの satoshi だけであっても、前進が確実に行われることを保証する。状態を維持することを避け、切断と再接続の間に料金が移動してしまったというコーナーケースに対処するために、再接続の際に交渉を再開する。
一度、両ノードが funding_locked
を交換すると、そのチャネルは HTLC を通して支払いをするために使用できる。変更はバッチで送信される。次の図のように、1つ以上の update_
メッセージが commitment_signed
メッセージの前に送信される。
+-------+ +-------+
| |--(1)---- update_add_htlc ---->| |
| |--(2)---- update_add_htlc ---->| |
| |<-(3)---- update_add_htlc -----| |
| | | |
| |--(4)--- commitment_signed --->| |
| A |<-(5)---- revoke_and_ack ------| B |
| | | |
| |<-(6)--- commitment_signed ----| |
| |--(7)---- revoke_and_ack ----->| |
| | | |
| |--(8)--- commitment_signed --->| |
| |<-(9)---- revoke_and_ack ------| |
+-------+ +-------+
これらの更新は他のノードのコミットメントトランザクションに適応される。遠隔ノードが revoke_and_ack
を通してそれらを適応することを認めるとき、自身のコミットメントトランザクションに更新を追加するだけである。したがって、各更新は以下の状態を通過する。
2 つのノードの更新が独立しているため、2つのコミットメントトランザクションはいつまでも同期しない可能性がある。これは問題ではない。問題なのは、双方が特定の更新に取り消し不可能なコミットをしているかどうかである。
一般的にはノードは2つの理由で HTLC を提供する(自身の支払いを開始するため、他のノードの支払いをフォワードするため)。転送する場合、受信した HTLC が払い戻されない限り、送信する HTLC は払い戻しされないことを保証することに注意する必要がある。以下の必要条件はこれを常に真実であると保証している。
HTLC の 追加/削除 はそれぞれ取り消し不可能でコミットされていると見なす。
ノード:
update_add_htlc
)を提供してはいけないupdate_fail_htlc
)を失敗してはいけないcltv_expiry
が一度達成する、もしくは cltv_expiry
- current_height
が対応した送信 HTLC の cltv_expiry_delta
より小さい場合:update_fail_htlc
)を失敗しなければならないcltv_expiry
が不合理に遠い場合:update_fail_htlc
)を失敗するべきであるupdate_fulfill_htlc
を受信する場合、もしくはオンチェーン HTLC 支出から payment_preimage
を発見した場合:一般的には、交換の一方を先に処理する必要がある。HTLC を満たすことは難しい。プレイメージの知識は取り消し不可能で、受信 HTLC は遅延を減らすためにできるだけ早く満たすべきである。不合理に期限の長い HTLC は DoS ベクタであるため許されない。"不合理" という正確な値は現在明確ではなく、ネットワークトポロジーに依存する可能性がある。
cltv_expiry_delta
Selection一度 HTLC がタイムアウトすると、それは満たされるか、タイムアウトされるかどちらかである。この移行の際には、提供された HTLC と受信した HTLC の両方に注意が払われなければならない。
以下のシナリオを考える。A が B に HTLC を送る。B は C にフォワードする。C は支払いを受け取るとすぐに商品を発送する。
cltv_expiry_delta
はフォワーディングする場合(B)の HTLC CLTV タイムアウトでの最小誤差である。min_final_cltv_expiry
は ターミナルの場合(C)の HTLC CLTV タイムアウトと現在のブロック高の最小誤差である。
送信と受信の HTLC 解決の間の最悪の場合のブロック数は、いくつかの仮定が与えられた場合に導出することができる。
R
G
S
フォワーディングするノード(B)にとっての最悪なケースは、HTLC 達成を見出すのに可能な限り長い時間がかかり、また、オンチェーンで換金するのにも可能な限り長い時間がかかることである。
N
でタイムアウトし、B は C を待つのをやめるまでG
ブロック待つ。B もしくは C がブロックチェーンにコミットし、B が HTLC を支出する(ブロックに含まれてから S
経過して)。N+G+S+1
を見たときだけそのトランザクションを見ている。R
深度リオルグがある。B は N+G+S+R
でのトランザクションしか見ていない。G
ブロック待つ。A か B はブロックチェーンにコミットする。N+G+R+G+1
で見て、S ブロックがマイニングされて、HTLC 出力を支出しなければならない。R
深度の他のリオクグがある。そのため、B は A のコミットメントトランザクションを N+G+S+R+G+R
ブロックで見て、S
ブロックがマイニングされた HTLC 出力が支出されなければならない。R
深度である必要があり、そうでなければ他のリオルグは A がそのトランザクションをタイムアウトすることを可能にする。従って、最悪の場合は 3R+2G+2S
である。高い手数料が使用されるため、S
は通常操作の間は小さくするべきである。
ブロック時間が不規則であること、空のブロックが発生すること、手数料が大きく変化すること、HTLC トランザクショ ンで手数料をぶつけることができないことを考えると、S=12 は最小値であると考えるべきである。S はまた、攻撃を受けたときに最も変化しやすいパラメータでもあるので、無視できない金額がリスクにさらされているときには、より高い値が望ましいかもしれない。猶予期間 G は、ノードがタイムアウトするか、できるだけ早くフルフィルすることが要求されるため、低くてもよい(1 または 2)。
しかし、ブロック時間が不規則であること、空のブロックがまだ発生すること、手数料が大きく変化すること、HTLC トランザクショ ンで手数料をバンプさせることができないことを考えると、S=12 は最小値であると考えるべきである。S
はまた、攻撃を受けたときに最も変化しやすいパラメータでもあるので、無視できない金額がリスクにさらされているときには、より高い値が望ましいかもしれない。猶予期間 G
は、ノードがタイムアウトするか、できるだけ早くフルフィルすることが要求されるため、低くてもよい(1 または 2)。
4 つの値を作る必要がある。
cltv_expiry_delta
(3R+2G+2S):もし疑わしい場合は少なくとも 34 の cltv_expiry_delta
が妥当である(R=2, G=2, S=12)。cltv_expiry
の後の G
ブロックです。1 ブロックか 2 ブロックが妥当です。cltv_expiry
の前にチャネルが失敗して HTLC がオンチェーンで満たされなければならない期限。cltv_expiry
の前に 2R+G+S
ブロックのデッドラインを暗示する上記のステップ 4-7 を参照する。18 ブロックが合理的である。cltv_expiry
:末端ノード C の最悪ケースの場合、2R+G+S
ブロックである。提供ノード:
cltv_expiry
の前にした HTLC を提供してはいけない満たす(提供を受ける)ノード:
update_add_htlc
どちらかのノードが他のノードに HTLC を提供するために、支払いのプレイメージを引き換えに交換可能な update_add_htlc
を送ることができる。オンチェーンでの施行はダストリミットを超える全量のサトシに対してのみ可能である。
送信ノード:
feerate_per_kw
でローカルまたはリモートコミットメントトランザクションのいずれかの料金を支払うことができない場合は、amount_msat
を提供してはならないoption_anchor_outputs
がこのコミットメントトランザクションが適応され、送信ノードが出資者である場合:to_local_anchor
と to_remote_anchor
には、そのリザーブ以上の金額を追加で支払うことができなければならないamount_msat
を提供すべきではない。この "料金スパイクバッファ" は、実装間の予測可能性を確保するために、現在の feerate_per_kw
の 2 倍を扱うことが推奨されているfeerate_per_kw
で更新されたローカルまたはリモートトランザクションの料金を支払うことができない場合、amount_msat
を提供すべきではないamount_msat
は 0 より大きくしなければならないhtlc_minimum_msat
以下の amount_msat
を提供してはいけないcltv_expiry
を設定しなければならないchain_hash
を持つチャネルの場合:amount_msat
の最上位 4 バイトを 0 に設定しなければならないmax_accepted_htlcs
HTLC よりも多くの HTLC をリモートのコミットメントトランザクションで提供している場合:max_htlc_value_in_flight_msat
を超える場合:id
に 0 を設定しなければならないid
の値を 1 ずつ増加させなければならないid
は更新が完了したあと(revoke_and_ack
を受け取ったあと)に 0 にリセットしてはいけない。代わりにインクリメントしなければならない。
受信ノード:
amount_msat
が 0 であり、自身の htlc_minimum_msat
より小さい場合:feerate_per_kw
では余裕がない amount_msat
を受信する(チャンネルリザーブと to_local_anchor
と to_remote_anchor
のコストを維持している間)場合:max_accepted_htlcs
HTLC を超える HTLC をローカルコミットトランザクションに追加した場合、または、提供された HTLC の受信者の max_htlc_value_in_flight_msat
の価値を超える HTLC をローカルコミットトランザクションに追加した場合:cltv_expiry
を 500000000 以上に設定する場合:chain_hash
を持つチャネルで、amount_msat
の最上位 4 バイトが 0 ではない場合:payment_hash
を持つ複数の HTLC を可能にしなければならないid
値を無視しなければならないid
違反が発生した場合:onion_routing_packet
は、パスに沿った各ホップの難読化されたリストと指示を含んでいる。これは、payment_hash を関連付けられたデータとして設定することで HTLC にコミットする(すなわち、HMAC の計算に payment_hash
を含める)。これは、以前の onion_routing_packet
を異なる payment_hash
で再利用するリプレイ攻撃を防ぐ。
もしノードが同じ支払いハッシュを持つ複数の HTLC を受け入れない場合、攻撃者はノードが既存の HTLC を持っているかどうかを調べることができる。この要件は、重複に対処するために、別個の識別子を使用することにつながる。max_accepted_htlcs
は、双方が最大数の HTLC を送信しても、commitment_signed
メッセージが最大メッセージサイズ以下になることを確実にするために 483 に制限されている。これはまた、単一のペナルティトランザクションがコミットメントトランザクション全体を費やすことができることを保証する。
cltv_expiry
の値が 500000000 以上の場合は秒単位の時間を示し、プロトコルはブロック単位の有効期限のみをサポートする。amount_msat
は、このバージョンの仕様では意図的に制限されている。Bitcoin 料金を支払う責任のあるノードは、将来の料金の増加に対応するために、リザーバの上に「料金スパイクバッファ」を維持しなければならない。このバッファがなければ、Bitcoin 料金を支払う責任のあるノードは、チャネルリザーバを維持しながら、非dust HTLCを送受信できない状態に達し、結果としてチャネルが劣化する可能性がある。
update_fulfill_htlc
, update_fail_htlc
, update_fail_malformed_htlc
For simplicity, a node can only remove HTLCs added by the other node. There are four reasons for removing an HTLC: the payment preimage is supplied, it has timed out, it has failed to route, or it is malformed.
The reason field is an opaque encrypted blob for the benefit of the original HTLC initiator, as defined in BOLT #4; however, there's a special malformed failure variant for the case where the peer couldn't parse it: in this case the current node instead takes action, encrypting it into a update_fail_htlc for relaying.
commitment_signed
あるノードがリモートコミットメントに対する変更を持っている時、それらを適応することができ、結果として生じるトランザクションに署名することができ、commitment_signed
メッセージを送ることができる。
送信ノード:
commitment_signed
メッセージを送信してはいけないcommitment_signed
メッセージを送信する可能性があるcommitment_signed
メッセージを送信する可能性がある。htlc_signature
を含んでいる必要があるping
を使い、commitment_signed
送る前に pong
応答を待つべきである受信ノード:
signature
が正当である場合:num_htlc
がローカルコミットメントの HTLC 出力の数と一致しない場合:htlc_signature
が対応する HTLC トランザクションに対して正当でない場合:revoke_and_ack
メッセージで応答する必要があるnum_htlcs
フィールドは冗長だが、パケット長チェックを完全に自己完結型にする。最近のメッセージを要求することの推奨は、ネットワークが信頼できないという現実(ノードは、commitment_signed
を送信した後でないと相手がオフラインであることに気づかないかもしれない)を認識している。一旦 commitmentment_signed
が送信されると、送信者はそれ自身をそれらの HTLC にバインドされていると考え、出力された HTLC が完全に解決されるまでは、関連する受信 HTLC を失敗させることはできない。
htlc_signature
は、提供された HTLC
がタイムアウトした場合や受信した HTLC
が使用された場合に、暗黙のうちにタイムロック機構を強制することに注意してください。これは、HTLC
出力に明示的にタイムロックを記述する場合に比べて、より小さなスクリプトを作成することで料金 を削減するために行われている。
option_anchor_outputs
は、HTLC
トランザクションが他の入力と出力を添付することで「自分の料金を持ってくる」ことを可能にし、それゆえに修正された署名フラグがある。
revoke_and_ack
一度、commitment_signed
の受信者が署名を確認し、正当な新しいコミットメントトランザクションだとわかると、revoke_and_ack
メッセージでの前のコミットメントトランザクションのためのコミットメントプレイメージで応答する。このメッセージは commitment_signed
の領収書の承認として暗に提供されるため、これは commitment_signed
の送信者が、その commitment_signed
の前に送信した保留で中の更新を(自分のコミットメントに)適用する論理的な時間である。
送信ノード:
per_commitment_secret
を設定しなければならないnext_per_commitment_point
を設定しなければならない受信ノード:
per_commitment_secret
が前の per_commitment_point
を生成しない場合:per_commitment_secret
が BOLT #3 でのプロトコルによって生成されていない場合:ノード:
update_fee
update_fee
メッセージは Bitcoin 手数料を支払うノードによって送信される。どんな更新でも、最初に受信者のコミットメントトランザクションにコミットされ、そのあとに送信者のをコミットされる。HTLC とは異なり update_fee
は決してクローズされないが、単に置き換えられる。
受信者は update_fee
を受け取る前に新しい HTLC を追加することができるため、競合の可能性がある。この環境のもと、一度受信者によって update_fee
が最終的に認められると、送信者は自身のコミットメントトランザクションでの手数料に余裕を持たせることができない可能性がある。
Bitcoin 手数料を支払う責任があるノード:
update_fee
を送信するべきである責任のないノード:
update_fee
を送信してはいけない受信ノード:
update_fee
がタイムリーな処理のために小さすぎる、もしくは不合理に大きすぎる場合:update_fee
がコミットされるまでチェックに遅延がかかる可能性がある)Bitcoin 手数料は一方向クローズを有効にするために必要である。option_anchor_outputs
によって feerate_per_kw
はレガシーのコミットメント形式の時のように確認を保証するために重要ではなくなったが、mempool に入るためには十分な量が必要である。
現在、手数料は一方(チャネル作成を要求したノードが常にコミットメントトランザクションの手数料を支払う)であるため、それに手数料レベルを設定することを可能にすることは最もシンプルである。しかし、同じ手数料レートが HTLC にも適応されるため、受信ノードは手数料の公平性に注意しなければならない。