客户端:验证轻节点机制

以太坊Ethereum本质上是由分散式节点所组成的网络架构,这些节点称为「以太坊节点Ethereum Nodes」或「以太坊客户端Ethereum Clients」。任何人只要有规格足够的硬件设备都能够加入进来成为以太坊的节点。

节点就是运行以太坊客户端软件的硬件设备,包括服务器、电脑或者手机。也就是说用户需要在硬件设备上有一个应用程序,就可以称之为客户端,来运行节点。

节点的工作内容

  • Receive Transactions:接收来自DApp、钱包或其它节点的交易资讯
  • Receive Blocks:从其它节点接收区块资讯同步至最新的区块高度
  • Validating:验证新的区块之正确性、验证待处理交易之有效性
  • Executing:处理交易,进行运算并更改状态值,打包成新区块
  • Mining:用电脑算力来计算nonce 值,最先找到nonce 值出块并广播的矿工可以获得区块奖励与所有交易之手续费(Gas)
  • Consensus:通过共识机制达成全网帐本之一致性或区块重组(reorg)

正是这些分布在全球的数千个节点们不间断地工作维系了以太坊区块链的正常运作。

节点有许多不同形式,上述参与所有工作内容(包含接收、验证、挖矿)的节点仅是大众普遍认知的其中一种形式。事实上,客户端可以运行3种不同类型的节点——轻节点(light)、全节点(full)和归档节点(archive)。

全节点

全节点是拥有完整区块链帐本资料的节点,具备独立验证的能力来确认交易之有效性。主要在处理下列四件事:

  • 储存所有历史交易资讯,资料公开透明
  • 监测矿工挖出来的新区块,验证其合法性后同步该区块
  • 监测区块链网络中的新交易资讯,验证每个交易的合法性
  • 将验证过的「交易/区块资讯」广播给全网络节点

一个节点只要下载了完整且最新的区块链资料,稳定运行验证交易和同步区块资讯,那它就是一个全节点了。由于每一个全节点都保有全网资料,所以即使其中部分节点出现问题,例如断网或被黑客攻击,都不会影响整个区块链网络的安全性。这就是去中心化记帐系统的优势所在。

同时,全节点的数量越多,也代表完整的区块链帐本被保存的份数越多,不可篡改性也就越强,整个区块链网络的安全性也随之提升。一但有人企图组织算力叛变,试图改变区块共识或发动双花攻击,其它正常运作的全节点可以即时验证拒绝掉这些交易。

这其中,挖矿的过程即是将验证过的待处理交易打包成新区块,并以电脑算力来计算nonce值,最先找到nonce值成功出块并广播的矿工会获得区块奖励与所有交易之手续费(gas)作为报酬。

矿工必须要运行全节点才能即时浏览区块链历史资料进行交易验证,再将验证通过的交易进行打包。因此,所有矿工必定是全节点;然而全节点未必是矿工,运行全节点的人未必会花费电脑算力去参与新区块nonce值的运算来争取区块奖励。

轻节点

轻节点顾名思义即是轻量级的节点,具体定义是不储存或维护完整的区块链副本,只储存最小量的状态来作为发送或传递交易讯息的节点。

Block Header and Body

以太坊的每个区块主要分为Header 和Body 两个部分存储,Body 即是交易列表;Block Header则较为复杂,包含了前个区块的Hash、时间戳及挖矿难度等相关参数。

在Block Header中采用一种名为Merkle-Patricia Trie (MPT)的核心资料结构来储存区块链资讯,可以理解为把帐本分割成无数个小的资料块,每个资料块像是一棵树中的无数叶片,而我们把每两个相邻的叶片合并成一个字串,并算出该字串的Hash值。如此过程经过无数次后,最终如同所有树枝归向一个树干一般,会得到一个包含了所有区块资料的Hash值,称为「Merkle Root」。

轻节点资讯

全节点储存了所有区块的Block Header与Body(交易列表),而轻节点只储存最小量的状态,即区块标头Block Header,借此大幅降低储存空间的需求。

轻节点如何验证交易

由于割舍掉区块的Body,即所有历史的交易列表,因此当轻节点需要验证某个交易的合法性时,先要向邻近的全节点发起确认请求,在全节点收到请求后提供所需相关资讯供验证。之所以需要向全节点请求的原因是假设有一个合约执行的交易,那么便必须要有该合约部署时的原始码(位在Contract Created 之交易中)。由于该交易位于某个区块之Body,故轻节点必须要向全节点请求该合约之相关资讯方能进行交易验证。

