节点为什么删掉按哈希点菜的功能:EIP-4938与eth/67的瘦身 图 1
节点为什么删掉按哈希点菜的功能:EIP-4938与eth/67的瘦身 · 图 1

在以太坊节点的同步日志里,你偶尔会看到一种说法:老版本节点连上新网络后会有一些请求石沉大海。原因之一是协议里一条叫GetNodeData的消息被退役了。EIP-4938在2022年3月提出,把GetNodeData和NodeData这两条消息从线上协议中移除,随以太坊协议升级进入eth/67版本,提案状态是Final。要理解为什么删,得先理解节点同步时数据是怎么补的。

按哈希点菜:状态同步的最后一块补丁

以太坊执行层的同步大致分两步:先下载区块本体,再把执行这些交易需要的状态补齐。节点在重放交易时经常会发现手里缺某段合约代码或某个trie节点,于是需要向邻居节点要。GetNodeData的设计思路很直接:我知道缺失数据的哈希,我按哈希列一个清单发给你,你把对应的trie节点或代码给我带回来。听起来像按菜单点菜,精确又按需。问题出在两个地方。其一,节点执行时缺的东西往往是结构相关的——要一个账户的存储,往往顺带需要它的路径上一串节点,按单个哈希零散点菜等于把一趟车拆成几十趟;其二,实现这条消息的软件长期存在缺陷,返回数据不完整、格式对不上的报告时有耳闻,客户端开发者在EIP里直接把它列为动机之一。

删掉消息之后,缺的数据从哪来

退役不等于不需要这些数据。替代路线是从区块下载阶段就把状态变更打包着传:新的同步流程让节点按批次从对端领取区块对应的状态数据(围绕这一思路另有专门的提案把状态分发做成结构化消息),执行时按顺序领用,缺件率大幅下降。剩下偶尔的缺口,节点可以用另一条状态服务消息定向补齐,或者用全量快照类方案直接跳过逐个补齐的阶段。从协议视角看,这是一次典型的删繁就简:一条实现不可靠、效率又差的消息,被两条更成体系的通道取代。

对普通用户意味着什么

绝大多数人不会直接感知这次改动。能感知的是运维:跑老版本节点的人升级后,软件会自动改用新版本的消息集与邻居交流;如果一个节点迟迟不升级,它和新节点之间就少了一种共同语言,同步效率下降。另一个间接影响是网络整体的带宽利用率——按哈希点菜的请求模式被批评为放大器,一次缺口触发一串往返,删掉之后同类同步的流量结构更接近流水线。

一次同步的两种剧本

把同一个缺口放进两条时间线里对比最直观。老协议下:节点重放交易时发现缺一段代码,发一条按哈希点菜的请求,等回复,发现还缺它依赖的路径节点,再发一条——每个来回都是一次完整往返,缺口越结构化,往返越碎片化。新协议下:同一个区块的状态数据在下载阶段已经随批次到达,执行到那一步直接从待用队列里取,取不到的概率只剩边角情形。两种剧本的差别不在单点速度,而在等待次数:前者等待次数由数据结构决定,后者接近常数。这正是协议设计里常见的换法——宁可让不需要同步的普通请求多带一点数据,也要把最坏路径上的往返次数压下来。

快速问答

问:删一条消息不会让老节点断连吗? 答:不会一刀切。节点之间先协商用哪个协议版本,老版本节点之间照常使用旧消息;只有双方都支持eth/67及以上时才走新规矩。协议的代际是叠加的,不是一刀切除。 问:这条提案是硬分叉吗? 答:它属于网络协议层面的变更,不改变交易的共识规则;但它随升级周期一起发布,实际部署节奏与硬分叉协调在一起。 问:为什么要等这么多年才删? 答:删消息的前提是替代品成熟。状态分发和快照两条路线的实现在2021年前后才在主要客户端里站稳,过早删除会让所有节点同时失去兜底。

风险提示:本文描述协议机制,不构成任何投资建议,也不涉及任何资产的买卖时机判断。协议版本信息以以太坊官方仓库与EIP原文为准。