共识算法 - PBFT
本文翻译自博客 - Introduction to Sawtooth PBFT 和 pBFT — Understanding the Consensus Algorithm。同时,作了一定的取舍和删减。
1. 什么是 PBFT?
PBFT 的历史可以追溯到 1999 年由 MIT 的 Miguel Castro 和 Barbara Liskov 撰写的论文。与当时的其他算法不同,PBFT 是第一个设计用于实际异步环境中的拜占庭容错算法。 PBFT 经过深思熟虑的定义,完善的建立和广泛的理解。
PBFT 在某些常规方面类似于 Raft:
- 它是基于领导者且非分叉的(不同于彩票式算法)
- 它不支持开放注册,但是管理员可以添加和删除节点
- 它要求完全对等(所有节点必须连接到所有其他节点)
PBFT 提供拜占庭容错能力,而 Raft 仅支持崩溃容错能力。拜占庭式容错意味着即使网络的某些部分出现故障或恶意,也可以确保活动性和安全性。只要 PBFT 网络中至少有一定百分比的节点已连接,正常工作并诚实运行,网络将始终取得进步,并且不允许任何节点操纵网络。
2. PBFT 如何工作?
原始 PBFT 论文对共识算法进行了详细而严格的解释。以下是算法关键点的摘要。原始定义广泛适用于任何类型的复制系统。通过保持特定于区块链的信息,我们可以更轻松地描述 PBFT 共识引擎的功能。
2.1 网络概述
PBFT 网络由一系列从 0 到 n-1 的节点组成,其中 n 是网络中的节点数。如前所述,PBFT 网络可以容忍的最大“坏”节点数量,只要不超过这个坏节点的数量(称为常数 f),网络就可以正常工作。对于 PBFT,常数 f 等于网络中节点的三分之一。在任何给定时间,不超过三分之一的网络(四舍五入)可能是“乱序”或不诚实的,以使算法起作用。 n 和 f 的值非常重要;你稍后会在我们讨论算法如何运行时看到它们。
Figure 1 — n and f in the PBFT algorithmFigure 1 — n and f in the PBFT algorithm
随着网络的发展,节点在一系列“视图”中移动。视图是给定节点是网络的主体(领导者)的时间段。简单来说,从第一个节点开始,每个节点在一个永无止境的循环中依次成为主体节点。对于四节点网络,节点 0 是视图 0 的主体节点,节点 1 是视图 1 的主体节点,依此类推。当网络查看 4 时,它将“回绕”,以便节点 0 再次成为主体节点。
用更专业的术语来说,每个视图的主视图(p)是基于视图编号(v)和节点的顺序确定的。确定给定网络上任何视图的主要视图的公式为 p = v mod n
。例如,在视图 7 的四节点网络上,公式 p = 7 mod 4
意味着节点 3 将是主节点(7 mod 4 = 3
)。
除了浏览一系列视图外,网络还浏览一系列“序列号”。在区块链的上下文中,序列号等同于区块号;因此,说一个节点在序列号 10 上与说该节点在区块链中的区块 10 上执行共识是相同的。
每个节点在其状态中维护一些关键信息:
- 属于网络的节点列表
- 当前视图数
- 当前序列号(正在处理的区块)
- 当前处于算法的阶段(请参阅“常规情况下的操作”)
- 接收到的区块的日志
- 从其他节点收到的所有有效消息的日志
正常情况下的操作
Figure 2 — Messages sent during normal operation of PBFT (Node 3 is faulty)
Figure 2 — Messages sent during normal operation of PBFT (Node 3 is faulty)
为了提交一个区块并取得进展,PBFT 网络中的节点经历三个阶段:
- 预备 (Pre-preparing)
- 准备中 (Preparing)
- 提交中 (Committing)
图 2 显示了简单的四节点网络的这些阶段。在此示例中,节点 0 是主体节点,节点 3 是故障节点(因此它不发送任何消息)。因为网络中有四个节点(n = 4),所以网络的 f 值为 (4 - 1) / 3 = 1
。这意味着示例网络只能容忍一个故障节点。
2.1.1 预备
首先,当前视图的主视图将创建一个区块并将其发布到网络;每个节点都将接收此区块并执行一些初步验证,以确保该区块有效。
主体节点将一个区块发布到网络后,它会向所有节点广播预准备消息。预先准备的消息包含四个关键信息:刚发布的主体对象的 ID,该对象的编号,主体对象的视图编号和主体对象的 ID。当节点从主体节点收到预准备消息时,它将验证该消息并将该消息添加到其内部日志中。消息验证包括验证消息的数字签名,检查消息的视图号是否与节点的当前视图号匹配以及确保消息来自当前视图的主体视图。
预准备消息用作主体节点公开背书给定区块的方法,以及网络就该序列号同意在哪个区块上执行共识的方法。为了确保一次只考虑一个区块,节点在给定的视图和序列号上不允许有多个预准备消息。
2.1.2 准备中
一旦节点接收到一个区块和该区块的预备消息,并且该区块和消息都已添加到该节点的日志中,该节点将进入准备阶段。在准备阶段,节点将向网络的其余部分(包括自身)广播准备消息。与准备消息一样,准备消息包含它们要用于的区块的 ID 和编号,以及节点的视图编号和 ID。
为了进入下一阶段,该节点必须等待,直到它收到 2f + 1
准备消息,这些消息具有相同的区块 ID,区块编号和视图编号,并且来自不同的节点。通过等待 2f +1
匹配的准备消息,该节点可以确保在此阶段,所有正常运行的节点(无故障且无恶意的节点)都已达成协议。一旦节点接受了所需的 2f +1
匹配准备消息并将其添加到其日志中,就可以进入提交阶段了。
2.1.3 提交中
当节点进入提交阶段时,它会向整个网络(包括自身)广播一条提交消息。与其他消息类型一样,提交消息包含它们所针对的区块的 ID 和编号,以及节点的视图编号和 ID。与准备阶段一样,节点必须先从不同节点接收到 2f +1
个匹配的提交消息,才能完成提交阶段。再次,这保证了网络中所有非故障节点都同意提交该区块,这意味着该节点可以知道不需要恢复该节点而可以安全地提交该区块。接受所需的 2f +1
提交消息并在其日志中,节点可以安全地提交该区块。
一旦主节点完成了提交阶段并提交了区块,它将通过创建一个区块,发布它并为它广播预准备消息来重新开始整个过程。
2.2 视图变化
为了具有拜占庭式的容错能力,共识算法必须防止节点不当更改网络(以确保安全)或无限期停止进程(以确保活跃性)。 PBFT 通过要求所有非故障节点都同意才能超越准备和提交阶段,从而确保安全。但是,为了保证活动的活跃性,必须有一种机制来确定领导者的行为是否不当(例如产生无效消息或干脆不做任何事情)。PBFT 通过视图更改提供活跃性保证。
Figure 3 — Messages sent for a view change in PBFT (Node 0 is the faulty primary, Node 1 is the new primary)
Figure 3 — Messages sent for a view change in PBFT (Node 0 is the faulty primary, Node 1 is the new primary)
当节点确定视图 v 的主体节点有故障时(可能是因为该主体节点发送了无效消息或未及时生成有效的区块),它将向网络广播视图 v + 1
的视图更改消息。如果主体节点确实存在故障,则所有非故障节点都将广播视图更改消息。当新视图的主体视图(v + 1
)从不同节点接收到 2f + 1
个视图更改消息时,它将向所有节点广播新的视图 v + 1
视图消息。当其他节点收到新的视图消息时,它们将切换到新视图,新的主体节点将开始发布区块并发送预准备的消息。
视图更改可确保在当前主数据库出现故障时,网络可以继续使用新的主体数据库。此 PBFT 功能使网络能够继续前进,而不会因不良的主体节点而停滞。
3. 对 PBFT 的优化
我们无法使用 PBFT 减少消息的数量,因此我们只能减少消息所需的加密证明。与 RSA 数字签名相比,MAC 的 CPU 强度降低了几个数量级
因此,RSA 数字签名仅用于视图更改和新视图消息,它们仅用于将备份副本升级为主副本。视图更改仅在主节点出现故障或已处理 k 个请求之后发生。所有其他消息均使用 SHA256 等 MAC 进行身份验证。
麻省理工学院最初的 1999 年 PBFT 论文 的作者 Miguel Castro 和 Barbara Lisk 发现,MAC 的计算速度比数字签名快三个数量级。尽管他们将 MD5 与 1024 位 RSA 签名进行了比较,但现在我们通常使用 SHA256 和 2048 位 RSA。
Reference
- Introduction to Sawtooth PBFT, https://cn.hyperledger.org/%E7%BD%91%E5%BF%97/2019/02/13/introduction-to-sawtooth-pbft
- pBFT — Understanding the Consensus Algorithm - https://medium.com/coinmonks/pbft-understanding-the-algorithm-b7a7869650ae
- Practical Byzantine Fault Tolerance, http://pmg.csail.mit.edu/papers/osdi99.pdf
项目源代码
项目源代码会逐步上传到 Github,地址为 https://github.com/windstamp/blockchain。
Contributor
- Windstamp, https://github.com/windstamp
网友评论