翻译Gavin 博文 升级到2MB版本的导游

vatten Yellow v2 · 2016-02-06 11:14 · 296 次点击 · 4.20691375

把区块大小从1MB改到2MB听起来很容易:就把1改成2就完了,对么?

如果我们不关心一个平稳流畅的升级,那么确实可以是这么简单。就把下面这行代码(在src/consensus/consensus.h里)

。。。 MAX_BLOCK_SIZE = 1000000
改为
。。。 MAX_BLOCK_SIZE = 2000000

如果你改动这一行,重新汇编并运行新生成的比特币核心,它将正常工作。你的计算机将会下载区块链并和网络上的其他节点协同工作,毫无问题

如果你的节点是挖矿节点(solo mine或者矿池管理者),那就要更复杂一些。接下来我就要陈述这些复杂的地方,希望能让你理解为了保证升级的安全需要做出多少努力

GITHUB有个功能可以比较代码,打开
https://github.com/bitcoin/bitcoin/compare/v0.11.2…gavinandresen:two_mb_bump
你就可以看到所有的有关升级到2MB的代码改变,你将看到

有五个commit, 一个commit是一组相关的代码改变,他们共同实现区块大小升级(请忽略David Harding的第一个commit,那只是core 0.11.2版本的最后一个commit)

22个文件被改变了,大约900行新代码,其中一半以上(500行)是新的测试程序,以便保证新代码正常工作

第一个commit是“为升级2MB所需最小共识/矿工变化”,这不大,少于20行。你可以看到有一行把MAX_BLOCK_SIZE从1000000字节改到2000000字节。其他的变化是矿工需要知道的,以便决定是否安全并开始产生大的区块。一个新的MaxBlockSize()方式被定义以便返回旧的或是新的区块上限,决定的依据是区块头中的时间戳

共识变化体现在main.cpp的第2816行里的CheckBlock()方式,并使用新的MaxBlockSize()方式而非MAX_BLOCK_SIZE来决定一个区块是否过大。一个类似的变化也发生在CreateNewBlock()函数以及’getblocktemplate’远程调用里,以便矿工能够产生更大的区块

下一个commit (“Testing infrastructure fixes”) 在我们用于测试比特币代码变化的程序中加入了几个新功能和修复了一个漏洞

有两个级别的测试:单元测试(unit test) 是放在 src/test里,用C++些的,确保代码语句都正确。回归测试 (regression test) 在qa/rpc-tests里,用Python写的,用远程调用的接口和bitcoind 的 -regtest 模式对接,可测试所有的功能都正确运行

“矿工投票和缓冲期后的2MB分叉”是目前最多的commit – 几乎有700行代码。这里实现了升级的规则:在75%算力通过在区块版本中设定一个特殊的位来表示支持升级,以及28天缓冲期到达后产生大于1MB的区块

75%和28天原则是人为的选择。我讨厌人为的选择,因为太容易产生意见的分歧而争论不休。我另有一篇博文解释为什么选择这些数字是好的
http://gavinandresen.ninja/seventyfive-twentyeight

“矿工投票和缓冲期”代码是从XT的BIP101里借用来的,有三层的测试

在block_size_tests.cpp里有一个新的单元测试。测试CheckBlock()调用,创建刚好够1MB和2MB的区块,以及各大出1个字节的区块,测试这些区块是否会分别按照规则在升级前和升级后被接受/拒绝

此外还有一个新的回归测试,bigblocks.py 在开发者的机器上运行4个比特币核心线程,创建一个区块链(回归测试中区块可随时创建),并测试分叉的激活代码,保证矿工的算力投票被正确计算,并保证在缓冲期结束之前不产生大区块。此外还要保证这个代码在2018年1月的限期到达之后无效

绝大多数我的开发时间都放在保证回归测试和单元测试彻底的测试了新代码。一旦回归测试和单元测试通过了,更多的其他测试可以在testnet上进行。写代码是简单的部分

最后,这套升级代码已经被Jonathan Toomim在测试XT的8MB方案的时候在testnet上反复测试过(也通过了中国的防火墙)

