PBFT && RBFT算法流程

PBFT && RBFT算法流程以及其实现(上)

这篇文章主要是讲一下RBFT中共识算法流程以及节点的加入的流程。在下一篇博客中,将使用Java实现该算法。

传统的PBFT算法无法动态的添加和删除结点,高鲁棒拜占庭容错算法RBFT(Robust Byzantine Tolerance)算法实现了该功能。

在RBFT算法中,有几个变量我们需要知道:f,N,quorum

  • N ; 代表结点的数量。
  • f :代表PBFT中最多能容忍的错误的结点$ f = \lfloor\frac{N-1} { 3} \rfloor$
  • quorum:达到共识需要的结点数量 $quorum = \lceil \frac {N + f +1 }{2 }\rceil $

因此在PBFT算法中,为了能够容忍f个错误,需要的结点数量是$3f+1$

在RBFT算法中,有一个主节点和多个从结点,其中主节点是通过选举产生的,负责对客户端发来的交易进行打包处理,而从节点很简单,进行共识认证以及主结点的选取。

RBFT && PBFT的常规流程

下面是来自hyperchain的关于RBFT流程的一些介绍:

RBFT常规流程

RBFT的常规流程保证了区块链各共识节点以相同的顺序处理来自客户端的交易。RBFT同PBFT的容错能力相同,需要至少3f+1个节点才能容忍f个拜占庭错误。下图为最少集群节点数下的共识流程,其N=4,f=1。图中的Primary1为共识节点动态选举出来的主节点,负责对客户端发来的交易进行排序打包,Replica2,3,4为从节点。所有节点执行交易的逻辑相同并能够在主节点失效时参与新主节点的选举。

常规流程

RBFT共识保留了PBFT原有的三阶段处理流程(PrePrepare、Prepare、Commit)的同时增加了重要的交易验证(validate)环节,在保证对交易执行顺序达成共识的同时也保证了对区块验证结果的共识。

RBFT常规流程在原生的PBFT算法中穿插了交易验证环节,主节点将交易打包成块后先行验证,并将验证结果包含到PrePrepare消息中进行全网广播,这样PrePrepare消息中既包含了排好序的交易信息也包含了区块验证结果。从节点在收到主节点的PrePrepare消息后先检查消息的合法性,检查通过后广播Prepare消息表明本节点同意主节点的排序结果;在收到(quorum-1)个Prepare消息后从节点才会开始验证区块,并将验证结果与主节点的验证结果进行比对,比对结果一致则广播Commit表明本节点同意主节点的验证结果,否则直接发起ViewChange表明本节点认为主节点有异常行为。RBFT常规流程具体分为如下几个步骤:

  1. 交易转发阶段: 客户端将交易发送到区块链中的任意节点(包括共识节点与记账节点),其中记账节点在收到交易后会主动转发给与其相连的共识节点;而共识节点在收到客户端的交易后将其广播给其他共识节点,这样所有共识节点的交易池中都会维护一份完整的交易列表;
  2. PrePrepare阶段: 主节点按照如下策略进行打包:用户可以根据需求自定义打包的超时时间(batch timeout)与打包的最大区块大小(batch size),主节点在超时时间内收集到了足够多(超过最大区块大小个数)的交易或者超时时间到达后仍未收集到足够多的交易都会触发主节点的打包事件。主节点将交易按照接收的时间顺序打包成块,并进行验证,计算执行结果,最后将定序好的交易信息连同验证结果等写入PrePrepare消息中广播给所有共识节点,开始三阶段处理流程;
  3. Prepare阶段: 从节点在收到主节点的PrePrepare消息后,首先进行消息合法性检查,检查当前的视图与区块号等信息,检查通过后向共识节点广播Prepare消息;
  4. Commit阶段: 从节点在收到(quorum-1)个Prepare消息以及相应的PrePrepare消息后进行验证,并将验证结果与主节点写入PrePrepare消息中的验证结果进行比对,比对结果一致则广播Commit表明本节点同意主节点的验证结果,否则直接发起ViewChange表明本节点认为主节点存在异常行为,需要切换主节点;
  5. 写入账本: 所有共识节点在收到quorum个Commit消息后将执行结果写入本地账本。

以上的过程还是很简单的,就是主节点发送交易信息,如果大部分的从结点(也就是quorum个结点)同意,则这个交易信息会被写入所有结点的区块(少数服从多数)。

在前面我们可以发现,从节点是可以怀疑主节点的,也就是说从节点可以发起请求进行重新选举,得到一个新的主节点(这个在主节点被攻击或者宕机是非常有效的)。

主节点的生成以及变迁

在PBFT以及RBFT中,都有视图(View),这个值从零开始只增不减。那么我们如何得到主节点呢?或者说重新选举,选择谁为主节点。

设:结点数为N,当前视图为view,则主结点的id为:

