重新创造比特币14:交易的同步

作者:何岩,由 recreating.org发行。

0.前言 #

在上一篇中,中本聪和Gilfoyle搞定了最简单的点对点网络。但是无法正常运行,因为账本还没实现同步机制。为了解决账本的同步,需要先引出交易的同步。

1.账本不一致 #

咖啡馆,中本聪对着老板Bob说:“老板,这几天Bitcoin系统要升级,暂时无法用了”

Bob说:“我看到了,你们又是搬机器,又是写代码,这次升级动静够大的。”

中本聪说:“是啊,Bitcoin要发生质变了,对了,你家要是有不用的机器也搬过来,我们需要更多节点。”

Bob说:“好啊,我家还真有一台,不过运行Bitcoin我能得到什么好处呢?”

中本聪说:“好处……这个我得想想,暂时还没有,纯是友情支持。”

Bob说:“好吧,看在你是我的老客户,我去给你搬过来。”

中本聪说:“太好了!你真是个慷慨的老板!”

中本聪对Gilfoyle说:“我们将要有第3个节点啦!现在,我们来解决账本的同步问题吧!”

我们假设一个交易场景:

1.Alice账本中的余额是50,并且记账节点1和记账节点2的账本一致。

2.Alice的客户端连接的是记账节点1。

3.Carol的客户端连接的是记账节点2。

4.Alice向节点1发送一个交易消息:Alice to Bob 50

5.Carol向节点2发送一个交易消息:Carol to Alice 30

6.这时候的Alice的正确余额本应该是30。但是由于账本没有同步,所以在节点1中Alice的余额是0,在节点2中Alice的余额是80,都不正确。(见下图)

图片 1.png

账本不一致

面对这个场景,应该如何解决账本不一致的问题呢?

中本聪解释到:“解决这个场景还算简单。只需要节点互相将自己的账本发送给对方节点,收到对方的账本后,找出自己账本中缺少的交易记录,然后将此交易记录补充到自己的账本,这样俩个节点的账本就又一致了。”
在上面这个场景中,

节点1补充进自己账本的交易记录是:Carol to Alice 30。

节点2补充进自己账本的交易记录是:Alice to Bob 50。

这样在俩个节点中的账本又恢复一致,Alice的余额都显示为30。(见下图)
图片 1.png

账本的同步

Gilfoyle感叹到:“多亏了UTXO机制,由于没有账户模型,交易不会修改过去的记录,只会在账本中新增交易记录,所以,节点间账本不一致也只会缺失彼此的交易记录,而不会存在数据冲突”

中本聪笑到:“别高兴的太早,我感觉不会这么简单。”

中本聪的直觉是准确的,这个同步机制的确存在漏洞,那就是所谓的双花,这还是等后面问题发生了,我们再去讨论,现在我们看看现在的账本同步方案,有没有什么优化空间。

2.交易的同步 #

中本聪说:“每次节点接受到新的交易,都发送全量账本给对方节点,这样做太浪费网络资源了,其实只需要将新增的交易记录发送给对方节点就够了。对方节点只需要将这条交易记录补充到自己的账本即可。”

Gilfoyle说:“那就是不再同步账本,而只同步增量交易记录。”

中本聪说:“如果只考虑新增交易记录的同步,那么具体步骤应该是这样的。”

中本聪解释着详细的增量交易同步机制:

1.节点1接受到用户通过轻节点发来的最新交易:Alice to Bob 50

2.节点1将这条交易记录写入账本,同时将交易记录通过自己的Socket Server广播出去。(这里之所以将Socket Server发送消息说成是广播,是因为一个Socket Server会连接多个Socket Client,这个传播路径很像广播。而反过来看,Socket Client主动连接Socket Server的行为则是:订阅,就好像用户通过收音机订阅了一个广播频道一样。所以,每个记账节点即能广播又能订阅。)

3.节点2由于订阅了节点1,所以可以收到这条新增交易消息。

4.节点2不可以直接写入自己的账本,因为自己的账本中没准已经存在相同的交易记录。所以要验证这条交易记录是否已经在账本中存在。

Gilfoyle不解的问到:“为什么会存在相同交易记录呢?”

中本聪解释到:“可能是Alice通过客户端同时在向节点1和节点2发起相同的交易请求。

也可能节点1发送同步消息的时候发重复了,这样第一遍节点2就已经将其写入账本了。”

5.如果本交易记录已经存在于节点2的账本中,则什么都不做,结束本次同步行为。

6.如果本交易记录不存在于节点2的账本中,则将其写入账本,同时将这条交易记录广播出去。提供给其它订阅自己的节点,让其它节点进行增量交易的同步。

Gilfoyle问:“为什么节点2还要再次广播这条同步记录,这条消息源头就是节点1给节点2的,节点2如果再广播出去,不就又到了节点1这里,这样不就形成消息的无限循环了吗?”

