{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Ouroboros.Consensus.Block.Forging (
CannotForge
, ForgeStateInfo
, ForgeStateUpdateError
, ForgeStateUpdateInfo(..)
, castForgeStateUpdateInfo
, BlockForging(..)
, ShouldForge(..)
, checkShouldForge
, UpdateInfo (..)
, castUpdateInfo
) where
import Control.Tracer (Tracer, traceWith)
import Data.Kind (Type)
import Data.Text (Text)
import GHC.Stack
import Ouroboros.Consensus.Block.Abstract
import Ouroboros.Consensus.Config
import Ouroboros.Consensus.Ledger.Abstract
import Ouroboros.Consensus.Ledger.SupportsMempool
import Ouroboros.Consensus.Protocol.Abstract
import Ouroboros.Consensus.Ticked
type family CannotForge blk :: Type
type family ForgeStateInfo blk :: Type
type family ForgeStateUpdateError blk :: Type
newtype ForgeStateUpdateInfo blk = ForgeStateUpdateInfo {
ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk)
(ForgeStateInfo blk)
(ForgeStateUpdateError blk)
getForgeStateUpdateInfo :: UpdateInfo
(ForgeStateInfo blk)
(ForgeStateInfo blk)
(ForgeStateUpdateError blk)
}
deriving instance (Show (ForgeStateInfo blk), Show (ForgeStateUpdateError blk))
=> Show (ForgeStateUpdateInfo blk)
castForgeStateUpdateInfo ::
( ForgeStateInfo blk ~ ForgeStateInfo blk'
, ForgeStateUpdateError blk ~ ForgeStateUpdateError blk'
)
=> ForgeStateUpdateInfo blk -> ForgeStateUpdateInfo blk'
castForgeStateUpdateInfo :: ForgeStateUpdateInfo blk -> ForgeStateUpdateInfo blk'
castForgeStateUpdateInfo =
UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk')
-> ForgeStateUpdateInfo blk'
forall blk.
UpdateInfo
(ForgeStateInfo blk)
(ForgeStateInfo blk)
(ForgeStateUpdateError blk)
-> ForgeStateUpdateInfo blk
ForgeStateUpdateInfo
(UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk')
-> ForgeStateUpdateInfo blk')
-> (ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk'))
-> ForgeStateUpdateInfo blk
-> ForgeStateUpdateInfo blk'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk')
-> UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk')
forall updated updated' unchanged unchanged' failed failed'.
(updated ~ updated', unchanged ~ unchanged', failed ~ failed') =>
UpdateInfo updated unchanged failed
-> UpdateInfo updated' unchanged' failed'
castUpdateInfo
(UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk')
-> UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk'))
-> (ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk'))
-> ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk')
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk')
(ForgeStateInfo blk')
(ForgeStateUpdateError blk')
forall blk.
ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk)
(ForgeStateInfo blk)
(ForgeStateUpdateError blk)
getForgeStateUpdateInfo
data BlockForging m blk = BlockForging {
BlockForging m blk -> Text
forgeLabel :: Text
, BlockForging m blk -> CanBeLeader (BlockProtocol blk)
canBeLeader :: CanBeLeader (BlockProtocol blk)
, BlockForging m blk -> SlotNo -> m (ForgeStateUpdateInfo blk)
updateForgeState :: SlotNo -> m (ForgeStateUpdateInfo blk)
, BlockForging m blk
-> forall p.
(BlockProtocol blk ~ p) =>
TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState p)
-> IsLeader p
-> ForgeStateInfo blk
-> Either (CannotForge blk) ()
checkCanForge ::
forall p. BlockProtocol blk ~ p
=> TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState p)
-> IsLeader p
-> ForgeStateInfo blk
-> Either (CannotForge blk) ()
, BlockForging m blk
-> TopLevelConfig blk
-> BlockNo
-> SlotNo
-> TickedLedgerState blk
-> [GenTx blk]
-> IsLeader (BlockProtocol blk)
-> m blk
forgeBlock ::
TopLevelConfig blk
-> BlockNo
-> SlotNo
-> TickedLedgerState blk
-> [GenTx blk]
-> IsLeader (BlockProtocol blk)
-> m blk
}
data ShouldForge blk =
ForgeStateUpdateError (ForgeStateUpdateError blk)
| CannotForge (CannotForge blk)
| NotLeader
| ShouldForge (IsLeader (BlockProtocol blk))
checkShouldForge ::
forall m blk.
( Monad m
, ConsensusProtocol (BlockProtocol blk)
, HasCallStack
)
=> BlockForging m blk
-> Tracer m (ForgeStateInfo blk)
-> TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState (BlockProtocol blk))
-> m (ShouldForge blk)
checkShouldForge :: BlockForging m blk
-> Tracer m (ForgeStateInfo blk)
-> TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState (BlockProtocol blk))
-> m (ShouldForge blk)
checkShouldForge BlockForging{Text
CanBeLeader (BlockProtocol blk)
SlotNo -> m (ForgeStateUpdateInfo blk)
TopLevelConfig blk
-> BlockNo
-> SlotNo
-> TickedLedgerState blk
-> [GenTx blk]
-> IsLeader (BlockProtocol blk)
-> m blk
forall p.
(BlockProtocol blk ~ p) =>
TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState p)
-> IsLeader p
-> ForgeStateInfo blk
-> Either (CannotForge blk) ()
forgeBlock :: TopLevelConfig blk
-> BlockNo
-> SlotNo
-> TickedLedgerState blk
-> [GenTx blk]
-> IsLeader (BlockProtocol blk)
-> m blk
checkCanForge :: forall p.
(BlockProtocol blk ~ p) =>
TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState p)
-> IsLeader p
-> ForgeStateInfo blk
-> Either (CannotForge blk) ()
updateForgeState :: SlotNo -> m (ForgeStateUpdateInfo blk)
canBeLeader :: CanBeLeader (BlockProtocol blk)
forgeLabel :: Text
forgeBlock :: forall (m :: * -> *) blk.
BlockForging m blk
-> TopLevelConfig blk
-> BlockNo
-> SlotNo
-> TickedLedgerState blk
-> [GenTx blk]
-> IsLeader (BlockProtocol blk)
-> m blk
checkCanForge :: forall (m :: * -> *) blk.
BlockForging m blk
-> forall p.
(BlockProtocol blk ~ p) =>
TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState p)
-> IsLeader p
-> ForgeStateInfo blk
-> Either (CannotForge blk) ()
updateForgeState :: forall (m :: * -> *) blk.
BlockForging m blk -> SlotNo -> m (ForgeStateUpdateInfo blk)
canBeLeader :: forall (m :: * -> *) blk.
BlockForging m blk -> CanBeLeader (BlockProtocol blk)
forgeLabel :: forall (m :: * -> *) blk. BlockForging m blk -> Text
..}
Tracer m (ForgeStateInfo blk)
forgeStateInfoTracer
TopLevelConfig blk
cfg
SlotNo
slot
Ticked (ChainDepState (BlockProtocol blk))
tickedChainDepState = do
Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
eForgeStateInfo <-
SlotNo -> m (ForgeStateUpdateInfo blk)
updateForgeState SlotNo
slot m (ForgeStateUpdateInfo blk)
-> (ForgeStateUpdateInfo blk
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)))
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ForgeStateUpdateInfo blk
updateInfo ->
case ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk)
(ForgeStateInfo blk)
(ForgeStateUpdateError blk)
forall blk.
ForgeStateUpdateInfo blk
-> UpdateInfo
(ForgeStateInfo blk)
(ForgeStateInfo blk)
(ForgeStateUpdateError blk)
getForgeStateUpdateInfo ForgeStateUpdateInfo blk
updateInfo of
Updated ForgeStateInfo blk
info -> do
Tracer m (ForgeStateInfo blk) -> ForgeStateInfo blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ForgeStateInfo blk)
forgeStateInfoTracer ForgeStateInfo blk
info
Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)))
-> Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk))
forall a b. (a -> b) -> a -> b
$ ForgeStateInfo blk
-> Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
forall a b. b -> Either a b
Right ForgeStateInfo blk
info
Unchanged ForgeStateInfo blk
info -> do
Tracer m (ForgeStateInfo blk) -> ForgeStateInfo blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ForgeStateInfo blk)
forgeStateInfoTracer ForgeStateInfo blk
info
Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)))
-> Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk))
forall a b. (a -> b) -> a -> b
$ ForgeStateInfo blk
-> Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
forall a b. b -> Either a b
Right ForgeStateInfo blk
info
UpdateFailed ForgeStateUpdateError blk
err ->
Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)))
-> Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
-> m (Either (ForgeStateUpdateError blk) (ForgeStateInfo blk))
forall a b. (a -> b) -> a -> b
$ ForgeStateUpdateError blk
-> Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
forall a b. a -> Either a b
Left ForgeStateUpdateError blk
err
ShouldForge blk -> m (ShouldForge blk)
forall (m :: * -> *) a. Monad m => a -> m a
return (ShouldForge blk -> m (ShouldForge blk))
-> ShouldForge blk -> m (ShouldForge blk)
forall a b. (a -> b) -> a -> b
$
case Either (ForgeStateUpdateError blk) (ForgeStateInfo blk)
eForgeStateInfo of
Left ForgeStateUpdateError blk
err -> ForgeStateUpdateError blk -> ShouldForge blk
forall blk. ForgeStateUpdateError blk -> ShouldForge blk
ForgeStateUpdateError ForgeStateUpdateError blk
err
Right ForgeStateInfo blk
forgeStateInfo ->
case ConsensusConfig (BlockProtocol blk)
-> CanBeLeader (BlockProtocol blk)
-> SlotNo
-> Ticked (ChainDepState (BlockProtocol blk))
-> Maybe (IsLeader (BlockProtocol blk))
forall p.
(ConsensusProtocol p, HasCallStack) =>
ConsensusConfig p
-> CanBeLeader p
-> SlotNo
-> Ticked (ChainDepState p)
-> Maybe (IsLeader p)
checkIsLeader (TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg) CanBeLeader (BlockProtocol blk)
canBeLeader SlotNo
slot Ticked (ChainDepState (BlockProtocol blk))
tickedChainDepState of
Maybe (IsLeader (BlockProtocol blk))
Nothing -> ShouldForge blk
forall blk. ShouldForge blk
NotLeader
Just IsLeader (BlockProtocol blk)
isLeader ->
case TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState (BlockProtocol blk))
-> IsLeader (BlockProtocol blk)
-> ForgeStateInfo blk
-> Either (CannotForge blk) ()
forall p.
(BlockProtocol blk ~ p) =>
TopLevelConfig blk
-> SlotNo
-> Ticked (ChainDepState p)
-> IsLeader p
-> ForgeStateInfo blk
-> Either (CannotForge blk) ()
checkCanForge TopLevelConfig blk
cfg SlotNo
slot Ticked (ChainDepState (BlockProtocol blk))
tickedChainDepState IsLeader (BlockProtocol blk)
isLeader ForgeStateInfo blk
forgeStateInfo of
Left CannotForge blk
cannotForge -> CannotForge blk -> ShouldForge blk
forall blk. CannotForge blk -> ShouldForge blk
CannotForge CannotForge blk
cannotForge
Right () -> IsLeader (BlockProtocol blk) -> ShouldForge blk
forall blk. IsLeader (BlockProtocol blk) -> ShouldForge blk
ShouldForge IsLeader (BlockProtocol blk)
isLeader
data UpdateInfo updated unchanged failed =
Updated updated
| Unchanged unchanged
| UpdateFailed failed
deriving (Int -> UpdateInfo updated unchanged failed -> ShowS
[UpdateInfo updated unchanged failed] -> ShowS
UpdateInfo updated unchanged failed -> String
(Int -> UpdateInfo updated unchanged failed -> ShowS)
-> (UpdateInfo updated unchanged failed -> String)
-> ([UpdateInfo updated unchanged failed] -> ShowS)
-> Show (UpdateInfo updated unchanged failed)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall updated unchanged failed.
(Show updated, Show unchanged, Show failed) =>
Int -> UpdateInfo updated unchanged failed -> ShowS
forall updated unchanged failed.
(Show updated, Show unchanged, Show failed) =>
[UpdateInfo updated unchanged failed] -> ShowS
forall updated unchanged failed.
(Show updated, Show unchanged, Show failed) =>
UpdateInfo updated unchanged failed -> String
showList :: [UpdateInfo updated unchanged failed] -> ShowS
$cshowList :: forall updated unchanged failed.
(Show updated, Show unchanged, Show failed) =>
[UpdateInfo updated unchanged failed] -> ShowS
show :: UpdateInfo updated unchanged failed -> String
$cshow :: forall updated unchanged failed.
(Show updated, Show unchanged, Show failed) =>
UpdateInfo updated unchanged failed -> String
showsPrec :: Int -> UpdateInfo updated unchanged failed -> ShowS
$cshowsPrec :: forall updated unchanged failed.
(Show updated, Show unchanged, Show failed) =>
Int -> UpdateInfo updated unchanged failed -> ShowS
Show)
castUpdateInfo ::
( updated ~ updated'
, unchanged ~ unchanged'
, failed ~ failed'
)
=> UpdateInfo updated unchanged failed
-> UpdateInfo updated' unchanged' failed'
castUpdateInfo :: UpdateInfo updated unchanged failed
-> UpdateInfo updated' unchanged' failed'
castUpdateInfo = \case
Updated updated
updated -> updated -> UpdateInfo updated unchanged' failed'
forall updated unchanged failed.
updated -> UpdateInfo updated unchanged failed
Updated updated
updated
Unchanged unchanged
unchanged -> unchanged -> UpdateInfo updated' unchanged failed'
forall updated unchanged failed.
unchanged -> UpdateInfo updated unchanged failed
Unchanged unchanged
unchanged
UpdateFailed failed
failed -> failed -> UpdateInfo updated' unchanged' failed
forall updated unchanged failed.
failed -> UpdateInfo updated unchanged failed
UpdateFailed failed
failed