• 注册
    • 查看作者
    • 《重新创造比特币》第14章:交易的同步

      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,都不正确。(见下图)

      《重新创造比特币》第14章:交易的同步

      账本不一致

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

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

      在上面这个场景中,

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

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

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

      《重新创造比特币》第14章:交易的同步

      账本的同步

      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。”(见下图)

      《重新创造比特币》第14章:交易的同步

      节点3只订阅了节点2

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

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

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

      《重新创造比特币》第14章:交易的同步

      蜂群即网络

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

      3.交易内存池

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

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

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

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

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

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

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

      《重新创造比特币》第14章:交易的同步

      加入交易内存池

      4.后记

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

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

    • 0
    • 0
    • 0
    • 110
    • 请登录之后再进行评论

      登录
    • 单栏布局 侧栏位置: