V神的99%容错共识算法详解

最近V神发了一篇博客,提出了一种能99%容错的共识算法,引发了大家的广泛思考。原文地址:
https://vitalik.ca/general/2018/08/07/99_fault_tolerant.html

众所周知,在同步网络中,容错率可以达到50%(这就是51%攻击的来源)。而在异步网络中,容错率则下降到33%(如PBFT要求拜占庭节点比例小于1/3)。V神提出的这一共识算法容错率竟可以达到99%,究竟是何方神圣?今天小伙伴们在会议上进行了激烈的讨论,最终揭开了这一算法的神秘面纱,撰文以记录之。

实际上,这一算法早在1982年Leslie Lamport的著名论文《拜占庭将军问题》中就已经提出了,而V神的算法只是该算法的一个简化版本。那我们就先来分析一下这个原始算法。

拜占庭将军问题

首先简单说明一下什么是拜占庭将军问题:
拜占庭帝国有10位将军统帅10支部队,每次出现敌情时,由其中一位将军担任统帅(commander)并发出进攻或者撤退的命令,然后由信使将该命令传达给其他将军(lieutenant)。每位将军在收到命令后又会把该命令转发给其他的所有将军,因此在保证消息传递没有问题的情况下,每位将军最终都会收到9个命令。但是,这10个将军中可能有叛徒,因此将军1可以向将军2转发进攻的命令,而向将军3转发撤退的命令。这样,每位将军收到的这9个命令就会有一部分要求进攻,另一部分要求撤退。

下面是重点,解决拜占庭将军问题核心是满足下面两个条件:

IC1:所有的诚实将军都能够按照一致的命令行动(一致性)

IC2:如果统帅是诚实的话,所有诚实将军必须都按照统帅的命令行动(正确性)

所以,拜占庭将军问题并不是要让所有将军都达成一致共识,而只是要让所有诚实将军达成一致共识,即使在统帅自己也是叛徒的情况下。

假设总共有n个将军,在存在m个叛徒的情况下,如果达到上述目标呢?考虑下图中的两种情况:

这里写图片描述

事实上,将军1无法区分这两种情况,因此也无法保证做出正确的决策。
如果再增加一位诚实将军,问题就迎刃而解了,因此n >= 3m+1时才能够解决该问题,即容错率为33%。Lamport通过反证法证明了这一结论。

口头消息(oral message) vs. 签名消息(signed message)

上一节传递的消息其实是一种“口头消息”,因此将军1可以给将军2和将军3发送不同的指示进行作恶。

在现代网络系统系统一般传递的是“签名消息”,即通过非对称加密等形式对消息进行签名,这就使得上面这种作恶方式变得不可能:如果收到了由同一位将军签名的不同指示,那我们立刻就可以知道该将军是叛徒。

这里写图片描述

那么,在使用签名消息的情况下,容错率能否提高呢?答案是肯定的,Lamport提供了一种算法,也就是V神99%容错算法的原型:

这里写图片描述

算法步骤如下:(v表示命令,v:i表示第i个将军对该命令进行签名)

  1. 统帅对命令进行签名,然后把v:0发送给其他所有将军
  2. 对于每一位将军i:
    a) 如果接收到v:0,保存v,加上自己的签名然后把v:0:i发送给其他所有将军
    b) 如果接收到v:0:j1:j2:…:jk,保存v,此外如果k < m的话,加上自己的签名然后把v:0:j1:j2:…:jk:i发送给其他所有将军
    c) 注意:在如果之前已经接收过v,那么后面再收到的和v相关的消息时就不需要执行步骤a和b了(只签名转发一次)
  3. 当将军i不再收到消息时,根据choice函数完成决策
    这里的choice函数是自定义的,目的是从保存的命令集合中选出一个。如果所有诚实将军具有相同的命令集合,那么采用相同的choice函数,就能做出一致的决策。

那么如何保证所有诚实将军具有相同的命令集合呢?答案就是上面的k < m的条件。如果k = m,说明一共收到了m+1个将军的签名(包括统帅),而一共只有m个叛徒,所以至少会包含1个诚实将军的签名。诚实将军一定会向全网广播相同的命令,因此所有的诚实节点就一定能够收到该命令。

还有一个问题是将军怎么知道何时“不再收到消息”?文中提到了两种可能的方案:一种是要求其他将军发送一条消息通知其他人“我不再转发和v相关的消息啦”,还有一种是设定一个超时时间。

V神的99%容错算法

