目标
- 共识算法的实现目的
- 共识算法的分类
- Hyperledger Fabric所使用的共识算法
任务实现
7.1.1 概述
在区块链网络中,不同的参与者发起的交易必须按照产生的顺序被依次写入到账本中。交易如何在分布式场景下, 所有节点对同一个提案或值达成一致性,是区块链技术中必须考虑并加以解决的一个问题。要实现这一目标,交易顺序必须被正确的建立,并且必须包含对交易被篡改或者恶意提交交易的处理方法。
通常,共识算法就是保证分布式系统一致性实现的解决方式,共识算法是计算机科学中用于在分布式过程或系统之间实现对单个数据值的一致性的过程。共识算法旨在实现涉及在网络中多个不可靠节点的可靠性。解决该问题(称为共识问题)在分布式计算和多代理系统中非常重要。
7.1.2 共识算法类型
7.1.2.1 共识属性
共识算法必须满足两个属性,以保证节点之间的一致性, 这两个属性分别是:安全性和活跃性。
- **安全性:**表示每个节点保证相同的输入序列,并在每个节点上产生相同的输出结果。当节点收到相同的一系列交易时,每个节点上将发生相同的状态更改。该算法必须与单个节点系统的执行结果相同。
- **活跃性:**在通信正常的情况下,每个非故障节点最终都能接收每个提交的交易。
7.1.2.2 共识算法类型
共识算法可以以不同的方式实现,一般有如下两种类型:
- **基于彩票的算法(Lottery-based Algorithms),**包括消耗时间证明(Proof of Elapsed Time,PoET)和工作量证明(Proof of Work,PoW)算法。基于彩票的算法的优势在于它们可以扩展到一个大的数字,由网络中任意一个节点生成一个区块,并将其传递给网络中的其它节点加以验证。另一方面,这些算法可能导致分叉,当两个“赢家”同时各广播一个新产生的区块时,会产生分支,每一个分支都必须被解析,这导致使用很长时间来确认终结。
- **基于投票的方法(Voting-based Methods),**包括冗余的拜占庭容错(Redundant Byzantine Fault Tolerance,RBFT)和 Paxos(基于消息传递的一致性算法)。每一种方法都针对不同的网络需求容错模型。基于投票的算法的优势在于它们提供了低延迟的终结性。当大多数节点验证事务或块时,就存在共识和终结性发生。因为基于投票的算法通常需要节点来对网络上的每个节点传输消息,所以网络上存在的节点越多,达成共识的时间越长。这导致了可伸缩性之间的权衡和速度, 不能满足高并发、快速交易(低延迟)的需求场景。
下表介绍了两种共识算法类型的比较:
基于彩票的算法 | 基于投票的方法 | |
---|---|---|
速度 | 较好 | 较好 |
可扩展性 | 较好 | 中等 |
确定性 | 中等 | 较好 |
因为区块链中的业务需求会有所不同,所以 Hyperledger 社区研究几种不同的一致性共识机制并进行实施以确保模块化实现。Hyperledger 团队开发人员为了提高资源使用及时间效率, 在 Hyperledger 项目开发前做出评估,将区块链业务指定在部分信任的网络环境中运行。所以,Hyperledger 网络环境中不支持匿名访问者的标准工作共识证明方法(Pow共识算法)。
目前,Hyperledger 中各框架项目所使用的共识算法如下:
- Hyperledger Fabric 中使用了基于 Zookeeper(分布式服务框架)的 Apache Kafka(分布式消息系统)。
- Hyperledger Indy 中使用了基于投票的方法 RBFT(Redundant Byzantine Fault Tolerance,冗余拜占庭容错算法)。
- Hyperledger Iroha 中使用了一种基于投票的方法(Sumeragi)来达成共识故障容错。
- Hyperledger Sawtooth 中使用了基于彩票的 PoET 算法以拖延为代价实现共识。
7.1.3 Hyperledger Fabric中的共识实现
不同的 Hyperledger 框架可以选择不同的方式实现共识。Hyperledger 区块链框架业务通过执行两个框架达成单独的共识过程:
- Ordering of transactions (交易排序)
- Validating Transactions(交易验证)
为了确保任何 Hyperledger 框架可以应用于任何的 Hyperledger 共识模块,通过逻辑分离这两个共识实现过程。Hyperledger Fabric 网络中的共识被分解为三个阶段:背书阶段、排序阶段和验证阶段。
-
背书阶段:签名必须由参与者的背书策略确定。
客户端应用程序将交易请求打包成为交易提案(Proposal)后,根据背书策略(Endorse Policy)发达给指定的背书节点(Endorse Peer)。背书节点接收到交易提案后调用链码(Chaincode)执行,但此执行过程是模拟执行,并不会将数据记录到账本中。执行完成后调用交易背书系统链码(Endorsement System Chaincode,ESCC)对执行结果进行签名,然后响应给客户端应用程序。Ordering Service 可以以不同的方式实现:开发和测试阶段可以使用集中式排序服务(中心化),针对不同网络的分布式协议节点故障模型。为了保证交易的机密性,Ordering Service 不能看到交易中的具体内容(不参与对交易内容的任何处理),也就是说,交易内容可以使用哈希散列或加密方式去处理。
-
排序阶段:接受提交的被认可的交易并进行排序,确保交易顺序的一致性。
排序阶段通过 Ordering 服务提供的接口接收到已经背书的交易,Ordering Service 根据共识算法配置策略(根据指定的配置信息中定义时间限制或指定允许的交易数量),确定交易的顺序和交易数量。然后将交易打包到区块中进行广播。大多数时候,由于为了提高系统效率的原因,Ordering 服务将多个交易分组到一个区块中,而不是将单个交易输出成为一个区块。
-
验证阶段:获取有序事务块并验证其结果的正确性,包括检查背书策略和重复提交攻击。
Peer 节点接收到广播的区块后,进行保存之前的最终检查验证,验证通过后将该区块保存在区块链中。为了校验交易的正确性,共识的建立依赖于智能合约层(Hyperledger Fabric 中的 Chaincode),智能合约层定义了商业逻辑来如何验证交易的有效性。智能合约层根据特定的策略与约定来确认每一笔交易都是有效的。无效的交易会被拒绝,并在块中剔除。潜在的校验失败主要分为以下两种:
-
语法错误:包含以下几种类型,比如无效输入、未验证的签名、重复的交易等,这类交易应该被丢弃。
-
逻辑错误:此类错误更为复杂,应该需要定义策略决定是继续处理还是终止执行。如,导致重复交易或版本控制的交易。如果策略需要,我们可能需要日志记录这些交易以进行审计。
-
Hyperledger Fabric 应用程序可以根据不同的交易背书、排序和验证模型要求,实现支持对3个阶段的可拔插共识服务,特别是 Ordering 服务 API 允许插入基于 BFT 的协议算法。Orderer 节点通过gRPC服务提供两个 API 接口:广播(broadcase)和交付(deliver)。
-
**broadcast(blob):**客户端调用此函数在通道中广播任意的消息blob(客户端向排序服务发送交易请求)。在BFT中,给服务发送一个请求时,又称为 request(blob)。
-
**deliver(seqno,prevhash,blob):**Ordering 服务调用此函数给 Peer 节点发送blob消息,包含非负整数的序列号 seqno 和最近一次消息的哈希 prevhash 。换句话说,它是共识服务的输出接口。deliver()在发布/订阅系统中称为notify(),在BFT系统中称为commit()。
注意共识服务客户端(即 Peer 节点)只通过broadcast()和deliver()事件和服务进行交互。
在 Hyperledger Fabric 框架项目的正式版本中支持两种共识算法类型:
- **Solo:**单节点共识,整个Fabric网络只有一个 Orderer 节点(Fabric网络默认)。主要用于测试模式。
- **Kafka:**分布式消息队列,整个Fabric网络的共识由 Kafka 集群实现(实际上Kafka实现了对于Hyperledger Fabric网络中所有的交易请求进行排序服务)。具体实现方式请参见下一节内容。
目前,Hyperledger 项目团队正在开发其它 Ordering 共识插件,包括BFT Smart,简化拜占庭容错算法(Simplified Byzantine Fault Tolerance,SBFT),蜜獾拜占庭容错算法(Honey Badger of BFT)等。
FAQ
-
已经启动了 Orderer 服务,然后想使用其它一致性算法,如何实现?
在 Hyperledger Fabric 中不支持此种操作方式。
-
现在可以在 Hyperledger Fabric 中使用拜占庭容错算法 吗?
不可以,目前在 Fabric 发布的标准版本中只能使用 Solo 与 Kafka 实现共识,其它共识插件处于开发状态中,在哪个正式版本中发布官方并没有确定。