#engine #consensus #clique #block #state #vapory #defined

vapcore-clique

Vapory风格的Clique共识引擎

显示包…

2个不稳定版本

0.1.0 2021年3月8日
0.0.0 2021年3月7日

#28 in #vapory


10个包中使用(通过vapcore-spec

GPL-3.0许可证

2.5MB
12K SLoC

vapcore-clique

Clique PoA引擎的实现。

文件结构

  • mod.rs -> 提供引擎API实现,带有额外的区块状态跟踪
  • block_state.rs -> 记录特定区块的Clique状态。
  • params.rs -> 包含Clique引擎的参数。
  • step_service.rs -> 一个事件循环来触发密封。
  • util.rs -> 各种独立实用函数。
  • tests.rs -> 根据EIP-225定义的共识测试。

同步工作原理

  1. 客户端将调用
    • Clique::verify_block_basic()
    • Clique::verify_block_unordered()
    • Clique::verify_block_family()
  2. 使用 Clique::state() 尝试检索父状态。如果未找到,则需要从最后一个已知检查点回填。
  3. 一旦我们有一个良好的状态,我们可以使用 CliqueBlockState::apply() 记录它。

密封工作原理

  1. 使用 Engine::set_signer() 设置签名者。如果通过配置文件或CLI标志设置了矿工账户,则最终将通过 MinerService::set_author() 设置签名者
  2. 我们通过 Clique::sealing_state() 检查引擎是否已准备好密封。注意:对于Clique来说,这始终是 SealingState::Ready
  3. 调用 Clique::new() 将创建一个 StepService 线程。此线程将定期调用 Engine::step()。在内部,Clique 的 step() 函数调用 Client::update_sealing(),这是创建和密封区块的过程。
  4. Clique::generate_seal() 将被 miner 调用。这将返回一个 Seal 对象,它可以是 Seal::NoneSeal:Regular。以下是如何选择 Seal 变体的示例:a. 如果没有签名者或签名者未授权,则返回 Seal::None。b. 如果周期 == 0 且区块中有交易,则返回 Seal::Regular,否则返回 Seal::None。c. 如果我们处于 INTURN 状态,则在尝试密封之前至少等待上一个区块的 period。d. 如果我们不是 INTURN 状态,我们将使用 EIP-225 中指定的算法等待一个随机的时间量,然后再尝试密封。
  5. 矿工将创建新的区块,在此过程中将调用多个引擎方法来完成以下操作:a. Clique::open_block_header_timestamp() 必须正确设置时间戳。b. Clique::populate_from_parent() 必须设置正确的难度值。注意:Clique::populate_from_parent() 在同步和密封代码路径中都会使用。
  6. 我们调用 Clique::on_seal_block(),这将允许我们在密封生成过程中修改区块头。
  7. 最后,调用 Clique::verify_local_seal()。之后,将遵循同步代码路径以导入新的区块。

依赖项

~26MB
~405K SLoC