概括而言,轻节点大致上具备以下几点特色:

  • 只储存每个区块的区块标头Block Header
  • 不一定保持随时在线(获取最新的Block Header 资讯)
  • 根据需求可以只保存与自己相关的交易内容
  • 无法验证大多数交易的合法性,只能验证与自己相关交易的合法性
  • 无法验证新区块的正确性
  • 只能检测到当前的最长链,但无法知道哪条是最长合法链

由于轻节点必须要向全节点请求与交易验证相关的Block Body 资讯,那么要怎么知道全节点回传的资讯是正确的呢?这时就要回到以太坊的资料结构来谈,前面提到轻节点为了减少储存空间,而割舍掉Block Body,仅保留作为验证之用的Block Header。由于存有已经验证合法之Block Header,因此当未来需要验证相关交易时只要透过跟全节点请求相关的Block Body 资讯即可进行验证,不需要从头验证整个区块。

Block Header与交易验证

轻节点能够利用Block Header验证交易的原因在于Block Header中的Merkle Root,也就是由Block Body中的交易资讯经由杂凑演算法(Hash Algorithm)生成的数字指纹(Digital Fingerprint),因此Block Header可以充分代表Block Body内的资讯。

Block Header中的Merkle-Patricia Trie是一个生成Hash需要花费大量算力、但验证非常迅速的结构。当轻节点收到全节点提供的资讯时,便能够利用已有的Block Header相关讯息迅速验证该资讯是否正确,进一步进行交易验证。

归档节点

归档节点是在全节点的基础之上,额外储存了每个区块高度的区块状态,包括个人帐户与合约帐户之当时余额等信息,即针对每个区块高度当下的状态进行快照并存档。存储保存在全节点中的所有内容,并建立历史状态的存档。如果你想查询#4,000,000区块的账户余额,或者简单而可靠地测试你自己的交易数据集,而不使用OpenEthereum挖掘它们,则需要此功能。

这些数据以兆兆字节(terabytes)为单位,这使得归档节点对普通用户的吸引力不大,但对于区块浏览器、钱包供应商和区块链分析等服务来说却很方便。

节点会根据共识规则自行验证所有交易和区块。这意味着不必依赖网络中其它节点,也不必完全信任他们。不必将地址和余额泄露给随机节点。一切都可以通过自己的客户端核实。

多样化的节点对以太坊的健康、安全和运行弹性非常重要。它们为依赖于区块链数据的轻节点提供访问区块链数据的机会。在使用高峰期,需要有足够多的全节点来帮助轻节点同步。轻节点不存储整个区块链,而是通过区块头中的状态根来验证数据。如果需要的话,它们可以从区块中请求更多的信息。

全节点强制执行PoW共识机制,它们不接受不遵循规则的区块。这为网络提供了额外的安全性,因为如果所有节点都是轻节点,不进行全面验证,区块生产者可能会攻击网络,例如创建奖励更高的区块。

执行客户端

以太坊社区维护着多个开源执行客户端(以前称为“Eth1 客户端”,或简称为“以太坊1.0客户端”),由不同团队使用不同的编程语言开发。这使得网络更强大和多样化。理想的目标是在没有任何客户端主导的情况下实现多样性,以减少任何单点故障。

(1)Go Ethereum(简称Geth)是以太坊协议的原始实现之一。目前,它是受众最广泛的客户端,拥有最大用户群,为用户和开发者提供各种工具。它是用Go语言编写,完全开源,并采用GNU LGPL v3授权。

(2)OpenEthereum是一个快速、功能丰富的以太坊客户端,提供快速可靠的服务所需基础架构,这些服务需要快速同步和最大限度的运行时间。注意:OpenEthereum已被弃用,不再进行维护。最好切换到另一个客户端实现。

(3)Nethermind是基于C#.NET技术栈创建的以太坊实现,可在包括ARM在内的所有主流平台上运行。它提供了虚拟机、Prometheus/Graphana仪表盘、seq企业日志支持、JSON RPC追踪和分析插件等服务,也拥有详细的文档,强大的开发支持,在线社区以及为高级用户提供全天候支持。

