本文档详细描述了闪电网络通道管理对等协议,该协议分为建立、正常运行和关闭三个阶段。
对等通道协议有三个阶段:建立、正常运行和关闭。
channel_id
的定义一些消息使用 channel_id
来标识通道。它从 funding transaction(资金交易)派生而来,方法是将 funding_txid
和 funding_output_index
组合起来,使用大端序异或(即 funding_output_index
更改最后 2 个字节)。
在通道建立之前,使用 temporary_channel_id
,这是一个随机 nonce。
请注意,由于来自不同对等点的重复 temporary_channel_id
可能存在,因此在创建资金交易之前,通过其通道 ID 引用通道的 API 本质上是不安全的。 在交换 funding_created
之前,协议提供的唯一通道标识符是 (source_node_id
, destination_node_id
, temporary_channel_id
) 元组。 请注意,在资金交易确认之前,任何通过其通道 ID 引用通道的此类 API 也不是持久的——在你知道对应于资金输出的 script pubkey 之前,没有任何因素可以阻止重复的通道 ID。
在进行身份验证和初始化连接后(分别参见 BOLT #8 和 BOLT #1),可以开始通道建立。这包括资金节点(funder)发送 open_channel
消息,然后响应节点(fundee)发送 accept_channel
。 锁定通道参数后,funder 可以创建 funding transaction 和两种版本的 commitment transaction,如 BOLT #3 中所述。 然后,funder 通过 funding_created
消息发送 funding output 的输出点(outpoint),以及 fundee 版本的 commitment transaction 的签名。 一旦 fundee 获知 funding outpoint,它就能够生成 funder 版本的 commitment transaction 的签名,并使用 funding_signed
消息发送它。
一旦通道 funder 收到 funding_signed
消息,它必须将 funding transaction 广播到比特币网络。 发送/接收 funding_signed
消息后,双方应等待 funding transaction 进入区块链并达到指定的深度(确认数)。 在双方都发送了 funding_locked
消息后,通道建立完成,可以开始正常运行。 funding_locked
消息包含将用于构建通道身份验证证明的信息。
+-------+ +-------+
| |--(1)--- open_channel ----->| |
| |<-(2)-- accept_channel -----| |
| | | |
| A |--(3)-- funding_created --->| B |
| |<-(4)-- funding_signed -----| |
| | | |
| |--(5)--- funding_locked ---->| |
| |<-(6)--- funding_locked -----| |
+-------+ +-------+
- 其中节点 A 是 'funder',节点 B 是 'fundee'
如果在任何阶段失败,或者如果一个节点认为另一节点提供的通道条款不合适,则通道建立失败。
请注意,多个通道可以并行运行,因为所有通道消息都由 temporary_channel_id
(在创建 funding transaction 之前)或 channel_id
(从 funding transaction 派生)标识。
open_channel
消息此消息包含有关节点的信息,并表明其希望设置新通道。这是创建 funding transaction 和两种版本的 commitment transaction 的第一步。
类型:32 (open_channel
)
数据:
chain_hash
:chain_hash
]32*byte
:temporary_channel_id
]u64
:funding_satoshis
]u64
:push_msat
]u64
:dust_limit_satoshis
]u64
:max_htlc_value_in_flight_msat
]u64
:channel_reserve_satoshis
]u64
:htlc_minimum_msat
]u32
:feerate_per_kw
]u16
:to_self_delay
]u16
:max_accepted_htlcs
]point
:funding_pubkey
]point
:revocation_basepoint
]point
:payment_basepoint
]point
:delayed_payment_basepoint
]point
:htlc_basepoint
]point
:first_per_commitment_point
]byte
:channel_flags
]open_channel_tlvs
:tlvs
]tlv_stream
: open_channel_tlvs
类型:
upfront_shutdown_script
)...*byte
:shutdown_scriptpubkey
]channel_type
)...*byte
:type
]chain_hash
值表示打开的通道将驻留在的确切区块链。这通常是相应区块链的创世哈希。 chain_hash
的存在允许节点跨许多不同的区块链打开通道,以及与同一对等点打开多个区块链内的通道(如果它支持目标链)。
在建立 funding transaction 之前,temporary_channel_id
用于在每个对等点的基础上标识此通道,此时它将被从 funding transaction 派生的 channel_id
替换。
funding_satoshis
是发送方放入通道的金额。 push_msat
是发送方无条件给予接收方的初始资金金额。 dust_limit_satoshis
是低于该阈值不应为此节点的 commitment 或 HTLC transaction 生成输出的阈值(即,低于此金额加上 HTLC transaction 费用的 HTLC 在链上不可强制执行)。 这反映了微小输出不被认为是标准交易并且不会通过比特币网络传播的现实。 channel_reserve_satoshis
是另一个节点要保留的最小金额,作为直接付款。 htlc_minimum_msat
指示此节点将接受的最小价值 HTLC。
max_htlc_value_in_flight_msat
是未完成 HTLC 总价值的上限,允许节点限制其对 HTLC 的风险;同样,max_accepted_htlcs
限制了另一节点可以提供的未完成 HTLC 的数量。
feerate_per_kw
指示每 1000 权重(即,通常使用的“每 1000 vbytes 的 satoshi”的 1/4)的初始费用率,该费用为此侧将支付 commitment 和 HTLC transaction 的费用,如 BOLT #3 中所述(稍后可以通过 update_fee
消息进行调整)。
to_self_delay
是另一个节点的 to-self 输出必须延迟的块数,使用 OP_CHECKSEQUENCEVERIFY
延迟; 这是在发生故障时,它在赎回自己的资金之前必须等待的时间。
funding_pubkey
是 funding transaction 输出的 2-of-2 multisig 脚本中的公钥。
各种 _basepoint
字段用于派生唯一密钥 BOLT #3 中所述,用于每个 commitment transaction。 更改这些密钥可确保每个 commitment transaction 的 transaction ID 对于外部观察者来说是不可预测的,即使看到一个 commitment transaction 也是如此; 此属性对于在将惩罚 transaction 外包给第三方时保持隐私非常有用。
first_per_commitment_point
是要用于第一个 commitment transaction 的 per-commitment point。
目前仅定义了 channel_flags
的最低有效位:announce_channel
。 这表明 funding flow 的发起者是否希望向网络公开宣传此通道,如 BOLT #7 中详细说明。
shutdown_scriptpubkey
允许发送节点承诺在相互关闭时资金将流向何处,即使节点稍后遭到破坏,远程节点也应强制执行该承诺。
option_support_large_channel
是一种功能,用于让每个人都知道此节点将接受大于或等于 2^24 的 funding_satoshis
。由于它是在 node_announcement
消息中广播的,因此其他节点甚至可以在与它们交换 init
消息之前使用它来识别愿意接受大型通道的对等点。
通道类型是一个显式枚举:为了将来定义的方便,它们重用甚至特征位,但它们不是任意组合(它们表示影响通道操作的持久特征)。
当前定义的类型是:
option_static_remotekey
(bit 12)option_anchor_outputs
和 option_static_remotekey
(第 20 位和第 12 位)option_anchors_zero_fee_htlc_tx
和 option_static_remotekey
(第 22 位和第 12 位)发送节点:
chain_hash
值标识它希望在其内打开通道的链。temporary_channel_id
与同一对等点的任何其他通道 ID 是唯一的。option_support_large_channel
:
funding_satoshis
设置为大于或等于 2^24 satoshi。funding_satoshis
设置为小于 2^24 satoshi。push_msat
设置为等于或小于 1000 * funding_satoshis
。funding_pubkey
、revocation_basepoint
、htlc_basepoint
、payment_basepoint
和 delayed_payment_basepoint
设置为压缩格式的有效 secp256k1 公钥。first_per_commitment_point
设置为用于初始 commitment transaction 的 per-commitment point,如 BOLT #3 中指定的派生。channel_reserve_satoshis
设置为大于或等于 dust_limit_satoshis
。channel_flags
中的未定义位设置为 0。option_upfront_shutdown_script
功能:
upfront_shutdown_script
,其中包含 shutdown_scriptpubkey
所需的有效 shutdown
scriptpubkey
,或者零长度的 shutdown_scriptpubkey
(即 0x0000
)。upfront_shutdown_script
。open_channel_tlvs
:
upfront_shutdown_script
。option_channel_type
:
channel_type
channel_type
:
发送节点应该:
to_self_delay
,以确保发送方可以在接收方行为不端的情况下不可逆转地花费 commitment transaction 输出。feerate_per_kw
设置为至少可以使其 transaction 立即包含在块中的估计速率。dust_limit_satoshis
设置为足够的值,以允许 commitment transaction 通过比特币网络传播。htlc_minimum_msat
设置为其愿意从此对等方接受的最小价值 HTLC。接收节点必须:
channel_flags
中的未定义位。open_channel
之后,但在收到 funding_created
消息之前,连接已重新建立:
open_channel
消息。open_channel
消息。如果满足以下条件,则接收节点可以使通道失败:
option_channel_type
,但消息不包含 channel_type
announce_channel
为 false
(0
),但它希望公开声明该通道。funding_satoshis
太小。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
。dust_limit_satoshis
小于 354 satoshis
(参见 BOLT 3)。to_local
和 to_remote
金额都小于或等于 channel_reserve_satoshis
(参见 BOLT 3)。funding_satoshis
大于或等于 2^24 并且接收方不支持 option_support_large_channel
。channel_type
,channel_type
已设置,并且 type
不合适。接收节点不得:
push_msat
收到的资金已收到。在实施尚未被认为是稳定时,要求 funding_satoshis
小于 2^24 satoshi 是一个临时的自我施加的限制,可以通过声明 option_support_large_channel
来取消。
通道储备金由对等方的 channel_reserve_satoshis
指定:建议占通道总额的 1%。 通道的每一方都维护此储备金,因此如果它尝试广播旧的、被撤销的 commitment transaction,它总是会损失一些东西。 最初,可能无法满足此储备金,因为只有一方拥有资金; 但该协议确保始终朝着满足此储备金取得进展,并且一旦满足,就会保持不变。
发送方可以使用非零 push_msat
无条件地向接收方提供初始资金,但即使在这种情况下,我们也要确保 funder 有足够的剩余资金来支付费用,并且一方可以花费一定的金额(这也意味着至少有一个非尘埃输出)。 请注意,像任何其他链上 transaction 一样,只有在 funding transaction 得到充分确认(在此之前存在双重支出的风险)之后,此付款才是确定的,并且可能需要单独的方法来通过链上确认来证明付款。
feerate_per_kw
通常只与发送方(支付费用的人)有关,但 HTLC transaction 也会支付费用; 因此,非常大的费用率也会惩罚接收方。
将 htlc_basepoint
与 payment_basepoint
分开可以提高安全性:节点需要与 htlc_basepoint
关联的密钥才能生成协议的 HTLC 签名,但 payment_basepoint
的密钥可以存储在冷存储中。
根据 dust_limit_satoshis
,channel_reserve_satoshis
不被认为是尘埃的要求消除了所有输出都将作为尘埃消除的情况。 accept_channel
中类似的 requirements 确保双方的 channel_reserve_satoshis
都高于 dust_limit_satoshis
。
接收方不应接受大的 dust_limit_satoshis
,因为这可能用于 griefing 攻击,在该攻击中,对等方发布其 commitment,其中包含大量尘埃 htlc,这些 htlc 实际上变成了矿工费用。
有关如何处理通道故障的详细信息,请参见 BOLT 5:通道故障。
accept_channel
消息此消息包含有关节点的信息,并表明其接受新通道。这是创建 funding transaction 和两种版本的 commitment transaction 的第二步。
类型:33 (accept_channel
)
数据:
32*byte
:temporary_channel_id
]u64
:dust_limit_satoshis
]u64
:max_htlc_value_in_flight_msat
]u64
:channel_reserve_satoshis
]u64
:htlc_minimum_msat
]u32
:minimum_depth
]u16
:to_self_delay
]u16
:max_accepted_htlcs
]point
:funding_pubkey
]point
:revocation_basepoint
]point
:payment_basepoint
]point
:delayed_payment_basepoint
]point
:htlc_basepoint
]point
:first_per_commitment_point
]accept_channel_tlvs
:tlvs
]tlv_stream
: accept_channel_tlvs
类型:
upfront_shutdown_script
)...*byte
:shutdown_scriptpubkey
]channel_type
)...*byte
:type
]temporary_channel_id
必须与 open_channel
消息中的 temporary_channel_id
相同。
发送方:
minimum_depth
设置为它认为合理的块数,以避免对 funding transaction 进行双重支出。channel_reserve_satoshis
设置为大于或等于 open_channel
消息中的 dust_limit_satoshis
。dust_limit_satoshis
设置为小于或等于 open_channel
消息中的 channel_reserve_satoshis
。option_channel_type
:
channel_type
设置为 open_channel
中的 channel_type
接收方:
minimum_depth
非常大:
channel_reserve_satoshis
小于 open_channel
消息中的 dust_limit_satoshis
:
open_channel
消息中的 channel_reserve_satoshis
小于 dust_limit_satoshis
:
channel_type
已设置,并且 open_channel
中已设置 channel_type
,并且它们的类型不相等:
option_channel_type
,但消息不包含 channel_type
:
其他字段具有与其在 open_channel
中的对应字段相同的 requirements。
funding_created
消息此消息描述了 funder 为初始 commitment transaction 创建的 outpoint。 在通过 funding_signed
收到对等方的签名后,它将广播 funding transaction。
funding_created
)32*byte
:temporary_channel_id
]sha256
:funding_txid
]u16
:funding_output_index
]signature
:signature
]发送方必须设置:
temporary_channel_id
与 open_channel
消息中的 temporary_channel_id
相同。funding_txid
设置为非可延展 transaction 的 transaction ID,
funding_output_index
设置为与资金 transaction 输出相对应的 transaction 的输出编号,如 BOLT #3 中所定义。signature
设置为使用其 funding_pubkey
对于初始 commitment transaction 的有效签名,如 BOLT #3 中所定义。发送方:
接收方:
signature
不正确或不符合 LOW-S 标准规则<sup>LOWS</sup>:
warning
并关闭连接,或者发送一个 error
并使通道失败。funding_output_index
只能是 2 个字节,因为这就是它被打包到 channel_id
中并在整个 gossip 协议中使用的方式。 65535 个输出的限制不应过于繁重。
具有所有隔离见证输入的 transaction 不可延展,因此建议使用资金 transaction。
funder 可以在找零输出上使用 CPFP,以确保资金 transaction 在 2016 个区块之前得到确认,否则 fundee 可能会忘记该通道。
funding_signed
消息此消息为 funder 提供了第一个 commitment transaction 所需的签名,因此它可以广播该 transaction,知道资金可以在需要时赎回。
此消息引入了 channel_id
来标识通道。它从资金 transaction 派生而来,方法是将 funding_txid
和 funding_output_index
组合起来,使用大端序异或(即 funding_output_index
更改最后 2 个字节)。
funding_signed
)channel_id
:channel_id
]signature
:signature
]双方:
channel_type
在 open_channel
和 accept_channel
中都存在:
channel_type
(它们必须相等,以上要求)option_anchors_zero_fee_htlc_tx
:
channel_type
是 option_anchors_zero_fee_htlc_tx
和 option_static_remotekey
(第 22 位和第 12 位)option_anchor_outputs
:
channel_type
是 option_anchor_outputs
和 option_static_remotekey
(第 20 位和第 12 位)option_static_remotekey
:
channel_type
是 option_static_remotekey
(第 12 位)channel_type
为空channel_type
用于所有 commitment transaction。发送方必须设置:
channel_id
通过异或 funding_created
消息中的 funding_txid
和 funding_output_index
来设置。signature
设置为有效签名,使用其 funding_pubkey
对于初始 commitment transaction 的有效签名,如 BOLT #3 中所定义。接收方:
signature
不正确或不符合 LOW-S 标准规则<sup>LOWS</sup>:
warning
并关闭连接,或者发送一个 error
并使通道失败。funding_signed
之前,不得广播资金 transaction。funding_signed
后:
我们在此刻决定 option_static_remotekey
、option_anchor_outputs
或 option_anchors_zero_fee_htlc_tx
,此时我们必须首先生成 commitment transaction。 在当前连接的 init
消息交换中传达的特征位确定了通道承诺格式在通道的整个生命周期内。 即使以后的重新连接没有协商此参数,此通道也将继续使用 option_static_remotekey
、option_anchor_outputs
或 option_anchors_zero_fee_htlc_tx
; 我们不支持“降级”。
option_anchors_zero_fee_htlc_tx
被认为优于 option_anchor_outputs
,而 option_anchor_outputs
又被认为优于 option_static_remotekey
,如果协商了多个,则优先选择更好的一个。
funding_locked
消息此消息指示资金 transaction 已达到 accept_channel
中要求的 minimum_depth
。 一旦两个节点都发送了此消息,通道就会进入正常运行模式。
funding_locked
)channel_id
:channel_id
]point
:next_per_commitment_point
]发送方必须:
funding_created
消息中的 funding_txid
和 funding_output_index
给出的 outpoint 恰好将 funding_satoshis
支付给 BOLT #3 中指定的 scriptpubkey,否则不得发送 funding_locked
。minimum_depth
。next_per_commitment_point
设置为将用于以下 commitment transaction 的 per-commitment point,如 BOLT #3 中指定的派生。非资金节点(fundee):
从等待 funding_locked
的那一刻起,如果未在合理的超时后收到另一节点的必要响应,任何节点都可以发送 error
并使通道失败。
非 funder 可以简单地忘记该通道曾经存在过,因为没有资金处于风险之中。 如果 fundee 永远记住该通道,这将构成拒绝服务风险; 因此,建议忘记它(即使 push_msat
的承诺意义重大)。
如果 fundee 在确认之前忘记了该通道,则 funder 将需要广播 commitment transaction 以取回其资金并打开一个新通道。 为避免这种情况,funder 应确保资金 transaction 在接下来的 2016 个区块中得到确认。
节点可以协商相互关闭连接,这与单方面关闭不同,它允许他们立即访问他们的资金,并且可以通过较低的费用进行协商。
关闭分为两个阶段:
+-------+ +-------+
| |--(1)----- shutdown ------->| |
| |<-(2)----- shutdown --------| |
| | | |
| | <完成所有挂起的 HTLC> | |
| A | ... | B |
| | | |
| |--(3)-- closing_signed F1--->| |
| |<-(4)-- closing_signed F2----| |
| | ... | |
| |--(?)-- closing_signed Fn--->| |
| |<-(?)-- closing_signed Fn----| |
+-------+ +-------+
shutdown
任何节点(或两个节点)都可以发送 shutdown
消息以启动关闭,以及它想要支付的 scriptpubkey
。
shutdown
)channel_id
:channel_id
]u16
:len
]len*byte
:scriptpubkey
]发送节点:
funding_created
(如果它是 funder)或 funding_signed
(如果它是 fundee):
shutdown
funding_locked
之前发送 shutdown
,即在资金 transaction 达到 minimum_depth
之前。shutdown
。shutdown
之后,不得发送 update_add_htlc
。shutdown
之后,不得发送任何 update
消息。shutdown
之后添加的任何 HTLC。open_channel
或 accept_channel
中发送了非零长度的 shutdown_scriptpubkey
:
scriptpubkey
中发送相同的值。必须以以下形式之一设置 scriptpubkey
:
OP_0
20
20 字节(版本 0 pay to witness pubkey 哈希),或者OP_0
32
32 字节(版本 0 pay to witness script 哈希),或者option_shutdown_anysegwit
:
OP_1
到 OP_16
(含),后跟 2 到 40 个字节的单个推送
(见证程序版本 1 到 16)
一个接收节点:funding_signed
(如果它是一个 funder) 或 funding_created
(如果它是一个 fundee):
error
并使通道失败。scriptpubkey
不在上述形式之一中:
warning
。funding_locked
:
shutdown
回复 shutdown
消息shutdown
:
shutdown
回复 shutdown
消息option_upfront_shutdown_script
功能,并且接收节点在 open_channel
或 accept_channel
中接收到了非零长度的 shutdown_scriptpubkey
,并且 shutdown_scriptpubkey
不等于 scriptpubkey
:
warning
。如果通道状态在关闭开始时总是 "干净的"(没有挂起的更改),则避免了在状态不干净时如何操作的问题:发送方总是首先发送一个 commitment_signed
。
由于关闭意味着终止的意愿,它意味着不会添加或接受新的 HTLC。一旦任何 HTLC 被清除,peer 可以立即开始关闭协商,因此我们禁止进一步更新 commitment transaction(特别是,否则 update_fee
是可能的)。
scriptpubkey
表格仅包括比特币网络接受的标准隔离见证表格,这确保了生成的交易将传播给矿工。然而,旧节点可能会发送非隔离见证脚本,为了向后兼容性,可以接受这些脚本(但需要注意,如果此输出不满足 dust relay 要求,则强制关闭)。
option_upfront_shutdown_script
功能意味着节点想要预先提交到 shutdown_scriptpubkey
,以防它以某种方式受到损害。这是一个微弱的承诺(一个恶意的实现往往会忽略像这样的规范!),但它通过要求接收节点的合作来更改 scriptpubkey
,从而提供了安全性的增量改进。
shutdown
响应要求意味着节点在回复之前发送 commitment_signed
以提交任何未完成的更改;然而,理论上它可以重新连接,这将简单地消除所有未决的未提交更改。
closing_signed
一旦关闭完成并且通道中没有 HTLC,最终的当前 commitment transaction 将没有任何 HTLC,并且开始关闭费用协商。funder 选择它认为公平的费用,并使用来自 shutdown
消息的 scriptpubkey
字段(以及它选择的费用)签署 closing transaction 并发送签名;然后另一个节点以类似的方式回复,使用它认为公平的费用。这个交换一直持续到双方都同意相同的费用或一方使通道失败。
在现代方法中,funder 发送其允许的费用范围,并且非 funder 必须在此范围内选择费用。如果非 funder 选择相同的值,则协商在两条消息后完成,否则 funder 将回复相同的值(在三条消息后完成)。
1. type: 39 (`closing_signed`)
2. data:
* [`channel_id`:`channel_id`]
* [`u64`:`fee_satoshis`]
* [`signature`:`signature`]
* [`closing_signed_tlvs`:`tlvs`]
1. `tlv_stream`: `closing_signed_tlvs`
2. types:
1. type: 1 (`fee_range`)
2. data:
* [`u64`:`min_fee_satoshis`]
* [`u64`:`max_fee_satoshis`]
funding 节点:
shutdown
之后,并且在两个 commitment transaction 中都没有剩余 HTLC:
closing_signed
消息。发送节点:
fee_satoshis
。fee_range
。closing_signed
响应:
max_fee_satoshis
设置为至少等于接收到的 max_fee_satoshis
min_fee_satoshis
设置为一个相当低的值signature
设置为 close transaction 的比特币签名,如 BOLT #3 中指定的那样。接收节点:
signature
对于 BOLT #3 中指定的 closing transaction 的任何变体无效,或者不符合 LOW-S-standard 规则<sup>LOWS</sup>:
warning
并关闭连接,或者发送一个 error
并使通道失败。fee_satoshis
等于其先前发送的 fee_satoshis
:
fee_satoshis
与其先前发送的 fee_range
匹配:
fee_satoshis
来签署并广播最终的 closing transactionfee_satoshis
值不同,则应该回复一个具有相同 fee_satoshis
值的 closing_signed
fee_range
:
fee_range
与它自己的 fee_range
之间没有重叠:
fee_range
,则必须使通道失败fee_satoshis
不在发送和接收的 fee_range
之间的重叠部分:
fee_satoshis
。closing_signed
:
fee_satoshis
与它发送的值不同:fee_range
之间的重叠部分中提出一个 fee_satoshis
。fee_satoshis
不是严格介于其上次发送的 fee_satoshis
和其先前接收的 fee_satoshis
之间,除非它此后重新连接:
warning
并关闭连接,或者发送一个 error
并使通道失败。fee_satoshis
值的 closing_signed
。fee_satoshis
和其先前发送的 fee_satoshis
之间的值。接收节点:
scriptpubkey
的 dust limit(参见 BOLT 3):
当未提供 fee_range
时,"严格介于" 要求确保取得进展,即使每次只增加一个 satoshi。为了避免保持状态并处理断开连接和重新连接之间的极端情况,协商会在重新连接时重新开始。
请注意,如果 closing transaction 被延迟,风险有限,但它将很快被广播;因此,通常没有理由为快速处理支付溢价。
注意,非 funder 不支付费用,因此它没有理由设置最大 feerate。但是,它可能需要一个最小 feerate,以确保交易传播。如有必要,它总是可以使用 CPFP 稍后加速确认,因此该最小值应较低。
可能会发生 closing transaction 不符合比特币的默认 relay 策略的情况(例如,当为低于 546 satoshis 的输出使用非隔离见证 shutdown 脚本时,如果 dust_limit_satoshis
低于 546 satoshis,则可能发生这种情况)。在这种情况下,没有资金处于风险之中,但通道必须被强制关闭,因为 closing transaction 可能永远不会到达矿工。
一旦两个节点交换了 funding_locked
(并且可选地交换了 announcement_signatures
),该通道就可以用于通过 Hashed Time Locked Contracts 进行支付。
更改以批处理方式发送:在 commitment_signed
消息之前发送一条或多条 update_
消息,如下图所示:
+-------+ +-------+
| |--(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 ------| |
+-------+ +-------+
与直觉相反,这些更新应用于另一个节点的 commitment transaction;只有当远程节点通过 revoke_and_ack
消息确认它已应用这些更新时,该节点才会将这些更新添加到它自己的 commitment transaction 中。
因此,每个更新都经历以下状态:
由于两个节点的更新是独立的,因此两个 commitment transaction 可能会无限期地不同步。这并不令人担忧:重要的是双方是否已不可撤销地提交了特定的更新(上述最终状态)。
一般来说,节点提供 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 是不同的:preimage 的知识,根据定义,是不可撤销的,传入 HTLC 应尽快实现以减少延迟。
具有不合理长 expiry 的 HTLC 是一种拒绝服务向量,因此不允许。请注意,"不合理" 的确切值目前不明确,并且可能取决于网络拓扑。
cltv_expiry_delta
选择HTLC 超时后,它可以被实现或超时;必须小心处理此转换,无论是对于提供的 HTLC 还是接收的 HTLC。
考虑以下场景,其中 A 向 B 发送 HTLC,B 转发给 C,C 在收到付款后立即交付货物。
C 需要确保来自 B 的 HTLC 不会超时,即使 B 变得无响应;即,C 可以在 B 在链上使其超时之前在链上实现传入 HTLC。
B 需要确保如果 C 实现来自 B 的 HTLC,它可以实现来自 A 的传入 HTLC;即,B 可以从 C 获取 preimage 并在 A 在链上使其超时之前在链上实现传入 HTLC。
此处的关键设置是 BOLT #7 中的 cltv_expiry_delta
和 BOLT #11 中相关的 min_final_cltv_expiry
。cltv_expiry_delta
是转发情况(B)中 HTLC CLTV 超时的最小差异。min_final_cltv_expiry
是终端情况(C)中 HTLC CLTV 超时与当前区块高度之间的最小差异。
请注意,如果节点在一个通道中接受 HTLC 并在另一个通道中提供 HTLC,并且 CLTV 超时之间的差异太小,则该节点存在风险。因此,传出 通道的 cltv_expiry_delta
用作节点上的 delta。
假设一些假设,可以得出传出和传入 HTLC 解决方案之间最坏情况的区块数:
R
个区块G
个区块S
最坏的情况是转发节点 (B) 花费尽可能长的时间来发现传出 HTLC 实现,并且还花费尽可能长的时间来在链上赎回它:
N
超时,B 等待 G
个区块,直到放弃等待 C。B 或 C 提交到区块链,而 B 花费 HTLC,这需要 S
个区块才能被包含。N+G+S+1
时看到该交易。R
深度的重组,其中 C 获胜并实现。B 仅在 N+G+S+R
处看到交易。G
个区块,然后放弃等待 A。A 或 B 提交到区块链。N+G+S+R+G+1
中看到 A 的 commitment transaction,并且必须花费 HTLC 输出,这需要 S
个区块才能被挖掘。R
深度的重组,A 使用该重组来花费 commitment transaction,因此 B 在区块 N+G+S+R+G+R
中看到 A 的 commitment transaction,并且必须花费 HTLC 输出,这需要 S
个区块才能被挖掘。R
深度,否则另一个重组可能允许 A 使交易超时。因此,最坏的情况是 3R+2G+2S
,假设 R
至少为 1。请注意,对于 2 个或更多的 R
,其中另一个节点赢得所有交易的三个重组的几率很低。由于使用了很高的费用(并且 HTLC 支出可以使用几乎任意的费用),因此在正常运行期间 S
应该很小;但是,鉴于区块时间不规则,仍然会发生空区块,费用可能会发生很大变化,并且无法在 HTLC 交易上增加费用,因此应将 S=12
视为最小值。S
也是在攻击下变化最大的参数,因此当有不可忽略的金额处于风险中时,可能需要更高的值。宽限期 G
可以很低(1 或 2),因为要求节点尽快超时或履行;但是,如果 G
太低,则会增加由于网络延迟导致的不必要的通道关闭的风险。
需要得出四个值:
通道的 cltv_expiry_delta
, 3R+2G+2S
:如有疑问,至少 34 的 cltv_expiry_delta
是合理的 (R=2, G=2, S=12)。
提供的 HTLC 的截止日期:通道必须失败并在链上超时之后的截止日期。这是 HTLC 的 cltv_expiry
之后的 G
个区块:1 或 2 个区块是合理的。
此节点已实现的收到的 HTLC 的截止日期:通道必须失败并且 HTLC 在其 cltv_expiry
之前在链上实现的截止日期。请参阅上面的步骤 4-7,这意味着在 cltv_expiry
之前的 2R+G+S
个区块的截止日期:18 个区块是合理的。
终端付款接受的最小 cltv_expiry
:终端节点 C 的最坏情况是 2R+G+S
个区块(因为,同样,上面的步骤 1-3 不适用)。BOLT #11 中的默认值为 18,与此计算匹配。
一个提供节点:
cltv_expiry
之前的超时截止日期的 HTLC。error
(如果已连接)。一个履行节点:
error
(如果已连接)。update_add_htlc
任一节点都可以发送 update_add_htlc
以向另一个节点提供 HTLC,该 HTLC 可以通过支付 preimage 来兑换。金额以毫聪为单位,尽管链上强制执行仅适用于大于 dust limit 的完整聪金额(在 commitment transaction 中,这些金额会向下舍入,如 BOLT #3 中指定的那样)。
onion_routing_packet
部分的格式指示支付的目的地,在 BOLT #4 中进行了描述。
1. type: 128 (`update_add_htlc`)
2. data:
* [`channel_id`:`channel_id`]
* [`u64`:`id`]
* [`u64`:`amount_msat`]
* [`sha256`:`payment_hash`]
* [`u32`:`cltv_expiry`]
* [`1366*byte`:`onion_routing_packet`]
发送节点:
feerate_per_kw
支付本地或远程 commitment transaction 的费用,同时维持其通道储备(请参阅 更新费用),则不得提供 amount_msat
。option_anchors
适用于此 commitment transaction 并且发送节点是 funder:
to_local_anchor
和 to_remote_anchor
的费用。amount_msat
。建议此 "费用峰值缓冲区" 可以处理当前 feerate_per_kw
的两倍,以确保实现之间的可预测性。feerate_per_kw
支付更新后的本地或远程交易的费用,同时维持其通道储备,则不应提供 amount_msat
。amount_msat
。htlc_minimum_msat
的 amount_msat
cltv_expiry
。max_accepted_htlcs
HTLC:
max_htlc_value_in_flight_msat
:
id
设置为 0。id
的值增加 1。在更新完成后(即在收到 revoke_and_ack
之后),id
不得 重置为 0。必须改为继续递增。
接收节点:
amount_msat
等于 0,或者小于其自己的 htlc_minimum_msat
:
warning
并关闭连接,或者发送一个 error
并使通道失败。amount_msat
是发送节点无法以当前的 feerate_per_kw
负担的(同时维持其通道储备以及任何 to_local_anchor
和 to_remote_anchor
成本):
warning
并关闭连接,或者发送一个 error
并使通道失败。max_accepted_htlcs
HTLC,或者向其本地 commitment transaction 添加了超过接收节点 max_htlc_value_in_flight_msat
价值的提供的 HTLC:
warning
并关闭连接,或者发送一个 error
并使通道失败。cltv_expiry
设置为大于或等于 500000000:
warning
并关闭连接,或者发送一个 error
并使通道失败。payment_hash
的多个 HTLC。id
值。id
违规:
warning
并关闭连接,或者发送一个 error
并使通道失败。onion_routing_packet
包含沿路径的每个 hop 的混淆的 hop 列表和指令。
它通过将 payment_hash
设置为关联数据来提交 HTLC,即在 HMAC 的计算中包括 payment_hash
。
这可以防止重放攻击,该攻击将重用具有不同 payment_hash
的先前 onion_routing_packet
。
无效的金额是明显的协议违反,表明发生了故障。
如果节点不接受具有相同支付哈希的多个 HTLC,则攻击者可以探测以查看节点是否具有现有的 HTLC。这种处理重复项的要求导致了单独的标识符的使用;假设 64 位计数器永远不会环绕。
明确允许为重新连接目的重传未确认的更新;允许在其他时间进行简化了接收方代码(尽管严格检查可能有助于调试)。
max_accepted_htlcs
限制为 483,以确保即使双方都发送了最大数量的 HTLC,commitment_signed
消息仍将小于最大消息大小。它还确保单个 penalty transaction 可以花费整个 commitment transaction,如 BOLT #5 中计算的那样。
等于或大于 500000000 的 cltv_expiry
值将指示以秒为单位的时间,并且该协议仅支持以区块为单位的 expiry。
负责 支付比特币费用的节点应在其储备之上保持 "费用峰值缓冲区",以适应未来的费用增加。 如果没有此缓冲区,负责 支付比特币费用的节点可能会达到无法发送或接收任何非 dust HTLC 的状态,同时维持其通道储备(因为 commitment transaction 的权重增加),从而导致通道降级。有关更多详细信息,请参阅 #728。
update_fulfill_htlc
、update_fail_htlc
和 update_fail_malformed_htlc
为简单起见,节点只能移除由另一个节点添加的 HTLC。移除 HTLC 有四个原因:提供了支付 preimage,它已超时,它无法路由或它格式不正确。
要提供 preimage:
1. type: 130 (`update_fulfill_htlc`)
2. data:
* [`channel_id`:`channel_id`]
* [`u64`:`id`]
* [`32*byte`:`payment_preimage`]
对于超时或路由失败的 HTLC:
1. type: 131 (`update_fail_htlc`)
2. data:
* [`channel_id`:`channel_id`]
* [`u64`:`id`]
* [`u16`:`len`]
* [`len*byte`:`reason`]
reason
字段是一个不透明的加密blob,为了原始 HTLC 发起人的利益,如 BOLT #4 中所定义;
然而,对于 peer 无法解析它的情况,有一个特殊的格式错误的失败变体:在这种情况下,当前节点采取行动,将其加密到 update_fail_htlc
中以进行转发。
对于无法解析的 HTLC:
1. type: 135 (`update_fail_malformed_htlc`)
2. data:
* [`channel_id`:`channel_id`]
* [`u64`:`id`]
* [`sha256`:`sha256_of_onion`]
* [`u16`:`failure_code`]
一个节点:
update_fulfill_htlc
、update_fail_htlc
或
update_fail_malformed_htlc
。接收节点:
id
与其当前 commitment transaction 中的 HTLC 不对应:
warning
并关闭连接,或者发送一个 error
并使通道失败。update_fulfill_htlc
中的 payment_preimage
值
没有 SHA256 哈希到相应的 HTLC payment_hash
:
warning
并关闭连接,或者发送一个 error
并使通道失败。failure_code
中没有为
update_fail_malformed_htlc
设置 BADONION
位:
warning
并关闭连接,或者发送一个 error
并使通道失败。update_fail_malformed_htlc
中的 sha256_of_onion
与其发送的
onion 不匹配:
update_fail_malformed_htlc
取消了传出 HTLC 的接收节点:
failure_code
并将数据设置为 sha256_of_onion
的情况下,在发送到最初发送 HTLC 的链接的 update_fail_htlc
中返回错误。不使 HTLC 超时的节点有通道失败的风险(请参阅 cltv_expiry_delta
选择)。
发送 update_fulfill_htlc
的节点在发送方之前也已
提交到 HTLC,并冒着损失资金的风险。
如果 onion 格式错误,上游节点将无法提取共享密钥以生成响应 - 因此需要特殊的失败消息,使此节点执行此操作。
该节点可以检查上游抱怨的 SHA256 是否与其发送的 onion 匹配,这可能使其能够检测到随机位错误。但是,如果不重新检查发送的实际加密数据包,它将不知道错误是它自己的还是远程的;因此,此类检测留作选项。
commitment_signed
当一个节点有远程 commitment 的更改时,它可以应用它们,签署生成的交易(如 BOLT #3 中所定义),然后发送一个 commitment_signed
消息。
1. type: 132 (`commitment_signed`)
2. data:
* [`channel_id`:`channel_id`]
* [`signature`:`signature`]
* [`u16`:`num_htlcs`]
* [`num_htlcs*signature`:`htlc_signature`]
发送节点:
commitment_signed
消息。commitment_signed
消息。commitment_signed
消息(由于 dust、相同的 HTLC 替换或不重要的或多次费用更改)。htlc_signature
(请参阅 BOLT #3)。ping
之前并等待回复 pong
,然后再发送commitment_signed
。
接收节点:signature
对于其本地承诺交易无效,或者不符合 LOW-S-standard 规则 <sup>LOWS</sup>:
warning
并关闭连接,或者发送一个 error
并使通道失效。num_htlcs
不等于本地承诺交易中 HTLC 输出的数量:
warning
并关闭连接,或者发送一个 error
并使通道失效。htlc_signature
对于相应的 HTLC 交易无效,或者不符合 LOW-S-standard 规则 <sup>LOWS</sup>:
warning
并关闭连接,或者发送一个 error
并使通道失效。revoke_and_ack
消息。提供垃圾更新没什么意义:这意味着存在错误。
num_htlcs
字段是冗余的,但使得数据包长度检查完全自包含。
建议要求最近的消息,这认识到网络是不可靠的这一现实:节点可能在发送 commitment_signed
之后才意识到它们的对等节点已离线。 一旦 commitment_signed
被发送,发送方认为自己受到这些 HTLC 的约束,并且在输出 HTLC 完全解决之前无法使相关的传入 HTLC 失效。
请注意,在提供的 HTLC 超时或收到的 HTLC 被花费的情况下,htlc_signature
隐式地执行了时间锁定机制。这样做是为了通过创建比在 HTLC 输出上显式声明时间锁定的更小的脚本来减少费用。
option_anchors
允许 HTLC 交易通过附加其他输入和输出来“自带费用”,因此修改了签名标志。
revoke_and_ack
一旦 commitment_signed
的接收者检查了签名并知道它有一个有效的新承诺交易,它将回复 revoke_and_ack
消息中先前承诺交易的承诺preimage。
此消息也隐式地充当对收到 commitment_signed
的确认,因此这是 commitment_signed
发送者应用(对其自身的承诺)在 commitment_signed
之前发送的任何挂起更新的合理时间。
密钥派生的描述在 BOLT #3 中。
revoke_and_ack
)channel_id
:channel_id
]32*byte
:per_commitment_secret
]point
:next_per_commitment_point
]发送节点:
per_commitment_secret
设置为用于为先前的承诺交易生成密钥的secret。next_per_commitment_point
设置为其下一个承诺交易的值。接收节点:
per_commitment_secret
不是有效的secret key,或者没有生成先前的 per_commitment_point
:
error
并使通道失效。per_commitment_secret
不是由 BOLT #3 中的协议生成的:
warning
并关闭连接,或者发送一个 error
并使通道失效。一个节点:
update_fee
update_fee
消息由支付比特币费用的节点发送。与任何更新一样,它首先被提交到接收者的承诺交易,然后(一旦确认)被提交到发送者的承诺交易。与 HTLC 不同,update_fee
永远不会关闭,而只是被替换。
存在竞争的可能性,因为接收者可以在收到 update_fee
之前添加新的 HTLC。在这种情况下,一旦 update_fee
最终被接收者确认,发送者可能无法承担自己承诺交易的费用。在这种情况下,费用将低于费用率,如 BOLT #3 中所述。
用于从费用率导出费用的确切计算在 BOLT #3 中给出。
update_fee
)channel_id
:channel_id
]u32
:feerate_per_kw
]负责支付比特币费用的节点:
update_fee
以确保当前费用率足以(以很大的幅度)及时处理承诺交易。不负责支付比特币费用的节点:
update_fee
。接收节点:
update_fee
太低而无法及时处理,或者非常大:
warning
并关闭连接,或者发送一个 error
并使通道失效。warning
并关闭连接,或者发送一个 error
并使通道失效。warning
并关闭连接,或者发送一个 error
并使通道失效。
update_fee
被提交。比特币费用是单方面关闭生效所必需的。 对于 option_anchors
,feerate_per_kw
不再像传统承诺格式中那样对保证确认至关重要,但它仍然需要足以进入内存池(满足最小 relay fee 和内存池最小费用)。
对于传统的承诺格式,广播节点没有使用 child-pays-for-parent 来增加其有效费用的一般方法。
鉴于费用的差异,以及该交易将来可能被花费的事实,费用支付者最好保持良好的保证金(比如预期费用要求的 5 倍)对于传统的承诺交易; 但是,由于费用估算方法不同,因此未指定确切的值。
由于费用目前是单方面的(请求创建通道的一方始终支付承诺交易的费用),因此最简单的方法是仅允许它设置费用水平; 但是,由于相同的费用率适用于 HTLC 交易,因此接收节点也必须关心费用的合理性。
因为通信传输是不可靠的,并且可能需要不时地重新建立,所以传输的设计已与协议显式分离。
然而,假设我们的传输是有序且可靠的。 重新连接会引入对已接收内容的怀疑,因此在此时存在显式确认。
在通道建立和关闭的情况下,这是非常简单的,因为消息具有显式顺序,但在正常操作期间,更新的确认会延迟到 commitment_signed
/ revoke_and_ack
交换; 因此不能假定已收到更新。 这也意味着接收节点只需要在收到 commitment_signed
时存储更新。
请注意,BOLT #7 中描述的消息独立于特定通道; 它们的传输要求在那里涵盖,并且除了在 init
之后传输(如所有消息一样)之外,它们与此处的任何要求无关。
channel_reestablish
)channel_id
:channel_id
]u64
:next_commitment_number
]u64
:next_revocation_number
]32*byte
:your_last_per_commitment_secret
]point
:my_current_per_commitment_point
]next_commitment_number
: 承诺编号是每个承诺交易的 48 位递增计数器; 计数器对于通道中的每个对等方都是独立的,并且从 0 开始。它们仅在重新建立的情况下显式地转发到另一个节点,否则它们是隐式的。
资金节点:
非资金节点:
funding_signed
消息:
一个节点:
commitment_signed
的所有以 update_
开头的消息)。
update_fulfill_htlc
中的 payment_preimage
值,因此 update_fulfill_htlc
的效果并没有完全撤销。channel_reestablish
。channel_reestablish
消息,然后才能发送该通道的任何其他消息。发送节点:
next_commitment_number
设置为它期望接收的下一个 commitment_signed
的 承诺编号。next_revocation_number
设置为它期望接收的下一个 revoke_and_ack
消息的 承诺编号。option_static_remotekey
适用于承诺交易:
my_current_per_commitment_point
设置为有效点。my_current_per_commitment_point
设置为其从通道对等方收到的最后一次签名承诺的承诺点(即,发送方将用于单方面关闭的承诺交易对应的 commitment_point)。next_revocation_number
等于 0:
your_last_per_commitment_secret
设置为全零your_last_per_commitment_secret
设置为其收到的最后一个 per_commitment_secret
一个节点:
channel_reestablish
中,next_commitment_number
都为 1:
funding_locked
。funding_locked
。funding_locked
。next_commitment_number
等于接收节点已发送的最后一个 commitment_signed
消息的承诺编号:
commitment_signed
重用相同的承诺编号。next_commitment_number
不比接收节点已发送的最后一个 commitment_signed
消息的承诺编号大 1:
error
并使通道失效。commitment_signed
,并且 next_commitment_number
不等于 1:
error
并使通道失效。next_revocation_number
等于接收节点已发送的最后一个 revoke_and_ack
的承诺编号,并且接收节点尚未收到 closing_signed
:
revoke_and_ack
。commitment_signed
:
revoke_and_ack
和 commitment_signed
。next_revocation_number
不比接收节点已发送的最后一个 revoke_and_ack
的承诺编号大 1:
error
并使通道失效。revoke_and_ack
,并且 next_revocation_number
不等于 0:
error
并使通道失效。接收节点:
option_static_remotekey
适用于承诺交易:
next_revocation_number
大于上面预期的值,并且 your_last_per_commitment_secret
对于该 next_revocation_number
减 1 是正确的:
error
以请求对等方使通道失效。your_last_per_commitment_secret
与预期值不匹配:error
并使通道失效。option_data_loss_protect
:
next_revocation_number
大于上面预期的值,并且 your_last_per_commitment_secret
对于该 next_revocation_number
减 1 是正确的:
error
以请求对等方使通道失效。my_current_per_commitment_point
以检索资金,以防发送节点在链上广播其承诺交易。your_last_per_commitment_secret
或 my_current_per_commitment_point
与预期值不匹配):
error
并使通道失效。一个节点:
commitment_signed
消息:
update_
消息,这一点尤其重要。shutdown
:
shutdown
。上述要求确保了开放阶段几乎是原子的:如果它没有完成,它会重新开始。 唯一的例外是 funding_signed
消息已发送但未收到。 在这种情况下,资助者将忘记该通道,并可能在重新连接时打开一个新通道; 同时,由于从未收到 funding_locked
或在链上看到 funding 交易,因此另一个节点最终会忘记原始通道。
error
没有确认,因此如果发生重新连接,最好在再次断开连接之前重新传输; 但是,这不是必须的,因为在某些情况下,节点可以完全忘记通道。
closing_signed
也没有确认,因此必须在重新连接时重新传输(尽管协商会在重新连接时重新开始,因此不需要完全重新传输)。 shutdown
的唯一确认是 closing_signed
,因此需要重新传输其中一个或另一个。
更新的处理方式类似地是原子的:如果提交未被确认(或未发送),则会重新发送更新。 但是,并不坚持要求 它们必须相同:它们的顺序可能不同,涉及不同的费用,甚至可能缺少现在太旧而无法添加的 HTLC。 要求它们是相同的实际上意味着发送方在每次传输时都要写入磁盘,而此处的方案鼓励为每个发送或接收的 commitment_signed
进行一次持久写入磁盘。 但是,如果你需要重新传输 commitment_signed
和revoke_and_ack
,则必须保留这两者的相对顺序,否则将导致通道关闭。
在收到 closing_signed
之后,永远不应要求重新传输 revoke_and_ack
,因为这将意味着已完成关闭--这只能在远程节点收到 revoke_and_ack
之后发生。
请注意,next_commitment_number
从 1 开始,因为承诺编号 0 是在打开期间创建的。 在发送对承诺编号 1 的 commitment_signed
并收到对承诺编号 0 的撤消之前,next_revocation_number
将为 0。
funding_locked
通过正常操作的开始来隐式确认,已知该操作在收到 commitment_signed
之后开始 - 因此,测试 next_commitment_number
大于 1。
先前的草案坚持认为,资助者“如果已广播 funding 交易,则必须记住......否则不得记住”:这实际上是不可能的要求。 节点必须首先提交到磁盘并其次广播交易,反之亦然。 新的语言反映了这一现实:记住一个尚未广播的通道肯定比忘记一个已经广播的通道更好! 同样,对于被资助者的 funding_signed
消息:记住一个从未打开(并超时)的通道比让资助者在被资助者忘记它的情况下打开它更好。
添加了 option_data_loss_protect
以允许以某种方式落后的节点(例如,已从旧备份还原)检测到它已落后。 落后的节点必须知道它不能广播其当前的承诺交易——这将导致资金的完全损失——因为远程节点可以证明它知道撤销 preimage。 落后的节点返回的 error
应该使另一个节点放弃其当前对链的承诺交易。 另一个节点应该等待该 error
,以便使落后的节点有机会首先修复其状态(例如,通过使用不同的备份重新启动)。 如果落后的节点没有最新的备份,那么至少这将允许它恢复非 HTLC 资金(如果 my_current_per_commitment_point
有效)。 但是,这也意味着落后的节点已经透露了这一事实(尽管无法证明:它可能在撒谎),并且另一个节点可以使用它来广播先前的状态。
option_static_remotekey
移除了正在更改的 to_remote
密钥,因此 my_current_per_commitment_point
是不必要的,因此被忽略(为了解析简单起见,它仍然存在并且必须是一个有效的点,但是); 然而,先前密钥的泄露仍然允许检测到已经落后。 但是,实现可以同时提供两者,并且如果未协商 option_static_remotekey
,则回退到 option_data_loss_protect
行为。
[ 待定:插入作者列表 ]
<br>
本作品已获得 Creative Commons Attribution 4.0 International License 许可。
- 原文链接: github.com/lightning/bol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!