PBFT(Practical Byzantine Fault Tolerance)共识算法可以在少数节点作恶(如伪造消息)场景中达成共识,它采用签名、签名验证、哈希等密码学算法确保消息传递过程中的防篡改性、防伪造性、不可抵赖性。

并优化了前人工作,将拜占庭容错算法复杂度从指数级降低到多项式级别,在一个由(3*f+1)个节点构成的系统中,只要有不少于(2*f+1)个非恶意节点正常工作,该系统就能达成一致性,如:7个节点的系统中允许2个节点出现拜占庭错误。

FISCO BCOS区块链系统实现了PBFT共识算法。

PBFT的共识就是确定谁是Leader节点

1. 重要概念

1.1 节点类型

  • Leader/Primary: 共识节点,负责将交易打包成区块和区块共识,每轮共识过程中有且仅有一个leader,为了防止leader伪造区块,每轮PBFT共识后,均会切换leader;
  • Replica: 副本节点,负责区块共识,每轮共识过程中有多个Replica节点,每个Replica节点的处理过程类似;
  • Observer: 观察者节点,负责从共识节点或副本节点获取最新区块,执行并验证区块执行结果后,将产生的区块上链。

其中Leader和Replica统称为共识节点。

1.2 节点ID && 节点索引

为了防止节点作恶,PBFT共识过程中每个共识节点均

  • 对其发送的消息进行签名,
  • 对收到的消息包进行验签名,

因此每个节点均维护一份公私钥对,私钥用于对发送的消息进行签名,公钥作为节点ID,用于标识和验签。

节点ID : 共识节点签名公钥是共识节点唯一标识, 一般是64字节二进制串,其他节点使用消息包发送者的节点ID对消息包进行验签

考虑到节点ID很长,在共识消息中包含该字段会耗费部分网络带宽,FISCO BCOS引入了节点索引,每个共识节点维护一份公共的共识节点列表,节点索引记录了每个共识节点ID在这个列表中的位置,发送网络消息包时,只需要带上节点索引,其他节点即可以从公共的共识节点列表中索引出节点的ID,进而对消息进行验签:

节点索引 : 每个共识节点ID在这个公共节点ID列表中的位置

1.3 视图(view)

PBFT共识算法使用视图view记录每个节点的共识状态,相同视图节点维护相同的Leader和Replicas节点列表。

当Leader出现故障,会发生视图切换,若视图切换成功(至少2*f+1个节点达到相同视图),则根据新的视图选出新leader,新leader开始出块,否则继续进行视图切换,直至全网大部分节点(大于等于2*f+1)达到一致视图。

FISCO BCOS系统中,leader索引的计算公式如下:

leader_idx = (view + block_number) % node_num

下图简单展示了4(3*f+1, f=1)节点FISCO BCOS系统中,第三个节点(node3)为拜占庭节点情况下,视图切换过程:

  • 前三轮共识: node0、node1、node2为leader,且非恶意节点数目等于2*f+1,节点正常出块共识;
  • 第四轮共识:node3为leader,但node3为拜占庭节点,node0-node2在给定时间内未收到node3打包的区块,触发视图切换,试图切换到view_new=view+1的新视图,并相互间广播viewchange包,节点收集满在视图view_new上的(2*f+1)个viewchange包后,将自己的view切换为view_new,并计算出新leader;
  • 为第五轮共识:node0为leader,继续打包出块。

1.4 共识消息

PBFT模块主要包括PrepareReq、SignReq、CommitReq和ViewChangeReq四种共识消息:

PrepareReqPacket:

包含区块的请求包,由leader产生并向所有Replica节点广播。

Replica节点收到Prepare包后,验证PrepareReq签名、执行区块并缓存区块执行结果,达到防止拜占庭节点作恶、保证区块执行结果的最终确定性的目的;

SignReqPacket:

带有区块执行结果的签名请求,由收到Prepare包并执行完区块的共识节点产生,

SignReq请求带有执行后区块的hash以及该hash的签名,分别记为SignReq.block_hash和SignReq.sig,

节点将SignReq广播到所有其他共识节点后,其他节点对SignReq(即区块执行结果)进行共识;

CommitReqPacket:

用于确认区块执行结果的提交请求,由收集满(2*f+1)个block_hash相同且来自不同节点SignReq请求的节点产生,