(4)Hyperledger Besu是一个用于公共网络和许可网络的企业级以太坊客户端。它运行所有以太坊主网功能,从追踪到GraphQL,具有广泛的监控,并由ConsenSys支持,无论是在开放的社区渠道还是通过企业的商业SLA。它是用Java编写的,并获得Apache 2.0许可。Hyperledger Besu是一个以Apache 2.0许可开发并以Java编写的开源以太坊客户端。它运行在以太坊公共网络,专用网络以及测试网络(如Rinkeby,Ropsten和Grli)上。Besu实施工作量证明(Ethash)和权限证明(IBFT 2.0和Clique)共识机制。

(5)Erigon(原Turbo‐Geth)是Go以太坊的一个分叉,以速度和磁盘空间效率为目标。Erigon是一个完全重新架构的以太坊实现,目前用Go编写,但计划用其他语言实现。Erigon的目标是提供更快、更模块化、更优化的以太坊实现。它可以在3天内使用不到2TB的磁盘空间执行完全归档节点同步。

每个节点客户端对硬件配置的要求不同,但不要把它和挖矿的矿机混为一谈,挖矿需要更多的计算能力。在2.0时代,以太坊可以在手机、电脑、家庭服务器、单板电脑或云端的虚拟专用服务器上运行。不过在深入讨论这个问题之前,让我们先回到区块链原教旨主义的比特币客户端说说为什么它不是挖矿机。

2008年中本聪最初设计比特币的时候,整个硬件逻辑都是基于电脑进行的,包括POW的设计目标都是一个CPU一票制。所以整个比特币硬件的矿机演变史,都是基于个人电脑进行。

第一代矿机-CPU矿机,从2010年开始,都是沿用中本聪的设计思路,个人电脑的CPU挖矿,用户只需要下载比特币的矿机端软件,就可以在电脑上挖矿,门槛极低。

而第二代比特币矿机-GPU矿机,从2010年到2013年,属于显卡挖矿阶段,个人电脑上的显卡挖矿软件发布,用户只需要在电脑上安装显卡软件,既可以实现挖矿,且能力比CPU挖矿明显提升。

第三代矿机-FPGA/ASIC矿机,从2013年ASIC和FPGA矿机几乎同时问世,从设计原理上,这两种矿机都真正脱离了个人电脑,相当于将原来个人电脑CPU和GPU上比特币挖矿功能单独进行了集成电路层面的设计,发明了“专用”的挖矿设备,在这波浪潮中比特大陆等一批公司脱颖而出,直至2019年。

之后的第四代矿机-矿池,从本质上讲,矿池并没有技术上重大进步,只是在矿机的组织形式上做了一些改进。矿池就是集中大家的算力,共担风险,按算力分配收益。

虽然第三代矿机有了专门芯片级的设计,但是从本质上讲,仍然没有摆脱中本聪的思想,因为他们都是以POW算法为基础产生,所以区块链业界一直将基于POW算法设计的矿机认为是区块链硬件1.0。因为本质上这些矿机都是源于个人电脑PC,我们可以将这个阶段统称为区块链PC时代。

在PC时代,按照中本聪的设计理念,在比特币网络上,一个CPU就是一个独立的节点,网络节点上的每个CPU都是平等的,在争夺记账权的机会是均等的。这里的“平等”靠的PoW共识来实现。PoW共识的基础是计算哈希函数的算力,谁的算力大,谁就有话语权。在个人电脑上,每个CPU计算哈希函数的算力都基本差不多,可以实现“平等”,但是随着第二代GPU矿机,第三代FPGA/ASIC矿机以及第四代矿池矿机的出现,这种“平等”被打破了。

这种基于PoW的设计,带来了另外一个意外的结果就是无节制的算力竞争导致过高的能源消耗,进而带来了被外界广泛批评的区块链环境问题。可以说,这样的矿机发展模式已经完全偏离了原来中本聪的设计理念,个人电脑不再能够参与挖矿,能够参与PoW算力竞争的设备不但造价高昂,且严重消耗能源。

中本聪在2008年提出比特币和区块链的天才设想,Iphone手机才刚发布不久,虽然有一定影响力,但还远没有形成今天移动互联网的规模。当时他是无法估计移动互联网的未来的,所以比特币网络的底层硬件是基于第一代互联网硬件即PC来实现的。

