Fuel Core 存储系统提供了一个灵活的、支持事务的数据库层,为区块链状态提供支持。它同时支持持久化存储和内存存储,并具备历史状态访问能力。本文档解释了存储系统的架构、组件和关键概念。
有关基于此存储系统构建的数据模型的信息,请参阅数据模型。
来源:[crates/fuel-core/src/database.rs], [crates/fuel-core/src/state/data_source.rs]
存储系统分为多层组织
Database<OnChain>, Database<OffChain> 等RocksDb 和 MemoryStore 等实现Fuel Core 为不同类别的数据使用独立的数据库实例
每个数据库都实现了 DatabaseDescription trait(特性),该 trait 定义了其列、高度类型和其他特征。
来源:[crates/fuel-core/src/database/database_description], [crates/fuel-core/src/database/database_description/compression.rs]
数据被组织成列(类似于关系数据库中的表)。每列存储特定类型的数据,并通过唯一 ID 标识。例如
| 数据库类型 | 列类型 | 示例列 |
|---|---|---|
| 链上 | 链上列 | Fuel区块、事务、合约状态、消息 |
| 链下 | GraphQL 列 | 持有的代币、事务状态、持有的消息 ID |
| 中继器 | 中继器列 | 事件历史、DA 区块 |
| 压缩 | 压缩列 | 压缩区块 |
每列都由一个表蓝图进一步描述,该蓝图定义了键和值的编码、解码和访问方式。
来源:[crates/fuel-core/src/graphql_api/storage.rs], [crates/storage/src/structured_storage.rs]
主要的存储后端是 RocksDB,由 [crates/fuel-core/src/state/rocks_db.rs] 中的 RocksDb 结构体实现。它提供持久化存储,并具有以下特性:
The columns_policy 决定列族是惰性创建还是全部一次性创建
ColumnsPolicy::Lazy:仅在需要时创建列族ColumnsPolicy::OnCreation:在数据库打开时创建所有列族来源:[crates/fuel-core/src/state/rocks_db.rs:124-143]
HistoricalRocksDB 扩展了基本的 RocksDB 实现,增加了历史状态访问能力。它提供:
来源:[crates/fuel-core/src/state/historical_rocksdb.rs:76-87]
对于测试和临时用例,MemoryStore 后端提供内存实现
BTreeMap 集合中来源:[crates/fuel-core/src/state/in_memory/memory_store.rs]
存储系统采用事务模型,在原子提交之前将更改累积在内存中。
事务通过 read_transaction() 或 write_transaction() 方法创建
对事务执行的操作在内存中累积
更改以嵌套映射结构存储
当事务提交时,更改将应用于底层存储
对于区块链数据库,提交过程还会:
来源:[crates/storage/src/transactional.rs], [crates/fuel-core/src/database.rs:490-628]
存储系统的关键特性之一是能够访问历史状态。
系统跟踪每个区块高度的数据库状态
view_at 方法提供对历史状态的访问
历史访问通过以下方式实现:
系统支持不同的历史数据保留策略
来源:[crates/fuel-core/src/state/historical_rocksdb.rs], [crates/fuel-core/src/state/historical_rocksdb/view_at_height.rs]
存储系统为 GraphQL API 提供专用适配器
GraphQL 服务使用专用接口与存储交互
OnChainDatabase:访问区块链状态(区块、事务等)OffChainDatabase:访问索引数据(余额、所有权信息等)OnChainDatabaseAt/OffChainDatabaseAt:访问历史状态这些接口抽象了存储细节,仅提供 GraphQL 解析器所需的功能。
一个专门的工作服务处理新区块以更新链下数据库
这种链上和链下数据的分离允许高效查询,同时不影响核心区块链操作。
来源:[crates/fuel-core/src/graphql_api/worker_service.rs], [crates/fuel-core/src/service/adapters/graphql_api.rs]
存储系统定义了几个提供不同功能的关键接口
| 接口 | 目的 | 关键方法 |
|---|---|---|
KeyValueInspect | 对键值存储的基本只读访问 | get(), exists() |
KeyValueMutate | 键值存储的写入操作 | put(), delete() |
IterableStore | 存储内容的迭代 | iter_store(), iter_store_keys() |
原子视图 | 存储在某个时间点的原子视图 | latest_view() |
HistoricalView | 访问历史状态 | view_at(), latest_height() |
可修改 | 提交更改的能力 | commit_changes() |
TransactableStorage | 具有历史能力存储 | view_at_height(), rollback_block_to() |
表在原始键值存储之上提供了一个更高级别的接口
这种模式利用 Rust 的类型系统,为存储中的不同数据类型提供类型安全的访问。
来源:[crates/storage/src/kv_store.rs], [crates/fuel-core/src/state.rs], [crates/storage/src/structured_storage.rs]
Fuel Core 存储系统为区块链状态提供了坚实的基础,具有以下特点:
这种设计平衡了区块链执行层的性能、灵活性和可靠性要求。
来源:[crates/fuel-core/src/database.rs], [crates/fuel-core/src/state.rs]