{-# 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
( initialChainSelection
, addBlockAsync
, addBlockSync
, chainSelectionForBlock
, olderThanK
) where
import Control.Exception (assert)
import Control.Monad.Except
import Control.Monad.Trans.State.Strict
import Control.Tracer (Tracer, contramap, 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.Set (Set)
import qualified Data.Set as Set
import GHC.Stack (HasCallStack)
import Ouroboros.Network.AnchoredFragment (Anchor,
AnchoredFragment (..))
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.AnchoredFragment
import Ouroboros.Consensus.Util.IOLike
import Ouroboros.Consensus.Util.STM (WithFingerprint (..))
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 (..), InvalidBlockReason (..))
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
initialChainSelection
:: forall m blk. (IOLike m, LedgerSupportsProtocol blk)
=> ImmutableDB m blk
-> VolatileDB m blk
-> LgrDB m blk
-> Tracer m (TraceEvent blk)
-> TopLevelConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks blk)
-> CheckInFuture m blk
-> m (ChainAndLedger blk)
initialChainSelection :: ImmutableDB m blk
-> VolatileDB m blk
-> LgrDB m blk
-> Tracer m (TraceEvent blk)
-> TopLevelConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks blk)
-> CheckInFuture m blk
-> m (ChainAndLedger blk)
initialChainSelection ImmutableDB m blk
immutableDB VolatileDB m blk
volatileDB LgrDB m blk
lgrDB Tracer m (TraceEvent blk)
tracer TopLevelConfig blk
cfg StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid
StrictTVar m (FutureBlocks 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 block.
HasHeader block =>
Anchor block -> AnchoredFragment block
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 (TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
BlockSupportsProtocol blk =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cfg 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
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 (FutureBlocks blk) m [AnchoredFragment (Header blk)]
-> FutureBlocks blk -> m [AnchoredFragment (Header blk)])
-> FutureBlocks blk
-> StateT (FutureBlocks blk) m [AnchoredFragment (Header blk)]
-> m [AnchoredFragment (Header blk)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT (FutureBlocks blk) m [AnchoredFragment (Header blk)]
-> FutureBlocks blk -> m [AnchoredFragment (Header blk)]
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT FutureBlocks blk
forall k a. Map k a
Map.empty (StateT (FutureBlocks blk) m [AnchoredFragment (Header blk)]
-> m [AnchoredFragment (Header blk)])
-> StateT (FutureBlocks blk) m [AnchoredFragment (Header blk)]
-> m [AnchoredFragment (Header blk)]
forall a b. (a -> b) -> a -> b
$
(NonEmpty (HeaderHash blk)
-> StateT (FutureBlocks blk) m (AnchoredFragment (Header blk)))
-> [NonEmpty (HeaderHash blk)]
-> StateT (FutureBlocks 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 (FutureBlocks 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.candidates 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 (FutureBlocks blk) m (AnchoredFragment (Header blk))
constructChain NonEmpty (HeaderHash blk)
hashes =
Anchor (Header blk)
-> [Header blk] -> AnchoredFragment (Header blk)
forall block.
HasHeader block =>
Anchor block -> [block] -> AnchoredFragment block
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 (FutureBlocks blk) m [Header blk]
-> StateT (FutureBlocks blk) m (AnchoredFragment (Header blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(HeaderHash blk -> StateT (FutureBlocks blk) m (Header blk))
-> [HeaderHash blk] -> StateT (FutureBlocks 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 (FutureBlocks 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 (TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
BlockSupportsProtocol blk =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cfg 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
$
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 (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 :: ChainSelEnv m blk
chainSelEnv = ChainSelEnv :: forall (m :: * -> *) blk.
LgrDB m blk
-> (TraceValidationEvent blk -> m ())
-> TopLevelConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks blk)
-> CheckInFuture m blk
-> BlockCache blk
-> ChainAndLedger blk
-> ChainSelEnv m blk
ChainSelEnv
{ LgrDB m blk
lgrDB :: LgrDB m blk
lgrDB :: LgrDB m blk
lgrDB
, TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg
, StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid
, StrictTVar m (FutureBlocks blk)
varFutureBlocks :: StrictTVar m (FutureBlocks blk)
varFutureBlocks :: StrictTVar m (FutureBlocks 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
, trace :: TraceValidationEvent blk -> m ()
trace = Tracer m (TraceValidationEvent blk)
-> TraceValidationEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith
((TraceValidationEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceValidationEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap (TraceInitChainSelEvent blk -> TraceEvent blk
forall blk. TraceInitChainSelEvent blk -> TraceEvent blk
TraceInitChainSelEvent (TraceInitChainSelEvent blk -> TraceEvent blk)
-> (TraceValidationEvent blk -> TraceInitChainSelEvent blk)
-> TraceValidationEvent blk
-> TraceEvent blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TraceValidationEvent blk -> TraceInitChainSelEvent blk
forall blk. TraceValidationEvent blk -> TraceInitChainSelEvent blk
InitChainSelValidation) Tracer m (TraceEvent blk)
tracer)
}
addBlockAsync
:: forall m blk. (IOLike m, HasHeader blk)
=> ChainDbEnv m blk
-> blk
-> m (AddBlockPromise m blk)
addBlockAsync :: ChainDbEnv m blk -> 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 -> blk -> m (AddBlockPromise m blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader blk) =>
Tracer m (TraceAddBlockEvent blk)
-> BlocksToAdd m blk -> blk -> m (AddBlockPromise m blk)
addBlockToAdd ((TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent 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)
StrictTVar m (m ())
StrictTVar m (FutureBlocks blk)
StrictTVar m (Map ReaderKey (ReaderHandle m blk))
StrictTVar m (Map IteratorKey (m ()))
StrictTVar m (AnchoredFragment (Header blk))
StrictTVar m (WithFingerprint (InvalidBlocks blk))
StrictTVar m ReaderKey
StrictTVar m IteratorKey
DiffTime
TopLevelConfig blk
StrictMVar m ()
VolatileDB m blk
ChunkInfo
ResourceRegistry m
ImmutableDB m blk
LgrDB m blk
CheckInFuture m blk
BlocksToAdd m blk
blk -> Bool
cdbFutureBlocks :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (FutureBlocks 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 ()
cdbNextReaderKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m ReaderKey
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
cdbReaders :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (Map ReaderKey (ReaderHandle m blk))
cdbIterators :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (Map IteratorKey (m ()))
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 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 ()
cdbNextReaderKey :: StrictTVar m ReaderKey
cdbNextIteratorKey :: StrictTVar m IteratorKey
cdbInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: TopLevelConfig blk
cdbReaders :: StrictTVar m (Map ReaderKey (ReaderHandle m blk))
cdbIterators :: StrictTVar m (Map IteratorKey (m ()))
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)
varBlockProcessed :: forall (m :: * -> *) blk.
BlockToAdd m blk -> StrictTMVar m (Point blk)
varBlockWrittenToDisk :: forall (m :: * -> *) blk. BlockToAdd m blk -> StrictTMVar m Bool
varBlockProcessed :: StrictTMVar m (Point blk)
varBlockWrittenToDisk :: StrictTMVar m Bool
.. } = 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
TraceAddBlockEvent blk -> m ()
trace (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
TraceAddBlockEvent blk -> m ()
trace (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
TraceAddBlockEvent blk -> m ()
trace (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
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
VolatileDB m blk -> blk -> m ()
forall (m :: * -> *) blk.
VolatileDB m blk -> HasCallStack => blk -> m ()
VolatileDB.putBlock VolatileDB m blk
cdbVolatileDB blk
b
TraceAddBlockEvent blk -> m ()
trace (TraceAddBlockEvent blk -> m ()) -> TraceAddBlockEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ RealPoint blk -> BlockNo -> IsEBB -> TraceAddBlockEvent blk
forall blk.
RealPoint blk -> BlockNo -> IsEBB -> 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
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 -> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader blk, LedgerSupportsProtocol blk,
InspectLedger blk, HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk -> BlockCache blk -> Header blk -> m (Point blk)
chainSelectionForBlock ChainDbEnv m blk
cdb BlockCache blk
blockCache Header blk
hdr
Point blk -> m ()
deliverProcessed Point blk
newTip
where
trace :: TraceAddBlockEvent blk -> m ()
trace :: TraceAddBlockEvent blk -> m ()
trace = Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith ((TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent 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
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)
StrictTVar m (m ())
StrictTVar m (FutureBlocks blk)
StrictTVar m (Map ReaderKey (ReaderHandle m blk))
StrictTVar m (Map IteratorKey (m ()))
StrictTVar m (AnchoredFragment (Header blk))
StrictTVar m (WithFingerprint (InvalidBlocks blk))
StrictTVar m ReaderKey
StrictTVar m IteratorKey
DiffTime
TopLevelConfig blk
StrictMVar m ()
VolatileDB m blk
ChunkInfo
ResourceRegistry m
ImmutableDB m blk
LgrDB m blk
CheckInFuture m blk
BlocksToAdd m blk
blk -> Bool
cdbFutureBlocks :: StrictTVar m (FutureBlocks 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 ()
cdbNextReaderKey :: StrictTVar m ReaderKey
cdbNextIteratorKey :: StrictTVar m IteratorKey
cdbInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: TopLevelConfig blk
cdbReaders :: StrictTVar m (Map ReaderKey (ReaderHandle m blk))
cdbIterators :: StrictTVar m (Map IteratorKey (m ()))
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 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 ()
cdbNextReaderKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m ReaderKey
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
cdbReaders :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (Map ReaderKey (ReaderHandle m blk))
cdbIterators :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (Map IteratorKey (m ()))
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]
futureBlockHeaders <- STM m [Header blk] -> m [Header blk]
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m [Header blk] -> m [Header blk])
-> STM m [Header blk] -> m [Header blk]
forall a b. (a -> b) -> a -> b
$ do
FutureBlocks blk
futureBlocks <- StrictTVar m (FutureBlocks blk) -> STM m (FutureBlocks blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (FutureBlocks blk)
cdbFutureBlocks
StrictTVar m (FutureBlocks blk) -> FutureBlocks blk -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (FutureBlocks blk)
cdbFutureBlocks FutureBlocks blk
forall k a. Map k a
Map.empty
[Header blk] -> STM m [Header blk]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Header blk] -> STM m [Header blk])
-> [Header blk] -> STM m [Header blk]
forall a b. (a -> b) -> a -> b
$ FutureBlocks blk -> [Header blk]
forall k a. Map k a -> [a]
Map.elems FutureBlocks blk
futureBlocks
[Header blk] -> (Header blk -> m (Point blk)) -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Header blk]
futureBlockHeaders ((Header blk -> m (Point blk)) -> m ())
-> (Header blk -> m (Point blk)) -> m ()
forall a b. (a -> b) -> a -> b
$ \Header blk
hdr -> do
TraceAddBlockEvent blk -> m ()
trace (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 -> m (Point blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader blk, LedgerSupportsProtocol blk,
InspectLedger blk, HasHardForkHistory blk, HasCallStack) =>
ChainDbEnv m blk -> BlockCache blk -> Header blk -> m (Point blk)
chainSelectionForBlock ChainDbEnv m blk
cdb BlockCache blk
blockCache Header blk
hdr
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
trace :: TraceAddBlockEvent blk -> m ()
trace = Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith ((TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent 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
-> m (Point blk)
chainSelectionForBlock :: ChainDbEnv m blk -> BlockCache blk -> Header blk -> m (Point blk)
chainSelectionForBlock cdb :: ChainDbEnv m blk
cdb@CDB{Tracer m (LedgerDB' blk)
Tracer m (TraceEvent blk)
StrictTVar m (m ())
StrictTVar m (FutureBlocks blk)
StrictTVar m (Map ReaderKey (ReaderHandle m blk))
StrictTVar m (Map IteratorKey (m ()))
StrictTVar m (AnchoredFragment (Header blk))
StrictTVar m (WithFingerprint (InvalidBlocks blk))
StrictTVar m ReaderKey
StrictTVar m IteratorKey
DiffTime
TopLevelConfig blk
StrictMVar m ()
VolatileDB m blk
ChunkInfo
ResourceRegistry m
ImmutableDB m blk
LgrDB m blk
CheckInFuture m blk
BlocksToAdd m blk
blk -> Bool
cdbFutureBlocks :: StrictTVar m (FutureBlocks 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 ()
cdbNextReaderKey :: StrictTVar m ReaderKey
cdbNextIteratorKey :: StrictTVar m IteratorKey
cdbInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbTopLevelConfig :: TopLevelConfig blk
cdbReaders :: StrictTVar m (Map ReaderKey (ReaderHandle m blk))
cdbIterators :: StrictTVar m (Map IteratorKey (m ()))
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 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 ()
cdbNextReaderKey :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m ReaderKey
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
cdbReaders :: forall (m :: * -> *) blk.
ChainDbEnv m blk
-> StrictTVar m (Map ReaderKey (ReaderHandle m blk))
cdbIterators :: forall (m :: * -> *) blk.
ChainDbEnv m blk -> StrictTVar m (Map IteratorKey (m ()))
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 = 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 block. HasHeader block => AnchoredFragment block -> 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
TraceAddBlockEvent blk -> m ()
trace (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
TraceAddBlockEvent blk -> m ()
trace (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
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
TraceAddBlockEvent blk -> m ()
trace (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, HasCallStack) =>
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
TraceAddBlockEvent blk -> m ()
trace (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
TraceAddBlockEvent blk -> m ()
trace (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
trace :: TraceAddBlockEvent blk -> m ()
trace :: TraceAddBlockEvent blk -> m ()
trace = Tracer m (TraceAddBlockEvent blk) -> TraceAddBlockEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith ((TraceAddBlockEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceAddBlockEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap TraceAddBlockEvent blk -> TraceEvent blk
forall blk. TraceAddBlockEvent blk -> TraceEvent blk
TraceAddBlockEvent 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
-> (TraceValidationEvent blk -> m ())
-> TopLevelConfig blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
-> StrictTVar m (FutureBlocks blk)
-> CheckInFuture m blk
-> BlockCache blk
-> ChainAndLedger blk
-> ChainSelEnv m blk
ChainSelEnv
{ lgrDB :: LgrDB m blk
lgrDB = LgrDB m blk
cdbLgrDB
, cfg :: TopLevelConfig blk
cfg = TopLevelConfig blk
cdbTopLevelConfig
, varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid = StrictTVar m (WithFingerprint (InvalidBlocks blk))
cdbInvalid
, varFutureBlocks :: StrictTVar m (FutureBlocks blk)
varFutureBlocks = StrictTVar m (FutureBlocks blk)
cdbFutureBlocks
, futureCheck :: CheckInFuture m blk
futureCheck = CheckInFuture m blk
cdbCheckInFuture
, blockCache :: BlockCache blk
blockCache = BlockCache blk
blockCache
, curChainAndLedger :: ChainAndLedger blk
curChainAndLedger = ChainAndLedger blk
curChainAndLedger
, trace :: TraceValidationEvent blk -> m ()
trace =
Tracer m (TraceValidationEvent blk)
-> TraceValidationEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith ((TraceValidationEvent blk -> TraceEvent blk)
-> Tracer m (TraceEvent blk) -> Tracer m (TraceValidationEvent blk)
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap (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) Tracer m (TraceEvent blk)
cdbTracer)
}
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.candidates 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 block.
HasHeader block =>
Anchor block -> [block] -> AnchoredFragment block
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
(FutureBlocks blk) m (NonEmpty (AnchoredFragment (Header blk)))
-> FutureBlocks blk
-> m (NonEmpty (AnchoredFragment (Header blk))))
-> FutureBlocks blk
-> StateT
(FutureBlocks blk) m (NonEmpty (AnchoredFragment (Header blk)))
-> m (NonEmpty (AnchoredFragment (Header blk)))
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT
(FutureBlocks blk) m (NonEmpty (AnchoredFragment (Header blk)))
-> FutureBlocks blk -> m (NonEmpty (AnchoredFragment (Header blk)))
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT FutureBlocks blk
forall k a. Map k a
Map.empty (StateT
(FutureBlocks blk) m (NonEmpty (AnchoredFragment (Header blk)))
-> m (NonEmpty (AnchoredFragment (Header blk))))
-> StateT
(FutureBlocks 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 (FutureBlocks blk) m (AnchoredFragment (Header blk)))
-> StateT
(FutureBlocks 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 (FutureBlocks blk) m (AnchoredFragment (Header blk)))
-> StateT
(FutureBlocks blk) m (NonEmpty (AnchoredFragment (Header blk))))
-> (NonEmpty (HeaderHash blk)
-> StateT (FutureBlocks blk) m (AnchoredFragment (Header blk)))
-> StateT
(FutureBlocks blk) m (NonEmpty (AnchoredFragment (Header blk)))
forall a b. (a -> b) -> a -> b
$ \NonEmpty (HeaderHash blk)
hashes -> do
[Header blk]
hdrs <- (HeaderHash blk -> StateT (FutureBlocks blk) m (Header blk))
-> [HeaderHash blk] -> StateT (FutureBlocks 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 (FutureBlocks 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 (FutureBlocks blk) m [Header blk])
-> [HeaderHash blk] -> StateT (FutureBlocks 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 (FutureBlocks blk) m (AnchoredFragment (Header blk))
forall (m :: * -> *) a. Monad m => a -> m a
return (AnchoredFragment (Header blk)
-> StateT (FutureBlocks blk) m (AnchoredFragment (Header blk)))
-> AnchoredFragment (Header blk)
-> StateT (FutureBlocks blk) m (AnchoredFragment (Header blk))
forall a b. (a -> b) -> a -> b
$ Anchor (Header blk)
-> [Header blk] -> AnchoredFragment (Header blk)
forall block.
HasHeader block =>
Anchor block -> [block] -> AnchoredFragment block
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 ( TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
BlockSupportsProtocol blk =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cdbTopLevelConfig 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)
-> ([LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk)
-> m (Point blk)
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ([LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk)
-> m (Point blk)
switchTo ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff [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
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 block.
HasHeader block =>
AnchoredFragment block -> Anchor block
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 :: FutureBlocks blk
initCache = HeaderHash blk -> Header blk -> FutureBlocks 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
( TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
BlockSupportsProtocol blk =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cdbTopLevelConfig 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 (FutureBlocks blk) m [ChainDiff (Header blk)]
-> FutureBlocks blk -> m [ChainDiff (Header blk)])
-> FutureBlocks blk
-> StateT (FutureBlocks blk) m [ChainDiff (Header blk)]
-> m [ChainDiff (Header blk)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT (FutureBlocks blk) m [ChainDiff (Header blk)]
-> FutureBlocks blk -> m [ChainDiff (Header blk)]
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT FutureBlocks blk
initCache
(StateT (FutureBlocks blk) m [ChainDiff (Header blk)]
-> m [ChainDiff (Header blk)])
-> (ChainDiff (HeaderFields blk)
-> StateT (FutureBlocks 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 (FutureBlocks blk) m (ChainDiff (Header blk)))
-> [ChainDiff (HeaderFields blk)]
-> StateT (FutureBlocks 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 (FutureBlocks blk) m (ChainDiff (Header blk))
translateToHeaders
([ChainDiff (HeaderFields blk)]
-> StateT (FutureBlocks blk) m [ChainDiff (Header blk)])
-> (ChainDiff (HeaderFields blk) -> [ChainDiff (HeaderFields blk)])
-> ChainDiff (HeaderFields blk)
-> StateT (FutureBlocks 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)
-> ([LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk)
-> m (Point blk)
ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ([LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk)
-> m (Point blk)
switchTo ValidatedChainDiff (Header blk) (LedgerDB' blk)
validatedChainDiff [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
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 r. LedgerDB l r -> 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)
-> ( [LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
)
-> m (Point blk)
switchTo :: ValidatedChainDiff (Header blk) (LedgerDB' blk)
-> ([LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk)
-> m (Point blk)
switchTo (ValidatedChainDiff ChainDiff (Header blk)
chainDiff LedgerDB' blk
newLedger) [LedgerEvent blk]
-> NewTipInfo blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> TraceAddBlockEvent blk
mkTraceEvent = do
(AnchoredFragment (Header blk)
curChain, AnchoredFragment (Header blk)
newChain, [LedgerEvent blk]
events) <- STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk])
-> m (AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk])
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk])
-> m (AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk]))
-> STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk])
-> m (AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent 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])
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 r. LedgerDB l r -> 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 r. LedgerDB l r -> l
LgrDB.ledgerDbCurrent LedgerDB' blk
newLedger)
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
[ReaderHandle m blk]
readerHandles <- Map ReaderKey (ReaderHandle m blk) -> [ReaderHandle m blk]
forall k a. Map k a -> [a]
Map.elems (Map ReaderKey (ReaderHandle m blk) -> [ReaderHandle m blk])
-> STM m (Map ReaderKey (ReaderHandle m blk))
-> STM m [ReaderHandle m blk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (Map ReaderKey (ReaderHandle m blk))
-> STM m (Map ReaderKey (ReaderHandle m blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (Map ReaderKey (ReaderHandle m blk))
cdbReaders
[ReaderHandle m blk]
-> (ReaderHandle m blk -> STM m ()) -> STM m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [ReaderHandle m blk]
readerHandles ((ReaderHandle m blk -> STM m ()) -> STM m ())
-> (ReaderHandle m blk -> STM m ()) -> STM m ()
forall a b. (a -> b) -> a -> b
$ \ReaderHandle m blk
readerHandle ->
ReaderHandle m blk
-> Point blk -> AnchoredFragment (Header blk) -> STM m ()
forall (m :: * -> *) blk.
ReaderHandle m blk
-> Point blk -> AnchoredFragment (Header blk) -> STM m ()
rhSwitchFork ReaderHandle m blk
readerHandle Point blk
ipoint AnchoredFragment (Header blk)
newChain
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk])
-> STM
m
(AnchoredFragment (Header blk), AnchoredFragment (Header blk),
[LedgerEvent blk])
forall (m :: * -> *) a. Monad m => a -> m a
return (AnchoredFragment (Header blk)
curChain, AnchoredFragment (Header blk)
newChain, [LedgerEvent blk]
events)
TraceAddBlockEvent blk -> m ()
trace (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
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
translateToHeaders
:: ChainDiff (HeaderFields blk)
-> StateT (Map (HeaderHash blk) (Header blk))
m
(ChainDiff (Header blk))
translateToHeaders :: ChainDiff (HeaderFields blk)
-> StateT (FutureBlocks blk) m (ChainDiff (Header blk))
translateToHeaders =
(HeaderFields blk -> StateT (FutureBlocks blk) m (Header blk))
-> ChainDiff (HeaderFields blk)
-> StateT (FutureBlocks 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 (FutureBlocks 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 (FutureBlocks blk) m (Header blk))
-> (HeaderFields blk -> HeaderHash blk)
-> HeaderFields blk
-> StateT (FutureBlocks 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 -> TraceValidationEvent blk -> m ()
trace :: TraceValidationEvent blk -> m ()
, ChainSelEnv m blk -> TopLevelConfig blk
cfg :: TopLevelConfig blk
, ChainSelEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
, ChainSelEnv m blk -> StrictTVar m (FutureBlocks blk)
varFutureBlocks :: StrictTVar m (FutureBlocks 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
}
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 (TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
BlockSupportsProtocol blk =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cfg 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 { TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg :: forall (m :: * -> *) blk. ChainSelEnv m blk -> TopLevelConfig blk
cfg, ChainAndLedger blk
curChainAndLedger :: ChainAndLedger blk
curChainAndLedger :: forall (m :: * -> *) blk. ChainSelEnv m blk -> ChainAndLedger blk
curChainAndLedger, StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid :: forall (m :: * -> *) blk.
ChainSelEnv m blk
-> StrictTVar m (WithFingerprint (InvalidBlocks blk))
varInvalid, StrictTVar m (FutureBlocks blk)
varFutureBlocks :: StrictTVar m (FutureBlocks blk)
varFutureBlocks :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (FutureBlocks blk)
varFutureBlocks } =
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 (TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Ordering
forall blk.
(BlockSupportsProtocol blk, HasCallStack) =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Ordering
compareAnchoredCandidates TopLevelConfig blk
cfg) (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) =
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 -> 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
[ChainDiff (Header blk)]
candidates1 <- [ChainDiff (Header blk)] -> m [ChainDiff (Header blk)]
truncateRejectedBlocks [ChainDiff (Header blk)]
candidates0
let candidates2 :: [ChainDiff (Header blk)]
candidates2
| TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
BlockSupportsProtocol blk =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cfg 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)
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 blk
futureBlocks) <-
STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks blk)
-> m (WithFingerprint (InvalidBlocks blk), FutureBlocks blk)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks blk)
-> m (WithFingerprint (InvalidBlocks blk), FutureBlocks blk))
-> STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks blk)
-> m (WithFingerprint (InvalidBlocks blk), FutureBlocks blk)
forall a b. (a -> b) -> a -> b
$ (,) (WithFingerprint (InvalidBlocks blk)
-> FutureBlocks blk
-> (WithFingerprint (InvalidBlocks blk), FutureBlocks blk))
-> STM m (WithFingerprint (InvalidBlocks blk))
-> STM
m
(FutureBlocks blk
-> (WithFingerprint (InvalidBlocks blk), FutureBlocks 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 blk
-> (WithFingerprint (InvalidBlocks blk), FutureBlocks blk))
-> STM m (FutureBlocks blk)
-> STM m (WithFingerprint (InvalidBlocks blk), FutureBlocks blk)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StrictTVar m (FutureBlocks blk) -> STM m (FutureBlocks blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (FutureBlocks 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 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 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 (TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
forall blk.
BlockSupportsProtocol blk =>
TopLevelConfig blk
-> AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Bool
preferAnchoredCandidate TopLevelConfig blk
cfg 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
-> [Header blk]
-> m (ValidateResult blk)
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk, HasCallStack) =>
LgrDB m blk
-> LedgerDB' blk
-> BlockCache blk
-> Word64
-> [Header blk]
-> m (ValidateResult blk)
LgrDB.validate LgrDB m blk
lgrDB LedgerDB' blk
curLedger BlockCache blk
blockCache Word64
rollback [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
TraceValidationEvent blk -> m ()
trace (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
TraceValidationEvent blk -> m ()
trace (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'))
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
TraceValidationEvent blk -> m ()
trace (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, TraceValidationEvent blk -> m ()
trace :: TraceValidationEvent blk -> m ()
trace :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> TraceValidationEvent blk -> m ()
trace, 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 } =
ChainSelEnv m blk
chainSelEnv
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 block. AnchoredFragment block -> [block]
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 blk])
forall (m :: * -> *) blk.
CheckInFuture m blk
-> ValidatedFragment (Header blk) (LedgerState blk)
-> m (AnchoredFragment (Header blk), [InFuture blk])
checkInFuture CheckInFuture m blk
futureCheck ValidatedFragment (Header blk) (LedgerState blk)
validatedSuffix m (AnchoredFragment (Header blk), [InFuture blk])
-> ((AnchoredFragment (Header blk), [InFuture 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 blk]
inFuture) -> do
let ([InFuture blk]
exceedClockSkew, [InFuture blk]
inNearFuture) =
(InFuture blk -> Bool)
-> [InFuture blk] -> ([InFuture blk], [InFuture blk])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition InFuture blk -> Bool
forall blk. InFuture blk -> Bool
InFuture.inFutureExceedsClockSkew [InFuture blk]
inFuture
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([InFuture blk] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InFuture blk]
inNearFuture) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
let futureHeaders :: [Header blk]
futureHeaders = InFuture blk -> Header blk
forall blk. InFuture blk -> Header blk
InFuture.inFutureHeader (InFuture blk -> Header blk) -> [InFuture blk] -> [Header blk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [InFuture blk]
inNearFuture
futureBlocks :: Map (HeaderHash blk) (Header blk)
futureBlocks = [(HeaderHash blk, Header blk)] -> Map (HeaderHash blk) (Header 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, Header blk
hdr) | Header blk
hdr <- [Header blk]
futureHeaders ]
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))
-> (Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk))
-> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (Map (HeaderHash blk) (Header blk))
varFutureBlocks ((Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk))
-> STM m ())
-> (Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk))
-> STM m ()
forall a b. (a -> b) -> a -> b
$ (Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk))
-> Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk)
-> Map (HeaderHash blk) (Header blk)
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map (HeaderHash blk) (Header blk)
futureBlocks
TraceValidationEvent blk -> m ()
trace (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 [Header blk]
futureHeaders
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([InFuture blk] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InFuture blk]
exceedClockSkew) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
let invalidHeaders :: [Header blk]
invalidHeaders = InFuture blk -> Header blk
forall blk. InFuture blk -> Header blk
InFuture.inFutureHeader (InFuture blk -> Header blk) -> [InFuture blk] -> [Header blk]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [InFuture 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)
TraceValidationEvent blk -> m ()
trace (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
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 { TraceValidationEvent blk -> m ()
trace :: TraceValidationEvent blk -> m ()
trace :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> TraceValidationEvent blk -> m ()
trace, 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))
varFutureBlocks :: StrictTVar m (Map (HeaderHash blk) (Header blk))
varFutureBlocks :: forall (m :: * -> *) blk.
ChainSelEnv m blk -> StrictTVar m (FutureBlocks 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 r. LedgerDB l r -> 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
| AnchoredFragment (Header blk) -> Int
forall block. HasHeader block => AnchoredFragment block -> Int
AF.length (ChainDiff (Header blk) -> AnchoredFragment (Header blk)
forall b. ChainDiff b -> AnchoredFragment b
Diff.getSuffix ChainDiff (Header blk)
chainDiff) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==
AnchoredFragment (Header blk) -> Int
forall block. HasHeader block => AnchoredFragment block -> Int
AF.length (ChainDiff (Header blk) -> AnchoredFragment (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)
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