深入理解PBFT算法——提交阶段的作用

文章目录

1. 前述

PBFT(Practical Byzantine Fault Tolerance,实用拜占庭容错算法)是联盟链常用的一种共识算法。本文讨论PBFT提交阶段的作用,要求读者对PBFT的算法有一个大致了解,如果你是刚听过这个算法,知道算法的基本流程,看完本文可能会对PBFT有更深入的理解;如果你研读过PBFT原论文,那么本文也许可以作为阅读拓展。如果有不同理解或者认为文中表述有问题,欢迎讨论指正。

2. PBFT算法的QC性质

在讨论主题之前,我们需要先了解PBFT算法的QC性质,这是证明PBFT正确性的重要前提。

Q 和 C 分别表示 Quorum 和 Certificate。

  • Quorum 意思为 仲裁数,法定人数。在PBFT中,当总节点数为3f+1时(用 f 表示拜占庭节点数量时,总节点数大于等于 3f+1 时拜占庭问题才有解,这个问题的证明不在本文的讨论范围),Quorum 表示数量不少于 2f+1 的节点集合。
  • Quorum certificate 则表示来自一个Quorum的每个节点的某种消息组成的一个集合,称为证书,如准备证书和提交证书。

Quorum 有两个重要的性质:

  1. 相交性: 任何两个 Quorum 至少有一个共同的正确节点。
  2. 可得性: 总能找到一个没有错误节点的 Quorum 。

Intersection property: any two quorums have at least one correct replica in common. Availability property: there is always a quorum available with no faulty replicas.

这两个性质贯穿了PBFT的整个证明过程,特别是性质1。

第一个性质,我们可以用一个图直观地理解:

图1. Quorum 的相交性

我们在一个大小为3f+1的集合中,画两个2f+1子集,并且使得交集尽可能地小,可以看到,即使尽最大的努力减小交集,最小的交集还是f+1,即交集中至少有一个正确节点。

另外,当 f=1 时,3f+1=4,当 f=2 时,3f+1=7,那么当总节点数等于5或6时,Quorum 的数量该如何计算呢?我们记总节点数为N,且 3f+1≤N<3(f+1)+1 ,则一个 Quorum 的数量不少于\lceil\frac{2N}{3}\rceil ,其中\lceil\rceil 表示向上取整,推导:

设 Quorum 的数量为x,为了满足性质1,两个 Quorum 的交集大小至少为 f+1,则有

2x-N≥f+1
x≥\frac{N+f+1}{2}

3f+1≤N<3(f+1)+1 ,即 \frac{N-1}{3}-1<f≤\frac{N-1}{3} ,可得 f = \lfloor\frac{N-1}{3}\rfloor ,其中\lfloor\rfloor 表示向下取整,带入上式,并由\lfloor\frac{n}{m}\rfloor=\lceil\frac{n+1}{m}\rceil-1 1有:

x≥\frac{N+\lfloor\frac{N-1}{3}\rfloor+1}{2}=\frac{N+(\lceil\frac{N}{3}\rceil-1)+1}{2}=\frac{1}{2}\lceil\frac{4N}{3}\rceil

因为x为整数,可对上式右侧向上取整,得:

x≥\lceil\frac{1}{2}\lceil\frac{4N}{3}\rceil\rceil=\lceil\frac{2N}{3}\rceil=\lfloor\frac{2N-1}{3}\rfloor+1

转化为向下取整可以方便转化为编程语言(编程语言的整数除法一般为向下取整)。

N=3f+1时带入校验,同样满足上式。

3. 提交阶段的作用

3.1 前两个阶段

PBFT包含三个阶段:预准备阶段、准备阶段、提交阶段。

图2. PBFT算法大致流程

准备阶段收集2f+1个来自不同节点的序列号相同、请求相同的准备消息(可以含1个预准备消息),这一步确保了请求顺序在所有正确节点上达成一致。这利用了性质1,对于任意两个节点来说,如果他们分别收到了2f+1个来自不同节点的序列号相同的准备消息,那么一定有一个消息来自一个共同的正确节点,再加上正确节点不会对同一个请求发送两个序列号不同的消息(算法决定),所以他们收到的准备消息的序列号一定相同。

前两个阶段是用于同一个视图内保证请求的顺序一致,提交阶段是用于保证跨视图(主节点切换)的请求顺序一致。也就是说,如果没有视图切换,前两个阶段已经能够保证顺序一致。

3.2 假设只有两个阶段

为了看清提交阶段的作用,我们假设没有这个阶段,看是否能够保证算法的正确(安全性和活动性),或者说,我们能否设计出一个算法,可以将提交阶段去除。

我们考虑四个节点的情况,节点1为主节点、且为恶意节点,在一次共识周期中,主节点向节点3和4发送编号为n、请求为m的预准备消息,向节点2发送编号为n、请求为m’(与m不同)的预准备消息,假设在一定时间之后,节点3收集到了准备证书(2f个准备消息和1个预准备消息),并执行了该请求,对客户端进行了响应。

图3. 假设没有提交阶段

假设此时发生了主节点切换,新的主节点为节点2,我们知道,节点2并没有收集到请求m的准备证书,但由于此时节点3认为该请求已达成共识,并且已经执行了该请求,所以请求m必须被重放,以使得所有节点达成一致。为了重放请求m,节点2需要收集来自其他节点的准备证书,假设只有节点3收集到了准备证书,那么只有保证节点2能够收到来自节点3的准备证书,才能重放该请求。

我们尝试能否通过设计一定的算法来达到这样的目的:在视图切换的时候,所有节点向新的主节点发送已有的准备证书,主节点收集这些证书并对这些请求进行重放,那么主节点要在什么时候停止收集证书呢?假设是收到2f+1个节点的消息时,停止收集,那就可能错过节点3的准备证书;所以不难得出,必须收集所有节点的消息,才能停止,但这更是不可能的,因为拜占庭节点可以选择不发送消息。可见,设计出这样的算法是不太可能的。

3.3 提交阶段的作用

那么提交阶段是如何解决这个问题的呢?通过以上的讨论,我们可以看到,如果收集到准备证书就执行请求,此时由于可能没有足够的节点收集到了准备证书,所以后续无法保证在切换主节点之后,该请求能够被重放(被其他节点执行)。因此,每个节点应该在获知有足够的节点收集到准备证书之后,再执行请求,提交阶段就是做了这样的事情。

首先,提交阶段要求节点收集到2f+1个提交消息之后,才进入已提交状态,此时节点执行该请求并对客户端进行响应。这个要求保证了在执行请求的时候,已经有2f+1个节点收集到了准备证书,这对于后续请求的重放起了关键作用。

在主节点切换时,节点在广播的View-Change消息中包含了(所有未达到稳定检查点的)准备证书,新主节点发出的New-View消息之前,至少收集2f+1个节点的View-Change消息。假设请求m在主节点切换之前已经被提交了,也就是有2f+1个节点持有它的准备证书,由PBFT算法的QC性质1,这**2f+1**个节点与New-View消息中的**2f+1**个节点,一定有一个共同的正确节点,也就是被提交的请求一定会在新的视图中重放,这解决了跨视图的一致性问题。

综上所述,提交阶段是用于与View-Change配合,保证在上一视图中执行的请求,可以在新的视图中重放,并且编号n相同,即保证了跨视图请求顺序的一致性。

参考:

原文地址:https://cloud.tencent.com/developer/article/2028461

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340