Processing math: 100%
ouroboros-consensus-0.26.0.0: Consensus layer for the Ouroboros blockchain protocol
Safe HaskellNone
LanguageHaskell2010

Ouroboros.Consensus.Storage.LedgerDB.API

Description

The Ledger DB is responsible for the following tasks:

  • Maintaining the in-memory ledger state at the tip: When we try to extend our chain with a new block fitting onto our tip, the block must first be validated using the right ledger state, i.e., the ledger state corresponding to the tip.
  • Maintaining the past k in-memory ledger states: we might roll back up to k blocks when switching to a more preferable fork. Consider the example below:

    Our current chain's tip is C2, but the fork containing blocks F1, F2, and F3 is more preferable. We roll back our chain to the intersection point of the two chains, I, which must be not more than k blocks back from our current tip. Next, we must validate block F1 using the ledger state at block I, after which we can validate F2 using the resulting ledger state, and so on.

    This means that we need access to all ledger states of the past k blocks, i.e., the ledger states corresponding to the volatile part of the current chain. Note that applying a block to a ledger state is not an invertible operation, so it is not possible to simply unapply C1 and C2 to obtain I.

    Access to the last k ledger states is not only needed for validating candidate chains, but also by the:

    • Local state query server: To query any of the past k ledger states.
    • Chain sync client: To validate headers of a chain that intersects with any of the past k blocks.
  • Providing LedgerTables at any of the last k ledger states: To apply blocks or transactions on top of ledger states, the LedgerDB must be able to provide the appropriate ledger tables at any of those ledger states.
  • Storing snapshots on disk: To obtain a ledger state for the current tip of the chain, one has to apply all blocks in the chain one-by-one to the initial ledger state. When starting up the system with an on-disk chain containing millions of blocks, all of them would have to be read from disk and applied. This process can take hours, depending on the storage and CPU speed, and is thus too costly to perform on each startup.

    For this reason, a recent snapshot of the ledger state should be periodically written to disk. Upon the next startup, that snapshot can be read and used to restore the current ledger state, as well as the past k ledger states.

  • Flushing LedgerTable differences: The running Consensus has to periodically flush chunks of differences from the DbChangelog to the BackingStore, so that memory is off-loaded to the backing store, and if the backing store is an on-disk implementation, reduce the memory usage.

Note that whenever we say ledger state we mean the ExtLedgerState blk mk type described in Ouroboros.Consensus.Ledger.Basics.

(image code)

Expand
>>> import Image.LaTeX.Render
>>> import Control.Monad
>>> import System.Directory
>>> 
>>> createDirectoryIfMissing True "docs/haddocks/"
>>> :{
>>> either (error . show) pure =<<
>>> renderToFile "docs/haddocks/ledgerdb-switch.svg" defaultEnv (tikz ["positioning", "arrows"]) "\
>>> \ \\draw (0, 0) -- (50pt, 0) coordinate (I);\
>>> \  \\draw (I) -- ++(20pt,  20pt) coordinate (C1) -- ++(20pt, 0) coordinate (C2);\
>>> \  \\draw (I) -- ++(20pt, -20pt) coordinate (F1) -- ++(20pt, 0) coordinate (F2) -- ++(20pt, 0) coordinate (F3);\
>>> \  \\node at (I)  {$\\bullet$};\
>>> \  \\node at (C1) {$\\bullet$};\
>>> \  \\node at (C2) {$\\bullet$};\
>>> \  \\node at (F1) {$\\bullet$};\
>>> \  \\node at (F2) {$\\bullet$};\
>>> \  \\node at (F3) {$\\bullet$};\
>>> \  \\node at (I) [above left] {$I$};\
>>> \  \\node at (C1) [above] {$C_1$};\
>>> \  \\node at (C2) [above] {$C_2$};\
>>> \  \\node at (F1) [below] {$F_1$};\
>>> \  \\node at (F2) [below] {$F_2$};\
>>> \  \\node at (F3) [below] {$F_3$};\
>>> \  \\draw (60pt, 50pt) node {$\\overbrace{\\hspace{60pt}}$};\
>>> \  \\draw (60pt, 60pt) node[fill=white] {$k$};\
>>> \  \\draw [dashed] (30pt, -40pt) -- (30pt, 45pt);"
>>> :}
Synopsis

