拜占庭将军问题
拜占庭容错技术来源于拜占庭将军问题。拜占庭将军问题是Leslie Lamport在20世纪
80年代提出的一个假象问题 。拜占庭是东罗马帝国的首都,由于当时拜占庭罗马帝国
国土辽阔,每支军队的驻地分隔很远,将军们只能靠信使传递消息。发生战争时,将军们
必须制订统一的行动计划。然而,这些将军中有叛徒,叛徒希望通过影响统一行动计划的
制定与传播,破坏忠诚的将军们一致的行动计划。因此,将军们必须有一个预定的方法协
议,使所有忠诚的将军能够达成一致,而且少数几个叛徒不能使忠诚的将军做出错误的计
划。也就是说,拜占庭将军问题的实质就是要寻找一个方法,使得将军们能在一个有叛徒
的非信任环境中建立对战斗计划的共识。在分布式系统中,特别是在区块链网络环境中,
也和拜占庭将军的环境类似,有运行正常的服务器(类似忠诚的拜占庭将军),有故障的
服务器,还有破坏者的服务器(类似叛变的拜占庭将军)。共识算法的核心是在正常的节
点间形成对网络状态的共识。
求解拜占庭将军问题,隐含要满足以下两个条件:
1)每个忠诚的将军必须收到相同的命令值vi(vi是第i个将军的命令)。
2)如果第i个将军是忠诚的,那么他发送的命令和每个忠诚将军收到的vi相同。
于是,拜占庭将军问题的可以描述为:一个发送命令的将军要发送一个命令给其余n-
1个将军,使得:
IC1.所有忠诚的接收命令的将军遵守相同的命令;
IC2.如果发送命令的将军是忠诚的,那么所有忠诚的接收命令的将军遵守所接收的命
令。
Lamport对拜占庭将军问题的研究表明 ,当n>3m时,即叛徒的个数m小于将军总数
n的1/3时,通过口头同步通信(假设通信是可靠的),可以构造同时满足IC1和IC2的解决
方案,即将军们可以达成一致的命令。但如果通信是可认证、防篡改伪造的(如采用PKI
认证,消息签名等),则在任意多的叛徒(至少得有两个忠诚将军)的情况下都可以找到
解决方案。
而在异步通信情况下,情况就没有这么乐观。Fischer-Lynch-Paterson定理证明了,只
要有一个叛徒存在,拜占庭将军问题就无解。翻译成分布式计算语言,在一个多进程
异步系统中,只要有一个进程不可靠,那么就不存在一个协议,此协议能保证有限时间内
使所有进程达成一致。
由此可见,拜占庭将军问题在一个分布式系统中,是一个非常有挑战性的问题。因为
分布式系统不能依靠同步通信,否则性能和效率将非常低。因此寻找一种实用的解决拜占
庭将军问题的算法一直是分布式计算领域中的一个重要问题。
在这里,我们先给出分布式计算中有关拜占庭缺陷和故障的两个定义:
定义1: 拜占庭缺陷(Byzantine Fault):
任何观察者从不同角度看,表现出不同症状的缺陷。
定义2: 拜占庭故障(Byzantine Failure):
在需要共识的系统中由于拜占庭缺陷导致丧失系统服务。
在分布式系统中,不是所有的缺陷或故障都能称作拜占庭缺陷或故障。像死机、丢消
息等缺陷或故障不能算为拜占庭缺陷或故障。拜占庭缺陷或故障是最严重缺陷或故障,拜
占庭缺陷有不可预测、任意性的缺陷,例如遭黑客破坏,中木马的服务器就是一个拜占庭
服务器。
在一个有拜占庭缺陷存在的分布式系统中,所有的进程都有一个初始值。在这种情况
下,共识问题(Consensus Problem),就是要寻找一个算法和协议,使得该协议满足以下
三个属性。
1)一致性(Agreement):所有的非缺陷进程都必须同意同一个值。
2)正确性(Validity):如果所有的非缺陷的进程有相同的初始值,那么所有非缺陷
的进程所同意的值必须是同一个初始值。
3)可结束性(Termination):每个非缺陷的进程必须最终确定一个值。
根据Fischer-Lynch-Paterson的理论,在异步通信的分布式系统中,只要有一个拜占庭
缺陷的进程,就不可能找到一个共识算法,可同时满足上述要求的一致性、正确性和可结
束性要求。在实际情况下,根据不同的假设条件,有很多不同的共识算法被设计出来。这
些算法各有优势和局限。算法的假设条件有以下几种情况:
1)故障模型:非拜占庭故障/拜占庭故障。
2)通信类型:同步/异步。
3)通信网络连接:节点间直连数。
4)信息发送者身份:实名/匿名。
5)通信通道稳定性:通道可靠/不可靠。
6)消息认证性:认证消息/非认证消息。
在区块链网络中,由于应用场景的不同,所设计的目标各异,不同的区块链系统采用
了不同的共识算法。一般来说,在私有链和联盟链情况下,对一致性、正确性有很强的要
求。一般来说要采用强一致性的共识算法。而在公有链情况下,对一致性和正确性通常没
法做到百分之百,通常采用最终一致性(Eventual Consistency)的共识算法。
拜占庭容错系统
上面的分析表明,区块链网络的记账共识和拜占庭将军问题是相似的。参与共识记
账的每一个记账节点相当于将军,节点之间的消息传递相当于信使,某些节点可能由于各
种原因而产生错误的信息并传达给其他节点。通常,这些发生故障节点被称为拜占庭节点
,而正常的节点即为非拜占庭节点 。
拜占庭容错系统是一个拥有n台节点的系统,整个系统对于每一个请求,满足以下条
件:
1)所有非拜占庭节点使用相同的输入信息,产生同样的结果;
2)如果输入的信息正确,那么所有非拜占庭节点必须接收这个信息,并计算相应的
结果。
与此同时,在拜占庭系统的实际运行过程中,还需要假设整个系统中拜占庭节点不超
过m台,并且每个请求还需要满足两个指标。
·安全性:任何已经完成的请求都不会被更改,它可以在以后请求看到;
·活性:可以接受并且执行非拜占庭客户端的请求,不会被任何因素影响而导致非拜
占庭客户端的请求不能执行。
拜占庭系统普遍采用的假设条件包括:
1)拜占庭节点的行为可以是任意的,拜占庭节点之间可以共谋;
2)节点之间的错误是不相关的;
3)节点之间通过异步网络连接,网络中的消息可能丢失、乱序并延时到达,但大部
分协议假设消息在有限的时间里能传达到目的地;
4)服务器之间传递的信息,第三方可以嗅探到,但是不能篡改、伪造信息的内容和
验证信息的完整性。
实用的拜占庭容错系统
原始的拜占庭容错系统 由于需要展示其理论上的可行性而缺乏实用性。另外,还
需要额外的时钟同步机制支持,算法的复杂度也是随节点增加而指数级增加。实用拜占庭
容错系统(Practical Byzantine Fault Tolerance,PBFT) ,降低了拜占庭协议的运行复杂
度,从指数级别降低到多项式级别(Polynomial),使拜占庭协议在分布式系统中应用成
为可能。
PBFT是一类状态机拜占庭系统 ,要求共同维护一个状态,所有节点采取的行动一
致。为此,需要运行三类基本协议,包括一致性协议、检查点协议和视图更换协议。我们
主要关注支持系统日常运行的一致性协议。
一致性协议要求来自客户端的请求在每个服务节点上都按照一个确定的顺序执行。这
个协议把服务器节点分为两类:主节点和从节点,其中主节点仅一个。在协议中,主节点
负责将客户端的请求排序;从节点按照主节点提供的顺序执行请求。每个服务器节点在同
样的配置信息下工作,该配置信息被称为视图,主节点更换,视图也随之变化。
一致性协议至少包含若干个阶段:请求(request)、序号分配(pre-prepare)和响应
(reply)。根据协议设计的不同,可能包含相互交互(prepare),序号确认(commit)
等阶段。
PBFT的一致性协议如图5-1所示。PBFT系统通常假设故障节点数为m个,而整个服务
节点数为3m+1个。每一个客户端的请求需要经过5个阶段,通过采用两次两两交互的方式
在服务器达成一致之后再执行客户端的请求。由于客户端不能从服务器端获得任何服务器
运行状态的信息,PBFT中主节点是否发生错误只能由服务器监测。如果服务器在一段时
间内都不能完成客户端的请求,则会触发视图更换协议。
图5-1 PBFT协议通信模式
图5-1显示了一个简化的PBFT的协议通信模式,其中C为客户端,N 0 ~N 3 表示服务节
点,特别的,N 0 为主节点,N 3 为故障节点。整个协议的基本过程如下。
1)客户端发送请求,激活主节点的服务操作。
2)当主节点接收请求后,启动三阶段的协议以向各从节点广播请求。
[2.1]序号分配阶段,主节点给请求赋值一个序列号n,广播序号分配消息和客户端
的请求消息m,并将构造PRE-PREPARE消息给各从节点;
[2.2]交互阶段,从节点接收PRE-PREPARE消息,向其他服务节点广播PREPARE
消息;
[2.3]序号确认阶段,各节点对视图内的请求和次序进行验证后,广播COMMIT消
息,执行收到的客户端的请求并给客户端以响应。
3)客户端等待来自不同节点的响应,若有m+1个响应相同,则该响应即为运算的结
果。
PBFT在很多场景都有应用,在区块链场景中,一般适合于对强一致性有要求的私有
链和联盟链场景。例如,在IBM主导的区块链超级账本项目中,PBFT是一个可选的共识
协议。
除了PBFT之外,超级账本项目还引入了基于PBFT的自用共识协议,它的目的是希望
在PBFT基础之上能够对节点的输出也做好共识,这是因为,超级账本项目的一个重要功
能是提供区块链之上的智能合约,即在区块链上执行的一段代码,因此它会导致区块链账
本上最终状态的不确定,为此这个自有共识协议会在PBFT实现的基础之上,引入代码执
行结果签名进行验证。