IBFT 共识算法

1. 概述

PlatONE 中的共识为高度优化的BFT类共识算法,其容错率为1/3,在保留即时确认(instant finality)的关键特性的同时,极大地提高了去中心化的程度。共识可以保证上链的区块是确定的,也就是说链不会出现分叉,同时每一个有效的区块都会插入到链上。

PlatONE 的共识支持超过100个共识节点。相对于其他一些常见的BFT共识,PlatONE 的共识的性能有显著的提升。在10个共识节点的情况下,TPS 接近 1000。

PlatONE 的共识运行的相关参数可以灵活地进行配置,并且 PlatONE 的共识中的共识节点集合可以灵活地进行更新。近期计划支持共识的插件化,以及共识的可审计性等。

PlatONE 共识是在 round 上进行的。在特定的 round 上,通过预先设置的策略选取一个出块者节点。出块者节点的选取策略目前支持两种:round robin 和 sticky proposer。

出块者节点提议区块后,各共识节点进行共识。共识分三阶段,其中后两个阶段为投票阶段,用以保证 Safety。PlatONE 共识使用 round change 机制结合锁定和解锁机制来保证共识的的 liveness 。通过优化解锁机制,解决了业界多个知名项目内存在的共识死锁问题。

PlatONE 共识会为每一个链上的区块生成共识证明,也就是对于该区块的各共识节点的有效签名,因而区块可以进行自验证,同时也能支持轻节点。

区块中如果不包含交易,则称为空区块。PlatONE 目前支持不出空区块,也就是上链的区块中都含有交易。不出空区块的机制可以有效地节省区块链占用的存储空间。

以下具体介绍 PlatONE 中的共识算法。

2. 共识节点选取机制

节点分为共识节点(validator)和观察员节点两种类型。对于共识节点来说,存在两种状态:正常和隔离。只有处于正常状态的共识节点才可以参与共识和打包区块。

节点管理(NodeManager)系统合约设计用于存储和管理节点信息。可以通过节点申请(NodeRegister)系统合约申请注册共识节点,审核通过后,申请节点的类型会更新为共识节点,更新后的节点信息存储在节点管理合约中,并且可被查询。

管理员可以根据需要更新共识节点的状态,来决定共识节点是否可以参加共识。

链上每次产生新区块后,节点管理合约中最新的节点信息都会被读取,并且最新的共识节点集合会被保存下来,并被共识引擎读取和使用。

3. 共识流程

3.1. 正常流程

3.1.1. 定义

以下是一些重要术语或概念的定义。

3.1.2. 选取proposer的规则

3.1.3. 共识流程(三阶段协议)

共识流程由三个阶段组成:PRE-PREPARE, PREPARECOMMIT,也称为三阶段协议。

以上三阶段完成后,整个共识流程就成功完成了。

3.1.4. 状态迁移:

下图描述了PlatONE的共识流程的状态迁移过程。

State transition diagram

3.2. Round change 机制

以下三种条件都会触发ROUND CHANGE:

3.2.1. round change 的流程

3.3. 区块锁定机制

节点锁定在区块Bround number R 的含义是指,当前节点只能对区块B的信息投commit票 。当一个节点收到了+2/3个对区块BPREPARE投票后,进入PREPARED状态。此时,节点被锁定,等待接收其他节点的commit投票信息,锁定的round即当前round;

除了共识起始阶段,当收到更高区块的同步数据时,或当前高度成功产生区块并达成共识时,锁定被状态重置为非锁定状态,并开始新一轮对更高区块共识。如未能在锁定期间收到+2/3个指定round和区块的commit投票,则触发ROUND CHANGE。并且,在特定场景下,原有锁定解锁机制还会出现死锁的情况,我们在代码层面也优化了相关的解锁实现。具体可参考「2. 对Istanbul锁定解锁机制的优化」。

3.4. Consensus proof 目前的存储机制

区块上链前,每个validator节点需要收集2F + 1个committed seal以构成一个consensus proof(共识证明)。一旦validator节点接收到足够的committed seal,就会将其存储于区块头的extraData字段中IstabulExtra结构中CommittedSeal 字段中,并重新计算extraData字段,然后将区块插入到区块链中。

Committed seal计算过程如下:

每个validator节点使用其私钥对区块哈希级联上commit消息代码COMMIT_MSG_CODE的结果进行签名,得到签名即为Committed seal:

  type IstanbulExtra struct {
  Validators    []common.Address    //Validator addresses
  Seal          []byte          //Proposer seal 65 bytes
  CommittedSeal [][]byte            //Committed seal, 65 * len(Validators) bytes
  }
其中,各字段的含义如下: + Validators:参与共识的各validator节点的列表 + Seal:Proposer 节点对区块的签名,长度为65字节 + CommittedSeal:用于存储validator节点收集到的committed seal列表