继续看代码变化。。。

main.cpp里的IsSuperMajority()函数以及block.h里的VersionKnown()函数有一些改变,用于统计矿工支持各类变化提议的区块数。因为要保证和 BIP009以及在区块升级过程中要实现的其他的一些BIP兼容

除了测试代码以外,最多数的代码变化发生在txdb.cpp上。当矿工投票成功后,触发的那个块的哈希值被写入区块链目录。这并不是绝对必要的,可以通过扫描所有块的办法同样得知投票是否成功。只是这个信息放在区块链目录里效率更高

天,写这些没准比写代码花的时间还长。还剩两个commit

“准确的计算和限制sigop/sighash”是重要的,因为如果没有限制,大区块会变得危险。你可以看看我11月在DevCore上的演讲。总的来说,Satoshi并没有仔细考虑交易是如何被签名的,结果就是可能构建一些极为消耗CPU时间来验证的交易。这个commit把这个问题解决了,通过一个新的ValidationCostTracker来持续追踪验证区块的工作量,并和一个新的限制MAX_BLOCK_SIGHASH一起保证没人可以通过发布一个极为耗时验证的区块来阻塞网络

通常人们不想产生这样极为耗时验证的区块,矿工希望尽快广播自己的区块减少被孤立的可能。但安全的编程实践是必要的

MAX_BLOCK_SIGHASH又是一个人为设定的值,它设在1.3GB,大到足够使目前已有的任何区块不会达到这个值,但也足够保证不会出现花好几分钟才能验证的区块

最后一个commit,“不转发和打包含有大量sighash的交易”是另一项安全措施。目前已有一些防止大的、验证费时的规则,但这条加入了另外一个限制,以保证一个聪明的黑客不能诱骗矿工打包一笔验证极为耗时的交易

如果你有耐心一路看到这里,你能集中注意力的时间已经比我要长了。对非程序员来说,我希望你能因此而了解为了把1改成2所需要付出的努力


译后注:我觉得没有必要谈论测试程序那部分,毕竟这和升级的直接关系不大,软件发布需要提供相关的测试代码是规范。但我想他应该是为了向不懂的人表明任何改变所涉及的实际工作量

kcb medium avatar
1

kcb Yellow v    27 天前

感谢@vatten!!!
这篇文章很技术啊,这么大工作量!
辛苦辛苦!

8btc上也发一个呗~

比特币感谢地址: 1CWdUWWgdVuLi7aBHNALqijXm1aecZxCuC
xraysun medium avatar
2

xraysun Yellow v    26 天前

我注意到Gavin的博客域名后缀是ninja,忍者。。。

比特币感谢地址: 1XrayTebdqtdKeLPdw8XQVcbBPUL9viKe
Trueiron medium avatar
3

Trueiron Yellow v    26 天前   via Android

设置一下感谢地址,让我们能感谢一下你吧!

比特币感谢地址: 1ronNBrnGoAmfTQ9L5mXcSJUL3moNzoz2
BitThink medium avatar
4

BitThink Yellow v    26 天前   via iPhone

赞原创翻译

比特币感谢地址: 1Aug9NQPT1Hotn6BGhc14YeRHszMduhU79
mkz899 medium avatar
5

mkz899 Yellow v    26 天前   via iPhone

請設置感謝地址,在比特幣價值還沒因為分叉失敗歸零前我用來感謝下譯者的工作

比特币感谢地址: 12tuNgu2RHYQy7BNcU2AubvPx3dPN1qjsV
cndx medium avatar
6

cndx Yellow v    26 天前   via Android

我反而觉得

MAX_BLOCK_SIZE = 2000000

然后再加个90%区块支持即启动硬分叉的规则即可。

其它代码感觉都是画蛇添足。加得越多风险越大。

像1.3GB的MAX_BLOCK_SIGHASH限制,有必要吗?整个区块大小都限制在2MB了,怎么可能会有超大的签名?
反而加上这些代码万一影响了其它正常的代码怎么办?

其它那些众多的测试代码,本地测试即可,何必写到钱包中?