CommitReq被广播给所有其他共识节点,

其他节点收集满(2*f+1)个block_hash相同、来自不同节点的CommitReq后,将本地节点缓存的最新区块上链;

ViewChangeReqPacket:

视图切换请求,当leader无法提供正常服务(如网络连接不正常、服务器宕机等)时, 其他共识节点会主动触发视图切换,

ViewChangeReq中带有该节点即将切换到的视图(记为toView,为当前视图加一),

某节点收集满(2*f+1)个视图等于toView、来自不同节点的ViewChangeReq后,会将当前视图切换为toView。

这四类消息包包含的字段大致相同,所有消息包共有的字段如下:

字段名 字段含义
字段名 字段含义
idx 当前节点索引
packetType 请求包类型(包括PrepareReqPacket/SignReqPacket/CommitReqPacket/ViewChangeReqPacket)
height 当前正在处理的区块高度(一般是本地区块高度加一)
blockHash 当前正在处理的区块哈希
view 当前节点所处的视图
sig 当前节点对blockHash的签名

PrepareReqPacket类型消息包包含了正在处理的区块信息:

消息包类型 字段名 字段含义
PrepareReqPacket block 所有共识节点正在共识的区块数据

2. 系统框架

系统框架如下图:

PBFT共识主要包括两个线程:

PBFTSealer:

  • PBFT打包线程,负责从交易池取交易,
  • 并将打包好的区块封装成PBFT Prepare包,
  • 交给PBFTEngine处理;

PBFTEngine:

  • PBFT共识线程,从PBFTSealer或者P2P网络接收PBFT共识消息包,
  • 区块验证器(Blockverifier)负责开始执行区块,
  • 完成共识流程,将达成共识的区块写入区块链,
  • 区块上链后,从交易池中删除已经上链的交易。

3. 核心流程

PBFT共识主要包括Pre-prepare、Prepare和Commit三个阶段:

  • Pre-prepare:负责执行区块,产生签名包,并将签名包广播给所有共识节点;
  • Prepare:负责收集签名包,某节点收集满2*f+1的签名包后,表明自身达到可以提交区块的状态,开始广播Commit包;
  • Commit:负责收集Commit包,某节点收集满2*f+1的Commit包后,直接将本地缓存的最新区块提交到数据库。

下图详细介绍了PBFT各个阶段的具体流程:

3.1 leader打包区块

PBFT共识算法中,共识节点轮流出块,每一轮共识仅有一个leader打包区块,

leader索引通过公式(block_number + current_view) % consensus_node_num计算得出。

节点计算当前leader索引与自己索引相同后,就开始打包区块。

区块打包主要由PBFTSealer线程完成,Sealer线程的主要工作如下图所示:

  • 产生新的空块: 通过区块链(BlockChain)获取当前最高块,并基于最高块产生新空块(将新区块父哈希置为最高块哈希,时间戳置为当前时间,交易清空);
  • 从交易池打包交易: 产生新空块后,从交易池中获取交易,并将获取的交易插入到产生的新区块中;
  • 组装新区块: Sealer线程打包到交易后,将新区块的打包者(Sealer字段)置为自己索引,并根据打包的交易计算出所有交易的transactionRoot;位置void Block::calTransactionRoot(bool update) const
  • 产生Prepare包: 将组装的新区块编码到Prepare包内,通过PBFTEngine线程广播给组内所有共识节点,其他共识节点收到Prepare包后,开始进行三阶段共识。

3.2 pre-prepare阶段-执行区块

共识节点收到Prepare包后,进入pre-prepare阶段,此阶段的主要工作流程包括:

  • Prepare包合法性判断:主要判断是否是重复的Prepare包、Prepare请求中包含的区块父哈希是否是当前节点最高块哈希(防止分叉)、Prepare请求中包含区块的块高是否等于最高块高加一;
  • 缓存合法的Prepare包: 若Prepare请求合法,则将其缓存到本地,用于过滤重复的Prepare请求;
  • 空块判断:若Prepare请求包含的区块中交易数目是0,则触发空块视图切换,将当前视图加一,并向所有其他节点广播视图切换请求;
  • 执行区块并缓存区块执行结果: 若Prepare请求包含的区块中交易数目大于0,则调用BlockVerifier区块执行器执行区块,并缓存执行后的区块;
  • 产生并广播签名包:基于执行后的区块哈希,产生并广播签名包,表明本节点已经完成区块执行和验证。