基于此,我们假设如果中本聪在2022年重新设计比特币的话,它的底层硬件基础应该是什么?毫无疑问,应该是移动互联网的主要硬件即手机。手机这个硬件终端人人拥有,这是最实时在线的互联网设备。如果要建立一个去中心化的、分布式、点对点的电子现金系统,选择底层硬件的话,手机当然是不二选择。

也就是如果中本聪选择在2022年,而不是2008年发布比特币的话,区块链底层的硬件设计应该是手机,而不是电脑。

那么问题就来了,如何以手机为底层硬件来设计Web3.0网络呢?在某种意义上,这个问题就等同于Web3手机应该如何设计?

要回答这个问题,至少要弄清楚三个方面内容:

  1. 比特币网络是如何基于电脑来设计的?
  2. 手机和电脑有什么本质的区别?
  3. Web3.0网络如何将手机纳入到底层硬件系统中来?

首先,比特币网络是如何基于电脑来设计的?

比特币设计理念是实现一个点对点的电子现金系统,其核心要素是P2P网络,非对称加密技术,分布式账本。通俗来讲,比特币网络就是要在一个去中心化的P2P网络中,设计一个所有节点共同管理的账本系统。在网络运作过程中,每个节点需要使用非对称加密技术来实现节点用户接入管理,同时每个节点还必须按照PoW共识算法来共同记录和维护一个分布式账本系统,这要求每个节点都必须有足够算力来计算哈希函数,也要有足够的存储空间来存储分布式账本的本地副本。

我们把比特币网络对硬件的关键要素提取出来:有足够的计算能力,实时联网,足够带宽,足够的存储空间。而这,其实就是一个个人电脑的基本功能。

关于比特币网络对硬件存储的要求,在比特币白皮书中有这样的描述:“不含交易信息的区块头(Block header)大小仅有80字节。如果我们设定区块生成的速率为每10分钟一个,那么每一年产生的数据位4.2MB。(80 bytes 6 24 * 365 = 4.2MB)。2008年,PC系统通常的内存容量为2GB,按照摩尔定律的预言,即使将全部的区块头存储于内存之中都不是问题。”

可以看出,整个比特币网络的设计都是以2008年的电脑硬件水平为前提的。

第二个问题,手机和电脑有什么本质的区别?

从Web3.0网络相关的指标来看,手机和电脑的区别点如下:

  1. 从算力上来看:手机的CPU基本上都是基于ARM架构的嵌入式系统,电脑的CPU主流架构是Intel公司的X86系统,从工作效率看,ARM系统效率更高,但是如果从算力上来看X86系统还是处于领先地位,当然不排除ARM系统会逐渐追赶上来。从当前电子工业的水平来看,电脑的算力还是要优于手机;
  2. 从存储空间来看:虽然已经有VERTU手机已经推出了1T ROM存储空间的配置,但是从行业整体水平来看,电脑的存储空间还是要大于手机;
  3. 从带宽来看:由于手机主要是靠无线通信即4G/5G网络和WIFI,而电脑主要靠有线以太网和WIFI,所以从带宽角度看,电脑也是优于手机;
  4. 从待机时间看:由于电脑大部分是直接靠外部电源供电,而手机主要靠电池供电,所以电脑的待机时间也是优于手机;
  5. 从分布的广度来看:由于手机整体成本比电脑更低,操作更简单,且很多地方的人们可能只有手机而没有电脑,所以从分布的广度来看,手机远比电脑更加普及,且除了部分发展中国家以外,全球基本实现人人都有手机。

总结一下:从硬件指标来看,手机实际上是一个简化版的电脑,但是却比电脑更加普及,分布更广。

第三个问题,Web3.0网络如何将手机纳入到底层硬件系统中来?

本质上,分布式账本是网络上每一个节点都要在本地保留一份全网账本的副本,然后全网节点组合起来,就成了一个完整的分布式账本,不管中间哪一个节点出现了问题,只要全网还有51%以上节点能够正常工作,这个分布式账本就是安全和完整的。在整个分布式账本运作过程中,每一个节点都必须要有足够的带宽和存储空间,而且随着时间的推移,分布式账本系统对带宽和存储空间的要求会越来越高。

