作者:段玉龙2018201112 、朱江2018201116、卢薪丞2017201116
拜占庭将军问题是由Leslie Lanport提出的分布式对等网络通信融资问题,那么它具体是什么呢,我们来打个比方,如果你是一支拜占庭军队的将军,并且准备攻击一座敌方城市,在城市周围有几支有其他将军领导的军队,如果大家一起合作进攻,那么一定会大获全胜。但是如果大家各顾各,零散攻击,那么会导致进攻失败。这个时候作为将军的你,决定在傍晚攻击。在那个时期你并没有办法通过电话商量,也没有办法发送可能被敌方看到的信号弹,来联系所有的将军,让大家达成共识一起发动傍晚的攻击。所以您只能通过传令兵来传递信息。那么问题来了,如果传令兵在路途中被杀害怎么办,被敌方逮捕换成假信息怎么办,再者其他将军又如何判定你的传令兵递送的消息就是你的消息呢?更要命的是如果其中有叛军故意发送同意攻击的信息,但是实际进攻中不出兵又怎么办,这样各支军队的一致协同就遭到了破坏,所以你该怎么确保所有的军队会达成共识,并且同时出击呢?这个就是困扰了近千年的拜占庭将军问题,他问题的核心就是:单独个体如何可以不带任何条件地相信彼此。
由此引出拜占庭容错算法。
拜占庭容错技术被设计用来处理异常行为(包括硬件错误、网络拥塞、以及恶意攻击),被设计用来处理这些异常行为。发生故障的节点是拜占庭节点,正常的节点为非拜占庭节点。
但是拜占庭容错算法(BFT)在实用中有很多不便之处, 早期提出的能解决拜占庭问题的算法(包括随拜占庭问题论文提出来的两种原生算法),要么仅仅停留在展示算法的理论可能性阶段,而实用性不高,要么就假设算法的使用环境为同步系统,而真实生产中的信息系统往往是异步的,例如互联网。由此衍生出了实用拜占庭容错算法(PBFT),它也是庭容错算法(BFT)下的一个分支。下面会详细讲解实用拜占庭容错算法(PBFT)。
PBFT算法前提,采用密码学算法保证节点之间的消息传送是不可篡改的。
PBFT容忍无效或者恶意节点数:f,为了保障整个系统可以正常运转,需要有2f+1个正常节点,系统的总节点数为:|R| = 3f + 1。也就是说,PBFT算法可以容忍小于1/3个无效或者恶意节点。
PBFT是一种状态机副本复制算法,所有的副本在一个视图(view)轮换的过程中操作,主节点通过视图编号以及节点数集合来确定,即:主节点 p = v mod |R|。v:视图编号,|R|节点个数,p:主节点编号。
PBFT算法每个客户端请求需要经过5个阶段,主要是①request——请求②pre-Prepare——序号分配③Prepare——交互④commit——序号确认⑤reply——响应
以下详细说明一下这五个阶段流程:
客户端c向主节点p发送
主节点收到客户端的请求,需要进行校验客户端请求消息签名是否正确。校验的步骤如下
非法请求丢弃。正确请求,分配一个编号n,编号n主要用于对客户端的请求进行排序。然后广播一条<
副本节点i收到主节点的Pre-Prepare消息,需要进行以下校验:
a. 主节点Pre-Prepare消息签名是否正确。
b. 当前副本节点是否已经收到了一条在同一v下并且编号也是n,但是签名不同的Pre-Prepare信息。
c. d与m的摘要是否一致。
d. n是否在区间[h, H]内。
非法请求丢弃。正确请求,副本节点i向其他节点包括主节点发送一条
主节点和副本节点收到Prepare消息,需要进行以下校验:
a. 副本节点Prepare消息签名是否正确。
b. 当前副本节点是否已经收到了同一视图v下的n。
c. n是否在区间[h, H]内。
d. d是否和当前已收到Pre-Prepare中的d相同
非法请求丢弃。如果副本节点i收到了2f+1个验证通过的Prepare消息,则向其他节点包括主节点发送一条
主节点和副本节点收到Commit消息,需要进行以下校验:
a. 副本节点Commit消息签名是否正确。
b. 当前副本节点是否已经收到了同一视图v下的n。
c. d与m的摘要是否一致。
d. n是否在区间[h, H]内。
非法请求丢弃。如果副本节点i收到了2f+1个验证通过的Commit消息,说明当前网络中的大部分节点已经达成共识,运行客户端的请求操作o,并返回
(流程示意参考图)
总结
PBFT算法由于每个副本节点都需要和其他节点进行P2P的共识同步,因此随着节点的增多,性能会下降的很快,但是在较少节点的情况下可以有不错的性能,并且分叉的几率很低,可以较好的解决拜占庭容错问题。
参考文献:https://blog.csdn.net/jfkidear/article/details/81275974