0.前言
最近一直在研究区块链中的核心技术组件:共识算法。
作为一个非CS专业出身的人,理解共识算法我更多的强调逻辑的正确而非数学公式及代码实现。那么考虑问题的思路如下:
三连问:
为什么需要共识?—-如何共识?——达成共识的效果如何?
这三个问题对应到区块链中是这样的:
一个区块链面临着怎样的信任环境?
在该信任环境下应该采用何种共识算法?
该共识算法下区块链的性能及其他特性如何?(TPS,资源消耗,安全隐私等)
本文我们主要关注为什么需要共识—-由此衍生出需要着重讨论的两军问题和拜占庭将军问题,并讨论两军问题和拜占庭将军问题的共识策略和效果。而关于区块链当中不同共识算法的使用,我会再下一篇中进行描述。
为什么需要共识?从社会学的角度上来说这似乎是一个无需回答的问题:群体总是需要合作协力,而共识是合作协力的前提。上句是一个非常宏观的共识理由,但如果以通信的视角来看我们则会发现更加具体的理由。
1.信道不可靠情况下能否共识—-两军问题
“马上相逢无纸笔,凭君传语报平安。”—-岑参《逢入京使》
上句是一个典型的通信场景:主角需要通过中间人向家人传递自己平安的消息。诚然,托熟人带个信这个行为从古至今都是合理的,但其合理性建立在一个暗含的前提上———这个熟人是可靠的。
当传递信息的人或者信道本身有问题时,下面的两军问题就发生了:
如下图所示,一支实力强大的白军驻扎在山谷中,两支单兵实力较弱的蓝军驻扎在山谷两侧。两支蓝军合力进攻可以击破白军,但在这之间他们必须就进攻时间达成一致:比如午夜偷袭或者正午猛攻。
一个限制性条件是,两支蓝军无法通过远程喊话的方式来协商进攻时间,他们必须穿过山谷派出通信兵去传信,此时就存在着通信兵可能被白军俘获的问题——即传令信道是不可靠的。那么在信道不可靠的前提下,两军之间有办法就攻击时间问题达成一致吗?且看以下推演:
a.假设左侧蓝军提议午夜0点进行攻击,他派出通信兵将该信息传递给右侧蓝军。
b.左侧蓝军考虑到信使被截获的危险,所以他必须收到右侧蓝军的回信“收到了你的0点进攻指令”
c.右侧蓝军即使真的收到了左侧蓝军的指令并予以回信,但他仍会犹豫是否0点进攻。因为有白军截获可能,右侧蓝军无法确认左侧蓝军是不是听到了“我同意你0点进攻的提议”。于是右侧蓝军还需左侧蓝军再回信,回信内容为“我知道了你确认了我的提议”
d.左侧蓝军继续对C中的内容进行回复,”我知道了你确认了我0点进攻的提议“,但考虑到信使被截获的危险,他也不敢100%的到点进攻,因此他又需要右侧蓝军对这一轮回信再进行答复。
e.以上步骤会形成死循环:无论通信进行多少轮,两侧蓝军都需要等待对方的下一轮回复,这个通信系统中永远都需要下一个回执。
经过以上推演可知,在信道不可靠的情况下,不存在一个通信的方法使得两侧蓝军达到共识。更进一步的考虑,当这个通信兵被截获且传令内容被白军修改时,情况将会变得更加复杂。因此一般看来,两军问题是没有一个完美的解决方案的。
2.信道可靠情况下能否共识—拜占庭将军问题
“千人同心,则得千人之力;万人异心,则无一人之用” —《淮南子.兵略训》
那么当信道可靠的情况下,能够做到千人同心达成共识吗?或者如果不能做到千人同心,能够做到多少异心者的情况下达成共识?这实际上就涉及到了另外一个叫做拜占庭将军的问题:
古代拜占庭帝国兵多将广,他们决议合力围攻一个城市。但帝国的将军们分散在这个城市的周围,单兵作战必败无疑,只有军队数量超过一定规模之后才有成功进攻的可能。同样,他们只能通过信使传令的方式做出一致性的军事决策:打还是不打?几点打?这个例子跟之前的两军问题在某种程度上是类似的,即多个军队通过信使传令的方式做出一个决定。但拜占庭将军问题的不同之处在于:
a.该问题中假设信道是可靠的,信使能够正确的传递将军们的指令,不存在截获和干扰的可能。
b.将军并不都一定是诚实正直的,他们当中不是所有人都有意愿想要进攻,其中可能存在反叛的将军故意破坏整个军事行动的一致性,即反叛将军可能传递错误的指令,干扰其他诚实将军。
c.所有的将军都知道有反叛将军的存在。
在以上条件下,这些将军们有可能对一次军事行动达成共识吗?即是否存在一个通信协议,使得当N个将军中存在f个叛徒时,仍能采取一致的策略(此一致性可意味着都打,或都不打)。且看以下推演:
2.1当将军总数为3,叛徒数量为1时:(3个将军2个叛徒情况下肯定无法达成一致了)
a.假设A将军诚实且为司令,他首先向BC两位将军发送我下午1点进攻的指令。
b.假设B将军叛徒,他在收到A的命令之后,向C将军发送“A告诉我下午2点进攻”的消息
c.假设C将军诚实,他在收到A的命令之后,向B将军发送“A告诉我下午1点进攻”的消息
那么在上述通信之后,情况如下:
A1点进攻,B不进攻,C收到1点进攻和2点进攻2条信息,并且无法判断以哪一条为准。最好的情况是,A和C同时1点进攻,最差的情况是A1点去,B不去,C2点去,时间段内单兵作战行动失败。
由此可见,3个节点一个叛徒的情况下,拜占庭将军问题中还是不存在一个必定达成一致性的共识协议。
2.2接下来考虑4个节点1个叛徒的情况:
a.假设A为司令且诚实,他向BCD三位将军发送1点进攻的指令
b.假设B将军叛徒,他向CD将军分别发送“A让我2点进攻”的消息;
c.假设C将军诚实,他向BD将军分别发送“A让我1点进攻”的消息
d.假设D将军诚实,他向BC将军分别发送“A让我1点进攻”的消息
那么在上述通信之后,情况如下:
A因为诚实选择1点进攻,B收到的三个消息分别是(1点,1点,1点),C收到的三个消息分别是(1点,2点,1点),D收到的三个消息分别是(1点,2点,1点)B为叛徒不选择进攻,但对于C和D来说,他们收到的三个消息里有2个都是1点进攻,因此他们只需要按照多数命令行事即可,最后结果是ACD发起进攻,保证了此次军事行动的一致性。
2.3同样还是4个节点1个叛徒,但此时叛徒为司令A:
a.假设A叛徒,分别告诉BCD“下午1点进攻“,”下午2点进攻“,”下午三点进攻“
b.假设B诚实,告诉CD“A让我1点进攻”
c.假设C诚实,告诉BD“A让我2点进攻”
d.假设D诚实,告诉BC“A让我3点进攻”
那么在上述通信之后,情况如下:
A是叛徒不进攻,B收到三个消息(1点,2点,3点),C和D也同样收到(1点,2点,3点),BCD很容易判断出来是将军A故意扰乱行动,因此BCD三者自然选择不进攻,本次军事行动仍达成了一致
2.4 4个节点,2个叛徒的情况:
这种情况下的推演不再赘述,A为诚实司令,BC为叛徒,D为诚实将军时,D最后收到的3个信息必将各异(有兴趣可以自己推演下),D无法判断几点攻打,那么最好的情况就是AD一起攻打,但寡不敌众;最差的情况就是A和D各自在不同的时间打,军事行动无法达成一致。这种情况下军事行动无法100%保证一致。
2.5拜占庭将军问题有解的条件
拜占庭将军问题的实质就是在信道可靠的情况下,容忍恶意节点存在并使诚实节点达成一致。
通过上面的一些推到可以看出,要使拜占庭将军问题有解,节点总数量至少为4个,且通过节点之间互相通信告知收到的消息来进行一致性判断,当节点数上升到一定量级时,可想而知通信的效率将显著降低,通信复杂度和成本将显著提高。
此外,目前大量的研究也表明,在N(总数)≥3F(恶意节点数)+1时,拜占庭将军问题有解,各节点之间能够达成共识
3.总结
“前人之述备矣” —-《岳阳楼记》
对于区块链而言,共识是基石,基石之上才有了价值的可信转移。
而关于共识的两军问题和拜占庭将军问题之前已经有大量成熟的实证研究,早在区块链之前就已经存在,且已经运用到解决分布式系统中各节点对指令执行的一致性和共识当中。区块链在本质上也是一个分布式系统,尤其为了应对拜占庭将军问题,区块链1.0时期的比特币就提出了工作量证明算法来加以解决,后续又有POS,DPOS等变种。此外,针对分布式系统的一致性和共识问题的算法还有Paxos,Raft,PBFT等,之后有时间我将逐一进行分析和研究。
参考材料:区块链研习 | 看懂“拜占庭容错”,也就看懂了区块链的核心技术