以太坊组合客户端中,核心共识工作由以太坊 2.0 客户端管理,而状态 / 区块则由以太坊 1.0 引擎管理。

原文标题:《干货丨详解以太坊 2.0 如何与 1.0 合并》(Eth1+eth2 client relationship)
撰文:Danny Ryan
编译:洒脱喜

原文作者是以太坊 2.0 协调员 Danny Ryan (djrtwo),在这篇文章中,他详细介绍了以太坊 1.0 将如何与以太坊 2.0 合并,根据他的介绍,在 eth1+eth2 组合客户端中,eth2 客户端可以处理 PoS 和分片共识的复杂性,而附属 eth1 客户端可以成为一个 eth1 引擎,它可以处理状态、交易、虚拟机等事物的复杂性。

技术详解如何合并以太坊 2.0 客户端与 1.0 引擎图片来自:tuchong.com

以太坊 1.0 和以太坊 2.0 客户端的关系

自从 Vitalik 在 2019 年 12 月提出一个早期 eth1 <-> eth2 合并替代方案之后,研究人员一直在进行积极讨论,以从软件的角度来考虑这种合并的可能形式,而对于原型设计的期望,也是愈发变得更强。我们的愿景是创建一个混合体,其中核心共识工作是由以太坊 2.0 客户端(以下简称 eth2 客户端)管理,而状态 / 区块则由一个以太坊 1.0 引擎(以下简称 eth1 引擎)管理,而它们一起构成了 eth1+eth2 组合客户端。

本文旨在更明确地区分 eth2 客户端和附属 eth1 引擎之间的职责,以便为会话、规范编写及原型提供更好的基础。注意,文章并不会定义协议的具体细节(例如 eth1 客户端调用 eth2 引擎的精确方法),并且文中包含的任何示例,都只是用于帮助描述及后续讨论。

而要理解本文的内容,前提条件是需要你基本熟悉以太坊 2.0 以及无状态以太坊的概念。

分工明确

eth1+eth2 的合并目的,是在升级的以太坊 2.0 共识环境中利用现有以太坊 1.0 的状态、生态系统以及软件。

概括地说,我们今天所认为的 eth2 客户端会处理核心 PoS 以及分片共识。本质上,eth2 协议及 eth2 客户端被设计成非常擅于在一堆「东西」上产生及达成共识,而这些东西,就是很多充满数据和(最终)状态的分片链。与当今 eth1 的 PoW 共识层相比,eth2 的「共识层」要先进的多,同时也复杂的多。

今天,eth1 客户端具有相对简单且较薄的共识层,它只有一条链,并且 PoW 可处理协议外硬件中的大部分复杂性。eth1 客户端的大多数复杂性及优化,都位于用户层(包括状态存储 / 管理、状态同步、虚拟机执行、交易处理、交易池等)。

当 eth1 作为一个分片被纳入 eth2 时,这种关注点分离就可实现很好的配对,eth2 客户端可以处理 PoS 和分片共识的复杂性,而附属 eth1 客户端可以成为 eth1 引擎,它可以处理状态、交易、虚拟机以及更接近用户层事物的复杂性。

最小的改变,实现本地通信

如何将 eth1 和 eth2 客户端软件组合在一起,有很多可能的途径(比如完全合并、将 eth1 作为库导入、通过两者之间的通信协议等),但在本文当中,我们会重点介绍一个最具微创性和和模块化的方法 —— 一种 eth2 客户端与简化 eth1 引擎之间的本地通信协议。

考虑到 eth1 和 eth2 客户端实现的多样性,这种方法可以防止客户端软件在任一侧锁定,允许客户端团队保持独立,并专注于他们自己的研发工作,使软件项目在很大程度上保持稳定,以便进行快速原型制作。

那它会是什么样子的呢?

大致上,一个 eth1+eth2 组合客户端会是下面这个样子的:

技术详解如何合并以太坊 2.0 客户端与 1.0 引擎

其中 eth2 引擎和 eth1 引擎一起运行,通过 eth2 客户端驱动的 RPC 进行本地通信。
两者都会维护自己的 p2p 接口,连接到对等方并处理与每个特定域相关的网络协议。

以太坊 2.0 客户端

技术详解如何合并以太坊 2.0 客户端与 1.0 引擎

  1. 信标链和信标状态 (构建系统其余部分的核心共识对象);
  2. 分片链(1、eth1 分片链,2、很多仅限数据的分片链);
  3. Mempool 操作 [未显示](证明(Attestation)、存款(deposit)、退出出口( exit)等)
  4. P2P 接口(1、共识层信息,2、包括 eth1 分片区块 gossip);
  5. RPC 到 eth1 引擎 (所有调用都由 eth2 客户端驱动);

