FISCO BCOS PBFT是什么 基础流程
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是什么 基础流程相关推荐
- 区块链 Fisco bcos 智能合约(19)-区块链性能腾飞:基于DAG的并行交易执行引擎PTE
在区块链世界中,交易是组成事务的基本单元. 交易吞吐量很大程度上能限制或拓宽区块链业务的适用场景,愈高的吞吐量,意味着区块链能够支持愈广的适用范围和愈大的用户规模. 当前,反映交易吞吐量的TPS(Tr ...
- FISCO BCOS 联盟链Pro搭建
FISCO BCOS Pro版本 版本说明 FISCO BCOS 3.0支持Pro版本微服务区块链架构,Pro版本FISCO BCOS包含RPC服务.Gateway服务和节点服务,每个服务均可独立部署 ...
- spring boot 实现fisco bcos最基础案例
spring boot 实现fisco bcos最基础案例 一.基于国密搭建的4个节点联盟链 1.1 依赖文件 1.2 config.toml配置文件 1.3 用工具编译Helloworld.sol生 ...
- 联盟链中的Hyperledger Fabric、FISCO BCOS和CITA
本文援引自链接:https://mp.weixin.qq.com/s/4JAZGwI32bZNlxBqPfkihg 一.摘要 第 46 届世界经济论坛达沃斯年会将区块链与人工智能.自动驾驶等一并列入& ...
- 区块链学习路径,看这一篇就够了 | FISCO BCOS
FISCO BCOS开源社区已沉淀过百篇文章,覆盖了区块链学习各个阶段.为了方便大家对应自身学习阶段找到合适的教程,我们按照区块链学习成长路径对社区文章进行整理排序,希望沿着这份路径规划,大家都能成为 ...
- 开源架构Fabric、FISCO BCOS(以下简称“BCOS”)、CITA 技术对比
转自 https://www.coingogo.com/news/41300 联盟链技术哪家强?开源架构Fabric.FISCO BCOS(以下简称"BCOS").CITA 技术对 ...
- FISCO BCOS 联盟链Max搭建
FISCO BCOS Max版本 版本说明 为了能够支撑海量交易上链场景,v3.0.0推出了Max版本FISCO BCOS,Max版本FISCO BCOS旨在提供海量存储服务.高性能可扩展的执行模块. ...
- 一文说清FISCO BCOS性能压测(附实例教程)
"我的区块链能跑多少TPS?""能不能达到'官方'所说的峰值?""为啥总是压不上去?是我的机器不够好吗?" 如今,区块链技术被广泛应用在各行 ...
- Fabric、FISCO BCOS、以太坊对比
Fabric.FISCO BCOS.以太坊对比 一.以太坊 1.1 什么是工作量证明(POW) 1.2 这是如何运作的? 1.3 工作量证明的问题 1.4 股权证明 二.Fabric 2.1 产生背景 ...
- FISCO BCOS 区块链
FISCO BCOS是由国内企业主导研发.对外开源.安全可控的企业级金融联盟链底层平台,由金链盟开源工作组协作打造,并于2017年正式对外开源. 社区以开源链接多方,截止2020年5月,汇聚了超100 ...
最新文章
- 【C++】C++好书推荐
- 如何搭建一个 MySQL 分布式集群
- C++标准转换运算符static_cast
- 1792 关于数论中的互质数的最大不能组合数
- Flink SQL Client方言切换与datagen->Hive(DDL形式+streaming形式)
- vue-cli中的webpack的config配置详细说明
- Variable Assembly Language可变汇编语言
- matlab的try函数,matlab – 是否可以在没有try块的情况下测试函数句柄?
- android界面设计所用中文什么字体,「界面」手机界面设计字体大小知多少
- php怎么打印json数据,php输出json格式数据的例子
- python3爬虫-通过requests爬取图虫网
- Codeforces Round #499 (Div. 2): F. Mars rover(DFS)
- Java Web开发实战(二)—Tomcat安装及环境变量配置
- 美团Robust热修复工具使用记录
- matlab解线性方程组后结果是小数,MATLAB线性方程组求解
- 文件上传漏洞---Web渗透学习
- Mac 安装Photoshop遇到一系列问题解决方法
- C#上位机开发串口通信编程——倒计时器开发
- 三维目标检测算法汇总学习笔记
- delphi源码 中间件 框架【网盘映射】
热门文章
- CISCO路由器NAT-T与IPSec ×××配置实验【实践闯未来】
- 买车,给点建议和意见
- 梅花雨的日历控件在ASP.NET2.0下不可用的解决方法
- 男人在拥有女人之后!
- 林锐:5 C++/C程序的基本概念
- Python全栈开发——线程与进程的概念
- 案例5-条件查询商品
- 用C++完成三国杀(无GUI)
- 拓端tecdat|R语言和Stan,JAGS:用rstan,rjags建立贝叶斯多元线性回归预测选举数据
- 拓端tecdat|R语言如何找到患者数据中具有差异的指标?(PLS—DA分析)