Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
-
data
ChainDB
m blk =
ChainDB
{
- addBlockAsync :: InvalidBlockPunishment m -> blk -> m ( AddBlockPromise m blk)
- getCurrentChain :: STM m ( AnchoredFragment ( Header blk))
- getLedgerDB :: STM m ( LedgerDB ( ExtLedgerState blk))
- getTipBlock :: m ( Maybe blk)
- getTipHeader :: m ( Maybe ( Header blk))
- getTipPoint :: STM m ( Point blk)
- getBlockComponent :: forall b. BlockComponent blk b -> RealPoint blk -> m ( Maybe b)
- getIsFetched :: STM m ( Point blk -> Bool )
- getIsValid :: STM m ( RealPoint blk -> Maybe Bool )
- getMaxSlotNo :: STM m MaxSlotNo
- stream :: forall b. ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m ( Either ( UnknownRange blk) ( Iterator m blk b))
- newFollower :: forall b. ResourceRegistry m -> ChainType -> BlockComponent blk b -> m ( Follower m blk b)
- getIsInvalidBlock :: STM m ( WithFingerprint ( HeaderHash blk -> Maybe ( InvalidBlockReason blk)))
- closeDB :: m ()
- isOpen :: STM m Bool
- getCurrentLedger :: ( Monad ( STM m), IsLedger ( LedgerState blk)) => ChainDB m blk -> STM m ( ExtLedgerState blk)
- getCurrentTip :: ( Monad ( STM m), HasHeader ( Header blk)) => ChainDB m blk -> STM m ( Tip blk)
- getHeaderStateHistory :: Monad ( STM m) => ChainDB m blk -> STM m ( HeaderStateHistory blk)
- getImmutableLedger :: Monad ( STM m) => ChainDB m blk -> STM m ( ExtLedgerState blk)
- getPastLedger :: ( Monad ( STM m), LedgerSupportsProtocol blk) => ChainDB m blk -> Point blk -> STM m ( Maybe ( ExtLedgerState blk))
- getTipBlockNo :: ( Monad ( STM m), HasHeader ( Header blk)) => ChainDB m blk -> STM m ( WithOrigin BlockNo )
-
data
AddBlockPromise
m blk =
AddBlockPromise
{
- blockWrittenToDisk :: STM m Bool
- blockProcessed :: STM m ( Point blk)
- addBlock :: IOLike m => ChainDB m blk -> InvalidBlockPunishment m -> blk -> m ( Point blk)
- addBlockWaitWrittenToDisk :: IOLike m => ChainDB m blk -> InvalidBlockPunishment m -> blk -> m Bool
- addBlock_ :: IOLike m => ChainDB m blk -> InvalidBlockPunishment m -> blk -> m ()
-
data
WithPoint
blk b =
WithPoint
{
- withoutPoint :: !b
- point :: !( Point blk)
- getPoint :: BlockComponent blk ( Point blk)
- getSerialisedBlockWithPoint :: BlockComponent blk ( WithPoint blk ( Serialised blk))
- getSerialisedHeaderWithPoint :: BlockComponent blk ( WithPoint blk ( SerialisedHeader blk))
-
data
BlockComponent
blk a
where
- GetVerifiedBlock :: BlockComponent blk blk
- GetBlock :: BlockComponent blk blk
- GetRawBlock :: BlockComponent blk ByteString
- GetHeader :: BlockComponent blk ( Header blk)
- GetRawHeader :: BlockComponent blk ByteString
- GetHash :: BlockComponent blk ( HeaderHash blk)
- GetSlot :: BlockComponent blk SlotNo
- GetIsEBB :: BlockComponent blk IsEBB
- GetBlockSize :: BlockComponent blk Word32
- GetHeaderSize :: BlockComponent blk Word16
- GetNestedCtxt :: BlockComponent blk ( SomeSecond ( NestedCtxt Header ) blk)
- GetPure :: a -> BlockComponent blk a
- GetApply :: BlockComponent blk (a -> b) -> BlockComponent blk a -> BlockComponent blk b
- fromChain :: forall m blk. IOLike m => m ( ChainDB m blk) -> Chain blk -> m ( ChainDB m blk)
- toChain :: forall m blk. ( HasCallStack , IOLike m, HasHeader blk) => ChainDB m blk -> m ( Chain blk)
-
data
Iterator
m blk b =
Iterator
{
- iteratorNext :: m ( IteratorResult blk b)
- iteratorClose :: m ()
-
data
IteratorResult
blk b
- = IteratorExhausted
- | IteratorResult b
- | IteratorBlockGCed ( RealPoint blk)
-
data
StreamFrom
blk
- = StreamFromInclusive !( RealPoint blk)
- | StreamFromExclusive !( Point blk)
- newtype StreamTo blk = StreamToInclusive ( RealPoint blk)
-
data
UnknownRange
blk
- = MissingBlock ( RealPoint blk)
- | ForkTooOld ( StreamFrom blk)
- emptyIterator :: Monad m => Iterator m blk b
- streamAll :: ( MonadSTM m, HasHeader blk, HasCallStack ) => ChainDB m blk -> ResourceRegistry m -> BlockComponent blk b -> m ( Iterator m blk b)
- streamFrom :: ( MonadSTM m, HasHeader blk, HasCallStack ) => StreamFrom blk -> ChainDB m blk -> ResourceRegistry m -> BlockComponent blk b -> m ( Iterator m blk b)
- traverseIterator :: Monad m => (b -> m b') -> Iterator m blk b -> Iterator m blk b'
- validBounds :: StandardHash blk => StreamFrom blk -> StreamTo blk -> Bool
-
data
InvalidBlockReason
blk
- = ValidationError !( ExtValidationError blk)
- | InFutureExceedsClockSkew !( RealPoint blk)
- data ChainType
-
data
Follower
m blk a =
Follower
{
- followerInstruction :: m ( Maybe ( ChainUpdate blk a))
- followerInstructionBlocking :: m ( ChainUpdate blk a)
- followerForward :: [ Point blk] -> m ( Maybe ( Point blk))
- followerClose :: m ()
- traverseFollower :: Monad m => (b -> m b') -> Follower m blk b -> Follower m blk b'
-
data
ChainDbFailure
blk
- = LgrDbFailure FsError
- | ChainDbMissingBlock ( RealPoint blk)
- data IsEBB
-
data
ChainDbError
blk
- = ClosedDBError PrettyCallStack
- | ClosedFollowerError
- | InvalidIteratorRange ( StreamFrom blk) ( StreamTo blk)
Main ChainDB API
The chain database
The chain database provides a unified interface on top of:
- The ImmutableDB, storing the part of the chain that can't roll back.
- The VolatileDB, storing the blocks near the tip of the chain, possibly in multiple competing forks.
- The LedgerDB, storing snapshots of the ledger state for blocks in the ImmutableDB (and in-memory snapshots for the rest).
In addition to providing a unifying interface on top of these disparate components, the main responsibilities that the ChainDB itself has are:
- Chain selection (on initialization and whenever a block is added)
- Trigger full recovery whenever we detect disk failure in any component
- Provide iterators across fixed fragments of the current chain
- Provide followers that track the status of the current chain
The ChainDB instantiates all the various type parameters of these databases to conform to the unified interface we provide here.
ChainDB | |
|
getCurrentLedger :: ( Monad ( STM m), IsLedger ( LedgerState blk)) => ChainDB m blk -> STM m ( ExtLedgerState blk) Source #
Get current ledger
getCurrentTip :: ( Monad ( STM m), HasHeader ( Header blk)) => ChainDB m blk -> STM m ( Tip blk) Source #
getHeaderStateHistory :: Monad ( STM m) => ChainDB m blk -> STM m ( HeaderStateHistory blk) Source #
Get a
HeaderStateHistory
populated with the
HeaderState
s of the
last
k
blocks of the current chain.
getImmutableLedger :: Monad ( STM m) => ChainDB m blk -> STM m ( ExtLedgerState blk) Source #
Get the immutable ledger, i.e., typically
k
blocks back.
getPastLedger :: ( Monad ( STM m), LedgerSupportsProtocol blk) => ChainDB m blk -> Point blk -> STM m ( Maybe ( ExtLedgerState blk)) Source #
Get the ledger for the given point.
When the given point is not among the last
k
blocks of the current
chain (i.e., older than
k
or not on the current chain),
Nothing
is
returned.
getTipBlockNo :: ( Monad ( STM m), HasHeader ( Header blk)) => ChainDB m blk -> STM m ( WithOrigin BlockNo ) Source #
Adding a block
data AddBlockPromise m blk Source #
AddBlockPromise | |
|
addBlock :: IOLike m => ChainDB m blk -> InvalidBlockPunishment m -> blk -> m ( Point blk) Source #
Add a block synchronously: wait until the block has been processed (see
blockProcessed
). The new tip of the ChainDB is returned.
addBlockWaitWrittenToDisk :: IOLike m => ChainDB m blk -> InvalidBlockPunishment m -> blk -> m Bool Source #
Add a block synchronously: wait until the block has been written to disk
(see
blockWrittenToDisk
).
addBlock_ :: IOLike m => ChainDB m blk -> InvalidBlockPunishment m -> blk -> m () Source #
Add a block synchronously. Variant of
addBlock
that doesn't return the
new tip of the ChainDB.
Serialised block/header with its point
A
b
together with its
Point
.
The
Point
is needed because we often need to know the hash, slot, or
point itself of the block or header in question, and we don't want to
deserialise the block to obtain it.
WithPoint | |
|
Instances
StandardHash blk => StandardHash ( WithPoint blk b) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API |
|
type HeaderHash ( WithPoint blk b) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API |
getPoint :: BlockComponent blk ( Point blk) Source #
getSerialisedBlockWithPoint :: BlockComponent blk ( WithPoint blk ( Serialised blk)) Source #
getSerialisedHeaderWithPoint :: BlockComponent blk ( WithPoint blk ( SerialisedHeader blk)) Source #
BlockComponent
data BlockComponent blk a where Source #
Which component of the block to read from a database: the whole block, its header, its hash, the block size, ..., or combinations thereof.
NOTE: when requesting multiple components, we will not optimise/cache them.
GetVerifiedBlock :: BlockComponent blk blk |
Verify the integrity of the block by checking its signature and/or hashes. The interpreter should throw an exception when the block does not pass the check. |
GetBlock :: BlockComponent blk blk | |
GetRawBlock :: BlockComponent blk ByteString | |
GetHeader :: BlockComponent blk ( Header blk) | |
GetRawHeader :: BlockComponent blk ByteString | |
GetHash :: BlockComponent blk ( HeaderHash blk) | |
GetSlot :: BlockComponent blk SlotNo | |
GetIsEBB :: BlockComponent blk IsEBB | |
GetBlockSize :: BlockComponent blk Word32 | |
GetHeaderSize :: BlockComponent blk Word16 | |
GetNestedCtxt :: BlockComponent blk ( SomeSecond ( NestedCtxt Header ) blk) | |
GetPure :: a -> BlockComponent blk a | |
GetApply :: BlockComponent blk (a -> b) -> BlockComponent blk a -> BlockComponent blk b |
Instances
Functor ( BlockComponent blk) Source # | |
Defined in Ouroboros.Consensus.Storage.Common fmap :: (a -> b) -> BlockComponent blk a -> BlockComponent blk b Source # (<$) :: a -> BlockComponent blk b -> BlockComponent blk a Source # |
|
Applicative ( BlockComponent blk) Source # | |
Defined in Ouroboros.Consensus.Storage.Common pure :: a -> BlockComponent blk a Source # (<*>) :: BlockComponent blk (a -> b) -> BlockComponent blk a -> BlockComponent blk b Source # liftA2 :: (a -> b -> c) -> BlockComponent blk a -> BlockComponent blk b -> BlockComponent blk c Source # (*>) :: BlockComponent blk a -> BlockComponent blk b -> BlockComponent blk b Source # (<*) :: BlockComponent blk a -> BlockComponent blk b -> BlockComponent blk a Source # |
Support for tests
fromChain :: forall m blk. IOLike m => m ( ChainDB m blk) -> Chain blk -> m ( ChainDB m blk) Source #
toChain :: forall m blk. ( HasCallStack , IOLike m, HasHeader blk) => ChainDB m blk -> m ( Chain blk) Source #
Iterator API
data Iterator m blk b Source #
Iterator | |
|
Instances
Functor m => Functor ( Iterator m blk) Source # | |
Foldable m => Foldable ( Iterator m blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API fold :: Monoid m0 => Iterator m blk m0 -> m0 Source # foldMap :: Monoid m0 => (a -> m0) -> Iterator m blk a -> m0 Source # foldMap' :: Monoid m0 => (a -> m0) -> Iterator m blk a -> m0 Source # foldr :: (a -> b -> b) -> b -> Iterator m blk a -> b Source # foldr' :: (a -> b -> b) -> b -> Iterator m blk a -> b Source # foldl :: (b -> a -> b) -> b -> Iterator m blk a -> b Source # foldl' :: (b -> a -> b) -> b -> Iterator m blk a -> b Source # foldr1 :: (a -> a -> a) -> Iterator m blk a -> a Source # foldl1 :: (a -> a -> a) -> Iterator m blk a -> a Source # toList :: Iterator m blk a -> [a] Source # null :: Iterator m blk a -> Bool Source # length :: Iterator m blk a -> Int Source # elem :: Eq a => a -> Iterator m blk a -> Bool Source # maximum :: Ord a => Iterator m blk a -> a Source # minimum :: Ord a => Iterator m blk a -> a Source # |
|
Traversable m => Traversable ( Iterator m blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API traverse :: Applicative f => (a -> f b) -> Iterator m blk a -> f ( Iterator m blk b) Source # sequenceA :: Applicative f => Iterator m blk (f a) -> f ( Iterator m blk a) Source # mapM :: Monad m0 => (a -> m0 b) -> Iterator m blk a -> m0 ( Iterator m blk b) Source # sequence :: Monad m0 => Iterator m blk (m0 a) -> m0 ( Iterator m blk a) Source # |
data IteratorResult blk b Source #
IteratorExhausted | |
IteratorResult b | |
IteratorBlockGCed ( RealPoint blk) |
The block that was supposed to be streamed was garbage-collected from the VolatileDB, but not added to the ImmutableDB. This will only happen when streaming very old forks very slowly. |
Instances
data StreamFrom blk Source #
The lower bound for an iterator
Hint: use
to start streaming from
Genesis.
StreamFromExclusive
genesisPoint
StreamFromInclusive !( RealPoint blk) | |
StreamFromExclusive !( Point blk) |
Instances
StreamToInclusive ( RealPoint blk) |
Instances
StandardHash blk => Eq ( StreamTo blk) Source # | |
StandardHash blk => Show ( StreamTo blk) Source # | |
Generic ( StreamTo blk) Source # | |
( StandardHash blk, Typeable blk) => NoThunks ( StreamTo blk) Source # | |
type Rep ( StreamTo blk) Source # | |
Defined in Ouroboros.Consensus.Storage.Common
type
Rep
(
StreamTo
blk) =
D1
('
MetaData
"StreamTo" "Ouroboros.Consensus.Storage.Common" "ouroboros-consensus-0.1.0.1-DT4Cvwf63DZKctsEvaJqCU" '
True
) (
C1
('
MetaCons
"StreamToInclusive" '
PrefixI
'
False
) (
S1
('
MetaSel
('
Nothing
::
Maybe
Symbol
) '
NoSourceUnpackedness
'
NoSourceStrictness
'
DecidedLazy
) (
Rec0
(
RealPoint
blk))))
|
data UnknownRange blk Source #
MissingBlock ( RealPoint blk) |
The block at the given point was not found in the ChainDB. |
ForkTooOld ( StreamFrom blk) |
The requested range forks off too far in the past, i.e. it doesn't fit on the tip of the ImmutableDB. |
Instances
StandardHash blk => Eq ( UnknownRange blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API (==) :: UnknownRange blk -> UnknownRange blk -> Bool Source # (/=) :: UnknownRange blk -> UnknownRange blk -> Bool Source # |
|
StandardHash blk => Show ( UnknownRange blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API |
emptyIterator :: Monad m => Iterator m blk b Source #
An iterator that is immediately exhausted.
streamAll :: ( MonadSTM m, HasHeader blk, HasCallStack ) => ChainDB m blk -> ResourceRegistry m -> BlockComponent blk b -> m ( Iterator m blk b) Source #
Stream all blocks from the current chain.
streamFrom :: ( MonadSTM m, HasHeader blk, HasCallStack ) => StreamFrom blk -> ChainDB m blk -> ResourceRegistry m -> BlockComponent blk b -> m ( Iterator m blk b) Source #
Stream blocks from the given point up to the tip from the current chain.
To stream all blocks from the current chain from the ChainDB, one would use
as the lower bound and
StreamFromExclusive
genesisPoint
as the upper bound where
StreamToInclusive
tip
tip
is retrieved with
getTipPoint
.
However, when the ChainDB is empty,
tip
will be
genesisPoint
too, in
which case the bounds don't make sense. This function correctly handles
this case.
Note that this is not a
Follower
, so the stream will not include blocks
that are added to the current chain after starting the stream.
traverseIterator :: Monad m => (b -> m b') -> Iterator m blk b -> Iterator m blk b' Source #
Variant of
traverse
instantiated to
that executes
the monadic function when calling
Iterator
m blk
iteratorNext
.
validBounds :: StandardHash blk => StreamFrom blk -> StreamTo blk -> Bool Source #
Check whether the bounds make sense
An example of bounds that don't make sense:
StreamFromExclusive (BlockPoint 3 ..) StreamToInclusive (RealPoint 3 ..)
This function does not check whether the bounds correspond to existing blocks.
Invalid block reason
data InvalidBlockReason blk Source #
The reason why a block is invalid.
ValidationError !( ExtValidationError blk) |
The ledger found the block to be invalid. |
InFutureExceedsClockSkew !( RealPoint blk) |
The block's slot is in the future, exceeding the allowed clock skew. Possible causes, order by decreasing likelihood:
|
Instances
Followers
Chain type
Follower
s can choose to track changes to the "normal"
SelectedChain
, or
track the
TentativeChain
, which might contain a pipelineable header at the
tip.
Instances
Eq ChainType Source # | |
Show ChainType Source # | |
Generic ChainType Source # | |
type Rep ChainType Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API
type
Rep
ChainType
=
D1
('
MetaData
"ChainType" "Ouroboros.Consensus.Storage.ChainDB.API" "ouroboros-consensus-0.1.0.1-DT4Cvwf63DZKctsEvaJqCU" '
False
) (
C1
('
MetaCons
"SelectedChain" '
PrefixI
'
False
) (
U1
::
Type
->
Type
)
:+:
C1
('
MetaCons
"TentativeChain" '
PrefixI
'
False
) (
U1
::
Type
->
Type
))
|
data Follower m blk a Source #
Follower
See
newFollower
for more info.
The type parameter
a
will be instantiated with
blk
or
Header
blk@.
Follower | |
|
traverseFollower :: Monad m => (b -> m b') -> Follower m blk b -> Follower m blk b' Source #
Variant of
traverse
instantiated to
that executes the
monadic function when calling
Follower
m blk
followerInstruction
and
followerInstructionBlocking
.
Recovery
data ChainDbFailure blk Source #
Database failure
This exception wraps any kind of unexpected problem with the on-disk storage of the chain.
The various constructors only serve to give more detailed information about what went wrong, in case sysadmins want to investigate the disk failure. The Chain DB itself does not differentiate; all disk failures are treated equal and all trigger the same recovery procedure.
LgrDbFailure FsError |
The ledger DB threw a file-system error |
ChainDbMissingBlock ( RealPoint blk) |
Block missing from the chain DB Thrown when we are not sure in which DB the block should have been. |
Instances
StandardHash blk => Show ( ChainDbFailure blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API |
|
( Typeable blk, StandardHash blk) => Exception ( ChainDbFailure blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API toException :: ChainDbFailure blk -> SomeException Source # fromException :: SomeException -> Maybe ( ChainDbFailure blk) Source # displayException :: ChainDbFailure blk -> String Source # |
Whether a block is an Epoch Boundary Block (EBB)
See Ouroboros.Storage.ImmutableDB.API for a discussion of EBBs. Key idiosyncracies:
- An EBB carries no unique information.
-
An EBB has the same
BlockNo
as its predecessor. - EBBs are vestigial. As of Shelley, nodes no longer forge EBBs: they are only a legacy/backwards-compatibility concern.
Exceptions
data ChainDbError blk Source #
Database error
Thrown upon incorrect use: invalid input.
ClosedDBError PrettyCallStack |
The ChainDB is closed.
This will be thrown when performing any operation on the ChainDB except
for
|
ClosedFollowerError |
The follower is closed.
This will be thrown when performing any operation on a closed followers,
except for
|
InvalidIteratorRange ( StreamFrom blk) ( StreamTo blk) |
When there is no chain/fork that satisfies the bounds passed to
|
Instances
( Typeable blk, StandardHash blk) => Show ( ChainDbError blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API |
|
( Typeable blk, StandardHash blk) => Exception ( ChainDbError blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API toException :: ChainDbError blk -> SomeException Source # fromException :: SomeException -> Maybe ( ChainDbError blk) Source # displayException :: ChainDbError blk -> String Source # |