このドキュメントはトランポリンホップの使用を可能にするために、我々が既存のオニオンルーティングに加える追加機能について説明する。
ネットワークが成長するにつれて、ネットワーク全体を最新の状態に保つために、より多くの帯域幅とストレージが必要になる。支払い経路を見つけることは、より多くの計算能力を必要とし、制限のあるデバイスにとってはそれを持続不可能にする。
制限のあるデバイスはネットワークのごく一部のビューを持ち、トランポリンノードを利用して支払いを転送するようにする。この提案は、それでも匿名性を犠牲にしないよう送信者によって作成されたオニオンを使用している(ほとんどの場合、それはより大きな匿名セットを提供するだろう。)。
ネットワーク全体を追跡するノードは、option_trampoline_routing
のサポートを広告する必要がある。これらのトランポリンノードには、従来のオニオンルーティングよりも多くの手数料を稼ぐ機会がある。
送信者は、いくつかのトランポリンノードを選択し、対応するトランポリンオニオンTLVを作成する。続いて、最初のトランポリンノード宛のオニオンパケットの最後のper_hop
ペイロードにそのトランポリンオニオンを埋め込む。トランポリンノード間の経路計算はトランポリンノード辞退に委ねられる。
マーチャントは、送信者が良い最後のトランポリンノードを選択するのを支援するため、自身のインボイスに自身に近いいくつかのトランポリンノードを含めても良い。これはあくまでオプションなので、送信者はこのルーティングヒントを使ってもいいし、使わなくても良い。
興味深い副作用としては、トランポリンルーティングがランデブールーティングとうまく組み合わさっている点だ。単純な新しいTLVタイプとインボイスに含まれるデータが増えたことで、ランデブールーティングはトランポリン具ルーティングの上で簡単に機能し、ここで説明しているのと似た構造になる。
トランポリンオニオンは以下の構造を持つ、固定サイズのTLVパケット:
- タイプ:
trampoline_onion_packet
- データ:
- [
1
:0x08
] (type
) - [
3
:0xfde202
] (length
) - [
1
:version
] - [
33
:public_key
] - [
672
:tranpoline_hops_data
] - [
32
:hmac
]
- [
結果、742バイトの固定サイズのパケットとなり、値はonion_packet
とまったく同じ形式でhops_data
がより小さくなる。
trampoline_hops_data
フィールドは、trampoline_hop_payload
のリストで、次のトランポリンホップのアドレス、転送情報およびそれに関連するHMACの難読化データで構成される。またonion_packet
の可変サイズのper_hop
ペイロードと同じフォーマットを使用する。つまり、任意のTVLストリームを含められる:
- タイプ:
trampoline_hops_data
- データ:
- [
n1
:trampoline_hop_payload
] - [
n2
:trampoline_hop_payload
] - ...
filler
- [
各trampoline_hop_payload
は、以下の構造のデータ:
- タイプ:
trampoline_hop_payload
- データ:
- [
var_int
:length
] - [
length
:tlv_stream
] - [
32
:hmac
]
- [
tlv_stream
には、次のトランポリンホップにルーティングするために必要なデータが含まれている。そのデータをエンコードするために以下の型を使用できる:
- タイプ:
node_id
- データ:
- [
1
:0x02
] (type
) - [
1
:0x21
] (length
) - [
33
:node_id
]
- [
- タイプ:
amount_msat
- データ:
- [
1
:0x04
] (type
) - [
1
:length
] - [
length
:amount_msat_value
]
- [
- タイプ:
cltv
- データ:
- [
1
:0x06
] (type
) - [
1
:length
] - [
length
:cltv_value
]
- [
支払いを中継するためにトランポリンノードを使用したいノードは、onion_packet
の最後のホップのTLVストリームにtrampoline_onion_packet
を使用する:
- タイプ:
onion_packet
- データ:
- [
1
:version
] - [
33
:public_key
] - [
n1
:hop_payload
](通常のホップペイロード) - [
n2
:hop_payload
](通常のホップペイロード) - ...
- [
n
:hop_payload
](trampoline_onion_packet
を含むホップペイロード) filler
- [
32
:hmac
]
- [
最後のhop_payload
の構造は、以下のとおり:
- タイプ:
hop_payload
- データ:
- [
var_int
:length
] - [
742
:trampoline_onion_packet
] オプションのTLVをここに追加可能
- [
32
:hmac
]
- [
支払い先の受信者がトランポリンルーティングをサポートしていない場合は、最後のトランポリンノードに最後のホップを標準のオニオン支払いに変換してもらう。
最後のtrampoline_hop_payload
には、以下の構造のrecipient_info
TLVパケットが含まれてなければならない:
- タイプ:
recipient_info
- データ:
- [
1
:0x0a
] (type
) - [
1
:0x01
] (length
) - [
1
:0x00
] (option_trampoline_routing
)
- [
このデータは、受信者の身元と最後のトランポリンノードに支払われた金額を明らかにすることに注意すること(しかし送信者の身元を明らかにすることはない)。受信者がその身元を隠すためにランデブールーティングを使っている場合、これは回避できる。それ以外の場合、受信者は自身の匿名性を保つためにoption_trampoline_routing
をサポートすべきだ(そして、多くの支払いをルーティングしたくない場合は高めのfee
を広告することもできる)。
送信ノードは、
trampoline_onion_packet
の各ホップがoption_trampoline_routing
をサポートしていることを確認しなければならない。- 受信者が
option_trampoline_routing
をサポートしていない場合、option_trampoline_routing
を0x00
にセットしたTLVをrecipient_info
に含めなければならない。 onion_packet
と同じ構造で、trampoline_onion_packet
を暗号化しなければならない。trampoline_onion_packet
とonion_packet
で異なるsession_key
を使わなければならない。trampoline_hop_payload
内で、node_id
、amount_msat
およびcltv
以外のTLVタイプを使ってもいい。trampoline_hop_payload
に追加のTLVタイプを含めることができる。trampoline_onion_packet
を最後のホップのonion_packet
のペイロードに入れなければならない。
受信ノードはtrampoline_onion_packet
を処理する際、
option_trampoline_routing
をサポートしていない場合、起点ノードへ経路障害を報告しなければならない。trampoline_onion_packet
をonion_packet
として処理しなければならない。trampoline_onion_packet
の中で、未知の偶数のTLVタイプに遭遇したら、起点ノードへ経路障害を報告しなければならない。- 次のホップを見つけるのに十分なデータがない場合、起点ノードへ経路障害を報告しなければならない。
- 次のトランポリンホップへの経路を計算しなければならない:
cltv
要件を満たす経路が見つからない場合、起点ノードへ経路障害を報告しなければならない。fee
要件を満たす経路が見つからない場合、起点ノードへ経路障害を報告しなければならない。- 次のトランポリンホップとチャネルを開いている場合、シングルホップの経路を構築するのにそれを使ってもいい。
recipient_info
TLVのoption_trampoline_routing
が0x00
に設定されていた場合、trampoline_onion_packet
をonion_packet
に変換しなければならない。- それ以外では、最後の
hop_payload
にtrampoline_onion_packet
を含めてはならない。
- エラーハンドリングセクションで指定されているようにエラーを返す。
この構造はネットワークの不完全なビューを持つノードがトランポリンノードに経路の一部の構造を委任することを可能にする。
起点ノードはトランポリンノードのセットを選択し、最初のトランポリンノードへの経路を知る必要があるだけだ。各トランポリンノードは、次のトランポリンノードへの独自の経路を見つける必要がある。トランポリンノードは前のノード(これはトランポリンノードであってもなくてもいい)だけを知っている。
trampoline_onion_packet
はトランポリンノードが使用されるトランポリンノードの数を推測できないように固定サイズになっている。それはonion_packet
と同じ構造を使う。
トランポリンノードは、cltv
とfee
の要件を満たす経路を作成できる限り、自由にホップの数を決めることができる。利用可能な適切なチャネルがある場合、これには次のトランポリンノードへのシングルホップ支払い実行が含まれる。
trampoline_hop_payload
は、node_id
、amokunt_msat
、cltv
タイプを使って、次のトランポリンノードへの死はリアを作成するためのデータを指定する。これらのタイプを使用するのは必須ではなく、他のエンコードを使ってもいい(例えば、node_id
よりもノードアドレスを指定するよりコンパクトな方法が利用可能であればそれを使ってもいい)。
パケットサイズはトランポリンノードに最大8個の中間トランポリンノードと最大10個の中間ノードを許容するよう選択されている。
トランポリンルーティングを使って死hらいを送信するには、全てのトランポリンノードが、次のトランポリンノードにルーティングするのに十分なfees
とcltv
を受け取る必要がある。
以下のようなノードとチャネルを考える。
H1 -- H2 H4
/ \ / \
T1 T2 T3
\ / \ /
`---- H3 H5
それぞれ以下のcltv_expiry_delta
を各チャネルの最後に広告する:
- H1: 10 ブロック
- H2: 20 ブロック
- H3: 30 ブロック
- H4: 40 ブロック
- H5: 50 ブロック
- T1: 60 ブロック
- T2: 70 ブロック
- T3: 80ブロック
T3は支払いを要求する際に、デフォルトで9のmin_final_cltv_expiry
を使用する。
また、各ノードは各チャネルに使用する手数料体系がある。
- H1: 100 base + 1000 millionths
- H2: 200 base + 2000 millionths
- H3: 300 base + 3000 millionths
- H4: 400 base + 4000 millionths
- H5: 500 base + 5000 millionths
- T1: 600 base + 6000 millionths
- T2: 700 base + 7000 millionths
- T3: 800 base + 8000 millionths
アリスがランダム化されたcltvの有効期限が42で5000 satoshiの支払いをT3に送信すると仮定する。
T2はT3まで、H4を経由するケースとH5を経由するケースの2つの経路がある。
H4経由の経路の場合は以下のようになる。
- H4:
amount_msat
= 5000000 + 400 + ( 4000 * 5000000 / 1000000 ) = 5020400cltv_expiry
= current-block-height + 40 + 42 + 9onion_packet
:amt_to_forward
= 5000000outgoing_cltv_value
= current-block-height + 42 + 9
- T2
amount_msat
= 5020400 + 700 + ( 7000 * 5020400 / 1000000 ) = 5056243cltv_expiry
= current-block-height + 70 + 40 + 42 + 9onion_packet
:amt_to_forward
= 5020400outgoing_cltv_value
= current-block-height + 40 + 42 + 9
H5経由の経路の場合は以下のようになる。
- H5:
amount_msat
= 5000000 + 500 + ( 5000 * 5000000 / 1000000 ) = 5025500cltv_expiry
= current-block-height + 50 + 42 + 9onion_packet
:amt_to_forward
= 5000000outgoing_cltv_value
= current-block-height + 42 + 9
- T2:
amount_msat
= 5025500 + 700 + ( 7000 * 5025500 / 1000000 ) = 5061379cltv_expiry
= current-block-height + 70 + 50 + 42 + 9onion_packet
:amt_to_forward
= 5025500outgoing_cltv_value
= current-block-height + 50 + 42 + 9
T2は、これらいずれかの経路を使ったトランポリン支払いをルーティングするため次の値を広告する。
fees
: 1200 base + 12500 millionthscltv_expiry_delta
: 120 ブロック
T2→T3では、以下のトランポリン値が必要:
amount_msat
= 5000000 + 1200 + ( 12500 * 5000000 / 1000000 ) = 5063700cltv_expiry
= current-block-height + 120 + 42 + 9trampoline_onion_packet
:amt_to_forward
= 5000000outgoing_cltv_value
= current-block-height + 42 + 9
T1はT2まで、H1,H2を経由するケースとH3を経由するケースの2つの経路がある。
H1からH2を介したルーティングには、以下の値が必要:
- H2:
amount_msat
= 5063700 + 200 + ( 2000 * 5063700 / 1000000 ) = 5074028cltv_expiry
= current-block-height + 20 + 120 + 42 + 9onion_packet
:amt_to_forward
= 5063700outgoing_cltv_value
= current-block-height + 120 + 42 + 9
- H1:
amount_msat
= 5074028 + 100 + ( 1000 * 5074028 / 1000000 ) = 5079203cltv_expiry
= current-block-height + 10 + 20 + 120 + 42 + 9onion_packet
:amt_to_forward
= 5074028outgoing_cltv_value
= current-block-height + 20 + 120 + 42 + 9
- T1:
amount_msat
= 5079203 + 600 + ( 6000 * 5079203 / 1000000 ) = 5110279cltv_expiry
= current-block-height + 60 + 10 + 20 + 120 + 42 + 9onion_packet
:amt_to_forward
= 5079203outgoing_cltv_value
= current-block-height + 10 + 20 + 120 + 42 + 9
H3を介したルーティングには以下の値が必要:
- H3:
amount_msat
= 5063700 + 300 + ( 3000 * 5063700 / 1000000 ) = 5079192cltv_expiry
= current-block-height + 30 + 120 + 42 + 9onion_packet
:amt_to_forward
= 5063700outgoing_cltv_value
= current-block-height + 120 + 42 + 9
- T1:
amount_msat
= 5079192 + 600 + ( 6000 * 5079192 / 1000000 ) = 5110268cltv_expiry
= current-block-height + 60 + 30 + 120 + 42 + 9onion_packet
:amt_to_forward
= 5079192outgoing_cltv_value
= current-block-height + 30 + 120 + 42 + 9
T1は、これらいずれかの経路を使ったトランポリン支払いをルーティングするため次の値を広告する。
fees
: 900 base + 9500 millionthscltv_expiry_delta
: 90 ブロック
T1→T2では、以下のトランポリン値が必要:
amount_msat
= 5063700 + 900 + ( 9500 * 5063700 / 1000000 ) = 5112706cltv_expiry
= current-block-height + 90 + 120 + 42 + 9trampoline_onion_packet
:amt_to_forward
= 5063700outgoing_cltv_value
= current-block-height + 120 + 42 + 9
TODO:このセクションはまだスペックのフォーマットではない。スペックの取り組みを始める前に、進む道の同意を確認するための全体的な考えのドラフト。
制限のあるデバイス(電話、IoTデバイスなど)で実行されているノードは、自身と近くのチャネルのみ(例えばN
半径のヒューリスティックみたいに)を追跡する必要がある。これら近くのチャネルは、最初のトランポリンノードへのv0オニオンルートを構築するのに使われる。
制限ノードはmin_chan_capacity
より小さい容量のチャネルを無視するという選択もできる。N
とmin_chan_capacity
はノードによって設定されネットワークには広告されない。
制限ノードはこれらの要件を満たしていないchannel_announcement
を単純に無視する。
制限ノードはトランポリンとして使うため、彼らのネットワークビューの外側にあるノードに関する情報も格納する必要がある。
対照的にトランポリンノードは、支払いを効率的にルーティングできるようにネットワーク・トポロジーの全体像を把握する必要がある。
以下の構造を持つ新しいオプションのnode_update
メッセージを導入する。
- タイプ: 261(
node_update
) - データ:
- [
varint
:length
] - [
1
:0x02
] (type
) - [
1
:0x21
] (length
) - [
33
:node_id
] - [
1
:0x04
] (type
) - [
1
:0x40
] (length
) - [
64
:signature
] - [
1
:0x06
] (type
) - [
1
:0x20
] (length
) - [
32
:chain_hash
] - [
1
:0x08
] (type
) - [
1
:0x1e
] (length
) - [
4
:timestamp
] - [
2
:cltv_expiry_delta
] - [
8
:htlc_minimum_msat
] - [
8
:htlc_maximum_msat
] - [
4
:fee_base_msat
] - [
4
:fee_proportional_millionths
]
- [
これはchannel_update
メッセージに似た構造を持っているが、チャネルに依存しない。node_update
はchannel_update
が中継されるのと同じ方法(staggered broadcast)で中継される必要がある。
トランポリンノードは、インバウンドおよびアウトバウンドキャパシティを持つオープンチャネルを持つノードからnode_update
のみを受け入れて中継する必要がある。
ノードがトランポリンペイメントを中継する意思がない場合、ノードは単純にnode_update
を送信しない。これによりネットワークは、フォーマットを理解しているが送信者もしくは受信者としてのみ使用するノードからトランポリン支払いを中継できるノードを区別できる。
トランポリンノードは、他のノードと競合しながら他のトランポリンノードへルーティングできるようにするcltv_expiry_delta
とfee
を見積もる必要がある。これはトランポリンコストを最小限に抑えるようノードが互いにチャネルを開くよう動機付ける絶好の機会だ。これはノードが競争上の優位性としてスマート手数料見積もりアルゴリズムを実装するための大きな機会でもある。
ノードは非常に保守的で、到達可能な最も遠いノードに対応する最悪のケースのfee
とcltv_expiry_delta
を広告することがある。
対照的に、ノードは他の全てのトランポリンノードへ到達できないが、ほとんどの場合には上手く行くだろうより低いfee
およびcltv_expiry_delta
を見つけるためにネットワークの統計分析を適用するかもしれない。そのようなノードは、信頼性を高く持つため、いくつかの支払いは損失を含めてルーティングし、信頼性の評判を高めより多くの支払いを惹きつけることで全体的に利益を出すような選択ができる。
ノードはnode_update
にいくつかの優先ネイバーを含めることができ、これはこれらのノードに安価にルーティングできることを意味する。送信者はその情報を使ってもいいし使わなくてもいい。
トランポリンノードは、経済的実行可能な方法で支払いをルーティングできる場合(例えば次のトランポリンノードと直接もしくは安価な経路がある場合など)、広告している金額よりも低い手数料で支払いを受け入れることができる。
つまり使用しているfee/cltvでまだ適切にルーティングできると思われる場合、支払人は広告された手数料を完全に無視することを選択できる。
手数料の計算に関する詳細例については、手数料とCLTV要件を参照。
制限ノードはnode_update
メッセージを監視し、トランポリンとして使用するためそれらのいくつかを保存する必要がある。ノードはトランポリンノードを選択するためのヒューリスティックを自由に選択できる(匿名性のためにある程度のランダム性が望まれる)。
これにより制限ノードのストレージ要件が削減されるが、帯域幅の要件は削減されない。制限ノードは引き続きnode_update
およびchannel_update
メッセージをリッスンする必要がある(それらのほとんどは無視される)。
ゴシップの再送信の前に適用されるべきゴシップフィルタを導入する。制限ノードは、option_gossip_filters
をサポートするリモートノードにのみ接続する。そしてそのリモートノードとフィルタの調整をする。ゴシップメッセージを受信すると、リモートノードはフィルタを適用し、フィルタに一致するエントリーのみローカルノードに転送する。
※リモートノードはフィルタを完全に無視してローカルノードに全てのゴシップメッセージを転送することを決定できる。その場合、ローカルノードはリモートノードとの全てのチャネルを閉じ、接続を失敗し、より協調的なノードとチャネルを開く。
TODO:アイディアに同意する場合、init
フェーズとフィルタの調整要件が必要。
ローカルノードは、channel_update_filter
をリモードノードに送信できる。リモートノードは、channel_update
を送信する前にこのフィルタを適用する必要がある。これによりローカルノードは、ネットワークのごく一部の最新のビューを維持できる。
フィルタは単純な距離整数だ。リモートノードはリモートノード自体から最大ホップ数だけ離れているノードのchannel_update
のみを転送する必要がある。
このフィルタを計算することは、短い距離については安価だ。リモートノードは評価にコストがかかり過ぎる距離を拒否する必要がある。
TODO: アイディアに同意する場合はメッセージフォーマットの詳細を追加
ローカルノードはnode_update_filter
をリモートノードに送信できる。リモートノードはnode_update
を転送する前に、このフィルタを適用する必要がある。これによりローカルノードはトランポリンノードのリストを定期的に更新し、それらの手数料率とcltvを最新の状態に保つために関係するnode_update
のみを受け取ることができる。
ローカルノードは十分に信頼できるのであればトランポリンノードの同じセットを保持する選択をしてもいい。或いはローカルノードは、匿名性を改善し、新しい支払い経路をテストするためにトランポリンノードのセットを定期的にローテートしてもいい。この決定はユーザー/実装によって設定可能であるべき。
トランポリンノードのセットを頻繁にローテートする簡単なヒューリスティックは、node_id
とsha256(local_node_id || latest_block_hash)を比較し、これをNブロックごとに更新することだ。node_update_filter
は、これら2つの値の間の距離に基づいている。次に、ローカルノードは広告されている手数料/cltvと信頼性の評判(そのようなデータをを収集できる場合はその履歴データに基づいて)に基づいて、どのトランポリンノードを維持するか選択する。
TODO: アイディアに同意する場合はメッセージフォーマットの詳細を追加
ボブはトランポリンペイメントをサポートするマーチャントである。ボブは5000 satoshiのインボイスを作成し、そのインボイスにトランポリンルーティングをサポートする近隣の3つ(TB1およびTB2、TB3)を含める。
アリスはトランポリンペイメントでこのインボイスの支払いをしたい。アリスは自分が経路を知っている最初のトランポリンノード(TA1)を選択する。次に別のトランポリンノードTA2(近隣になくてもいい)を選択し、インボイスからトランポリンノードを1つ選択する(TB3)。
トランポリンルートは以下のようになる。
アリス -> TA1 -> TA2 -> TB3 -> ボブ
TA1の最新のnode_update
はcltv_expiry_delta = 20
およびfee = 3000 msat
を広告した。TA2のnode_update
は、cltv_expiry_delta = 15
で、fee = 2000 msat
。インボイスに記載されているTB3の詳細では、cltv_expiry_delta = 30
で、fee = 1000 msat
が指定されていた。
※ シンプルにするため、手数料は単一の固定値であるかのように動作する。
アリスは以下のtrampoline_onion_packet
を作成する(簡単にするため暗号化は省略)
- [
1
:0x08
] (type
) - [
3
:0xfde202
] (length
) - [
1
:version
] - [
33
:public_key
] - [
76
:trampoline_hop_payload
] (payload for TA1)- [
1
:0x4b
] (length
) - [
1
:0x02
] (type
) - [
1
:0x21
] (length
) - [
33
:TA2_node_id
] - [
1
:0x04
] (type
) - [
1
:0x03
] (length
) - [
3
:5003000
] (amt_to_forward
) - [
1
:0x06
] (type
) - [
1
:0x01
] (length
) - [
1
:70
] (outgoing_cltv_value
) - [
32
:hmac
]
- [
- [
76
:trampoline_hop_payload
] (payload for TA2)- [
1
:0x4b
] (length
) - [
1
:0x02
] (type
) - [
1
:0x21
] (length
) - [
33
:TB3_node_id
] - [
1
:0x04
] (type
) - [
1
:0x03
] (length
) - [
3
:5001000
] (amt_to_forward
) - [
1
:0x06
] (type
) - [
1
:0x01
] (length
) - [
1
:55
] (outgoing_cltv_value
) - [
32
:hmac
]
- [
- [
76
:trampoline_hop_payload
] (payload for TB3)- [
1
:0x4b
] (length
) - [
1
:0x02
] (type
) - [
1
:0x21
] (length
) - [
33
:Bob_node_id
] - [
1
:0x04
] (type
) - [
1
:0x03
] (length
) - [
3
:5000000
] (amt_to_forward
) - [
1
:0x06
] (type
) - [
1
:0x01
] (length
) - [
1
:25
] (outgoing_cltv_value
) - [
32
:hmac
]
- [
- [
76
:trampoline_hop_payload
] (payload for Bob)- [
1
:0x4b
] (length
) - [
1
:0x02
] (type
) - [
1
:0x21
] (length
) - [
33
:Bob_node_id
] - [
1
:0x04
] (type
) - [
1
:0x03
] (length
) - [
3
:5000000
] (payment_amt
) - [
1
:0x06
] (type
) - [
1
:0x01
] (length
) - [
1
:25
] (final_cltv_expiry
) - [
32
:hmac
] (0x00...00
)
- [
- [
368
:filler
] - [
32
:hmac
]
アリスは自身の近隣のビューからTA1の経路を見つける。
アリス -> H1 -> H2 -> TA1
簡単にするため、全ての中間ノードHiは固定の500 msat 手数料とcltv_expiry_delta=5
を広告すると仮定する。
アリスは以下のonion_packet
を作成する(簡単にするため暗号化は省略)
- [
1
:0x00
] (version
) - [
33
:public_key
] - [
65
:hop_payload
] (payload for H1)- [
1
:0x00
] (realm
) - [
8
:channel_from_H1_to_H2
] (short_channel_id
) - [
8
:5006500
] (amt_to_forward
) - [
4
:95
] (outgoing_cltv_value
) - [
12
:padding
] - [
32
:hmac
]
- [
- [
65
:hop_payload
] (payload for H2)- [
1
:0x00
] (realm
) - [
8
:channel_from_H2_to_TA1
] (short_channel_id
) - [
8
:5006000
] (amt_to_forward
) - [
4
:90
] (outgoing_cltv_value
) - [
12
:padding
] - [
32
:hmac
]
- [
- [
777
:hop_payload
] (payload for TA1)- [
3
:0xfde602
] (length
) - [
742
:trampoline_onion_packet
] - [
32
:hmac
] (0x00...00
)
- [
- [
393
:filler
] - [
32
:hmac
]
H1とH2は他のonion_packet
と同じようにonion_packet
を転送するが、それがトランポリンルーティング用であることを知らない。
TA1はonion_packet
を受け取り、trampoline_onion_packet
TLVを見つける。TA1は、trampoline_onion_packet
の1つの層を剥がして次のトランポリンホップ(TA2)を発見する。
TA1はTA2への経路を見つける。
TA1 -> H3 -> H4 -> TA2
TA1は以下のonion_packet
を作成する(簡単にするため暗号化は省略)
- [
1
:0x00
] (version
) - [
33
:public_key
] - [
65
:hop_payload
] (payload for H3)- [
1
:0x00
] (realm
) - [
8
:channel_from_H3_to_H4
] (short_channel_id
) - [
8
:5003500
] (amt_to_forward
) - [
4
:75
] (outgoing_cltv_value
) - [
12
:padding
] - [
32
:hmac
]
- [
- [
65
:hop_payload
] (payload for H4)- [
1
:0x00
] (realm
) - [
8
:channel_from_H4_to_TA2
] (short_channel_id
) - [
8
:5003000
] (amt_to_forward
) - [
4
:70
] (outgoing_cltv_value
) - [
12
:padding
] - [
32
:hmac
]
- [
- [
777
:hop_payload
] (payload for TA2)- [
3
:0xfde602
] (length
) - [
742
:trampoline_onion_packet
] (with the TA1 layer peeled) - [
32
:hmac
] (0x00...00
)
- [
- [
393
:filler
] - [
32
:hmac
]
TA1は事実上2000 msatの手数料を受け取った(受信した3000 msatとTA2にルーティングするために支払われる1000 msat)。
H3とH4は他のonion_packet
と同じようにonion_packet
を転送し、それがトランポリンルーティング用だとは知らない。
TA2はonion_packet
を受け取り、trampoline_onion_packet
TLVを見つける。TA2はtrampoline_onion_packet
の1つの層をはがして、次のトランポリンホップ(TB3)を発見する。
TA2はTB3とのチャネルを持っているため、以下のonion_packet
を作成する(簡単にするため暗号化は省略)
- [
1
:0x00
] (version
) - [
33
:public_key
] - [
777
:hop_payload
] (payload for TB3)- [
3
:0xfde602
] (length
) - [
742
:trampoline_onion_packet
] (with the TA2 layer peeled) - [
32
:hmac
] (0x00...00
)
- [
- [
523
:filler
] - [
32
:hmac
]
TA2は事実上2000 msatの手数料を受け取る(2000 msat受信し、TB3へのチャネルを既に持ってるので追加のルーティングコストがかからない)
TB3は、onion_packet
を受信し、trampoline_onion_packet
TLVを発見する。TB3はtrampoline_onion_packet
の1つの層をはがし、次のトランポリンホップ(ボブ)を発見する。TB3はボブが最後の受信者であることを知らない。
TB3はボブへの経路を探す。
TB3 -> H5 -> ボブ
TB3は以下のonion_packet
を作成する(簡単にするため暗号化は省略)
- [
1
:0x00
] (version
) - [
33
:public_key
] - [
65
:hop_payload
] (payload for H5)- [
1
:0x00
] (realm
) - [
8
:channel_from_H5_to_Bob
] (short_channel_id
) - [
8
:5000000
] (amt_to_forward
) - [
4
:25
] (outgoing_cltv_value
) - [
12
:padding
] - [
32
:hmac
]
- [
- [
777
:hop_payload
] (payload for Bob)- [
3
:0xfde602
] (length
) - [
742
:trampoline_onion_packet
] (with the TB3 layer peeled) - [
32
:hmac
] (0x00...00
)
- [
- [
458
:filler
] - [
32
:hmac
]
TB3は事実上500 msatの手数料を得る(1000 msat受信し、500 msat ボブへの経路に支払う)。
ボブはonion_packet
を受信し、trampoline_onion_packet
TLVを発見する。ボブはtrampoline_onion_packet
の層を1つはがし、自分が受信者であることを発見する(hmacが0x00...00
なので)。
有効な支払いルートは以下のとおり:
Alice TA1 TA2 -> TB3 Bob
| ^ | ^ | ^
| | | | | |
`---> H1 ---> H2 ---' `---> H3 ---> H4 ---' `---> H5 ---'
ボブはトランポリンペイメントをサポートしないマーチャントで、ルーティングのヒントのない5000 satoshiのインボイスを作成する。
アリスはこのインボイスにトランポリンルーティングを使って支払いたい。説明を短くするため、アリスは単一のトランポリンホップTを選択する。
トランポリン経路は、
アリス -> T -> ボブ
Tの最新のnode_update
では、cltv_expiry_delta=20
とfee=3000
msatが広告されていた。
簡単にするため、全ての中間ノードHiは固定の500 msat 手数料とcltv_expiry_delta=5
を広告すると仮定する。
アリスは以下のtrampoline_onion_packet
を作成する(簡単にするため暗号化は省略)
- [
1
:0x08
] (type
) - [
3
:0xfde202
] (length
) - [
1
:version
] - [
33
:public_key
] - [
79
:trampoline_hop_payload
] (payload for T)- [
1
:0x4e
] (length
) - [
1
:0x02
] (type
) - [
1
:0x21
] (length
) - [
33
:Bob_node_id
] - [
1
:0x04
] (type
) - [
1
:0x03
] (length
) - [
3
:5000000
] (amt_to_forward
) - [
1
:0x06
] (type
) - [
1
:0x01
] (length
) - [
1
:25
] (outoing_cltv_value
) - [
1
:0x0a
] (type
) - [
1
:0x01
] (length
) - [
1
:0x00
] (option_trampoline_routing
) - [
32
:hmac
] (0x00...00
)
- [
- [
593
:filler
] - [
32
:hmac
]
アリスはTへの経路を見つけて、onion_packet
内にtrampoline_onion_packet
をラップして送信する(前の例を参照)。
Tはtrampoline_onion_packet
を受け取り、ボブが支払先で、option_trampoline_routing
をサポートしていないことを発見する。
Tはボブへの経路を見つける。
T -> H1 -> H2 -> ボブ
Tは以下のonion_packet
を作成する(簡単にするため暗号化は省略)
- [
1
:0x00
] (version
) - [
33
:public_key
] - [
65
:hop_payload
] (payload for H1)- [
1
:0x00
] (realm
) - [
8
:channel_from_H1_to_H2
] (short_channel_id
) - [
8
:5000500
] (amt_to_forward
) - [
4
:30
] (outgoing_cltv_value
) - [
12
:padding
] - [
32
:hmac
]
- [
- [
65
:hop_payload
] (payload for H2)- [
1
:0x00
] (realm
) - [
8
:channel_from_H2_to_Bob
] (short_channel_id
) - [
8
:5000000
] (amt_to_forward
) - [
4
:25
] (outgoing_cltv_value
) - [
12
:padding
] - [
32
:hmac
]
- [
- [
65
:hop_payload
] (payload for Bob)- [
1
:0x00
] (realm
) - [
8
:0x0000000000000000
] (short_channel_id
) - [
8
:5000000
] (payment_amt
) - [
4
:25
] (final_cltv_expiry
) - [
12
:padding
] - [
32
:hmac
] (0x00...00
)
- [
- [
1105
:filler
] - [
32
:hmac
]
ボブはonion_packet
を受信し、自分が支払いの受信者であることを知る(hmacが0x00...00
であるため)。ボブはトランポリンルーティングが使われたことを知ること無く支払いを処理する。
効率的な支払いの経路は
Alice T Bob
| ^ | ^
| | | |
`-------' `---> H1 ---> H2 ---'