引介 shadow-reth - 通过扩展执行层节点,极大方便链上数据索引
- 原文链接:blog.shadow.xyz/shadow-reth
- 译者:AI翻译官,校对:翻译小组
- 本文链接:learnblockchain.cn/article…
5 月,我们发布了 shadow-reth – 一个基于 Reth 的开源影子节点。
shadow-reth 包含了一系列 Reth 的修改,允许你通过 Execution Extensions 生成影子事件,并通过自定义 RPC 扩展轻松检索它们。
影子事件是一种强大的新原语,用于生成区块链数据,使开发者在处理来自智能合约的链上数据时拥有更大的自由度和灵活性。
影子事件带来了明显的好处:
我们的 托管平台 将强大的功能打包成一系列易于使用的特性,使单个开发者能够在几分钟内编写高级数据管道,而无需复杂的 ETL 管道或额外的离线基础设施。
然而,完全托管的平台存在信任无关性的权衡。尽管影子分叉不会以公共区块链的方式持有用户资金,但它们确实管理数据——而数据是非常有价值的。
我们相信,任何人都应该能够以去中心化和自托管的方式生成影子事件,并验证托管影子分叉生成的数据是否符合其影子合约实现的预期——就像任何人都可以通过自托管自己的主网节点来验证他们从托管主网 RPC 提供者获取的数据一样。
为此,我们发布了 shadow-reth:一个基于 Reth 的开源影子节点,采用 Apache 2.0 和 MIT 许可证。
Reth 执行扩展 引入了一种构建可定制、高效节点的框架。简而言之,执行扩展 (ExExes) 是构建 Reth 之上的离线基础设施的后执行Hook。
shadow-reth 利用 Reth ExExes 提供影子节点的开源实现,允许任何人生成影子事件并通过 JSON-RPC 检索它们。重要的是,这一切都可以在单一的 Reth 节点内运行,无需额外的离线基础设施或维护经过大量修改的客户端分叉。
这使得影子事件的好处对所有人可及,并随着其使用的普及,增加了信任无关性和可验证性。
接下来,让我们深入了解 shadow-reth 是如何构建的。
在高层次上,shadow-reth 有三个主要组件:
ShadowExEx
从规范链重放交易,使用提供的影子字节码覆盖配置。此重放生成影子日志并将其写入索引 (SQLite)。shadow_getLogs
),从索引中获取影子日志。shadow.json
)。这包含合约地址到影子合约字节码的映射。当 Reth 节点内发生某些事件时——例如区块被提交到链、重组和状态回退——Reth 的 ExExManager
会发出相应的 ExExNotification
,允许 ExEx Hook 链状态并在事件被发现时执行任意代码。这些通知使我们能够访问节点的状态、已提交链以及其他有用的上下文信息。
通过后执行Hook,我们实现了一个影子节点,能够以影子合约覆盖重新执行规范链,允许发出自定义的影子事件。我们通过执行扩展 ShadowExEx
来完成这一点,它监听 ExExNotification::ChainCommitted
事件,并利用提供的状态构造一个 ShadowDatabase<DB: revm::Database>
。该数据库实现封装了由通知的只读数据库提供者构建的 HistoricalStateProviderRef
,并用来自 shadow.json
的提供的覆盖替换合约字节码。
使用我们的 ShadowDatabase
,我们能够使用 ShadowExecutor
重新执行已提交的链;一个简单的区块执行器,能够用重写字节码来执行区块。我们使用这个自定义执行器而不是 Reth 的 BatchExecutor
,因为修改和执行自定义合约字节码会导致 gas 和状态根问题,从而导致执行器失败。另一方面,ShadowExecutor
不执行状态验证,而是使用 revm::Evm::transact_preverified()
来用影子字节码执行区块并将其状态提交到 ShadowDatabase
。从已执行区块的 ResultAndState
中,我们能够获取区块内发出的影子事件并将其保存到 SQLite。
此外,ShadowExEx
还监听 ChainReverted
通知,以便根据 以太坊 JSON-RPC 规范 将重组的影子事件标记为 removed
。
注意:尽管还有许多其他可扩展的数据库引擎,我们选择在这个初始实现中使用 SQLite,因为它在大多数系统上开箱即用,不需要额外安装,并且可以在单台机器上运行。我们希望 shadow-reth 支持多种数据目的地,如 Postgres,用户可以选择。
Shadow RPC 扩展允许你创建自定义方法的实现,以返回有关索引的影子事件的信息。它主要由 ShadowRpc
类型和 ShadowRpcApi
特性驱动。
ShadowRpc
类型作为数据库管理器和通用区块链提供者的包装器,允许访问链的状态。你可以根据需要更改和扩展这些类型;我们选择使用 SQLite 进行影子事件存储,是因为易于使用和可移植性,但这个类型及其实现可以轻松更改为使用不同的数据库产品,甚至在存储解决方案间保持无关性。
ShadowRpcApi
特性定义了自定义 RPC 扩展的公共接口,应该为 ShadowRpc
结构体实现。为了说明该扩展的功能和与影子数据交互的可能性,我们包含了一个 shadow_getLogs
RPC 调用:这是常用的 eth_getLogs
RPC 调用的命名空间等效。你可以使用与 eth_getLogs
中相同的请求参数检索影子合约的原始日志。
该接口还可以扩展以实现其他常见 RPC 调用,甚至完全是你影子数据唯一的新调用。ShadowRpc
类型上的 provider
字段使你能够访问链状态的多个部分,得益于 Reth 广泛的提供者特性集合;只需在自定义 RPC 调用的实现中包含必要的特性,你就能够使用你的 Reth 节点检索关于链的信息。
为了方便起见,你可以创建一个免费的 Shadow 账户,设置你希望具有自定义影子事件的合约,并下载 shadow.json
配置以在你自己的自托管 Reth 节点上运行。
或者,你可以使用任何外部工具生成影子合约字节码,例如 Foundry。未来,我们将发布一个集成,使你可以直接从 CLI 轻松完成这一步。
由于 shadow-reth 旨在与单个自托管节点一起使用,因此相对于 Shadow 托管平台,有几个重要的功能限制需要注意。
ShadowExecutor
重新执行区块时不会覆盖 gas 限制。如果在影子重新执行期间耗尽 gas,交易可能会失败,而且不会为该交易发出任何影子事件。shadow_getLogs
终端。eth_subscribe
websocket 订阅发布。我们很高兴能继续让影子事件对所有人可访问和可验证。
它们带来的好处:无权限无 gas 日志、更深的数据覆盖以及简化的索引管道是难以忽视的。然而,仍然有很多工作要做,以解锁它们向更广泛的加密生态系统承诺的全部潜力和好处。
未来,我们的目标是实现以下功能:
使用 shadow-reth,你将能够在不需要额外的离线基础设施或维护大量修改的客户端分支的情况下完成所有这些。如果你更喜欢不管理自己的节点,你也可以通过我们的托管平台轻松完成所有这些。
shadow-reth 的代码在 Github 上免费获取,遵循 Apache 2.0 和 MIT 许可证,供任何人无条件使用。我们鼓励社区进行分叉,贡献文档、问题、PR、问题甚至尝试破解它。我们非常期待看到你对此的贡献。
如果你希望与我们合作推动链上数据的未来,请通过 gm@shadow.xyz 与我们联系。
没有以下项目的辛勤工作,shadow-reth 将不可能实现:
ShadowExecutor
以及 Reth 本身的核心。如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!