中本聪解释到:“不会循环的,因为你看第5条,如果发现交易记录之前存在,就会终止。”

中本聪继续解释到:“而节点2为什么要再次广播呢?这是因为,如果节点3加入到了记账网络中,而节点3只订阅了节点2,没有订阅节点1,那么就需要节点2作为一个传话筒,将自己订阅节点1的同步消息传递给节点3。”(见下图)

图片 1.png

节点3只订阅了节点2

Gilfoyle说:“明白了,这样就严谨了,在点对点的网络中,节点的角色即是消费者,又是服务者。真是人人为我,我为人人啊!”

中本聪说:“对,这样任何一个节点,广播任何一条消息,都可以一瞬之间传遍整个网络,一石激起千层浪。”

Gilfoyle说:“这让我想到,上周在我家后院看到了一个飞行中的蜂群,蜂群中没有任何一个蜜蜂发出中心化的指令,但是任何蜜蜂根据自己前方的外界环境刺激,发出的信号可以瞬间传遍整个蜂群中的每个个体,使得蜂群可以像一只灵活的动物一样精准的躲避树木等障碍物。这个飞行的怪物看上去智商还很高呢!这就是点对点网络的精髓之处,网络中的每个个体只需要遵守简单的底层规则,大家连接在一起就可以通过平等的协作涌现极其复杂的行为!”

图片 1.png

蜂群即网络

中本聪说:“简单规则衍生复杂行为,群系统很神奇吧!”

3.交易内存池 #

中本聪说:“既然账本不用频繁同步了,我们可以再优化一下,在记账节点中创建一个交易的内存池。将每次收到的新增交易第一时间放入交易内存池中,而不是写入账本。等内存池中的交易积累了一段时间(例如每隔10分钟),再一次性的写入到账本中。”

Gilfoyle说:“这么做的目的是什么?减少硬盘的频繁写入吗?”

中本聪说:“对,减少频繁写硬盘,因为账本是文件,写文件就是在写硬盘。内存访问速度就要比硬盘访问速度快上10万倍以上。”

这就像什么呢?内存就好似人的短期记忆,比如我们在马路上搭讪了一个美女,问人家要电话号,人家告诉你之后,你先记在脑子里,然后继续和美女聊家常,这样搭讪的节奏才flow。等美女走了,你马上要将刚才脑子里记住的电话号码写在小本子上,以免自己忘了。这就好像交易内存池和账本的关系。

记在脑子里的电话号,方便快捷,不会打断你的搭讪动作连续性,但不稳固,没准一个节点断电重启就丢了。而写在小本子上就很麻烦笨重,但很稳固,节点断电也不会丢。

另外,不光是用户的新增交易,节点间的交易同步也会先写入到交易内存池。

这样,就引出了“交易内存池”这个概念。(见下图)

图片 1.png

加入交易内存池

4.后记 #

虽然加入了交易的同步机制,但是现在的同步机制还是有很多漏洞,需要账本的同步来填补漏洞。

本篇重点讨论了交易的同步,并引出了点对点网络的广播机制和交易内存池等概念,下一篇将要讨论账本的同步。

下一篇:重新创造比特币15:账本的同步

相关链接 #

重新创造比特币:前言

Part One : 交易
重新创造比特币1:从一个简单的web交易系统开始
重新创造比特币2:第一个版本上线啦
重新创造比特币3:舍弃账户模型
重新创造比特币4:数字签名
重新创造比特币5:公钥和私钥
重新创造比特币6:第二个版本上线啦
重新创造比特币7:UTXO
重新创造比特币8:基于UTXO的系统重构
重新创造比特币9:万物皆交易
重新创造比特币10:交易脚本

Part Two : 群系统
重新创造比特币11:群系统(上)
重新创造比特币12:群系统(下)
重新创造比特币13:P2P网络
重新创造比特币14:交易的同步
重新创造比特币15:账本的同步
重新创造比特币16:Block Chain
重新创造比特币17:网络的弹性
重新创造比特币18:工作量证明(上)
重新创造比特币19:工作量证明(下)
重新创造比特币20:分叉之重组与分裂

书面设计矢量图_36.png

英文版Amazon.com在售 : Recreating Bitcoin

BSV打赏:
1Djc4TdVBi8urzmSXKHwg8cpEAYKcRQxgY

©2019 - Recreating.org all rights reserved

 
0
Kudos
 
0
Kudos

Now read this

Recreating Bitcoin

“I’m extremely happy to see people finally trying to understand bitcoin and thinking for themselves. Bitcoin SV is my original bitcoin protocol with a lot of the code bugs fixed. I enjoyed reading the story and I was impressed to see... Continue →