3.3 Prepare阶段

共识节点收到签名包后,进入Prepare阶段,此阶段的主要工作流程包括:

  • 签名包合法性判断:主要判断签名包的哈希与pre-prepare阶段缓存的执行后的区块哈希相同,若不相同,则继续判断该请求是否属于未来块签名请求(产生未来块的原因是本节点处理性能低于其他节点,还在进行上一轮共识,判断未来块的条件是:签名包的height字段大于本地最高块高加一),若请求也非未来块,则是非法的签名请求,节点直接拒绝该签名请求;
  • 缓存合法的签名包:节点会缓存合法的签名包;
  • 判断pre-prepare阶段缓存的区块对应的签名包缓存是否达到2*f+1,若收集满签名包,广播Commit包:若pre-prepare阶段缓存的区块哈希对应的签名包数目超过2*f+1,则说明大多数节点均执行了该区块,并且执行结果一致,说明本节点已经达到可以提交区块的状态,开始广播Commit包;
  • 若收集满签名包,备份pre-prepare阶段缓存的Prepare包落盘:为了防止Commit阶段区块未提交到数据库之前超过2*f+1个节点宕机,这些节点启动后重新出块,导致区块链分叉(剩余的节点最新区块与这些节点最高区块不同),还需要备份pre-prepare阶段缓存的Prepare包到数据库,节点重启后,优先处理备份的Prepare包。

3.4 Commit阶段

共识节点收到Commit包后,进入Commit阶段,此阶段工作流程包括:

  • Commit包合法性判断:主要判断Commit包的哈希与pre-prepare阶段缓存的执行后的区块哈希相同,若不相同,则继续判断该请求是否属于未来块Commit请求(产生未来块的原因是本节点处理性能低于其他节点,还在进行上一轮共识,判断未来块的条件是:Commit的height字段大于本地最高块高加一),若请求也非未来块,则是非法的Commit请求,节点直接拒绝该请求;
  • 缓存合法的Commit包:节点缓存合法的Commit包;
  • 判断pre-prepare阶段缓存的区块对应的Commit包缓存是否达到2*f+1,若收集满Commit包,则将新区块落盘:若pre-prepare阶段缓存的区块哈希对应的Commit请求数目超过2*f+1,则说明大多数节点达到了可提交该区块状态,且执行结果一致,则调用BlockChain模块将pre-prepare阶段缓存的区块写入数据库;

3.5 视图切换处理流程

当PBFT三阶段共识超时或节点收到空块时,PBFTEngine会试图切换到更高的视图(将要切换到的视图toView加一),并触发ViewChange处理流程;

节点收到ViewChange包时,也会触发ViewChange处理流程:

  • 判断ViewChange包是否有效: 有效的ViewChange请求中带有的块高值必须不小于当前节点最高块高,视图必须大于当前节点视图;
  • 缓存有效ViewChange包: 防止相同的ViewChange请求被处理多次,也作为判断节点是否可以切换视图的统计依据;
  • 收集ViewChange包:若收到的ViewChange包中附带的view等于本节点的即将切换到的视图toView且本节点收集满2*f+1来自不同节点view等于toView的ViewChange包,则说明超过三分之二的节点要切换到toView视图,切换当前视图到toView。

https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/design/consensus/pbft.html?highlight=PBFT#pbft