以太坊 1.0 引擎

技术详解如何合并以太坊 2.0 客户端与 1.0 引擎

  1. EVM 虚拟机(eth1 分片区块的执行与验证);
  2. eth1 状态(今天以太坊中的用户层 eth1 状态);
  3. 交易存储池 Mempool (用户交易 mempool,为区块生产做准备);
  4. P2P 接口(1、今天以太坊上的交易 gossip,2、状态同步,3、没有 eth1 分片区块 gossip);
  5. 来自 eth2 客户端的 RPC (所有调用都由 eth2 客户端驱动);

共识

从核心共识的角度来看,eth2 客户端负责并推动信标链、数据分片链以及 eth1 分片链的构建。eth2 客户端通过 RPC 直接提供有关 eth1 引擎关于 eth1 分片链和核心共识(信标链 / 状态)的任何知识。

具体来说,附加的 eth1 引擎必须能够访问 eth2 客户端,因为它不能维护自己的共识。在今天以太坊的 PoW 中,eth1 客户端检查工作量证明,形成一个树状结构,并运行分叉选择规则来查找链的顶端。在 eth2 中,这些机制要大不相同,这需要对 eth2 的核心共识有深入的了解。eth2 客户端提供有关 eth1 分片链头部(head)的最新信息,以便 eth1 引擎可以维护 eth1 状态的准确视图。

由于 eth1 引擎完全依赖 eth2 客户端推动共识,因此我们提议 eth2 客户端与 eth1 引擎之间的通信,都是 eth2 客户端调用的 eth1 引擎上的所有方法(例如 addBlock, getBlockProposal 等)。这将强制执行一个 leader/follower 关系,以降低系统推理的复杂性,并限制 eth1 引擎所需的业务逻辑。

从 eth2 客户端和核心共识的角度来看,eth1 分片链的处理,几乎与所有其他分片链(分叉选择、交联、区块结构、签名等)完全相同。主要区别在于,可以针对 eth1 引擎执行分片区块内容,因此 eth1 分片区块数据的格式必须与 eth1 相关,并且必须针对此成功执行进行额外的验证。

状态

eth2 有一种与核心共识相关的状态,这就是所谓的「信标状态」(beacon-state)。信标状态数据很小(大约只有 10-40MB,取决于验证者集的大小),它包含了理解核心共识及如何处理分片链所需的所有信息。事实上,要处理分片链中与共识相关的部分,客户端必须能够访问信标状态(例如,运行分片链分叉选择的最新交联 crosslink、验证分片链签名的当前验证集或 shuffling 随机分配)。

eth2 的状态不会一直和用户层状态交互,其交互最多的是分片链数据的可用性。实际的用户层数据根位于该分片链数据中,对于 eth1 分片链,则为当前以太坊用户状态根。

下面讨论了和 eth2 客户端相关的 eth1 状态的不同情况:

没有 eth1 引擎的 eth2 客户端

核心 eth2 协议可以在没有附加 eth1 引擎的情况下运行。单独的 eth2 客户端可以遵循信标链和分片链(包括 eth1 分片)。而没有 eth1 引擎,客户端将无法执行无状态 eth1 分片区块,因此无法完全验证它们或从中获取任何有用的用户信息。不过,根据对 eth2 核心共识和验证者的假设,eth1 分片链的头部(head)仍然可以安全地找到。

带无状态 eth1 引擎的 eth2 客户端

要运行一个验证者节点,必须使用附加的 eth1 引擎运行 eth2 客户端。这可以通过无状态的方式完成(即不在本地存储整个 eth1 状态),因此 eth1 分片区块具有可用于执行的验证数据(witness)。信标委员会可以通过对 eth1 引擎进行无状态调用,来检查分片区块数据的可用性及关于 eth1 的数据有效性。

除了验证者外,很多用户 / 应用程序节点也可能使用无状态或半状态的 eth1 引擎运行。使用瘦 eth2 客户端,来跟随 eth1 分片链的头部,并以无状态或半无状态的方式与其交互。

带有状态 eth1 引擎的 eth2 客户端

要运行可产生 eth1 分片区块的验证者,必须使用附加的 eth1 引擎和完整的 eth1 状态运行 eth2 协议(研发者们正在探索无状态的区块产生方法,但为简单起见,我们不对其进行讨论)。然后,可以使用本地状态和交易存储池(TX mempool)按需形成新的有效区块(在下文中有更多讨论)。

除验证者外,很多用户 / 应用程序节点也可能使用完全有状态的 eth1 引擎运行,例如区块浏览器、存档节点、状态提供者等。

网络

