编者注:北京时间 2020 年 8 月 20 日晚上,Medalla 测试网从肇始于 8 月 15 日的网络动荡中恢复,重新获得终局性。但我们的探究,还不能止步。第三份材料,来自 Lighthouse 客户端团队的常规更新日志。在这份日志中,Lighthouse 团队含蓄地承认,在网络动荡期间,因为网络长期无法获得终局性,Lighthouse 客户端出现了内存占用过高的问题。

Lighthouse 更新 #28(节选)

(……)

Medalla 测试网

在上次更新之后,Medalla 公开多客户端测试网已经启动。已有超过 20,000 个验证者和至少 5 个不同的客户端实现在上面运行。测试网启动初期比较艰难,因为大量质押者在创始期间掉线。这就导致参与率低于预期。很快,许多质押者加入,测试网开始获得终局性,且运行得相当顺利。在过去几周时间里,我们有机会在这个测试网上进行了大量的客户端互操作性测试和性能调整。

见证消息的打包

在 Medalla 测试网上,我们观察到的主要问题之一是见证消息被打包的比率。每个验证者必须在每个时段(epoch)内产生一条见证消息。这些见证消息将被打包进未来的区块中,而一旦被打包,与该见证消息关联的验证者就会得到奖励。虽然在一个只有 lighthouse 客户端的 Medalla 测试网中,我们看到了 100% 的见证消息打包率(即所有产生的见证消息都被打包进了区块中),但是一些见证消息被跳过了(没有被打包进未来的第一个区块中)。想要解决这一问题绝非易事,因为这个过程有点复杂,且听我细细道来。在每个时段内,验证者都会被分成不同的委员会。

委员会中的每个验证者都必须将他们的见证消息发布到一个(与所属委员会相关的)特定的 gossipsub 子网内。在委员会的所有验证者中,需要有个伪随机的验证者子集(大约 16 个)来收集并聚合所有的见证消息。然后,这些 “聚合者” 将聚合过的见证消息发布到一个全局性的 “聚合” gossipsub 通道中。这使得区块提议者只需订阅 “聚合” 通道就够了,因此他们只需关注按每个委员会的被组合过的见证消息,而无需关注所有验证者发布在 gossipsub 子网内的见证消息。然后,区块提议者会选择能使其利润最大化的聚合见证消息并将这些见证消息打包它所提议的区块里。

此过程中许多地方都有可能出现故障,进而阻止验证者的见证消息被打包进区块中。首先,客户端节点需要找到同样订阅了所需子网的其他对等节点。如果不存在这样的对等节点,那么它发布的见证消息就无法传播,更不可能进行任何被打包进区块中的步骤。如果客户端已经找到了足够多的对等节点,接下来就要依赖于子网中的 “聚合者” 首先从 gosispsub 子网中接收并聚合节点的见证消息。聚合者的客户端实现可能有所不同,也有可能不认同它们在子网上收到的见证消息。在这里,客户端之间传播见证消息的时间也很重要,要确保在聚合者聚合见证消息之前送达见证消息。然后,聚合者必须将见证消息发布到全局 “聚合” 通道内。

(在见证消息所发布的时段内的)区块生产者必须关注聚合者发布的见证消息并决定是否将这些消息包含在其区块中。最后两个步骤可以由网络上的任何节点完成,这部分的挑战在于让所有客户端实现在整个流程中协调一致地工作。这就是我们团队(我相信也是其他客户端实现团队)的目标 —— 让我们所有的验证者实现 100% 的见证消息打包率。但这将是一项跨客户端的调试和工程工作,此过程中会涉及到大量的迭代,并可能伴随客户端的进展而不断改进。在过去的一周里,我们已经看到各个团队在这方面的巨大进展。通过设法降低客户端在其它部分的处理负载,我们已经提高了低性能节点的打包率。

Medalla 故障

8 月 14 日,Cloudfare 的 Roughtime 服务器出了问题,导致所有的 Prysm 节点出现了时钟偏差,它们所有的见证消息和区块都被否定了。这其实等同于驱逐出链上所有的 Prysm 节点,这些节点占据了全网 70% 左右的份额 (这里有详细的账户信息)。由于大量的验证者掉线,主链无法实现终局性。这就是多客户端链以及客户端多样性重要的原因之一:在诸如此类的事件中,即便一类客户端实现掉线,区块链也能持续运转。

尽管这是一个灾难性的故障(占全网如此大比例的客户端同时掉线),但对于客户端的实现者来说,这是一个绝佳的机会来观察他们的客户端如何处理此类事件。对我们来说,我们可以看到大量无效区块和见证消息涌入 gossipsub 通道中,进而导致了 Lighthouse 客户端遇到了一些处理上的瓶颈。我们已经观察到了奇怪的内存使用情况,还有一些有趣的同步极端情况,这是由于 Prysm 客户端的多条分叉导致的。这使得我们可以找出这些发生在不利情况下的热点事件,进而纠正它们,最终获得一个更加稳定的客户端,进一步使得其有能力处理这些极端情况。我们正致力于完成许多诸如此类的更新,想象一下,一旦大功告成,我们将拥有一个更加强健和高性能的客户端。(……)

稳定性、性能以及对等节点的管理