比特币感谢地址: 1DogeKd9JrUNzFaLEyWAVxCVXSvWxe6sAm
BitThink medium avatar
7

BitThink Yellow v    26 天前   via iPhone

@cndx 你又来对自己不熟悉的领域乱评论了。

1,这个交易验证在特殊情况下会有平方复杂度的问题很多人都清楚。扩容必须先解决这个问题。包括SW方案也是在bip143里改进了验证方法的。
https://gist.github.com/gavinandresen/4e4a22d41103a0f1ae19
上面是个参考链接。简单说就是构造一个特殊的非常多input和一个output的交易,会导致验证是做很多遍的签名hash。交易本身1M的话做1000次就是1G了。加个1.3G的上限当然是有用的。

2,测试不放进代码,下载的人怎么测试?之后改代码的人怎么保证自己的commit能够通过测试呢?

比特币感谢地址: 1Aug9NQPT1Hotn6BGhc14YeRHszMduhU79
cndx medium avatar
8

cndx Yellow v    26 天前

BitThink 只有自己很熟悉的领域才能评论,那岂不是强行剥夺了很多人的话语权??

1、加个1.3G的上限有用,那你就这样解释下,我学习了即可,这样我也涨知识了,那不很好么?这才是论坛交流的目的。

75%和28天原则是人为的选择。我讨厌人为的选择,因为太容易产生意见的分歧而争论不休。

75%确实引起很大的争议,建议修改为90%。支持90%2MB共识。
那这个1.3GB是否也是人为的选择的。是否大小合适?

2、层主说

测试不放进代码,下载的人怎么测试?之后改代码的人怎么保证自己的commit能够通过测试呢?

建议可以开发个独立的测试工具即可。即开发个独立的开源测试软件,而不是和主代码混杂放在一起。

比特币感谢地址: 1DogeKd9JrUNzFaLEyWAVxCVXSvWxe6sAm
mkz899 medium avatar
9

mkz899 Yellow v    26 天前   via iPhone

挺受教益,讓我這非技術的關注者也能略窺其中一二細節。

@cndx 真是無知還無畏
“BitThink 只有自己很熟悉的领域才能评论,那岂不是强行剥夺了很多人的话语权??”

—-自己不熟悉而放棄評論,這是自知之明、自我剝奪,自己剝奪自己的話語權沒問題。
自己不熟悉要參與評論,要與別人探討,難免會給別人帶來普及基礎知識或背景知識的額外精力消耗,不妨自己做功課後發言或直接請教,而不是想當然的神遊或反問。我想這是正確的態度。

“加个1.3G的上限有用,那你就这样解释下,我学习了即可,这样我也涨知识了,那不很好么?这才是论坛交流的目的。”

—-我表示懷疑,每個人來論壇的目的是專門來義務幫你長知識的,如果是也沒有你們上面的關於想當然發表評論的對話了。

比特币感谢地址: 12tuNgu2RHYQy7BNcU2AubvPx3dPN1qjsV
cndx medium avatar
10

cndx Yellow v    26 天前   via Android

@mkz899 繁体是在香港还是台湾,若是台湾,关心问候一下,还好吧。

首先,我只是按他的逻辑说即使我不太懂,也应该有发言权。你当然有选择自己剥夺自己发言权的权力,但是不能强迫别人都自己剥夺自己的发言权。
科普知识不是一个只说一个只听。完全可以对一些点提出质疑或提问。只有这样有交互才能更好地科普。因为你提出疑问的点,很可能同时也是其它人疑问的点,也是欠科普透的点。一个好的科普者是不会拒绝别人提问质疑的。尤其是以“你自己不熟悉的领域乱评论了”的理由借口来拒绝。

其次,我并不是完全不懂不熟悉。只是他说我不熟悉而已。
我开发过大量币应用http://idgui.com 虽然只是做币应用,没有花大量时间研究核心QT钱包,但整个币的构架,区块的构架,整个币收发打包等等均较清楚的,假设连我这样的人都因“不熟”无权留言评论,那么可能就类似于禁止评论讨论了。

