| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Ouroboros.Consensus.Storage.ChainDB.API
Synopsis
- data ChainDB m blk = ChainDB {
- addBlockAsync :: blk -> m (AddBlockPromise m blk)
- getCurrentChain :: STM m (AnchoredFragment (Header blk))
- getCurrentLedger :: STM m (ExtLedgerState blk)
- getPastLedger :: Point blk -> STM m (Maybe (ExtLedgerState blk))
- getHeaderStateHistory :: STM m (HeaderStateHistory 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))
- newReader :: forall b. ResourceRegistry m -> BlockComponent blk b -> m (Reader m blk b)
- getIsInvalidBlock :: STM m (WithFingerprint (HeaderHash blk -> Maybe (InvalidBlockReason blk)))
- closeDB :: m ()
- isOpen :: STM m Bool
- getCurrentTip :: (Monad (STM m), HasHeader (Header blk)) => ChainDB m blk -> STM m (Tip 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)
- addBlockWaitWrittenToDisk :: IOLike m => ChainDB m blk -> blk -> m Bool
- addBlock :: IOLike m => ChainDB m blk -> blk -> m (Point blk)
- addBlock_ :: IOLike m => ChainDB m blk -> blk -> m ()
- data WithPoint blk b = WithPoint {
- withoutPoint :: !b
- point :: !(Point blk)
- getSerialisedBlockWithPoint :: BlockComponent blk (WithPoint blk (Serialised blk))
- getSerialisedHeaderWithPoint :: BlockComponent blk (WithPoint blk (SerialisedHeader blk))
- getPoint :: BlockComponent blk (Point 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
- toChain :: forall m blk. (HasCallStack, IOLike m, HasHeader blk) => ChainDB m blk -> m (Chain blk)
- fromChain :: forall m blk. IOLike m => m (ChainDB m blk) -> Chain blk -> m (ChainDB m blk)
- data StreamFrom blk
- = StreamFromInclusive !(RealPoint blk)
- | StreamFromExclusive !(Point blk)
- newtype StreamTo blk = StreamToInclusive (RealPoint blk)
- data Iterator m blk b = Iterator {
- iteratorNext :: m (IteratorResult blk b)
- iteratorClose :: m ()
- data IteratorResult blk b
- = IteratorExhausted
- | IteratorResult b
- | IteratorBlockGCed (RealPoint blk)
- emptyIterator :: Monad m => Iterator m blk b
- traverseIterator :: Monad m => (b -> m b') -> Iterator m blk b -> Iterator m blk b'
- data UnknownRange blk
- = MissingBlock (RealPoint blk)
- | ForkTooOld (StreamFrom blk)
- validBounds :: StandardHash blk => StreamFrom blk -> StreamTo blk -> Bool
- streamAll :: (MonadSTM m, HasHeader blk, HasCallStack) => ChainDB m blk -> ResourceRegistry m -> BlockComponent blk b -> m (Iterator m blk b)
- data InvalidBlockReason blk
- = ValidationError !(ExtValidationError blk)
- | InFutureExceedsClockSkew !(RealPoint blk)
- data Reader m blk a = Reader {
- readerInstruction :: m (Maybe (ChainUpdate blk a))
- readerInstructionBlocking :: m (ChainUpdate blk a)
- readerForward :: [Point blk] -> m (Maybe (Point blk))
- readerClose :: m ()
- traverseReader :: Monad m => (b -> m b') -> Reader m blk b -> Reader m blk b'
- data ChainDbFailure
- = LgrDbFailure FsError
- | forall blk.(Typeable blk, StandardHash blk) => ChainDbMissingBlock (RealPoint blk)
- data IsEBB
- data ChainDbError
- = ClosedDBError PrettyCallStack
- | ClosedReaderError
- | forall blk.(Typeable blk, StandardHash blk) => 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 readers 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.
Constructors
| ChainDB | |
Fields
| |
getCurrentTip :: (Monad (STM m), HasHeader (Header blk)) => ChainDB m blk -> STM m (Tip blk) Source #
getTipBlockNo :: (Monad (STM m), HasHeader (Header blk)) => ChainDB m blk -> STM m (WithOrigin BlockNo) Source #
Adding a block
data AddBlockPromise m blk Source #
Constructors
| AddBlockPromise | |
Fields
| |
addBlockWaitWrittenToDisk :: IOLike m => ChainDB m blk -> 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 -> 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.
addBlock_ :: IOLike m => ChainDB m blk -> 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.
Constructors
| WithPoint | |
Fields
| |
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 | |
getSerialisedBlockWithPoint :: BlockComponent blk (WithPoint blk (Serialised blk)) Source #
getSerialisedHeaderWithPoint :: BlockComponent blk (WithPoint blk (SerialisedHeader blk)) Source #
getPoint :: BlockComponent blk (Point 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.
Constructors
| 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 Methods fmap :: (a -> b) -> BlockComponent blk a -> BlockComponent blk b # (<$) :: a -> BlockComponent blk b -> BlockComponent blk a # | |
| Applicative (BlockComponent blk) Source # | |
Defined in Ouroboros.Consensus.Storage.Common Methods pure :: a -> BlockComponent blk a # (<*>) :: BlockComponent blk (a -> b) -> BlockComponent blk a -> BlockComponent blk b # liftA2 :: (a -> b -> c) -> BlockComponent blk a -> BlockComponent blk b -> BlockComponent blk c # (*>) :: BlockComponent blk a -> BlockComponent blk b -> BlockComponent blk b # (<*) :: BlockComponent blk a -> BlockComponent blk b -> BlockComponent blk a # | |
Support for tests
toChain :: forall m blk. (HasCallStack, IOLike m, HasHeader blk) => ChainDB m blk -> m (Chain blk) Source #
Iterator API
data StreamFrom blk Source #
The lower bound for an iterator
Hint: use to start streaming from
Genesis.StreamFromExclusive genesisPoint
Constructors
| StreamFromInclusive !(RealPoint blk) | |
| StreamFromExclusive !(Point blk) |
Instances
Constructors
| 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.0-GfJNvFcM6lj2s5utKAUPEp" 'True) (C1 ('MetaCons "StreamToInclusive" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (RealPoint blk)))) | |
data Iterator m blk b Source #
Constructors
| Iterator | |
Fields
| |
Instances
| Functor m => Functor (Iterator m blk) Source # | |
| Foldable m => Foldable (Iterator m blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API Methods fold :: Monoid m0 => Iterator m blk m0 -> m0 # foldMap :: Monoid m0 => (a -> m0) -> Iterator m blk a -> m0 # foldMap' :: Monoid m0 => (a -> m0) -> Iterator m blk a -> m0 # foldr :: (a -> b -> b) -> b -> Iterator m blk a -> b # foldr' :: (a -> b -> b) -> b -> Iterator m blk a -> b # foldl :: (b -> a -> b) -> b -> Iterator m blk a -> b # foldl' :: (b -> a -> b) -> b -> Iterator m blk a -> b # foldr1 :: (a -> a -> a) -> Iterator m blk a -> a # foldl1 :: (a -> a -> a) -> Iterator m blk a -> a # toList :: Iterator m blk a -> [a] # null :: Iterator m blk a -> Bool # length :: Iterator m blk a -> Int # elem :: Eq a => a -> Iterator m blk a -> Bool # maximum :: Ord a => Iterator m blk a -> a # minimum :: Ord a => Iterator m blk a -> a # | |
| Traversable m => Traversable (Iterator m blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API Methods traverse :: Applicative f => (a -> f b) -> Iterator m blk a -> f (Iterator m blk b) # sequenceA :: Applicative f => Iterator m blk (f a) -> f (Iterator m blk a) # mapM :: Monad m0 => (a -> m0 b) -> Iterator m blk a -> m0 (Iterator m blk b) # sequence :: Monad m0 => Iterator m blk (m0 a) -> m0 (Iterator m blk a) # | |
data IteratorResult blk b Source #
Constructors
| 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
emptyIterator :: Monad m => Iterator m blk b Source #
An iterator that is immediately exhausted.
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 blkiteratorNext.
data UnknownRange blk Source #
Constructors
| 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 Methods (==) :: UnknownRange blk -> UnknownRange blk -> Bool # (/=) :: UnknownRange blk -> UnknownRange blk -> Bool # | |
| StandardHash blk => Show (UnknownRange blk) Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API Methods showsPrec :: Int -> UnknownRange blk -> ShowS # show :: UnknownRange blk -> String # showList :: [UnknownRange blk] -> ShowS # | |
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.
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.
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 tiptip 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 Reader, so the stream will not include blocks
that are added to the current chain after starting the stream.
Invalid block reason
data InvalidBlockReason blk Source #
The reason why a block is invalid.
Constructors
| 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
Readers
Reader
See newHeaderReader for more info.
The type parameter a will be instantiated with blk or Header blk@.
Constructors
| Reader | |
Fields
| |
traverseReader :: Monad m => (b -> m b') -> Reader m blk b -> Reader m blk b' Source #
Variant of traverse instantiated to that executes the
monadic function when calling Reader m blkreaderInstruction and
readerInstructionBlocking.
Recovery
data ChainDbFailure 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.
Constructors
| LgrDbFailure FsError | The ledger DB threw a file-system error |
| forall blk.(Typeable blk, StandardHash blk) => ChainDbMissingBlock (RealPoint blk) | Block missing from the chain DB Thrown when we are not sure in which DB the block should have been. |
Instances
| Show ChainDbFailure Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API Methods showsPrec :: Int -> ChainDbFailure -> ShowS # show :: ChainDbFailure -> String # showList :: [ChainDbFailure] -> ShowS # | |
| Exception ChainDbFailure Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API Methods toException :: ChainDbFailure -> SomeException # | |
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
BlockNoas its predecessor. - EBBs are vestigial. As of Shelley, nodes no longer forge EBBs: they are only a legacy/backwards-compatibility concern.
Exceptions
data ChainDbError Source #
Database error
Thrown upon incorrect use: invalid input.
Constructors
| ClosedDBError PrettyCallStack | The ChainDB is closed. This will be thrown when performing any operation on the ChainDB except
for |
| ClosedReaderError | The reader is closed. This will be thrown when performing any operation on a closed readers,
except for |
| forall blk.(Typeable blk, StandardHash blk) => InvalidIteratorRange (StreamFrom blk) (StreamTo blk) | When there is no chain/fork that satisfies the bounds passed to
|
Instances
| Show ChainDbError Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API Methods showsPrec :: Int -> ChainDbError -> ShowS # show :: ChainDbError -> String # showList :: [ChainDbError] -> ShowS # | |
| Exception ChainDbError Source # | |
Defined in Ouroboros.Consensus.Storage.ChainDB.API Methods toException :: ChainDbError -> SomeException # fromException :: SomeException -> Maybe ChainDbError # displayException :: ChainDbError -> String # | |