CITA 共识

共识

CITA 的共识模块主要是保证多个节点对于交易的顺序和 Block 的内容达成一致。在众多的分布式算法中, 我们选择实现了非拜占庭容错的 Raft 算法和拜占庭容错的的 CITA-BFT 算法。

共识的架构

共识主要有 MQ(消息队列)通讯模块、交易池、定时模块、WAL(write ahead log)、算法逻辑模块。

   +-------------+       +-------------+       +-----+
   | MQ通讯模块   |<----->| 算法逻辑模块 |<----> | WAL |
   +-------------+       +-------------+       +-----+
          ^                ^    ^
          |                |    |
          |----------------+    |
          |                     |
     +--------+           +-----------+
     | 交易池  |           | 定时模块  |
     +--------+           +-----------+

MQ 通讯模块: CITA 的消息通过 MQ 进行周转,MQ 通讯模块负责订阅、发布基于 MQ 的消息。

交易池: 交易池订阅和存储交易信息,并提供交易的打包、生成 Block。还进行交易的持久化,实现快速确认的功能。

定时模块: 提供算法定时服务。使用者向定时模块发送定时请求,定时模块在时间到达后,发送确认信息。

WAL: WAL 提供预写日志(write ahead log)的服务,持久化各个节点的投票。用来进行节点崩溃后恢复。

算法逻辑模块: 分布式算法逻辑的实现模块,接受共识其它模块发送过来的信息,根据自身的算法要求,进行算法逻辑相应的处理。 例如对于 CITA-BFT 就需要进行一系列的状态转换。

基本前提

  • 每个共识节点知道其它共识节点的公钥
  • 每个共识节点发送的投票信息,都必须有自己的签名
  • 共识节点根据公钥和签名可以验证消息的真实性
  • 共识节点数量需要满足算法要求的基本数量

基本步骤

虽然分布式算法多种多样,具体落实在 CITA 中,基本上需要进行如下的步骤:

  • 共识模块从消息队列中订阅交易信息,放入交易池。如果应用有快速确认的需求,交易池可以对交易进行持久化。
  • 共识算法根据配置和算法要求,选择一个出块的节点。该出块节点把块的哈希值(Block.Hash)作为共识的主要信息通过 MQ 通讯模块向其它的节点进行广播。
  • 当出块节点进过一轮或者多轮投票,收到算法要求的法定多数的投票返回时,向 Chain 模块确认出块,否则进入重新选择出块节点的计算,由下一个出块节点继续出块。
  • 接收 Chain 返回的状态信息,作为出块成功的标志。
  • 出块成功后,从交易池删除已经达成共识的交易。

Raft 算法

Raft 作为非拜占庭容错的算法,主要是主节点出块。主节点有故障时,从节点会启动重新选主的流程,所以 Raft 的机制主要分为两部分:选主流程和 主节点同步信息流程。

选主流程:

  1. 每个节点发送提升请求给其他节点。
  2. 收到 1/2+的投票的节点,升为主节点。
  3. 如果有冲突,采用随机退避的方式,再次投票。

主节点同步信息:

  1. 主节点打包交易,出块,把块发送给从节点。
  2. 从节点收到后发送确认信息返回。
  3. 主节点收到 1/2+确认后,发送确认信息给从节点。
  4. 主节点持久化和发送 Block 到 Chain 进行计算。

CITA-BFT 算法

CITA-BFT 是一种专为区块链设计的高性能共识算法,基于半同步网络假设,CITA-BFT 在保证活性和安全性(Liveness & Safety)的前提下能够容忍 1/3 的拜占庭节点。 CITA 共识节点通过点对点共识消息交换协议对每一个区块交换投票信息,迅速形成多数共识。投票结果最后会被记录在区块里。CITA 支持独有的低延迟技术,能够实现 毫秒级交易确认延迟。

CITA-BFT 状态转换

CITA-BFT 是一种状态机副本复制算法(State Machine Replication),在实现上包括以下几个状态:

    NewHeight -> (Propose -> Prevote -> Precommit)+ -> Commit -> NewHeight -> ...


                            +-------------------------------------+
                            v                                     |(Wait til `CommmitTime+timeoutCommit`)
                      +-----------+                         +-----+-----+
         +----------> |  Propose  +--------------+          | NewHeight |
         |            +-----------+              |          +-----------+
         |                                       |                ^
         |(Else, after timeoutPrecommit)         v                |
   +-----+-----+                           +-----------+          |
   | Precommit |  <------------------------+  Prevote  |          |
   +-----+-----+                           +-----------+          |
         |(When +2/3 Precommits for block found)                  |
         v                                                        |
   +--------------------------------------------------------------------+
   |  Commit                                                            |
   |                                                                    |
   |  * Set CommitTime = now;                                           |
   |  * Wait for block, then stage/save/commit block;                   |
   +--------------------------------------------------------------------+

CITA-BFT 是随着块的高度增长,多种状态的依次循环的过程。在决定某个高度的块的过程中,可能需要一轮或者多轮的投票。 下面介绍 CITA-BFT 在块高度 H 和第 R 轮上,进行块的共识的主要流程:

  1. proposal 阶段:proposal 节点打包交易池中的交易,WAL 记录后,通过 MQ 通讯模块,发送 proposal 消息给共识的其它节点,然后进入 prevote 阶段。而非 proposal 节点在进行一段时间的超时后,进入 prevote 投票阶段。
  2. prevote 阶段:每个共识节点根据收到的 proposal 信息,进行 prevote 投票。校验成功则 prevote block.hash,校验失败或者没有收到 proposal 信息则 prevote 空票。
  3. prevote 等待阶段:等待节点收到 2/3 节点以上的 prevote 投票,在必要的超时后,进入 precommit 阶段。
  4. precommit 阶段:节点根据 prevote 阶段收到的投票进行判断,如果收到相同 block.hash 的 prevote 投票,超过 2/3,则 precommit block.hash,否则 precommit 空值
  5. precommit 等待阶段:等待收到的 precommit 投票数超过节点数的 2/3。如果收到 precommit 相同 block.hash 投票超过 2/3 时,进入 commit 阶段。否则进入新一轮的 proposal 的阶段。
  6. commit 阶段:共识模块把共识完成的 block 发送给 chain 模块后,等待 chain 模块的计算完成后发送的状态信息,然后进入下一个高度 NewHeight。

CITA-BFT 交易池操作流程

  1. 交易池启动时,尝试从 KV 数据库恢复数据
  2. 交易池订阅 MQ 的交易信息
  3. 交易池收到交易后,持久化到 KV 数据库
  4. 交易池收到打包请求,检查交易的有效性,输出有效交易列表
  5. 交易池根据出块的交易列表,删除已经上链的交易

CITA-BFT 故障重启流程

  1. 从 WAL 模块中,恢复某个块高度的投票信息
  2. 根据恢复后的状态信息,重复投票信息
  3. 进程根据当前状态,继续运行

你可能感兴趣的:(区块链,互联网与区块链)