• 该系统维护了一个重复的(replicated)有序的(ordered)transactions 的 log,这被称为账本(ledger)。
  • 维护这个 log 的系统的参与者们被称为节点(nodes)。这些节点运行着一个共识协议(RBFT)来同意 transactions 的排序。为了简单起见,我们可以假设这些节点中的一个会作为 leader(primary),它会决定 transactions 的排序然后将这个排序发送给其他的节点(followers)。
  • 每一次运行这个共识协议(会有3个阶段的提交)会要求一个批量 batch (集合 collection)的 transactions。
  • 节点维护着多个账本,每个账本都是为了一个不同的目的。它还有一个 pool 的账本,这被用来记录节点成员的 transactions,比如新增一个节点,暂停一个节点,变更一个节点的 IP/Port 或者密钥,对于 identity transactions 的账本,等等
  • 除了账本以外,节点还维护了 state(针对每个账本),这些 state 是一个 Merkle Patricia Trie。节点可能也会维护一些其他的关于账本的预测信息。关于存储的更多信息,请参考存储文档
  • 具有合适的权限的客户端可以向节点发送写入请求(transactions),不过任何的客户端都是可以向节点发送读取请求的。
  • 客户端到节点(client-to-node)和节点到节点(node-to-node)的沟通交流是在 CurveZMQ 上发生的。这个代码库有一个抽象概念叫做 Stack,它管理着这个沟通交流。它具有一些变量可以提供不同的功能。
  • 当接收到 transactions 之后,节点会进行一些基本的校验并且将这个请求广播给其他节点。这个被称为请求的传播(propagation),在 RBFT 文档中有更详细的信息。一旦节点发现已经有足够的节点得到了这个请求之后,他们会认为这个请求是可以被处理的了。主节点(primary node)会发起新一轮的共识,这个新的过程会经过3个阶段的提交流程,在流程的最后所有节点会将这个 transaction 添加到他们的账本和相关的存储中。在 RBFT 的文档中有关于三阶段提交流程的详细信息。不同类型的请求会更新不同的账本和存储层。可以在这里找到关于请求处理的详细的解释。
  • 在系统的生命周期中,节点可能会崩溃(crash)或者重启(restart),无法连接(disconnected)/重新连接(re-connected),新的节点也可能会加入这个网络。因此节点需要有一个机制来获得他们错过的或者从来没有收到过的(对于新的节点)的 transactions。他们通过一个叫做 catchup 的流程来实现这个目的。节点会找到他们自己的 state 并且学习其他的节点的 states,如果节点发现他们的信息是落后的话,他们会运行一个协议来获得错过的那些 transactions。可以从 catchup 文档中了解更多的信息。
  • 节点可以通过一个 MESSAGE_REQUEST 消息向其他的节点要求不同的协议指定(protocol-specific)的消息。
  • 当主节点(primary node)崩溃(或者因为其他的原因不能工作)的时候,或者它错误的发送一个坏消息(bad messages)或者它变得非常慢,这个时候 follower 节点会发起一个改变 leader 的协议,这个协议被称为 view change。View change 会选择一个新的 leader,这个会以一个 round robin 的形式并且相互沟通 state(如果需要的话还会有 catchup),所以在一个新的 leader 开始工作前,每个节点都具有相同的 state。
  • 这个共识环(三阶段提交)跟 RBFT paper 有一些不同的地方:
    1. RBFT 为每一个请求都描述了一个独特的三阶段提交,但是在 plenum 中,三阶段提交是发生在批量的请求上的,这会让它更有效率,因为三阶段的提交会涉及到 n 次方次的沟通(n 是节点的数量)。
    2. PRE-PREPARE 和 PREPARE 包含默克尔树的根(merkle tree roots)和 state 树的根,以此来确认每个执行这个批量的请求的节点拥有相同的账本和 state。
    3. PRE-PREPARE 包含了一个关于这个批处理的时间戳,follower 节点会检查验证这个时间戳,如果通过验证会接受并带有一个 PREPARE。对于每个 transaction 的时间戳是会被存储在账本中的。
    4. 三阶段提交也包含了一个签名聚合协议(signature aggregation protocal),所有的节点会将它们的签名提交到 state 树的根(root),这些签名会在节点间进行传播并存储。之后当一个客户端需要对 state 进行查询的话,客户端会得到一个基于 state value 和 signed(聚合的签名) root 的一个证明(proof)。这样客户端就不需要必须依赖于多个节点的 response 了。签名 schema 用的是 BLS
10-04 09:47