五个阶段:request,预准备(pre-prepare)、准备(prepare)、和确认(commit),reply
步骤:
1.从全网节点选举出一个主节点(Leader),新区块由主节点负责生成
2.Pre-Prepare:每个节点把客户端发来的交易向全网广播,主节点0将从网络收集到需放在新区块内的多个交易排序后存入列表,并将该列表向全网广播,扩散至123
3.Prepare:每个节点接收到交易列表后,根据排序模拟执行这些交易。所有交易执行完后,基于交易结果计算新区块的哈希摘要,并向全网广播,1->023,2->013,3因为宕机无法广播
4.Commit:如果一个节点收到的2f(f为可容忍的拜占庭节点数)个其它节点发来的摘要都和自己相等,就向全网广播一条commit消息
5.Reply:如果一个节点收到2f+1条commit消息,即可提交新区块及其交易到本地的区块链和状态数据库。
拜占庭容错能够容纳将近1/3的错误节点误差,IBM创建的Hyperledger 0.6版本就是使用了该算法作为共识算法(1.0版本已弃用,使用kafka)。
Fabric1.0采用共识算法为Solo、Kafka
1.Solo Orderer: The solo orderer is intended to be an extremely easy to deploy, non-production orderer. It consists of a single process which serves all clients, so no `consensus' is required as there is a single central authority. There is correspondingly no high availability or scalability. This makes solo ideal for development and testing, but not deployment. The Solo orderer depends on a backing orderer ledge
order-solo模式作为单节点通信模式,所有从peer收到的消息都在本节点进行排序与生成数据块,详细流程见下图:(用于开发模式下)
order-solo过程分析:Peer(客户端)通过GRPC发起通信,与Orderer连接成功之后,便可以向Orderer发送消息。Orderer通过Recv接口接收Peer发送过来的消息,Orderer将接收到的消息生成数据块,并将数据块存入ledger,peer通过deliver接口从orderer中的ledger获取数据块。
2.Kafka Orderer : The Kafka orderer leverages the Kafka pubsub system to perform the ordering, but wraps this in the familiar ab.proto definition so that the peer orderer client code does not to be written specifically for Kafka. In real world deployments, it would be expected that the Kafka proto service would bound locally in process, as Kafka has its own robust wire protocol. However, for testing or novel deployment scenarios, the Kafka orderer may be deployed as a network service. Kafka is anticipated to be the preferred choice production deployments which demand high throughput and high availability but do not require byzantine fault tolerance. The Kafka orderer does not utilize a backing orderer ledger because this is handled by the Kafka brokers.
Orderer-Kafka分析 (用于正式环境下)
Peer通过GRPC与orderer建立通信,连接成功以后,通过deliver接口发起获取数据请求。Orderer通过recv接口接收到数据获取请求,分析请求参数(SeekInfo_Start:1、SeekPosition_Oldest:从第一条数据块开始获取。2、SeekPosition_Newest:从最新一个数据块开始获取 3、SeekPosition_Specified:从指定数据块数获取)。Orderer从ledger中获取数据块迭代器入口,循环迭代器获取所有的数据块,每获取一个数据块同时就获取到的数据块返回给peer,知道所有数据块获取完,最后向peer返回获取成功状态。