Skip to content

Storage

prasad-kumkar edited this page May 5, 2025 · 1 revision

Storage

The jam.storage module provides persistent storage capabilities for the Tessera node, handling database interactions and data persistence.

Storage Components

The storage system consists of several key components:

Database Backend

Tessera uses RocksDB as its primary database backend:

  • Key-Value Store: Efficient key-value storage engine
  • Column Families: Logical separation of different data types
  • Transactions: Support for atomic operations
  • Snapshots: Point-in-time view of the database

Storage Layers

The storage system is organized into logical layers:

  • Low-Level Storage: Direct interaction with the database backend
  • Column Families: Data organization by type (blocks, state, metadata, etc.)
  • Storage Adapters: Type-specific storage interfaces
  • Caching Layer: Performance optimization through caching

Column Families

Data is organized into several column families:

  • META: Node metadata and configuration
  • BLOCKS: Block data (headers, bodies, justifications)
  • STATE: State trie nodes
  • TRANSACTIONS: Transaction data and indices
  • FINALITY: Finality data (votes, justifications)

Usage

from jam.storage import Storage

# Initialize storage
storage = Storage(db_path="./data/db")

# Basic key-value operations
storage.put(b"key", b"value")
value = storage.get(b"key")
storage.delete(b"key")

# Column family operations
storage.put(b"key", b"value", column_family="BLOCKS")
value = storage.get(b"key", column_family="BLOCKS")

# Batch operations
with storage.batch() as batch:
    batch.put(b"key1", b"value1")
    batch.put(b"key2", b"value2")
    batch.delete(b"key3")

# Iterating over keys
for key, value in storage.iterate_prefix(b"block:"):
    print(f"Key: {key}, Value: {value}")

# Database snapshots
snapshot = storage.create_snapshot()
value = storage.get_from_snapshot(b"key", snapshot)
storage.release_snapshot(snapshot)

Specialized Storage

The storage module provides specialized adapters for different data types:

BlockStorage

from jam.storage import BlockStorage

# Initialize block storage
block_storage = BlockStorage(storage)

# Store and retrieve blocks
block_storage.store_block(block)
block = block_storage.get_block_by_hash(block_hash)
block = block_storage.get_block_by_number(block_number)

# Check if a block exists
exists = block_storage.has_block(block_hash)

# Get canonical head
head = block_storage.get_canonical_head()

StateStorage

from jam.storage import StateStorage

# Initialize state storage
state_storage = StateStorage(storage)

# Store and retrieve state trie nodes
state_storage.store_node(key, node)
node = state_storage.get_node(key)

# Store and retrieve state roots
state_storage.store_state_root(block_hash, state_root)
state_root = state_storage.get_state_root(block_hash)

Configuration

Storage can be configured through the node configuration:

storage_config = {
    "path": "./data/db",
    "cache_size": 512,  # MB
    "max_open_files": 1000,
    "compression": "lz4",
    "create_if_missing": True
}

For detailed information about how state is stored and managed in the storage system, see ADR-0002: State Storage Design.

Clone this wiki locally