{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Ouroboros.Consensus.Ledger.Abstract (
Validated
, ApplyBlock (..)
, UpdateLedger
, applyLedgerBlock
, foldLedger
, reapplyLedgerBlock
, refoldLedger
, tickThenApply
, tickThenApplyLedgerResult
, tickThenReapply
, tickThenReapplyLedgerResult
, ledgerTipHash
, ledgerTipPoint
, ledgerTipSlot
, module Ouroboros.Consensus.Ledger.Basics
) where
import Control.Monad.Except
import Data.Kind (Type)
import GHC.Stack (HasCallStack)
import Ouroboros.Consensus.Block.Abstract
import Ouroboros.Consensus.Ledger.Basics
import Ouroboros.Consensus.Ticked
import Ouroboros.Consensus.Util (repeatedly, repeatedlyM, (..:))
data family Validated x :: Type
class ( IsLedger l
, HeaderHash l ~ HeaderHash blk
, HasHeader blk
, HasHeader (Header blk)
) => ApplyBlock l blk where
applyBlockLedgerResult ::
HasCallStack
=> LedgerCfg l
-> blk
-> Ticked l
-> Except (LedgerErr l) (LedgerResult l l)
reapplyBlockLedgerResult ::
HasCallStack
=> LedgerCfg l
-> blk
-> Ticked l
-> LedgerResult l l
class ApplyBlock (LedgerState blk) blk => UpdateLedger blk
applyLedgerBlock ::
(ApplyBlock l blk, HasCallStack)
=> LedgerCfg l
-> blk
-> Ticked l
-> Except (LedgerErr l) l
applyLedgerBlock :: forall l blk.
(ApplyBlock l blk, HasCallStack) =>
LedgerCfg l -> blk -> Ticked l -> Except (LedgerErr l) l
applyLedgerBlock = (LedgerResult l l -> l)
-> ExceptT (LedgerErr l) Identity (LedgerResult l l)
-> ExceptT (LedgerErr l) Identity l
forall a b.
(a -> b)
-> ExceptT (LedgerErr l) Identity a
-> ExceptT (LedgerErr l) Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LedgerResult l l -> l
forall l a. LedgerResult l a -> a
lrResult (ExceptT (LedgerErr l) Identity (LedgerResult l l)
-> ExceptT (LedgerErr l) Identity l)
-> (LedgerCfg l
-> blk
-> Ticked l
-> ExceptT (LedgerErr l) Identity (LedgerResult l l))
-> LedgerCfg l
-> blk
-> Ticked l
-> ExceptT (LedgerErr l) Identity l
forall y z x0 x1 x2.
(y -> z) -> (x0 -> x1 -> x2 -> y) -> x0 -> x1 -> x2 -> z
..: LedgerCfg l
-> blk
-> Ticked l
-> ExceptT (LedgerErr l) Identity (LedgerResult l l)
forall l blk.
(ApplyBlock l blk, HasCallStack) =>
LedgerCfg l
-> blk -> Ticked l -> Except (LedgerErr l) (LedgerResult l l)
applyBlockLedgerResult
reapplyLedgerBlock ::
(ApplyBlock l blk, HasCallStack)
=> LedgerCfg l
-> blk
-> Ticked l
-> l
reapplyLedgerBlock :: forall l blk.
(ApplyBlock l blk, HasCallStack) =>
LedgerCfg l -> blk -> Ticked l -> l
reapplyLedgerBlock = LedgerResult l l -> l
forall l a. LedgerResult l a -> a
lrResult (LedgerResult l l -> l)
-> (LedgerCfg l -> blk -> Ticked l -> LedgerResult l l)
-> LedgerCfg l
-> blk
-> Ticked l
-> l
forall y z x0 x1 x2.
(y -> z) -> (x0 -> x1 -> x2 -> y) -> x0 -> x1 -> x2 -> z
..: LedgerCfg l -> blk -> Ticked l -> LedgerResult l l
forall l blk.
(ApplyBlock l blk, HasCallStack) =>
LedgerCfg l -> blk -> Ticked l -> LedgerResult l l
reapplyBlockLedgerResult
tickThenApplyLedgerResult ::
ApplyBlock l blk
=> LedgerCfg l
-> blk
-> l
-> Except (LedgerErr l) (LedgerResult l l)
tickThenApplyLedgerResult :: forall l blk.
ApplyBlock l blk =>
LedgerCfg l -> blk -> l -> Except (LedgerErr l) (LedgerResult l l)
tickThenApplyLedgerResult LedgerCfg l
cfg blk
blk l
l = do
let lrTick :: LedgerResult l (Ticked l)
lrTick = LedgerCfg l -> SlotNo -> l -> LedgerResult l (Ticked l)
forall l.
IsLedger l =>
LedgerCfg l -> SlotNo -> l -> LedgerResult l (Ticked l)
applyChainTickLedgerResult LedgerCfg l
cfg (blk -> SlotNo
forall b. HasHeader b => b -> SlotNo
blockSlot blk
blk) l
l
LedgerResult l l
lrBlock <- LedgerCfg l
-> blk -> Ticked l -> Except (LedgerErr l) (LedgerResult l l)
forall l blk.
(ApplyBlock l blk, HasCallStack) =>
LedgerCfg l
-> blk -> Ticked l -> Except (LedgerErr l) (LedgerResult l l)
applyBlockLedgerResult LedgerCfg l
cfg blk
blk (LedgerResult l (Ticked l) -> Ticked l
forall l a. LedgerResult l a -> a
lrResult LedgerResult l (Ticked l)
lrTick)
LedgerResult l l -> Except (LedgerErr l) (LedgerResult l l)
forall a. a -> ExceptT (LedgerErr l) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure LedgerResult {
lrEvents :: [AuxLedgerEvent l]
lrEvents = LedgerResult l (Ticked l) -> [AuxLedgerEvent l]
forall l a. LedgerResult l a -> [AuxLedgerEvent l]
lrEvents LedgerResult l (Ticked l)
lrTick [AuxLedgerEvent l] -> [AuxLedgerEvent l] -> [AuxLedgerEvent l]
forall a. Semigroup a => a -> a -> a
<> LedgerResult l l -> [AuxLedgerEvent l]
forall l a. LedgerResult l a -> [AuxLedgerEvent l]
lrEvents LedgerResult l l
lrBlock
, lrResult :: l
lrResult = LedgerResult l l -> l
forall l a. LedgerResult l a -> a
lrResult LedgerResult l l
lrBlock
}
tickThenReapplyLedgerResult ::
ApplyBlock l blk
=> LedgerCfg l
-> blk
-> l
-> LedgerResult l l
tickThenReapplyLedgerResult :: forall l blk.
ApplyBlock l blk =>
LedgerCfg l -> blk -> l -> LedgerResult l l
tickThenReapplyLedgerResult LedgerCfg l
cfg blk
blk l
l =
let lrTick :: LedgerResult l (Ticked l)
lrTick = LedgerCfg l -> SlotNo -> l -> LedgerResult l (Ticked l)
forall l.
IsLedger l =>
LedgerCfg l -> SlotNo -> l -> LedgerResult l (Ticked l)
applyChainTickLedgerResult LedgerCfg l
cfg (blk -> SlotNo
forall b. HasHeader b => b -> SlotNo
blockSlot blk
blk) l
l
lrBlock :: LedgerResult l l
lrBlock = LedgerCfg l -> blk -> Ticked l -> LedgerResult l l
forall l blk.
(ApplyBlock l blk, HasCallStack) =>
LedgerCfg l -> blk -> Ticked l -> LedgerResult l l
reapplyBlockLedgerResult LedgerCfg l
cfg blk
blk (LedgerResult l (Ticked l) -> Ticked l
forall l a. LedgerResult l a -> a
lrResult LedgerResult l (Ticked l)
lrTick)
in LedgerResult {
lrEvents :: [AuxLedgerEvent l]
lrEvents = LedgerResult l (Ticked l) -> [AuxLedgerEvent l]
forall l a. LedgerResult l a -> [AuxLedgerEvent l]
lrEvents LedgerResult l (Ticked l)
lrTick [AuxLedgerEvent l] -> [AuxLedgerEvent l] -> [AuxLedgerEvent l]
forall a. Semigroup a => a -> a -> a
<> LedgerResult l l -> [AuxLedgerEvent l]
forall l a. LedgerResult l a -> [AuxLedgerEvent l]
lrEvents LedgerResult l l
lrBlock
, lrResult :: l
lrResult = LedgerResult l l -> l
forall l a. LedgerResult l a -> a
lrResult LedgerResult l l
lrBlock
}
tickThenApply ::
ApplyBlock l blk
=> LedgerCfg l
-> blk
-> l
-> Except (LedgerErr l) l
tickThenApply :: forall l blk.
ApplyBlock l blk =>
LedgerCfg l -> blk -> l -> Except (LedgerErr l) l
tickThenApply = (LedgerResult l l -> l)
-> ExceptT (LedgerErr l) Identity (LedgerResult l l)
-> ExceptT (LedgerErr l) Identity l
forall a b.
(a -> b)
-> ExceptT (LedgerErr l) Identity a
-> ExceptT (LedgerErr l) Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LedgerResult l l -> l
forall l a. LedgerResult l a -> a
lrResult (ExceptT (LedgerErr l) Identity (LedgerResult l l)
-> ExceptT (LedgerErr l) Identity l)
-> (LedgerCfg l
-> blk -> l -> ExceptT (LedgerErr l) Identity (LedgerResult l l))
-> LedgerCfg l
-> blk
-> l
-> ExceptT (LedgerErr l) Identity l
forall y z x0 x1 x2.
(y -> z) -> (x0 -> x1 -> x2 -> y) -> x0 -> x1 -> x2 -> z
..: LedgerCfg l
-> blk -> l -> ExceptT (LedgerErr l) Identity (LedgerResult l l)
forall l blk.
ApplyBlock l blk =>
LedgerCfg l -> blk -> l -> Except (LedgerErr l) (LedgerResult l l)
tickThenApplyLedgerResult
tickThenReapply ::
ApplyBlock l blk
=> LedgerCfg l
-> blk
-> l
-> l
tickThenReapply :: forall l blk. ApplyBlock l blk => LedgerCfg l -> blk -> l -> l
tickThenReapply = LedgerResult l l -> l
forall l a. LedgerResult l a -> a
lrResult (LedgerResult l l -> l)
-> (LedgerCfg l -> blk -> l -> LedgerResult l l)
-> LedgerCfg l
-> blk
-> l
-> l
forall y z x0 x1 x2.
(y -> z) -> (x0 -> x1 -> x2 -> y) -> x0 -> x1 -> x2 -> z
..: LedgerCfg l -> blk -> l -> LedgerResult l l
forall l blk.
ApplyBlock l blk =>
LedgerCfg l -> blk -> l -> LedgerResult l l
tickThenReapplyLedgerResult
foldLedger ::
ApplyBlock l blk
=> LedgerCfg l -> [blk] -> l -> Except (LedgerErr l) l
foldLedger :: forall l blk.
ApplyBlock l blk =>
LedgerCfg l -> [blk] -> l -> Except (LedgerErr l) l
foldLedger = (blk -> l -> ExceptT (LedgerErr l) Identity l)
-> [blk] -> l -> ExceptT (LedgerErr l) Identity l
forall (m :: * -> *) a b.
Monad m =>
(a -> b -> m b) -> [a] -> b -> m b
repeatedlyM ((blk -> l -> ExceptT (LedgerErr l) Identity l)
-> [blk] -> l -> ExceptT (LedgerErr l) Identity l)
-> (LedgerCfg l -> blk -> l -> ExceptT (LedgerErr l) Identity l)
-> LedgerCfg l
-> [blk]
-> l
-> ExceptT (LedgerErr l) Identity l
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LedgerCfg l -> blk -> l -> ExceptT (LedgerErr l) Identity l
forall l blk.
ApplyBlock l blk =>
LedgerCfg l -> blk -> l -> Except (LedgerErr l) l
tickThenApply
refoldLedger ::
ApplyBlock l blk
=> LedgerCfg l -> [blk] -> l -> l
refoldLedger :: forall l blk. ApplyBlock l blk => LedgerCfg l -> [blk] -> l -> l
refoldLedger = (blk -> l -> l) -> [blk] -> l -> l
forall a b. (a -> b -> b) -> [a] -> b -> b
repeatedly ((blk -> l -> l) -> [blk] -> l -> l)
-> (LedgerCfg l -> blk -> l -> l) -> LedgerCfg l -> [blk] -> l -> l
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LedgerCfg l -> blk -> l -> l
forall l blk. ApplyBlock l blk => LedgerCfg l -> blk -> l -> l
tickThenReapply
ledgerTipPoint ::
UpdateLedger blk
=> LedgerState blk -> Point blk
ledgerTipPoint :: forall blk. UpdateLedger blk => LedgerState blk -> Point blk
ledgerTipPoint = Point (LedgerState blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (LedgerState blk) -> Point blk)
-> (LedgerState blk -> Point (LedgerState blk))
-> LedgerState blk
-> Point blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LedgerState blk -> Point (LedgerState blk)
forall l. GetTip l => l -> Point l
getTip
ledgerTipHash ::
UpdateLedger blk
=> LedgerState blk -> ChainHash blk
ledgerTipHash :: forall blk. UpdateLedger blk => LedgerState blk -> ChainHash blk
ledgerTipHash = Point blk -> ChainHash blk
forall {k} (block :: k). Point block -> ChainHash block
pointHash (Point blk -> ChainHash blk)
-> (LedgerState blk -> Point blk)
-> LedgerState blk
-> ChainHash blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LedgerState blk -> Point blk
forall blk. UpdateLedger blk => LedgerState blk -> Point blk
ledgerTipPoint
ledgerTipSlot ::
UpdateLedger blk
=> LedgerState blk -> WithOrigin SlotNo
ledgerTipSlot :: forall blk.
UpdateLedger blk =>
LedgerState blk -> WithOrigin SlotNo
ledgerTipSlot = Point blk -> WithOrigin SlotNo
forall {k} (block :: k). Point block -> WithOrigin SlotNo
pointSlot (Point blk -> WithOrigin SlotNo)
-> (LedgerState blk -> Point blk)
-> LedgerState blk
-> WithOrigin SlotNo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LedgerState blk -> Point blk
forall blk. UpdateLedger blk => LedgerState blk -> Point blk
ledgerTipPoint