1 个不稳定版本

0.1.0 2024年7月12日

#8#l2

Download history 146/week @ 2024-07-11 32/week @ 2024-07-18 17/week @ 2024-07-25

195 每月下载
37 个crate(32个直接)中使用

MIT/Apache

1.5MB
33K SLoC

DAL(数据访问层)

此crate提供对主数据库(Postgres)的读写访问,它是真实来源的主数据库。

当前模式由 sqlx 管理。模式更改存储在 migrations 目录中。

模式概述

此概述跳过了与验证器相关的和以太坊发送者相关的表,这些表是主节点特有的。

L2 区块和L1 批次

  • miniblocks. 存储L2 区块头。命名是由于历史原因。

  • miniblocks_consensus. 存储与去中心化序列器使用的共识算法相关的L2 区块数据。与L2 区块一对一相关(关系的一端是可选的)。

  • l1_batches. 存储L1 批次头。

  • commitments. 存储L1 批次提交数据的一部分(事件队列和引导程序内存提交)。将来,其他与提交相关的列将从 l1_batches 移动到这里。

交易

  • transactions. 存储节点接收的所有交易,包括L2和L1交易。此表中的交易不一定包含在L2 区块中;即,此表还用作持久化内存池。

VM 存储

有关更多上下文,请参阅 zksync_state crate。

  • storage_logs。存储所有事务的VM存储写入日志,以及引导加载程序生成的非事务写入。这是VM存储的真相来源;所有其他VM存储实现(见zksync_state crate)都基于它(例如,通过添加持久或内存缓存)。由多个组件使用,包括元数据计算器、提交生成器、API服务器(用于读取一次性值,如账户余额,以及作为VM沙箱的一部分)等。

  • initial_writes。存储每个L1批次的初始写入信息,即每个键分配的枚举索引。在元数据计算器和提交生成器组件中生成L1批次元数据时使用,以及在API服务器中的VM沙箱中用于费用估算。

  • protective_reads。存储每个L1批次的保护读取信息,即未修改的、影响批次的VM执行的关键。在提交生成器中生成L1批次元数据时使用。

  • factory_deps。存储所有部署的L2合同的字节码。

  • storage。**已过时,将予以删除;不得在新的代码中使用。**

其他VM工件

  • events。存储在VM执行期间由智能合约发出的所有事件(又称日志)。

  • l2_to_l1_logs。存储在VM执行期间由智能合约发出的L2到L1日志。

  • call_traces。存储在VM执行期间发出的交易调用跟踪。(与L1节点实现不同,在Era中,当前所有交易都主动生成调用跟踪。)

  • tokens。存储在L1-L2桥中注册的所有ERC-20代币。

  • transaction_traces。**已过时,将予以删除;不得在新的代码中使用。**

快照生成和恢复

有关应用级节点快照的概述,请参阅snapshots_creatorsnapshots_applier crate。

  • snapshots。存储由snapshots_creator生成的所有快照的元数据,例如快照的L1批次。

  • snapshot_recovery。存储在节点恢复期间使用的快照的元数据(如果有)。目前,预期此表不会有超过一行。

逻辑不变性

除了直接在数据库模式中体现的外键约束和其他约束外,以下不变性预期将被维持

  • 如果在miniblocks表中存在一个标题,则预期数据库包含所有与L2块执行相关的工件,如eventsl2_to_l1_logscall_tracestokens等。(有关这些工件的精确定义,请参阅状态管理员I/O逻辑。)
  • 同样,如果在l1_batches表中存在一个标题,则预期数据库中也包含所有与L1批次执行相关的工件,例如initial_writesprotective_reads。(有关这些工件的精确定义,请参阅状态管理员I/O逻辑。)
  • 数据库中存在的L2块和L1批次形成一个连续的数字范围。如果从节点快照恢复数据库,则第一个L2块/L1批次是snapshot_recovery表中提到的快照L2块/L1批次之后的下一个(即下一个)。
  • addresskey 字段在 storage_logs 表中对于节点上执行的所有区块都不是空(即,其头信息存在于 miniblocks 中)。另一方面,addresskey 字段在快照存储日志中可能是空的。这些字段对于某些组件的后处理 L1 批次是必要的,例如 Merkle 树和承诺生成器。它们都使用 (address, key) 元组来对批次中的日志进行排序,以获得规范顺序。由于快照不会以这种方式进行后处理,因此对于快照日志可以接受跳过它们(仅限于快照日志)。

为 DAL 贡献

一些使贡献给 DAL 更容易的小技巧

  • 如果您想添加新的 DB 查询,请搜索 DAL 代码或 .sqlx 目录中的相同或等效查询。重用几乎总是比复制更好。
  • 通常使用 instrument 工具对您的查询进行检测是有意义的。有关详细信息,请参阅 instrument 模块文档。
  • 最好为添加的查询编写单元测试,以确保它们工作且未来不会出问题。虽然 sqlx 具有编译时模式检查,但这并不是万能的。
  • 如果对查询性能有疑问,请在生产规模数据库上运行带有 EXPLAIN / EXPLAIN ANALYZE 前缀的查询。

向后兼容性

预计所有 DB 模式更改都应该是向后兼容的。也就是说, 代码必须能够与 模式一起工作。例如,不允许删除/重命名列。相反,应使用两阶段迁移

  1. 应将列标记为已弃用,并在所有查询中替换其提及。如果应重命名列,则应创建新列并将数据(如果有的话)从旧列复制(另请参阅:程序性迁移)。
  2. 在经过显著的延迟(大约数月)后,旧列可以在单独的迁移中删除。

程序性迁移

我们不能承受由数据迁移引起的非平凡停机时间。也就是说,如果迁移可能引起此类停机时间(例如,它复制大量数据),则必须将其组织为程序性迁移,并在节点后台运行(可能将工作分割成多个部分,并在它们之间设置延迟,以便迁移不会占用所有数据库资源)。

依赖关系

~85MB
~1.5M SLoC