FISCO BCOS PBFT是什么 基础流程相关推荐

  1. 区块链 Fisco bcos 智能合约(19)-区块链性能腾飞:基于DAG的并行交易执行引擎PTE

    在区块链世界中,交易是组成事务的基本单元. 交易吞吐量很大程度上能限制或拓宽区块链业务的适用场景,愈高的吞吐量,意味着区块链能够支持愈广的适用范围和愈大的用户规模. 当前,反映交易吞吐量的TPS(Tr ...

  2. FISCO BCOS 联盟链Pro搭建

    FISCO BCOS Pro版本 版本说明 FISCO BCOS 3.0支持Pro版本微服务区块链架构,Pro版本FISCO BCOS包含RPC服务.Gateway服务和节点服务,每个服务均可独立部署 ...

  3. spring boot 实现fisco bcos最基础案例

    spring boot 实现fisco bcos最基础案例 一.基于国密搭建的4个节点联盟链 1.1 依赖文件 1.2 config.toml配置文件 1.3 用工具编译Helloworld.sol生 ...

  4. 联盟链中的Hyperledger Fabric、FISCO BCOS和CITA

    本文援引自链接:https://mp.weixin.qq.com/s/4JAZGwI32bZNlxBqPfkihg 一.摘要 第 46 届世界经济论坛达沃斯年会将区块链与人工智能.自动驾驶等一并列入& ...

  5. 区块链学习路径,看这一篇就够了 | FISCO BCOS

    FISCO BCOS开源社区已沉淀过百篇文章,覆盖了区块链学习各个阶段.为了方便大家对应自身学习阶段找到合适的教程,我们按照区块链学习成长路径对社区文章进行整理排序,希望沿着这份路径规划,大家都能成为 ...

  6. 开源架构Fabric、FISCO BCOS(以下简称“BCOS”)、CITA 技术对比

    转自 https://www.coingogo.com/news/41300 联盟链技术哪家强?开源架构Fabric.FISCO BCOS(以下简称"BCOS").CITA 技术对 ...

  7. FISCO BCOS 联盟链Max搭建

    FISCO BCOS Max版本 版本说明 为了能够支撑海量交易上链场景,v3.0.0推出了Max版本FISCO BCOS,Max版本FISCO BCOS旨在提供海量存储服务.高性能可扩展的执行模块. ...

  8. 一文说清FISCO BCOS性能压测(附实例教程)

    "我的区块链能跑多少TPS?""能不能达到'官方'所说的峰值?""为啥总是压不上去?是我的机器不够好吗?" 如今,区块链技术被广泛应用在各行 ...

  9. Fabric、FISCO BCOS、以太坊对比

    Fabric.FISCO BCOS.以太坊对比 一.以太坊 1.1 什么是工作量证明(POW) 1.2 这是如何运作的? 1.3 工作量证明的问题 1.4 股权证明 二.Fabric 2.1 产生背景 ...

  10. FISCO BCOS 区块链

    FISCO BCOS是由国内企业主导研发.对外开源.安全可控的企业级金融联盟链底层平台,由金链盟开源工作组协作打造,并于2017年正式对外开源. 社区以开源链接多方,截止2020年5月,汇聚了超100 ...

最新文章

  1. 【C++】C++好书推荐
  2. 如何搭建一个 MySQL 分布式集群
  3. C++标准转换运算符static_cast
  4. 1792 关于数论中的互质数的最大不能组合数
  5. Flink SQL Client方言切换与datagen->Hive(DDL形式+streaming形式)
  6. vue-cli中的webpack的config配置详细说明
  7. Variable Assembly Language可变汇编语言
  8. matlab的try函数,matlab – 是否可以在没有try块的情况下测试函数句柄?
  9. android界面设计所用中文什么字体,「界面」手机界面设计字体大小知多少
  10. php怎么打印json数据,php输出json格式数据的例子
  11. python3爬虫-通过requests爬取图虫网
  12. Codeforces Round #499 (Div. 2): F. Mars rover(DFS)
  13. Java Web开发实战(二)—Tomcat安装及环境变量配置
  14. 美团Robust热修复工具使用记录
  15. matlab解线性方程组后结果是小数,MATLAB线性方程组求解
  16. 文件上传漏洞---Web渗透学习
  17. Mac 安装Photoshop遇到一系列问题解决方法
  18. C#上位机开发串口通信编程——倒计时器开发
  19. 三维目标检测算法汇总学习笔记
  20. delphi源码 中间件 框架【网盘映射】

热门文章

  1. CISCO路由器NAT-T与IPSec ×××配置实验【实践闯未来】
  2. 买车,给点建议和意见
  3. 梅花雨的日历控件在ASP.NET2.0下不可用的解决方法
  4. 男人在拥有女人之后!
  5. 林锐:5 C++/C程序的基本概念
  6. Python全栈开发——线程与进程的概念
  7. 案例5-条件查询商品
  8. 用C++完成三国杀(无GUI)
  9. 拓端tecdat|R语言和Stan,JAGS:用rstan,rjags建立贝叶斯多元线性回归预测选举数据
  10. 拓端tecdat|R语言如何找到患者数据中具有差异的指标?(PLS—DA分析)