Main API

class CanUpgradeLedgerTables (l ∷ MapKindType) where Source #

When pushing differences on InMemory Ledger DBs, we will sometimes need to update ledger tables to the latest era. For unary blocks this is a no-op, but for the Cardano block, we will need to upgrade all TxOuts in memory.

No correctness property relies on this, as Consensus can work with TxOuts from multiple eras, but the performance depends on it as otherwise we will be upgrading the TxOuts every time we consult them.

Methods

upgradeTables Source #

Arguments

∷ ∀ (mk1 ∷ MapKind) (mk2 ∷ MapKind). l mk1

The original ledger state before the upgrade. This will be the tip before applying the block.

→ l mk2

The ledger state after the upgrade, which might be in a different era than the one above.

LedgerTables l ValuesMK

The tables we want to maybe upgrade.

LedgerTables l ValuesMK 

Instances

Instances details
(CanHardFork xs, HasHardForkTxOut xs) ⇒ CanUpgradeLedgerTables (LedgerState (HardForkBlock xs)) Source # 
Instance details

Defined in Ouroboros.Consensus.HardFork.Combinator.Ledger

CanUpgradeLedgerTables (LedgerState (DualBlock m a)) Source # 
Instance details

Defined in Ouroboros.Consensus.Ledger.Dual