$$primaryId = (view +1) mod N$$

下面的引用还是来自hyperchain,毕竟有图能够理解的更好。其中:

  • nullRequest 消息的目的是查看主节点是不是在线

视图变更流程

上图中,Primary 1为拜占庭节点,需要进行ViewChange。在RBFT中的ViewChange流程如下:

  1. 从节点在检测到主节点有异常情况(没有按时收到nullRequest消息)或者接收到来自其他f+1个节点的ViewChange消息之后会向全网广播ViewChange消息,自身view从v更改为v+1;
  2. 新视图中主节点收到N-f 个ViewChange消息后,根据收到的ViewChange消息计算出新视图中主节点开始执行的checkpoint和接下来要处理的交易包,封装进NewView消息并广播,发起VcReset;
  3. 从节点接收到NewView消息之后进行消息的验证和对比,如果通过验证,进行VcReset,如果不通过,发送ViewChange消息,进行又一轮ViewChange;
  4. 所有节点完成VcReset之后向全网广播FinishVcReset;
  5. 每个节点在收到N-f个FinishVcReset消息之后,开始处理确定的checkpoint后的交易,完成整个ViewChange流程。

由于共识模块与执行模块之间是异步通信的,而ViewChange之后执行模块可能存在一些无用的validate缓存,因此共识模块需要在ViewChange完成之前通知执行模块清除无用的缓存,RBFT通过VcReset事件主动通知执行模块清除缓存,并在清理完成之后才能完成ViewChange。

RBFT中结点动态的增添和删除

在前面我们知道,PBFT算法是无法实现结点动态的增删的,而新的算法RBFT实现了该功能。

结点的增加和删除当然会遵守共识原则,下面还是来自hyperchain的介绍。毕竟别人介绍的比我好多了,我就不多介绍了。

简单点来说,就是新加入的结点会向区块链中的已经存在的结点申请加入,如果存在的结点同意的话,则就加入成功,然后新加入的结点会发送recovery消息(关于recovery可以看hyperchain的介绍),目的是为了让自己与区块链中结点的内容保持一致。然后新加入的结点会要求进行重新选举主节点(因为N已经发生改变),然后完成主节点的更改。

新增节点流程

上图中,Replica 5为待新增的节点。RBFT节点的动态新增节点流程如下:

  1. 新增节点Replica 5通过读取配置文件信息,主动向现有节点发起连接,确认所有节点连接成功后更新自身的路由表,并发起recovery;
  2. 现有节点接收到Replica 5的连接请求后确认同意该节点加入,然后向全网广播AddNode消息,表明自己同意该新节点加入整个共识网络;
  3. 当现有节点收到N条(N为现有区块链共识网络中节点总数)AddNode消息后,更新自身的路由表,随后开始回应新增节点的共识消息请求(在此之前,新增节点的所有共识消息是不予处理的);
  4. Replica 5完成recovery之后,向全网现有节点广播ReadyForN请求;
  5. 现有节点在收到ReadyForN请求后,重新计算新增节点加入之后的N,view等信息,随后将其与PQC消息封装到AgreeUpdateN消息中,进行全网广播;
  6. Replica 5加入后的共识网络会产生一个新的主节点,该主节点在收到N-f个AgreeUpdateN消息后,以新的主节点的身份发送UpdateN消息;
  7. 全网所有节点在收到UpdateN消息之后确认消息的正确性,进行VCReset;
  8. 每个节点完成VCReset后,全网广播FinishUpdate消息;
  9. 节点在收到N-f个FinishUpdate消息后,处理后续请求,完成新增节点流程。

这篇文章基本上就是从hyperchain上面copy上来的,在这里仅仅是做一个笔记用。如果想了解更多,建议参考官方文档。这一篇主要是为了弄清楚PBFT or RBFT的流程,这几天在看《区块链底层设计 Java实战》一直没弄得太懂,然后代码也写的没头绪。这里不得不感谢牛冬(这本书的作者)大佬,很热心的回答我的问题(真没想到加作者的微信竟然加成功了O(∩_∩)O~~)。

哦,还得掉头发,想一想怎么实现这些算法……

参考

  1. hyperchain:https://hyperchain.readthedocs.io/zh_CN/latest/consensus.html#

原文地址:https://www.cnblogs.com/xiaohuiduan/p/12210891.html

时间: 2024-07-30 20:21:33

PBFT && RBFT算法流程的相关文章

Latex 如何书写算法流程

最近要在论文中写算法流程, 幸好看到一个latex版本, 借此机会学习下. 代码如下: %\dontprintsemicolon%doesn't work on my machine \SetCommentSty{textit} \SetKwComment{tcc}{}{} %default /* */ \SetSideCommentRight \SetKwInOut{Input}{Input}\SetKwInOut{Output}{Output} \Input{Signal to be fil