Medalla 测试网上发生的事故帮助我们找到了 Lighthouse 中需要改进的一些关键领域。我们一直致力于分析客户端、寻找处理瓶颈、过度的内存占用和整体的客户端稳定性。我们观察到,在 Lighthouse 客户端 解码/处理 大量的 区块/见证消息 时出现了性能下降。这些数据最初是由核心执行器(core-executor,一个管理基本客户端操作的线程池)来处理的,这意味着 Lighthouse 的核心组件在处理 区块/见证消息 时会被延迟。我们一直在寻找此类运算量很大的进程,并将此类进程从核心执行器上转移到它们自己专属的任务处理器上,从而使得即便在高负载的情况下, Lighthouse 核心组件也能按照预期运行。结果表明这一改动提高了 Lighthouse 用户的见证消息打包率。我们还在 Lighthouse 中找到了一些内存分配过多(超出实际所需)的区域。我们正在积极寻找和追踪内存溢出和不必要的内存分配,因为我们观察到在 Medalla 故障期间,一些 Lighthouse 节点的内存使用出现了小高峰。同时,客户端中还存在一个已知的死锁,在 CPU 数量较少的节点上发生频率更高。我们也正在(已经有段时间了)积极地寻找这个死锁并缩小它的范围,应该很快可以干掉这个问题。最后,自从上次更新以来,我们已经增强了对等节点管理系统。除了评分机制,我们还积极地跟踪当前和过去已知的对等节点。当使用默认参数运行一个 Lighthouse 节点时,它通常会连接到 50 个对等节点,且连接的节点数会在 50~55 之间波动。默认情况下,Lighthouse 的目标是连接到 50 个对等节点,并允许 10% 阈值以内的额外节点接入。这就使得新的节点可以轻松地加入网络(即便我们已经连接了 50 个对等节点,也不会拒绝连接新节点),并允许我们与新的对等节点交换节点池(peer-pool),从而移除其它性能不佳或恶意的对等节点。如果你所运行的 Lighthouse 节点连接的对等节点在 50~55 之间波动,不用担心,这就是所需的行为,你的节点正如预期的那样运行。(……)

(完)


原文链接:

https://lighthouse.sigmaprime.io/update-28.html

作者: Lighthouse team

翻译&校对: 曾汨 & 阿剑


编者注:第四份材料是 8 月 17 日的 What‘s New in Eth2,简明扼要地勾勒出了事件发生的顺序以及相关的问题。

What’s New in Eth2 – 17 August 2020(节选)

发生了什么事?

无可否认的是,当时网络中所有的 Prysm 验证者都突然间消失了。因为 Prysm 客户端是使用最广泛的客户端,影响是非常巨大的。Prysmatic 团队正在撰写一份详尽的事故报告(编者注:即本系列的 Part-1),包含了所有的细节和他们的应对措施。下文正是其中的一些关键以及我的评论。问题出在时钟同步(clock sync)上。Prysm 客户端的配置是使用 Cloudflare 的 Roughtime 服务来计算时间。不太清楚这是怎么发生的(至少对我来说),但显然 Roughtime 报出了四个小时之后的时间,而且持续了超过一个小时(编者注:根据 Prysmatic 团队的报告,其实是报出了 24 小时之后的时间)。结果就是,所有的 Prysm 客户端都突然之间发现自己跳到了 4 个小时之后的时空,欣然地开始为一条还不存在的区块链制造区块和见证消息。就这件事本身而言,算不上是灾难性的。

因为剩下的节点可以继续建构原初的那条链,可以无视掉大量 “来自未来” 的见证消息,尽管它们不得不跳过许多区块。这样,慢慢地,Prysm 节点会开始回归(因为时钟调整过来),参与度也会回升,这样事情就解决了!但事情并不是这样发展的,几个小时后,事情变得更加不可收拾。最初的事故发生的四个小时之后,两件事情开始浮现。第一件,所有本来是 “来自未来” 的 Prysm 客户端发出的见证消息,开始变成有效的见证消息。第二件,这些时钟调整后重新加入网络的 Prysm 节点又消失了,因为 Prysm 客户端的罚没保护措施启动了,阻止它们发出与任何与之前发出的见证消息相冲突的见证消息。

这两件事情的效果加在一起就是混乱。当剩下的节点挣扎著处理它们收到的混乱信息时,信标链破碎成了分叉的森林。(更新:Prysmatic 团队的 raul 告诉我,他们发布的第一个修复版本中的一个严重 bug 加剧了这个问题)。在一段时间内,处理这些消息的任务还是可控的。但是,24 小时之后,处理这些越来越复杂的大量分叉所需的内存和 CPU 开始变得高不可攀。我发现一个 Lighthouse 客户端使用着 30 GB 的内存(约是平时用量的 100 倍),而 Teku 客户端早在处理 12 GB 的 Java 堆栈的时候就不堪重负。这一切都是在周末发生的事,请务必记住这一点。感谢客户端团队,他们一直在努力工作、不断优化节点的内存使用和效率,使节点能处理网络的混沌情形。现在的情况是,整个网络正在缓慢地恢复。用户的反映多种多样,但新近推出的 Prysm 客户端和 Lighthouse 客户端都能相当高效地找出正确的链头,并继续建构信标链。Eth2Stats 展示了一些现已找出或逼近链头部的 Lighthouse、Prysm 和 Teku 节点。我们正在改进 Teku 客户端的效率,使之既能不掉队,资源耗用又是可持续的。

什么没有发生

客户端之间没有共识失败,意思是,当大家都到达区块链的最新区块时,所有客户端都能对区块链头部区块的状态达成一致。这是很棒的事,意味着信标链没有在根本上被破坏,而且也不需要任何硬分叉。(……)