Skip to main content

Storage

Overview#

The Polygon SDK currently utilizes LevelDB for data storage, as well as an in-memory data store.

Throughout the SDK, 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 Polygon SDK 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#