Conflux 共识层的设计与实现
Conflux 的共识层处理从同步层接收到的所有区块,根据 Conflux GHAST 共识算法产生区块的完整顺序,并调用底层的交易执行引擎以按确定的顺序运行交易。 它提供了必要的信息,以协助 区块生成器 准备新区块的骨架。 它还通知 交易池(transaction pool) 已处理好的交易,以便交易池可以做出更好的交易选择决策。
本文档旨在为想要了解 Conflux 共识层(位于目录core/src/consensus中)的 Rust 实现的读者提供高级概述。 对于更多的实现细节,请查看代码中的内联注释。 对于 Conflux 共识算法的更多信息,请参阅 Conflux 协议规范和 Conflux 论文(https://arxiv.org/abs/1805.03870)。
设计目标
共识层有以下设计目标。
-
在后台按照一致的共识算法处理新的区块
-
我们希望最小化共识图中每个块的内存使用。 即使有检查点机制,在正常情况下图中会包含 300K-500K 个块,在面对存活性攻击时可能会超过 1M 个块。 这可能会给内存带来压力。
-
我们想要快速处理每个区块。 因为全节点/归档节点在从零开始同步网络时必须处理从_初始创世区块_开始的之后每一个区块,因此快速处理区块对于缩短所需时间是非常重要的。
-
面对潜在攻击时具有稳健性。 恶意攻击者可能会在TreeGraph的任意位置生成恶意区块。
结构与组成部分。
共识图(ConsensusGraph)
ConsensusGraph
(core/src/consensus/mod.rs)是共识层的主要结构体。 同步层通过一个存储所有区块元数据信息的 BlockDataManager
来构建 ConsensusGraph
。
ConsensusGraph::on_new_block()
是将新区 块发送给 ConsensusGraph
结构体进行处理的关键函数。 它还提供了一组公共函数,用于查询区块/交易的状态。 这应该是其他组件与之交互的主要接口。
共识图核心(ConsensusGraphInner)
ConsensusGraphInner
(core/src/consensus/consensus_inner/mod.rs)是 ConsensusGraph
的内部结构。 ConsensusGraph::on_new_block()
在函数开始时会获取内部结构的写入锁。 其余的查询函数只会获取读锁。
ConsensusGraphInner
的内部结构相当复杂。
一般来说,它维护两种类型的信息。 第一种信息是整个TreeGraph的状态,即当前的_pivot chain_、timer chain、_difficulty_等等。 第二种信息是每个区块的状态(即每个区块的ConsensusGraphNode
结构)。
Each block corresponds to a ConsensusGraphNode
struct for its information.
When it first enters ConsensusGraphInner
, it will be inserted into
ConsensusGraphInner::arena : Slab<ConsensusGraphNode>
. The index in the
slab will become the arena index of the block in ConsensusGraphInner
. We use
the arena index to represent a block internally instead of H256
because it is
much cheaper. We will refer back to the fields in ConsensusGraphInner
and
ConsensusGraphNode
when we talk about algorithm mechanism and their
implementations.