提示:作者 Johnson Lau 为Bitcoin Core贡献者,参与隔离见证的开发
背景
Bitcoin Unlimited (BU) 这个软件,是以 Bitcoin Core (BC) 为基础,加上一些改动。除了最为著名的取消区块上限的改动以外,其实也有很多不被留意到的小改动,这次意外就是由一个在技术上没有实际好处的改动所导致。
事件经过
事件经过可以参考BU一方的解释 https://bitco.in/forum/threads/buir-2017-01-29-statement-regarding-excessive-block-by-bitcoin-unlimited-software-29-jan-2017.1790/
在打包交易的时候,由于奖励交易 (coinbase) 的大小存在不确定性,BC在设计上预留了1000 字节的安全空间。这相等于区块上限的千分之一,对矿工收益和网络确认交易速度的影响可以完全忽略,却可以防止出现区块意外过大的情况。
2015年11月14日,BU开发员Andrew Stone移除了以上限制
https://github.com/gandrewstone/BitcoinUnlimited/commit/56015b9232f14c472ad35a3a13021a26ab4410b5#diff-4a59b408ad3778278c3aeffa7da33c3cL123
这项修改没有经过任何讨论而被直接加进BU代码。然而由于BC另有机制防止出现问题,所以BU一直以来都没有因此产生无效区块。
一年后,2016年11月17日,Andrew Stone建议对BU代码进行改动 (#164)
https://github.com/BitcoinUnlimited/BitcoinUnlimited/pull/164/
改动的名义上是改变交易大小和签署数目的限制,但实际上包括了各种不同的改动,包括导致这次事件的改动:
https://github.com/BitcoinUnlimited/BitcoinUnlimited/pull/164/files#diff-4a59b408ad3778278c3aeffa7da33c3cL124
#164完全解除了1000 byte的安全空间,但并没有对原因作出清楚解释。纵观对#164的110项讨论,并没有任何人对该项改动提出任何意见。
2016年12月22日,#164被合并到BU的代码。
2017年1月27日,包含#164的BU 1.0.0 发布。
2017年1月29日,运行BU 1.0.0 的Bitcoin.com矿池意外生产了一个大小为1,000,023 byte的无效区块,超过了现有可被接受的上限1,000,000 byte。
根据 Bitcoin.com 的解释:https://forum.bitcoin.com/mining/bitcoin-com-s-excessive-block-pool-analysis-t16844.html
这无效区块经过 Bitcoin.com 的私人网络快速传播出去。由于他们的部份私人节点会接受高达16MB的区块,这无效区块就被传到公开的Bitcoin网络。
对Bitcoin网络的影响
大量BU节点也接受了这个无效区块,并传递给BC节点。 BC节点拒绝接受并封禁了这些BU节点。
在众多的区块浏覧器,只有 blockcypher 留下了纪录:
https://live.blockcypher.com/btc/block/000000000000000000cf208f521de0424677f7a87f2f278a1042f38d159565f5/
根据Bitcoin.com的纪录,无效区块450529号在6:58:48挖出,在一秒内即6:58:49,包括ViaBTC, BTC.TOP, BTC.com, HaoBTC, BTCC, F2Pool在没有验证的情况下,开始在无效区块之上盲挖(SPV mining)。各矿池纠错需时:BTCC 1秒,ViaBTC 14秒,BTC.TOP 31 秒,F2Pool 41秒,HaoBTC 61秒,其间没有发现新区块。直至7:20:19,Bitclub Network找出一个有效的450529号区块。
补救措施:发现问题后,BU即时建议矿工通过bitcoin-cli把生产区块的上限降为999,000 bytes。随后BU以#259修补该问题。
以上大致把事情有关的事实陈述出来。
———–
反应
Bitcoin.com 老板及 BU主要支持者 Roger Ver 于 reddit上声称这只是一个孤块,而孤块是很普通的事情,没什么大不了。
BU在其声明中指出,该缺陷没有在测试中被找出来,是因为BU的测试架构并没有考虑区块上限的问题,因此没有在公布前发现。
一般的批评,是指BU缺乏测试,不负责任等。
———–
评论
在阅读以下评论时,应留意本人为Bitcoin Core贡献者,深度参与隔离见证的开发。另外,本人从事Bitcoin相关活动并没有收取任何报酬,也不代表任何公司的利益。
这是否只是一般的孤块?
孤块的意思,一般是指两个相同高度的有效块,其中一个在竞争中没有被延长,最终被网络忽略。找到孤块的矿工得不到任何补偿,其中的交易如果没有在最长的有效链中被确认,也会变为未被确认,还会有被双花的风险。随着BC一直优化,孤块的情况在过去多年一直减少。现在的BU是基于BC 0.13,除了BU自家的xthin block以外,其余的主要优化都是BC多年的累积。
但这次发生的问题并不是一般的孤块,而是无效块,也就是没有一个认真参与Bitcoin经济的人会承认的区块。极少数的BU节点接受了这个区块,但这类节点一般只为兴趣或研究而建立,却绝对没有任何正式的钱包服务或交易所等会接受区块中的任何交易。如果真的有人接受了,视作等同于价值6000多人民币一个的Bitcoin,必会蒙受损失。
其它矿池也会产生无效块吧?
矿池产生无效块偶有发生,近年比较严重的一次是2015年有矿池在无效块上一共盲挖了6个区块。去年也有矿池生产了带有无效Coinbase交易的区块。以上的例子,都是矿池为了把利润最大化,制作自家的挖矿程序而出错;虽然也会对一般用户造成影响,但为矿池带来的损失也只是他们自己的事。
但BU的目标,是要提倡新的标准,期望大部份矿工和用户都会使用BU。他们把版本号改为1.0.0,声称这标志着Bitcoin一个时代的结束,将会有更多功能,更稳定,更大容量。 (https://bitco.in/forum/threads/announcement-bitcoin-unlimited-general-release-1-0-0.1783/) 。有这样的理想不是问题,不过单说稳定性一项便有很大疑问。
因为自家程序失误而损失,和制作不可靠的软件以管理一个市值千亿人民币的网络,是完全不同的事情。
为什么会找不出这缺憾?
根据BU的解释,是因为BU的测试架构并没有考虑区块上限的问题,意思是他们不是没有测试,只是测试得不够好。这解释我认为是不可以接受的,因为BU在推销时是以现有的矿工为目标,而矿工要有收益,挖出的块必须要被主流所接受。因此其测试环境,也必须要以主流的环境为标准。他们的测试方法,等于把实验品当作为稳定的制成品推销。
BC本身已经有一套完善的测试系统。另外,testnet也是一个有着不同软件共同使用的测试环境。只要BU曾经在testnet上测试,是必定可以找出这缺慽。
对其它矿池有什么影响?
根据Bitcoin.com的纪录,以下矿池花了1至61秒在无效区块上盲挖 (SPV mining):ViaBTC, BTC.TOP, BTC.com, HaoBTC, BTCC, F2Pool。这些矿池虽然没有找到任何区块,但PPS矿池实际上已承受了不同程度的损失。
矿池为了利润最大化,盲挖是常见行为,由于无效块非常罕有,长远的收益会高于损失。但作为负责任的矿池,应设法把盲挖的时间降低。如果处理一个 1MB区块也需时半分钟,体积倍增将令情况难以接受。
为什么会出现这样的缺憾?
以下的答案比较主观。
我认为除了技术水平以外,最重要是开发的态度。在BU的开发员决定要拿掉1000字节安全空间的时候,究竟目的是什么?没有任何解释。究竟有什么好处?也没有任何解释,也没有人发问。似乎目的就只是用尽区块每一寸空间,尽管只带来千分之一的改善。这一方面显示开发员对系统的不熟悉,更重要是显示他们的开发态度有着很大问题。
BU的开发态度,是不惜要解除一切安全限制,也要快速地把系统按其意愿推动。他们认为出了错也不重要,之后可以改过来。 (例如去年5月Roger Ver说如果Bitcoin因为过度扩容而变成中心化的PayPal2.0,也可以再搅一个Bitcoin 3.0出来:http://coinjournal.net/roger-ver-paypal-acceptable-risk-bitcoin / )。
这种”快速推进,不是暴发,就是死亡”的方针,是风投项目的标准策略。但Bitcoin系统绝不是一个风投项目。 Bitcoin是一个价值一千亿人民币的网络,还有数以十亿计的矿机矿池投资。更重要是,Bitcoin是去中心化的系统,也就是说,出了问题不会有人可以补救。打个比喻,你忘记了银行的密码,拿着身份证到银行签个名,就可以搞回来,因为银行是中心化的;但你被偷去了保管Bitcoin的私钥,就没有任何方法可以补救,因为那就是在去中心化系统中唯一可以证明身份的东西。如果强行要救,下场很可能就会是像以太坊一般的分裂。
因此我认为,从事Bitcoin开发的人员,一个重要的特质是要对每一个系统细节均非常敏感,时刻都要为最坏后果设想。因为任何错误造成的损失都是不能补救的,因此预防是唯一方法。这不只是技术水平问题,而是性格问题;技术可以学习,但性格却不容易改变。
事件还有什么启示?
虽然事件的发生是完全无意的,却正好表现了矿工在硬分叉上面的角色。当矿工生产出一个区块,却因为违反了一些规则而不为任何Bitcoin经济参与者所接受,这个块的唯一下场就是被忘记,传递这个块的节点被封禁,对整个Bitcoin经济而言,一切都好像没有发生过一样。
如果发生这事情的时候已经有大量矿工支持BU,在这个区块上开挖,又会如何?答案也是一样,如果这区块不为任何Bitcoin经济参与者所接受,无论他们挖什么也没有关系。无论有多少算力,也不能改变5000多个全节点所实行的任何规则,更强迫不了他们改用BU。要他们全节点改用BU的唯一合理方法,就是说服他们BU是可信的,安全的,对Bitcoin长远利益是好的。不先做到这一点而企图强行以算力突破,后果就必定和以太坊一样,甚至更坏。