{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
module Ouroboros.Consensus.Storage.ChainDB.Impl.ChainSel (
addBlockAsync
, addBlockSync
, chainSelectionForBlock
, initialChainSelection
, olderThanK
) where
import Control.Exception (assert)
import Control.Monad.Except
import Control.Monad.Trans.State.Strict
import Control.Tracer (Tracer, nullTracer, traceWith)
import Data.Function (on)
import Data.List (partition, sortBy)
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NE
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (isJust)
import Data.Maybe.Strict (StrictMaybe (..), isSNothing,
strictMaybeToMaybe)
import Data.Set (Set)
import qualified Data.Set as Set
import GHC.Stack (HasCallStack)
import Ouroboros.Network.AnchoredFragment (Anchor, AnchoredFragment,
AnchoredSeq (..))
import qualified Ouroboros.Network.AnchoredFragment as AF
import Ouroboros.Consensus.Block
import Ouroboros.Consensus.Config
import Ouroboros.Consensus.Fragment.InFuture (CheckInFuture (..))
import qualified Ouroboros.Consensus.Fragment.InFuture as InFuture
import Ouroboros.Consensus.Fragment.Validated (ValidatedFragment)
import qualified Ouroboros.Consensus.Fragment.Validated as VF
import Ouroboros.Consensus.HardFork.Abstract
import qualified Ouroboros.Consensus.HardFork.History as History
import Ouroboros.Consensus.Ledger.Abstract
import Ouroboros.Consensus.Ledger.Extended
import Ouroboros.Consensus.Ledger.Inspect
import Ouroboros.Consensus.Ledger.SupportsProtocol
import Ouroboros.Consensus.Util (whenJust)
import Ouroboros.Consensus.Util.AnchoredFragment
import Ouroboros.Consensus.Util.IOLike
import Ouroboros.Consensus.Util.STM (WithFingerprint (..))
import Ouroboros.Consensus.Util.TentativeState
import Data.Functor.Contravariant ((>$<))
import Ouroboros.Consensus.Fragment.Diff (ChainDiff (..))
import qualified Ouroboros.Consensus.Fragment.Diff as Diff
import Ouroboros.Consensus.Fragment.ValidatedDiff
(ValidatedChainDiff (..))
import qualified Ouroboros.Consensus.Fragment.ValidatedDiff as ValidatedDiff
import Ouroboros.Consensus.Storage.ChainDB.API (AddBlockPromise (..),
BlockComponent (..), ChainType (..),
InvalidBlockReason (..))
import Ouroboros.Consensus.Storage.ChainDB.API.Types.InvalidBlockPunishment
(InvalidBlockPunishment)
import qualified Ouroboros.Consensus.Storage.ChainDB.API.Types.InvalidBlockPunishment as InvalidBlockPunishment
import Ouroboros.Consensus.Storage.ChainDB.Impl.BlockCache
(BlockCache)
import qualified Ouroboros.Consensus.Storage.ChainDB.Impl.BlockCache as BlockCache
import Ouroboros.Consensus.Storage.ChainDB.Impl.LgrDB (LedgerDB',
LgrDB)
import qualified Ouroboros.Consensus.Storage.ChainDB.Impl.LgrDB as LgrDB
import Ouroboros.Consensus.Storage.ChainDB.Impl.Paths
(LookupBlockInfo)
import qualified Ouroboros.Consensus.Storage.ChainDB.Impl.Paths as Paths
import qualified Ouroboros.Consensus.Storage.ChainDB.Impl.Query as Query
import Ouroboros.Consensus.Storage.ChainDB.Impl.Types
import Ouroboros.Consensus.Storage.ImmutableDB (ImmutableDB)
import qualified Ouroboros.Consensus.Storage.ImmutableDB as ImmutableDB
import Ouroboros.Consensus.Storage.VolatileDB (VolatileDB)
import qualified Ouroboros.Consensus.Storage.VolatileDB as VolatileDB
import Ouroboros.Consensus.Util.Enclose (encloseWith)
initialChainSelection
:: forall m blk. (IOLike m, LedgerSupportsProtocol blk)
=> ImmutableDB m blk
-> VolatileDB m blk
-> LgrDB m blk
-> Tracer m (TraceInitChainSelEvent blk)
-> TopLevelConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks m blk)
-> CheckInFuture m blk
-> m (ChainAndLedger blk)
initialChainSelection :: ImmutableDB m blk
-> VolatileDB m blk
-> LgrDB m blk
-> Tracer m (TraceInitChainSelEvent blk)
-> TopLevelConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks m blk)
-> CheckInFuture m blk
-> m (ChainAndLedger blk)
initialChainSelection ImmutableDB m blk
immutableDB VolatileDB m blk
volatileDB LgrDB m blk
lgrDB Tracer m (TraceInitChainSelEvent blk)
tracer TopLevelConfig blk
cfg StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid
StrictTVar m (FutureBlocks m blk)
varFutureBlocks CheckInFuture m blk
futureCheck = do
(Anchor blk
i :: Anchor blk, ChainHash blk -> Set (HeaderHash blk)
succsOf, LedgerDB' blk
ledger) <- STM
m
(Anchor blk, ChainHash blk -> Set (HeaderHash blk), LedgerDB' blk)
-> m (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
m
(Anchor blk, ChainHash blk -> Set (HeaderHash blk), LedgerDB' blk)
-> m (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk))
-> STM
m
(Anchor blk, ChainHash blk -> Set (HeaderHash blk), LedgerDB' blk)
-> m (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk)
forall a b. (a -> b) -> a -> b
$ do
InvalidBlocks blk
invalid <- WithFingerprint (InvalidBlocks blk) -> InvalidBlocks blk
forall a. WithFingerprint a -> a
forgetFingerprint (WithFingerprint (InvalidBlocks blk) -> InvalidBlocks blk)
-> STM m (WithFingerprint (InvalidBlocks blk))
-> STM m (InvalidBlocks blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> STM m (WithFingerprint (InvalidBlocks blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid
(,,)
(Anchor blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> LedgerDB' blk
-> (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk))
-> STM m (Anchor blk)
-> STM
m
((ChainHash blk -> Set (HeaderHash blk))
-> LedgerDB' blk
-> (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ImmutableDB m blk -> STM m (Anchor blk)
forall (m :: * -> *) blk.
(MonadSTM m, HasCallStack) =>
ImmutableDB m blk -> STM m (Anchor blk)
ImmutableDB.getTipAnchor ImmutableDB m blk
immutableDB
STM
m
((ChainHash blk -> Set (HeaderHash blk))
-> LedgerDB' blk
-> (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk))
-> STM m (ChainHash blk -> Set (HeaderHash blk))
-> STM
m
(LedgerDB' blk
-> (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (VolatileDB m blk
-> InvalidBlocks blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> ChainHash blk
-> Set (HeaderHash blk)
forall blk (proxy :: * -> *).
HasHeader blk =>
proxy blk
-> InvalidBlocks blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> ChainHash blk
-> Set (HeaderHash blk)
ignoreInvalidSuc VolatileDB m blk
volatileDB InvalidBlocks blk
invalid ((ChainHash blk -> Set (HeaderHash blk))
-> ChainHash blk -> Set (HeaderHash blk))
-> STM m (ChainHash blk -> Set (HeaderHash blk))
-> STM m (ChainHash blk -> Set (HeaderHash blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
VolatileDB m blk
-> HasCallStack => STM m (ChainHash blk -> Set (HeaderHash blk))
forall (m :: * -> *) blk.
VolatileDB m blk
-> HasCallStack => STM m (ChainHash blk -> Set (HeaderHash blk))
VolatileDB.filterByPredecessor VolatileDB m blk
volatileDB)
STM
m
(LedgerDB' blk
-> (Anchor blk, ChainHash blk -> Set (HeaderHash blk),
LedgerDB' blk))
-> STM m (LedgerDB' blk)
-> STM
m
(Anchor blk, ChainHash blk -> Set (HeaderHash blk), LedgerDB' blk)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> LgrDB m blk -> STM m (LedgerDB' blk)
forall (m :: * -> *) blk.
IOLike m =>
LgrDB m blk -> STM m (LedgerDB' blk)
LgrDB.getCurrent LgrDB m blk
lgrDB
[AnchoredFragment (Header blk)]
chains <- Anchor blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> m [AnchoredFragment (Header blk)]
constructChains Anchor blk
i ChainHash blk -> Set (HeaderHash blk)
succsOf
let curChain :: AnchoredFragment (Header blk)
curChain = Anchor (Header blk) -> AnchoredFragment (Header blk)
forall v a b. Anchorable v a b => a -> AnchoredSeq v a b
Empty (Anchor blk -> Anchor (Header blk)
forall a b. (HeaderHash a ~ HeaderHash b) => Anchor a -> Anchor b
AF.castAnchor Anchor blk
i)
curChainAndLedger :: ChainAndLedger blk
curChainAndLedger = AnchoredFragment (Header blk)
-> LedgerDB' blk -> ChainAndLedger blk
forall l b.
(IsLedger l, HasHeader b, HeaderHash b ~ HeaderHash l,
HasCallStack) =>
AnchoredFragment b -> l -> ValidatedFragment b l
VF.ValidatedFragment AnchoredFragment (Header blk)
curChain LedgerDB' blk
ledger
case [AnchoredFragment (Header blk)]
-> Maybe (NonEmpty (AnchoredFragment (Header blk)))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty ((AnchoredFragment (Header blk) -> Bool)
-> [AnchoredFragment (Header blk)]
-> [AnchoredFragment (Header blk)]
forall a. (a -> Bool) -> [a] -> [a]
filter (BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate BlockConfig blk
bcfg AnchoredFragment (Header blk)
curChain) [AnchoredFragment (Header blk)]
chains) of
Maybe (NonEmpty (AnchoredFragment (Header blk)))
Nothing -> ChainAndLedger blk -> m (ChainAndLedger blk)
forall (m :: * -> *) a. Monad m => a -> m a
return ChainAndLedger blk
curChainAndLedger
Just NonEmpty (AnchoredFragment (Header blk))
chains' -> ChainAndLedger blk
-> (ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ChainAndLedger blk)
-> Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> ChainAndLedger blk
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ChainAndLedger blk
curChainAndLedger ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ChainAndLedger blk
toChainAndLedger (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> ChainAndLedger blk)
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (ChainAndLedger blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
HasCallStack =>
ChainAndLedger blk
-> NonEmpty (AnchoredFragment (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
ChainAndLedger blk
-> NonEmpty (AnchoredFragment (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection' ChainAndLedger blk
curChainAndLedger NonEmpty (AnchoredFragment (Header blk))
chains'
where
bcfg :: BlockConfig blk
bcfg :: BlockConfig blk
bcfg = TopLevelConfig blk -> BlockConfig blk
forall blk. TopLevelConfig blk -> BlockConfig blk
configBlock TopLevelConfig blk
cfg
toChainAndLedger
:: ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ChainAndLedger blk
toChainAndLedger :: ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ChainAndLedger blk
toChainAndLedger (ValidatedChainDiff ChainDiff (Header blk)
chainDiff LedgerDB' blk
ledger) =
case ChainDiff (Header blk)
chainDiff of
ChainDiff Word64
rollback AnchoredFragment (Header blk)
suffix
| Word64
rollback Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0
-> AnchoredFragment (Header blk)
-> LedgerDB' blk -> ChainAndLedger blk
forall l b.
(IsLedger l, HasHeader b, HeaderHash b ~ HeaderHash l,
HasCallStack) =>
AnchoredFragment b -> l -> ValidatedFragment b l
VF.ValidatedFragment AnchoredFragment (Header blk)
suffix LedgerDB' blk
ledger
| Bool
otherwise
-> [Char] -> ChainAndLedger blk
forall a. HasCallStack => [Char] -> a
error [Char]
"constructed an initial chain with rollback"
constructChains ::
Anchor blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> m [AnchoredFragment (Header blk)]
constructChains :: Anchor blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> m [AnchoredFragment (Header blk)]
constructChains Anchor blk
i ChainHash blk -> Set (HeaderHash blk)
succsOf = (StateT
(Map (HeaderHash blk) (Header blk))
m
[AnchoredFragment (Header blk)]
-> Map (HeaderHash blk) (Header blk)
-> m [AnchoredFragment (Header blk)])
-> Map (HeaderHash blk) (Header blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
[AnchoredFragment (Header blk)]
-> m [AnchoredFragment (Header blk)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT
(Map (HeaderHash blk) (Header blk))
m
[AnchoredFragment (Header blk)]
-> Map (HeaderHash blk) (Header blk)
-> m [AnchoredFragment (Header blk)]
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT Map (HeaderHash blk) (Header blk)
forall k a. Map k a
Map.empty (StateT
(Map (HeaderHash blk) (Header blk))
m
[AnchoredFragment (Header blk)]
-> m [AnchoredFragment (Header blk)])
-> StateT
(Map (HeaderHash blk) (Header blk))
m
[AnchoredFragment (Header blk)]
-> m [AnchoredFragment (Header blk)]
forall a b. (a -> b) -> a -> b
$
(NonEmpty (HeaderHash blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk)))
-> [NonEmpty (HeaderHash blk)]
-> StateT
(Map (HeaderHash blk) (Header blk))
m
[AnchoredFragment (Header blk)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM NonEmpty (HeaderHash blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk))
constructChain [NonEmpty (HeaderHash blk)]
suffixesAfterI
where
suffixesAfterI :: [NonEmpty (HeaderHash blk)]
suffixesAfterI :: [NonEmpty (HeaderHash blk)]
suffixesAfterI = (ChainHash blk -> Set (HeaderHash blk))
-> Point blk -> [NonEmpty (HeaderHash blk)]
forall blk.
(ChainHash blk -> Set (HeaderHash blk))
-> Point blk -> [NonEmpty (HeaderHash blk)]
Paths.maximalCandidates ChainHash blk -> Set (HeaderHash blk)
succsOf (Anchor blk -> Point blk
forall block. Anchor block -> Point block
AF.anchorToPoint Anchor blk
i)
constructChain ::
NonEmpty (HeaderHash blk)
-> StateT (Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk))
constructChain :: NonEmpty (HeaderHash blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk))
constructChain NonEmpty (HeaderHash blk)
hashes =
Anchor (Header blk)
-> [Header blk] -> AnchoredFragment (Header blk)
forall v a b. Anchorable v a b => a -> [b] -> AnchoredSeq v a b
AF.fromOldestFirst (Anchor blk -> Anchor (Header blk)
forall a b. (HeaderHash a ~ HeaderHash b) => Anchor a -> Anchor b
AF.castAnchor Anchor blk
i) ([Header blk] -> AnchoredFragment (Header blk))
-> StateT (Map (HeaderHash blk) (Header blk)) m [Header blk]
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk))
-> [HeaderHash blk]
-> StateT (Map (HeaderHash blk) (Header blk)) m [Header blk]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (VolatileDB m blk
-> HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall (m :: * -> *) blk.
(MonadThrow m, HasHeader blk) =>
VolatileDB m blk
-> HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
getKnownHeaderThroughCache VolatileDB m blk
volatileDB) (NonEmpty (HeaderHash blk) -> [HeaderHash blk]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty (HeaderHash blk)
hashes)
chainSelection' ::
HasCallStack
=> ChainAndLedger blk
-> NonEmpty (AnchoredFragment (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection' :: ChainAndLedger blk
-> NonEmpty (AnchoredFragment (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection' ChainAndLedger blk
curChainAndLedger NonEmpty (AnchoredFragment (Header blk))
candidates =
Bool
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a. HasCallStack => Bool -> a -> a
assert ((AnchoredFragment (Header blk) -> Bool)
-> NonEmpty (AnchoredFragment (Header blk)) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((LedgerDB' blk -> Point blk
forall blk. UpdateLedger blk => LedgerDB' blk -> Point blk
LgrDB.currentPoint LedgerDB' blk
ledger Point blk -> Point blk -> Bool
forall a. Eq a => a -> a -> Bool
==) (Point blk -> Bool)
-> (AnchoredFragment (Header blk) -> Point blk)
-> AnchoredFragment (Header blk)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Point (Header blk) -> Point blk
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> (AnchoredFragment (Header blk) -> Point (Header blk))
-> AnchoredFragment (Header blk)
-> Point blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnchoredFragment (Header blk) -> Point (Header blk)
forall block. AnchoredFragment block -> Point block
AF.anchorPoint)
NonEmpty (AnchoredFragment (Header blk))
candidates) (m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$
Bool
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a. HasCallStack => Bool -> a -> a
assert ((AnchoredFragment (Header blk) -> Bool)
-> NonEmpty (AnchoredFragment (Header blk)) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate BlockConfig blk
bcfg AnchoredFragment (Header blk)
curChain) NonEmpty (AnchoredFragment (Header blk))
candidates) (m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$ do
ChainSelEnv m blk
cse <- m (ChainSelEnv m blk)
chainSelEnv
ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, HasCallStack) =>
ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection ChainSelEnv m blk
cse (AnchoredFragment (Header blk) -> ChainDiff (Header blk)
forall b. AnchoredFragment b -> ChainDiff b
Diff.extend (AnchoredFragment (Header blk) -> ChainDiff (Header blk))
-> NonEmpty (AnchoredFragment (Header blk))
-> NonEmpty (ChainDiff (Header blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (AnchoredFragment (Header blk))
candidates)
where
curChain :: AnchoredFragment (Header blk)
curChain = ChainAndLedger blk -> AnchoredFragment (Header blk)
forall b l. ValidatedFragment b l -> AnchoredFragment b
VF.validatedFragment ChainAndLedger blk
curChainAndLedger
ledger :: LedgerDB' blk
ledger = ChainAndLedger blk -> LedgerDB' blk
forall b l. ValidatedFragment b l -> l
VF.validatedLedger ChainAndLedger blk
curChainAndLedger
chainSelEnv :: m (ChainSelEnv m blk)
chainSelEnv = do
StrictTVar m (TentativeState blk)
varTentativeState <- TentativeState blk -> m (StrictTVar m (TentativeState blk))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO TentativeState blk
forall blk. TentativeState blk
NoLastInvalidTentative
StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader <- StrictMaybe (Header blk)
-> m (StrictTVar m (StrictMaybe (Header blk)))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO StrictMaybe (Header blk)
forall a. StrictMaybe a
SNothing
ChainSelEnv m blk -> m (ChainSelEnv m blk)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChainSelEnv :: forall (m :: * -> *) blk.
LgrDB m blk
-> Tracer m (TraceValidationEvent blk)
-> Tracer m (TracePipeliningEvent blk)
-> BlockConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks m blk)
-> StrictTVar m (TentativeState blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> STM m [FollowerHandle m blk]
-> CheckInFuture m blk
-> BlockCache blk
-> ChainAndLedger blk
-> Maybe (RealPoint blk, InvalidBlockPunishment m)
-> ChainSelEnv m blk
ChainSelEnv
{ LgrDB m blk
lgrDB :: LgrDB m blk
lgrDB :: LgrDB m blk
lgrDB
, BlockConfig blk
bcfg :: BlockConfig blk
bcfg :: BlockConfig blk
bcfg
, StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid
, StrictTVar m (FutureBlocks m blk)
varFutureBlocks :: StrictTVar m (FutureBlocks m blk)
varFutureBlocks :: StrictTVar m (FutureBlocks m blk)
varFutureBlocks
, CheckInFuture m blk
futureCheck :: CheckInFuture m blk
futureCheck :: CheckInFuture m blk
futureCheck
, blockCache :: BlockCache blk
blockCache = BlockCache blk
forall blk. BlockCache blk
BlockCache.empty
, ChainAndLedger blk
curChainAndLedger :: ChainAndLedger blk
curChainAndLedger :: ChainAndLedger blk
curChainAndLedger
, validationTracer :: Tracer m (TraceValidationEvent blk)
validationTracer = TraceValidationEvent blk -> TraceInitChainSelEvent blk
forall blk. TraceValidationEvent blk -> TraceInitChainSelEvent blk
InitChainSelValidation (TraceValidationEvent blk -> TraceInitChainSelEvent blk)
-> Tracer m (TraceInitChainSelEvent blk)
-> Tracer m (TraceValidationEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceInitChainSelEvent blk)
tracer
, pipeliningTracer :: Tracer m (TracePipeliningEvent blk)
pipeliningTracer = Tracer m (TracePipeliningEvent blk)
forall (m :: * -> *) a. Applicative m => Tracer m a
nullTracer
, StrictTVar m (TentativeState blk)
varTentativeState :: StrictTVar m (TentativeState blk)
varTentativeState :: StrictTVar m (TentativeState blk)
varTentativeState
, StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader :: StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader :: StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader
, punish :: Maybe (RealPoint blk, InvalidBlockPunishment m)
punish = Maybe (RealPoint blk, InvalidBlockPunishment m)
forall a. Maybe a
Nothing
, getTentativeFollowers :: STM m [FollowerHandle m blk]
getTentativeFollowers = [FollowerHandle m blk] -> STM m [FollowerHandle m blk]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
}
addBlockAsync
:: forall m blk. (IOLike m, HasHeader blk)
=> ChainDbEnv m blk
-> InvalidBlockPunishment m
-> blk
-> m (AddBlockPromise m blk)
addBlockAsync :: ChainDbEnv m blk
-> InvalidBlockPunishment m -> blk -> m (AddBlockPromise m blk)
addBlockAsync CDB { Tracer m (TraceEvent blk)
cdbTracer :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> Tracer m (TraceEvent blk)
cdbTracer :: Tracer m (TraceEvent blk)
cdbTracer, BlocksToAdd m blk
cdbBlocksToAdd :: forall (m :: * -> *) blk. ChainDbEnv m blk -> BlocksToAdd m blk
cdbBlocksToAdd :: BlocksToAdd m blk
cdbBlocksToAdd } =
Tracer m (TraceAddBlockEvent blk)
-> BlocksToAdd m blk
-> InvalidBlockPunishment m
-> blk
-> m (AddBlockPromise m blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader blk) =>
Tracer m (TraceAddBlockEvent blk)
-> BlocksToAdd m blk
-> InvalidBlockPunishment m
-> blk
-> m (AddBlockPromise m blk)
addBlockToAdd (TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent (TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceEvent blk)
cdbTracer) BlocksToAdd m blk
cdbBlocksToAdd
addBlockSync
:: forall m blk.
( IOLike m
, GetPrevHash blk
, LedgerSupportsProtocol blk
, InspectLedger blk
, HasHardForkHistory blk
, HasCallStack
)
=> ChainDbEnv m blk
-> BlockToAdd m blk
-> m ()
addBlockSync :: ChainDbEnv m blk -> BlockToAdd m blk -> m ()
addBlockSync cdb :: ChainDbEnv m blk
cdb@CDB {Tracer m (LedgerDB' blk)
Tracer m (TraceEvent blk)
DiffTime
StrictTVar m (m ())
StrictTVar m (FutureBlocks m blk)
StrictTVar m (Map FollowerKey (FollowerHandle m blk))
StrictTVar m (Map IteratorKey (m ()))
StrictTVar m (AnchoredFragment (Header blk))
StrictTVar m (StrictMaybe (Header blk))
StrictTVar m (WithFingerprint (InvalidBlocks blk))
StrictTVar m (TentativeState blk)
StrictTVar m FollowerKey
StrictTVar m IteratorKey
TopLevelConfig blk
StrictMVar m ()
VolatileDB m blk
ChunkInfo
ResourceRegistry m
ImmutableDB m blk
CheckInFuture m blk
LgrDB m blk
BlocksToAdd m blk
blk -> Bool
cdbFutureBlocks :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (FutureBlocks m blk)
cdbCheckInFuture :: forall (m :: * -> *) blk. ChainDbEnv m blk -> CheckInFuture m blk
cdbCheckIntegrity :: forall (m :: * -> *) blk. ChainDbEnv m blk -> blk -> Bool
cdbChunkInfo :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ChunkInfo
cdbKillBgThreads :: forall (m :: * -> *) blk. ChainDbEnv m blk -> StrictTVar m (m ())
cdbGcInterval :: forall (m :: * -> *) blk. ChainDbEnv m blk -> DiffTime
cdbGcDelay :: forall (m :: * -> *) blk. ChainDbEnv m blk -> DiffTime
cdbRegistry :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ResourceRegistry m
cdbTraceLedger :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> Tracer m (LedgerDB' blk)
cdbCopyLock :: forall (m :: * -> *) blk. ChainDbEnv m blk -> StrictMVar m ()
cdbNextFollowerKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m FollowerKey
cdbNextIteratorKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m IteratorKey
cdbInvalid :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: forall (m :: * -> *) blk. ChainDbEnv m blk -> TopLevelConfig blk
cdbFollowers :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbIterators :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (Map IteratorKey (m ()))
cdbTentativeHeader :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
cdbTentativeState :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (TentativeState blk)
cdbChain :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (AnchoredFragment (Header blk))
cdbLgrDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> LgrDB m blk
cdbVolatileDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> VolatileDB m blk
cdbImmutableDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ImmutableDB m blk
cdbFutureBlocks :: StrictTVar m (FutureBlocks m blk)
cdbBlocksToAdd :: BlocksToAdd m blk
cdbCheckInFuture :: CheckInFuture m blk
cdbCheckIntegrity :: blk -> Bool
cdbChunkInfo :: ChunkInfo
cdbKillBgThreads :: StrictTVar m (m ())
cdbGcInterval :: DiffTime
cdbGcDelay :: DiffTime
cdbRegistry :: ResourceRegistry m
cdbTraceLedger :: Tracer m (LedgerDB' blk)
cdbTracer :: Tracer m (TraceEvent blk)
cdbCopyLock :: StrictMVar m ()
cdbNextFollowerKey :: StrictTVar m FollowerKey
cdbNextIteratorKey :: StrictTVar m IteratorKey
cdbInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: TopLevelConfig blk
cdbFollowers :: StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbIterators :: StrictTVar m (Map IteratorKey (m ()))
cdbTentativeHeader :: StrictTVar m (StrictMaybe (Header blk))
cdbTentativeState :: StrictTVar m (TentativeState blk)
cdbChain :: StrictTVar m (AnchoredFragment (Header blk))
cdbLgrDB :: LgrDB m blk
cdbVolatileDB :: VolatileDB m blk
cdbImmutableDB :: ImmutableDB m blk
cdbBlocksToAdd :: forall (m :: * -> *) blk. ChainDbEnv m blk -> BlocksToAdd m blk
cdbTracer :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> Tracer m (TraceEvent blk)
..} BlockToAdd { blockToAdd :: forall (m :: * -> *) blk. BlockToAdd m blk -> blk
blockToAdd = blk
b, StrictTMVar m Bool
StrictTMVar m (Point blk)
InvalidBlockPunishment m
varBlockProcessed :: forall (m :: * -> *) blk.
BlockToAdd m blk -> StrictTMVar m (Point blk)
varBlockWrittenToDisk :: forall (m :: * -> *) blk. BlockToAdd m blk -> StrictTMVar m Bool
blockPunish :: forall (m :: * -> *) blk.
BlockToAdd m blk -> InvalidBlockPunishment m
varBlockProcessed :: StrictTMVar m (Point blk)
varBlockWrittenToDisk :: StrictTMVar m Bool
blockPunish :: InvalidBlockPunishment m
.. } = do
(HeaderHash blk -> Bool
isMember, InvalidBlocks blk
invalid, AnchoredFragment (Header blk)
curChain) <- STM
m
(HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk))
-> m (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
m
(HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk))
-> m (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk)))
-> STM
m
(HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk))
-> m (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk))
forall a b. (a -> b) -> a -> b
$ (,,)
((HeaderHash blk -> Bool)
-> InvalidBlocks blk
-> AnchoredFragment (Header blk)
-> (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk)))
-> STM m (HeaderHash blk -> Bool)
-> STM
m
(InvalidBlocks blk
-> AnchoredFragment (Header blk)
-> (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VolatileDB m blk -> STM m (HeaderHash blk -> Bool)
forall (m :: * -> *) blk.
Functor (STM m) =>
VolatileDB m blk -> STM m (HeaderHash blk -> Bool)
VolatileDB.getIsMember VolatileDB m blk
cdbVolatileDB
STM
m
(InvalidBlocks blk
-> AnchoredFragment (Header blk)
-> (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk)))
-> STM m (InvalidBlocks blk)
-> STM
m
(AnchoredFragment (Header blk)
-> (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk)))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (WithFingerprint (InvalidBlocks blk) -> InvalidBlocks blk
forall a. WithFingerprint a -> a
forgetFingerprint (WithFingerprint (InvalidBlocks blk) -> InvalidBlocks blk)
-> STM m (WithFingerprint (InvalidBlocks blk))
-> STM m (InvalidBlocks blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> STM m (WithFingerprint (InvalidBlocks blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbInvalid)
STM
m
(AnchoredFragment (Header blk)
-> (HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk)))
-> STM m (AnchoredFragment (Header blk))
-> STM
m
(HeaderHash blk -> Bool, InvalidBlocks blk,
AnchoredFragment (Header blk))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ChainDbEnv m blk -> STM m (AnchoredFragment (Header blk))
forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk),
ConsensusProtocol (BlockProtocol blk)) =>
ChainDbEnv m blk -> STM m (AnchoredFragment (Header blk))
Query.getCurrentChain ChainDbEnv m blk
cdb
let immBlockNo :: WithOrigin BlockNo
immBlockNo = AnchoredFragment (Header blk) -> WithOrigin BlockNo
forall block. AnchoredFragment block -> WithOrigin BlockNo
AF.anchorBlockNo AnchoredFragment (Header blk)
curChain
Point blk
newTip <- if
| Header blk -> IsEBB -> WithOrigin BlockNo -> Bool
forall blk.
HasHeader (Header blk) =>
Header blk -> IsEBB -> WithOrigin BlockNo -> Bool
olderThanK Header blk
hdr IsEBB
isEBB WithOrigin BlockNo
immBlockNo -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ RealPoint blk -> TraceAddBlockEvent blk
forall blk. RealPoint blk -> TraceAddBlockEvent blk
IgnoreBlockOlderThanK (blk -> RealPoint blk
forall blk. HasHeader blk => blk -> RealPoint blk
blockRealPoint blk
b)
Bool -> m ()
deliverWrittenToDisk Bool
False
ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, InspectLedger blk,
HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
chainSelectionForFutureBlocks ChainDbEnv m blk
cdb BlockCache blk
forall blk. BlockCache blk
BlockCache.empty
| HeaderHash blk -> Bool
isMember (blk -> HeaderHash blk
forall b. HasHeader b => b -> HeaderHash b
blockHash blk
b) -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ RealPoint blk -> TraceAddBlockEvent blk
forall blk. RealPoint blk -> TraceAddBlockEvent blk
IgnoreBlockAlreadyInVolatileDB (blk -> RealPoint blk
forall blk. HasHeader blk => blk -> RealPoint blk
blockRealPoint blk
b)
Bool -> m ()
deliverWrittenToDisk Bool
True
ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, InspectLedger blk,
HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
chainSelectionForFutureBlocks ChainDbEnv m blk
cdb BlockCache blk
forall blk. BlockCache blk
BlockCache.empty
| Just (InvalidBlockInfo InvalidBlockReason blk
reason SlotNo
_) <- HeaderHash blk -> InvalidBlocks blk -> Maybe (InvalidBlockInfo blk)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (blk -> HeaderHash blk
forall b. HasHeader b => b -> HeaderHash b
blockHash blk
b) InvalidBlocks blk
invalid -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ RealPoint blk -> InvalidBlockReason blk -> TraceAddBlockEvent blk
forall blk.
RealPoint blk -> InvalidBlockReason blk -> TraceAddBlockEvent blk
IgnoreInvalidBlock (blk -> RealPoint blk
forall blk. HasHeader blk => blk -> RealPoint blk
blockRealPoint blk
b) InvalidBlockReason blk
reason
Bool -> m ()
deliverWrittenToDisk Bool
False
InvalidBlockPunishment m -> Invalidity -> m ()
forall (m :: * -> *).
InvalidBlockPunishment m -> Invalidity -> m ()
InvalidBlockPunishment.enact
InvalidBlockPunishment m
blockPunish
Invalidity
InvalidBlockPunishment.BlockItself
ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, InspectLedger blk,
HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
chainSelectionForFutureBlocks ChainDbEnv m blk
cdb BlockCache blk
forall blk. BlockCache blk
BlockCache.empty
| Bool
otherwise -> do
let traceEv :: Enclosing -> TraceAddBlockEvent blk
traceEv = RealPoint blk
-> BlockNo -> IsEBB -> Enclosing -> TraceAddBlockEvent blk
forall blk.
RealPoint blk
-> BlockNo -> IsEBB -> Enclosing -> TraceAddBlockEvent blk
AddedBlockToVolatileDB (blk -> RealPoint blk
forall blk. HasHeader blk => blk -> RealPoint blk
blockRealPoint blk
b) (blk -> BlockNo
forall b. HasHeader b => b -> BlockNo
blockNo blk
b) IsEBB
isEBB
Tracer m Enclosing -> m () -> m ()
forall (m :: * -> *) a.
Applicative m =>
Tracer m Enclosing -> m a -> m a
encloseWith (Enclosing -> TraceAddBlockEvent blk
traceEv (Enclosing -> TraceAddBlockEvent blk)
-> Tracer m (TraceAddBlockEvent blk) -> Tracer m Enclosing
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceAddBlockEvent blk)
addBlockTracer) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
VolatileDB m blk -> blk -> m ()
forall (m :: * -> *) blk.
VolatileDB m blk -> HasCallStack => blk -> m ()
VolatileDB.putBlock VolatileDB m blk
cdbVolatileDB blk
b
Bool -> m ()
deliverWrittenToDisk Bool
True
let blockCache :: BlockCache blk
blockCache = blk -> BlockCache blk
forall blk. HasHeader blk => blk -> BlockCache blk
BlockCache.singleton blk
b
m (Point blk) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Point blk) -> m ()) -> m (Point blk) -> m ()
forall a b. (a -> b) -> a -> b
$ ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, InspectLedger blk,
HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
chainSelectionForFutureBlocks ChainDbEnv m blk
cdb BlockCache blk
blockCache
ChainDbEnv m blk
-> BlockCache blk
-> Header blk
-> InvalidBlockPunishment m
-> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader blk, LedgerSupportsProtocol blk,
InspectLedger blk, HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk
-> BlockCache blk
-> Header blk
-> InvalidBlockPunishment m
-> m (Point blk)
chainSelectionForBlock ChainDbEnv m blk
cdb BlockCache blk
blockCache Header blk
hdr InvalidBlockPunishment m
blockPunish
Point blk -> m ()
deliverProcessed Point blk
newTip
where
addBlockTracer :: Tracer m (TraceAddBlockEvent blk)
addBlockTracer :: Tracer m (TraceAddBlockEvent blk)
addBlockTracer = TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent (TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceEvent blk)
cdbTracer
hdr :: Header blk
hdr :: Header blk
hdr = blk -> Header blk
forall blk. GetHeader blk => blk -> Header blk
getHeader blk
b
isEBB :: IsEBB
isEBB :: IsEBB
isEBB = Header blk -> IsEBB
forall blk. GetHeader blk => Header blk -> IsEBB
headerToIsEBB Header blk
hdr
deliverWrittenToDisk :: Bool -> m ()
deliverWrittenToDisk :: Bool -> m ()
deliverWrittenToDisk Bool
writtenToDisk = STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$
StrictTMVar m Bool -> Bool -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTMVar m a -> a -> STM m ()
putTMVar StrictTMVar m Bool
varBlockWrittenToDisk Bool
writtenToDisk
deliverProcessed :: Point blk -> m ()
deliverProcessed :: Point blk -> m ()
deliverProcessed Point blk
tip = STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$
StrictTMVar m (Point blk) -> Point blk -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTMVar m a -> a -> STM m ()
putTMVar StrictTMVar m (Point blk)
varBlockProcessed Point blk
tip
olderThanK
:: HasHeader (Header blk)
=> Header blk
-> IsEBB
-> WithOrigin BlockNo
-> Bool
olderThanK :: Header blk -> IsEBB -> WithOrigin BlockNo -> Bool
olderThanK Header blk
hdr IsEBB
isEBB WithOrigin BlockNo
immBlockNo
| BlockNo -> WithOrigin BlockNo
forall t. t -> WithOrigin t
NotOrigin BlockNo
bNo WithOrigin BlockNo -> WithOrigin BlockNo -> Bool
forall a. Eq a => a -> a -> Bool
== WithOrigin BlockNo
immBlockNo
, IsEBB
isEBB IsEBB -> IsEBB -> Bool
forall a. Eq a => a -> a -> Bool
== IsEBB
IsEBB
= Bool
False
| Bool
otherwise
= BlockNo -> WithOrigin BlockNo
forall t. t -> WithOrigin t
NotOrigin BlockNo
bNo WithOrigin BlockNo -> WithOrigin BlockNo -> Bool
forall a. Ord a => a -> a -> Bool
<= WithOrigin BlockNo
immBlockNo
where
bNo :: BlockNo
bNo = Header blk -> BlockNo
forall b. HasHeader b => b -> BlockNo
blockNo Header blk
hdr
data ChainSwitchType = AddingBlocks | SwitchingToAFork
deriving (Int -> ChainSwitchType -> ShowS
[ChainSwitchType] -> ShowS
ChainSwitchType -> [Char]
(Int -> ChainSwitchType -> ShowS)
-> (ChainSwitchType -> [Char])
-> ([ChainSwitchType] -> ShowS)
-> Show ChainSwitchType
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [ChainSwitchType] -> ShowS
$cshowList :: [ChainSwitchType] -> ShowS
show :: ChainSwitchType -> [Char]
$cshow :: ChainSwitchType -> [Char]
showsPrec :: Int -> ChainSwitchType -> ShowS
$cshowsPrec :: Int -> ChainSwitchType -> ShowS
Show, ChainSwitchType -> ChainSwitchType -> Bool
(ChainSwitchType -> ChainSwitchType -> Bool)
-> (ChainSwitchType -> ChainSwitchType -> Bool)
-> Eq ChainSwitchType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ChainSwitchType -> ChainSwitchType -> Bool
$c/= :: ChainSwitchType -> ChainSwitchType -> Bool
== :: ChainSwitchType -> ChainSwitchType -> Bool
$c== :: ChainSwitchType -> ChainSwitchType -> Bool
Eq)
chainSelectionForFutureBlocks
:: ( IOLike m
, LedgerSupportsProtocol blk
, InspectLedger blk
, HasHardForkHistory blk
, HasCallStack
)
=> ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
chainSelectionForFutureBlocks :: ChainDbEnv m blk -> BlockCache blk -> m (Point blk)
chainSelectionForFutureBlocks cdb :: ChainDbEnv m blk
cdb@CDB{Tracer m (LedgerDB' blk)
Tracer m (TraceEvent blk)
DiffTime
StrictTVar m (m ())
StrictTVar m (FutureBlocks m blk)
StrictTVar m (Map FollowerKey (FollowerHandle m blk))
StrictTVar m (Map IteratorKey (m ()))
StrictTVar m (AnchoredFragment (Header blk))
StrictTVar m (StrictMaybe (Header blk))
StrictTVar m (WithFingerprint (InvalidBlocks blk))
StrictTVar m (TentativeState blk)
StrictTVar m FollowerKey
StrictTVar m IteratorKey
TopLevelConfig blk
StrictMVar m ()
VolatileDB m blk
ChunkInfo
ResourceRegistry m
ImmutableDB m blk
CheckInFuture m blk
LgrDB m blk
BlocksToAdd m blk
blk -> Bool
cdbFutureBlocks :: StrictTVar m (FutureBlocks m blk)
cdbBlocksToAdd :: BlocksToAdd m blk
cdbCheckInFuture :: CheckInFuture m blk
cdbCheckIntegrity :: blk -> Bool
cdbChunkInfo :: ChunkInfo
cdbKillBgThreads :: StrictTVar m (m ())
cdbGcInterval :: DiffTime
cdbGcDelay :: DiffTime
cdbRegistry :: ResourceRegistry m
cdbTraceLedger :: Tracer m (LedgerDB' blk)
cdbTracer :: Tracer m (TraceEvent blk)
cdbCopyLock :: StrictMVar m ()
cdbNextFollowerKey :: StrictTVar m FollowerKey
cdbNextIteratorKey :: StrictTVar m IteratorKey
cdbInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: TopLevelConfig blk
cdbFollowers :: StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbIterators :: StrictTVar m (Map IteratorKey (m ()))
cdbTentativeHeader :: StrictTVar m (StrictMaybe (Header blk))
cdbTentativeState :: StrictTVar m (TentativeState blk)
cdbChain :: StrictTVar m (AnchoredFragment (Header blk))
cdbLgrDB :: LgrDB m blk
cdbVolatileDB :: VolatileDB m blk
cdbImmutableDB :: ImmutableDB m blk
cdbFutureBlocks :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (FutureBlocks m blk)
cdbCheckInFuture :: forall (m :: * -> *) blk. ChainDbEnv m blk -> CheckInFuture m blk
cdbCheckIntegrity :: forall (m :: * -> *) blk. ChainDbEnv m blk -> blk -> Bool
cdbChunkInfo :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ChunkInfo
cdbKillBgThreads :: forall (m :: * -> *) blk. ChainDbEnv m blk -> StrictTVar m (m ())
cdbGcInterval :: forall (m :: * -> *) blk. ChainDbEnv m blk -> DiffTime
cdbGcDelay :: forall (m :: * -> *) blk. ChainDbEnv m blk -> DiffTime
cdbRegistry :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ResourceRegistry m
cdbTraceLedger :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> Tracer m (LedgerDB' blk)
cdbCopyLock :: forall (m :: * -> *) blk. ChainDbEnv m blk -> StrictMVar m ()
cdbNextFollowerKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m FollowerKey
cdbNextIteratorKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m IteratorKey
cdbInvalid :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: forall (m :: * -> *) blk. ChainDbEnv m blk -> TopLevelConfig blk
cdbFollowers :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbIterators :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (Map IteratorKey (m ()))
cdbTentativeHeader :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
cdbTentativeState :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (TentativeState blk)
cdbChain :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (AnchoredFragment (Header blk))
cdbLgrDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> LgrDB m blk
cdbVolatileDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> VolatileDB m blk
cdbImmutableDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ImmutableDB m blk
cdbBlocksToAdd :: forall (m :: * -> *) blk. ChainDbEnv m blk -> BlocksToAdd m blk
cdbTracer :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> Tracer m (TraceEvent blk)
..} BlockCache blk
blockCache = do
[(Header blk, InvalidBlockPunishment m)]
futureBlockHeaders <- STM m [(Header blk, InvalidBlockPunishment m)]
-> m [(Header blk, InvalidBlockPunishment m)]
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m [(Header blk, InvalidBlockPunishment m)]
-> m [(Header blk, InvalidBlockPunishment m)])
-> STM m [(Header blk, InvalidBlockPunishment m)]
-> m [(Header blk, InvalidBlockPunishment m)]
forall a b. (a -> b) -> a -> b
$ do
FutureBlocks m blk
futureBlocks <- StrictTVar m (FutureBlocks m blk) -> STM m (FutureBlocks m blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (FutureBlocks m blk)
cdbFutureBlocks
StrictTVar m (FutureBlocks m blk) -> FutureBlocks m blk -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (FutureBlocks m blk)
cdbFutureBlocks FutureBlocks m blk
forall k a. Map k a
Map.empty
[(Header blk, InvalidBlockPunishment m)]
-> STM m [(Header blk, InvalidBlockPunishment m)]
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Header blk, InvalidBlockPunishment m)]
-> STM m [(Header blk, InvalidBlockPunishment m)])
-> [(Header blk, InvalidBlockPunishment m)]
-> STM m [(Header blk, InvalidBlockPunishment m)]
forall a b. (a -> b) -> a -> b
$ FutureBlocks m blk -> [(Header blk, InvalidBlockPunishment m)]
forall k a. Map k a -> [a]
Map.elems FutureBlocks m blk
futureBlocks
[(Header blk, InvalidBlockPunishment m)]
-> ((Header blk, InvalidBlockPunishment m) -> m (Point blk))
-> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Header blk, InvalidBlockPunishment m)]
futureBlockHeaders (((Header blk, InvalidBlockPunishment m) -> m (Point blk)) -> m ())
-> ((Header blk, InvalidBlockPunishment m) -> m (Point blk))
-> m ()
forall a b. (a -> b) -> a -> b
$ \(Header blk
hdr, InvalidBlockPunishment m
punish) -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
tracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ RealPoint blk -> TraceAddBlockEvent blk
forall blk. RealPoint blk -> TraceAddBlockEvent blk
ChainSelectionForFutureBlock (Header blk -> RealPoint blk
forall blk. HasHeader (Header blk) => Header blk -> RealPoint blk
headerRealPoint Header blk
hdr)
ChainDbEnv m blk
-> BlockCache blk
-> Header blk
-> InvalidBlockPunishment m
-> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader blk, LedgerSupportsProtocol blk,
InspectLedger blk, HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk
-> BlockCache blk
-> Header blk
-> InvalidBlockPunishment m
-> m (Point blk)
chainSelectionForBlock ChainDbEnv m blk
cdb BlockCache blk
blockCache Header blk
hdr InvalidBlockPunishment m
punish
STM m (Point blk) -> m (Point blk)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (Point blk) -> m (Point blk))
-> STM m (Point blk) -> m (Point blk)
forall a b. (a -> b) -> a -> b
$ ChainDbEnv m blk -> STM m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk)) =>
ChainDbEnv m blk -> STM m (Point blk)
Query.getTipPoint ChainDbEnv m blk
cdb
where
tracer :: Tracer m (TraceAddBlockEvent blk)
tracer = TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent (TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceEvent blk)
cdbTracer
chainSelectionForBlock
:: forall m blk.
( IOLike m
, HasHeader blk
, LedgerSupportsProtocol blk
, InspectLedger blk
, HasHardForkHistory blk
, HasCallStack
)
=> ChainDbEnv m blk
-> BlockCache blk
-> Header blk
-> InvalidBlockPunishment m
-> m (Point blk)
chainSelectionForBlock :: ChainDbEnv m blk
-> BlockCache blk
-> Header blk
-> InvalidBlockPunishment m
-> m (Point blk)
chainSelectionForBlock cdb :: ChainDbEnv m blk
cdb@CDB{Tracer m (LedgerDB' blk)
Tracer m (TraceEvent blk)
DiffTime
StrictTVar m (m ())
StrictTVar m (FutureBlocks m blk)
StrictTVar m (Map FollowerKey (FollowerHandle m blk))
StrictTVar m (Map IteratorKey (m ()))
StrictTVar m (AnchoredFragment (Header blk))
StrictTVar m (StrictMaybe (Header blk))
StrictTVar m (WithFingerprint (InvalidBlocks blk))
StrictTVar m (TentativeState blk)
StrictTVar m FollowerKey
StrictTVar m IteratorKey
TopLevelConfig blk
StrictMVar m ()
VolatileDB m blk
ChunkInfo
ResourceRegistry m
ImmutableDB m blk
CheckInFuture m blk
LgrDB m blk
BlocksToAdd m blk
blk -> Bool
cdbFutureBlocks :: StrictTVar m (FutureBlocks m blk)
cdbBlocksToAdd :: BlocksToAdd m blk
cdbCheckInFuture :: CheckInFuture m blk
cdbCheckIntegrity :: blk -> Bool
cdbChunkInfo :: ChunkInfo
cdbKillBgThreads :: StrictTVar m (m ())
cdbGcInterval :: DiffTime
cdbGcDelay :: DiffTime
cdbRegistry :: ResourceRegistry m
cdbTraceLedger :: Tracer m (LedgerDB' blk)
cdbTracer :: Tracer m (TraceEvent blk)
cdbCopyLock :: StrictMVar m ()
cdbNextFollowerKey :: StrictTVar m FollowerKey
cdbNextIteratorKey :: StrictTVar m IteratorKey
cdbInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: TopLevelConfig blk
cdbFollowers :: StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbIterators :: StrictTVar m (Map IteratorKey (m ()))
cdbTentativeHeader :: StrictTVar m (StrictMaybe (Header blk))
cdbTentativeState :: StrictTVar m (TentativeState blk)
cdbChain :: StrictTVar m (AnchoredFragment (Header blk))
cdbLgrDB :: LgrDB m blk
cdbVolatileDB :: VolatileDB m blk
cdbImmutableDB :: ImmutableDB m blk
cdbFutureBlocks :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (FutureBlocks m blk)
cdbCheckInFuture :: forall (m :: * -> *) blk. ChainDbEnv m blk -> CheckInFuture m blk
cdbCheckIntegrity :: forall (m :: * -> *) blk. ChainDbEnv m blk -> blk -> Bool
cdbChunkInfo :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ChunkInfo
cdbKillBgThreads :: forall (m :: * -> *) blk. ChainDbEnv m blk -> StrictTVar m (m ())
cdbGcInterval :: forall (m :: * -> *) blk. ChainDbEnv m blk -> DiffTime
cdbGcDelay :: forall (m :: * -> *) blk. ChainDbEnv m blk -> DiffTime
cdbRegistry :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ResourceRegistry m
cdbTraceLedger :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> Tracer m (LedgerDB' blk)
cdbCopyLock :: forall (m :: * -> *) blk. ChainDbEnv m blk -> StrictMVar m ()
cdbNextFollowerKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m FollowerKey
cdbNextIteratorKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m IteratorKey
cdbInvalid :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: forall (m :: * -> *) blk. ChainDbEnv m blk -> TopLevelConfig blk
cdbFollowers :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbIterators :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (Map IteratorKey (m ()))
cdbTentativeHeader :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
cdbTentativeState :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (TentativeState blk)
cdbChain :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (AnchoredFragment (Header blk))
cdbLgrDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> LgrDB m blk
cdbVolatileDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> VolatileDB m blk
cdbImmutableDB :: forall (m :: * -> *) blk. ChainDbEnv m blk -> ImmutableDB m blk
cdbBlocksToAdd :: forall (m :: * -> *) blk. ChainDbEnv m blk -> BlocksToAdd m blk
cdbTracer :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> Tracer m (TraceEvent blk)
..} BlockCache blk
blockCache Header blk
hdr InvalidBlockPunishment m
punish = do
(InvalidBlocks blk
invalid, ChainHash blk -> Set (HeaderHash blk)
succsOf, HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo, AnchoredFragment (Header blk)
curChain, Point blk
tipPoint, LedgerDB' blk
ledgerDB)
<- STM
m
(InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk)
-> m (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
m
(InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk)
-> m (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
-> STM
m
(InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk)
-> m (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk)
forall a b. (a -> b) -> a -> b
$ (,,,,,)
(InvalidBlocks blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> AnchoredFragment (Header blk)
-> Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
-> STM m (InvalidBlocks blk)
-> STM
m
((ChainHash blk -> Set (HeaderHash blk))
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> AnchoredFragment (Header blk)
-> Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (WithFingerprint (InvalidBlocks blk) -> InvalidBlocks blk
forall a. WithFingerprint a -> a
forgetFingerprint (WithFingerprint (InvalidBlocks blk) -> InvalidBlocks blk)
-> STM m (WithFingerprint (InvalidBlocks blk))
-> STM m (InvalidBlocks blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> STM m (WithFingerprint (InvalidBlocks blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbInvalid)
STM
m
((ChainHash blk -> Set (HeaderHash blk))
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> AnchoredFragment (Header blk)
-> Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
-> STM m (ChainHash blk -> Set (HeaderHash blk))
-> STM
m
((HeaderHash blk -> Maybe (BlockInfo blk))
-> AnchoredFragment (Header blk)
-> Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VolatileDB m blk
-> HasCallStack => STM m (ChainHash blk -> Set (HeaderHash blk))
forall (m :: * -> *) blk.
VolatileDB m blk
-> HasCallStack => STM m (ChainHash blk -> Set (HeaderHash blk))
VolatileDB.filterByPredecessor VolatileDB m blk
cdbVolatileDB
STM
m
((HeaderHash blk -> Maybe (BlockInfo blk))
-> AnchoredFragment (Header blk)
-> Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
-> STM m (HeaderHash blk -> Maybe (BlockInfo blk))
-> STM
m
(AnchoredFragment (Header blk)
-> Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VolatileDB m blk
-> HasCallStack => STM m (HeaderHash blk -> Maybe (BlockInfo blk))
forall (m :: * -> *) blk.
VolatileDB m blk
-> HasCallStack => STM m (HeaderHash blk -> Maybe (BlockInfo blk))
VolatileDB.getBlockInfo VolatileDB m blk
cdbVolatileDB
STM
m
(AnchoredFragment (Header blk)
-> Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
-> STM m (AnchoredFragment (Header blk))
-> STM
m
(Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ChainDbEnv m blk -> STM m (AnchoredFragment (Header blk))
forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk),
ConsensusProtocol (BlockProtocol blk)) =>
ChainDbEnv m blk -> STM m (AnchoredFragment (Header blk))
Query.getCurrentChain ChainDbEnv m blk
cdb
STM
m
(Point blk
-> LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
-> STM m (Point blk)
-> STM
m
(LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ChainDbEnv m blk -> STM m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk)) =>
ChainDbEnv m blk -> STM m (Point blk)
Query.getTipPoint ChainDbEnv m blk
cdb
STM
m
(LedgerDB' blk
-> (InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk))
-> STM m (LedgerDB' blk)
-> STM
m
(InvalidBlocks blk, ChainHash blk -> Set (HeaderHash blk),
HeaderHash blk -> Maybe (BlockInfo blk),
AnchoredFragment (Header blk), Point blk, LedgerDB' blk)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> LgrDB m blk -> STM m (LedgerDB' blk)
forall (m :: * -> *) blk.
IOLike m =>
LgrDB m blk -> STM m (LedgerDB' blk)
LgrDB.getCurrent LgrDB m blk
cdbLgrDB
let curChainAndLedger :: ChainAndLedger blk
curChainAndLedger :: ChainAndLedger blk
curChainAndLedger =
Bool -> ChainAndLedger blk -> ChainAndLedger blk
forall a. HasCallStack => Bool -> a -> a
assert (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (AnchoredFragment (Header blk) -> Int
forall v a b. Anchorable v a b => AnchoredSeq v a b -> Int
AF.length AnchoredFragment (Header blk)
curChain) Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
k) (ChainAndLedger blk -> ChainAndLedger blk)
-> ChainAndLedger blk -> ChainAndLedger blk
forall a b. (a -> b) -> a -> b
$
AnchoredFragment (Header blk)
-> LedgerDB' blk -> ChainAndLedger blk
forall l b.
(IsLedger l, HasHeader b, HeaderHash b ~ HeaderHash l,
HasCallStack) =>
AnchoredFragment b -> l -> ValidatedFragment b l
VF.ValidatedFragment AnchoredFragment (Header blk)
curChain LedgerDB' blk
ledgerDB
immBlockNo :: WithOrigin BlockNo
immBlockNo :: WithOrigin BlockNo
immBlockNo = AnchoredFragment (Header blk) -> WithOrigin BlockNo
forall block. AnchoredFragment block -> WithOrigin BlockNo
AF.anchorBlockNo AnchoredFragment (Header blk)
curChain
lookupBlockInfo' :: HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo' = ChainDbEnv m blk
-> InvalidBlocks blk
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> HeaderHash blk
-> Maybe (BlockInfo blk)
forall blk (proxy :: * -> *) a.
HasHeader blk =>
proxy blk
-> InvalidBlocks blk
-> (HeaderHash blk -> Maybe a)
-> HeaderHash blk
-> Maybe a
ignoreInvalid ChainDbEnv m blk
cdb InvalidBlocks blk
invalid HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo
succsOf' :: ChainHash blk -> Set (HeaderHash blk)
succsOf' = ChainDbEnv m blk
-> InvalidBlocks blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> ChainHash blk
-> Set (HeaderHash blk)
forall blk (proxy :: * -> *).
HasHeader blk =>
proxy blk
-> InvalidBlocks blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> ChainHash blk
-> Set (HeaderHash blk)
ignoreInvalidSuc ChainDbEnv m blk
cdb InvalidBlocks blk
invalid ChainHash blk -> Set (HeaderHash blk)
succsOf
Bool -> m () -> m ()
forall a. HasCallStack => Bool -> a -> a
assert (Maybe (BlockInfo blk) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (BlockInfo blk) -> Bool) -> Maybe (BlockInfo blk) -> Bool
forall a b. (a -> b) -> a -> b
$ HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr)) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
if
| Header blk -> IsEBB -> WithOrigin BlockNo -> Bool
forall blk.
HasHeader (Header blk) =>
Header blk -> IsEBB -> WithOrigin BlockNo -> Bool
olderThanK Header blk
hdr IsEBB
isEBB WithOrigin BlockNo
immBlockNo -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ RealPoint blk -> TraceAddBlockEvent blk
forall blk. RealPoint blk -> TraceAddBlockEvent blk
IgnoreBlockOlderThanK RealPoint blk
p
Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Point blk
tipPoint
| Just (InvalidBlockInfo InvalidBlockReason blk
reason SlotNo
_) <- HeaderHash blk -> InvalidBlocks blk -> Maybe (InvalidBlockInfo blk)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr) InvalidBlocks blk
invalid -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ RealPoint blk -> InvalidBlockReason blk -> TraceAddBlockEvent blk
forall blk.
RealPoint blk -> InvalidBlockReason blk -> TraceAddBlockEvent blk
IgnoreInvalidBlock RealPoint blk
p InvalidBlockReason blk
reason
InvalidBlockPunishment m -> Invalidity -> m ()
forall (m :: * -> *).
InvalidBlockPunishment m -> Invalidity -> m ()
InvalidBlockPunishment.enact
InvalidBlockPunishment m
punish
Invalidity
InvalidBlockPunishment.BlockItself
Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Point blk
tipPoint
| Point blk -> ChainHash blk
forall block. Point block -> ChainHash block
pointHash Point blk
tipPoint ChainHash blk -> ChainHash blk -> Bool
forall a. Eq a => a -> a -> Bool
== Header blk -> ChainHash blk
forall blk. GetPrevHash blk => Header blk -> ChainHash blk
headerPrevHash Header blk
hdr -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (RealPoint blk -> TraceAddBlockEvent blk
forall blk. RealPoint blk -> TraceAddBlockEvent blk
TryAddToCurrentChain RealPoint blk
p)
HasCallStack =>
(ChainHash blk -> Set (HeaderHash blk))
-> ChainAndLedger blk -> m (Point blk)
(ChainHash blk -> Set (HeaderHash blk))
-> ChainAndLedger blk -> m (Point blk)
addToCurrentChain ChainHash blk -> Set (HeaderHash blk)
succsOf' ChainAndLedger blk
curChainAndLedger
| Just ChainDiff (HeaderFields blk)
diff <- (HeaderHash blk -> Maybe (BlockInfo blk))
-> AnchoredFragment (Header blk)
-> RealPoint blk
-> Maybe (ChainDiff (HeaderFields blk))
forall blk.
(HasHeader blk, GetHeader blk) =>
LookupBlockInfo blk
-> AnchoredFragment (Header blk)
-> RealPoint blk
-> Maybe (ChainDiff (HeaderFields blk))
Paths.isReachable HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo' AnchoredFragment (Header blk)
curChain RealPoint blk
p -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (RealPoint blk
-> ChainDiff (HeaderFields blk) -> TraceAddBlockEvent blk
forall blk.
RealPoint blk
-> ChainDiff (HeaderFields blk) -> TraceAddBlockEvent blk
TrySwitchToAFork RealPoint blk
p ChainDiff (HeaderFields blk)
diff)
HasCallStack =>
(ChainHash blk -> Set (HeaderHash blk))
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> ChainAndLedger blk
-> ChainDiff (HeaderFields blk)
-> m (Point blk)
(ChainHash blk -> Set (HeaderHash blk))
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> ChainAndLedger blk
-> ChainDiff (HeaderFields blk)
-> m (Point blk)
switchToAFork ChainHash blk -> Set (HeaderHash blk)
succsOf' HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo' ChainAndLedger blk
curChainAndLedger ChainDiff (HeaderFields blk)
diff
| Bool
otherwise -> do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (RealPoint blk -> TraceAddBlockEvent blk
forall blk. RealPoint blk -> TraceAddBlockEvent blk
StoreButDontChange RealPoint blk
p)
Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Point blk
tipPoint
where
SecurityParam Word64
k = TopLevelConfig blk -> SecurityParam
forall blk.
ConsensusProtocol (BlockProtocol blk) =>
TopLevelConfig blk -> SecurityParam
configSecurityParam TopLevelConfig blk
cdbTopLevelConfig
p :: RealPoint blk
p :: RealPoint blk
p = Header blk -> RealPoint blk
forall blk. HasHeader (Header blk) => Header blk -> RealPoint blk
headerRealPoint Header blk
hdr
isEBB :: IsEBB
isEBB :: IsEBB
isEBB = Header blk -> IsEBB
forall blk. GetHeader blk => Header blk -> IsEBB
headerToIsEBB Header blk
hdr
addBlockTracer :: Tracer m (TraceAddBlockEvent blk)
addBlockTracer :: Tracer m (TraceAddBlockEvent blk)
addBlockTracer = TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent (TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceEvent blk)
cdbTracer
mkChainSelEnv :: ChainAndLedger blk -> ChainSelEnv m blk
mkChainSelEnv :: ChainAndLedger blk -> ChainSelEnv m blk
mkChainSelEnv ChainAndLedger blk
curChainAndLedger = ChainSelEnv :: forall (m :: * -> *) blk.
LgrDB m blk
-> Tracer m (TraceValidationEvent blk)
-> Tracer m (TracePipeliningEvent blk)
-> BlockConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks m blk)
-> StrictTVar m (TentativeState blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> STM m [FollowerHandle m blk]
-> CheckInFuture m blk
-> BlockCache blk
-> ChainAndLedger blk
-> Maybe (RealPoint blk, InvalidBlockPunishment m)
-> ChainSelEnv m blk
ChainSelEnv
{ lgrDB :: LgrDB m blk
lgrDB = LgrDB m blk
cdbLgrDB
, bcfg :: BlockConfig blk
bcfg = TopLevelConfig blk -> BlockConfig blk
forall blk. TopLevelConfig blk -> BlockConfig blk
configBlock TopLevelConfig blk
cdbTopLevelConfig
, varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid = StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbInvalid
, varFutureBlocks :: StrictTVar m (FutureBlocks m blk)
varFutureBlocks = StrictTVar m (FutureBlocks m blk)
cdbFutureBlocks
, varTentativeState :: StrictTVar m (TentativeState blk)
varTentativeState = StrictTVar m (TentativeState blk)
cdbTentativeState
, varTentativeHeader :: StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader = StrictTVar m (StrictMaybe (Header blk))
cdbTentativeHeader
, getTentativeFollowers :: STM m [FollowerHandle m blk]
getTentativeFollowers =
(FollowerHandle m blk -> Bool)
-> [FollowerHandle m blk] -> [FollowerHandle m blk]
forall a. (a -> Bool) -> [a] -> [a]
filter ((ChainType
TentativeChain ChainType -> ChainType -> Bool
forall a. Eq a => a -> a -> Bool
==) (ChainType -> Bool)
-> (FollowerHandle m blk -> ChainType)
-> FollowerHandle m blk
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FollowerHandle m blk -> ChainType
forall (m :: * -> *) blk. FollowerHandle m blk -> ChainType
fhChainType) ([FollowerHandle m blk] -> [FollowerHandle m blk])
-> (Map FollowerKey (FollowerHandle m blk)
-> [FollowerHandle m blk])
-> Map FollowerKey (FollowerHandle m blk)
-> [FollowerHandle m blk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map FollowerKey (FollowerHandle m blk) -> [FollowerHandle m blk]
forall k a. Map k a -> [a]
Map.elems
(Map FollowerKey (FollowerHandle m blk) -> [FollowerHandle m blk])
-> STM m (Map FollowerKey (FollowerHandle m blk))
-> STM m [FollowerHandle m blk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (Map FollowerKey (FollowerHandle m blk))
-> STM m (Map FollowerKey (FollowerHandle m blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbFollowers
, futureCheck :: CheckInFuture m blk
futureCheck = CheckInFuture m blk
cdbCheckInFuture
, blockCache :: BlockCache blk
blockCache = BlockCache blk
blockCache
, curChainAndLedger :: ChainAndLedger blk
curChainAndLedger = ChainAndLedger blk
curChainAndLedger
, validationTracer :: Tracer m (TraceValidationEvent blk)
validationTracer =
TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent (TraceAddBlockEvent blk -> TraceEvent blk)
-> (TraceValidationEvent blk -> TraceAddBlockEvent blk)
-> TraceValidationEvent blk
-> TraceEvent blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TraceValidationEvent blk -> TraceAddBlockEvent blk
forall blk. TraceValidationEvent blk -> TraceAddBlockEvent blk
AddBlockValidation (TraceValidationEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceValidationEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceEvent blk)
cdbTracer
, pipeliningTracer :: Tracer m (TracePipeliningEvent blk)
pipeliningTracer =
TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent (TraceAddBlockEvent blk -> TraceEvent blk)
-> (TracePipeliningEvent blk -> TraceAddBlockEvent blk)
-> TracePipeliningEvent blk
-> TraceEvent blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TracePipeliningEvent blk -> TraceAddBlockEvent blk
forall blk. TracePipeliningEvent blk -> TraceAddBlockEvent blk
PipeliningEvent (TracePipeliningEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TracePipeliningEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceEvent blk)
cdbTracer
, punish :: Maybe (RealPoint blk, InvalidBlockPunishment m)
punish = (RealPoint blk, InvalidBlockPunishment m)
-> Maybe (RealPoint blk, InvalidBlockPunishment m)
forall a. a -> Maybe a
Just (RealPoint blk
p, InvalidBlockPunishment m
punish)
}
addToCurrentChain ::
HasCallStack
=> (ChainHash blk -> Set (HeaderHash blk))
-> ChainAndLedger blk
-> m (Point blk)
addToCurrentChain :: (ChainHash blk -> Set (HeaderHash blk))
-> ChainAndLedger blk -> m (Point blk)
addToCurrentChain ChainHash blk -> Set (HeaderHash blk)
succsOf ChainAndLedger blk
curChainAndLedger = do
let suffixesAfterB :: [NonEmpty (HeaderHash blk)]
suffixesAfterB = (ChainHash blk -> Set (HeaderHash blk))
-> Point blk -> [NonEmpty (HeaderHash blk)]
forall blk.
(ChainHash blk -> Set (HeaderHash blk))
-> Point blk -> [NonEmpty (HeaderHash blk)]
Paths.maximalCandidates ChainHash blk -> Set (HeaderHash blk)
succsOf (RealPoint blk -> Point blk
forall blk. RealPoint blk -> Point blk
realPointToPoint RealPoint blk
p)
NonEmpty (AnchoredFragment (Header blk))
candidates <- case [NonEmpty (HeaderHash blk)]
-> Maybe (NonEmpty (NonEmpty (HeaderHash blk)))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [NonEmpty (HeaderHash blk)]
suffixesAfterB of
Maybe (NonEmpty (NonEmpty (HeaderHash blk)))
Nothing ->
NonEmpty (AnchoredFragment (Header blk))
-> m (NonEmpty (AnchoredFragment (Header blk)))
forall (m :: * -> *) a. Monad m => a -> m a
return (NonEmpty (AnchoredFragment (Header blk))
-> m (NonEmpty (AnchoredFragment (Header blk))))
-> NonEmpty (AnchoredFragment (Header blk))
-> m (NonEmpty (AnchoredFragment (Header blk)))
forall a b. (a -> b) -> a -> b
$ (Anchor (Header blk)
-> [Header blk] -> AnchoredFragment (Header blk)
forall v a b. Anchorable v a b => a -> [b] -> AnchoredSeq v a b
AF.fromOldestFirst Anchor (Header blk)
curHead [Header blk
hdr]) AnchoredFragment (Header blk)
-> [AnchoredFragment (Header blk)]
-> NonEmpty (AnchoredFragment (Header blk))
forall a. a -> [a] -> NonEmpty a
NE.:| []
Just NonEmpty (NonEmpty (HeaderHash blk))
suffixesAfterB' ->
(StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk)))
-> Map (HeaderHash blk) (Header blk)
-> m (NonEmpty (AnchoredFragment (Header blk))))
-> Map (HeaderHash blk) (Header blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk)))
-> m (NonEmpty (AnchoredFragment (Header blk)))
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk)))
-> Map (HeaderHash blk) (Header blk)
-> m (NonEmpty (AnchoredFragment (Header blk)))
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT Map (HeaderHash blk) (Header blk)
forall k a. Map k a
Map.empty (StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk)))
-> m (NonEmpty (AnchoredFragment (Header blk))))
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk)))
-> m (NonEmpty (AnchoredFragment (Header blk)))
forall a b. (a -> b) -> a -> b
$ NonEmpty (NonEmpty (HeaderHash blk))
-> (NonEmpty (HeaderHash blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk)))
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk)))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM NonEmpty (NonEmpty (HeaderHash blk))
suffixesAfterB' ((NonEmpty (HeaderHash blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk)))
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk))))
-> (NonEmpty (HeaderHash blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk)))
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(NonEmpty (AnchoredFragment (Header blk)))
forall a b. (a -> b) -> a -> b
$ \NonEmpty (HeaderHash blk)
hashes -> do
[Header blk]
hdrs <- (HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk))
-> [HeaderHash blk]
-> StateT (Map (HeaderHash blk) (Header blk)) m [Header blk]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (VolatileDB m blk
-> HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall (m :: * -> *) blk.
(MonadThrow m, HasHeader blk) =>
VolatileDB m blk
-> HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
getKnownHeaderThroughCache VolatileDB m blk
cdbVolatileDB) ([HeaderHash blk]
-> StateT (Map (HeaderHash blk) (Header blk)) m [Header blk])
-> [HeaderHash blk]
-> StateT (Map (HeaderHash blk) (Header blk)) m [Header blk]
forall a b. (a -> b) -> a -> b
$
NonEmpty (HeaderHash blk) -> [HeaderHash blk]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty (HeaderHash blk)
hashes
AnchoredFragment (Header blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (AnchoredFragment (Header blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk)))
-> AnchoredFragment (Header blk)
-> StateT
(Map (HeaderHash blk) (Header blk))
m
(AnchoredFragment (Header blk))
forall a b. (a -> b) -> a -> b
$ Anchor (Header blk)
-> [Header blk] -> AnchoredFragment (Header blk)
forall v a b. Anchorable v a b => a -> [b] -> AnchoredSeq v a b
AF.fromOldestFirst Anchor (Header blk)
curHead (Header blk
hdr Header blk -> [Header blk] -> [Header blk]
forall a. a -> [a] -> [a]
: [Header blk]
hdrs)
let chainDiffs :: Maybe (NonEmpty (ChainDiff (Header blk)))
chainDiffs = [ChainDiff (Header blk)]
-> Maybe (NonEmpty (ChainDiff (Header blk)))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty
([ChainDiff (Header blk)]
-> Maybe (NonEmpty (ChainDiff (Header blk))))
-> [ChainDiff (Header blk)]
-> Maybe (NonEmpty (ChainDiff (Header blk)))
forall a b. (a -> b) -> a -> b
$ (ChainDiff (Header blk) -> Bool)
-> NonEmpty (ChainDiff (Header blk)) -> [ChainDiff (Header blk)]
forall a. (a -> Bool) -> NonEmpty a -> [a]
NE.filter ( BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate (ChainSelEnv m blk -> BlockConfig blk
forall (m :: * -> *) blk. ChainSelEnv m blk -> BlockConfig blk
bcfg ChainSelEnv m blk
chainSelEnv) AnchoredFragment (Header blk)
curChain
(AnchoredFragment (Header blk) -> Bool)
-> (ChainDiff (Header blk) -> AnchoredFragment (Header blk))
-> ChainDiff (Header blk)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix
)
(NonEmpty (ChainDiff (Header blk)) -> [ChainDiff (Header blk)])
-> NonEmpty (ChainDiff (Header blk)) -> [ChainDiff (Header blk)]
forall a b. (a -> b) -> a -> b
$ (AnchoredFragment (Header blk) -> ChainDiff (Header blk))
-> NonEmpty (AnchoredFragment (Header blk))
-> NonEmpty (ChainDiff (Header blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AnchoredFragment (Header blk) -> ChainDiff (Header blk)
forall b. AnchoredFragment b -> ChainDiff b
Diff.extend NonEmpty (AnchoredFragment (Header blk))
candidates
case Maybe (NonEmpty (ChainDiff (Header blk)))
chainDiffs of
Maybe (NonEmpty (ChainDiff (Header blk)))
Nothing -> Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Point blk
curTip
Just NonEmpty (ChainDiff (Header blk))
chainDiffs' ->
ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, HasCallStack) =>
ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection ChainSelEnv m blk
chainSelEnv NonEmpty (ChainDiff (Header blk))
chainDiffs' m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Point blk))
-> m (Point blk)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
Nothing ->
Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Point blk
curTip
Just ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff ->
HasCallStack =>
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> ChainSwitchType
-> m (Point blk)
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> ChainSwitchType
-> m (Point blk)
switchTo
ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff
(ChainSelEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader ChainSelEnv m blk
chainSelEnv)
ChainSwitchType
AddingBlocks
where
chainSelEnv :: ChainSelEnv m blk
chainSelEnv = ChainAndLedger blk -> ChainSelEnv m blk
mkChainSelEnv ChainAndLedger blk
curChainAndLedger
curChain :: AnchoredFragment (Header blk)
curChain = ChainAndLedger blk -> AnchoredFragment (Header blk)
forall b l. ValidatedFragment b l -> AnchoredFragment b
VF.validatedFragment ChainAndLedger blk
curChainAndLedger
curTip :: Point blk
curTip = Point (Header blk) -> Point blk
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
curChain
curHead :: Anchor (Header blk)
curHead = AnchoredFragment (Header blk) -> Anchor (Header blk)
forall v a b. Anchorable v a b => AnchoredSeq v a b -> a
AF.headAnchor AnchoredFragment (Header blk)
curChain
switchToAFork ::
HasCallStack
=> (ChainHash blk -> Set (HeaderHash blk))
-> LookupBlockInfo blk
-> ChainAndLedger blk
-> ChainDiff (HeaderFields blk)
-> m (Point blk)
switchToAFork :: (ChainHash blk -> Set (HeaderHash blk))
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> ChainAndLedger blk
-> ChainDiff (HeaderFields blk)
-> m (Point blk)
switchToAFork ChainHash blk -> Set (HeaderHash blk)
succsOf HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo ChainAndLedger blk
curChainAndLedger ChainDiff (HeaderFields blk)
diff = do
let initCache :: Map (HeaderHash blk) (Header blk)
initCache = HeaderHash blk -> Header blk -> Map (HeaderHash blk) (Header blk)
forall k a. k -> a -> Map k a
Map.singleton (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr) Header blk
hdr
[ChainDiff (Header blk)]
chainDiffs <-
([ChainDiff (Header blk)] -> [ChainDiff (Header blk)])
-> m [ChainDiff (Header blk)] -> m [ChainDiff (Header blk)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( (ChainDiff (Header blk) -> Bool)
-> [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
forall a. (a -> Bool) -> [a] -> [a]
filter
( BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate (ChainSelEnv m blk -> BlockConfig blk
forall (m :: * -> *) blk. ChainSelEnv m blk -> BlockConfig blk
bcfg ChainSelEnv m blk
chainSelEnv) AnchoredFragment (Header blk)
curChain
(AnchoredFragment (Header blk) -> Bool)
-> (ChainDiff (Header blk) -> AnchoredFragment (Header blk))
-> ChainDiff (Header blk)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix
)
)
(m [ChainDiff (Header blk)] -> m [ChainDiff (Header blk)])
-> (ChainDiff (HeaderFields blk) -> m [ChainDiff (Header blk)])
-> ChainDiff (HeaderFields blk)
-> m [ChainDiff (Header blk)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)]
-> Map (HeaderHash blk) (Header blk) -> m [ChainDiff (Header blk)])
-> Map (HeaderHash blk) (Header blk)
-> StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)]
-> m [ChainDiff (Header blk)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)]
-> Map (HeaderHash blk) (Header blk) -> m [ChainDiff (Header blk)]
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT Map (HeaderHash blk) (Header blk)
initCache
(StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)]
-> m [ChainDiff (Header blk)])
-> (ChainDiff (HeaderFields blk)
-> StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)])
-> ChainDiff (HeaderFields blk)
-> m [ChainDiff (Header blk)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChainDiff (HeaderFields blk)
-> StateT
(Map (HeaderHash blk) (Header blk)) m (ChainDiff (Header blk)))
-> [ChainDiff (HeaderFields blk)]
-> StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ChainDiff (HeaderFields blk)
-> StateT
(Map (HeaderHash blk) (Header blk)) m (ChainDiff (Header blk))
translateToHeaders
([ChainDiff (HeaderFields blk)]
-> StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)])
-> (ChainDiff (HeaderFields blk) -> [ChainDiff (HeaderFields blk)])
-> ChainDiff (HeaderFields blk)
-> StateT
(Map (HeaderHash blk) (Header blk)) m [ChainDiff (Header blk)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChainDiff (HeaderFields blk) -> Bool)
-> NonEmpty (ChainDiff (HeaderFields blk))
-> [ChainDiff (HeaderFields blk)]
forall a. (a -> Bool) -> NonEmpty a -> [a]
NE.filter (Bool -> Bool
not (Bool -> Bool)
-> (ChainDiff (HeaderFields blk) -> Bool)
-> ChainDiff (HeaderFields blk)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainDiff (HeaderFields blk) -> Bool
forall b. HasHeader b => ChainDiff b -> Bool
Diff.rollbackExceedsSuffix)
(NonEmpty (ChainDiff (HeaderFields blk))
-> [ChainDiff (HeaderFields blk)])
-> (ChainDiff (HeaderFields blk)
-> NonEmpty (ChainDiff (HeaderFields blk)))
-> ChainDiff (HeaderFields blk)
-> [ChainDiff (HeaderFields blk)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChainHash blk -> Set (HeaderHash blk))
-> (HeaderHash blk -> Maybe (BlockInfo blk))
-> ChainDiff (HeaderFields blk)
-> NonEmpty (ChainDiff (HeaderFields blk))
forall blk.
HasHeader blk =>
(ChainHash blk -> Set (HeaderHash blk))
-> LookupBlockInfo blk
-> ChainDiff (HeaderFields blk)
-> NonEmpty (ChainDiff (HeaderFields blk))
Paths.extendWithSuccessors ChainHash blk -> Set (HeaderHash blk)
succsOf HeaderHash blk -> Maybe (BlockInfo blk)
lookupBlockInfo
(ChainDiff (HeaderFields blk) -> m [ChainDiff (Header blk)])
-> ChainDiff (HeaderFields blk) -> m [ChainDiff (Header blk)]
forall a b. (a -> b) -> a -> b
$ ChainDiff (HeaderFields blk)
diff
case [ChainDiff (Header blk)]
-> Maybe (NonEmpty (ChainDiff (Header blk)))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [ChainDiff (Header blk)]
chainDiffs of
Maybe (NonEmpty (ChainDiff (Header blk)))
Nothing -> Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Point blk
curTip
Just NonEmpty (ChainDiff (Header blk))
chainDiffs' ->
ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, HasCallStack) =>
ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection ChainSelEnv m blk
chainSelEnv NonEmpty (ChainDiff (Header blk))
chainDiffs' m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Point blk))
-> m (Point blk)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
Nothing ->
Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Point blk
curTip
Just ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff ->
HasCallStack =>
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> ChainSwitchType
-> m (Point blk)
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> ChainSwitchType
-> m (Point blk)
switchTo
ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff
(ChainSelEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader ChainSelEnv m blk
chainSelEnv)
ChainSwitchType
SwitchingToAFork
where
chainSelEnv :: ChainSelEnv m blk
chainSelEnv = ChainAndLedger blk -> ChainSelEnv m blk
mkChainSelEnv ChainAndLedger blk
curChainAndLedger
curChain :: AnchoredFragment (Header blk)
curChain = ChainAndLedger blk -> AnchoredFragment (Header blk)
forall b l. ValidatedFragment b l -> AnchoredFragment b
VF.validatedFragment ChainAndLedger blk
curChainAndLedger
curTip :: Point blk
curTip = Point (Header blk) -> Point blk
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
curChain
mkNewTipInfo :: LedgerDB' blk -> NewTipInfo blk
mkNewTipInfo :: LedgerDB' blk -> NewTipInfo blk
mkNewTipInfo LedgerDB' blk
newLedgerDB =
NewTipInfo :: forall blk.
RealPoint blk
-> EpochNo -> Word64 -> RealPoint blk -> NewTipInfo blk
NewTipInfo {
newTipPoint :: RealPoint blk
newTipPoint = RealPoint blk
tipPoint
, newTipEpoch :: EpochNo
newTipEpoch = EpochNo
tipEpoch
, newTipSlotInEpoch :: Word64
newTipSlotInEpoch = Word64
tipSlotInEpoch
, newTipTrigger :: RealPoint blk
newTipTrigger = RealPoint blk
p
}
where
cfg :: TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg = TopLevelConfig blk
cdbTopLevelConfig
ledger :: LedgerState blk
ledger :: LedgerState blk
ledger = ExtLedgerState blk -> LedgerState blk
forall blk. ExtLedgerState blk -> LedgerState blk
ledgerState (LedgerDB' blk -> ExtLedgerState blk
forall l. GetTip l => LedgerDB l -> l
LgrDB.ledgerDbCurrent LedgerDB' blk
newLedgerDB)
summary :: History.Summary (HardForkIndices blk)
summary :: Summary (HardForkIndices blk)
summary = LedgerConfig blk
-> LedgerState blk -> Summary (HardForkIndices blk)
forall blk.
HasHardForkHistory blk =>
LedgerConfig blk
-> LedgerState blk -> Summary (HardForkIndices blk)
hardForkSummary
(TopLevelConfig blk -> LedgerConfig blk
forall blk. TopLevelConfig blk -> LedgerConfig blk
configLedger TopLevelConfig blk
cfg)
LedgerState blk
ledger
(RealPoint blk
tipPoint, (EpochNo
tipEpoch, Word64
tipSlotInEpoch)) =
case Point blk -> WithOrigin (RealPoint blk)
forall blk. Point blk -> WithOrigin (RealPoint blk)
pointToWithOriginRealPoint
(Proxy blk -> LedgerState blk -> Point blk
forall blk.
UpdateLedger blk =>
Proxy blk -> LedgerState blk -> Point blk
ledgerTipPoint (Proxy blk
forall k (t :: k). Proxy t
Proxy @blk) LedgerState blk
ledger) of
WithOrigin (RealPoint blk)
Origin -> [Char] -> (RealPoint blk, (EpochNo, Word64))
forall a. HasCallStack => [Char] -> a
error [Char]
"cannot have switched to an empty chain"
NotOrigin RealPoint blk
tip ->
let query :: Qry (EpochNo, Word64)
query = SlotNo -> Qry (EpochNo, Word64)
History.slotToEpoch' (RealPoint blk -> SlotNo
forall blk. RealPoint blk -> SlotNo
realPointSlot RealPoint blk
tip)
in (RealPoint blk
tip, Qry (EpochNo, Word64)
-> Summary (HardForkIndices blk) -> (EpochNo, Word64)
forall a (xs :: [*]). HasCallStack => Qry a -> Summary xs -> a
History.runQueryPure Qry (EpochNo, Word64)
query Summary (HardForkIndices blk)
summary)
switchTo
:: HasCallStack
=> ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> ChainSwitchType
-> m (Point blk)
switchTo :: ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> StrictTVar m (StrictMaybe (Header blk))
-> ChainSwitchType
-> m (Point blk)
switchTo ValidatedChainDiff (Header blk) (LedgerDB' blk)
vChainDiff StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader ChainSwitchType
chainSwitchType = do
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$
Point blk -> TraceAddBlockEvent blk
forall blk. Point blk -> TraceAddBlockEvent blk
ChangingSelection
(Point blk -> TraceAddBlockEvent blk)
-> Point blk -> TraceAddBlockEvent blk
forall a b. (a -> b) -> a -> b
$ Point (Header blk) -> Point blk
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint
(Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint
(AnchoredFragment (Header blk) -> Point (Header blk))
-> AnchoredFragment (Header blk) -> Point (Header blk)
forall a b. (a -> b) -> a -> b
$ ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
getSuffix
(ChainDiff (Header blk) -> AnchoredFragment (Header blk))
-> ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall a b. (a -> b) -> a -> b
$ ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ChainDiff (Header blk)
forall b l. ValidatedChainDiff b l -> ChainDiff b
getChainDiff ValidatedChainDiff (Header blk) (LedgerDB' blk)
vChainDiff
(AnchoredFragment (Header blk)
curChain, AnchoredFragment (Header blk)
newChain, [LedgerEvent blk]
events, StrictMaybe (Header blk)
prevTentativeHeader) <- STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
-> m (AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
-> m (AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk)))
-> STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
-> m (AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
forall a b. (a -> b) -> a -> b
$ do
AnchoredFragment (Header blk)
curChain <- StrictTVar m (AnchoredFragment (Header blk))
-> STM m (AnchoredFragment (Header blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (AnchoredFragment (Header blk))
cdbChain
LedgerDB' blk
curLedger <- LgrDB m blk -> STM m (LedgerDB' blk)
forall (m :: * -> *) blk.
IOLike m =>
LgrDB m blk -> STM m (LedgerDB' blk)
LgrDB.getCurrent LgrDB m blk
cdbLgrDB
case AnchoredFragment (Header blk)
-> ChainDiff (Header blk) -> Maybe (AnchoredFragment (Header blk))
forall b.
HasHeader b =>
AnchoredFragment b -> ChainDiff b -> Maybe (AnchoredFragment b)
Diff.apply AnchoredFragment (Header blk)
curChain ChainDiff (Header blk)
chainDiff of
Maybe (AnchoredFragment (Header blk))
Nothing ->
[Char]
-> STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
forall a. HasCallStack => [Char] -> a
error [Char]
"chainDiff doesn't fit onto current chain"
Just AnchoredFragment (Header blk)
newChain -> do
StrictTVar m (AnchoredFragment (Header blk))
-> AnchoredFragment (Header blk) -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (AnchoredFragment (Header blk))
cdbChain AnchoredFragment (Header blk)
newChain
LgrDB m blk -> LedgerDB' blk -> STM m ()
forall (m :: * -> *) blk.
IOLike m =>
LgrDB m blk -> LedgerDB' blk -> STM m ()
LgrDB.setCurrent LgrDB m blk
cdbLgrDB LedgerDB' blk
newLedger
let events :: [LedgerEvent blk]
events :: [LedgerEvent blk]
events = TopLevelConfig blk
-> LedgerState blk -> LedgerState blk -> [LedgerEvent blk]
forall blk.
InspectLedger blk =>
TopLevelConfig blk
-> LedgerState blk -> LedgerState blk -> [LedgerEvent blk]
inspectLedger
TopLevelConfig blk
cdbTopLevelConfig
(ExtLedgerState blk -> LedgerState blk
forall blk. ExtLedgerState blk -> LedgerState blk
ledgerState (ExtLedgerState blk -> LedgerState blk)
-> ExtLedgerState blk -> LedgerState blk
forall a b. (a -> b) -> a -> b
$ LedgerDB' blk -> ExtLedgerState blk
forall l. GetTip l => LedgerDB l -> l
LgrDB.ledgerDbCurrent LedgerDB' blk
curLedger)
(ExtLedgerState blk -> LedgerState blk
forall blk. ExtLedgerState blk -> LedgerState blk
ledgerState (ExtLedgerState blk -> LedgerState blk)
-> ExtLedgerState blk -> LedgerState blk
forall a b. (a -> b) -> a -> b
$ LedgerDB' blk -> ExtLedgerState blk
forall l. GetTip l => LedgerDB l -> l
LgrDB.ledgerDbCurrent LedgerDB' blk
newLedger)
StrictMaybe (Header blk)
prevTentativeHeader <- StrictTVar m (StrictMaybe (Header blk))
-> StrictMaybe (Header blk) -> STM m (StrictMaybe (Header blk))
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> a -> STM m a
swapTVar StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader StrictMaybe (Header blk)
forall a. StrictMaybe a
SNothing
case ChainSwitchType
chainSwitchType of
ChainSwitchType
AddingBlocks -> () -> STM m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
ChainSwitchType
SwitchingToAFork -> do
let ipoint :: Point blk
ipoint = Point (Header blk) -> Point blk
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ ChainDiff (Header blk) -> Point (Header blk)
forall b. ChainDiff b -> Point b
Diff.getAnchorPoint ChainDiff (Header blk)
chainDiff
[FollowerHandle m blk]
followerHandles <- Map FollowerKey (FollowerHandle m blk) -> [FollowerHandle m blk]
forall k a. Map k a -> [a]
Map.elems (Map FollowerKey (FollowerHandle m blk) -> [FollowerHandle m blk])
-> STM m (Map FollowerKey (FollowerHandle m blk))
-> STM m [FollowerHandle m blk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (Map FollowerKey (FollowerHandle m blk))
-> STM m (Map FollowerKey (FollowerHandle m blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (Map FollowerKey (FollowerHandle m blk))
cdbFollowers
[FollowerHandle m blk]
-> (FollowerHandle m blk -> STM m ()) -> STM m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [FollowerHandle m blk]
followerHandles ((FollowerHandle m blk -> STM m ()) -> STM m ())
-> (FollowerHandle m blk -> STM m ()) -> STM m ()
forall a b. (a -> b) -> a -> b
$ \FollowerHandle m blk
followerHandle ->
FollowerHandle m blk
-> Point blk -> AnchoredFragment (Header blk) -> STM m ()
forall (m :: * -> *) blk.
FollowerHandle m blk
-> Point blk -> AnchoredFragment (Header blk) -> STM m ()
fhSwitchFork FollowerHandle m blk
followerHandle Point blk
ipoint AnchoredFragment (Header blk)
newChain
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
-> STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk], StrictMaybe (Header blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (AnchoredFragment (Header blk)
curChain, AnchoredFragment (Header blk)
newChain, [LedgerEvent blk]
events, StrictMaybe (Header blk)
prevTentativeHeader)
let mkTraceEvent :: [LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
mkTraceEvent = case ChainSwitchType
chainSwitchType of
ChainSwitchType
AddingBlocks -> [LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
forall blk.
[LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
AddedToCurrentChain
ChainSwitchType
SwitchingToAFork -> [LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
forall blk.
[LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
SwitchedToAFork
Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceAddBlockEvent blk)
addBlockTracer (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$
[LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
mkTraceEvent [LedgerEvent blk]
events (LedgerDB' blk -> NewTipInfo blk
mkNewTipInfo LedgerDB' blk
newLedger) AnchoredFragment (Header blk)
curChain AnchoredFragment (Header blk)
newChain
Maybe (Header blk) -> (Header blk -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust (StrictMaybe (Header blk) -> Maybe (Header blk)
forall a. StrictMaybe a -> Maybe a
strictMaybeToMaybe StrictMaybe (Header blk)
prevTentativeHeader) ((Header blk -> m ()) -> m ()) -> (Header blk -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ Tracer m (Header blk) -> Header blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith (Tracer m (Header blk) -> Header blk -> m ())
-> Tracer m (Header blk) -> Header blk -> m ()
forall a b. (a -> b) -> a -> b
$
TracePipeliningEvent blk -> TraceAddBlockEvent blk
forall blk. TracePipeliningEvent blk -> TraceAddBlockEvent blk
PipeliningEvent (TracePipeliningEvent blk -> TraceAddBlockEvent blk)
-> (Header blk -> TracePipeliningEvent blk)
-> Header blk
-> TraceAddBlockEvent blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header blk -> TracePipeliningEvent blk
forall blk. Header blk -> TracePipeliningEvent blk
OutdatedTentativeHeader (Header blk -> TraceAddBlockEvent blk)
-> Tracer m (TraceAddBlockEvent blk) -> Tracer m (Header blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceAddBlockEvent blk)
addBlockTracer
Tracer m (LedgerDB' blk) -> LedgerDB' blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (LedgerDB' blk)
cdbTraceLedger LedgerDB' blk
newLedger
Point blk -> m (Point blk)
forall (m :: * -> *) a. Monad m => a -> m a
return (Point blk -> m (Point blk)) -> Point blk -> m (Point blk)
forall a b. (a -> b) -> a -> b
$ Point (Header blk) -> Point blk
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
newChain
where
ValidatedChainDiff ChainDiff (Header blk)
chainDiff LedgerDB' blk
newLedger = ValidatedChainDiff (Header blk) (LedgerDB' blk)
vChainDiff
translateToHeaders
:: ChainDiff (HeaderFields blk)
-> StateT (Map (HeaderHash blk) (Header blk))
m
(ChainDiff (Header blk))
translateToHeaders :: ChainDiff (HeaderFields blk)
-> StateT
(Map (HeaderHash blk) (Header blk)) m (ChainDiff (Header blk))
translateToHeaders =
(HeaderFields blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk))
-> ChainDiff (HeaderFields blk)
-> StateT
(Map (HeaderHash blk) (Header blk)) m (ChainDiff (Header blk))
forall a b (m :: * -> *).
(HasHeader b, HeaderHash a ~ HeaderHash b, Monad m) =>
(a -> m b) -> ChainDiff a -> m (ChainDiff b)
Diff.mapM (VolatileDB m blk
-> HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall (m :: * -> *) blk.
(MonadThrow m, HasHeader blk) =>
VolatileDB m blk
-> HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
getKnownHeaderThroughCache VolatileDB m blk
cdbVolatileDB (HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk))
-> (HeaderFields blk -> HeaderHash blk)
-> HeaderFields blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeaderFields blk -> HeaderHash blk
forall b. HeaderFields b -> HeaderHash b
headerFieldHash)
getKnownHeaderThroughCache
:: (MonadThrow m, HasHeader blk)
=> VolatileDB m blk
-> HeaderHash blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
VolatileDB m blk
volatileDB HeaderHash blk
hash = (Map (HeaderHash blk) (Header blk) -> Maybe (Header blk))
-> StateT
(Map (HeaderHash blk) (Header blk)) m (Maybe (Header blk))
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (HeaderHash blk
-> Map (HeaderHash blk) (Header blk) -> Maybe (Header blk)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup HeaderHash blk
hash) StateT (Map (HeaderHash blk) (Header blk)) m (Maybe (Header blk))
-> (Maybe (Header blk)
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk))
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just Header blk
hdr -> Header blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Header blk
hdr
Maybe (Header blk)
Nothing -> do
Header blk
hdr <- m (Header blk)
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Header blk)
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk))
-> m (Header blk)
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall a b. (a -> b) -> a -> b
$ VolatileDB m blk
-> BlockComponent blk (Header blk)
-> HeaderHash blk
-> m (Header blk)
forall (m :: * -> *) blk b.
(MonadThrow m, HasHeader blk) =>
VolatileDB m blk -> BlockComponent blk b -> HeaderHash blk -> m b
VolatileDB.getKnownBlockComponent VolatileDB m blk
volatileDB BlockComponent blk (Header blk)
forall blk. BlockComponent blk (Header blk)
GetHeader HeaderHash blk
hash
(Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk))
-> StateT (Map (HeaderHash blk) (Header blk)) m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify (HeaderHash blk
-> Header blk
-> Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert HeaderHash blk
hash Header blk
hdr)
Header blk
-> StateT (Map (HeaderHash blk) (Header blk)) m (Header blk)
forall (m :: * -> *) a. Monad m => a -> m a
return Header blk
hdr
data ChainSelEnv m blk = ChainSelEnv
{ ChainSelEnv m blk -> LgrDB m blk
lgrDB :: LgrDB m blk
, ChainSelEnv m blk -> Tracer m (TraceValidationEvent blk)
validationTracer :: Tracer m (TraceValidationEvent blk)
, ChainSelEnv m blk -> Tracer m (TracePipeliningEvent blk)
pipeliningTracer :: Tracer m (TracePipeliningEvent blk)
, ChainSelEnv m blk -> BlockConfig blk
bcfg :: BlockConfig blk
, ChainSelEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
, ChainSelEnv m blk -> StrictTVar m (FutureBlocks m blk)
varFutureBlocks :: StrictTVar m (FutureBlocks m blk)
, ChainSelEnv m blk -> StrictTVar m (TentativeState blk)
varTentativeState :: StrictTVar m (TentativeState blk)
, :: StrictTVar m (StrictMaybe (Header blk))
, ChainSelEnv m blk -> STM m [FollowerHandle m blk]
getTentativeFollowers :: STM m [FollowerHandle m blk]
, ChainSelEnv m blk -> CheckInFuture m blk
futureCheck :: CheckInFuture m blk
, ChainSelEnv m blk -> BlockCache blk
blockCache :: BlockCache blk
, ChainSelEnv m blk -> ChainAndLedger blk
curChainAndLedger :: ChainAndLedger blk
, ChainSelEnv m blk
-> Maybe (RealPoint blk, InvalidBlockPunishment m)
punish :: Maybe (RealPoint blk, InvalidBlockPunishment m)
}
chainSelection
:: forall m blk.
( IOLike m
, LedgerSupportsProtocol blk
, HasCallStack
)
=> ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection :: ChainSelEnv m blk
-> NonEmpty (ChainDiff (Header blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
chainSelection ChainSelEnv m blk
chainSelEnv NonEmpty (ChainDiff (Header blk))
chainDiffs =
Bool
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a. HasCallStack => Bool -> a -> a
assert ((ChainDiff (Header blk) -> Bool)
-> NonEmpty (ChainDiff (Header blk)) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate BlockConfig blk
bcfg AnchoredFragment (Header blk)
curChain (AnchoredFragment (Header blk) -> Bool)
-> (ChainDiff (Header blk) -> AnchoredFragment (Header blk))
-> ChainDiff (Header blk)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix)
NonEmpty (ChainDiff (Header blk))
chainDiffs) (m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$
Bool
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a. HasCallStack => Bool -> a -> a
assert ((ChainDiff (Header blk) -> Bool)
-> NonEmpty (ChainDiff (Header blk)) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Maybe (AnchoredFragment (Header blk)) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (AnchoredFragment (Header blk)) -> Bool)
-> (ChainDiff (Header blk)
-> Maybe (AnchoredFragment (Header blk)))
-> ChainDiff (Header blk)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnchoredFragment (Header blk)
-> ChainDiff (Header blk) -> Maybe (AnchoredFragment (Header blk))
forall b.
HasHeader b =>
AnchoredFragment b -> ChainDiff b -> Maybe (AnchoredFragment b)
Diff.apply AnchoredFragment (Header blk)
curChain)
NonEmpty (ChainDiff (Header blk))
chainDiffs) (m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$
[ChainDiff (Header blk)]
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
go ([ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
sortCandidates (NonEmpty (ChainDiff (Header blk)) -> [ChainDiff (Header blk)]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty (ChainDiff (Header blk))
chainDiffs))
where
ChainSelEnv {Maybe (RealPoint blk, InvalidBlockPunishment m)
Tracer m (TracePipeliningEvent blk)
Tracer m (TraceValidationEvent blk)
STM m [FollowerHandle m blk]
StrictTVar m (FutureBlocks m blk)
StrictTVar m (StrictMaybe (Header blk))
StrictTVar m (WithFingerprint (InvalidBlocks blk))
StrictTVar m (TentativeState blk)
BlockConfig blk
BlockCache blk
ChainAndLedger blk
CheckInFuture m blk
LgrDB m blk
punish :: Maybe (RealPoint blk, InvalidBlockPunishment m)
curChainAndLedger :: ChainAndLedger blk
blockCache :: BlockCache blk
futureCheck :: CheckInFuture m blk
getTentativeFollowers :: STM m [FollowerHandle m blk]
varTentativeHeader :: StrictTVar m (StrictMaybe (Header blk))
varTentativeState :: StrictTVar m (TentativeState blk)
varFutureBlocks :: StrictTVar m (FutureBlocks m blk)
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
pipeliningTracer :: Tracer m (TracePipeliningEvent blk)
validationTracer :: Tracer m (TraceValidationEvent blk)
lgrDB :: LgrDB m blk
bcfg :: BlockConfig blk
getTentativeFollowers :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> STM m [FollowerHandle m blk]
punish :: forall (m :: * -> *) blk.
ChainSelEnv m blk
-> Maybe (RealPoint blk, InvalidBlockPunishment m)
varTentativeHeader :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (StrictMaybe (Header blk))
varTentativeState :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (TentativeState blk)
pipeliningTracer :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> Tracer m (TracePipeliningEvent blk)
validationTracer :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> Tracer m (TraceValidationEvent blk)
curChainAndLedger :: forall (m :: * -> *) blk. ChainSelEnv m blk -> ChainAndLedger blk
blockCache :: forall (m :: * -> *) blk. ChainSelEnv m blk -> BlockCache blk
futureCheck :: forall (m :: * -> *) blk. ChainSelEnv m blk -> CheckInFuture m blk
varFutureBlocks :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (FutureBlocks m blk)
varInvalid :: forall (m :: * -> *) blk.
ChainSelEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
bcfg :: forall (m :: * -> *) blk. ChainSelEnv m blk -> BlockConfig blk
lgrDB :: forall (m :: * -> *) blk. ChainSelEnv m blk -> LgrDB m blk
..} = ChainSelEnv m blk
chainSelEnv
curChain :: AnchoredFragment (Header blk)
curChain = ChainAndLedger blk -> AnchoredFragment (Header blk)
forall b l. ValidatedFragment b l -> AnchoredFragment b
VF.validatedFragment ChainAndLedger blk
curChainAndLedger
sortCandidates :: [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
sortCandidates :: [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
sortCandidates =
(ChainDiff (Header blk) -> ChainDiff (Header blk) -> Ordering)
-> [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk) -> Ordering)
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip (BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Ordering
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Ordering
compareAnchoredFragments BlockConfig blk
bcfg) (AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk) -> Ordering)
-> (ChainDiff (Header blk) -> AnchoredFragment (Header blk))
-> ChainDiff (Header blk)
-> ChainDiff (Header blk)
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix)
go ::
[ChainDiff (Header blk)]
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
go :: [ChainDiff (Header blk)]
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
go [] = Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a. Maybe a
Nothing
go (ChainDiff (Header blk)
candidate:[ChainDiff (Header blk)]
candidates0) = do
StrictMaybe (Header blk)
mTentativeHeader <- m (StrictMaybe (Header blk))
setTentativeHeader
ChainSelEnv m blk
-> ChainDiff (Header blk) -> m (ValidationResult blk)
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, HasCallStack) =>
ChainSelEnv m blk
-> ChainDiff (Header blk) -> m (ValidationResult blk)
validateCandidate ChainSelEnv m blk
chainSelEnv ChainDiff (Header blk)
candidate m (ValidationResult blk)
-> (ValidationResult blk
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
ValidationResult blk
InsufficientSuffix ->
Bool
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a. HasCallStack => Bool -> a -> a
assert (StrictMaybe (Header blk) -> Bool
forall a. StrictMaybe a -> Bool
isSNothing StrictMaybe (Header blk)
mTentativeHeader) (m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$ do
[ChainDiff (Header blk)]
candidates1 <- [ChainDiff (Header blk)] -> m [ChainDiff (Header blk)]
truncateRejectedBlocks [ChainDiff (Header blk)]
candidates0
[ChainDiff (Header blk)]
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
go ([ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
sortCandidates [ChainDiff (Header blk)]
candidates1)
FullyValid validatedCandidate :: ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedCandidate@(ValidatedChainDiff ChainDiff (Header blk)
candidate' LedgerDB' blk
_) ->
Bool
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a. HasCallStack => Bool -> a -> a
assert (ChainDiff (Header blk) -> Point (Header blk)
forall b. HasHeader b => ChainDiff b -> Point b
Diff.getTip ChainDiff (Header blk)
candidate Point (Header blk) -> Point (Header blk) -> Bool
forall a. Eq a => a -> a -> Bool
== ChainDiff (Header blk) -> Point (Header blk)
forall b. HasHeader b => ChainDiff b -> Point b
Diff.getTip ChainDiff (Header blk)
candidate') (m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$
Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$ ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a. a -> Maybe a
Just ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedCandidate
ValidPrefix ChainDiff (Header blk)
candidate' -> do
Maybe (Header blk) -> (Header blk -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust (StrictMaybe (Header blk) -> Maybe (Header blk)
forall a. StrictMaybe a -> Maybe a
strictMaybeToMaybe StrictMaybe (Header blk)
mTentativeHeader) Header blk -> m ()
clearTentativeHeader
[ChainDiff (Header blk)]
candidates1 <- [ChainDiff (Header blk)] -> m [ChainDiff (Header blk)]
truncateRejectedBlocks [ChainDiff (Header blk)]
candidates0
let candidates2 :: [ChainDiff (Header blk)]
candidates2
| BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate BlockConfig blk
bcfg AnchoredFragment (Header blk)
curChain (ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix ChainDiff (Header blk)
candidate')
= ChainDiff (Header blk)
candidate'ChainDiff (Header blk)
-> [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
forall a. a -> [a] -> [a]
:[ChainDiff (Header blk)]
candidates1
| Bool
otherwise
= [ChainDiff (Header blk)]
candidates1
[ChainDiff (Header blk)]
-> m (Maybe (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
go ([ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
sortCandidates [ChainDiff (Header blk)]
candidates2)
where
setTentativeHeader :: m (StrictMaybe (Header blk))
setTentativeHeader :: m (StrictMaybe (Header blk))
setTentativeHeader = do
StrictMaybe (Header blk)
mTentativeHeader <-
(\TentativeState blk
ts -> BlockConfig blk
-> TentativeState blk
-> ChainDiff (Header blk)
-> StrictMaybe (Header blk)
forall blk.
LedgerSupportsProtocol blk =>
BlockConfig blk
-> TentativeState blk
-> ChainDiff (Header blk)
-> StrictMaybe (Header blk)
isPipelineable BlockConfig blk
bcfg TentativeState blk
ts ChainDiff (Header blk)
candidate)
(TentativeState blk -> StrictMaybe (Header blk))
-> m (TentativeState blk) -> m (StrictMaybe (Header blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (TentativeState blk) -> m (TentativeState blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> m a
readTVarIO StrictTVar m (TentativeState blk)
varTentativeState
Maybe (Header blk) -> (Header blk -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust (StrictMaybe (Header blk) -> Maybe (Header blk)
forall a. StrictMaybe a -> Maybe a
strictMaybeToMaybe StrictMaybe (Header blk)
mTentativeHeader) ((Header blk -> m ()) -> m ()) -> (Header blk -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Header blk
tentativeHeader -> do
let setTentative :: Enclosing -> TracePipeliningEvent blk
setTentative = Header blk -> Enclosing -> TracePipeliningEvent blk
forall blk. Header blk -> Enclosing -> TracePipeliningEvent blk
SetTentativeHeader Header blk
tentativeHeader
Tracer m Enclosing -> m () -> m ()
forall (m :: * -> *) a.
Applicative m =>
Tracer m Enclosing -> m a -> m a
encloseWith (Enclosing -> TracePipeliningEvent blk
setTentative (Enclosing -> TracePipeliningEvent blk)
-> Tracer m (TracePipeliningEvent blk) -> Tracer m Enclosing
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TracePipeliningEvent blk)
pipeliningTracer) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ StrictTVar m (StrictMaybe (Header blk))
-> StrictMaybe (Header blk) -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader (StrictMaybe (Header blk) -> STM m ())
-> StrictMaybe (Header blk) -> STM m ()
forall a b. (a -> b) -> a -> b
$ Header blk -> StrictMaybe (Header blk)
forall a. a -> StrictMaybe a
SJust Header blk
tentativeHeader
m ()
forall (m :: * -> *). MonadFork m => m ()
yield
StrictMaybe (Header blk) -> m (StrictMaybe (Header blk))
forall (f :: * -> *) a. Applicative f => a -> f a
pure StrictMaybe (Header blk)
mTentativeHeader
clearTentativeHeader :: Header blk -> m ()
clearTentativeHeader :: Header blk -> m ()
clearTentativeHeader Header blk
tentativeHeader = do
STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
StrictTVar m (StrictMaybe (Header blk))
-> StrictMaybe (Header blk) -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (StrictMaybe (Header blk))
varTentativeHeader StrictMaybe (Header blk)
forall a. StrictMaybe a
SNothing
StrictTVar m (TentativeState blk) -> TentativeState blk -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (TentativeState blk)
varTentativeState (TentativeState blk -> STM m ()) -> TentativeState blk -> STM m ()
forall a b. (a -> b) -> a -> b
$
SelectView (BlockProtocol blk) -> TentativeState blk
forall blk. SelectView (BlockProtocol blk) -> TentativeState blk
LastInvalidTentative (BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
forall blk.
BlockSupportsProtocol blk =>
BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
selectView BlockConfig blk
bcfg Header blk
tentativeHeader)
(FollowerHandle m blk -> STM m ()) -> STM m ()
forTentativeFollowers ((FollowerHandle m blk -> STM m ()) -> STM m ())
-> (FollowerHandle m blk -> STM m ()) -> STM m ()
forall a b. (a -> b) -> a -> b
$ \FollowerHandle m blk
followerHandle -> do
let curTipPoint :: Point blk
curTipPoint = Point (Header blk) -> Point blk
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
curChain
FollowerHandle m blk
-> Point blk -> AnchoredFragment (Header blk) -> STM m ()
forall (m :: * -> *) blk.
FollowerHandle m blk
-> Point blk -> AnchoredFragment (Header blk) -> STM m ()
fhSwitchFork FollowerHandle m blk
followerHandle Point blk
curTipPoint AnchoredFragment (Header blk)
curChain
Tracer m (TracePipeliningEvent blk)
-> TracePipeliningEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TracePipeliningEvent blk)
pipeliningTracer (TracePipeliningEvent blk -> m ())
-> TracePipeliningEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Header blk -> TracePipeliningEvent blk
forall blk. Header blk -> TracePipeliningEvent blk
TrapTentativeHeader Header blk
tentativeHeader
where
forTentativeFollowers :: (FollowerHandle m blk -> STM m ()) -> STM m ()
forTentativeFollowers FollowerHandle m blk -> STM m ()
f = STM m [FollowerHandle m blk]
getTentativeFollowers STM m [FollowerHandle m blk]
-> ([FollowerHandle m blk] -> STM m ()) -> STM m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (FollowerHandle m blk -> STM m ())
-> [FollowerHandle m blk] -> STM m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ FollowerHandle m blk -> STM m ()
f
truncateRejectedBlocks ::
[ChainDiff (Header blk)]
-> m [ChainDiff (Header blk)]
truncateRejectedBlocks :: [ChainDiff (Header blk)] -> m [ChainDiff (Header blk)]
truncateRejectedBlocks [ChainDiff (Header blk)]
cands = do
(WithFingerprint (InvalidBlocks blk)
invalid, FutureBlocks m blk
futureBlocks) <-
STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk)
-> m (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk)
-> m (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk))
-> STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk)
-> m (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk)
forall a b. (a -> b) -> a -> b
$ (,) (WithFingerprint (InvalidBlocks blk)
-> FutureBlocks m blk
-> (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk))
-> STM m (WithFingerprint (InvalidBlocks blk))
-> STM
m
(FutureBlocks m blk
-> (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> STM m (WithFingerprint (InvalidBlocks blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid STM
m
(FutureBlocks m blk
-> (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk))
-> STM m (FutureBlocks m blk)
-> STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks m blk)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StrictTVar m (FutureBlocks m blk) -> STM m (FutureBlocks m blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (FutureBlocks m blk)
varFutureBlocks
let isRejected :: Header blk -> Bool
isRejected Header blk
hdr =
HeaderHash blk -> InvalidBlocks blk -> Bool
forall k a. Ord k => k -> Map k a -> Bool
Map.member (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr) (WithFingerprint (InvalidBlocks blk) -> InvalidBlocks blk
forall a. WithFingerprint a -> a
forgetFingerprint WithFingerprint (InvalidBlocks blk)
invalid)
Bool -> Bool -> Bool
|| HeaderHash blk -> FutureBlocks m blk -> Bool
forall k a. Ord k => k -> Map k a -> Bool
Map.member (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr) FutureBlocks m blk
futureBlocks
[ChainDiff (Header blk)] -> m [ChainDiff (Header blk)]
forall (m :: * -> *) a. Monad m => a -> m a
return ([ChainDiff (Header blk)] -> m [ChainDiff (Header blk)])
-> [ChainDiff (Header blk)] -> m [ChainDiff (Header blk)]
forall a b. (a -> b) -> a -> b
$ (ChainDiff (Header blk) -> Bool)
-> [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
forall a. (a -> Bool) -> [a] -> [a]
filter (BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
BlockConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate BlockConfig blk
bcfg AnchoredFragment (Header blk)
curChain (AnchoredFragment (Header blk) -> Bool)
-> (ChainDiff (Header blk) -> AnchoredFragment (Header blk))
-> ChainDiff (Header blk)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix)
([ChainDiff (Header blk)] -> [ChainDiff (Header blk)])
-> [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
forall a b. (a -> b) -> a -> b
$ (ChainDiff (Header blk) -> ChainDiff (Header blk))
-> [ChainDiff (Header blk)] -> [ChainDiff (Header blk)]
forall a b. (a -> b) -> [a] -> [b]
map ((Header blk -> Bool)
-> ChainDiff (Header blk) -> ChainDiff (Header blk)
forall b. HasHeader b => (b -> Bool) -> ChainDiff b -> ChainDiff b
Diff.takeWhileOldest (Bool -> Bool
not (Bool -> Bool) -> (Header blk -> Bool) -> Header blk -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header blk -> Bool
isRejected)) [ChainDiff (Header blk)]
cands
data ValidationResult blk =
FullyValid (ValidatedChainDiff (Header blk) (LedgerDB' blk))
| ValidPrefix (ChainDiff (Header blk))
| InsufficientSuffix
ledgerValidateCandidate
:: forall m blk.
( IOLike m
, LedgerSupportsProtocol blk
, HasCallStack
)
=> ChainSelEnv m blk
-> ChainDiff (Header blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
ledgerValidateCandidate :: ChainSelEnv m blk
-> ChainDiff (Header blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
ledgerValidateCandidate ChainSelEnv m blk
chainSelEnv chainDiff :: ChainDiff (Header blk)
chainDiff@(ChainDiff Word64
rollback AnchoredFragment (Header blk)
suffix) =
LgrDB m blk
-> LedgerDB' blk
-> BlockCache blk
-> Word64
-> (UpdateLedgerDbTraceEvent blk -> m ())
-> [Header blk]
-> m (ValidateResult blk)
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, HasCallStack) =>
LgrDB m blk
-> LedgerDB' blk
-> BlockCache blk
-> Word64
-> (UpdateLedgerDbTraceEvent blk -> m ())
-> [Header blk]
-> m (ValidateResult blk)
LgrDB.validate LgrDB m blk
lgrDB LedgerDB' blk
curLedger BlockCache blk
blockCache Word64
rollback UpdateLedgerDbTraceEvent blk -> m ()
traceUpdate [Header blk]
newBlocks m (ValidateResult blk)
-> (ValidateResult blk
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
LgrDB.ValidateExceededRollBack {} ->
[Char] -> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a. HasCallStack => [Char] -> a
error [Char]
"found candidate requiring rolling back past the immutable tip"
LgrDB.ValidateLedgerError (LgrDB.AnnLedgerError LedgerDB' blk
ledger' RealPoint blk
pt LedgerErr (ExtLedgerState blk)
e) -> do
let lastValid :: Point blk
lastValid = LedgerDB' blk -> Point blk
forall blk. UpdateLedger blk => LedgerDB' blk -> Point blk
LgrDB.currentPoint LedgerDB' blk
ledger'
chainDiff' :: ChainDiff (Header blk)
chainDiff' = Point (Header blk)
-> ChainDiff (Header blk) -> ChainDiff (Header blk)
forall b.
(HasHeader b, HasCallStack) =>
Point b -> ChainDiff b -> ChainDiff b
Diff.truncate (Point blk -> Point (Header blk)
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point blk
lastValid) ChainDiff (Header blk)
chainDiff
Tracer m (TraceValidationEvent blk)
-> TraceValidationEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceValidationEvent blk)
validationTracer (ExtValidationError blk -> RealPoint blk -> TraceValidationEvent blk
forall blk.
ExtValidationError blk -> RealPoint blk -> TraceValidationEvent blk
InvalidBlock LedgerErr (ExtLedgerState blk)
ExtValidationError blk
e RealPoint blk
pt)
ExtValidationError blk -> RealPoint blk -> m ()
addInvalidBlock LedgerErr (ExtLedgerState blk)
ExtValidationError blk
e RealPoint blk
pt
Tracer m (TraceValidationEvent blk)
-> TraceValidationEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceValidationEvent blk)
validationTracer (AnchoredFragment (Header blk) -> TraceValidationEvent blk
forall blk.
AnchoredFragment (Header blk) -> TraceValidationEvent blk
ValidCandidate (ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix ChainDiff (Header blk)
chainDiff'))
Maybe (RealPoint blk, InvalidBlockPunishment m)
-> ((RealPoint blk, InvalidBlockPunishment m) -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust Maybe (RealPoint blk, InvalidBlockPunishment m)
punish (((RealPoint blk, InvalidBlockPunishment m) -> m ()) -> m ())
-> ((RealPoint blk, InvalidBlockPunishment m) -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \(RealPoint blk
addedPt, InvalidBlockPunishment m
punishment) -> do
let m :: m ()
m = InvalidBlockPunishment m -> Invalidity -> m ()
forall (m :: * -> *).
InvalidBlockPunishment m -> Invalidity -> m ()
InvalidBlockPunishment.enact InvalidBlockPunishment m
punishment
(Invalidity -> m ()) -> Invalidity -> m ()
forall a b. (a -> b) -> a -> b
$ if RealPoint blk
addedPt RealPoint blk -> RealPoint blk -> Bool
forall a. Eq a => a -> a -> Bool
== RealPoint blk
pt
then Invalidity
InvalidBlockPunishment.BlockItself
else Invalidity
InvalidBlockPunishment.BlockPrefix
case RealPoint blk -> SlotNo
forall blk. RealPoint blk -> SlotNo
realPointSlot RealPoint blk
pt SlotNo -> SlotNo -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` RealPoint blk -> SlotNo
forall blk. RealPoint blk -> SlotNo
realPointSlot RealPoint blk
addedPt of
Ordering
LT -> m ()
m
Ordering
GT -> () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Ordering
EQ -> Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Point blk
lastValid Point blk -> Point blk -> Bool
forall a. Eq a => a -> a -> Bool
/= RealPoint blk -> Point blk
forall blk. RealPoint blk -> Point blk
realPointToPoint RealPoint blk
addedPt) m ()
m
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a b. (a -> b) -> a -> b
$ ChainDiff (Header blk)
-> LedgerDB' blk -> ValidatedChainDiff (Header blk) (LedgerDB' blk)
forall b l.
(IsLedger l, HasHeader b, HeaderHash l ~ HeaderHash b,
HasCallStack) =>
ChainDiff b -> l -> ValidatedChainDiff b l
ValidatedDiff.new ChainDiff (Header blk)
chainDiff' LedgerDB' blk
ledger'
LgrDB.ValidateSuccessful LedgerDB' blk
ledger' -> do
Tracer m (TraceValidationEvent blk)
-> TraceValidationEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceValidationEvent blk)
validationTracer (AnchoredFragment (Header blk) -> TraceValidationEvent blk
forall blk.
AnchoredFragment (Header blk) -> TraceValidationEvent blk
ValidCandidate AnchoredFragment (Header blk)
suffix)
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a b. (a -> b) -> a -> b
$ ChainDiff (Header blk)
-> LedgerDB' blk -> ValidatedChainDiff (Header blk) (LedgerDB' blk)
forall b l.
(IsLedger l, HasHeader b, HeaderHash l ~ HeaderHash b,
HasCallStack) =>
ChainDiff b -> l -> ValidatedChainDiff b l
ValidatedDiff.new ChainDiff (Header blk)
chainDiff LedgerDB' blk
ledger'
where
ChainSelEnv {
LgrDB m blk
lgrDB :: LgrDB m blk
lgrDB :: forall (m :: * -> *) blk. ChainSelEnv m blk -> LgrDB m blk
lgrDB
, Tracer m (TraceValidationEvent blk)
validationTracer :: Tracer m (TraceValidationEvent blk)
validationTracer :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> Tracer m (TraceValidationEvent blk)
validationTracer
, ChainAndLedger blk
curChainAndLedger :: ChainAndLedger blk
curChainAndLedger :: forall (m :: * -> *) blk. ChainSelEnv m blk -> ChainAndLedger blk
curChainAndLedger
, BlockCache blk
blockCache :: BlockCache blk
blockCache :: forall (m :: * -> *) blk. ChainSelEnv m blk -> BlockCache blk
blockCache
, StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: forall (m :: * -> *) blk.
ChainSelEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid
, Maybe (RealPoint blk, InvalidBlockPunishment m)
punish :: Maybe (RealPoint blk, InvalidBlockPunishment m)
punish :: forall (m :: * -> *) blk.
ChainSelEnv m blk
-> Maybe (RealPoint blk, InvalidBlockPunishment m)
punish
} = ChainSelEnv m blk
chainSelEnv
traceUpdate :: UpdateLedgerDbTraceEvent blk -> m ()
traceUpdate = Tracer m (UpdateLedgerDbTraceEvent blk)
-> UpdateLedgerDbTraceEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith (Tracer m (UpdateLedgerDbTraceEvent blk)
-> UpdateLedgerDbTraceEvent blk -> m ())
-> Tracer m (UpdateLedgerDbTraceEvent blk)
-> UpdateLedgerDbTraceEvent blk
-> m ()
forall a b. (a -> b) -> a -> b
$ UpdateLedgerDbTraceEvent blk -> TraceValidationEvent blk
forall blk.
UpdateLedgerDbTraceEvent blk -> TraceValidationEvent blk
UpdateLedgerDbTraceEvent (UpdateLedgerDbTraceEvent blk -> TraceValidationEvent blk)
-> Tracer m (TraceValidationEvent blk)
-> Tracer m (UpdateLedgerDbTraceEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< Tracer m (TraceValidationEvent blk)
validationTracer
curLedger :: LedgerDB' blk
curLedger :: LedgerDB' blk
curLedger = ChainAndLedger blk -> LedgerDB' blk
forall b l. ValidatedFragment b l -> l
VF.validatedLedger ChainAndLedger blk
curChainAndLedger
newBlocks :: [Header blk]
newBlocks :: [Header blk]
newBlocks = AnchoredFragment (Header blk) -> [Header blk]
forall v a b. AnchoredSeq v a b -> [b]
AF.toOldestFirst AnchoredFragment (Header blk)
suffix
addInvalidBlock :: ExtValidationError blk -> RealPoint blk -> m ()
addInvalidBlock :: ExtValidationError blk -> RealPoint blk -> m ()
addInvalidBlock ExtValidationError blk
e (RealPoint SlotNo
slot HeaderHash blk
hash) = STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$
StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> (WithFingerprint (InvalidBlocks blk)
-> WithFingerprint (InvalidBlocks blk))
-> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid ((WithFingerprint (InvalidBlocks blk)
-> WithFingerprint (InvalidBlocks blk))
-> STM m ())
-> (WithFingerprint (InvalidBlocks blk)
-> WithFingerprint (InvalidBlocks blk))
-> STM m ()
forall a b. (a -> b) -> a -> b
$ \(WithFingerprint InvalidBlocks blk
invalid Fingerprint
fp) ->
InvalidBlocks blk
-> Fingerprint -> WithFingerprint (InvalidBlocks blk)
forall a. a -> Fingerprint -> WithFingerprint a
WithFingerprint
(HeaderHash blk
-> InvalidBlockInfo blk -> InvalidBlocks blk -> InvalidBlocks blk
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert HeaderHash blk
hash (InvalidBlockReason blk -> SlotNo -> InvalidBlockInfo blk
forall blk.
InvalidBlockReason blk -> SlotNo -> InvalidBlockInfo blk
InvalidBlockInfo (ExtValidationError blk -> InvalidBlockReason blk
forall blk. ExtValidationError blk -> InvalidBlockReason blk
ValidationError ExtValidationError blk
e) SlotNo
slot) InvalidBlocks blk
invalid)
(Fingerprint -> Fingerprint
forall a. Enum a => a -> a
succ Fingerprint
fp)
futureCheckCandidate
:: forall m blk. (IOLike m, LedgerSupportsProtocol blk)
=> ChainSelEnv m blk
-> ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (Either (ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
futureCheckCandidate :: ChainSelEnv m blk
-> ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
futureCheckCandidate ChainSelEnv m blk
chainSelEnv ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff =
CheckInFuture m blk
-> ValidatedFragment (Header blk) (LedgerState blk)
-> m (AnchoredFragment (Header blk), [InFuture m blk])
forall (m :: * -> *) blk.
CheckInFuture m blk
-> ValidatedFragment (Header blk) (LedgerState blk)
-> m (AnchoredFragment (Header blk), [InFuture m blk])
checkInFuture CheckInFuture m blk
futureCheck ValidatedFragment (Header blk) (LedgerState blk)
validatedSuffix m (AnchoredFragment (Header blk), [InFuture m blk])
-> ((AnchoredFragment (Header blk), [InFuture m blk])
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
(AnchoredFragment (Header blk)
suffix', []) ->
Bool
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a. HasCallStack => Bool -> a -> a
assert (AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
suffix Point (Header blk) -> Point (Header blk) -> Bool
forall a. Eq a => a -> a -> Bool
== AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
suffix') (m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$
Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$ ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a b. b -> Either a b
Right ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff
(AnchoredFragment (Header blk)
suffix', [InFuture m blk]
inFuture) -> do
let ([InFuture m blk]
exceedClockSkew, [InFuture m blk]
inNearFuture) =
(InFuture m blk -> Bool)
-> [InFuture m blk] -> ([InFuture m blk], [InFuture m blk])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition InFuture m blk -> Bool
forall (m :: * -> *) blk. InFuture m blk -> Bool
InFuture.inFutureExceedsClockSkew [InFuture m blk]
inFuture
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([InFuture m blk] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InFuture m blk]
inNearFuture) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
let futureBlocks :: Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
futureBlocks = [(HeaderHash blk, (Header blk, InvalidBlockPunishment m))]
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr, (Header blk
hdr, InFuture m blk -> InvalidBlockPunishment m
forall (m :: * -> *) blk.
InFuture m blk -> InvalidBlockPunishment m
InFuture.inFuturePunish InFuture m blk
x))
| InFuture m blk
x <- [InFuture m blk]
inNearFuture
, let hdr :: Header blk
hdr = InFuture m blk -> Header blk
forall (m :: * -> *) blk. InFuture m blk -> Header blk
InFuture.inFutureHeader InFuture m blk
x
]
STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ StrictTVar
m (Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
-> (Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
-> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar
m (Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
varFutureBlocks ((Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
-> STM m ())
-> (Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
-> STM m ()
forall a b. (a -> b) -> a -> b
$ (Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
-> Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m)
futureBlocks
Tracer m (TraceValidationEvent blk)
-> TraceValidationEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceValidationEvent blk)
validationTracer (TraceValidationEvent blk -> m ())
-> TraceValidationEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$
AnchoredFragment (Header blk)
-> [Header blk] -> TraceValidationEvent blk
forall blk.
AnchoredFragment (Header blk)
-> [Header blk] -> TraceValidationEvent blk
CandidateContainsFutureBlocks
AnchoredFragment (Header blk)
suffix
(InFuture m blk -> Header blk
forall (m :: * -> *) blk. InFuture m blk -> Header blk
InFuture.inFutureHeader (InFuture m blk -> Header blk) -> [InFuture m blk] -> [Header blk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [InFuture m blk]
inNearFuture)
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([InFuture m blk] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InFuture m blk]
exceedClockSkew) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
let invalidHeaders :: [Header blk]
invalidHeaders = InFuture m blk -> Header blk
forall (m :: * -> *) blk. InFuture m blk -> Header blk
InFuture.inFutureHeader (InFuture m blk -> Header blk) -> [InFuture m blk] -> [Header blk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [InFuture m blk]
exceedClockSkew
invalidBlocks :: Map (HeaderHash blk) (InvalidBlockInfo blk)
invalidBlocks = [(HeaderHash blk, InvalidBlockInfo blk)]
-> Map (HeaderHash blk) (InvalidBlockInfo blk)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr, InvalidBlockInfo blk
info)
| Header blk
hdr <- [Header blk]
invalidHeaders
, let reason :: InvalidBlockReason blk
reason = RealPoint blk -> InvalidBlockReason blk
forall blk. RealPoint blk -> InvalidBlockReason blk
InFutureExceedsClockSkew (Header blk -> RealPoint blk
forall blk. HasHeader (Header blk) => Header blk -> RealPoint blk
headerRealPoint Header blk
hdr)
info :: InvalidBlockInfo blk
info = InvalidBlockReason blk -> SlotNo -> InvalidBlockInfo blk
forall blk.
InvalidBlockReason blk -> SlotNo -> InvalidBlockInfo blk
InvalidBlockInfo InvalidBlockReason blk
reason (Header blk -> SlotNo
forall b. HasHeader b => b -> SlotNo
blockSlot Header blk
hdr)
]
STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ StrictTVar
m (WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)))
-> (WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk))
-> WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)))
-> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar
m (WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)))
varInvalid ((WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk))
-> WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)))
-> STM m ())
-> (WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk))
-> WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)))
-> STM m ()
forall a b. (a -> b) -> a -> b
$ \(WithFingerprint Map (HeaderHash blk) (InvalidBlockInfo blk)
invalid Fingerprint
fp) ->
Map (HeaderHash blk) (InvalidBlockInfo blk)
-> Fingerprint
-> WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk))
forall a. a -> Fingerprint -> WithFingerprint a
WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)
-> Map (HeaderHash blk) (InvalidBlockInfo blk)
-> Map (HeaderHash blk) (InvalidBlockInfo blk)
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map (HeaderHash blk) (InvalidBlockInfo blk)
invalid Map (HeaderHash blk) (InvalidBlockInfo blk)
invalidBlocks) (Fingerprint -> Fingerprint
forall a. Enum a => a -> a
succ Fingerprint
fp)
Tracer m (TraceValidationEvent blk)
-> TraceValidationEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceValidationEvent blk)
validationTracer (TraceValidationEvent blk -> m ())
-> TraceValidationEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$
AnchoredFragment (Header blk)
-> [Header blk] -> TraceValidationEvent blk
forall blk.
AnchoredFragment (Header blk)
-> [Header blk] -> TraceValidationEvent blk
CandidateContainsFutureBlocksExceedingClockSkew
AnchoredFragment (Header blk)
suffix
[Header blk]
invalidHeaders
[InFuture m blk] -> (InFuture m blk -> m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [InFuture m blk]
exceedClockSkew ((InFuture m blk -> m ()) -> m ())
-> (InFuture m blk -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \InFuture m blk
x -> do
InvalidBlockPunishment m -> Invalidity -> m ()
forall (m :: * -> *).
InvalidBlockPunishment m -> Invalidity -> m ()
InvalidBlockPunishment.enact
(InFuture m blk -> InvalidBlockPunishment m
forall (m :: * -> *) blk.
InFuture m blk -> InvalidBlockPunishment m
InFuture.inFuturePunish InFuture m blk
x)
Invalidity
InvalidBlockPunishment.BlockItself
Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))))
-> Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall a b. (a -> b) -> a -> b
$ ChainDiff (Header blk)
-> Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a b. a -> Either a b
Left (ChainDiff (Header blk)
-> Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> ChainDiff (Header blk)
-> Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall a b. (a -> b) -> a -> b
$ Point (Header blk)
-> ChainDiff (Header blk) -> ChainDiff (Header blk)
forall b.
(HasHeader b, HasCallStack) =>
Point b -> ChainDiff b -> ChainDiff b
Diff.truncate (Point (Header blk) -> Point (Header blk)
forall b b'.
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
suffix')) ChainDiff (Header blk)
chainDiff
where
ChainSelEnv { Tracer m (TraceValidationEvent blk)
validationTracer :: Tracer m (TraceValidationEvent blk)
validationTracer :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> Tracer m (TraceValidationEvent blk)
validationTracer, StrictTVar
m (WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)))
varInvalid :: StrictTVar
m (WithFingerprint (Map (HeaderHash blk) (InvalidBlockInfo blk)))
varInvalid :: forall (m :: * -> *) blk.
ChainSelEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid, StrictTVar
m (Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
varFutureBlocks :: StrictTVar
m (Map (HeaderHash blk) (Header blk, InvalidBlockPunishment m))
varFutureBlocks :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (FutureBlocks m blk)
varFutureBlocks, CheckInFuture m blk
futureCheck :: CheckInFuture m blk
futureCheck :: forall (m :: * -> *) blk. ChainSelEnv m blk -> CheckInFuture m blk
futureCheck } =
ChainSelEnv m blk
chainSelEnv
ValidatedChainDiff chainDiff :: ChainDiff (Header blk)
chainDiff@(ChainDiff Word64
_ AnchoredFragment (Header blk)
suffix) LedgerDB' blk
_ = ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff
validatedSuffix :: ValidatedFragment (Header blk) (LedgerState blk)
validatedSuffix :: ValidatedFragment (Header blk) (LedgerState blk)
validatedSuffix =
ExtLedgerState blk -> LedgerState blk
forall blk. ExtLedgerState blk -> LedgerState blk
ledgerState (ExtLedgerState blk -> LedgerState blk)
-> (LedgerDB' blk -> ExtLedgerState blk)
-> LedgerDB' blk
-> LedgerState blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LedgerDB' blk -> ExtLedgerState blk
forall l. GetTip l => LedgerDB l -> l
LgrDB.ledgerDbCurrent (LedgerDB' blk -> LedgerState blk)
-> ValidatedFragment (Header blk) (LedgerDB' blk)
-> ValidatedFragment (Header blk) (LedgerState blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ValidatedFragment (Header blk) (LedgerDB' blk)
forall l b.
(IsLedger l, HasHeader b, HeaderHash l ~ HeaderHash b,
HasCallStack) =>
ValidatedChainDiff b l -> ValidatedFragment b l
ValidatedDiff.toValidatedFragment ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff
validateCandidate
:: ( IOLike m
, LedgerSupportsProtocol blk
, HasCallStack
)
=> ChainSelEnv m blk
-> ChainDiff (Header blk)
-> m (ValidationResult blk)
validateCandidate :: ChainSelEnv m blk
-> ChainDiff (Header blk) -> m (ValidationResult blk)
validateCandidate ChainSelEnv m blk
chainSelEnv ChainDiff (Header blk)
chainDiff =
ChainSelEnv m blk
-> ChainDiff (Header blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, HasCallStack) =>
ChainSelEnv m blk
-> ChainDiff (Header blk)
-> m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
ledgerValidateCandidate ChainSelEnv m blk
chainSelEnv ChainDiff (Header blk)
chainDiff m (ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> (ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (ValidationResult blk))
-> m (ValidationResult blk)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff
| ValidatedChainDiff (Header blk) (LedgerDB' blk) -> Bool
forall b l. HasHeader b => ValidatedChainDiff b l -> Bool
ValidatedDiff.rollbackExceedsSuffix ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff
-> ValidationResult blk -> m (ValidationResult blk)
forall (m :: * -> *) a. Monad m => a -> m a
return ValidationResult blk
forall blk. ValidationResult blk
InsufficientSuffix
| Bool
otherwise
-> ChainSelEnv m blk
-> ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk) =>
ChainSelEnv m blk
-> ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
futureCheckCandidate ChainSelEnv m blk
chainSelEnv ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff m (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk)))
-> (Either
(ChainDiff (Header blk))
(ValidatedChainDiff (Header blk) (LedgerDB' blk))
-> m (ValidationResult blk))
-> m (ValidationResult blk)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left ChainDiff (Header blk)
chainDiff'
| ChainDiff (Header blk) -> Bool
forall b. HasHeader b => ChainDiff b -> Bool
Diff.rollbackExceedsSuffix ChainDiff (Header blk)
chainDiff'
-> ValidationResult blk -> m (ValidationResult blk)
forall (m :: * -> *) a. Monad m => a -> m a
return ValidationResult blk
forall blk. ValidationResult blk
InsufficientSuffix
| Bool
otherwise
-> ValidationResult blk -> m (ValidationResult blk)
forall (m :: * -> *) a. Monad m => a -> m a
return (ValidationResult blk -> m (ValidationResult blk))
-> ValidationResult blk -> m (ValidationResult blk)
forall a b. (a -> b) -> a -> b
$ ChainDiff (Header blk) -> ValidationResult blk
forall blk. ChainDiff (Header blk) -> ValidationResult blk
ValidPrefix ChainDiff (Header blk)
chainDiff'
Right ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff'
| ValidatedChainDiff (Header blk) (LedgerDB' blk) -> Bool
forall b l. HasHeader b => ValidatedChainDiff b l -> Bool
ValidatedDiff.rollbackExceedsSuffix ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff'
-> ValidationResult blk -> m (ValidationResult blk)
forall (m :: * -> *) a. Monad m => a -> m a
return ValidationResult blk
forall blk. ValidationResult blk
InsufficientSuffix
| AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Int
forall v a b. Anchorable v a b => AnchoredSeq v a b -> Int
AF.length (ChainDiff (Header blk)
-> AnchoredSeq
(WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix ChainDiff (Header blk)
chainDiff) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==
AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Int
forall v a b. Anchorable v a b => AnchoredSeq v a b -> Int
AF.length (ChainDiff (Header blk)
-> AnchoredSeq
(WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix ChainDiff (Header blk)
chainDiff')
-> ValidationResult blk -> m (ValidationResult blk)
forall (m :: * -> *) a. Monad m => a -> m a
return (ValidationResult blk -> m (ValidationResult blk))
-> ValidationResult blk -> m (ValidationResult blk)
forall a b. (a -> b) -> a -> b
$ ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ValidationResult blk
forall blk.
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ValidationResult blk
FullyValid ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff'
| Bool
otherwise
-> ValidationResult blk -> m (ValidationResult blk)
forall (m :: * -> *) a. Monad m => a -> m a
return (ValidationResult blk -> m (ValidationResult blk))
-> ValidationResult blk -> m (ValidationResult blk)
forall a b. (a -> b) -> a -> b
$ ChainDiff (Header blk) -> ValidationResult blk
forall blk. ChainDiff (Header blk) -> ValidationResult blk
ValidPrefix ChainDiff (Header blk)
chainDiff'
where
chainDiff' :: ChainDiff (Header blk)
chainDiff' = ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ChainDiff (Header blk)
forall b l. ValidatedChainDiff b l -> ChainDiff b
ValidatedDiff.getChainDiff ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff'
type ChainAndLedger blk = ValidatedFragment (Header blk) (LedgerDB' blk)
isPipelineable ::
LedgerSupportsProtocol blk
=> BlockConfig blk
-> TentativeState blk
-> ChainDiff (Header blk)
-> StrictMaybe (Header blk)
isPipelineable :: BlockConfig blk
-> TentativeState blk
-> ChainDiff (Header blk)
-> StrictMaybe (Header blk)
isPipelineable BlockConfig blk
bcfg TentativeState blk
tentativeState ChainDiff {Word64
AnchoredFragment (Header blk)
getRollback :: forall b. ChainDiff b -> Word64
getSuffix :: AnchoredFragment (Header blk)
getRollback :: Word64
getSuffix :: forall b. ChainDiff b -> AnchoredFragment b
..}
|
AF.Empty Anchor (Header blk)
_ :> Header blk
hdr <- AnchoredFragment (Header blk)
getSuffix
, BlockConfig blk -> TentativeState blk -> Header blk -> Bool
forall blk.
LedgerSupportsProtocol blk =>
BlockConfig blk -> TentativeState blk -> Header blk -> Bool
preferToLastInvalidTentative BlockConfig blk
bcfg TentativeState blk
tentativeState Header blk
hdr
, Word64
getRollback Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0
= Header blk -> StrictMaybe (Header blk)
forall a. a -> StrictMaybe a
SJust Header blk
hdr
| Bool
otherwise = StrictMaybe (Header blk)
forall a. StrictMaybe a
SNothing
ignoreInvalid
:: HasHeader blk
=> proxy blk
-> InvalidBlocks blk
-> (HeaderHash blk -> Maybe a)
-> (HeaderHash blk -> Maybe a)
ignoreInvalid :: proxy blk
-> InvalidBlocks blk
-> (HeaderHash blk -> Maybe a)
-> HeaderHash blk
-> Maybe a
ignoreInvalid proxy blk
_ InvalidBlocks blk
invalid HeaderHash blk -> Maybe a
getter HeaderHash blk
hash
| HeaderHash blk -> InvalidBlocks blk -> Bool
forall k a. Ord k => k -> Map k a -> Bool
Map.member HeaderHash blk
hash InvalidBlocks blk
invalid = Maybe a
forall a. Maybe a
Nothing
| Bool
otherwise = HeaderHash blk -> Maybe a
getter HeaderHash blk
hash
ignoreInvalidSuc
:: HasHeader blk
=> proxy blk
-> InvalidBlocks blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> (ChainHash blk -> Set (HeaderHash blk))
ignoreInvalidSuc :: proxy blk
-> InvalidBlocks blk
-> (ChainHash blk -> Set (HeaderHash blk))
-> ChainHash blk
-> Set (HeaderHash blk)
ignoreInvalidSuc proxy blk
_ InvalidBlocks blk
invalid ChainHash blk -> Set (HeaderHash blk)
succsOf =
(HeaderHash blk -> Bool)
-> Set (HeaderHash blk) -> Set (HeaderHash blk)
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (HeaderHash blk -> InvalidBlocks blk -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.notMember` InvalidBlocks blk
invalid) (Set (HeaderHash blk) -> Set (HeaderHash blk))
-> (ChainHash blk -> Set (HeaderHash blk))
-> ChainHash blk
-> Set (HeaderHash blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainHash blk -> Set (HeaderHash blk)
succsOf