在比特币网络早期,个人电脑还能够承担分布式账本对硬件的要求,但是随着时间推移,比特币的账本系统越来越大,需求的带宽越来越高,比特币的矿机不得不发展到现在的最终形态,即矿池。在矿池系统中,单个矿机节点就不必成为全节点,更大的存储空间和带宽都有矿池统一运维,矿机节点只需要贡献算力即可。但通过比特币网络矿机的发展,我们可以得出一个逻辑,不管你的矿机节点的配置如何,随着时间推移,单个节点都是无法承担全节点的工作量。

到了以太坊2.0时代,由于PoS共识体系与经济模型奖惩机制的彻底改变,一部手机,就是一个轻量级的客户端,可以给网络作贡献,但又不要求同步区块链,大部分用户都在不知不觉中就开始运行轻客户端了。它有潜力能提升普通用户的安全性和隐私性,同时帮助提高以太坊的可靠性,因为更多用户可以为网络的健康作贡献。

现有的 DevP2P LES网络在设计上采用了 客户端/服务器 架构,轻客户端作为客户端,而全节点作为服务器端。因为这种架构把所有的负载都交给全节点来承担,而全节点的运营成本已经很高了,所以节点运营者就不愿意打开这个功能。

一个轻客户端友好的网络,必须设计得节点只需付出少量存储空间、少许工作量,就能参与网络并为网络做贡献,而不是要求每个节点都必须承担很高的负载(即:在内存里保存区块链的完整历史)。

换句话来说,这样一个网络必须允许轻客户端在实际上为网络做出贡献,使得每当有额外的客户端加入网络,都会增强网络的容量。

具体来说,这意味着要提出一种网络设计,可以减少你的偶发请求的数据的验证开销,并降低在网络中传递消息的基本开销。这些网络将与 ETH 协议共存 —— 但不像 ETH 协议,它们不必是完全无懈可击的,但它们需要能 几乎 不间断工作。

为什么说以太坊合并之后的以太坊2.0能够实现这样的链与端完美融合方式?,在回答这个问题之前,我们先了解一下什么是区块链历史记录,以及需要解决哪些问题才能让轻量级客户端轻松获得这些历史记录。

区块链历史记录

“区块链历史记录” 指的是所有区块头、区块体和收据的历史记录。在当前所有以太坊客户端用来通信的以太坊协议中,节点可以使用以下消息对来互相请求区块链历史记录:

  • GetBlockHeaders > BlockHeaders
  • GetBlockBodies > BlockBodies
  • GetReceipts > Receipts

区块链历史记录是一个相对简单的数据集。你可以把它当成是一个只能添加的文件。矿工每挖出一个新的区块,这个区块的区块头、交易、叔块和收据都会被添加到文件中。以太坊协议已经为这部分需要而优化过,所以一个新加入网络的节点可以高效地检索区块链的所有历史记录。一旦客户端实现完全同步,除了响应 JSON-RPC 请求之外无需使用这些数据。客户端自己也不会频繁用到这些数据,因为它们会通过 gossip 消息获取新的区块和区块头。作为区块执行的一部分,收据会在本地生成。尽管如此,协议还是强迫客户端要保留完整的历史记录。因此,我们需要的数据在以太坊节点所组成的网络中其实都有,只不过网络的架构没有考虑过我们的用例。在以太坊协议上构建轻量级客户端需要解决三大问题:

A:我们需要对正统链有一个简明的了解

B:我们需要使用索引,便于按区块号查找区块,并按哈希值查找交易

C:我们需要减少单个节点存储的总数据量

A:正统区块头链

要找到区块链最新区块,最免信任的方式是从头开始构建一条完整的区块头链(由区块头组成的链条)。为此,我们需要获取大约 1100 万个区块头,并为其提供大约 6GB 的存储空间。如果没有完整的区块头链,客户端就无法辨别区块头是属于正统链还是叔块的。对于手机来说,6GB 的存储成本显然过于高昂。如果用户要先获得 1100 万个区块头才能发出第一个请求的话,那就违反了客户端无需同步的要求。

所以说,以太坊2.0完美解决了这一问题。我们只需在以太坊协议上添加一个 “双倍批量默克尔 log 累加器(double-batched merkle log accumulator)”,就可以构建一个简单易懂的机制来提供某个区块头是否包含在正统链上的证明。客户端只需准确掌握最新区块头的信息,并通过累加器生成的简单默克尔证明来证明历史区块头包含在正统链上。