V神在上面的算法基础上增加了两个假设:

  1. 消息传递的网络时延和时钟偏移有一个上限值D(例如8秒)
    也就是说,如果节点在时间T发送了v,在T+D的时刻一定可以保证所有节点都收到了v(其实就是同步系统)。在这种情况下,作恶节点只有一种作恶方式:在T和T+D之间选择一个比较晚的时间点发送v,使得在T+D时刻,有一部分节点可以收到v,而另外一部分节点收不到v,让节点们无法做出一致的决策。
  2. m = N - 1
    也就是说,假设总共有N个节点,其中只有1个是诚实节点,其他都是作恶节点(这就是99%容错的由来)。所有节点必须等待(N-1)* D秒并执行Lamport算法。

V神举了一个例子,我们来具体分析一下:

这里写图片描述

图中灰色的节点0和节点2是诚实节点,红色的节点1是作恶节点。
图中的x, y, z, w是一种通用的表示,你可以把它们理解为区块。
在T时刻,节点0广播y:0消息,节点2广播x:2消息。
在T时刻之后,T+D时刻之前,节点1广播了z:1和w:1这两个消息。使用两个消息其实为了说明了2种情况:节点0收到了w但节点2没有收到w,节点0和节点2都没有收到z。
在T+D时刻,节点0广播x:2:0和w:1:0消息,而节点2则只广播y:0:2消息。
在T+2D时刻,我们会发现,节点0和节点2收到的区块集合都是(x, y, w)。可以看到,只要有一个诚实节点收到了w,就可以保证所有诚实节点都能收到。而所有诚实节点都没有收到z,因此集合中不包含z。此时,只需要使用相同的choice函数(比如选择x, y, w中区块哈希值最小的那个),就可以保证所有诚实节点获得一致的结果。

接下来我们引入一个新的角色:被动观察者(passive observers)。
被动观察者不参与共识,但是关心共识的结果。我们可以把被动观察者理解为钱包节点,或者甚至就是最终用户。被动观察者可以和节点之间发送消息,但是观察者和观察者之间不能通信。
我们的目标是:让所有的被动观察者都和诚实节点保持一致。这样,即使网络中99%的节点都是作恶节点,最终用户只认可那1个诚实节点的结果。

但是,V神发现这个算法存在一个漏洞:

这里写图片描述

Colluding nodes代表作恶节点集群,假设网络中一共有k个作恶节点,那么它们可以选择在临近T+kD时刻让Observer1收到包含k个签名的消息,而在超过T+kD后再发送给Observer2和诚实节点。虽然Observer1也会广播该消息,但是诚实节点收到时也已经超过T+k*D时刻了,因此会拒绝该消息。这样,Observer1和诚实节点看到的结果不一样,Observer1和Observer2看到的结果也不一样,这就无法达成我们之前定的目标了。

关于这个问题,V神提供了一种解决方案:

这里写图片描述

被动观察者接收消息采用不同的超时时间D’,D’ = 2D,即两倍的网络时延和时钟偏移。Observer1只接受在T+(k-0.5)*D’时刻之前发送过来的消息,这样它转发的消息就一定能在T+k*D’时刻之前到达诚实节点,而Observer2则可以在T+(k+0.5)*D时刻之前收到诚实节点发来的消息。这样,它们三个人就可以获得一致的结果了。

和其他的共识算法配合使用

上面的算法看起来很完美,但是同步性假设太强了,时间复杂度也非常高。

V神把目前主流的算法如PBFT、POS等称为“阈值依赖型(threshold-dependent)”共识算法,因为它们要求网络中作恶节点的比例不能超过一个阈值。而V神提出的这个算法是“时延依赖型(latency-dependent)”共识算法,因为它是由超时时间驱动的。

有没有办法把这两种类型的算法融合起来,取长补短呢?V神提出了一种设计:
先使用阈值依赖型共识快速出块,等过了4096秒(约1.13小时)后,以当前区块高度作为一个checkpoint,随机选取512个节点对该checkpoint运行一次时延依赖型共识。如果网络中有5%的诚实节点,那么选出的这512个节点都是作恶节点的概率只有万亿分之一,也就是说,系统可以达到95%左右的容错率。
思考一个问题:为什么是4096秒呢?之前提到D是8秒,因此512个节点一次共识的时间就是(512-1) * 8 = 4088秒。可以看到,运行这个算法是非常耗时的。

这两种算法是相辅相成的,如果某一时刻时延依赖型算法的限制条件(如最大超时D)被打破,而阈值依赖型算法仍然在其容错范围(如33%)内的话,系统仍能正常运行,反之亦然。直到后面某个时间点条件重新被满足,两套算法达成同步状态。

更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
或关注飞久微信公众号:
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值