拜占庭是历史上一个赫赫有名的帝国,也就是东罗马帝国,它的首是君士坦丁堡。1453年君士坦丁堡沦陷之后,这个帝国就灭亡了。
拜占庭将军问题并不是历史上真实存在的,而是一个虚拟的问题,它是在1982年由著名的计算机大神、图灵奖获得者兰波特提出的。
拜占庭将军问题可以这样描述:拜占庭帝国想进攻一个城堡,城堡非常坚固,足以抵制一两支军队的进攻,但如果所有军队同时进攻,城堡就可以沦陷。于是拜占庭帝国派出了很多支军队,但是因为通讯落后,这些军队之间只能通过信使来相互交流情报。于是他们就要商量一个方法,怎样才能让很多支军队在同一个时间进攻?
他们想到这么一个办法:咱们投票,比如我们说明天早上进攻,如果同意明天早上进攻的超过半数,那明天早上所有人都要进攻;如果不同意明天早上进攻的人超过半数,那么明天早上所有人都不要进攻。如此一来就保持了一致性。但是问题是,有可能在军队中出现叛徒,这个叛徒他会胡说八道。
比如说,在一次投票的时候,三支军队的将军都说我们应该进攻了,而另外三支部队的将军都说我们要撤退了,那么这个时候叛徒的意见就很重要,因为前面已经是3:3了。而这个叛徒他会告诉要进攻的三个将军,说我同意进攻;同时告诉三个要撤退的将军,说我们应该撤退。这样一来,这场战争只有一部分人进攻,一部分撤退,于是战斗就会失败。
这个就称之为拜占庭将军问题。
兰波特讲这个故事到底想说明什么呢?他实际上想说,计算机它可以分布在世界各地,我们称之为分布式节点,这些分布式节点可能会出现故障,比如宕机,也可能出现恶意节点,比如黑客,在这种情况下我们如何才能保持一致性,即保持这些忠诚的计算机输出的结果都一样,以及如何保持正确性,即如果大多数将军都认为应该进攻,那就要进攻,大多数将军都说要撤退,那就撤退。
尽管在这个分布式节点中有故障和恶意节点,但是还是有办法保证大部分忠诚的计算机是一致,而且是正确的。这个事儿就称之为拜占庭将军问题。
这个问题发展了将近40年,现在已经有很多种解决办法。比如在1982年兰波特提出这个问题的时候,他自己就给出了2种解决方法,我们称之为口头协议和书面协议。今天我们就给大家介绍一下其中的口头协议。
首先我们把这个拜占庭将军问题简化一下,简化为一个将军和副官模型,其实谁是将军都没有关系,所谓将军就是第一个提出进攻或撤退建议的人,其他的人就称之为副官,副官可以执行将军的命令,也可以不执行。
那怎么解决拜占庭将军问题呢?当时兰波特提出,假设m表示恶意节点(叛徒)的数量,n表示总节点数(总人数),那么当n>3m的时候,这个问题是可解的。比如有10个将军,其中有2个是叛徒,那么这个问题可解;如果一共只有3个人,其中有1个是叛徒,那因为没有满足n>3m,就解不了。
例1:假如m=1,n=4,一共有4个军队,其中1个是发号施令的Commander(简称C),另外3个是副官分别简称1号、2号、3号,其中有一个副官是叛徒,比如说3号副官是叛徒。
这样一来,如果将军发的命令是进攻,他告诉1号、2号、3号的命令都是进攻。然后3个副官之间互通信息,1号问2号“你接到的命令是什么”,2号会说“我接到的命令是进攻”,反过来,1号也会告诉2号“我接到的命令也是进攻”,因为他们是忠诚的。同时,1号、2号都会告诉3号“我接到的命令是进攻”,但是注意3号是叛徒,所以他就会胡说八道,说“我接到的是撤退”。
这种情况下,1号获得的信息是2个进攻、1个撤退,他只需要取这3个命令中最多的那个就可以了,也就是进攻。同样,2号获得的信息也是2个进攻、1个撤退,他只需要取这3个命令中最多的那个就可以了,也是进攻。
这样一来,就满足了1和2都进攻,并且忠实地执行了这个C的这个命令,即它达到了兰波特一开始设想的两个要求:一致性和正确性。
例2:假设将军B是叛徒,而3个副官都是忠诚的。那么他会跟前两个副官说要进攻,跟第3个副官说要撤退。然后3个副官会互通信息,1号会告诉2号、3号说“我接到的命令是进攻”,2号也会告诉1号、3号“我接到的命令是进攻”,3号会告诉1号、2号说“我接到的命令是撤退”。这样一来,1号、2号、3号副官得到的信息都是2个进攻、1个撤退,那么他3个都会选择进攻,这就就达到了一致性和正确性。
以上举的都是比较简单的例子,即只有1个叛徒的情况,如果叛徒有2个,那么按照n>3m的公式,至少得有7个人,否则就无解。
例3:假设m=2,n=7,有1个将军C,6个副官,其中2个副官是叛徒,假设5号、6号是叛徒,这时候我们就需要用到一种递归思想。
首先,将军C给6个副官发出进攻命令,这个时候1号副官不会立刻执行将军的命令,因为他不知道将军是不是叛徒,于是他就问2号“你接到的将军的命令是什么”,2号会告诉1号“是进攻”,但1号也不会马上相信2号的话,因为他也不知道2号是不是叛徒,于是他会接着去问3、4、5、6,他问“2告诉你他收到将军的命令是什么”,这话特别绕,就是嵌套(递归思想);同样,2、3、4、5、6号也这样问别人,他们得到的回答如下表格表示:
V1=进攻 | V2 | V3 | V4 | V5 | V6 |
V2=进攻 | 进攻 | 进攻 | 进攻 | … | … |
V3=进攻 | 进攻 | 进攻 | 进攻 | … | … |
V4=进攻 | 进攻 | 进攻 | 进攻 | … | … |
V5=…(胡说八道) | … | … | … | … | … |
V6=… | … | … | … | … | … |
最终我们在这个向量里边取最大的,有4个人说进攻,有2个人胡说八道,但最终的结果肯定是进攻的人数多,于是1、2、3、4号副官加上将军C都会进攻,这样一来,他们保持了一致性(他们同时选择进攻),也保证了准确性(7个人中5个人进攻,符合大多数人的意见)。
以上就是口头协议的解决方法,但当时兰波特提出这个方案的时候没有考虑到网络延迟问题,但在实际的情况下互联网是有网络延迟的,所以这个算法是不能用的。
到了1999年,有几个人提出了一种更加简洁实用的拜占庭容错算法(PBFT),这种算法在存在网络延迟的情况下,依然可以保证少数恶意节点和故障节点存在时,大部分忠诚节点的一致性和准确性。
后来还有更多的人提出拜占庭将军问题解决方案,比如中本聪发明了比特币和区块链,区块链的核心问题也是要保持一致性,中本聪提出的解决方案是算力证明(PoW),你要记账就得算一道数学题,如此就增加了叛徒的成本。
文章内容仅供参考,不构成投资建议,投资者据此操作风险自负。转载请注明出处:天府财经网