AdaBoost 人脸检测介绍(3) : AdaBoost算法流程

本系列文章总共有七篇,目录索引如下: AdaBoost 人脸检测介绍(1) : AdaBoost身世之谜 AdaBoost 人脸检测介绍(2) : 矩形特征和积分图 AdaBoost 人脸检测介绍(3) : AdaBoost算法流程 AdaBoost 人脸检测介绍(4) : AdaBoost算法举例 AdaBoost 人脸检测介绍(5) : AdaBoost算法的误差界限 AdaBoost 人脸检测介绍(6) : 使用OpenCV自带的 AdaBoost程序训练并检测目标 AdaBoost 人脸

写文件头的算法流程及C代码实现

一.问题描述 将多条记录写入文件中,每条记录占一行.每写入一条记录,要计算当前文件中所有记录的大小(精确到字节)和记录条数,并写到文件的第一行(即文件头).为了便于区分,文件记录的大小和文件中记录条数各占10个字节,左对齐,不足的位补以空格. 二.算法流程 三.C代码实现 四.程序说明 (1) 本程序在Linux环境下用makefile文件进行编译,makefile文件的内容如下: WriteFileHeader : WriteFileHeader.c gcc -c -g WriteFileHe

Imu_tk算法流程及数据采集要求和标定程序参数设置

Imu_tk算法流程 由于VIO中,普遍使用的是精度较低的imu,所以其需要一个较为准确的内参数和noise的估计.Noise大家通常使用Allan方差进行估计可以得到较为可信的结果,这里不赘述了.内参数标定比较方便的一个工具就是imu_tk.所以本篇文章主要详细介绍一下imu_tk的算法流程以及使用时的注意事项.下一篇的内容 计划是imu-camera外参数的标定方法. 首先分步介绍算法流程: 1. 读入数据,将时间单位转化为秒 2. 设置初始参数和标定算法的控制参数 3. 开始标定 3.1

08-01 通过线性回归了解算法流程

目录 通过线性回归带你了解算法流程 一.1. 1 线性回归引入 二.1. 2 决策函数 三.1. 3 损失函数 四.1. 4 目标函数 五.1. 5 目标函数最小化 六.1. 6 过拟合 七.1. 7 正则化 7.1 1. 7.1 L1正则化 7.2 1. 7.2 L2正则化 八.1. 8 训练集.验证集.测试集 8.1 1. 8.1 训练集 8.2 1. 8.2 验证集 8.3 1. 8.3 测试集 九.1. 9 本章小结 更新.更全的<机器学习>的更新网站,更有python.go.数据结构

SSL/TLS算法流程解析

SSL/TLS 早已不是陌生的词汇,然而其原理及细则却不是太容易记住.本文将试图通过一些简单图示呈现其流程原理,希望读者有所收获. 一.相关版本 Version Source Description   Browser Support SSL v2.0 Vendor Standard (from Netscape Corp.) [SSL2] First SSL protocol for which implementations exist - NS Navigator 1.x/2.x - MS

结对编程任务的算法流程思路

这次的结对编程的作业相较于上次的作业看似只是核心功能的嫁接过程,但是程序这个东西尤其是对于实战经验并不很足的我来讲,其实还是很有难度的,因为在这次的作业要求中新加了很多的可以由用户定制的功能要求,那么以前的取巧一些的方法在对于这种可以随意定制功能的要求之下就显得力不从心,于是对我来讲这次的作业只有部分的算法的框架还留在程序中,从代码的角度来讲的话基本所有的代码都是被重构的,作为处女座的一员即便是当初可以用的代码,再一次复审的时候发现很多不和标准的地方的有悖于自己的强迫症的地方还是不能忍受的于是果

Python多继承解析顺序的C3线性算法流程解析

Python多继承MRO 在Python2.1中,采用了经典类,使用深度优先算法解析. Python2.2中,引入了新式类,使用深度优先算法和广度优先算法. 在Python2.3以后的版本中,经典类和新式类共存,使用了DFS算法和C3算法. Python2中的经典类 class A(object): pass Python3的新式类 class A: pass C3算法 In computing, the C3 superclass linearization is an algorithm u

GB和GBDT 算法流程及分析

1.优化模型的两种策略: 1)基于残差的方法 残差其实就是真实值和预测值之间的差值,在学习的过程中,首先学习一颗回归树,然后将“真实值-预测值”得到残差,再把残差作为一个学习目标,学习下一棵回归树,依次类推,直到残差小于某个接近0的阀值或回归树数目达到某一阀值.其核心思想是每轮通过拟合残差来降低损失函数. 总的来说,第一棵树是正常的,之后所有的树的决策全是由残差来决定. 2)使用梯度下降算法减小损失函数. 对于一般损失函数,为了使其取得最小值,通过梯度下降算法,每次朝着损失函数的负梯度方向逐步移