CanUpgradeLedgerTables (LedgerState blk) ⇒ CanUpgradeLedgerTables (ExtLedgerState blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

upgradeTables ∷ ∀ (mk1 ∷ MapKind) (mk2 ∷ MapKind). ExtLedgerState blk mk1 → ExtLedgerState blk mk2 → LedgerTables (ExtLedgerState blk) ValuesMKLedgerTables (ExtLedgerState blk) ValuesMK Source #

LedgerTablesAreTrivial l ⇒ CanUpgradeLedgerTables (TrivialLedgerTables l) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

data LedgerDB (m ∷ TypeType) (l ∷ LedgerStateKind) blk Source #

The core API of the LedgerDB component

Constructors

LedgerDB 

Fields

Instances

Instances details
NoThunks (LedgerDB m l blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

noThunksContextLedgerDB m l blk → IO (Maybe ThunkInfo) Source #

wNoThunksContextLedgerDB m l blk → IO (Maybe ThunkInfo) Source #

showTypeOfProxy (LedgerDB m l blk) → String Source #

type HeaderHash (LedgerDB m l blk ∷ Type) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type HeaderHash (LedgerDB m l blk ∷ Type) = HeaderHash blk

type LedgerDB' (m ∷ TypeType) blk = LedgerDB m (ExtLedgerState blk) blk Source #

data LedgerDbPrune Source #

Options for prunning the LedgerDB

Rather than using a plain Word64 we use this to be able to distinguish that we are indeed using 1. 0 in places where it is necessary 2. the security parameter as is, in other places

Instances

Instances details
Show LedgerDbPrune Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type LedgerDbSerialiseConstraints blk = (Serialise (HeaderHash blk), EncodeDisk blk (LedgerState blk EmptyMK), DecodeDisk blk (LedgerState blk EmptyMK), EncodeDisk blk (AnnTip blk), DecodeDisk blk (AnnTip blk), EncodeDisk blk (ChainDepState (BlockProtocol blk)), DecodeDisk blk (ChainDepState (BlockProtocol blk)), MemPack (TxIn (LedgerState blk)), SerializeTablesWithHint (LedgerState blk), IndexedMemPack (LedgerState blk EmptyMK) (TxOut (LedgerState blk))) Source #

Serialization constraints required by the LedgerDB to be properly instantiated with a blk.

type ResolveBlock (m ∷ TypeType) blk = RealPoint blk → m blk Source #

Resolve a block

Resolving a block reference to the actual block lives in m because it might need to read the block from disk (and can therefore not be done inside an STM transaction).

NOTE: The ledger DB will only ask the ChainDB for blocks it knows must exist. If the ChainDB is unable to fulfill the request, data corruption must have happened and the ChainDB should trigger validation mode.

currentPoint ∷ ∀ (l ∷ LedgerStateKind) blk (m ∷ TypeType). (GetTip l, HeaderHash l ~ HeaderHash blk, Functor (STM m)) ⇒ LedgerDB m l blk → STM m (Point blk) Source #

Initialization

data InitDB db (m ∷ TypeType) blk Source #

Functions required to initialize a LedgerDB

Constructors

InitDB 

Fields

data InitLog blk Source #

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, or this is the first time we boot the node, we should see this only if data corruption occurred.

InitFromSnapshot DiskSnapshot (RealPoint blk)

Used a snapshot corresponding to the specified tip

InitFailure DiskSnapshot (SnapshotFailure blk) (InitLog blk)

Initialization skipped a snapshot

We record the reason why it was skipped.

NOTE: We should only see this if data corruption occurred or codecs for snapshots changed.

Instances

Instances details
Generic (InitLog blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Associated Types

type Rep (InitLog blk) 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

fromInitLog blk → Rep (InitLog blk) x #

toRep (InitLog blk) x → InitLog blk #

StandardHash blk ⇒ Show (InitLog blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

showsPrecIntInitLog blk → ShowS #

showInitLog blk → String #

showList ∷ [InitLog blk] → ShowS #

StandardHash blk ⇒ Eq (InitLog blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

(==)InitLog blk → InitLog blk → Bool #

(/=)InitLog blk → InitLog blk → Bool #

type Rep (InitLog blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

initialize ∷ (IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasCallStack) ⇒ Tracer m (TraceReplayEvent blk) → Tracer m (TraceSnapshotEvent blk) → SomeHasFS m → LedgerDbCfg (ExtLedgerState blk) → StreamAPI m blk blk → Point blk → InitDB db m blk → Maybe DiskSnapshot → m (InitLog blk, db, Word64) Source #

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 a log of the initialization and the number of blocks replayed between the snapshot and the tip of the immutable DB.

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, they refer to a slot which is later than the last slot in the immutable db.

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.

Tracing

newtype ReplayGoal (blk ∷ k) Source #

Which point the replay is expected to end at

Constructors

ReplayGoal (Point blk) 

Instances

Instances details
StandardHash blk ⇒ Show (ReplayGoal blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

showsPrecIntReplayGoal blk → ShowS #

showReplayGoal blk → String #

showList ∷ [ReplayGoal blk] → ShowS #

StandardHash blk ⇒ Eq (ReplayGoal blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

(==)ReplayGoal blk → ReplayGoal blk → Bool #

(/=)ReplayGoal blk → ReplayGoal blk → Bool #

newtype ReplayStart (blk ∷ k) Source #

Which point the replay started from

Constructors

ReplayStart (Point blk) 

Instances

Instances details
StandardHash blk ⇒ Show (ReplayStart blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

showsPrecIntReplayStart blk → ShowS #

showReplayStart blk → String #

showList ∷ [ReplayStart blk] → ShowS #

StandardHash blk ⇒ Eq (ReplayStart blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Methods

(==)ReplayStart blk → ReplayStart blk → Bool #

(/=)ReplayStart blk → ReplayStart blk → Bool #

data TraceReplayProgressEvent blk Source #

We replayed the given block (reference) on the genesis snapshot during the initialisation of the LedgerDB. Used during ImmutableDB replay.

Using this trace the node could (if it so desired) easily compute a "percentage complete".

Constructors

ReplayedBlock 

Fields

Instances

Instances details
Generic (TraceReplayProgressEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Associated Types

type Rep (TraceReplayProgressEvent blk) 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (TraceReplayProgressEvent blk) = D1 ('MetaData "TraceReplayProgressEvent" "Ouroboros.Consensus.Storage.LedgerDB.API" "ouroboros-consensus-0.26.0.0-inplace" 'False) (C1 ('MetaCons "ReplayedBlock" 'PrefixI 'False) ((S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (RealPoint blk)) :*: S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [LedgerEvent blk])) :*: (S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ReplayStart blk)) :*: S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ReplayGoal blk)))))
(StandardHash blk, InspectLedger blk) ⇒ Show (TraceReplayProgressEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

(StandardHash blk, InspectLedger blk) ⇒ Eq (TraceReplayProgressEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (TraceReplayProgressEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (TraceReplayProgressEvent blk) = D1 ('MetaData "TraceReplayProgressEvent" "Ouroboros.Consensus.Storage.LedgerDB.API" "ouroboros-consensus-0.26.0.0-inplace" 'False) (C1 ('MetaCons "ReplayedBlock" 'PrefixI 'False) ((S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (RealPoint blk)) :*: S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [LedgerEvent blk])) :*: (S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ReplayStart blk)) :*: S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ReplayGoal blk)))))

data TraceReplayStartEvent (blk ∷ k) 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

There were no LedgerDB snapshots on disk, so we're replaying all blocks starting from Genesis against the initial ledger.

ReplayFromSnapshot

There was a LedgerDB snapshot on disk corresponding to the given tip. We're replaying more recent blocks against it.

Fields

Instances

Instances details
Generic (TraceReplayStartEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Associated Types

type Rep (TraceReplayStartEvent blk) 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (TraceReplayStartEvent blk) = D1 ('MetaData "TraceReplayStartEvent" "Ouroboros.Consensus.Storage.LedgerDB.API" "ouroboros-consensus-0.26.0.0-inplace" 'False) (C1 ('MetaCons "ReplayFromGenesis" 'PrefixI 'False) (U1TypeType) :+: C1 ('MetaCons "ReplayFromSnapshot" 'PrefixI 'False) (S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 DiskSnapshot) :*: S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ReplayStart blk))))
StandardHash blk ⇒ Show (TraceReplayStartEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

StandardHash blk ⇒ Eq (TraceReplayStartEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (TraceReplayStartEvent blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (TraceReplayStartEvent blk) = D1 ('MetaData "TraceReplayStartEvent" "Ouroboros.Consensus.Storage.LedgerDB.API" "ouroboros-consensus-0.26.0.0-inplace" 'False) (C1 ('MetaCons "ReplayFromGenesis" 'PrefixI 'False) (U1TypeType) :+: C1 ('MetaCons "ReplayFromSnapshot" 'PrefixI 'False) (S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 DiskSnapshot) :*: S1 ('MetaSel ('NothingMaybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ReplayStart blk))))

decorateReplayTracerWithGoal Source #

Arguments

∷ ∀ blk (m ∷ TypeType). Point blk

Tip of the ImmutableDB

Tracer m (TraceReplayProgressEvent blk) 
Tracer m (ReplayGoal blk → TraceReplayProgressEvent blk) 

Add the tip of the Immutable DB to the trace event

decorateReplayTracerWithStart Source #

Arguments

∷ ∀ blk (m ∷ TypeType). Point blk

Starting point of the replay

Tracer m (ReplayGoal blk → TraceReplayProgressEvent blk) 
Tracer m (ReplayStart blk → ReplayGoal blk → TraceReplayProgressEvent blk) 

Add the block at which a replay started.

Configuration

data LedgerDbCfgF (f ∷ TypeType) (l ∷ LedgerStateKind) Source #

Instances

Instances details
NoThunks (LedgerCfg l) ⇒ NoThunks (LedgerDbCfg l) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Generic (LedgerDbCfgF f l) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

Associated Types

type Rep (LedgerDbCfgF f l) 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (LedgerDbCfgF f l) = D1 ('MetaData "LedgerDbCfgF" "Ouroboros.Consensus.Storage.LedgerDB.API" "ouroboros-consensus-0.26.0.0-inplace" 'False) (C1 ('MetaCons "LedgerDbCfg" 'PrefixI 'True) (S1 ('MetaSel ('Just "ledgerDbCfgSecParam") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (HKD f SecurityParam)) :*: (S1 ('MetaSel ('Just "ledgerDbCfg") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (HKD f (LedgerCfg l))) :*: S1 ('MetaSel ('Just "ledgerDbCfgComputeLedgerEvents") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ComputeLedgerEvents))))

Methods

fromLedgerDbCfgF f l → Rep (LedgerDbCfgF f l) x #

toRep (LedgerDbCfgF f l) x → LedgerDbCfgF f l #

type Rep (LedgerDbCfgF f l) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type Rep (LedgerDbCfgF f l) = D1 ('MetaData "LedgerDbCfgF" "Ouroboros.Consensus.Storage.LedgerDB.API" "ouroboros-consensus-0.26.0.0-inplace" 'False) (C1 ('MetaCons "LedgerDbCfg" 'PrefixI 'True) (S1 ('MetaSel ('Just "ledgerDbCfgSecParam") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (HKD f SecurityParam)) :*: (S1 ('MetaSel ('Just "ledgerDbCfg") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (HKD f (LedgerCfg l))) :*: S1 ('MetaSel ('Just "ledgerDbCfgComputeLedgerEvents") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ComputeLedgerEvents))))

Exceptions

data LedgerDbError (blk ∷ k) Source #

Database error

Thrown upon incorrect use: invalid input.

Constructors

ClosedDBError PrettyCallStack

The LedgerDB is closed.

This will be thrown when performing some operations on the LedgerDB. The CallStack of the operation on the LedgerDB is included in the error.

ClosedForkerError ForkerKey PrettyCallStack

A Forker is closed.

Forker

getReadOnlyForker ∷ ∀ m (l ∷ LedgerStateKind) blk. MonadSTM m ⇒ LedgerDB m l blk → ResourceRegistry m → Target (Point blk) → m (Either GetForkerError (ReadOnlyForker m l blk)) Source #

getTipStatistics ∷ ∀ m (l ∷ LedgerStateKind) blk. IOLike m ⇒ LedgerDB m l blk → m (Maybe Statistics) Source #

Get statistics from the tip of the LedgerDB.

readLedgerTablesAtFor ∷ ∀ m (l ∷ LedgerStateKind) blk. IOLike m ⇒ LedgerDB m l blk → Point blk → LedgerTables l KeysMK → m (Either GetForkerError (LedgerTables l ValuesMK)) Source #

Read a table of values at the requested point via a ReadOnlyForker

withPrivateTipForker ∷ ∀ m (l ∷ LedgerStateKind) blk a. IOLike m ⇒ LedgerDB m l blk → (Forker m l blk → m a) → m a Source #

Like withTipForker, but it uses a private registry to allocate and de-allocate the forker.

withTipForker ∷ ∀ m (l ∷ LedgerStateKind) blk a. IOLike m ⇒ LedgerDB m l blk → ResourceRegistry m → (Forker m l blk → m a) → m a Source #

bracket-style usage of a forker at the LedgerDB tip.

Snapshots

data SnapCounters Source #

Counters to keep track of when we made the last snapshot.

Constructors

SnapCounters 

Fields

Testing

data TestInternals (m ∷ TypeType) (l ∷ k) blk Source #

Constructors

TestInternals 

Fields

Instances

Instances details
NoThunks (TestInternals m l blk) Source # 
Instance details

Defined in Ouroboros.Consensus.Storage.LedgerDB.API

type TestInternals' (m ∷ TypeType) blk = TestInternals m (ExtLedgerState blk) blk Source #