This document explains the StructuredStorage system in fuel-core, which provides type-safe, codec-aware access to key-value storage. The system uses blueprints to define how table data is encoded, decoded, and accessed, enabling strongly-typed operations over raw byte storage while maintaining flexibility in encoding strategies.
For information about the underlying transactional layer that accumulates changes, see Transactional Storage. For the raw key-value storage implementations (RocksDB, in-memory), see RocksDB Implementation and Database Architecture Overview.
The structured storage system forms a layered architecture that transforms raw key-value operations into type-safe table access:
Sources: crates/storage/src/structured_storage.rs1-434 crates/storage/src/kv_store.rs1-190 crates/fuel-core/src/state/rocks_db.rs1-100
The StructuredStorage<S> type wraps any key-value storage and provides blueprint-based access:
The wrapper delegates raw operations to the inner storage while providing typed operations through blueprints. It implements AsRef<S>, AsMut<S>, Deref, and DerefMut for transparent access to the underlying storage.
Sources: crates/storage/src/structured_storage.rs94-138 crates/storage/src/structured_storage.rs140-267
Tables declare their blueprint and column through the TableWithBlueprint trait:
| Component | Type | Purpose |
|---|---|---|
Blueprint | Associated type | Defines encoding/decoding strategy |
Column | Associated type | Column identifier for storage |
column() | Static method | Returns the column this table occupies |
The trait inherits from Mappable, which defines the key-value types:
Mappable Field | Purpose |
|---|---|
Key | The borrowed key type |
OwnedKey | The owned key type |
Value | The borrowed value type |
OwnedValue | The owned value type |
Sources: crates/storage/src/structured_storage.rs81-92 crates/fuel-core/src/database/metadata.rs25-47
Blueprints implement encoding/decoding logic through three core traits:
BlueprintCodec<M> defines the encoding strategy:
KeyCodec: Encoder for keys (e.g., Postcard, Raw)ValueCodec: Encoder for values (e.g., Postcard, Raw)BlueprintInspect<M, S> implements read operations:
get(storage, key, column): Retrieve typed valueexists(storage, key, column): Check existencesize_of_value(storage, key, column): Get value sizeBlueprintMutate<M, S> implements write operations:
put(storage, key, column, value): Insert valuereplace(storage, key, column, value): Replace and return olddelete(storage, key, column): Remove valuetake(storage, key, column): Remove and return valueSources: crates/storage/src/structured_storage.rs269-312 crates/storage/src/blueprint.rs1-100
Three primary codec types handle encoding and decoding:
| Codec | Encoding Strategy | Use Case |
|---|---|---|
Postcard | Postcard serialization (compact binary) | Structured data types (blocks, transactions) |
Raw | Identity (no encoding) | Byte slices [u8] |
Manual | Custom encoding logic | Special encoding requirements |
The Encode trait defines the encoding interface:
The Encoder trait provides access to encoded bytes:
Sources: crates/storage/src/codec/postcard.rs1-50 crates/storage/src/codec/raw.rs1-50 crates/storage/src/codec/manual.rs1-50
The following diagram shows how a typed table operation flows through the system:
Key encoding steps:
StructuredStorage delegates to blueprint's get() implementationKeyCodec::encode()ValueCodec::decode()Sources: crates/storage/src/structured_storage.rs269-284 crates/storage/src/blueprint/plain.rs1-100
The MetadataTable demonstrates a complete blueprint implementation:
The implementation in code:
Blueprint selection rationale:
Plain: No special indexing or merkle tree neededPostcard for key: Unit type () encodes to empty bytesPostcard for value: DatabaseMetadata is a structured enum requiring serializationSources: crates/fuel-core/src/database/metadata.rs25-47
StructuredStorage automatically implements high-level storage traits for any table with a blueprint:
The implementation:
M::Blueprintget() or exists() methodsM::column()Cow::Owned for zero-copy when possibleSources: crates/storage/src/structured_storage.rs269-312
All operations delegate to the blueprint's corresponding methods, ensuring consistent encoding/decoding.
Sources: crates/storage/src/structured_storage.rs287-312
The database system builds on StructuredStorage to provide domain-specific access:
| Type | Description | Role |
|---|---|---|
CombinedDatabase | Aggregates domain databases | Top-level database container |
Database<Description> | Domain-specific database | On-chain, off-chain, relayer domains |
GenericDatabase<Storage, Metadata> | Storage + metadata wrapper | Adds height tracking to storage |
StructuredStorage<S> | Blueprint-based wrapper | Provides typed table access |
DataSource<Description, Stage> | Storage abstraction | Wraps TransactableStorage trait object |
Application code accesses tables through the database:
The storage() method is provided by StorageAsRef trait, which gives access to the underlying StructuredStorage for any table type.
Sources: crates/fuel-core/src/database.rs171-193 crates/fuel-core/src/state/generic_database.rs30-58
StructuredStorage provides typed iteration over tables:
The IterableTable<M> implementation:
Iteration flow:
KeyCodeciter_store() with encoded keyKeyCodecValueCodec(Key, Value) pairsSources: crates/storage/src/iter.rs125-226
For tables implementing SupportsBatching, structured storage provides efficient batch operations:
Implementation:
Batch operations encode all keys and values at once, then call BatchOperations::batch_write() on the underlying storage, enabling atomic multi-entry operations with a single storage write.
Sources: crates/storage/src/structured_storage.rs325-356 crates/storage/src/kv_store.rs183-189
The structured storage system provides:
StorageInspect/StorageMutate traitsKeyValueInspect implementation (RocksDB, in-memory, etc.)The system achieves separation of concerns:
This architecture enables fuel-core to maintain a clean, type-safe database API while supporting multiple storage backends and encoding strategies.
Sources: crates/storage/src/structured_storage.rs1-434 crates/fuel-core/src/database.rs1-300
Refresh this wiki