0.前言
上一篇描述了交易的同步,如果光是交易的同步是不够的,还需要考虑账本的同步
交易内存池代表着系统的当下,账本代表着系统的过去。
1.三个节点
咖啡馆,老板Bob给中本聪抱来了之前答应过的旧主机。中本聪接过老板怀中的主机,一顿表达感谢。
现在桌子上放着3台主机,由于桌子地方不够用了,第三台机器堆在了另外两台的上面,看起来像个金字塔。
中本聪对Gilfoyle说:“之前的2个节点已经可以正常的提供记账服务了,我们现在把第3个节点也接入Bitcoin网络吧。”
Gilfoyle说:“好,不过我感觉八成会出问题,先运行起来再说,反正现在是测试阶段,遇到问题解决问题。”
中本聪给节点3配置好IP,部署了最新的代码,重启运行。节点3很顺利的自动连接上了节点1和节点2(因为临时方案:代码中写死了节点1和节点2的IP),并且开始同步交易了。(见下图)
节点3加入记账网络,开始同步交易
运行了一会,中本聪发现问题了:“我给忘了,账本的同步还是需要的,新加入网络的节点账本是空的”
Gilfoyle说:“那就改一下代码,每次程序启动,向自己订阅的节点申请账本的同步。”
这个逻辑很简单,中本聪马上改好代码,重新部署了,启动。(见下图)
账本的同步,但是内存池缺失交易
这次节点3完成了账本的同步。
但是观察了一会,中本聪又发现了另一个问题:“我发现节点3的交易记录一直缺失2条交易记录”
原来问题出在这里,节点3加入记账网络的时候,节点1和节点2已经提前在内存中同步好了2条记录:“Alice to Bob 50” 和 “Carol to Alice 30″。而这2条记录还没来得及写入到账本,所以即便节点3得到最新账本,也不会包含这两条交易记录。
而继续运行,节点3只会同步之后发生的交易,即:“Bob to Alice 5”。
所以,节点3就会一直缺失那两条记录。
这就好像,一个中学的课堂上,老师在上面讲课,学生在下面记笔记。这时候一个叫老三的学生迟到了,慌慌张张的坐下来之后,不知道老师刚才讲了啥,赶紧管同桌老大借笔记来抄。但是问题来了,老师讲了3道题,老大的笔记只记了1道题,剩下的2道题还在脑子里呢,还没来得及写下来。老三不管那么多,先抄下来再说。与此同时,老师开始讲最新的第4题了,老三也只能从第4题开始继续听。这样,老三一直也不知道第2和第3题讲了啥。但是关键点是,老三还不确定自己少听了几道题。甚至还侥幸的希望自己没有少听。
现实中的解决方法很简单,我们让老三等一会,等老大把自己脑子里的题都写在笔记上,再管老大借一次笔记,再抄一次就解决啦。
虽然现实中看上去合理的方案,在记账网络这个场景中却不够严谨。
因为,节点3对自己的账本不够自信,所以想找节点1进行第二次的账本同步。
但是,节点1如何能保证自己的账本是完美的呢?节点1也许中间网络断过几秒钟,而错过了几笔交易,也说不定啊。关键如果网络闪断,节点1自己是无法察觉的。
节点1即无法证明自己的账本是完整的,也不应该让一个系统这么依赖某些节点必须是完美的。那样的话这个系统就太脆弱了。
节点1被我们说的都开始变得不自信了,节点1嘟囔着:“我咋办,节点3是新来的,我又不知道自己是否完美。要不我找节点2来同步一下账本吧,总不能大家都缺交易吧。啊!不行,节点2和我一样,它也无法证明自己是完美的,所有网络中的节点都可能不完美,这可咋办?”
2.记账权的轮换
如果是传统的精确系统,可以容忍次要部分的不完美,但是核心单点必须是完美的,因为精确系统的正确性本质上就是在依赖某个中心。
但是群系统反而不怕个体的不完美,大家都不完美,但是共同协作反而可以达到完美。
中本聪说:“既然每个节点对自己的账本都不自信,那么就不要各自为政,而是大家轮着记账。
10分钟一个周期,10分钟一到,记账权随机分配给一个节点。
这个节点就把自己内存池中的交易记录在账本中,然后将账本广播给大家。
其它节点收到账本就选择信任,将这个账本覆盖自己原来的账本。
同时,还要对比新账本和自己内存池中的交易记录。将重复的记录删除,这样内存中就会只剩下自己独有而别人缺失的交易。
等记账权轮到自己的时候,就可以将这些别人缺失的记录写到账本中,让其它节点同步过去。
这样轮着来,就等于是大家共同在补充缺失。
如果每个个体都不完美,大家加在一起可以凑出一份完美的账本,就OK啦!
这就是群体的力量,这就是去中心化的神奇:容错能力极高!”(见下图)
记账权的轮换
Gilfoyle问:“如何实现记账权的随机分配呢?总不能引入一个单点来做这个分配的工作吧,那样违背了群系统的没有单点的特质了!”
3.Timestamp Server
中本聪说:“这真是个难题,一不小心就会陷入传统精确系统的思维模式陷阱。在想到办法前,为了让系统可以正常运行,我们倒是可以加入一个单点来做记账权分配,当然这也是个临时方案。等后面我们想出好办法,再将这个临时方案替换掉。”
简单的做法是,再部署一个独立的单点服务,这个单点要干的事情就是:每隔10分钟,随机的选择一个节点,通过消息,通知这个节点进行记账,节点记账之后会将账本广播到记账网络。
由于这个单点起到了类似时钟的作用,即每10分钟嘀嗒一下(分配一次记账权),所以我们给它起名字为:时间戳服务器,英文Timestamp Server。(见下图)
新增一个临时的单点来分配记账权
Timestamp Server的代码逻辑很简单,中本聪很快就写好了程序,但是现在没有多余的服务器。
中本聪又打起了老板Bob的注意:”老板,我们有个临时方案,还需要一个服务器,我看到咖啡店柜台上有一台机器,平时也不咋用,让我部署一个小程序呗,不会影响你正常使用的。”
Bob说:“好吧,不影响我用它算账就行。”
就这样,中本聪将临时的程序部署在了那台机器上,在程序里同样写死了记账网络中的3个节点IP。
单点启动后,自动连接上了3个记账节点,每十分钟就会随机通知一个节点,进行记账。
中本聪观察了一会,节点3之前缺失的那2条交易记录的确补充回来了。
这样,记账网络可以正常运行了,并且同时具备了交易的同步和账本的同步机制。
4.账本的拆解
Gilfoyle说:“我忽然想到了另一个可改进的点,就是账本的拆解。如果账本要在整个网络中频繁广播,那就应该将账本拆解成一页一页的,每十分产生一页新增账本,每次只在全网同步最新的那页,这样就不会浪费网络资源。”
中本聪说:“这个思路很好,账本每次都全量同步的确太笨重了。今天先到这里,明天我们再继续讨论。”
Gilfoyle说:“好,明天继续,记得思考记账权轮换的最终解决方案。现在这个单点的临时方案太丑陋了!”
5.后记
本篇完,本篇引出了两个重大问题,一个是账本的拆解,另一个是记账权的轮换。
账本的拆解,将要引出的技术概念,即,区块链(Block Chain)。
记账权的轮换,将要引出的技术概念,即,工作量证明(Proof of Work)。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。