外行人有个误区就是以代码行数来评价开发量。实际上是很误解的。真正的关键的开发量是思路的缜密,在代码层面想到各种意外然后对这些意外处理。而不是单纯的靠加很多测试代码,和靠重写一些本来就可以用的函数,或可有可无的代码来累积行数。往往代码越多出错出漏洞的几率越大。
这是针对核心的修改,不像以前只是修改一下外观,修补漏洞。
我还是建议在Classic正式版中还是改变越少越好。

比特币感谢地址: 1DogeKd9JrUNzFaLEyWAVxCVXSvWxe6sAm
BitThink medium avatar
11

BitThink Yellow v    26 天前   via iPhone

@cndx 对不熟悉的领域可以探讨和询问 这当然没问题啊。比如你刚开始就说这个1.3G是干什么用的,不是挺好吗?:)另外即使是评论也没大问题,我指的是乱评论,其实就是不要乱批评的意思。这样对辛勤写代码的人不公平。

测试其实是代码很重要的一部分,1)可以增加写代码者自己对代码的信心 2)避免修改代码者破坏原来的正确性 尤其是现在有了持续集成系统 每次提交代码都需要通过所有测试 3)测试代码也可以帮助读者理解代码要达到的目的。

可以这么说,测试的覆盖率是评价一个开源项目的重要指标。

比特币感谢地址: 1Aug9NQPT1Hotn6BGhc14YeRHszMduhU79
BitThink medium avatar
12

BitThink Yellow v    26 天前   via iPhone

@cndx 另外你既然是开发者 应该清楚测试代码和运行代码是分开的吧?无论加多少测试代码,都不用担心会改变运行代码部分的。

当然我也明白你现在想快速提高积分数,所以有时也许故意这样说,以吸引回复与@。只是我老是管不住自己,就算配合一下你吧。牺牲我两分给你加四分。:)

比特币感谢地址: 1Aug9NQPT1Hotn6BGhc14YeRHszMduhU79
cndx medium avatar
13

cndx Yellow v    26 天前

@BitThink 谢谢送分。
看看我就是问的:“1.3GB的MAX_BLOCK_SIGHASH限制,有必要吗?” 和问“1.3G是干什么用的”难道不是类似的问法吗?

我那是询问是否有必要的疑问句。并不是乱评论,说1.3GB完全没有必要的陈述句。

测试代码和运行代码虽然是分开的,但是测试代码中若有漏洞,是可以加以利用来攻击系统。这个你应该认同吧。

关于积分,我承认我是很重视,但是不至于为了刷积分而故意那么说,引你回复。

看看我的所有贴,包括早期比特币贴吧,近期巴比特,几乎很少有纯刷经验的发贴或回复贴。

比特币感谢地址: 1DogeKd9JrUNzFaLEyWAVxCVXSvWxe6sAm
vatten medium avatar
14

vatten Yellow v    26 天前

忘了放原来的链接
http://gavinandresen.ninja/a-guided-tour-of-the-2mb-fork

总结一下就5个commit:

第一个commit是“为升级2MB所需最小共识/矿工变化”
第二个commit是“有关基础架构测试程序的修补”
第三个commit是“矿工投票和缓冲期后的2MB分叉”
第四个commit是“准确的计算和限制sigop/sighash”
第五个commit是“不转发和打包含有大量sighash的交易”

第二个是测试相关,而第一个和第三个一起实现了扩容2MB,第四个和第五个一起实现了禁止验证极为费时的交易在网络中传播,这也是当初扩容2MB最大的一个担心,因为鱼池曾产生过一个花了30秒才验证的1MB区块

vatten medium avatar
15

vatten Yellow v    26 天前

@Trueiron @mkz899 多谢支持,感谢地址就算了,我自己是交易商,可以看到买币的人以每年三倍的速度在增长,有空转发些相关知识,方便大家更多了解事实以便自己独立做出决策

我不精通C++,就算读了这么多,也不可能看懂每一行代码。还是觉得那个账本的例子最形象,几乎可以用来向任何没有IT知识的人解释比特币相关的几乎所有问题

Advertisements
翻译Gavin 博文 升级到2MB版本的导游

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s