为简单起见,eth2 和 eth1 最初会维护它们各自独立的网络堆栈和协议。为了响应责任转移(例如 eth1 分片区块 gossip),开发者已不赞成使用某些现有的 eth1 协议(例如 eth1 分片区块 gossip),取而代之的是 eth2 协议。在初始原型设计阶段之后,或者在更进一步的阶段,可能需要将 eth1 协议迁移到 libp2p 以统一网络堆栈,但这不是必须的。

eth2 客户端和 eth1 引擎可以访问相同的 discv5 DHT,但是可独立地找到具有适当功能的对等节点并独立地维护连接。

ENR

eth1+eth2 组合客户端会使用一个 ENR,因为节点位于具有多个功能的逻辑网络标识之后。

eth1 功能(状态、交易等)由 ENR 中的现有 eth (或新 eth1) key 表示。

eth2 功能(核心共识)在 ENR 中用 eth2 key 表示。

每种协议的存在,都意味着节点能够且愿意识别底层网络协议的类别。

Wire 协议

eth2 协议

  1. eth2 请求 / 响应(1、状态,2、信标区块同步,3、分片区块同步);
  2. 核心共识 gossip (1、Beacon 区块,2、证明,3、分片区块,包括 eth1 分片, 4、其它验证者操作);

eth1 协议

  1. eth1 wire 协议的子集 (1、交易 gossip,2、同步方法,例如 getnodedata 或新方法, 3、获取收据 receipt)
  2. NOT (与区块哈希、区块头或体相关的消息);

为什么 eth2 客户端会处理 eth1 区块 gossip?

eth2 专门用于处理分片区块的生产、gossip 以及验证。我们的目标是让 eth1 分片成为标准分片,并尽可能与其余分片保持一致。关于核心共识,与其他分片相比,eth1 区块的主要区别在于针对 eth1 引擎执行 / 验证区块内容的能力,当验证者正在将 eth1 分片区块叉联到信标链时,eth2 客户端将再次调用 eth1 引擎来执行和验证该区块。

当有状态的 eth1 + eth2 组合节点收到新的 eth1 分片区块时,eth2 客户端将再次调用 eth1 引擎,以验证该区块并更新本地状态存储。

交易 gossip 和存储池 mempool

eth1 引擎几乎会以当前以太坊相同的方式,维护用户交易 gossip 以及 eth1 交易储存池。同样的网络协议和本地机制,可以用于 gossip 及存储池的维护,为区块的生产做好准备。

主要的区别在于如何确定已用交易的知识,以及如何将存储池用于区块生产,但这些可以说是位于存储池外部的一个层中。

eth1 分片区块是从附属 eth2 客户端提供给 eth1 引擎的。包含在这些区块中的交易,应该以类似于当前以太坊主网 PoW 区块的方式从存储池中清除。

eth1 分片区块是根据附属 eth2 客户端,通过存储池 mempool 的内容生成的。此 RPC 方法和基础功能类似于 getWork,但将返回完整的区块内容,而不仅仅是一个哈希值。

区块生产

在 eth2 协议中,所有区块(信标区块、分片区块、eth1 分片区块)必须由 PoS 验证者根据核心共识进行生产及签名。为此,eth2 客户端最终要负责所有区块的生产。

对于信标区块和非 eth1 分片区块,eth2 客户端具有生成有效区块所需的一切。

对于 eth1 分片区块,eth2 客户端立即 / 随时访问 eth1 状态、交易和其它底层 eth1 结构,以生成有效区块。相反,当指定验证者生成 eth1 区块时,eth2 客户端从 eth1 引擎请求一个可行的 eth1 区块数据(TX、状态根等)。然后,eth2 客户端将此 eth1 区块数据打包到完整的分片区块中(添加 slot、positer_index、positer_signature 等),并将该区块广播至网络。

eth1 引擎之所以能够生成有效 / 可行的 eth1 区块数据,是因为它采用了今天以太坊主网所使用的相同方式来管理 eth1 交易存储池,并且它通过 eth2 客户端的更新来维护 eth1 头状态的最新信息。

下一步该怎么走?

如果这一总体设计被大家认同,那接下来的步骤包括:

  1. 确保有关 eth2 客户端驱动 eth1 引擎的假设与现有 eth1 软件一致,并且不会给现有 eth1 软件带来意外的负担;
  2. 更明确地定义用于驱动 eth1 引擎的通信协议,例如 new_head(block)、validate_block_transition(block)、get_proposal(parent_root) 等;
  3. 定义网络组件,例如需要 eth1 协议的哪一个子集,如何具体使用 ENR;
  4. 扩展以太坊 2.0 阶段 1 规范
  5. 原型!

本文经作者 Danny Ryan 授权翻译。

来源链接:ethresear.ch