转自:https://www.jianshu.com/p/29db1b94c677
拜占庭将军问题是区块链技术中另一个经常被提到的模型。本篇将尽量用通俗的语言解释拜占庭将军问题的本质以及背后的经典算法,不当之处请指正。
与两军问题一样,拜占庭将军问题也仅仅是提出了问题,并没有提出解决这个问题的方案。
首先,我们需要了解什么是拜占庭将军问题:
在中世纪,拜占庭帝国的几位将军各自带兵共同围困一座城市。这座城市的防守非常坚固,只有他们一起进攻才能攻下来。也就是说,他们要么一起进攻,要么一起撤退,否则都是灾难性后果。但是因为各位将军分处城市不同方向,没法坐在一起讨论,只能通过信使告诉彼此自己投票进攻还是撤退。于是,每位将军都是根据得到的所有别的将军的投票,做出自己进攻还是撤退的决定。
如果所有将军都是忠诚的,当然没有问题,根据大多数将军投票结果就好了。但是问题在于,将军中可能有叛徒。假设9位将军投票,4人投进攻,4人投撤退,剩下1人是叛徒,他选择告诉进攻的4人他投进攻,告诉撤退的4人他投撤退,那么结果就悲惨了。
问题的症结在于:一群忠诚的将军想要实现行动上的一致(一致撤退或者一致进攻),由于叛徒的存在,将军们不知道如何达成共识,取得行动上的一致。
因此,非常有必要找到一种解决方案,以保证即使在有叛徒的情况下,各位忠诚的将军可以在行动上取得一致。如果将军们在有叛徒存在的情况下仍然在行动上达成了一致,我们就称达到了“拜占庭容错”。
以上为拜占庭将军问题的简单描述。拜占庭将军问题的本质则是提出了如何在分布式系统中有节点被故意破坏的情况下达成共识的讨论。
与两军问题不同,在研究拜占庭将军问题的时候,我们不去考虑通信兵是否会被截获或者无法传递信息等问题,即消息传递的信道没有问题。
但是现实中,往往会遇到因网络不畅、节点故意沉默等问题收不到信息的情况,遇到这种情况,系统会默认节点收到了信息,且收到的信息统一是撤退(或者统一是进攻)。
需要强调的是,由于叛徒不受任何规则的约束,所以拜占庭将军问题的目标是实现忠诚的将军们在行动上取得一致,并不是所有的将军在行动上取得一致。
但是,光靠一致就可以解决问题吗?考虑一下,如果万事俱备,客观上每个忠诚的将军只要进攻了就一定能够胜利,但是却因为叛徒的存在他们都一致没有进攻;反之,条件不利,将军们不应该进攻,但是却因为叛徒的存在所有人都一致进攻了。
因此,对忠诚的将军而言,光有一致性还是不够解决问题的,还要提出一个“正确性”要求。
需要注意的是,这里的“正确性”并非指每个忠诚将军给出的答案必须符合一定的正确标准,而是指虽然叛徒进行了干扰,忠诚的将军所收到的问题答案仍然真实地反映了另一位忠诚将军的意图。因此,这个答案所对应的问题必须是值得斟酌的,并不是像1+1是否等于2这样没有任何争议性的问题,而是像结合军情来分析判断是进攻还是撤退这样的问题。对忠诚的将军而言,由于每个人的判断力和所处的环境不同,这类问题的答案有可能完全相同,也可能出现不尽相同的情况。
简单来说,“正确”就是在叛徒的干扰下,每个忠诚的将军所最终接受的另一个忠诚将军的答案都是相同的,并且这个答案与这位忠诚将军的真实意图完全一致。
反过来理解这个问题,我们就会知道,在拜占庭将军问题中,什么样的将军才算是叛徒:只有没有表达自己真实意图的将军才是叛徒。
比如,如果将军C给将军A发送的答案是进攻,给将军B发送的答案却是撤退,那么将军C就没有真实的表达自己的意图,将军C就是叛徒。还有,如果将军C收到的答案是进攻,可他却告诉别人他收到的的答案是撤退,那么将军C也没有表达自己的真实意图,将军C也是叛徒。
还有一种情况,假如将军C综合了各种情况后认为应该进攻,可是他却被敌人收买,做出了撤退的答案,并通知了其他将军他的答案是撤退,并且将其他将军的答案诚实地传递下去,那么,这种情况下将军C是叛徒吗?答案是不是。因为他并没有区分对象传送答案,也没有把其他将军的答案篡改后再传递,所以将军C并不是拜占庭将军问题意义上的叛徒。
至此,我们可以将拜占庭将军问题简化成:所有忠诚的将军都能够让别的将军接收到自己的真实意图,并最终一致行动。
与两军问题不同,在经典情形下,拜占庭将军问题是有解的。1999年,Miguel Castro和BarbaraLiskov提出了实用拜占庭容错算法(PBFT),能够实现只要叛徒少于三分之一,忠诚的将军们就一定能达成一致结果,实现拜占庭容错。
采用PBFT方法,本质上就是利用通信次数换取信用。每个命令的执行都需要节点间两两交互去核验消息,通信代价是非常高的。通常采用PBFT算法,节点间的通信复杂度是节点数的平方级。
在PBFT的基础上,又出现了很多变种算法,这些算法往往都带有一些额外的假设。例如:认为发起请求的客户端一定是忠诚的,由客户端去验证节点是否忠诚;认为绝大部分时候将军都是忠诚的,所以降低两两交互核验消息的次数;通过对节点进行分工,来提高整个系统的处理速度等。
对于不同类型的应用场景,有些假设是合理的,有些假设则是不合理的。例如,在类似比特币的代币转账系统中,不能认为客户端是忠诚的,因为客户端很可能会发起双花交易。
那么,区块链技术是怎样解决拜占庭将军问题的呢?
区块链解决拜占庭将军问题的思路就是,如果要做叛徒,就付出相应的成本,而付出这个成本还不如诚实地维护这个系统利益来得大。以PoW(Proof of Work)工作量共识机制为例,这个成本在PoW机制下,就是要掌握整个网络50%以上的算力——换句话说,有50%以上的叛徒才行,这是比PBFT高得多的容错率。可是,如果真的掌握那么大的算力的话,用这些算力维护网络获得的收益其实会高于破坏网络。当然,PoW机制也有缺陷,比如浪费了大量的算力以及产生这些算力的电、计算设备等。