同步问题是一个可以在客户端层面解决的用户体验问题。有两种解决方案:1. 设置区块头“检查点”;2. 信任观察到的链首块,并执行实际的工作来获取该链首块,然后对其进行异步验证。

B:数据索引

有一些 RPC 端点很难直接构建在现有网络架构上。客户端目前可以通过在区块链历史记录上创建索引来服务这些端点。存在问题的端点主要有:

  1. eth_getBlockByNumber
  2. eth_getTransactionByHash

任意区块高度都有可能出现无限个有效区块,但是只有其中一个区块在正统链上。因此,客户端在拼凑正统链时也会构建自己的索引来将 block_number 映射到 block_hash 上。当客户端通过 JSON-RPC 请求某个区块号的区块时,该索引会将这一请求转化为请求某个哈希值的区块。

单就正统链而言,一笔交易只存在于一个区块内。客户端在处理正统链时会创建一个索引来将 transaction_hash 映射到 (block_hash, transaction_index) 上。当客户端收到对某笔交易的数据请求时,该索引会将这一请求转化为允许查找该交易以及包含该交易的正统区块。交易和区块都必须包含在 JSON-RPC 响应内。因此,我们需要一个机制来显示这些索引。区块头累加器为我们提供了一种机制,可以让索引数据成为正统链的一部分。

C:降低个体存储要求

以太坊协议自设计之始,就将 DevP2P 以太坊网络中的节点设想为能够响应任何关于查找区块链历史记录的请求 —— 无论是最新的区块、很老的区块还是介于二者之间的区块。以太坊网络没有机制可以让节点仅存储区块链历史记录的子集。从根本上来说,整个网络都依赖于所有节点都存储所有数据这一假设。网络本身无法强制节点存储所有数据,但是客户端会与无法响应其请求数据的对等节点断开连接。这在一定程度上保障了安全性,因为无法响应请求的客户端不太可能会维护健康的对等连接。

因此,首先需要解决的问题是,创建一种机制让单个节点可以仅存储区块链历史记录的子集,同时让网络为节点提供一种机制,以便节点快速找到拥有它们所需数据的节点。

以太坊状态

当我们提到 “状态” 时,我们指的是所有账户信息(如 ETH 余额)以及所有存储在智能合约中的数据。目前以太坊状态包括:

  1. 1.32 亿个账户
  2. 大约 10 GB 的账户数据
  3. 大约 30 GB 的合约 storage 数据
  4. 大约 60 GB 的 Trie 节点经常性数据

我们先来看一下传统模式下客户端目前是如何访问状态的。

同步

以太坊节点需要访问完整的状态才能处理新挖出的区块。我们可以通过执行从创世块开始到链首块的每个区块来从头计算出状态。通常情况下,我们不会采用这个方法,因为计算成本太高。客户端倾向于直接从其它完全同步的客户端那里获取完整的状态副本。虽然不同的客户端执行该操作的具体方式不同,但无论是哪种客户端,在首次上线或离线一段时间后再次上线的情况下,通常都要花费一段时间同步至最新区块。同步可能需要花费很多时间。如果你使用自己的节点与区块链交互,这会是一大缺陷。要让客户端一直保持同步状态,你不仅需要花时间等待客户端同步,还需要消耗计算机的计算和存储资源。

我们的解决方案是专门针对资源受限的设备而设计的,可以一举解决上述两个问题。一个轻客户端在运行时只需消耗最少的 CPU/RAM/HDD/带宽资源,而且可以保证永远在线。在我们设计的模型下,手机只需要准确获得链首块的信息即可。我们的最终目标是构建一个在首次安装或离线一段时间后再次上线能够立即使用的手机。这样,这部手机只需能访问正确的数据即可。

如何分担并降低存储压力

这个网络上的节点要能为存储完整状态贡献少量存储空间。通过海量的Web3手机客户端,网络中的每个节点存储一小部分状态,而非完全复制所有状态。有了足够多的节点,整个网络就可以轻而易举地以极高的复制因子存储所有状态。由于每个节点只需存储小部分状态,我们再也不需要盲目地向网络中的任意节点请求数据。因此,网络需要一个节点发现机制,以便节点获取所需数据。

你用一部Web3手机客户端在运行自己的验证者节点时,首先只需要“安装 + 质押 ETH = 正常运行”就可以,而且同时需要意识到的是,你这样做是有助于网络安全性的,而且你无需过度担心正常运行时间。

