ZooBC 维基
参与证明 (PoP)

分叉选择与累计难度

有时,两个版本的链会竞争一段时间,例如当网络分裂几分钟时。此时每个 ZooBC 节点都跟随累计难度更大的分支:累计难度是区块权重的累加总和,其中由靠前被抽中的出块者产出的区块,比靠后被抽中者产出的区块权重更高。这条规则在每个节点上都是相同的算术,因此网络无需任何人挑选赢家就能收敛。

更重,而不是更长

每个区块都向累加总和加上一个值,其出块者在该高度抽签中的顺位越靠后,这个值就越小。最简单的形式是,一个区块加上 1,000,000 除以出块者在抽签中的名次:第一个被抽中的出块者产出的区块加 1,000,000,第三个被抽中的出块者产出的区块约加 333,333。

因此,一条由准时区块组成的链会胜过一条出块者不断错过轮次的链,即使后者更长。三个第一轮区块的权重为 3,000,000;四个第三轮区块的权重约为 1,333,332。

一次分叉:上方分支有三个 1,000,000 的区块(共 3,000,000),下方分支有四个 333,333 的区块(共 1,333,332)。天平倒向上方分支:更重者胜出,而不是更长者。
一次分叉:上方分支有三个 1,000,000 的区块(共 3,000,000),下方分支有四个 333,333 的区块(共 1,333,332)。天平倒向上方分支:更重者胜出,而不是更长者。

其他做法都行不通。按交易数量计算会让出块者往区块里填充交易来取胜。“先看到”因网络延迟而因节点而异,节点可能永远分裂下去。也没有任何权威机构把某个分支标记为正式分支。

区块的确切权重

从 0.5.8 版本起,一个区块的增量为:

increment = floor(1,000,000 × |S| / (k × |A|))
  • S 是前一个区块处的抽签集合:活跃节点减去被暂停的节点。
  • A 是前一个区块处完整的活跃注册表。比例 |S| / |A| 永远不会大于 1。
  • k 统计截至该区块所在轮次、直到出块者最后一次出现为止的抽签次数:第一个被抽中并准时盖上时间戳的出块者为 1,由第三次抽签指定的出块者为 3。(如果在这些轮次中找不到该出块者,则使用它在 2 × n 次抽签内首次出现的位置(n 为抽签集合中的节点数),再找不到则使用按哈希顺序得出的位置。)

有两条下限规则防止区块索取超过其应得的权重。k 永远不小于该区块时间戳所落入的轮次,因此迟到的时间戳无法保留较早轮次的权重(见 轮次、时间与窗口)。对于前一个区块的出块者,k 永远不小于其被降级后的轮次,即 10(见 优先轮次、空区块与前一个出块者)。

抽签集合所占的比例在网络分裂时很重要。如果分裂的每一方都暂停自己联系不上的节点,那么若没有这一比例,双方每个准时区块都会增加 1,000,000,看起来同样重。有了这一比例,以 11 个席位中的 3 个运行的一方每个区块最多增加 272,727,而拥有 8 个席位的一方增加 727,272。逐块比较,持有更多席位的一方更重。

增量公式在 |S| = 8、|A| = 11、k = 1 时得到 727,272;对于一条分裂的 11 节点链,拥有 8 个席位的一方每个区块增加 727,272,拥有 3 个席位的一方增加 272,727。
增量公式在 |S| = 8、|A| = 11、k = 1 时得到 727,272;对于一条分裂的 11 节点链,拥有 8 个席位的一方每个区块增加 727,272,拥有 3 个席位的一方增加 272,727。

每个区块都以十进制字符串的形式携带其累计难度。每个验证者都会重新计算它,并拒绝填写错误的区块。比较两个总和时,先比较长度,再逐位比较。

参与分数在这一切中都不起作用:权重读取的是抽签位次和抽签集合,而不是分数。

完全平局

完全平局确实会发生,例如两条长度相同的分支都由准时的第一轮区块组成。从 0.5.8 版本起,两个分支的链顶区块哈希按字节比较,哈希较小者胜出。若权重相等的分支其链顶哈希小于自己的,节点就切换过去,否则保留自己的分支,并且不询问任何人。每个节点都对同样的两个哈希做同样的比较,因此整个网络会立即收敛。

切换之前先衡量分支

对等节点声称其分支更重,这本身证明不了任何事。节点在动自己的链之前,会先衡量竞争分支:

  1. 找到两条链共有的最后一个区块。
  2. 分页获取该区块之后的分支,检查每个区块头的签名以及区块之间的链接。
  3. 重新计算每个区块的权重,从共同区块起重放该分支自身的注册表和暂停情况,因为在分裂的另一侧,它们可能有所不同。
  4. 一旦该分支比自己的链更重就停止,然后才回滚并应用该分支。最终更轻、或未能在有限数量的区块内反超的分支会被拒绝,不回滚任何内容。

声称的难度与重新计算的值不符的对等节点,会被记录为撒了谎。

回滚有硬性上限:在 mainnet 上永远不超过 720 个区块(3 小时),并且永远不低于在脊链上联署的最后一个检查点。见 最终性与回滚。

落后的节点与对等节点询问

如果节点的链顶已是 7,200 秒(2 小时)以前的区块,它不会信任任何声称领先的对等节点:它跟随一组已注册对等节点样本中至少三分之二所报告的链顶。节点可能进行的其他对等节点询问,例如确认更重的分支或检查自身健康状况,属于本地策略,而非共识。

另见