---
title: 领导者轮换
---

在任何时候，集群都只需要一个验证节点来生成账本条目。 由于每次只有一个领导者，所有验证节点都能够重复相同的账本副本。 然而，一次只有一名领导者的缺点是，恶意领导者可能会审查选票和交易。 由于审查无法同网络丢弃数据包区分开，因此集群不能简单地选择某一个节点来长期担任领导者角色。 相反，集群通过轮换来决定哪个节点担任领导者，从而最大限度减少恶意领导者的影响。

每个验证节点使用下文描述的同一种算法来选择预期的领导者。 当验证节点收到一个新的签名账本条目时，可以肯定某条目是来自预期的领导者。 分配给每位领导者的插槽顺序称为 _leader schedule（领导者安排表）_。

## 领导者轮换计划

一个验证节点会拒绝未经过 _插槽领导者_ 签名的区块。 所有插槽领导者的身份列表称为 _领导者安排表_。 领导者安排表是通过本地定期重新计算产生的。 它指派插槽领导者持续一段称为 _epoch（纪元）_ 的时间。 安排表必须早于它分配的时间段， 这样它保证了计算计划的账本状态最后能够确定。 该持续时间称为 _领导者安排表偏移时间_。 Solana 将偏移时间设置为直到下一个 epoch 的插槽持续时间。 也就是说，一个 epoch 的领导者计划通过上一个 epoch 开始时的账本状态来计算得到。 一个纪元的偏移量是比较随意的，并且假定时间足够长，使所有验证节点都将在生成下一个计划之前确定其账本状态。 集群可以选择缩短偏移时间，来缩短质押变化与领导者计划更新之间的时间。

在没有分区的情况下运行时间比一个 epoch 长的时候，只有在根分叉的 epoch 边界才能生成安排表。 由于安排表用于下一个纪元，因此在下一个纪元之前，任何质押给根分叉的新质押都不会被激活。 用于生成领导者计划的区块是跨过纪元边界的第一个区块。

如果分区比一个 epoch 时间短，集群将按以下方式运作：

1. 验证节点在投票时不断更新自己的根分叉。
2. 每次在纪元边缘的插槽高度的时候，验证节点将更新其领导者安排表。

例如：

Epoch 持续时间为 100 个插槽。 根分叉从在插槽高度 99 处计算的分叉更新为在插槽高度 102 处计算出来的。 由于故障，跳过了插槽高度分别为 100、101 的分叉。 新的领导者计划通过分叉在高度为 102 的位置计算出来。 在插槽 200 中它处于活动状态，直到再次更新。

不会存在共识不一致的情况，因为当群集的根节点通过 102 时，对群集进行投票的每个验证节点都跳过了 100 和 101。 无论采用哪种投票方式，所有验证节点都将提交为 102 或 102 后代的根。

### 带有纪元分区的领导者轮换计划。

领导者安排表偏移的持续时间与群集对正确的领导者安排表不一致的可能性有直接关系。

考虑以下几种假设情况：

两个分区正在生成每个区块的一半。 但它们两个都不是最终的大多数分叉。 两者都将跨过纪元 100 和 200，而实际上并没有形成一个根，因此将在整个集群范围内承诺一个新的领导者安排表。

在这种不稳定的情况下，存在多个有效的领导者计划。

- 这时候，系统将为直系父级在上一个纪元的每个分叉生成一个领导者安排表。
- 领导者安排表在后代分叉的下一个纪元开始后才有效，直到更新为止。

每个分区的日程表将在一个分区持续超过一个纪元之后发生变化。 因此，纪元持续时间应当设置为远大于插槽时间和分叉提交到根的预期长度。

在观察集群足够长的时间后，可以根据中位数分区持续时间及其标准偏差来选择领导者安排表偏移量。 例如，偏移量长于中位数分区持续时间再加上六个标准偏差，则可以将群集中账本计划不一致的可能性降低到百万分之一。

## 生产创世领导者安排表

创世配置声明第一个纪元的第一个领导者。 该领导者计划在前两个纪元结束，因为领导者计划也在下一个时期的插槽 0 中生成。 前两个纪元的长度也可以在创世配置中指定。 前几个纪元的最小长度必须大于或等于 [Tower BFT](../implemented-proposals/tower-bft.md) 中定义的最大回滚深度。

## 创世领导者安排表算法

领导者时间表通过预定义的种子生成。 过程如下：

1. 定期使用 PoH 滴答高度 \(单调递增的计数器\) 产生稳定的伪随机算法种子。
2. 在该高度下，对银行中所有具有领导者身份且已在集群配置的滴答中进行投票的抵押帐户进行抽样。 该示例被称为 _活动集合（activate set）_。
3. 按质押权重对活动集进行排序。
4. 使用随机种子选择按质押加权的节点，来创建质押加权排序。
5. 在群集配置的一定滴答后，该排序开始生效。

## 安排表攻击矢量

### 种子

所选择的种子是可预测的，但是不存在偏差。 没有任何可怕的攻击会影响其结果。

### 活动集

领导者可以通过审查验证人的投票来使活动集偏差。 领导者可能通过两种方式来审查活动集：

- 忽略验证节点的投票
- 拒绝使用验证节点的票对区块进行投票

为了减少审查的可能性，在_活动集采样期间_，网络将在领导者安排表偏移量边界上计算活动集。 有效设置的采样持续时间足够长，从而让多个领导者收集到投票。

### 质押

领导者可以审查新的质押交易，或拒绝验证有新质押的区块。 这种攻击类似于对验证节点选票的审查。

### 验证节点操作密钥丢失

领导者和验证节点应使用临时密钥进行操作，而质押所有者授权验证节点通过委托来处理其质押。

群集应该能够能通过领导者和验证者丢失的所有临时密钥进行恢复，这可能是所有节点共享出现的常见软件漏洞。 质押所有人应该能够通过共同签署验证节点的投票直接进行表决，即使质押已经委托给验证节点。

## 追加条目

领导者时间表的生命周期称为一个 _纪元（epoch）_。 纪元又划分为多个 _插槽_，每个插槽的持续时间 `T` 称为 PoH 滴答时间。

领导者在其插槽期间发送条目。 在 `T` 滴答时间后，所有验证节点都将切换到下一个预定的领导者。 验证节点必须忽略在领导者指定的插槽之外发送的条目。

下一位领导者必须观察所有的 `T` 滴答，以便其建立自己的条目。 如果没有观察到条目\(领导者掉线\) 或条目无效 \(领导者故障或作恶\)， 则下一个领导者必须滴答来填充前一个领导者的插槽。 请注意，下一位领导者应并行执行维修请求，并推迟发送滴答，直到确信其他验证节点也没有观察到上一位领导者的条目。 如果领导者错误地产生自己的滴答，那么跟随它的领导者必须替换其所有滴答。
