Storage

Overview

The Credit Smart Chain currently utilizes LevelDB for data storage, as well as an in-memory data store.

Throughout the Credit Smart Chain, when modules need to interact with the underlying data store, they don't need to know which DB engine or service they're speaking to.

The DB layer is abstracted away between a module called Storage, which exports interfaces that modules query.

Each DB layer, for now only LevelDB, implements these methods separately, making sure they fit in with their implementation.

blockchain/storage/storage.go

// Storage is a generic blockchain storage
type Storage interface {
    ReadCanonicalHash(n uint64) (types.Hash, bool)
    WriteCanonicalHash(n uint64, hash types.Hash) error

    ReadHeadHash() (types.Hash, bool)
    ReadHeadNumber() (uint64, bool)
    WriteHeadHash(h types.Hash) error
    WriteHeadNumber(uint64) error

    WriteForks(forks []types.Hash) error
    ReadForks() ([]types.Hash, error)

    WriteDiff(hash types.Hash, diff *big.Int) error
    ReadDiff(hash types.Hash) (*big.Int, bool)

    WriteHeader(h *types.Header) error
    ReadHeader(hash types.Hash) (*types.Header, error)

    WriteCanonicalHeader(h *types.Header, diff *big.Int) error

    WriteBody(hash types.Hash, body *types.Body) error
    ReadBody(hash types.Hash) (*types.Body, error)

    WriteSnapshot(hash types.Hash, blob []byte) error
    ReadSnapshot(hash types.Hash) ([]byte, bool)

    WriteReceipts(hash types.Hash, receipts []*types.Receipt) error
    ReadReceipts(hash types.Hash) ([]*types.Receipt, error)

    WriteTxLookup(hash types.Hash, blockHash types.Hash) error
    ReadTxLookup(hash types.Hash) (types.Hash, bool)

    Close() error
}

LevelDB

Prefixes

In order to make querying the LevelDB storage deterministic, and to avoid key storage clashing, the Credit Smart Chain leverages prefixes and sub-prefixes when storing data

blockchain/storage/keyvalue.go

// Prefixes for the key-value store
var (
    // DIFFICULTY is the difficulty prefix
    DIFFICULTY = []byte("d")

    // HEADER is the header prefix
    HEADER = []byte("h")

    // HEAD is the chain head prefix
    HEAD = []byte("o")

    // FORK is the entry to store forks
    FORK = []byte("f")

    // CANONICAL is the prefix for the canonical chain numbers
    CANONICAL = []byte("c")

    // BODY is the prefix for bodies
    BODY = []byte("b")

    // RECEIPTS is the prefix for receipts
    RECEIPTS = []byte("r")

    // SNAPSHOTS is the prefix for snapshots
    SNAPSHOTS = []byte("s")

    // TX_LOOKUP_PREFIX is the prefix for transaction lookups
    TX_LOOKUP_PREFIX = []byte("l")
)

// Sub-prefixes
var (
    HASH   = []byte("hash")
    NUMBER = []byte("number")
    EMPTY  = []byte("empty")
)

Future Plans

The plans for the near future include adding some of the most popular DB solutions, such as:

  • PostgreSQL

  • MySQL

📜 Resources

Last updated