Reth 数据库的抽象、编码和表布局设计

本文介绍了 Reth 数据库的抽象、编码和表布局设计。

数据库

抽象

  • 我们使用 Rust Stable GATs 创建了一个 Database trait 抽象,这使我们不再受限于单一的数据库实现。我们目前使用 MDBX,但也正在探索 redb 作为替代方案。
  • 然后,我们对 Transaction 进行了迭代,作为一个非泄漏抽象,它带有用于严格类型化和单元测试的高级数据库抽象的助手函数。

编解码器

  • 我们希望 Reth 的序列化格式能够根据用户的不同,在读/写速度和大小之间进行权衡。
  • 为了实现这一点,我们创建了 Encode/Decode/Compress/Decompress traits,以使数据库 Table::KeyTable::Values 的(反)序列化具有通用性。
  • 我们为以下编码格式实现了该 trait:
    • 以太坊专用紧凑编码:许多以太坊数据类型在序列化时都有不必要的零,或者可选的(例如在空哈希上),如果不支付存储成本会很好。
    • Erigon 通过在 Table "PlainState" 上设置一个 bitfield 来实现这一点,该表向 Accounts 添加了一个位字段。
    • Akula 手动将其扩展到其他表和数据类型。它还通过使用 modular_bitfield crate 存储某些类型(U256, u64)的长度来节省更多空间,从而压缩了此信息。
    • 我们通过编写一个派生宏来自动生成用于实现该 trait 的代码,从而为所有类型对其进行了泛化。它还生成使用 ToB/test-fuzz 进行模糊测试所需的接口:
    • Scale Encoding
    • Postcard Encoding
    • Passthrough(在代码库中称为 no_codec
  • 我们通过一个名为 reth_codec 的派生宏,使得这些 trait 的实现变得容易,该宏委托给 Compact(默认)、Scale、Postcard 或 Passthrough 编码之一。这在 我们需要的每个结构体上都会被派生,并使我们能够在每次不必修改整个代码库的情况下尝试不同的编码格式。

表格布局

历史状态更改由 BlockNumber 索引。这意味着 reth 存储每个账户在触摸它的每个区块之后的状态,并提供用于快速访问该数据的索引。虽然这可能会使数据库大小更大(一旦 reth 更接近生产环境,就需要进行基准测试)。

下面,你可以看到实现此方案的表格设计:

erDiagram
CanonicalHeaders {
    u64 BlockNumber "PK"
    B256 HeaderHash "Value for CanonicalHeaders"
}
HeaderNumbers {
    B256 BlockHash "PK"
    u64 BlockNumber
}
Headers {
    u64 BlockNumber "PK"
    Header Data
}
BlockBodyIndices {
    u64 BlockNumber "PK"
    u64 first_tx_num
    u64 tx_count
}
BlockOmmers {
    u64 BlockNumber "PK"
    Header[] Ommers
}
BlockWithdrawals {
    u64 BlockNumber "PK"
    Withdrawal[] Withdrawals
}
Transactions {
    u64 TxNumber "PK"
    TransactionSigned Data
}
TransactionHashNumbers {
    B256 TxHash "PK"
    u64 TxNumber
}
TransactionBlocks {
    u64 MaxTxNumber "PK"
    u64 BlockNumber
}
Receipts {
    u64 TxNumber "PK"
    Receipt Data
}
Bytecodes {
    B256 CodeHash "PK"
    Bytes Code
}
PlainAccountState {
    Address Account "PK"
    Account Data
}
PlainStorageState {
    Address Account "PK"
    B256 StorageKey "PK"
    U256 StorageValue
}
AccountsHistory {
    B256 Account "PK"
    BlockNumberList BlockNumberList "List of transitions where account was changed"
}
StoragesHistory {
    B256 Account "PK"
    B256 StorageKey "PK"
    BlockNumberList BlockNumberList "List of transitions where account storage entry was changed"
}
AccountChangeSets {
    u64 BlockNumber "PK"
    B256 Account "PK"
    ChangeSet AccountChangeSets "Account before transition"
}
StorageChangeSets {
    u64 BlockNumber "PK"
    B256 Account "PK"
    B256 StorageKey "PK"
    ChangeSet StorageChangeSets "Storage entry before transition"
}
HashedAccounts {
    B256 HashedAddress "PK"
    Account Data
}
HashedStorages {
    B256 HashedAddress "PK"
    B256 HashedStorageKey "PK"
    U256 StorageValue
}
AccountsTrie {
    StoredNibbles Nibbles "PK"
    BranchNodeCompact Node
}
StoragesTrie {
    B256 HashedAddress "PK"
    StoredNibblesSubKey NibblesSubKey "PK"
    StorageTrieEntry Node
}
TransactionSenders {
    u64 TxNumber "PK"
    Address Sender
}
TransactionHashNumbers ||--|| Transactions : "hash -> tx id"
TransactionBlocks ||--|{ Transactions : "tx id -> block number"
BlockBodyIndices ||--o{ Transactions : "block number -> tx ids"
Headers ||--o{ AccountChangeSets : "each block has zero or more changesets"
Headers ||--o{ StorageChangeSets : "each block has zero or more changesets"
AccountsHistory }|--|{ AccountChangeSets : index
StoragesHistory }|--|{ StorageChangeSets : index
Headers ||--o| BlockOmmers : "each block has 0 or more ommers"
BlockBodyIndices ||--|| Headers : "index"
HeaderNumbers |o--|| Headers : "block hash -> block number"
CanonicalHeaders |o--|| Headers : "canonical chain block number -> block hash"
Transactions ||--|| Receipts : "each tx has a receipt"
PlainAccountState }o--o| Bytecodes : "an account can have a bytecode"
PlainAccountState ||--o{ PlainStorageState : "an account has 0 or more storage slots"
Transactions ||--|| TransactionSenders : "a tx has exactly 1 sender"

PlainAccountState ||--|| HashedAccounts : "hashed representation"
PlainStorageState ||--|| HashedStorages : "hashed representation"
  • 原文链接: github.com/paradigmxyz/r...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
paradigmxyz
paradigmxyz
江湖只有他的大名,没有他的介绍。