假设网络总体上是健康的(始终有超过 2/3 的节点在线,并且一直在终局化新的区块),在线时间超过 50% 的验证者将看到自己的权益会不断增加。而对每个人每天都在使用的智能手机而言,随时在线基本是每个人自己的刚需和必备。

引用以太坊基金会的ETH Staking指南系列文章中所言:

这就减轻了验证者在客户端备份和网络延迟上的负担,因为离线的惩罚并不严重。

究竟这样的方法是否可行?用事实说话!

为此目的,我们对在不同硬件、多个设置配置和几个用例下的以太坊2.0共识层(CL)客户端进行了全面的研究。这项研究花费了几个月的时间,消耗了近30000个CPU小时(3.4个CPU年),在此期间我们收集了超过7.35亿个数据点,从中提取了近1.5亿个数据点,绘制了大约1000个不同的数据,以显示不同的CL客户端的表现。

实验设置

我们测量了CL客户端在三个不同的硬件平台上的表现,一个标准节点、一个胖节点和一个Raspberry Pi 4b。我们还测试了默认配置以及所有主题配置以及客户端侦听 GossipSub 层上的所有子主题的全主题配置。我们测试的客户端和版本如下:

Prysm: 2.0.6

Lighthouse: 2.1.4

Teku: 22.3.2

Nimbus: 1.6.0

Lodestar: 0.34.0

Grandine: 0.2.0

整体性能分析

首先,我们绘制了不同CL客户端的CPU使用情况和内存消耗情况。我们看到,大多数CL客户端在标准节点上对CPU的使用都很合理。

▵ 图1 CPU消耗

就内存而言,它们都表现出了不同的性能。在这个实验中,Nimbus是内存消耗最低的一个。

▵ 图2 内存消耗

如果我们看一下磁盘使用情况,我们注意到不同客户端需要的存储空间有很大的不同,例如Lighthouse占用的存储空间是Teku的三倍,Teku是CL客户端中占用存储空间最少的,其次是Nimbus。

▵ 图3 磁盘使用情况

在磁盘写入操作方面,大多数客户端,尤其是Prysm,在同步过程开始时,每秒的磁盘写入操作次数较多,这一数字逐渐减少,直到Altair之后趋于平稳。

▵ 图4 每秒的磁盘写入操作

这可以解释为,在Beacon链的初期,验证者的数量远低于今天,而这些时段的时隙处理速度要快得多。这两个数字是相关的,正如我们在图3中所看到的,随着网络中验证者和证明数量的增加,磁盘使用量的增长在前半段相当低,在后半段则加速。

▵ 图5 每秒磁盘读取操作次数(标准节点)

关于每秒磁盘读取操作,我们发现了一个模式,我们已经与不同的团队讨论过,但还没有完全理解这种模式。在某个时刻,磁盘读取操作会急剧增加,这在除了Teku的大多数CL客户端中都可以观察到。这并不是一个真正的问题,因为它不会影响性能,但我们仍在试图理解为什么会发生这种情况。最明显暴露出这种行为的客户端是Prysm。我们已经与Prysmatic团队分享了这一发现,他们正在调查这一模式。更奇怪的是,对于大多数客户端来说,这几乎上是同时发生的,如图5所示,大约在slot 900K。

▵ 图6 每秒磁盘读取操作(胖节点)

我们在胖节点上重复了这个实验,我们看到了几乎相同的情况(图6),但这次的模式开始得要晚得多,大约在slot 2M附近。我们注意到这种情况也发生在Raspberry Pi上,但要更早。事实上,在拥有更多内存的节点上,这种现象发生得更晚,这使我们相信有某种内存缓存进程正在进行。当客户端达到其缓冲限制时,它开始产生大量的磁盘读取。

▵ 图7 从genesis的同步时间

在我们所做的大多数实验中,我们必须要同步CL客户端。我们同时尝试了两种方法,即从genesis同步和从检查点同步。这是一个有争议的观点,因为许多人表示,从genesis测量的同步速度不应该相关,还有人说,不管主观性多弱,从genesis开始同步仍然是该领域最常见的做法。由于我们对两者都进行了测试,所以我们给出了结果。在图7中,我们展示了CL客户端的同步速度。我们可以看到,Nimbus是所有开源CL客户端中同步速度最快的客户端。

▵ 图8 胖节点上的同步速度

