Safe Haskell | None |
---|---|
Language | Haskell2010 |
Ouroboros.Consensus.Storage.ChainDB
Description
The storage layer is a highly specialized database for storing the blockchain. It consists of five subcomponents:
- An abstract file system API,
HasFS
, that smooths out over some differences between the file systems of different operating systems and, more importantly, allows us to simulate all kinds of failures. This is then used for stress-testing the other components below. - The Immutable DB, stores
the part of the chain that is immutable, that is, no longer subject to
rollback. It is an append-only database, providing efficient access to the
chain.
ImmutableDB
defines the immutable DB API. - The Volatile DB, stores the
part of the chain near its tip. This doesn't really store a chain as
such, but rather simply a collection of blocks from which we might
construct a chain.
VolatileDB
defines the volatile DB API. - The Ledger DB, stores the
\(k\) last ledger states corresponding to the blocks on the current chain
(which are part of the volatile DB), and means to read
LedgerTables
for them.LedgerDB
defines the ledger DB API. - The Chain DB finally combines all of these components. It makes decisions
about which chains to adopt (chain selection), switches to forks when
needed, deals with clock skew, and provides various interfaces to the rest
of the consensus layer for things like finding out which blocks were
invalid (so we can disconnect from the clients who sent them), cursors that
follow the tip of the chain (so that we can inform our downstream peers of
how our chain evolves), etc. In many ways, the chain DB is the component
that is responsible for "consensus": deciding which chain is the one true
chain.
ChainDB
defines the chain DB API.
Resource Management in the ChainDB
Clients of the ChainDB can allocate resources from the databases it contains (LedgerDB, VolatileDB, and ImmutableDB):
- The LedgerDB is used to create
Forker
s. - The ChainDB is used to create
Follower
s (which in turn containIterator
s).
These resources must eventually be freed.
Threads that make use of the ChainDB to allocate resources *MUST* be closed
before the ChainDB is closed. See runWith
for the
approach we follow in consensus to ensure this principle.