本文讨论了比特币中 BIP30 存在的共识 bug 以及 BIP30 UTXO 集检查的低效性。作者提出了两种可能的解决方案:一是限制重组的深度,二是将 BIP30 的检查替换为 coinbase 交易唯一性检查,并确保与未来的 coinbase 交易不冲突,从而实现 BIP30 的完全退场。
作者:Ruben Somsen
来源: https://gist.github.com/RubenSomsen/a02b9071bf81b922dcc9edea7d810b7c
在我最近关于 “ SwiftSync” 的研究( 中文译本)中,我意识到, BIP30 有一个尚未解决的共识 bug 。看起来,如果没有能够深及 2010 年的区块链重组,就不会触发这个 bug ,所以它是否严重是可以辩论的。我们当前的比特币客户端带有 2013 年的检查点,所以能够防止这样深的重组。但是,一旦我们 移除了所有的检查点,这个 bug 就成为理论上可能被利用的了。
(译者注:“检查点” 是一种特殊的维护区块链网络共识的手段:在客户端软件中强制约束某一高度的区块哈希值应为某个值,如果所得的的区块的哈希值不是这个值,就拒绝它。在基于工作量证明(PoW)的区块链网络中,这种手段可用于防止新加入网络的节点被诱骗到可以低成本制造的恶意区块链上(随着挖矿机器能力的提升,制造与较为久远的历史区块同等难度的区块会变得越来越便宜)。尽管有这种正面理由,人们还是倾向于认为,允许存在这种机制可能会给客户端的开发者太大的权力(担心这足以让开发者在实质上决定用户选择哪一条区块链)。因此,向来就有在客户端中消除这种机制的努力。)
从共识检查的角度看,BIP30 也有一些奇怪,因为它需要遍历整个 UTXO 集,即使它们与交易所花费的输入无关。这是低效的,而且让另类的验证模式(例如 utreexo、SwiftSync,很可能也会影响到基于零知识证据的系统例如 ZeroSync)的实现变得复杂许多。如果我们可以让 BIP30 完全退场,那会是一件好事。
并不是非要倡议采取什么行动(现状似乎相当不错),我希望为上述两者提出解决方案并开启讨论。
有两笔重合交易被 BIP30 视为例外。后一笔重合交易是区块高度 91880 的 coinbase 交易。当这笔交易得到处理的时候,区块高度 91722 的 coinbase 交易就被覆盖掉了。另一个这样的情况发生在 91812 和 91842 两个区块上。
那么,当区块链重组到区块高低 91880 和 91772 之间的时候,问题就会发生。在我们回滚区块链的时候,91880 区块所创建的输出会从 UTXO 集中移除。结果是,被覆写的输出就从 UTXO 集中完全消失了。而另一个从未见证过这次重组的节点,却依然保留着这个输出在自己的集合中(因为它从未被覆写过)。一旦这个 UTXO 被花费,链分叉就会发生。
我们可以强制,重组不能刚好停留在 91722 区块和 91880 之间 —— 要么深到 91722 区块之前,要么浅到只在 91880 区块高度之后。这保证了不论是经历过重组的区块,还是新的节点,在自己的 UTXO 集中都不会有这个问题输出。考虑到这是在 2010 年的挖矿难度下的大约 160 个区块,这不会是什么很大的限制。
在跟 Sjors Provoost 讨论我的发现时,他支出, 正在被考虑的 移除检查点(自身可被视为一种硬分叉)也是一种改变检查点以前的共识规则的机会 —— 我们可以在触及区块高度 91880 和 91842 的重组时不移除 coinbase 交易,从而修复这个 bug 。除此之外,Sjors 的观察也开启了一个问题:我们是否想要改变 2013 年以前的其它共识规则。
当前,BIP30 的适用范围是从创世区块到 BIP34 激活(区块高度 227931,2013 年 3 月)。如果这个区块被重组,BIP30 就会保持无限期适用。BIP34 也有自身的问题,在 “ 共识清理 BIP” 中得到了解决 —— 你可以自己读读,我在这里就不展开了。
技术上来说,BIP30 仅仅是为了防止出现重合的 未花费 输出。它是通过检查已经存在于 UTXO 集中的每一个条目(如有重合就拒绝制造重合的区块)来保证这一点的(也正是其低效所在)。2010 年出现的两笔重合交易被硬编码为例外。在这些规则下,花费一个输出、然后又重新创建出相同的输出,是不违反规则的。不过,这似乎从没发生过。
最后一个要解决的问题是,为什么如果区块 227931 被重组,BIP34 就会被弃用。原因是,如不相应弃用,就有可能在 BIP34 激活之前创建出违反 BIP34 规则(确保 coinbase 交易唯一性)的输出(这也正是共识清理提议尝试解决的问题)。
理想情况下,让 BIP30 检查完全退场(确保即使发生区块重组也不再需要它)是好事。
给定除了那两个例外,我们并没有重合交易,我们可以将低效的 BIP30 UTXO 集检查替换成 coinbae 交易唯一性检查。我们只需缓存 coinbase 交易的 TXID,并确保 coinbase 交易中没有重合交易,即可。持续到区块高度 227931 的检查只需要大约 7MB 的缓存。然而,因为 BIP34 可能被弃用,BIP30 检查可能会一直持续,那这样我们就会有一个不断增长的缓存。解决方法如下。
除了检查 coinbase 交易的唯一性,我们也检查它不会与未来的任何 coinbase 交易冲突(即,不会与 BIP34 和共识清理 BIP 相冲突)。这保证了 BIP34 可以在区块高度 227931 激活,无论是否会发生重组。
以上是 BIP30 的一些问题以及可能的解决方案。无论我们是否要行动,本文都可作为一种参考。感谢 Antoine Poinsot、Pieter Wuille 和 Sjors Provoost 在本文发表之前的讨论。
- 本文转载自: btcstudy.org/2025/09/02/... , 如有侵权请联系管理员删除。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!