本周的周报总结了关于允许在 taproot 交易的 annex 字段内包含数据、在交易中转发的讨论,以及一份关于 “静默支付” 的 BIP 草案。此外还有我们的 “交易池规则” 限定系列的新一篇文章,以及我们的常规栏目:总结最近一次 Bitcoin Core PR 审核俱乐部会议的成果、软件的新版本和候选版本,以及热门比特币基础设施软件的重要变化。

新闻

  • 关于 taproot annex 的讨论:Joost Jager 在 Bitcoin-Dev 邮件组中发帖,请求改变 Bitcoin Core 的交易转发和挖矿策略,以允许在 taproot 交易的 annex 字段存储任意数据。 这个字段是 taproot 交易的见证数据的一个可选部分。如果这个字段里面有数据,交易和 tapscript 中的签名必须承诺这个数据(使之无法被第三方添加、移除和改变),但当前没有其它得到定义的作用 —— 它是为了未来的协议升级(尤其是软分叉)而保留的。

    虽然之前已经有提议为 annex 定义一种格式,这些提议并没有得到广泛的接受和实现。Jager 提出了两种格式(1,以及 2),可用于在 annex 内添加任意数据,同时不会显著让后续的标准化工作变得更加复杂(未来的软分叉可能会捆绑这样的标准化工作)。

    Greg Sanders 询问 Jager 具体想在 annex 中存储什么样的数据,并介绍了他自己在使用 Bitcoin inquisition(见周报 #244)测试 SIGHASH_ANYPREVOUT 提议以及 LN-Symmetry 协议时对 annex 的用法。Sanders 也提出了一个关于 annex 的问题:在一个多方参与的协议(例如 coinjoin)中,每一个签名者都只承诺自己的签名所在的输入的 annex —— 不包括同一笔交易的其它输入的 annex。这意味着,如果 Alice、Bob 和 Mallory 一起签名了一笔 coinjoin 交易,Alice 和 Bob 无法阻止 Mallory 广播一个携带了更大体积的 annex 的交易版本,从而推迟交易得到确认。因为 Bitcoin Core 和其他全节点目前不会转发包含了 annex 的交易,所以现在这不是一个问题。Jager 回复 称他希望实现一种不需要软分叉的 “保险柜” 合约,要在 annex 里面存储来自一次性密钥的签名;而且他指出 Bitcoin Core 之前的一些工作可能可以解决这个 annex 影响多方协议的问题。

  • 静默支付的 BIP 草案:Josie Baker 和 Ruben Somsen 在 Bitcoin-Dev 邮件组中发帖出示了一份关于静默支付的 BIP 草案。静默支付是一种可复用的支付码,将为每一次使用生成一个唯一的链上地址,从而阻止输出关联。输出关联会显著降低用户的隐私性(包括并不参与这笔交易的用户的隐私性)。这份草案非常详尽,给出了这份提议的好处、牺牲以及软件如何有效使用它的指南。一些富有洞见的评论已经在该 BIP 的 PR 中出现。

等待确认 #5:用于保护节点资源的规则

这是一份关于交易转发、交易池接纳和交易挖矿选择的限定周刊,目标是解释为什么 Bitcoin Core 具有比共识规则更严格的交易池规则,以及钱包如何更高效地使用这些规则。

在本系列文章的开篇,我们提到,比特币的隐私和抗审查特性,都来自于网络的去中心化。用户运行自己的节点的习惯,减少了单点故障、监视和审查。这又来自于比特币节点软件的首要设计目标:运行节点是非常轻松的。如果每个比特币用户都需要购买昂贵的硬件、使用特定的操作系统、每个月支出数百美元的运营成本,那网络中的节点数量可能会大大减少。

此外,比特币网络中的节点就是一台计算机,它使用互联网跟陌生人的节点相互连接;这些陌生人可能会对这个节点发送 “拒绝服务式(DoS)” 攻击:发送会导致这个节点耗尽内存然后宕机的消息、使用无意义的数据耗费这个节点的运算资源和贷款从而使之不能接收新区块。因为这些陌生人都是匿名的(系统本身就是这样设计的),节点无法在连接之前预先断定哪个对等节点是诚实的、恶意的;而且在观察到攻击之后也无法有效地绝交。所以,实现保护节点免受 DoS 攻击的交易池规则,不仅是一种理想,更是一种现实需要。

节点实现中内置了通用的 DoS 保护措施,以防止资源耗尽。举例来说,如果一个 Bitcoin Core 节点从单个对等节点处收到许多消息,那么它会仅处理第一条收到的消息、将其余的消息放到一个待处理队列中,等其他对等节点的消息到达之后再处理。类似地,节点一般会先下载一个区块头,待验证完这个区块头的 “工作量证明(PoW)” 之后,才下载和验证完整的区块。因此,任何希望通过区块转发来耗尽这个节点的资源的攻击者,都必须先花费不成比例的大量资源计算出一个有效的 PoW ,然后才能施行攻击。PoW 的高昂计算成本和微不足道的验证成本,提供了一种应对区块转发 DoS 的天然方法。但这种特性无法延伸到 未确认的 交易的转发中。

通用的 DoS 保护措施并不能提供足够多的抗性,让一个节点的共识引擎可以放心地暴露在点对点网络中接收输入。攻击者可以尝试制作一个计算任务极为繁重、但在共识上有效的交易,就像区块 #364292 处出现的这笔 1MB 的 “巨型交易” 一样,因为签名验证中的哈希运算量呈平方级膨胀的问题,它需要反常的长时间来验证。攻击者也可以制作一个只有最后一个签名无效的交易,让节点在这笔交易的验证上花费大量的时间,直到最后才发现它是个垃圾。在这样浪费时间的时候,节点会推迟处理新的区块。你可以想象,某个矿工可以针对自己的对手发起这样的攻击,从而在下一个区块的挖掘中获得 “起跑优势”。

为避免处理计算量非常繁重的交易,Bitcoin Core 节点为每一笔交易施加了一个体积限制和签名操作(“sigop”)数量限制,这个限制比共识规则在区块层面实施的限制更为严格。Bitcoin Core 节点也对祖先交易包和后代交易包的体积施加限制、让区块模板的生产和驱逐算法更加高效,同时还会约束交易池插入和删除操作的计算复杂度(更新一笔交易的祖先和后代集合就涉及这样的操作)。虽然这意味着一些合法的交易可能不会被接受和转发,但预计这样的交易是罕见的。

这些规则都是 “交易转发规则” 的案例 —— 节点在共识规则要求之上,对未确认的交易施加的额外验证规则。

默认情况下,Bitcoin Core 节点不会接受手续费率低于 1 聪/vb 的交易(“minrelaytxfee”),也不会在检查完这个要求之前验证任何签名,也不会在交易池接受一笔交易之前转发这笔交易。从某种意义上说,这个手续费率的规则,是在为网络验证和转发的工作设置一个 “价格” 的下限。不挖矿的节点不能收到手续费 —— 交易只会给确认它的矿工支付手续费。但是,手续费代表了攻击者的成本。如果有人要通过发送大量的交易来 “浪费” 网络的资源,那么 TA 最终将因为手续费而耗尽资金。

Bitcoin Core 所实现的手续费替换(Replace by Fee)” 规则要求替换交易支付比跟它直接冲突的任一笔交易更高的手续费率,同时还要求它所支付的手续费总额也要比任一笔竞争交易更高。而且,额外支付的手续费除以替代交易的虚拟体积,必须至少是 1 聪/vb 。换句话说,无论原版交易和替代交易的手续费率的绝对水平如何,新交易都必须为自身所耗费的网络带宽支付至少 1 聪/vb 的 “新” 手续费。这个手续费规则的首要顾虑不是激励兼容性。相反,它是为重复的交易替换施加一个成本下限,以阻止浪费带宽的攻击,比如,每笔替换交易只多付 1 聪手续费的攻击。

完全验证区块和交易的节点,需要包括内存、运算力、网络带宽在内的资源。我们必须保证资源要求处于较低水平,从而让节点容易运行,并保护节点免受轰炸。通用的 DoS 保护措施是不够的,所以节点需要在验证未确认交易时,在共识规则之上应用交易转发规则。但是,因为这样的规则不是共识的一部分,两个节点可能会使用完全不同的规则,但依然能对链的最新状态达成共识。下周,我们会讨论作为个人选择的交易池规则。

Bitcoin Core PR 审核俱乐部

在这个月度栏目中,我们会总结最新的一期 Bitcoin Core PR 审核俱乐部会议,举出一些重要的问题和回答。点击下方的问题描述,可以看到会上对该问题的回答总结。

允许白名单中的入站节点在连接满载时更主动地挤出其他对等节点” 是一个由 Matthew Zipkin(pinheadmz)提出的 PR,提升了节点运营者在特定场合中为自己的节点配置更理想的对等节点的能力。具体来说,即使节点运营者为潜在的入站对等节点(inbound peer)配置了一份白名单(例如,由该节点运营者自己控制的另一个轻节点),那么,在没有这个 PR 的时候,节点也可能会拒绝这个轻节点的连接(这也取决于该节点的对等节点的状态)。

这个 PR 让理想的对等节点更有可能连接到我们的节点。它是通过断开现存的入站对等节点来做到的;而在没有这个 PR 的时候,这些入站对等节点无法断开。

  • 为什么这个 PR 仅适用于入站的对等节点请求?

    出站的(outbound)连接是由我们的节点自己 发起 的。这个 PR 修改的是我们的节点 响应 一个他人发起的连接请求时的行为。出站对等节点也可以断开,但那是通过一个完全独立的算法实现的。 

  • 在调用 SelectNodeToEvict() 时,使用 force 参数会对结果产生什么影响?

    指定 force 参数为 true,会保证返回一个非 noban 入账节点,如果有的话;即使如果不使用 force,该节点会被保护、不会被断开。没有这个 PR,函数不会返回一个被保护(不会被断开)的节点。 

  • 这个 PR 会如何改变 EraseLastKElements() 的功能签名?

    这个函数会从一个返回 void 的函数,变成返回最后一个从候选断连列表中移除的条目。(这个 “受到保护” 的节点可能也会被断连,如果有必要的话。)但是,作为这次审核俱乐部会议的讨论成果,这个 PR 后续会简化,从而这个函数不会改变。 

  • EraseLastKElements 曾经是一个模板化的函数,但这个 PR 移除了两个模板参数。为什么要这样做呢?这个变更有什么缺点吗?

    这个函数曾经会,现在(有了这个 PR)也会使用独特的模板参数来调用,所以不需要这个函数是模板化的。这个 PR 对这个函数的变更已经被撤回了,所以它依然是模板化的,因为改变它超出了这个 PR 的范围。 

  • 假设我们向 SelectNodeToEvict() 传入了一个有 40 个断连候选的向量。在这个 PR 实施前后,可以保护起来不断连的 Tor 节点的理论上限有变化吗?

    不论有无这个 PR,都是 40 个节点中的 34 个,假设它们都是入站节点,并且都不是 noban 节点的话。 

新版本和候选版本

热门的比特币基础设施项目的新版本和候选版本。请考虑升级到新版本或帮助测试候选版本。

  • Core Lightning 23.05.1 是这个闪电节点实现的维护版本。它的更新说明里面说:“这是一个仅仅包含 bug 修复的版本,修复了外部报告的多种宕机情形。建议所有使用 v23.05 的运营者升级到此版本。”

重大的代码和说明书变更

本周出现重大变更的有:Bitcoin CoreCore LightningEclairLDKLNDlibsecp256k1Hardware Wallet Interface (HWI)Rust BitcoinBTCPay ServerBDKBitcoin Improvement Proposals (BIPs)Lightning BOLTsBitcoin Inquisition

  • Bitcoin Core #27501 添加了一个 getpriorisisedtransactions RPC,可以返回由用户使用 prioritisetransaction 创建的所有手续费的偏移量(deltas)的表,由 txid 索引。这个表也会指出各交易是否在交易池中。亦见 周报 #250

  • Core Lightning #6243 升级了 listconfigs RPC,将所有的配置信息都放在单个目录中,同时,也会把所有配置选项的状态都传递到插件系统以重启插件。

  • Eclair #2677 将默认的 max_cltv 参数从 1008 个区块(大概一周)提升到 2016 个区块(大约两周)。这延长了支付超时的时间上限(以区块数量计)。这项变更的动机是为了让网络中的节点可以有更长的尝试支付的时间窗口(cltv_expiry_delta),以应对高手续费率的环境。类似的变更已经被 LND 和 CLN 合并

  • Rust bitcoin #1890 加入了一种方法,可以统计在非 tapscript 脚本中的签名操作(sigop)的数量。单个区块内的签名操作的数量是受到限制的,而且 Bitcoin Core 的挖矿交易选择算法也会将 “签名操作体积比(ratio of sigops per size)” 更高的交易当成更大的交易,实际上就是让它们的手续费率降低。这意味着,交易的创建者使用这种新方法来检查自己所使用的签名操作的数量,会变成一件重要的事。