Safe Haskell | None |
---|---|
Language | Haskell2010 |
Ouroboros.Consensus.Storage.LedgerDB.OnDisk
Synopsis
- data InitFailure blk
-
data
InitLog
blk
- = InitFromGenesis
- | InitFromSnapshot DiskSnapshot ( RealPoint blk)
- | InitFailure DiskSnapshot ( InitFailure blk) ( InitLog blk)
- initLedgerDB :: forall m blk. ( IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasCallStack ) => Tracer m ( ReplayGoal blk -> TraceReplayEvent blk) -> Tracer m ( TraceEvent blk) -> SomeHasFS m -> ( forall s. Decoder s ( ExtLedgerState blk)) -> ( forall s. Decoder s ( HeaderHash blk)) -> LedgerDbCfg ( ExtLedgerState blk) -> m ( ExtLedgerState blk) -> StreamAPI m blk -> m ( InitLog blk, LedgerDB' blk, Word64 )
- type AnnLedgerError' blk = AnnLedgerError ( ExtLedgerState blk) blk
- type LedgerDB' blk = LedgerDB ( ExtLedgerState blk)
-
data
NextBlock
blk
- = NoMoreBlocks
- | NextBlock blk
-
data
StreamAPI
m blk =
StreamAPI
{
- streamAfter :: forall a. HasCallStack => Point blk -> ( Either ( RealPoint blk) (m ( NextBlock blk)) -> m a) -> m a
- readSnapshot :: forall m blk. IOLike m => SomeHasFS m -> ( forall s. Decoder s ( ExtLedgerState blk)) -> ( forall s. Decoder s ( HeaderHash blk)) -> DiskSnapshot -> ExceptT ReadIncrementalErr m ( ExtLedgerState blk)
- takeSnapshot :: forall m blk. ( MonadThrow m, IsLedger ( LedgerState blk)) => Tracer m ( TraceEvent blk) -> SomeHasFS m -> ( ExtLedgerState blk -> Encoding ) -> LedgerDB' blk -> m ( Maybe ( DiskSnapshot , RealPoint blk))
- trimSnapshots :: Monad m => Tracer m ( TraceEvent r) -> SomeHasFS m -> DiskPolicy -> m [ DiskSnapshot ]
- writeSnapshot :: forall m blk. MonadThrow m => SomeHasFS m -> ( ExtLedgerState blk -> Encoding ) -> DiskSnapshot -> ExtLedgerState blk -> m ()
- deleteSnapshot :: HasCallStack => SomeHasFS m -> DiskSnapshot -> m ()
- snapshotToFileName :: DiskSnapshot -> String
- snapshotToPath :: DiskSnapshot -> FsPath
- data DiskSnapshot = DiskSnapshot { }
- newtype ReplayGoal blk = ReplayGoal ( Point blk)
- newtype ReplayStart blk = ReplayStart ( Point blk)
-
data
TraceEvent
blk
- = InvalidSnapshot DiskSnapshot ( InitFailure blk)
- | TookSnapshot DiskSnapshot ( RealPoint blk)
- | DeletedSnapshot DiskSnapshot
-
data
TraceReplayEvent
blk
- = ReplayFromGenesis ( ReplayGoal blk)
- | ReplayFromSnapshot DiskSnapshot ( RealPoint blk) ( ReplayStart blk) ( ReplayGoal blk)
- | ReplayedBlock ( RealPoint blk) [ LedgerEvent blk] ( ReplayStart blk) ( ReplayGoal blk)
- decorateReplayTracerWithGoal :: Point blk -> Tracer m ( TraceReplayEvent blk) -> Tracer m ( ReplayGoal blk -> TraceReplayEvent blk)
Opening the database
data InitFailure blk Source #
Constructors
InitFailureRead ReadIncrementalErr |
We failed to deserialise the snapshot This can happen due to data corruption in the ledger DB. |
InitFailureTooRecent ( RealPoint blk) |
This snapshot is too recent (ahead of the tip of the chain) |
InitFailureGenesis |
This snapshot was of the ledger state at genesis, even though we never take snapshots at genesis, so this is unexpected. |
Instances
Initialization log
The initialization log records which snapshots from disk were considered, in which order, and why some snapshots were rejected. It is primarily useful for monitoring purposes.
Constructors
InitFromGenesis |
Defaulted to initialization from genesis NOTE: Unless the blockchain is near genesis, we should see this only if data corrupted occurred. |
InitFromSnapshot DiskSnapshot ( RealPoint blk) |
Used a snapshot corresponding to the specified tip |
InitFailure DiskSnapshot ( InitFailure blk) ( InitLog blk) |
Initialization skipped a snapshot We record the reason why it was skipped. NOTE: We should only see this if data corrupted occurred. |
Instances
Arguments
:: forall m blk. ( IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasCallStack ) | |
=> Tracer m ( ReplayGoal blk -> TraceReplayEvent blk) | |
-> Tracer m ( TraceEvent blk) | |
-> SomeHasFS m | |
-> ( forall s. Decoder s ( ExtLedgerState blk)) | |
-> ( forall s. Decoder s ( HeaderHash blk)) | |
-> LedgerDbCfg ( ExtLedgerState blk) | |
-> m ( ExtLedgerState blk) |
Genesis ledger state |
-> StreamAPI m blk | |
-> m ( InitLog blk, LedgerDB' blk, Word64 ) |
Initialize the ledger DB from the most recent snapshot on disk
If no such snapshot can be found, use the genesis ledger DB. Returns the initialized DB as well as the block reference corresponding to the snapshot we found on disk (the latter primarily for testing/monitoring purposes).
We do
not
catch any exceptions thrown during streaming; should any be
thrown, it is the responsibility of the
ChainDB
to catch these
and trigger (further) validation. We only discard snapshots if
- We cannot deserialise them, or
- they are ahead of the chain
It is possible that the Ledger DB will not be able to roll back
k
blocks
after initialization if the chain has been truncated (data corruption).
We do not attempt to use multiple ledger states from disk to construct the ledger DB. Instead we load only a single ledger state from disk, and compute all subsequent ones. This is important, because the ledger states obtained in this way will (hopefully) share much of their memory footprint with their predecessors.
Instantiate in-memory to
blk
type AnnLedgerError' blk = AnnLedgerError ( ExtLedgerState blk) blk Source #
type LedgerDB' blk = LedgerDB ( ExtLedgerState blk) Source #
Abstraction over the stream API
Next block returned during streaming
Constructors
NoMoreBlocks | |
NextBlock blk |
Stream blocks from the immutable DB
When we initialize the ledger DB, we try to find a snapshot close to the tip of the immutable DB, and then stream blocks from the immutable DB to its tip to bring the ledger up to date with the tip of the immutable DB.
In CPS form to enable the use of
withXYZ
style iterator init functions.
Constructors
StreamAPI | |
Fields
|
Read from disk
readSnapshot :: forall m blk. IOLike m => SomeHasFS m -> ( forall s. Decoder s ( ExtLedgerState blk)) -> ( forall s. Decoder s ( HeaderHash blk)) -> DiskSnapshot -> ExceptT ReadIncrementalErr m ( ExtLedgerState blk) Source #
Read snapshot from disk
Write to disk
takeSnapshot :: forall m blk. ( MonadThrow m, IsLedger ( LedgerState blk)) => Tracer m ( TraceEvent blk) -> SomeHasFS m -> ( ExtLedgerState blk -> Encoding ) -> LedgerDB' blk -> m ( Maybe ( DiskSnapshot , RealPoint blk)) Source #
Take a snapshot of the oldest ledger state in the ledger DB
We write the
oldest
ledger state to disk because the intention is to only
write ledger states to disk that we know to be immutable. Primarily for
testing purposes,
takeSnapshot
returns the block reference corresponding
to the snapshot that we wrote.
If a snapshot with the same number already exists on disk or if the tip is at genesis, no snapshot is taken.
Note that an EBB can have the same slot number and thus snapshot number as the block after it. This doesn't matter. The one block difference in the ledger state doesn't warrant an additional snapshot. The number in the name of the snapshot is only indicative, we don't rely on it being correct.
NOTE: This is a lower-level API that takes a snapshot independent from
whether this snapshot corresponds to a state that is more than
k
back.
TODO: Should we delete the file if an error occurs during writing?
trimSnapshots :: Monad m => Tracer m ( TraceEvent r) -> SomeHasFS m -> DiskPolicy -> m [ DiskSnapshot ] Source #
Trim the number of on disk snapshots so that at most
onDiskNumSnapshots
snapshots are stored on disk. The oldest snapshots are deleted.
The deleted snapshots are returned.
writeSnapshot :: forall m blk. MonadThrow m => SomeHasFS m -> ( ExtLedgerState blk -> Encoding ) -> DiskSnapshot -> ExtLedgerState blk -> m () Source #
Write snapshot to disk
Low-level API (primarily exposed for testing)
deleteSnapshot :: HasCallStack => SomeHasFS m -> DiskSnapshot -> m () Source #
Delete snapshot from disk
snapshotToPath :: DiskSnapshot -> FsPath Source #
opaque
data DiskSnapshot Source #
Constructors
DiskSnapshot | |
Fields
|
Instances
Trace events
newtype ReplayGoal blk Source #
Which point the replay is expected to end at
Constructors
ReplayGoal ( Point blk) |
Instances
StandardHash blk => Eq ( ReplayGoal blk) Source # | |
Defined in Ouroboros.Consensus.Storage.LedgerDB.OnDisk Methods (==) :: ReplayGoal blk -> ReplayGoal blk -> Bool Source # (/=) :: ReplayGoal blk -> ReplayGoal blk -> Bool Source # |
|
StandardHash blk => Show ( ReplayGoal blk) Source # | |
Defined in Ouroboros.Consensus.Storage.LedgerDB.OnDisk |
newtype ReplayStart blk Source #
Which point the replay started from
Constructors
ReplayStart ( Point blk) |
Instances
StandardHash blk => Eq ( ReplayStart blk) Source # | |
Defined in Ouroboros.Consensus.Storage.LedgerDB.OnDisk Methods (==) :: ReplayStart blk -> ReplayStart blk -> Bool Source # (/=) :: ReplayStart blk -> ReplayStart blk -> Bool Source # |
|
StandardHash blk => Show ( ReplayStart blk) Source # | |
Defined in Ouroboros.Consensus.Storage.LedgerDB.OnDisk |
data TraceEvent blk Source #
Constructors
InvalidSnapshot DiskSnapshot ( InitFailure blk) |
An on disk snapshot was skipped because it was invalid. |
TookSnapshot DiskSnapshot ( RealPoint blk) |
A snapshot was written to disk. |
DeletedSnapshot DiskSnapshot |
An old or invalid on-disk snapshot was deleted |
Instances
data TraceReplayEvent blk Source #
Events traced while replaying blocks against the ledger to bring it up to date w.r.t. the tip of the ImmutableDB during initialisation. As this process takes a while, we trace events to inform higher layers of our progress.
Constructors
ReplayFromGenesis ( ReplayGoal blk) |
There were no LedgerDB snapshots on disk, so we're replaying all blocks starting from Genesis against the initial ledger. |
ReplayFromSnapshot | |
Fields
|
|
ReplayedBlock | |
Fields
|
Instances
decorateReplayTracerWithGoal Source #
Arguments
:: Point blk |
Tip of the ImmutableDB |
-> Tracer m ( TraceReplayEvent blk) | |
-> Tracer m ( ReplayGoal blk -> TraceReplayEvent blk) |
Add the tip of the Immutable DB to the trace event
Between the tip of the immutable DB and the point of the starting block, the node could (if it so desired) easily compute a "percentage complete".