我们还测试了Grandine,这是一个封闭源代码的CL客户端,它似乎在并行化共识处理的某些方面投入了大量的精力。在Grandine的高速处理中可以观察到这一点,如图8所示,这使得它的同步速度比所有其他客户端都快。请注意与磁盘写入操作类似的模式(图4)。实际上,slot的处理速度在开始时要快得多,然后迅速下降,直到达到平稳状态,这也与Beacon链开始时网络中验证者的数量较少有关。

▵图9 对等体数量

在网络带宽利用率方面,我们分析了CL客户端配对的对等体数量,我们可以看到有显著的差异(图9)。Lodestar只与25个对等体配对,而Nimbus是最灵活的,其范围在100到150个对等体之间,平均约125个对等体。Prysm显示的范围在40和60个对等体之间摇摆不定。Lighthouse和Teku也显示出非常稳定的对等策略。值得一提的是,我们对所有客户端的对等限制使用了默认配置。我们之所以选择这样做,是因为CL客户团队解释说,他们的客户端对这些数字进行了“优化”,更改它可能会影响性能。

▵ 图10 网络发送数据(MB/s)

当我们将其与网络活动进行比较时(图10),结果与预期略有不同。Nimbus拥有最多的对等体,但比大多数其他客户端占用更少的带宽。Lodestar带宽消耗低,这与对等体数量最少的情况相符。相反,Teku占用比所有客户端更多的带宽,当启用all-topics选项时,这一点尤其明显。我们已经与Teku团队分享了这些发现,他们正在调查这种高网络活动。Teku团队报告称,自v22.5.1更新以来,CPU减少了25%,输出带宽减少了38%。Lodestar在所有主题上也显示出一些奇怪的模式,在这种模式下,它发送的数据比默认模式下要少。Lodestar团队正在调查这个问题。

▵ 图11 API响应时间

我们还研究了CL客户端在存档模式下的行为(只有四个客户端支持存档模式)。存档模式是一种配置,在这种配置中,客户端存储了许多中间状态,以便能够轻松地回答关于区块链历史上任何时间的查询。这在设置区块资源管理器或一些类似的API时特别有用。我们向四个CL客户端发送了数千个请求,并记录了它们的响应时间,如图11所示。在这方面最慢的客户端是Prysm,因为他们只支持部分标准API,所以他们将查询转换为gRPC上的另一个接口,这增加了一定的开销。到目前为止,在存档模式下回答查询的所有客户端中,速度最快的是Teku,其响应时间非常快且稳定。在与Teku团队的交谈中,他们向我们解释说,他们开发了一种新的极其快速的树状结构状态存储来快速回答查询,这对Infura团队来说尤其有趣。

▵ 图12 Raspberry Pi上的内存使用情况

最后,我们在Raspberry Pi设备上测试了客户端。在这么小的设备上从genesis同步可能需要很长时间。令人高兴的是,检查点同步工作正常,所有CL客户端在这些低功耗设备上都表现得相当好。图12显示了Raspberry Pi上CL客户端的内存使用情况。

在这个详尽的评估过程中,我们发现了所有以太坊CL客户端的多个优点和改进空间。我们本研究的目标有三个方面:i)为CL客户端团队提供有用的反馈;ii)向以太坊基金会提供大量数据,以衡量以太坊2.0 CL客户端的准备情况;iii)最后但并非最不重要的是,为权益池运营商提供他们所需的所有信息,以指导有关CL客户端部署的决策。

经过实际验证分析,我们可以发现,基于以太坊2.0体系下的Web3手机客户端Nimbus最符合以太坊2.0的验证节点规范要求,是所有平台上对CPU和内存需求最低的客户端,同时也是同步速度最快的客户端。显然,它是更适合运行在低功耗设备手机终端上的客户端,但它在功能更强大的服务器上也同样表现良好。

让我们再次重温一遍Vitalik Buterin的《Endgame》:区块生产是中心化的,区块验证是去信任和高度分散的,并且仍然可以防止审查。手机作为以太坊2.0的轻节点,是完全可以实现愿景:只需为网络贡献少量数据,就让整个网络具有巨大意义! 要实现这个目的,就要求手机只需付出最小化的网络带宽、CPU、RAM和电池资源即可加入进来。显然,5G时代的智能手机要实现这一点,毫无困难!

results matching ""

    No results matching ""