{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-strictness #-}
module Ouroboros.Consensus.MiniProtocol.ChainSync.Client (
bracketChainSyncClient
, chainSyncClient
, ChainDbView (..)
, ConfigEnv (..)
, DynamicEnv (..)
, InternalEnv (..)
, defaultChainDbView
, ChainSyncClientException (..)
, ChainSyncClientResult (..)
, Consensus
, Our (..)
, Their (..)
, CSJConfig (..)
, CSJEnabledConfig (..)
, ChainSyncLoPBucketConfig (..)
, ChainSyncLoPBucketEnabledConfig (..)
, TraceChainSyncClientEvent (..)
, ChainSyncClientHandle (..)
, ChainSyncState (..)
, ChainSyncStateView (..)
, Jumping.noJumping
, chainSyncStateFor
, noIdling
, noLoPBucket
, viewChainSyncState
) where
import Control.Monad (join, void)
import Control.Monad.Class.MonadTimer (MonadTimer)
import Control.Monad.Except (runExcept, throwError)
import Control.Tracer
import Data.Functor ((<&>))
import Data.Kind (Type)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Maybe.Strict (StrictMaybe (..))
import Data.Proxy
import Data.Typeable
import Data.Word (Word64)
import GHC.Generics (Generic)
import GHC.Stack (HasCallStack)
import Network.TypedProtocol.Core
import NoThunks.Class (unsafeNoThunks)
import Ouroboros.Consensus.Block
import Ouroboros.Consensus.BlockchainTime (RelativeTime)
import Ouroboros.Consensus.Config
import Ouroboros.Consensus.Forecast
import Ouroboros.Consensus.HardFork.History
(PastHorizonException (PastHorizon))
import Ouroboros.Consensus.HeaderStateHistory
(HeaderStateHistory (..), HeaderStateWithTime (..),
validateHeader)
import qualified Ouroboros.Consensus.HeaderStateHistory as HeaderStateHistory
import Ouroboros.Consensus.HeaderValidation hiding (validateHeader)
import Ouroboros.Consensus.Ledger.Basics (LedgerState)
import Ouroboros.Consensus.Ledger.Extended
import Ouroboros.Consensus.Ledger.SupportsProtocol
import Ouroboros.Consensus.MiniProtocol.ChainSync.Client.HistoricityCheck
(HistoricalChainSyncMessage (..), HistoricityCheck,
HistoricityException)
import qualified Ouroboros.Consensus.MiniProtocol.ChainSync.Client.HistoricityCheck as HistoricityCheck
import qualified Ouroboros.Consensus.MiniProtocol.ChainSync.Client.InFutureCheck as InFutureCheck
import qualified Ouroboros.Consensus.MiniProtocol.ChainSync.Client.Jumping as Jumping
import Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State
import Ouroboros.Consensus.Node.GsmState (GsmState (..))
import Ouroboros.Consensus.Node.NetworkProtocolVersion
import Ouroboros.Consensus.Protocol.Abstract
import Ouroboros.Consensus.Storage.ChainDB (ChainDB)
import qualified Ouroboros.Consensus.Storage.ChainDB as ChainDB
import Ouroboros.Consensus.Util
import Ouroboros.Consensus.Util.AnchoredFragment (cross)
import Ouroboros.Consensus.Util.Assert (assertWithMsg)
import Ouroboros.Consensus.Util.EarlyExit (WithEarlyExit, exitEarly)
import qualified Ouroboros.Consensus.Util.EarlyExit as EarlyExit
import Ouroboros.Consensus.Util.IOLike hiding (handle)
import Ouroboros.Consensus.Util.LeakyBucket
(atomicallyWithMonotonicTime)
import qualified Ouroboros.Consensus.Util.LeakyBucket as LeakyBucket
import Ouroboros.Consensus.Util.STM (Fingerprint, Watcher (..),
WithFingerprint (..), withWatcher)
import Ouroboros.Network.AnchoredFragment (AnchoredFragment,
AnchoredSeq (..))
import qualified Ouroboros.Network.AnchoredFragment as AF
import qualified Ouroboros.Network.AnchoredSeq as AS
import Ouroboros.Network.Block (Tip (..), getTipBlockNo)
import Ouroboros.Network.ControlMessage (ControlMessage (..),
ControlMessageSTM)
import Ouroboros.Network.PeerSelection.PeerMetric.Type
(HeaderMetricsTracer)
import Ouroboros.Network.Protocol.ChainSync.ClientPipelined
import Ouroboros.Network.Protocol.ChainSync.PipelineDecision
type Consensus
(client :: Type -> Type -> Type -> (Type -> Type) -> Type -> Type)
blk
m
= client (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
data ChainDbView m blk = ChainDbView {
forall (m :: * -> *) blk.
ChainDbView m blk -> STM m (AnchoredFragment (Header blk))
getCurrentChain :: STM m (AnchoredFragment (Header blk))
,
:: STM m (HeaderStateHistory blk)
,
forall (m :: * -> *) blk.
ChainDbView m blk
-> Point blk -> STM m (Maybe (ExtLedgerState blk))
getPastLedger :: Point blk -> STM m (Maybe (ExtLedgerState blk))
,
forall (m :: * -> *) blk.
ChainDbView m blk
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock ::
STM m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
}
data ChainSyncLoPBucketEnabledConfig = ChainSyncLoPBucketEnabledConfig {
ChainSyncLoPBucketEnabledConfig -> Integer
csbcCapacity :: Integer,
ChainSyncLoPBucketEnabledConfig -> Rational
csbcRate :: Rational
}
data ChainSyncLoPBucketConfig
=
ChainSyncLoPBucketDisabled
|
ChainSyncLoPBucketEnabled ChainSyncLoPBucketEnabledConfig
data CSJConfig
=
CSJDisabled
|
CSJEnabled CSJEnabledConfig
newtype CSJEnabledConfig = CSJEnabledConfig {
CSJEnabledConfig -> SlotNo
csjcJumpSize :: SlotNo
}
defaultChainDbView ::
(IOLike m, LedgerSupportsProtocol blk)
=> ChainDB m blk -> ChainDbView m blk
defaultChainDbView :: forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk) =>
ChainDB m blk -> ChainDbView m blk
defaultChainDbView ChainDB m blk
chainDB = ChainDbView {
$sel:getCurrentChain:ChainDbView :: STM m (AnchoredFragment (Header blk))
getCurrentChain = ChainDB m blk -> STM m (AnchoredFragment (Header blk))
forall (m :: * -> *) blk.
ChainDB m blk -> STM m (AnchoredFragment (Header blk))
ChainDB.getCurrentChain ChainDB m blk
chainDB
, $sel:getHeaderStateHistory:ChainDbView :: STM m (HeaderStateHistory blk)
getHeaderStateHistory = ChainDB m blk -> STM m (HeaderStateHistory blk)
forall (m :: * -> *) blk.
ChainDB m blk -> STM m (HeaderStateHistory blk)
ChainDB.getHeaderStateHistory ChainDB m blk
chainDB
, $sel:getPastLedger:ChainDbView :: Point blk -> STM m (Maybe (ExtLedgerState blk))
getPastLedger = ChainDB m blk -> Point blk -> STM m (Maybe (ExtLedgerState blk))
forall (m :: * -> *) blk.
(Monad (STM m), LedgerSupportsProtocol blk) =>
ChainDB m blk -> Point blk -> STM m (Maybe (ExtLedgerState blk))
ChainDB.getPastLedger ChainDB m blk
chainDB
, $sel:getIsInvalidBlock:ChainDbView :: STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock = ChainDB m blk
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
forall (m :: * -> *) blk.
ChainDB m blk
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
ChainDB.getIsInvalidBlock ChainDB m blk
chainDB
}
newtype Their a = Their { forall a. Their a -> a
unTheir :: a }
deriving stock (Their a -> Their a -> Bool
(Their a -> Their a -> Bool)
-> (Their a -> Their a -> Bool) -> Eq (Their a)
forall a. Eq a => Their a -> Their a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Their a -> Their a -> Bool
== :: Their a -> Their a -> Bool
$c/= :: forall a. Eq a => Their a -> Their a -> Bool
/= :: Their a -> Their a -> Bool
Eq)
deriving newtype (Int -> Their a -> ShowS
[Their a] -> ShowS
Their a -> String
(Int -> Their a -> ShowS)
-> (Their a -> String) -> ([Their a] -> ShowS) -> Show (Their a)
forall a. Show a => Int -> Their a -> ShowS
forall a. Show a => [Their a] -> ShowS
forall a. Show a => Their a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Their a -> ShowS
showsPrec :: Int -> Their a -> ShowS
$cshow :: forall a. Show a => Their a -> String
show :: Their a -> String
$cshowList :: forall a. Show a => [Their a] -> ShowS
showList :: [Their a] -> ShowS
Show, Context -> Their a -> IO (Maybe ThunkInfo)
Proxy (Their a) -> String
(Context -> Their a -> IO (Maybe ThunkInfo))
-> (Context -> Their a -> IO (Maybe ThunkInfo))
-> (Proxy (Their a) -> String)
-> NoThunks (Their a)
forall a. NoThunks a => Context -> Their a -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Proxy (Their a) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: forall a. NoThunks a => Context -> Their a -> IO (Maybe ThunkInfo)
noThunks :: Context -> Their a -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall a. NoThunks a => Context -> Their a -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Their a -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall a. NoThunks a => Proxy (Their a) -> String
showTypeOf :: Proxy (Their a) -> String
NoThunks)
newtype Our a = Our { forall a. Our a -> a
unOur :: a }
deriving stock (Our a -> Our a -> Bool
(Our a -> Our a -> Bool) -> (Our a -> Our a -> Bool) -> Eq (Our a)
forall a. Eq a => Our a -> Our a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Our a -> Our a -> Bool
== :: Our a -> Our a -> Bool
$c/= :: forall a. Eq a => Our a -> Our a -> Bool
/= :: Our a -> Our a -> Bool
Eq)
deriving newtype (Int -> Our a -> ShowS
[Our a] -> ShowS
Our a -> String
(Int -> Our a -> ShowS)
-> (Our a -> String) -> ([Our a] -> ShowS) -> Show (Our a)
forall a. Show a => Int -> Our a -> ShowS
forall a. Show a => [Our a] -> ShowS
forall a. Show a => Our a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Our a -> ShowS
showsPrec :: Int -> Our a -> ShowS
$cshow :: forall a. Show a => Our a -> String
show :: Our a -> String
$cshowList :: forall a. Show a => [Our a] -> ShowS
showList :: [Our a] -> ShowS
Show, Context -> Our a -> IO (Maybe ThunkInfo)
Proxy (Our a) -> String
(Context -> Our a -> IO (Maybe ThunkInfo))
-> (Context -> Our a -> IO (Maybe ThunkInfo))
-> (Proxy (Our a) -> String)
-> NoThunks (Our a)
forall a. NoThunks a => Context -> Our a -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Proxy (Our a) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: forall a. NoThunks a => Context -> Our a -> IO (Maybe ThunkInfo)
noThunks :: Context -> Our a -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall a. NoThunks a => Context -> Our a -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Our a -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall a. NoThunks a => Proxy (Our a) -> String
showTypeOf :: Proxy (Our a) -> String
NoThunks)
viewChainSyncState ::
IOLike m =>
StrictTVar m (Map peer (ChainSyncClientHandle m blk)) ->
(ChainSyncState blk -> a) ->
STM m (Map peer a)
viewChainSyncState :: forall (m :: * -> *) peer blk a.
IOLike m =>
StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> (ChainSyncState blk -> a) -> STM m (Map peer a)
viewChainSyncState StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles ChainSyncState blk -> a
f =
(ChainSyncState blk -> a)
-> Map peer (ChainSyncState blk) -> Map peer a
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map ChainSyncState blk -> a
f (Map peer (ChainSyncState blk) -> Map peer a)
-> STM m (Map peer (ChainSyncState blk)) -> STM m (Map peer a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((ChainSyncClientHandle m blk -> STM m (ChainSyncState blk))
-> Map peer (ChainSyncClientHandle m blk)
-> STM m (Map peer (ChainSyncState blk))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Map peer a -> f (Map peer b)
traverse (StrictTVar m (ChainSyncState blk) -> STM m (ChainSyncState blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (StrictTVar m (ChainSyncState blk) -> STM m (ChainSyncState blk))
-> (ChainSyncClientHandle m blk
-> StrictTVar m (ChainSyncState blk))
-> ChainSyncClientHandle m blk
-> STM m (ChainSyncState blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainSyncClientHandle m blk -> StrictTVar m (ChainSyncState blk)
forall (m :: * -> *) blk.
ChainSyncClientHandle m blk -> StrictTVar m (ChainSyncState blk)
cschState) (Map peer (ChainSyncClientHandle m blk)
-> STM m (Map peer (ChainSyncState blk)))
-> STM m (Map peer (ChainSyncClientHandle m blk))
-> STM m (Map peer (ChainSyncState blk))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> STM m (Map peer (ChainSyncClientHandle m blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles)
chainSyncStateFor ::
Ord peer =>
IOLike m =>
StrictTVar m (Map peer (ChainSyncClientHandle m blk)) ->
peer ->
STM m (ChainSyncState blk)
chainSyncStateFor :: forall peer (m :: * -> *) blk.
(Ord peer, IOLike m) =>
StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> peer -> STM m (ChainSyncState blk)
chainSyncStateFor StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles peer
peer =
StrictTVar m (ChainSyncState blk) -> STM m (ChainSyncState blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (StrictTVar m (ChainSyncState blk) -> STM m (ChainSyncState blk))
-> (Map peer (ChainSyncClientHandle m blk)
-> StrictTVar m (ChainSyncState blk))
-> Map peer (ChainSyncClientHandle m blk)
-> STM m (ChainSyncState blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChainSyncClientHandle m blk -> StrictTVar m (ChainSyncState blk)
forall (m :: * -> *) blk.
ChainSyncClientHandle m blk -> StrictTVar m (ChainSyncState blk)
cschState (ChainSyncClientHandle m blk -> StrictTVar m (ChainSyncState blk))
-> (Map peer (ChainSyncClientHandle m blk)
-> ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk)
-> StrictTVar m (ChainSyncState blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map peer (ChainSyncClientHandle m blk)
-> peer -> ChainSyncClientHandle m blk
forall k a. Ord k => Map k a -> k -> a
Map.! peer
peer) (Map peer (ChainSyncClientHandle m blk)
-> STM m (ChainSyncState blk))
-> STM m (Map peer (ChainSyncClientHandle m blk))
-> STM m (ChainSyncState blk)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> STM m (Map peer (ChainSyncClientHandle m blk))
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles
data Idling m = Idling {
forall (m :: * -> *). Idling m -> m ()
idlingStart :: !(m ())
, forall (m :: * -> *). Idling m -> m ()
idlingStop :: !(m ())
}
deriving stock ((forall x. Idling m -> Rep (Idling m) x)
-> (forall x. Rep (Idling m) x -> Idling m) -> Generic (Idling m)
forall x. Rep (Idling m) x -> Idling m
forall x. Idling m -> Rep (Idling m) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) x. Rep (Idling m) x -> Idling m
forall (m :: * -> *) x. Idling m -> Rep (Idling m) x
$cfrom :: forall (m :: * -> *) x. Idling m -> Rep (Idling m) x
from :: forall x. Idling m -> Rep (Idling m) x
$cto :: forall (m :: * -> *) x. Rep (Idling m) x -> Idling m
to :: forall x. Rep (Idling m) x -> Idling m
Generic)
deriving anyclass instance IOLike m => NoThunks (Idling m)
noIdling :: Applicative m => Idling m
noIdling :: forall (m :: * -> *). Applicative m => Idling m
noIdling =
Idling {
$sel:idlingStart:Idling :: m ()
idlingStart = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
, $sel:idlingStop:Idling :: m ()
idlingStop = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
}
data LoPBucket m = LoPBucket {
forall (m :: * -> *). LoPBucket m -> m ()
lbPause :: !(m ())
, forall (m :: * -> *). LoPBucket m -> m ()
lbResume :: !(m ())
, forall (m :: * -> *). LoPBucket m -> m ()
lbGrantToken :: !(m ())
}
deriving stock ((forall x. LoPBucket m -> Rep (LoPBucket m) x)
-> (forall x. Rep (LoPBucket m) x -> LoPBucket m)
-> Generic (LoPBucket m)
forall x. Rep (LoPBucket m) x -> LoPBucket m
forall x. LoPBucket m -> Rep (LoPBucket m) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) x. Rep (LoPBucket m) x -> LoPBucket m
forall (m :: * -> *) x. LoPBucket m -> Rep (LoPBucket m) x
$cfrom :: forall (m :: * -> *) x. LoPBucket m -> Rep (LoPBucket m) x
from :: forall x. LoPBucket m -> Rep (LoPBucket m) x
$cto :: forall (m :: * -> *) x. Rep (LoPBucket m) x -> LoPBucket m
to :: forall x. Rep (LoPBucket m) x -> LoPBucket m
Generic)
deriving anyclass instance IOLike m => NoThunks (LoPBucket m)
noLoPBucket :: Applicative m => LoPBucket m
noLoPBucket :: forall (m :: * -> *). Applicative m => LoPBucket m
noLoPBucket =
LoPBucket {
$sel:lbPause:LoPBucket :: m ()
lbPause = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
, $sel:lbResume:LoPBucket :: m ()
lbResume = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
, $sel:lbGrantToken:LoPBucket :: m ()
lbGrantToken = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
}
data ChainSyncStateView m blk = ChainSyncStateView {
forall (m :: * -> *) blk.
ChainSyncStateView m blk
-> AnchoredFragment (Header blk) -> STM m ()
csvSetCandidate :: !(AnchoredFragment (Header blk) -> STM m ())
, forall (m :: * -> *) blk.
ChainSyncStateView m blk -> WithOrigin SlotNo -> STM m ()
csvSetLatestSlot :: !(WithOrigin SlotNo -> STM m ())
, forall (m :: * -> *) blk. ChainSyncStateView m blk -> Idling m
csvIdling :: !(Idling m)
, forall (m :: * -> *) blk. ChainSyncStateView m blk -> LoPBucket m
csvLoPBucket :: !(LoPBucket m)
, forall (m :: * -> *) blk. ChainSyncStateView m blk -> Jumping m blk
csvJumping :: !(Jumping.Jumping m blk)
}
deriving stock ((forall x.
ChainSyncStateView m blk -> Rep (ChainSyncStateView m blk) x)
-> (forall x.
Rep (ChainSyncStateView m blk) x -> ChainSyncStateView m blk)
-> Generic (ChainSyncStateView m blk)
forall x.
Rep (ChainSyncStateView m blk) x -> ChainSyncStateView m blk
forall x.
ChainSyncStateView m blk -> Rep (ChainSyncStateView m blk) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) blk x.
Rep (ChainSyncStateView m blk) x -> ChainSyncStateView m blk
forall (m :: * -> *) blk x.
ChainSyncStateView m blk -> Rep (ChainSyncStateView m blk) x
$cfrom :: forall (m :: * -> *) blk x.
ChainSyncStateView m blk -> Rep (ChainSyncStateView m blk) x
from :: forall x.
ChainSyncStateView m blk -> Rep (ChainSyncStateView m blk) x
$cto :: forall (m :: * -> *) blk x.
Rep (ChainSyncStateView m blk) x -> ChainSyncStateView m blk
to :: forall x.
Rep (ChainSyncStateView m blk) x -> ChainSyncStateView m blk
Generic)
deriving anyclass instance (
IOLike m,
HasHeader blk,
NoThunks (Header blk)
) => NoThunks (ChainSyncStateView m blk)
bracketChainSyncClient ::
forall m peer blk a.
( IOLike m
, Ord peer
, LedgerSupportsProtocol blk
, MonadTimer m
)
=> Tracer m (TraceChainSyncClientEvent blk)
-> ChainDbView m blk
-> StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> STM m GsmState
-> peer
-> NodeToNodeVersion
-> ChainSyncLoPBucketConfig
-> CSJConfig
-> DiffusionPipeliningSupport
-> (ChainSyncStateView m blk -> m a)
-> m a
bracketChainSyncClient :: forall (m :: * -> *) peer blk a.
(IOLike m, Ord peer, LedgerSupportsProtocol blk, MonadTimer m) =>
Tracer m (TraceChainSyncClientEvent blk)
-> ChainDbView m blk
-> StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> STM m GsmState
-> peer
-> NodeToNodeVersion
-> ChainSyncLoPBucketConfig
-> CSJConfig
-> DiffusionPipeliningSupport
-> (ChainSyncStateView m blk -> m a)
-> m a
bracketChainSyncClient
Tracer m (TraceChainSyncClientEvent blk)
tracer
ChainDbView { STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
$sel:getIsInvalidBlock:ChainDbView :: forall (m :: * -> *) blk.
ChainDbView m blk
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock :: STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock }
StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles
STM m GsmState
getGsmState
peer
peer
NodeToNodeVersion
version
ChainSyncLoPBucketConfig
csBucketConfig
CSJConfig
csjConfig
DiffusionPipeliningSupport
pipelining
ChainSyncStateView m blk -> m a
body
=
(Handlers m -> m a) -> m a
forall (m :: * -> *) a.
(MonadDelay m, MonadAsync m, MonadFork m, MonadMask m,
MonadTimer m, NoThunks (m ())) =>
(Handlers m -> m a) -> m a
LeakyBucket.execAgainstBucket'
((Handlers m -> m a) -> m a) -> (Handlers m -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Handlers m
lopBucket ->
m (StrictTVar m (ChainSyncState blk))
mkChainSyncClientHandleState m (StrictTVar m (ChainSyncState blk))
-> (StrictTVar m (ChainSyncState blk) -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \StrictTVar m (ChainSyncState blk)
csHandleState ->
Handlers m
-> StrictTVar m (ChainSyncState blk)
-> CSJConfig
-> (Jumping m blk -> m a)
-> m a
withCSJCallbacks Handlers m
lopBucket StrictTVar m (ChainSyncState blk)
csHandleState CSJConfig
csjConfig ((Jumping m blk -> m a) -> m a) -> (Jumping m blk -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Jumping m blk
csjCallbacks ->
String
-> Watcher
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
Fingerprint
-> m a
-> m a
forall (m :: * -> *) a fp r.
(IOLike m, Eq fp, HasCallStack) =>
String -> Watcher m a fp -> m r -> m r
withWatcher
String
"ChainSync.Client.rejectInvalidBlocks"
(StrictTVar m (ChainSyncState blk)
-> Watcher
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
Fingerprint
invalidBlockWatcher StrictTVar m (ChainSyncState blk)
csHandleState)
(m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ ChainSyncStateView m blk -> m a
body ChainSyncStateView {
$sel:csvSetCandidate:ChainSyncStateView :: AnchoredFragment (Header blk) -> STM m ()
csvSetCandidate =
StrictTVar m (ChainSyncState blk)
-> (ChainSyncState blk -> ChainSyncState blk) -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (ChainSyncState blk)
csHandleState ((ChainSyncState blk -> ChainSyncState blk) -> STM m ())
-> (AnchoredFragment (Header blk)
-> ChainSyncState blk -> ChainSyncState blk)
-> AnchoredFragment (Header blk)
-> STM m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \ AnchoredFragment (Header blk)
c ChainSyncState blk
s -> ChainSyncState blk
s {csCandidate = c}
, $sel:csvSetLatestSlot:ChainSyncStateView :: WithOrigin SlotNo -> STM m ()
csvSetLatestSlot =
StrictTVar m (ChainSyncState blk)
-> (ChainSyncState blk -> ChainSyncState blk) -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (ChainSyncState blk)
csHandleState ((ChainSyncState blk -> ChainSyncState blk) -> STM m ())
-> (WithOrigin SlotNo -> ChainSyncState blk -> ChainSyncState blk)
-> WithOrigin SlotNo
-> STM m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \ WithOrigin SlotNo
ls ChainSyncState blk
s -> ChainSyncState blk
s {csLatestSlot = SJust ls}
, $sel:csvIdling:ChainSyncStateView :: Idling m
csvIdling = Idling {
$sel:idlingStart:Idling :: m ()
idlingStart = STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
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 (ChainSyncState blk)
-> (ChainSyncState blk -> ChainSyncState blk) -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (ChainSyncState blk)
csHandleState ((ChainSyncState blk -> ChainSyncState blk) -> STM m ())
-> (ChainSyncState blk -> ChainSyncState blk) -> STM m ()
forall a b. (a -> b) -> a -> b
$ \ ChainSyncState blk
s -> ChainSyncState blk
s {csIdling = True}
, $sel:idlingStop:Idling :: m ()
idlingStop = STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
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 (ChainSyncState blk)
-> (ChainSyncState blk -> ChainSyncState blk) -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (ChainSyncState blk)
csHandleState ((ChainSyncState blk -> ChainSyncState blk) -> STM m ())
-> (ChainSyncState blk -> ChainSyncState blk) -> STM m ()
forall a b. (a -> b) -> a -> b
$ \ ChainSyncState blk
s -> ChainSyncState blk
s {csIdling = False}
}
, $sel:csvLoPBucket:ChainSyncStateView :: LoPBucket m
csvLoPBucket = LoPBucket {
$sel:lbPause:LoPBucket :: m ()
lbPause = Handlers m -> Bool -> m ()
forall (m :: * -> *).
(MonadMonotonicTime m, MonadSTM m) =>
Handlers m -> Bool -> m ()
LeakyBucket.setPaused' Handlers m
lopBucket Bool
True
, $sel:lbResume:LoPBucket :: m ()
lbResume = Handlers m -> Bool -> m ()
forall (m :: * -> *).
(MonadMonotonicTime m, MonadSTM m) =>
Handlers m -> Bool -> m ()
LeakyBucket.setPaused' Handlers m
lopBucket Bool
False
, $sel:lbGrantToken:LoPBucket :: m ()
lbGrantToken = m FillResult -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m FillResult -> m ()) -> m FillResult -> m ()
forall a b. (a -> b) -> a -> b
$ Handlers m -> Rational -> m FillResult
forall (m :: * -> *).
(MonadMonotonicTime m, MonadSTM m) =>
Handlers m -> Rational -> m FillResult
LeakyBucket.fill' Handlers m
lopBucket Rational
1
}
, $sel:csvJumping:ChainSyncStateView :: Jumping m blk
csvJumping = Jumping m blk
csjCallbacks
}
where
mkChainSyncClientHandleState :: m (StrictTVar m (ChainSyncState blk))
mkChainSyncClientHandleState =
ChainSyncState blk -> m (StrictTVar m (ChainSyncState blk))
forall (m :: * -> *) a.
(HasCallStack, MonadSTM m, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO ChainSyncState {
csCandidate :: AnchoredFragment (Header blk)
csCandidate = Anchor (Header blk) -> AnchoredFragment (Header blk)
forall v a b. Anchorable v a b => a -> AnchoredSeq v a b
AF.Empty Anchor (Header blk)
forall block. Anchor block
AF.AnchorGenesis
, csLatestSlot :: StrictMaybe (WithOrigin SlotNo)
csLatestSlot = StrictMaybe (WithOrigin SlotNo)
forall a. StrictMaybe a
SNothing
, csIdling :: Bool
csIdling = Bool
False
}
withCSJCallbacks ::
LeakyBucket.Handlers m ->
StrictTVar m (ChainSyncState blk) ->
CSJConfig ->
(Jumping.Jumping m blk -> m a) ->
m a
withCSJCallbacks :: Handlers m
-> StrictTVar m (ChainSyncState blk)
-> CSJConfig
-> (Jumping m blk -> m a)
-> m a
withCSJCallbacks Handlers m
lopBucket StrictTVar m (ChainSyncState blk)
cschState CSJConfig
CSJDisabled Jumping m blk -> m a
f = do
ThreadId m
tid <- m (ThreadId m)
forall (m :: * -> *). MonadThread m => m (ThreadId m)
myThreadId
StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo <- Maybe (JumpInfo blk) -> m (StrictTVar m (Maybe (JumpInfo blk)))
forall (m :: * -> *) a.
(HasCallStack, MonadSTM m, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO Maybe (JumpInfo blk)
forall a. Maybe a
Nothing
StrictTVar m (ChainSyncJumpingState m blk)
cschJumping <- ChainSyncJumpingState m blk
-> m (StrictTVar m (ChainSyncJumpingState m blk))
forall (m :: * -> *) a.
(HasCallStack, MonadSTM m, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO (DisengagedInitState -> ChainSyncJumpingState m blk
forall (m :: * -> *) blk.
DisengagedInitState -> ChainSyncJumpingState m blk
Disengaged DisengagedInitState
DisengagedDone)
let handle :: ChainSyncClientHandle m blk
handle = ChainSyncClientHandle {
cschGDDKill :: m ()
cschGDDKill = ThreadId m -> ChainSyncClientException -> m ()
forall e. Exception e => ThreadId m -> e -> m ()
forall (m :: * -> *) e.
(MonadFork m, Exception e) =>
ThreadId m -> e -> m ()
throwTo ThreadId m
tid ChainSyncClientException
DensityTooLow
, cschOnGsmStateChanged :: GsmState -> Time -> STM m ()
cschOnGsmStateChanged = Handlers m -> GsmState -> Time -> STM m ()
updateLopBucketConfig Handlers m
lopBucket
, StrictTVar m (ChainSyncState blk)
cschState :: StrictTVar m (ChainSyncState blk)
cschState :: StrictTVar m (ChainSyncState blk)
cschState
, StrictTVar m (ChainSyncJumpingState m blk)
cschJumping :: StrictTVar m (ChainSyncJumpingState m blk)
cschJumping :: StrictTVar m (ChainSyncJumpingState m blk)
cschJumping
, StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo :: StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo :: StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo
}
insertHandle :: m ()
insertHandle = (Time -> STM m ()) -> m ()
forall (m :: * -> *) b.
(MonadMonotonicTime m, MonadSTM m) =>
(Time -> STM m b) -> m b
atomicallyWithMonotonicTime ((Time -> STM m ()) -> m ()) -> (Time -> STM m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Time
time -> do
GsmState
initialGsmState <- STM m GsmState
getGsmState
Handlers m -> GsmState -> Time -> STM m ()
updateLopBucketConfig Handlers m
lopBucket GsmState
initialGsmState Time
time
StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> (Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk))
-> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles ((Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk))
-> STM m ())
-> (Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk))
-> STM m ()
forall a b. (a -> b) -> a -> b
$ peer
-> ChainSyncClientHandle m blk
-> Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert peer
peer ChainSyncClientHandle m blk
handle
deleteHandle :: m ()
deleteHandle = STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
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 peer (ChainSyncClientHandle m blk))
-> (Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk))
-> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles ((Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk))
-> STM m ())
-> (Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk))
-> STM m ()
forall a b. (a -> b) -> a -> b
$ peer
-> Map peer (ChainSyncClientHandle m blk)
-> Map peer (ChainSyncClientHandle m blk)
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete peer
peer
m () -> m () -> m a -> m a
forall a b c. m a -> m b -> m c -> m c
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> m b -> m c -> m c
bracket_ m ()
insertHandle m ()
deleteHandle (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ Jumping m blk -> m a
f Jumping m blk
forall (m :: * -> *) blk. MonadSTM m => Jumping m blk
Jumping.noJumping
withCSJCallbacks Handlers m
lopBucket StrictTVar m (ChainSyncState blk)
csHandleState (CSJEnabled CSJEnabledConfig
csjEnabledConfig) Jumping m blk -> m a
f =
m (PeerContext m peer blk)
-> (PeerContext m peer blk -> m ())
-> (PeerContext m peer blk -> m a)
-> m a
forall a b c. m a -> (a -> m b) -> (a -> m c) -> m c
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket (Handlers m
-> StrictTVar m (ChainSyncState blk)
-> CSJEnabledConfig
-> m (PeerContext m peer blk)
acquireContext Handlers m
lopBucket StrictTVar m (ChainSyncState blk)
csHandleState CSJEnabledConfig
csjEnabledConfig) PeerContext m peer blk -> m ()
releaseContext ((PeerContext m peer blk -> m a) -> m a)
-> (PeerContext m peer blk -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \PeerContext m peer blk
peerContext ->
Jumping m blk -> m a
f (Jumping m blk -> m a) -> Jumping m blk -> m a
forall a b. (a -> b) -> a -> b
$ PeerContext m peer blk -> Jumping m blk
forall (m :: * -> *) peer blk.
(MonadSTM m, Eq peer, LedgerSupportsProtocol blk) =>
PeerContext m peer blk -> Jumping m blk
Jumping.mkJumping PeerContext m peer blk
peerContext
acquireContext :: Handlers m
-> StrictTVar m (ChainSyncState blk)
-> CSJEnabledConfig
-> m (PeerContext m peer blk)
acquireContext Handlers m
lopBucket StrictTVar m (ChainSyncState blk)
cschState (CSJEnabledConfig SlotNo
jumpSize) = do
ThreadId m
tid <- m (ThreadId m)
forall (m :: * -> *). MonadThread m => m (ThreadId m)
myThreadId
(Time -> STM m (PeerContext m peer blk))
-> m (PeerContext m peer blk)
forall (m :: * -> *) b.
(MonadMonotonicTime m, MonadSTM m) =>
(Time -> STM m b) -> m b
atomicallyWithMonotonicTime ((Time -> STM m (PeerContext m peer blk))
-> m (PeerContext m peer blk))
-> (Time -> STM m (PeerContext m peer blk))
-> m (PeerContext m peer blk)
forall a b. (a -> b) -> a -> b
$ \Time
time -> do
GsmState
initialGsmState <- STM m GsmState
getGsmState
Handlers m -> GsmState -> Time -> STM m ()
updateLopBucketConfig Handlers m
lopBucket GsmState
initialGsmState Time
time
StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo <- Maybe (JumpInfo blk) -> STM m (StrictTVar m (Maybe (JumpInfo blk)))
forall (m :: * -> *) a.
(HasCallStack, MonadSTM m, NoThunks a) =>
a -> STM m (StrictTVar m a)
newTVar Maybe (JumpInfo blk)
forall a. Maybe a
Nothing
Context m peer blk
context <- StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> SlotNo -> STM m (Context m peer blk)
forall (m :: * -> *) peer blk.
MonadSTM m =>
StrictTVar m (Map peer (ChainSyncClientHandle m blk))
-> SlotNo -> STM m (Context m peer blk)
Jumping.makeContext StrictTVar m (Map peer (ChainSyncClientHandle m blk))
varHandles SlotNo
jumpSize
Context m peer blk
-> peer
-> StrictTVar m (ChainSyncState blk)
-> (StrictTVar m (ChainSyncJumpingState m blk)
-> ChainSyncClientHandle m blk)
-> STM m (PeerContext m peer blk)
forall peer blk (m :: * -> *).
(Ord peer, LedgerSupportsProtocol blk, IOLike m) =>
Context m peer blk
-> peer
-> StrictTVar m (ChainSyncState blk)
-> (StrictTVar m (ChainSyncJumpingState m blk)
-> ChainSyncClientHandle m blk)
-> STM m (PeerContext m peer blk)
Jumping.registerClient Context m peer blk
context peer
peer StrictTVar m (ChainSyncState blk)
cschState ((StrictTVar m (ChainSyncJumpingState m blk)
-> ChainSyncClientHandle m blk)
-> STM m (PeerContext m peer blk))
-> (StrictTVar m (ChainSyncJumpingState m blk)
-> ChainSyncClientHandle m blk)
-> STM m (PeerContext m peer blk)
forall a b. (a -> b) -> a -> b
$ \StrictTVar m (ChainSyncJumpingState m blk)
cschJumping -> ChainSyncClientHandle
{ cschGDDKill :: m ()
cschGDDKill = ThreadId m -> ChainSyncClientException -> m ()
forall e. Exception e => ThreadId m -> e -> m ()
forall (m :: * -> *) e.
(MonadFork m, Exception e) =>
ThreadId m -> e -> m ()
throwTo ThreadId m
tid ChainSyncClientException
DensityTooLow
, cschOnGsmStateChanged :: GsmState -> Time -> STM m ()
cschOnGsmStateChanged = Handlers m -> GsmState -> Time -> STM m ()
updateLopBucketConfig Handlers m
lopBucket
, StrictTVar m (ChainSyncState blk)
cschState :: StrictTVar m (ChainSyncState blk)
cschState :: StrictTVar m (ChainSyncState blk)
cschState
, StrictTVar m (ChainSyncJumpingState m blk)
cschJumping :: StrictTVar m (ChainSyncJumpingState m blk)
cschJumping :: StrictTVar m (ChainSyncJumpingState m blk)
cschJumping
, StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo :: StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo :: StrictTVar m (Maybe (JumpInfo blk))
cschJumpInfo
}
releaseContext :: PeerContext m peer blk -> m ()
releaseContext = STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ())
-> (PeerContext m peer blk -> STM m ())
-> PeerContext m peer blk
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PeerContext m peer blk -> STM m ()
forall (m :: * -> *) peer blk.
(MonadSTM m, Ord peer, LedgerSupportsProtocol blk) =>
PeerContext m peer blk -> STM m ()
Jumping.unregisterClient
invalidBlockWatcher :: StrictTVar m (ChainSyncState blk)
-> Watcher
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
Fingerprint
invalidBlockWatcher StrictTVar m (ChainSyncState blk)
varState =
Tracer m (TraceChainSyncClientEvent blk)
-> NodeToNodeVersion
-> DiffusionPipeliningSupport
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
-> STM m (AnchoredFragment (Header blk))
-> Watcher
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
Fingerprint
forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk) =>
Tracer m (TraceChainSyncClientEvent blk)
-> NodeToNodeVersion
-> DiffusionPipeliningSupport
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
-> STM m (AnchoredFragment (Header blk))
-> Watcher
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
Fingerprint
invalidBlockRejector
Tracer m (TraceChainSyncClientEvent blk)
tracer NodeToNodeVersion
version DiffusionPipeliningSupport
pipelining STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock (ChainSyncState blk -> AnchoredFragment (Header blk)
forall blk. ChainSyncState blk -> AnchoredFragment (Header blk)
csCandidate (ChainSyncState blk -> AnchoredFragment (Header blk))
-> STM m (ChainSyncState blk)
-> STM m (AnchoredFragment (Header blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (ChainSyncState blk) -> STM m (ChainSyncState blk)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (ChainSyncState blk)
varState)
updateLopBucketConfig :: LeakyBucket.Handlers m -> GsmState -> Time -> STM m ()
updateLopBucketConfig :: Handlers m -> GsmState -> Time -> STM m ()
updateLopBucketConfig Handlers m
lopBucket GsmState
gsmState =
Handlers m
-> ((Rational, Config m) -> (Rational, Config m))
-> Time
-> STM m ()
forall (m :: * -> *).
Handlers m
-> ((Rational, Config m) -> (Rational, Config m))
-> Time
-> STM m ()
LeakyBucket.updateConfig Handlers m
lopBucket (((Rational, Config m) -> (Rational, Config m))
-> Time -> STM m ())
-> ((Rational, Config m) -> (Rational, Config m))
-> Time
-> STM m ()
forall a b. (a -> b) -> a -> b
$ \(Rational, Config m)
_ ->
let config :: Config m
config = GsmState -> Config m
lopBucketConfig GsmState
gsmState in
(Config m -> Rational
forall (m :: * -> *). Config m -> Rational
LeakyBucket.capacity Config m
config, Config m
config)
lopBucketConfig :: GsmState -> LeakyBucket.Config m
lopBucketConfig :: GsmState -> Config m
lopBucketConfig GsmState
gsmState =
case (GsmState
gsmState, ChainSyncLoPBucketConfig
csBucketConfig) of
(GsmState
Syncing, ChainSyncLoPBucketEnabled ChainSyncLoPBucketEnabledConfig {Integer
$sel:csbcCapacity:ChainSyncLoPBucketEnabledConfig :: ChainSyncLoPBucketEnabledConfig -> Integer
csbcCapacity :: Integer
csbcCapacity, Rational
$sel:csbcRate:ChainSyncLoPBucketEnabledConfig :: ChainSyncLoPBucketEnabledConfig -> Rational
csbcRate :: Rational
csbcRate}) ->
LeakyBucket.Config
{ capacity :: Rational
capacity = Integer -> Rational
forall a. Num a => Integer -> a
fromInteger (Integer -> Rational) -> Integer -> Rational
forall a b. (a -> b) -> a -> b
$ Integer
csbcCapacity,
rate :: Rational
rate = Rational
csbcRate,
onEmpty :: m ()
onEmpty = ChainSyncClientException -> m ()
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO ChainSyncClientException
EmptyBucket,
fillOnOverflow :: Bool
fillOnOverflow = Bool
True
}
(GsmState
_, ChainSyncLoPBucketConfig
ChainSyncLoPBucketDisabled) -> Config m
forall (m :: * -> *). Applicative m => Config m
LeakyBucket.dummyConfig
(GsmState
PreSyncing, ChainSyncLoPBucketEnabled ChainSyncLoPBucketEnabledConfig
_) -> Config m
forall (m :: * -> *). Applicative m => Config m
LeakyBucket.dummyConfig
(GsmState
CaughtUp, ChainSyncLoPBucketEnabled ChainSyncLoPBucketEnabledConfig
_) -> Config m
forall (m :: * -> *). Applicative m => Config m
LeakyBucket.dummyConfig
data UnknownIntersectionState blk = UnknownIntersectionState {
forall blk.
UnknownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: !(AnchoredFragment (Header blk))
,
:: !(HeaderStateHistory blk)
,
forall blk. UnknownIntersectionState blk -> BlockNo
uBestBlockNo :: !BlockNo
}
deriving ((forall x.
UnknownIntersectionState blk
-> Rep (UnknownIntersectionState blk) x)
-> (forall x.
Rep (UnknownIntersectionState blk) x
-> UnknownIntersectionState blk)
-> Generic (UnknownIntersectionState blk)
forall x.
Rep (UnknownIntersectionState blk) x
-> UnknownIntersectionState blk
forall x.
UnknownIntersectionState blk
-> Rep (UnknownIntersectionState blk) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall blk x.
Rep (UnknownIntersectionState blk) x
-> UnknownIntersectionState blk
forall blk x.
UnknownIntersectionState blk
-> Rep (UnknownIntersectionState blk) x
$cfrom :: forall blk x.
UnknownIntersectionState blk
-> Rep (UnknownIntersectionState blk) x
from :: forall x.
UnknownIntersectionState blk
-> Rep (UnknownIntersectionState blk) x
$cto :: forall blk x.
Rep (UnknownIntersectionState blk) x
-> UnknownIntersectionState blk
to :: forall x.
Rep (UnknownIntersectionState blk) x
-> UnknownIntersectionState blk
Generic)
instance
LedgerSupportsProtocol blk
=> NoThunks (UnknownIntersectionState blk) where
showTypeOf :: Proxy (UnknownIntersectionState blk) -> String
showTypeOf Proxy (UnknownIntersectionState blk)
_ = TypeRep -> String
forall a. Show a => a -> String
show (TypeRep -> String) -> TypeRep -> String
forall a b. (a -> b) -> a -> b
$ Proxy (UnknownIntersectionState blk) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(UnknownIntersectionState blk))
data KnownIntersectionState blk = KnownIntersectionState {
forall blk. KnownIntersectionState blk -> Point blk
mostRecentIntersection :: !(Point blk)
,
forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: !(AnchoredFragment (Header blk))
,
forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag :: !(AnchoredFragment (Header blk))
,
:: !(HeaderStateHistory blk)
,
forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo :: !BlockNo
}
deriving ((forall x.
KnownIntersectionState blk -> Rep (KnownIntersectionState blk) x)
-> (forall x.
Rep (KnownIntersectionState blk) x -> KnownIntersectionState blk)
-> Generic (KnownIntersectionState blk)
forall x.
Rep (KnownIntersectionState blk) x -> KnownIntersectionState blk
forall x.
KnownIntersectionState blk -> Rep (KnownIntersectionState blk) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall blk x.
Rep (KnownIntersectionState blk) x -> KnownIntersectionState blk
forall blk x.
KnownIntersectionState blk -> Rep (KnownIntersectionState blk) x
$cfrom :: forall blk x.
KnownIntersectionState blk -> Rep (KnownIntersectionState blk) x
from :: forall x.
KnownIntersectionState blk -> Rep (KnownIntersectionState blk) x
$cto :: forall blk x.
Rep (KnownIntersectionState blk) x -> KnownIntersectionState blk
to :: forall x.
Rep (KnownIntersectionState blk) x -> KnownIntersectionState blk
Generic)
instance
LedgerSupportsProtocol blk
=> NoThunks (KnownIntersectionState blk) where
showTypeOf :: Proxy (KnownIntersectionState blk) -> String
showTypeOf Proxy (KnownIntersectionState blk)
_ = TypeRep -> String
forall a. Show a => a -> String
show (TypeRep -> String) -> TypeRep -> String
forall a b. (a -> b) -> a -> b
$ Proxy (KnownIntersectionState blk) -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(KnownIntersectionState blk))
checkKnownIntersectionInvariants ::
( HasHeader blk
, HasHeader (Header blk)
, HasAnnTip blk
, ConsensusProtocol (BlockProtocol blk)
)
=> ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk
-> Either String ()
checkKnownIntersectionInvariants :: forall blk.
(HasHeader blk, HasHeader (Header blk), HasAnnTip blk,
ConsensusProtocol (BlockProtocol blk)) =>
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> Either String ()
checkKnownIntersectionInvariants ConsensusConfig (BlockProtocol blk)
cfg KnownIntersectionState blk
kis
| let HeaderStateHistory AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
snapshots = HeaderStateHistory blk
theirHeaderStateHistory
historyTips :: [WithOrigin (AnnTip blk)]
historyTips = HeaderState blk -> WithOrigin (AnnTip blk)
forall blk. HeaderState blk -> WithOrigin (AnnTip blk)
headerStateTip (HeaderState blk -> WithOrigin (AnnTip blk))
-> (HeaderStateWithTime blk -> HeaderState blk)
-> HeaderStateWithTime blk
-> WithOrigin (AnnTip blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeaderStateWithTime blk -> HeaderState blk
forall blk. HeaderStateWithTime blk -> HeaderState blk
hswtHeaderState (HeaderStateWithTime blk -> WithOrigin (AnnTip blk))
-> [HeaderStateWithTime blk] -> [WithOrigin (AnnTip blk)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
-> [HeaderStateWithTime blk]
forall v a b. AnchoredSeq v a b -> [b]
AS.toOldestFirst AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
snapshots
fragmentTips :: [WithOrigin (AnnTip blk)]
fragmentTips = AnnTip blk -> WithOrigin (AnnTip blk)
forall t. t -> WithOrigin t
NotOrigin (AnnTip blk -> WithOrigin (AnnTip blk))
-> (Header blk -> AnnTip blk)
-> Header blk
-> WithOrigin (AnnTip blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header blk -> AnnTip blk
forall blk.
(HasHeader (Header blk), HasAnnTip blk) =>
Header blk -> AnnTip blk
getAnnTip (Header blk -> WithOrigin (AnnTip blk))
-> [Header blk] -> [WithOrigin (AnnTip blk)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> [Header blk]
forall v a b. AnchoredSeq v a b -> [b]
AF.toOldestFirst AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
theirFrag
fragmentAnchorPoint :: Point blk
fragmentAnchorPoint = Point (Header blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
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
$ AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Point (Header blk)
forall block. AnchoredFragment block -> Point block
AF.anchorPoint AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
theirFrag
historyAnchorPoint :: Point blk
historyAnchorPoint =
WithOrigin (RealPoint blk) -> Point blk
forall blk. WithOrigin (RealPoint blk) -> Point blk
withOriginRealPointToPoint
(WithOrigin (RealPoint blk) -> Point blk)
-> WithOrigin (RealPoint blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnnTip blk -> RealPoint blk
forall blk. HasAnnTip blk => AnnTip blk -> RealPoint blk
annTipRealPoint (AnnTip blk -> RealPoint blk)
-> WithOrigin (AnnTip blk) -> WithOrigin (RealPoint blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HeaderState blk -> WithOrigin (AnnTip blk)
forall blk. HeaderState blk -> WithOrigin (AnnTip blk)
headerStateTip (HeaderStateWithTime blk -> HeaderState blk
forall blk. HeaderStateWithTime blk -> HeaderState blk
hswtHeaderState (HeaderStateWithTime blk -> HeaderState blk)
-> HeaderStateWithTime blk -> HeaderState blk
forall a b. (a -> b) -> a -> b
$ AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
-> HeaderStateWithTime blk
forall v a b. AnchoredSeq v a b -> a
AS.anchor AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
snapshots)
, [WithOrigin (AnnTip blk)]
historyTips [WithOrigin (AnnTip blk)] -> [WithOrigin (AnnTip blk)] -> Bool
forall a. Eq a => a -> a -> Bool
/= [WithOrigin (AnnTip blk)]
fragmentTips
Bool -> Bool -> Bool
||
Point blk
historyAnchorPoint Point blk -> Point blk -> Bool
forall a. Eq a => a -> a -> Bool
/= Point blk
fragmentAnchorPoint
= String -> Either String ()
forall a. String -> Either String a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> Either String ()) -> String -> Either String ()
forall a b. (a -> b) -> a -> b
$ Context -> String
unwords
[ String
"The tips in theirHeaderStateHistory"
, String
"didn't match the headers in theirFrag:"
, [WithOrigin (AnnTip blk)] -> String
forall a. Show a => a -> String
show [WithOrigin (AnnTip blk)]
historyTips
, String
"vs"
, [WithOrigin (AnnTip blk)] -> String
forall a. Show a => a -> String
show [WithOrigin (AnnTip blk)]
fragmentTips
, String
"with anchors"
, Point blk -> String
forall a. Show a => a -> String
show Point blk
historyAnchorPoint
, String
"vs"
, Point blk -> String
forall a. Show a => a -> String
show Point blk
fragmentAnchorPoint
]
| let nbHeaders :: Int
nbHeaders = AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Int
forall v a b. Anchorable v a b => AnchoredSeq v a b -> Int
AF.length AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
ourFrag
ourAnchorPoint :: Point (Header blk)
ourAnchorPoint = AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Point (Header blk)
forall block. AnchoredFragment block -> Point block
AF.anchorPoint AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
ourFrag
, Int
nbHeaders Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
k
, Point (Header blk)
ourAnchorPoint Point (Header blk) -> Point (Header blk) -> Bool
forall a. Eq a => a -> a -> Bool
/= Point (Header blk)
forall {k} (block :: k). Point block
GenesisPoint
= String -> Either String ()
forall a. String -> Either String a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> Either String ()) -> String -> Either String ()
forall a b. (a -> b) -> a -> b
$ Context -> String
unwords
[ String
"ourFrag contains fewer than k headers and not close to genesis:"
, Int -> String
forall a. Show a => a -> String
show Int
nbHeaders
, String
"vs"
, Word64 -> String
forall a. Show a => a -> String
show Word64
k
, String
"with anchor"
, Point (Header blk) -> String
forall a. Show a => a -> String
show Point (Header blk)
ourAnchorPoint
]
| let ourFragAnchor :: Point (Header blk)
ourFragAnchor = AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Point (Header blk)
forall block. AnchoredFragment block -> Point block
AF.anchorPoint AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
ourFrag
theirFragAnchor :: Point (Header blk)
theirFragAnchor = AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Point (Header blk)
forall block. AnchoredFragment block -> Point block
AF.anchorPoint AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
theirFrag
, Point (Header blk)
ourFragAnchor Point (Header blk) -> Point (Header blk) -> Bool
forall a. Eq a => a -> a -> Bool
/= Point (Header blk)
theirFragAnchor
= String -> Either String ()
forall a. String -> Either String a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> Either String ()) -> String -> Either String ()
forall a b. (a -> b) -> a -> b
$ Context -> String
unwords
[ String
"ourFrag and theirFrag have different anchor points:"
, Point (Header blk) -> String
forall a. Show a => a -> String
show Point (Header blk)
ourFragAnchor
, String
"vs"
, Point (Header blk) -> String
forall a. Show a => a -> String
show Point (Header blk)
theirFragAnchor
]
| let actualMostRecentIntersection :: Maybe (Point blk)
actualMostRecentIntersection =
Point (Header blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> Maybe (Point (Header blk)) -> Maybe (Point blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> AnchoredSeq
(WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
-> Maybe (Point (Header blk))
forall block1 block2.
(HasHeader block1, HasHeader block2,
HeaderHash block1 ~ HeaderHash block2) =>
AnchoredFragment block1
-> AnchoredFragment block2 -> Maybe (Point block1)
AF.intersectionPoint AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
theirFrag AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
ourFrag
, Point blk -> Maybe (Point blk)
forall a. a -> Maybe a
Just Point blk
mostRecentIntersection Maybe (Point blk) -> Maybe (Point blk) -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe (Point blk)
actualMostRecentIntersection
= String -> Either String ()
forall a. String -> Either String a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> Either String ()) -> String -> Either String ()
forall a b. (a -> b) -> a -> b
$ Context -> String
unwords
[ String
"mostRecentIntersection not the most recent intersection"
, String
"of theirFrag and ourFrag:"
, Point blk -> String
forall a. Show a => a -> String
show Point blk
mostRecentIntersection
, String
"vs"
, Maybe (Point blk) -> String
forall a. Show a => a -> String
show Maybe (Point blk)
actualMostRecentIntersection
]
| Bool
otherwise
= () -> Either String ()
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
SecurityParam Word64
k = ConsensusConfig (BlockProtocol blk) -> SecurityParam
forall p. ConsensusProtocol p => ConsensusConfig p -> SecurityParam
protocolSecurityParam ConsensusConfig (BlockProtocol blk)
cfg
KnownIntersectionState {
Point blk
$sel:mostRecentIntersection:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> Point blk
mostRecentIntersection :: Point blk
mostRecentIntersection
, AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
ourFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
ourFrag
, AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
theirFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag :: AnchoredSeq (WithOrigin SlotNo) (Anchor (Header blk)) (Header blk)
theirFrag
, HeaderStateHistory blk
$sel:theirHeaderStateHistory:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> HeaderStateHistory blk
theirHeaderStateHistory :: HeaderStateHistory blk
theirHeaderStateHistory
} = KnownIntersectionState blk
kis
assertKnownIntersectionInvariants ::
( HasHeader blk
, HasHeader (Header blk)
, HasAnnTip blk
, ConsensusProtocol (BlockProtocol blk)
, HasCallStack
)
=> ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk
-> KnownIntersectionState blk
assertKnownIntersectionInvariants :: forall blk.
(HasHeader blk, HasHeader (Header blk), HasAnnTip blk,
ConsensusProtocol (BlockProtocol blk), HasCallStack) =>
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
assertKnownIntersectionInvariants ConsensusConfig (BlockProtocol blk)
cfg KnownIntersectionState blk
kis =
Either String ()
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall a. HasCallStack => Either String () -> a -> a
assertWithMsg (ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> Either String ()
forall blk.
(HasHeader blk, HasHeader (Header blk), HasAnnTip blk,
ConsensusProtocol (BlockProtocol blk)) =>
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> Either String ()
checkKnownIntersectionInvariants ConsensusConfig (BlockProtocol blk)
cfg KnownIntersectionState blk
kis) KnownIntersectionState blk
kis
data ConfigEnv m blk = ConfigEnv {
forall (m :: * -> *) blk. ConfigEnv m blk -> MkPipelineDecision
mkPipelineDecision0 :: MkPipelineDecision
, forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer :: Tracer m (TraceChainSyncClientEvent blk)
, forall (m :: * -> *) blk. ConfigEnv m blk -> TopLevelConfig blk
cfg :: TopLevelConfig blk
, :: InFutureCheck.SomeHeaderInFutureCheck m blk
, forall (m :: * -> *) blk. ConfigEnv m blk -> HistoricityCheck m blk
historicityCheck :: HistoricityCheck m blk
, forall (m :: * -> *) blk. ConfigEnv m blk -> ChainDbView m blk
chainDbView :: ChainDbView m blk
, forall (m :: * -> *) blk.
ConfigEnv m blk -> DiffusionPipeliningSupport
getDiffusionPipeliningSupport
:: DiffusionPipeliningSupport
}
data DynamicEnv m blk = DynamicEnv {
forall (m :: * -> *) blk. DynamicEnv m blk -> NodeToNodeVersion
version :: NodeToNodeVersion
, forall (m :: * -> *) blk. DynamicEnv m blk -> ControlMessageSTM m
controlMessageSTM :: ControlMessageSTM m
, :: HeaderMetricsTracer m
, forall (m :: * -> *) blk.
DynamicEnv m blk -> AnchoredFragment (Header blk) -> STM m ()
setCandidate :: AnchoredFragment (Header blk) -> STM m ()
, forall (m :: * -> *) blk.
DynamicEnv m blk -> WithOrigin SlotNo -> STM m ()
setLatestSlot :: WithOrigin SlotNo -> STM m ()
, forall (m :: * -> *) blk. DynamicEnv m blk -> Idling m
idling :: Idling m
, forall (m :: * -> *) blk. DynamicEnv m blk -> LoPBucket m
loPBucket :: LoPBucket m
, forall (m :: * -> *) blk. DynamicEnv m blk -> Jumping m blk
jumping :: Jumping.Jumping m blk
}
data InternalEnv m blk arrival judgment = InternalEnv {
forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe ::
forall s n.
NoThunks s
=> Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
,
forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect ::
forall m' a.
MonadThrow m'
=> ChainSyncClientException
-> m' a
,
::
InFutureCheck.HeaderInFutureCheck m blk arrival judgment
,
forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain ::
KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
,
forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
terminate ::
ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
,
forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall (n :: N).
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
terminateAfterDrain ::
forall n.
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
,
forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment -> forall a. m a -> m a
traceException :: forall a. m a -> m a
}
chainSyncClient :: forall m blk.
( IOLike m
, LedgerSupportsProtocol blk
)
=> ConfigEnv m blk
-> DynamicEnv m blk
-> Consensus ChainSyncClientPipelined blk m
chainSyncClient :: forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk -> Consensus ChainSyncClientPipelined blk m
chainSyncClient ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv =
case ConfigEnv m blk -> SomeHeaderInFutureCheck m blk
forall (m :: * -> *) blk.
ConfigEnv m blk -> SomeHeaderInFutureCheck m blk
someHeaderInFutureCheck ConfigEnv m blk
cfgEnv of
InFutureCheck.SomeHeaderInFutureCheck HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck ->
m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> Consensus ChainSyncClientPipelined blk m
forall header point tip (m :: * -> *) a.
m (ClientPipelinedStIdle 'Z header point tip m a)
-> ChainSyncClientPipelined header point tip m a
ChainSyncClientPipelined
(m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> Consensus ChainSyncClientPipelined blk m)
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> Consensus ChainSyncClientPipelined blk m
forall a b. (a -> b) -> a -> b
$ ()
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState ()
(Stateful m blk () (ClientPipelinedStIdle 'Z)
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall a b. (a -> b) -> a -> b
$
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersectionTop
ConfigEnv m blk
cfgEnv
DynamicEnv m blk
dynEnv
(HeaderInFutureCheck m blk arrival judgment
-> InternalEnv m blk arrival judgment
forall arrival judgment.
HeaderInFutureCheck m blk arrival judgment
-> InternalEnv m blk arrival judgment
mkIntEnv HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck)
(Word64 -> BlockNo
BlockNo Word64
0)
(Point blk
-> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
forall blk.
BlockSupportsProtocol blk =>
Point blk
-> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
ForkTooDeep Point blk
forall {k} (block :: k). Point block
GenesisPoint)
where
ConfigEnv {
TopLevelConfig blk
$sel:cfg:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg
, ChainDbView m blk
$sel:chainDbView:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> ChainDbView m blk
chainDbView :: ChainDbView m blk
chainDbView
, Tracer m (TraceChainSyncClientEvent blk)
$sel:tracer:ConfigEnv :: forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer :: Tracer m (TraceChainSyncClientEvent blk)
tracer
} = ConfigEnv m blk
cfgEnv
ChainDbView {
STM m (AnchoredFragment (Header blk))
$sel:getCurrentChain:ChainDbView :: forall (m :: * -> *) blk.
ChainDbView m blk -> STM m (AnchoredFragment (Header blk))
getCurrentChain :: STM m (AnchoredFragment (Header blk))
getCurrentChain
} = ChainDbView m blk
chainDbView
DynamicEnv {
Idling m
$sel:idling:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> Idling m
idling :: Idling m
idling
} = DynamicEnv m blk
dynEnv
mkIntEnv ::
InFutureCheck.HeaderInFutureCheck m blk arrival judgment
-> InternalEnv m blk arrival judgment
mkIntEnv :: forall arrival judgment.
HeaderInFutureCheck m blk arrival judgment
-> InternalEnv m blk arrival judgment
mkIntEnv HeaderInFutureCheck m blk arrival judgment
hifc = InternalEnv {
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
$sel:drainThePipe:InternalEnv :: forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe :: forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe
,
$sel:disconnect:InternalEnv :: forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect = ChainSyncClientException -> m' a
forall e a. Exception e => e -> m' a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
throwIO
,
$sel:headerInFutureCheck:InternalEnv :: HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck = HeaderInFutureCheck m blk arrival judgment
hifc
,
KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
$sel:intersectsWithCurrentChain:InternalEnv :: KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain :: KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain
,
ChainSyncClientResult
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
$sel:terminate:InternalEnv :: ChainSyncClientResult
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
terminate :: ChainSyncClientResult
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
terminate
,
$sel:terminateAfterDrain:InternalEnv :: forall (n :: N).
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
terminateAfterDrain = \Nat n
n ChainSyncClientResult
result ->
()
-> Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState ()
(Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ Nat n
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n)
forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe Nat n
n
(Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ (()
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((()
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> Stateful m blk () (ClientPipelinedStIdle 'Z))
-> (()
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
forall a b. (a -> b) -> a -> b
$ \() -> ChainSyncClientResult
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
terminate ChainSyncClientResult
result
,
$sel:traceException:InternalEnv :: forall a. m a -> m a
traceException = \m a
m -> do
m a
m m a -> (ChainSyncClientException -> m a) -> m a
forall e a. Exception e => m a -> (e -> m a) -> m a
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` \(ChainSyncClientException
e :: ChainSyncClientException) -> do
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ ChainSyncClientException -> TraceChainSyncClientEvent blk
forall blk.
ChainSyncClientException -> TraceChainSyncClientEvent blk
TraceException ChainSyncClientException
e
ChainSyncClientException -> m a
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO ChainSyncClientException
e
}
drainThePipe ::
forall s n.
NoThunks s
=> Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe :: forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe Nat n
n0 Stateful m blk s (ClientPipelinedStIdle 'Z)
m =
let go ::
forall n'.
Nat n'
-> s
-> m (Consensus (ClientPipelinedStIdle n') blk m)
go :: forall (n' :: N).
Nat n' -> s -> m (Consensus (ClientPipelinedStIdle n') blk m)
go Nat n'
n s
s = case Nat n'
n of
Nat n'
Zero -> s
-> Stateful m blk s (ClientPipelinedStIdle n')
-> m (Consensus (ClientPipelinedStIdle n') blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState s
s Stateful m blk s (ClientPipelinedStIdle n')
Stateful m blk s (ClientPipelinedStIdle 'Z)
m
Succ Nat n
n' -> Consensus (ClientPipelinedStIdle n') blk m
-> m (Consensus (ClientPipelinedStIdle n') blk m)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Consensus (ClientPipelinedStIdle n') blk m
-> m (Consensus (ClientPipelinedStIdle n') blk m))
-> Consensus (ClientPipelinedStIdle n') blk m
-> m (Consensus (ClientPipelinedStIdle n') blk m)
forall a b. (a -> b) -> a -> b
$ Maybe
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> ClientStNext
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (m :: * -> *) (n1 :: N) header point tip a.
Maybe (m (ClientPipelinedStIdle ('S n1) header point tip m a))
-> ClientStNext n1 header point tip m a
-> ClientPipelinedStIdle ('S n1) header point tip m a
CollectResponse Maybe
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
forall a. Maybe a
Nothing (ClientStNext
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> ClientStNext
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall a b. (a -> b) -> a -> b
$ ClientStNext {
recvMsgRollForward :: Header blk
-> Tip blk
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
recvMsgRollForward = \Header blk
_hdr Tip blk
_tip -> Nat n
-> s
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall (n' :: N).
Nat n' -> s -> m (Consensus (ClientPipelinedStIdle n') blk m)
go Nat n
n' s
s
, recvMsgRollBackward :: Point blk
-> Tip blk
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
recvMsgRollBackward = \Point blk
_pt Tip blk
_tip -> Nat n
-> s
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall (n' :: N).
Nat n' -> s -> m (Consensus (ClientPipelinedStIdle n') blk m)
go Nat n
n' s
s
}
in (s -> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful m blk s (ClientPipelinedStIdle n)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((s -> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful m blk s (ClientPipelinedStIdle n))
-> (s -> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful m blk s (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ \s
s -> Idling m -> m ()
forall (m :: * -> *). Idling m -> m ()
idlingStop Idling m
idling m ()
-> m (Consensus (ClientPipelinedStIdle n) blk m)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Nat n -> s -> m (Consensus (ClientPipelinedStIdle n) blk m)
forall (n' :: N).
Nat n' -> s -> m (Consensus (ClientPipelinedStIdle n') blk m)
go Nat n
n0 s
s
terminate ::
ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
terminate :: ChainSyncClientResult
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
terminate ChainSyncClientResult
res = do
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (ChainSyncClientResult -> TraceChainSyncClientEvent blk
forall blk. ChainSyncClientResult -> TraceChainSyncClientEvent blk
TraceTermination ChainSyncClientResult
res)
ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> m (ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ChainSyncClientResult
-> ClientPipelinedStIdle
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall a header point tip (m :: * -> *).
a -> ClientPipelinedStIdle 'Z header point tip m a
SendMsgDone ChainSyncClientResult
res)
intersectsWithCurrentChain ::
KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain :: KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain KnownIntersectionState blk
kis = do
let KnownIntersectionState {
AnchoredFragment (Header blk)
ourFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: AnchoredFragment (Header blk)
ourFrag
, AnchoredFragment (Header blk)
theirFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag :: AnchoredFragment (Header blk)
theirFrag
, HeaderStateHistory blk
$sel:theirHeaderStateHistory:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> HeaderStateHistory blk
theirHeaderStateHistory :: HeaderStateHistory blk
theirHeaderStateHistory
, BlockNo
$sel:kBestBlockNo:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo :: BlockNo
kBestBlockNo
} = KnownIntersectionState blk
kis
AnchoredFragment (Header blk)
ourFrag' <- STM m (AnchoredFragment (Header blk))
getCurrentChain
let noChange :: Bool
noChange = AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint AnchoredFragment (Header blk)
ourFrag 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)
ourFrag'
UpdatedIntersectionState blk ()
-> STM m (UpdatedIntersectionState blk ())
forall a. a -> STM m a
forall (m :: * -> *) a. Monad m => a -> m a
return (UpdatedIntersectionState blk ()
-> STM m (UpdatedIntersectionState blk ()))
-> UpdatedIntersectionState blk ()
-> STM m (UpdatedIntersectionState blk ())
forall a b. (a -> b) -> a -> b
$ if Bool
noChange then () -> KnownIntersectionState blk -> UpdatedIntersectionState blk ()
forall blk a.
a -> KnownIntersectionState blk -> UpdatedIntersectionState blk a
StillIntersects () KnownIntersectionState blk
kis else
case AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk)
-> Maybe (Point (Header blk), AnchoredFragment (Header blk))
forall block.
HasHeader block =>
AnchoredFragment block
-> AnchoredFragment block
-> Maybe (Point block, AnchoredFragment block)
cross AnchoredFragment (Header blk)
ourFrag' AnchoredFragment (Header blk)
theirFrag of
Maybe (Point (Header blk), AnchoredFragment (Header blk))
Nothing -> UpdatedIntersectionState blk ()
forall blk a. UpdatedIntersectionState blk a
NoLongerIntersects
Just (Point (Header blk)
intersection, AnchoredFragment (Header blk)
trimmedCandidate) ->
() -> KnownIntersectionState blk -> UpdatedIntersectionState blk ()
forall blk a.
a -> KnownIntersectionState blk -> UpdatedIntersectionState blk a
StillIntersects ()
(KnownIntersectionState blk -> UpdatedIntersectionState blk ())
-> KnownIntersectionState blk -> UpdatedIntersectionState blk ()
forall a b. (a -> b) -> a -> b
$ ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall blk.
(HasHeader blk, HasHeader (Header blk), HasAnnTip blk,
ConsensusProtocol (BlockProtocol blk), HasCallStack) =>
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
assertKnownIntersectionInvariants (TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg)
(KnownIntersectionState blk -> KnownIntersectionState blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState {
$sel:mostRecentIntersection:KnownIntersectionState :: Point blk
mostRecentIntersection = Point (Header blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point (Header blk)
intersection
, ourFrag :: AnchoredFragment (Header blk)
ourFrag = AnchoredFragment (Header blk)
ourFrag'
, theirFrag :: AnchoredFragment (Header blk)
theirFrag = AnchoredFragment (Header blk)
trimmedCandidate
, $sel:theirHeaderStateHistory:KnownIntersectionState :: HeaderStateHistory blk
theirHeaderStateHistory =
Int -> HeaderStateHistory blk -> HeaderStateHistory blk
forall blk. Int -> HeaderStateHistory blk -> HeaderStateHistory blk
HeaderStateHistory.trim
(AnchoredFragment (Header blk) -> Int
forall v a b. Anchorable v a b => AnchoredSeq v a b -> Int
AF.length AnchoredFragment (Header blk)
trimmedCandidate)
HeaderStateHistory blk
theirHeaderStateHistory
, BlockNo
$sel:kBestBlockNo:KnownIntersectionState :: BlockNo
kBestBlockNo :: BlockNo
kBestBlockNo
}
findIntersectionTop ::
forall m blk arrival judgment.
( IOLike m
, LedgerSupportsProtocol blk
)
=> ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersectionTop :: forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersectionTop ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv InternalEnv m blk arrival judgment
intEnv =
BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersection
where
ConfigEnv {
Tracer m (TraceChainSyncClientEvent blk)
$sel:tracer:ConfigEnv :: forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer :: Tracer m (TraceChainSyncClientEvent blk)
tracer
, TopLevelConfig blk
$sel:cfg:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg
, ChainDbView m blk
$sel:chainDbView:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> ChainDbView m blk
chainDbView :: ChainDbView m blk
chainDbView
} = ConfigEnv m blk
cfgEnv
ChainDbView {
STM m (AnchoredFragment (Header blk))
$sel:getCurrentChain:ChainDbView :: forall (m :: * -> *) blk.
ChainDbView m blk -> STM m (AnchoredFragment (Header blk))
getCurrentChain :: STM m (AnchoredFragment (Header blk))
getCurrentChain
, STM m (HeaderStateHistory blk)
$sel:getHeaderStateHistory:ChainDbView :: forall (m :: * -> *) blk.
ChainDbView m blk -> STM m (HeaderStateHistory blk)
getHeaderStateHistory :: STM m (HeaderStateHistory blk)
getHeaderStateHistory
} = ChainDbView m blk
chainDbView
DynamicEnv {
AnchoredFragment (Header blk) -> STM m ()
$sel:setCandidate:DynamicEnv :: forall (m :: * -> *) blk.
DynamicEnv m blk -> AnchoredFragment (Header blk) -> STM m ()
setCandidate :: AnchoredFragment (Header blk) -> STM m ()
setCandidate
, Jumping m blk
$sel:jumping:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> Jumping m blk
jumping :: Jumping m blk
jumping
} = DynamicEnv m blk
dynEnv
InternalEnv {
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
$sel:disconnect:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect :: forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect
, ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
$sel:terminate:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
terminate :: ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
terminate
, forall a. m a -> m a
$sel:traceException:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment -> forall a. m a -> m a
traceException :: forall a. m a -> m a
traceException
} = InternalEnv m blk arrival judgment
intEnv
findIntersection ::
BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersection :: BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersection BlockNo
uBestBlockNo Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
mkResult = (() -> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((() -> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful m blk () (ClientPipelinedStIdle 'Z))
-> (() -> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
forall a b. (a -> b) -> a -> b
$ \() -> do
(AnchoredFragment (Header blk)
ourFrag, HeaderStateHistory blk
ourHeaderStateHistory) <- STM m (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> m (AnchoredFragment (Header blk), HeaderStateHistory blk)
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> m (AnchoredFragment (Header blk), HeaderStateHistory blk))
-> STM m (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> m (AnchoredFragment (Header blk), HeaderStateHistory blk)
forall a b. (a -> b) -> a -> b
$ (,)
(AnchoredFragment (Header blk)
-> HeaderStateHistory blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk))
-> STM m (AnchoredFragment (Header blk))
-> STM
m
(HeaderStateHistory blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> STM m (AnchoredFragment (Header blk))
getCurrentChain
STM
m
(HeaderStateHistory blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk))
-> STM m (HeaderStateHistory blk)
-> STM m (AnchoredFragment (Header blk), HeaderStateHistory blk)
forall a b. STM m (a -> b) -> STM m a -> STM m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> STM m (HeaderStateHistory blk)
getHeaderStateHistory
let maxOffset :: Word64
maxOffset = Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (AnchoredFragment (Header blk) -> Int
forall v a b. Anchorable v a b => AnchoredSeq v a b -> Int
AF.length AnchoredFragment (Header blk)
ourFrag)
k :: SecurityParam
k = ConsensusConfig (BlockProtocol blk) -> SecurityParam
forall p. ConsensusProtocol p => ConsensusConfig p -> SecurityParam
protocolSecurityParam (TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg)
offsets :: [Word64]
offsets = SecurityParam -> Word64 -> [Word64]
mkOffsets SecurityParam
k Word64
maxOffset
points :: [Point blk]
points =
(Point (Header blk) -> Point blk)
-> [Point (Header blk)] -> [Point blk]
forall a b. (a -> b) -> [a] -> [b]
map Point (Header blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
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
$ [Int] -> AnchoredFragment (Header blk) -> [Point (Header blk)]
forall block.
HasHeader block =>
[Int] -> AnchoredFragment block -> [Point block]
AF.selectPoints ((Word64 -> Int) -> [Word64] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Word64]
offsets) AnchoredFragment (Header blk)
ourFrag
!uis :: UnknownIntersectionState blk
uis = UnknownIntersectionState {
$sel:ourFrag:UnknownIntersectionState :: AnchoredFragment (Header blk)
ourFrag = AnchoredFragment (Header blk)
ourFrag
, $sel:ourHeaderStateHistory:UnknownIntersectionState :: HeaderStateHistory blk
ourHeaderStateHistory = HeaderStateHistory blk
ourHeaderStateHistory
, BlockNo
$sel:uBestBlockNo:UnknownIntersectionState :: BlockNo
uBestBlockNo :: BlockNo
uBestBlockNo
}
Consensus (ClientPipelinedStIdle 'Z) blk m
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return
(Consensus (ClientPipelinedStIdle 'Z) blk m
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Consensus (ClientPipelinedStIdle 'Z) blk m
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$ [Point blk]
-> ClientPipelinedStIntersect
(Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle 'Z) blk m
forall point header tip (m :: * -> *) a.
[point]
-> ClientPipelinedStIntersect header point tip m a
-> ClientPipelinedStIdle 'Z header point tip m a
SendMsgFindIntersect [Point blk]
points
(ClientPipelinedStIntersect
(Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle 'Z) blk m)
-> ClientPipelinedStIntersect
(Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle 'Z) blk m
forall a b. (a -> b) -> a -> b
$ ClientPipelinedStIntersect {
recvMsgIntersectFound :: Point blk
-> Tip blk -> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
recvMsgIntersectFound = \Point blk
i Tip blk
theirTip' ->
UnknownIntersectionState blk
-> Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState UnknownIntersectionState blk
uis
(Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$ Point blk
-> Their (Tip blk)
-> Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z)
intersectFound (Point blk -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point blk
i) (Tip blk -> Their (Tip blk)
forall a. a -> Their a
Their Tip blk
theirTip')
,
recvMsgIntersectNotFound :: Tip blk -> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
recvMsgIntersectNotFound = \Tip blk
theirTip' ->
ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
terminate
(ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$ Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
mkResult (AnchoredFragment (Header blk) -> Our (Tip blk)
forall blk.
HasHeader (Header blk) =>
AnchoredFragment (Header blk) -> Our (Tip blk)
ourTipFromChain AnchoredFragment (Header blk)
ourFrag) (Tip blk -> Their (Tip blk)
forall a. a -> Their a
Their Tip blk
theirTip')
}
intersectFound ::
Point blk
-> Their (Tip blk)
-> Stateful m blk
(UnknownIntersectionState blk)
(ClientPipelinedStIdle 'Z)
intersectFound :: Point blk
-> Their (Tip blk)
-> Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z)
intersectFound Point blk
intersection Their (Tip blk)
theirTip = (UnknownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((UnknownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z))
-> (UnknownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (UnknownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall a b. (a -> b) -> a -> b
$ \UnknownIntersectionState blk
uis -> do
let UnknownIntersectionState {
AnchoredFragment (Header blk)
$sel:ourFrag:UnknownIntersectionState :: forall blk.
UnknownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: AnchoredFragment (Header blk)
ourFrag
, HeaderStateHistory blk
$sel:ourHeaderStateHistory:UnknownIntersectionState :: forall blk. UnknownIntersectionState blk -> HeaderStateHistory blk
ourHeaderStateHistory :: HeaderStateHistory blk
ourHeaderStateHistory
, BlockNo
$sel:uBestBlockNo:UnknownIntersectionState :: forall blk. UnknownIntersectionState blk -> BlockNo
uBestBlockNo :: BlockNo
uBestBlockNo
} = UnknownIntersectionState blk
uis
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$
Point blk
-> Our (Tip blk)
-> Their (Tip blk)
-> TraceChainSyncClientEvent blk
forall blk.
Point blk
-> Our (Tip blk)
-> Their (Tip blk)
-> TraceChainSyncClientEvent blk
TraceFoundIntersection
Point blk
intersection (AnchoredFragment (Header blk) -> Our (Tip blk)
forall blk.
HasHeader (Header blk) =>
AnchoredFragment (Header blk) -> Our (Tip blk)
ourTipFromChain AnchoredFragment (Header blk)
ourFrag) Their (Tip blk)
theirTip
m (Consensus (ClientPipelinedStIdle 'Z) blk m)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a. m a -> m a
traceException (m (Consensus (ClientPipelinedStIdle 'Z) blk m)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$ do
(AnchoredFragment (Header blk)
theirFrag, HeaderStateHistory blk
theirHeaderStateHistory) <- do
case Point blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
forall blk.
(BlockSupportsProtocol blk, HasAnnTip blk) =>
Point blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
attemptRollback
Point blk
intersection
(AnchoredFragment (Header blk)
ourFrag, HeaderStateHistory blk
ourHeaderStateHistory)
of
Just (AnchoredFragment (Header blk)
c, HeaderStateHistory blk
d, Maybe (HeaderStateWithTime blk)
_oldestRewound) -> (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> m (AnchoredFragment (Header blk), HeaderStateHistory blk)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (AnchoredFragment (Header blk)
c, HeaderStateHistory blk
d)
Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
Nothing ->
ChainSyncClientException
-> m (AnchoredFragment (Header blk), HeaderStateHistory blk)
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect
(ChainSyncClientException
-> m (AnchoredFragment (Header blk), HeaderStateHistory blk))
-> ChainSyncClientException
-> m (AnchoredFragment (Header blk), HeaderStateHistory blk)
forall a b. (a -> b) -> a -> b
$ Point blk
-> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientException
forall blk.
BlockSupportsProtocol blk =>
Point blk
-> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientException
InvalidIntersection
Point blk
intersection (AnchoredFragment (Header blk) -> Our (Tip blk)
forall blk.
HasHeader (Header blk) =>
AnchoredFragment (Header blk) -> Our (Tip blk)
ourTipFromChain AnchoredFragment (Header blk)
ourFrag) Their (Tip blk)
theirTip
let kis :: KnownIntersectionState blk
kis =
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall blk.
(HasHeader blk, HasHeader (Header blk), HasAnnTip blk,
ConsensusProtocol (BlockProtocol blk), HasCallStack) =>
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
assertKnownIntersectionInvariants (TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg)
(KnownIntersectionState blk -> KnownIntersectionState blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState {
$sel:mostRecentIntersection:KnownIntersectionState :: Point blk
mostRecentIntersection = Point blk
intersection
, AnchoredFragment (Header blk)
ourFrag :: AnchoredFragment (Header blk)
ourFrag :: AnchoredFragment (Header blk)
ourFrag
, AnchoredFragment (Header blk)
theirFrag :: AnchoredFragment (Header blk)
theirFrag :: AnchoredFragment (Header blk)
theirFrag
, HeaderStateHistory blk
$sel:theirHeaderStateHistory:KnownIntersectionState :: HeaderStateHistory blk
theirHeaderStateHistory :: HeaderStateHistory blk
theirHeaderStateHistory
, $sel:kBestBlockNo:KnownIntersectionState :: BlockNo
kBestBlockNo = BlockNo
uBestBlockNo
}
STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
Jumping m blk -> KnownIntersectionState blk -> STM m ()
forall (m :: * -> *) blk.
Jumping m blk -> KnownIntersectionState blk -> STM m ()
updateJumpInfoSTM Jumping m blk
jumping KnownIntersectionState blk
kis
AnchoredFragment (Header blk) -> STM m ()
setCandidate AnchoredFragment (Header blk)
theirFrag
DynamicEnv m blk -> WithOrigin SlotNo -> STM m ()
forall (m :: * -> *) blk.
DynamicEnv m blk -> WithOrigin SlotNo -> STM m ()
setLatestSlot DynamicEnv m blk
dynEnv (AnchoredFragment (Header blk) -> WithOrigin SlotNo
forall block.
HasHeader block =>
AnchoredFragment block -> WithOrigin SlotNo
AF.headSlot AnchoredFragment (Header blk)
theirFrag)
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis (Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
knownIntersectionStateTop ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv InternalEnv m blk arrival judgment
intEnv Their (Tip blk)
theirTip
knownIntersectionStateTop ::
forall m blk arrival judgment.
( IOLike m
, LedgerSupportsProtocol blk
)
=> ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Their (Tip blk)
-> Stateful m blk
(KnownIntersectionState blk)
(ClientPipelinedStIdle 'Z)
knownIntersectionStateTop :: forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
knownIntersectionStateTop ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv InternalEnv m blk arrival judgment
intEnv =
MkPipelineDecision
-> Nat 'Z
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep MkPipelineDecision
mkPipelineDecision0 Nat 'Z
forall (n :: N). ('Z ~ n) => Nat n
Zero
where
ConfigEnv {
MkPipelineDecision
$sel:mkPipelineDecision0:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> MkPipelineDecision
mkPipelineDecision0 :: MkPipelineDecision
mkPipelineDecision0
, Tracer m (TraceChainSyncClientEvent blk)
$sel:tracer:ConfigEnv :: forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer :: Tracer m (TraceChainSyncClientEvent blk)
tracer
, TopLevelConfig blk
$sel:cfg:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg
, HistoricityCheck m blk
$sel:historicityCheck:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> HistoricityCheck m blk
historicityCheck :: HistoricityCheck m blk
historicityCheck
} = ConfigEnv m blk
cfgEnv
DynamicEnv {
ControlMessageSTM m
$sel:controlMessageSTM:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> ControlMessageSTM m
controlMessageSTM :: ControlMessageSTM m
controlMessageSTM
, HeaderMetricsTracer m
$sel:headerMetricsTracer:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> HeaderMetricsTracer m
headerMetricsTracer :: HeaderMetricsTracer m
headerMetricsTracer
, Idling m
$sel:idling:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> Idling m
idling :: Idling m
idling
, LoPBucket m
$sel:loPBucket:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> LoPBucket m
loPBucket :: LoPBucket m
loPBucket
, AnchoredFragment (Header blk) -> STM m ()
$sel:setCandidate:DynamicEnv :: forall (m :: * -> *) blk.
DynamicEnv m blk -> AnchoredFragment (Header blk) -> STM m ()
setCandidate :: AnchoredFragment (Header blk) -> STM m ()
setCandidate
, Jumping m blk
$sel:jumping:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> Jumping m blk
jumping :: Jumping m blk
jumping
} = DynamicEnv m blk
dynEnv
InternalEnv {
forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
$sel:drainThePipe:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe :: forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe
, HeaderInFutureCheck m blk arrival judgment
$sel:headerInFutureCheck:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck :: HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck
, forall (n :: N).
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
$sel:terminateAfterDrain:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall (n :: N).
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
terminateAfterDrain :: forall (n :: N).
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
terminateAfterDrain
, forall a. m a -> m a
$sel:traceException:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment -> forall a. m a -> m a
traceException :: forall a. m a -> m a
traceException
} = InternalEnv m blk arrival judgment
intEnv
InFutureCheck.HeaderInFutureCheck {
Header blk -> m arrival
recordHeaderArrival :: Header blk -> m arrival
recordHeaderArrival :: forall (m :: * -> *) blk arrival judgment.
HeaderInFutureCheck m blk arrival judgment
-> Header blk -> m arrival
recordHeaderArrival
} = HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck
nextStep ::
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful m blk
(KnownIntersectionState blk)
(ClientPipelinedStIdle n)
nextStep :: forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep MkPipelineDecision
mkPipelineDecision Nat n
n Their (Tip blk)
theirTip = (KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n))
-> (KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ \KnownIntersectionState blk
kis ->
ControlMessageSTM m -> m ControlMessage
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically ControlMessageSTM m
controlMessageSTM m ControlMessage
-> (ControlMessage
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
ControlMessage
Terminate -> Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall (n :: N).
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
terminateAfterDrain Nat n
n (ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ ChainSyncClientResult
AskedToTerminate
ControlMessage
_continue -> do
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer TraceChainSyncClientEvent blk
forall blk. TraceChainSyncClientEvent blk
TraceJumpingWaitingForNextInstruction
LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbPause LoPBucket m
loPBucket
Instruction blk
instruction <- Jumping m blk -> m (Instruction blk)
forall (m :: * -> *) blk. Jumping m blk -> m (Instruction blk)
Jumping.jgNextInstruction Jumping m blk
jumping
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Instruction blk -> TraceChainSyncClientEvent blk
forall blk. Instruction blk -> TraceChainSyncClientEvent blk
TraceJumpingInstructionIs Instruction blk
instruction
case Instruction blk
instruction of
Jumping.JumpInstruction JumpInstruction blk
jumpInstruction ->
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis
(Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ Nat n
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe Nat n
n
(Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ MkPipelineDecision
-> JumpInstruction blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
offerJump MkPipelineDecision
mkPipelineDecision JumpInstruction blk
jumpInstruction
Instruction blk
Jumping.RunNormally -> do
LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbResume LoPBucket m
loPBucket
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis
(Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep' MkPipelineDecision
mkPipelineDecision Nat n
n Their (Tip blk)
theirTip
Instruction blk
Jumping.Restart -> do
LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbResume LoPBucket m
loPBucket
()
-> Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState ()
(Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ Nat n
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n)
forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe Nat n
n
(Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersectionTop
ConfigEnv m blk
cfgEnv
DynamicEnv m blk
dynEnv
InternalEnv m blk arrival judgment
intEnv
(KnownIntersectionState blk -> BlockNo
forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo KnownIntersectionState blk
kis)
Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
forall blk.
BlockSupportsProtocol blk =>
Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
NoMoreIntersection
nextStep' ::
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful m blk
(KnownIntersectionState blk)
(ClientPipelinedStIdle n)
nextStep' :: forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep' MkPipelineDecision
mkPipelineDecision Nat n
n Their (Tip blk)
theirTip =
(KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n))
-> (KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ \KnownIntersectionState blk
kis ->
Consensus (ClientPipelinedStIdle n) blk m
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Consensus (ClientPipelinedStIdle n) blk m
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Consensus (ClientPipelinedStIdle n) blk m
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$
KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> WithOrigin BlockNo
-> Consensus (ClientPipelinedStIdle n) blk m
forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> WithOrigin BlockNo
-> Consensus (ClientPipelinedStIdle n) blk m
requestNext
KnownIntersectionState blk
kis
MkPipelineDecision
mkPipelineDecision
Nat n
n
Their (Tip blk)
theirTip
(AnchoredFragment (Header blk) -> WithOrigin BlockNo
forall block.
HasHeader block =>
AnchoredFragment block -> WithOrigin BlockNo
AF.headBlockNo (KnownIntersectionState blk -> AnchoredFragment (Header blk)
forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag KnownIntersectionState blk
kis))
offerJump ::
MkPipelineDecision
-> Jumping.JumpInstruction blk
-> Stateful m blk
(KnownIntersectionState blk)
(ClientPipelinedStIdle Z)
offerJump :: MkPipelineDecision
-> JumpInstruction blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
offerJump MkPipelineDecision
mkPipelineDecision JumpInstruction blk
jump = (KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z))
-> (KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall a b. (a -> b) -> a -> b
$ \KnownIntersectionState blk
kis -> do
let jumpInfo :: JumpInfo blk
jumpInfo = case JumpInstruction blk
jump of
Jumping.JumpTo JumpInfo blk
ji -> JumpInfo blk
ji
Jumping.JumpToGoodPoint JumpInfo blk
ji -> JumpInfo blk
ji
dynamoTipPt :: Point blk
dynamoTipPt = Point (Header blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint (AnchoredFragment (Header blk) -> Point (Header blk))
-> AnchoredFragment (Header blk) -> Point (Header blk)
forall a b. (a -> b) -> a -> b
$ JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jTheirFragment JumpInfo blk
jumpInfo
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Point blk -> TraceChainSyncClientEvent blk
forall blk. Point blk -> TraceChainSyncClientEvent blk
TraceOfferJump Point blk
dynamoTipPt
Consensus (ClientPipelinedStIdle 'Z) blk m
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Consensus (ClientPipelinedStIdle 'Z) blk m
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Consensus (ClientPipelinedStIdle 'Z) blk m
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$
[Point blk]
-> ClientPipelinedStIntersect
(Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle 'Z) blk m
forall point header tip (m :: * -> *) a.
[point]
-> ClientPipelinedStIntersect header point tip m a
-> ClientPipelinedStIdle 'Z header point tip m a
SendMsgFindIntersect [Point blk
dynamoTipPt] (ClientPipelinedStIntersect
(Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle 'Z) blk m)
-> ClientPipelinedStIntersect
(Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle 'Z) blk m
forall a b. (a -> b) -> a -> b
$
ClientPipelinedStIntersect {
recvMsgIntersectFound :: Point blk
-> Tip blk -> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
recvMsgIntersectFound = \Point blk
pt Tip blk
theirTip ->
if
| Point blk
pt Point blk -> Point blk -> Bool
forall a. Eq a => a -> a -> Bool
== Point blk
dynamoTipPt -> do
Jumping m blk -> JumpResult blk -> m ()
forall (m :: * -> *) blk. Jumping m blk -> JumpResult blk -> m ()
Jumping.jgProcessJumpResult Jumping m blk
jumping (JumpResult blk -> m ()) -> JumpResult blk -> m ()
forall a b. (a -> b) -> a -> b
$ JumpInstruction blk -> JumpResult blk
forall blk. JumpInstruction blk -> JumpResult blk
Jumping.AcceptedJump JumpInstruction blk
jump
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ JumpResult blk -> TraceChainSyncClientEvent blk
forall blk. JumpResult blk -> TraceChainSyncClientEvent blk
TraceJumpResult (JumpResult blk -> TraceChainSyncClientEvent blk)
-> JumpResult blk -> TraceChainSyncClientEvent blk
forall a b. (a -> b) -> a -> b
$ JumpInstruction blk -> JumpResult blk
forall blk. JumpInstruction blk -> JumpResult blk
Jumping.AcceptedJump JumpInstruction blk
jump
let kis' :: KnownIntersectionState blk
kis' = case JumpInstruction blk
jump of
Jumping.JumpToGoodPoint{} -> KnownIntersectionState blk
-> JumpInfo blk -> KnownIntersectionState blk
combineJumpInfo KnownIntersectionState blk
kis JumpInfo blk
jumpInfo
JumpInstruction blk
_ -> KnownIntersectionState blk
kis
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis' (Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$ MkPipelineDecision
-> Nat 'Z
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep MkPipelineDecision
mkPipelineDecision Nat 'Z
forall (n :: N). ('Z ~ n) => Nat n
Zero (Tip blk -> Their (Tip blk)
forall a. a -> Their a
Their Tip blk
theirTip)
| Bool
otherwise -> ChainSyncClientException
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO ChainSyncClientException
InvalidJumpResponse
,
recvMsgIntersectNotFound :: Tip blk -> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
recvMsgIntersectNotFound = \Tip blk
theirTip -> do
Jumping m blk -> JumpResult blk -> m ()
forall (m :: * -> *) blk. Jumping m blk -> JumpResult blk -> m ()
Jumping.jgProcessJumpResult Jumping m blk
jumping (JumpResult blk -> m ()) -> JumpResult blk -> m ()
forall a b. (a -> b) -> a -> b
$ JumpInstruction blk -> JumpResult blk
forall blk. JumpInstruction blk -> JumpResult blk
Jumping.RejectedJump JumpInstruction blk
jump
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ JumpResult blk -> TraceChainSyncClientEvent blk
forall blk. JumpResult blk -> TraceChainSyncClientEvent blk
TraceJumpResult (JumpResult blk -> TraceChainSyncClientEvent blk)
-> JumpResult blk -> TraceChainSyncClientEvent blk
forall a b. (a -> b) -> a -> b
$ JumpInstruction blk -> JumpResult blk
forall blk. JumpInstruction blk -> JumpResult blk
Jumping.RejectedJump JumpInstruction blk
jump
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis (Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
-> m (Consensus (ClientPipelinedStIdle 'Z) blk m)
forall a b. (a -> b) -> a -> b
$ MkPipelineDecision
-> Nat 'Z
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle 'Z)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep MkPipelineDecision
mkPipelineDecision Nat 'Z
forall (n :: N). ('Z ~ n) => Nat n
Zero (Tip blk -> Their (Tip blk)
forall a. a -> Their a
Their Tip blk
theirTip)
}
where
combineJumpInfo ::
KnownIntersectionState blk
-> JumpInfo blk
-> KnownIntersectionState blk
combineJumpInfo :: KnownIntersectionState blk
-> JumpInfo blk -> KnownIntersectionState blk
combineJumpInfo KnownIntersectionState blk
kis JumpInfo blk
ji =
let mRewoundHistory :: Maybe (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
mRewoundHistory =
Point blk
-> HeaderStateHistory blk
-> Maybe (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
forall blk.
HasAnnTip blk =>
Point blk
-> HeaderStateHistory blk
-> Maybe (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
HeaderStateHistory.rewind
(Point (Header blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
AF.castPoint (Point (Header blk) -> Point blk)
-> Point (Header blk) -> Point blk
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> Point (Header blk)
forall block.
HasHeader block =>
AnchoredFragment block -> Point block
AF.headPoint (AnchoredFragment (Header blk) -> Point (Header blk))
-> AnchoredFragment (Header blk) -> Point (Header blk)
forall a b. (a -> b) -> a -> b
$ JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jTheirFragment JumpInfo blk
ji)
(JumpInfo blk -> HeaderStateHistory blk
forall blk. JumpInfo blk -> HeaderStateHistory blk
jTheirHeaderStateHistory JumpInfo blk
ji)
(HeaderStateHistory blk
rewoundHistory, Maybe (HeaderStateWithTime blk)
_oldestRewound) =
(HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
-> Maybe (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
-> (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
forall a. a -> Maybe a -> a
fromMaybe (String -> (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
forall a. HasCallStack => String -> a
error String
"offerJump: cannot rewind history") Maybe (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
mRewoundHistory
historyNeedsRewinding :: Bool
historyNeedsRewinding =
(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 (JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jTheirFragment JumpInfo blk
ji)) (Point (Header blk) -> Bool) -> Point (Header blk) -> Bool
forall a b. (a -> b) -> a -> b
$
Point blk -> Point (Header blk)
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint (Point blk -> Point (Header blk))
-> Point blk -> Point (Header blk)
forall a b. (a -> b) -> a -> b
$
HeaderState blk -> Point blk
forall blk. HasAnnTip blk => HeaderState blk -> Point blk
headerStatePoint (HeaderState blk -> Point blk)
-> (Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
-> HeaderState blk)
-> Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
-> Point blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeaderStateWithTime blk -> HeaderState blk
forall blk. HeaderStateWithTime blk -> HeaderState blk
hswtHeaderState (HeaderStateWithTime blk -> HeaderState blk)
-> (Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
-> HeaderStateWithTime blk)
-> Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
-> HeaderState blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HeaderStateWithTime blk -> HeaderStateWithTime blk)
-> (HeaderStateWithTime blk -> HeaderStateWithTime blk)
-> Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
-> HeaderStateWithTime blk
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either HeaderStateWithTime blk -> HeaderStateWithTime blk
forall a. a -> a
id HeaderStateWithTime blk -> HeaderStateWithTime blk
forall a. a -> a
id (Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
-> Point blk)
-> Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
-> Point blk
forall a b. (a -> b) -> a -> b
$
AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
-> Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
forall v a b. Anchorable v a b => AnchoredSeq v a b -> Either a b
AF.head (AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
-> Either (HeaderStateWithTime blk) (HeaderStateWithTime blk))
-> AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
-> Either (HeaderStateWithTime blk) (HeaderStateWithTime blk)
forall a b. (a -> b) -> a -> b
$
HeaderStateHistory blk
-> AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
forall blk.
HeaderStateHistory blk
-> AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
HeaderStateHistory.unHeaderStateHistory (HeaderStateHistory blk
-> AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk))
-> HeaderStateHistory blk
-> AnchoredSeq
(WithOrigin SlotNo)
(HeaderStateWithTime blk)
(HeaderStateWithTime blk)
forall a b. (a -> b) -> a -> b
$
JumpInfo blk -> HeaderStateHistory blk
forall blk. JumpInfo blk -> HeaderStateHistory blk
jTheirHeaderStateHistory JumpInfo blk
ji
intersection :: Point blk
intersection
| Bool
historyNeedsRewinding = case AnchoredFragment (Header blk)
-> AnchoredFragment (Header blk) -> Maybe (Point (Header blk))
forall block1 block2.
(HasHeader block1, HasHeader block2,
HeaderHash block1 ~ HeaderHash block2) =>
AnchoredFragment block1
-> AnchoredFragment block2 -> Maybe (Point block1)
AF.intersectionPoint (JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jOurFragment JumpInfo blk
ji) (JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jTheirFragment JumpInfo blk
ji) of
Just Point (Header blk)
po -> Point (Header blk) -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point (Header blk)
po
Maybe (Point (Header blk))
Nothing -> String -> Point blk
forall a. HasCallStack => String -> a
error String
"offerJump: the jumpInfo should have a valid intersection"
| Bool
otherwise = JumpInfo blk -> Point blk
forall blk. JumpInfo blk -> Point blk
jMostRecentIntersection JumpInfo blk
ji
in KnownIntersectionState
{ $sel:mostRecentIntersection:KnownIntersectionState :: Point blk
mostRecentIntersection = Point blk
intersection
, ourFrag :: AnchoredFragment (Header blk)
ourFrag = JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jOurFragment JumpInfo blk
ji
, theirFrag :: AnchoredFragment (Header blk)
theirFrag = JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jTheirFragment JumpInfo blk
ji
, $sel:theirHeaderStateHistory:KnownIntersectionState :: HeaderStateHistory blk
theirHeaderStateHistory = HeaderStateHistory blk
rewoundHistory
, $sel:kBestBlockNo:KnownIntersectionState :: BlockNo
kBestBlockNo = BlockNo -> BlockNo -> BlockNo
forall a. Ord a => a -> a -> a
max (BlockNo -> WithOrigin BlockNo -> BlockNo
forall t. t -> WithOrigin t -> t
fromWithOrigin BlockNo
0 (WithOrigin BlockNo -> BlockNo) -> WithOrigin BlockNo -> BlockNo
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> WithOrigin BlockNo
forall block.
HasHeader block =>
AnchoredFragment block -> WithOrigin BlockNo
AF.headBlockNo (AnchoredFragment (Header blk) -> WithOrigin BlockNo)
-> AnchoredFragment (Header blk) -> WithOrigin BlockNo
forall a b. (a -> b) -> a -> b
$ JumpInfo blk -> AnchoredFragment (Header blk)
forall blk. JumpInfo blk -> AnchoredFragment (Header blk)
jTheirFragment JumpInfo blk
ji) (KnownIntersectionState blk -> BlockNo
forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo KnownIntersectionState blk
kis)
}
requestNext ::
KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> WithOrigin BlockNo
-> Consensus (ClientPipelinedStIdle n) blk m
requestNext :: forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> WithOrigin BlockNo
-> Consensus (ClientPipelinedStIdle n) blk m
requestNext KnownIntersectionState blk
kis MkPipelineDecision
mkPipelineDecision Nat n
n Their (Tip blk)
theirTip WithOrigin BlockNo
candTipBlockNo =
let theirTipBlockNo :: WithOrigin BlockNo
theirTipBlockNo = Tip blk -> WithOrigin BlockNo
forall {k} (b :: k). Tip b -> WithOrigin BlockNo
getTipBlockNo (Their (Tip blk) -> Tip blk
forall a. Their a -> a
unTheir Their (Tip blk)
theirTip)
decision :: (PipelineDecision n, MkPipelineDecision)
decision =
MkPipelineDecision
-> Nat n
-> WithOrigin BlockNo
-> WithOrigin BlockNo
-> (PipelineDecision n, MkPipelineDecision)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> WithOrigin BlockNo
-> WithOrigin BlockNo
-> (PipelineDecision n, MkPipelineDecision)
runPipelineDecision
MkPipelineDecision
mkPipelineDecision
Nat n
n
WithOrigin BlockNo
candTipBlockNo
WithOrigin BlockNo
theirTipBlockNo
onMsgAwaitReply :: m ()
onMsgAwaitReply = do
HistoricityCheck m blk
-> HistoricalChainSyncMessage
-> HeaderStateWithTime blk
-> m (Either HistoricityException ())
forall (m :: * -> *) blk.
HistoricityCheck m blk
-> HistoricalChainSyncMessage
-> HeaderStateWithTime blk
-> m (Either HistoricityException ())
HistoricityCheck.judgeMessageHistoricity
HistoricityCheck m blk
historicityCheck
HistoricalChainSyncMessage
HistoricalMsgAwaitReply
(HeaderStateHistory blk -> HeaderStateWithTime blk
forall blk. HeaderStateHistory blk -> HeaderStateWithTime blk
HeaderStateHistory.current (KnownIntersectionState blk -> HeaderStateHistory blk
forall blk. KnownIntersectionState blk -> HeaderStateHistory blk
theirHeaderStateHistory KnownIntersectionState blk
kis)) m (Either HistoricityException ())
-> (Either HistoricityException () -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left HistoricityException
ex -> ChainSyncClientException -> m ()
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ChainSyncClientException -> m ())
-> ChainSyncClientException -> m ()
forall a b. (a -> b) -> a -> b
$ HistoricityException -> ChainSyncClientException
HistoricityError HistoricityException
ex
Right () -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Idling m -> m ()
forall (m :: * -> *). Idling m -> m ()
idlingStart Idling m
idling
LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbPause LoPBucket m
loPBucket
Jumping m blk -> m ()
forall (m :: * -> *) blk. Jumping m blk -> m ()
Jumping.jgOnAwaitReply Jumping m blk
jumping
in
case (Nat n
n, (PipelineDecision n, MkPipelineDecision)
decision) of
(Nat n
Zero, (PipelineDecision n
Request, MkPipelineDecision
mkPipelineDecision')) ->
m ()
-> ClientStNext
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle 'Z) blk m
forall (m :: * -> *) header point tip a.
m ()
-> ClientStNext 'Z header point tip m a
-> ClientPipelinedStIdle 'Z header point tip m a
SendMsgRequestNext
m ()
onMsgAwaitReply
(KnownIntersectionState blk
-> MkPipelineDecision
-> Nat 'Z
-> ClientStNext
'Z (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision -> Nat n -> Consensus (ClientStNext n) blk m
handleNext KnownIntersectionState blk
kis MkPipelineDecision
mkPipelineDecision' Nat 'Z
forall (n :: N). ('Z ~ n) => Nat n
Zero)
(Nat n
_, (PipelineDecision n
Pipeline, MkPipelineDecision
mkPipelineDecision')) ->
m ()
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle n) blk m
forall (m :: * -> *) (n :: N) header point tip a.
m ()
-> ClientPipelinedStIdle ('S n) header point tip m a
-> ClientPipelinedStIdle n header point tip m a
SendMsgRequestNextPipelined
m ()
onMsgAwaitReply
(ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle n) blk m)
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> Consensus (ClientPipelinedStIdle n) blk m
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk
-> MkPipelineDecision
-> Nat ('S n)
-> Their (Tip blk)
-> WithOrigin BlockNo
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> WithOrigin BlockNo
-> Consensus (ClientPipelinedStIdle n) blk m
requestNext
KnownIntersectionState blk
kis
MkPipelineDecision
mkPipelineDecision'
(Nat n -> Nat ('S n)
forall (m :: N) (n :: N). (m ~ 'S n) => Nat n -> Nat m
Succ Nat n
n)
Their (Tip blk)
theirTip
WithOrigin BlockNo
candTipBlockNo
(Succ Nat n
n', (PipelineDecision n
CollectOrPipeline, MkPipelineDecision
mkPipelineDecision')) ->
Maybe
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> ClientStNext
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (m :: * -> *) (n1 :: N) header point tip a.
Maybe (m (ClientPipelinedStIdle ('S n1) header point tip m a))
-> ClientStNext n1 header point tip m a
-> ClientPipelinedStIdle ('S n1) header point tip m a
CollectResponse
( m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> Maybe
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
forall a. a -> Maybe a
Just
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> Maybe
(m (ClientPipelinedStIdle
('S n)
(Header blk)
(Point blk)
(Tip blk)
m
ChainSyncClientResult)))
-> m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> Maybe
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
forall a b. (a -> b) -> a -> b
$ ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall a b. (a -> b) -> a -> b
$ m ()
-> ClientPipelinedStIdle
('S ('S n))
(Header blk)
(Point blk)
(Tip blk)
m
ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (m :: * -> *) (n :: N) header point tip a.
m ()
-> ClientPipelinedStIdle ('S n) header point tip m a
-> ClientPipelinedStIdle n header point tip m a
SendMsgRequestNextPipelined
m ()
onMsgAwaitReply
(ClientPipelinedStIdle
('S ('S n))
(Header blk)
(Point blk)
(Tip blk)
m
ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
-> ClientPipelinedStIdle
('S ('S n))
(Header blk)
(Point blk)
(Tip blk)
m
ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk
-> MkPipelineDecision
-> Nat ('S ('S n))
-> Their (Tip blk)
-> WithOrigin BlockNo
-> ClientPipelinedStIdle
('S ('S n))
(Header blk)
(Point blk)
(Tip blk)
m
ChainSyncClientResult
forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> WithOrigin BlockNo
-> Consensus (ClientPipelinedStIdle n) blk m
requestNext
KnownIntersectionState blk
kis
MkPipelineDecision
mkPipelineDecision'
(Nat n -> Nat ('S ('S n))
forall (m :: N) (n :: N). (m ~ 'S n) => Nat n -> Nat m
Succ Nat n
n)
Their (Tip blk)
theirTip
WithOrigin BlockNo
candTipBlockNo
)
(KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> ClientStNext
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision -> Nat n -> Consensus (ClientStNext n) blk m
handleNext KnownIntersectionState blk
kis MkPipelineDecision
mkPipelineDecision' Nat n
n')
(Succ Nat n
n', (PipelineDecision n
Collect, MkPipelineDecision
mkPipelineDecision')) ->
Maybe
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> ClientStNext
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
-> ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (m :: * -> *) (n1 :: N) header point tip a.
Maybe (m (ClientPipelinedStIdle ('S n1) header point tip m a))
-> ClientStNext n1 header point tip m a
-> ClientPipelinedStIdle ('S n1) header point tip m a
CollectResponse
Maybe
(m (ClientPipelinedStIdle
('S n) (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
forall a. Maybe a
Nothing
(KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> ClientStNext
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision -> Nat n -> Consensus (ClientStNext n) blk m
handleNext KnownIntersectionState blk
kis MkPipelineDecision
mkPipelineDecision' Nat n
n')
handleNext ::
KnownIntersectionState blk
-> MkPipelineDecision
-> Nat n
-> Consensus (ClientStNext n) blk m
handleNext :: forall (n :: N).
KnownIntersectionState blk
-> MkPipelineDecision -> Nat n -> Consensus (ClientStNext n) blk m
handleNext KnownIntersectionState blk
kis MkPipelineDecision
mkPipelineDecision Nat n
n =
ClientStNext {
recvMsgRollForward :: Header blk
-> Tip blk
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
recvMsgRollForward = \Header blk
hdr Tip blk
theirTip -> do
(Idling m -> m ()
forall (m :: * -> *). Idling m -> m ()
idlingStop Idling m
idling m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbResume LoPBucket m
loPBucket)
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Header blk -> TraceChainSyncClientEvent blk
forall blk. Header blk -> TraceChainSyncClientEvent blk
TraceDownloadedHeader Header blk
hdr
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis (Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall a b. (a -> b) -> a -> b
$
MkPipelineDecision
-> Nat n
-> Header blk
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Header blk
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
rollForward
MkPipelineDecision
mkPipelineDecision
Nat n
n
Header blk
hdr
(Tip blk -> Their (Tip blk)
forall a. a -> Their a
Their Tip blk
theirTip)
,
recvMsgRollBackward :: Point blk
-> Tip blk
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
recvMsgRollBackward = \Point blk
intersection Tip blk
theirTip -> do
(Idling m -> m ()
forall (m :: * -> *). Idling m -> m ()
idlingStop Idling m
idling m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbResume LoPBucket m
loPBucket)
let intersection' :: Point blk
intersection' :: Point blk
intersection' = Point blk -> Point blk
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point blk
intersection
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Point blk -> TraceChainSyncClientEvent blk
forall blk. Point blk -> TraceChainSyncClientEvent blk
TraceRolledBack Point blk
intersection'
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis (Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (ClientPipelinedStIdle
n (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult)
forall a b. (a -> b) -> a -> b
$
MkPipelineDecision
-> Nat n
-> Point blk
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Point blk
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
rollBackward
MkPipelineDecision
mkPipelineDecision
Nat n
n
Point blk
intersection'
(Tip blk -> Their (Tip blk)
forall a. a -> Their a
Their Tip blk
theirTip)
}
rollForward ::
MkPipelineDecision
-> Nat n
-> Header blk
-> Their (Tip blk)
-> Stateful m blk
(KnownIntersectionState blk)
(ClientPipelinedStIdle n)
rollForward :: forall (n :: N).
MkPipelineDecision
-> Nat n
-> Header blk
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
rollForward MkPipelineDecision
mkPipelineDecision Nat n
n Header blk
hdr Their (Tip blk)
theirTip =
(KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n))
-> (KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ \KnownIntersectionState blk
kis -> m (Consensus (ClientPipelinedStIdle n) blk m)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a. m a -> m a
traceException (m (Consensus (ClientPipelinedStIdle n) blk m)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> m (Consensus (ClientPipelinedStIdle n) blk m)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ do
arrival
arrival <- Header blk -> m arrival
recordHeaderArrival Header blk
hdr
Time
arrivalTime <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
let slotNo :: SlotNo
slotNo = Header blk -> SlotNo
forall b. HasHeader b => b -> SlotNo
blockSlot Header blk
hdr
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> m ()
forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> m ()
checkKnownInvalid ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv InternalEnv m blk arrival judgment
intEnv Header blk
hdr
Jumping m blk -> Point (Header blk) -> m ()
forall (m :: * -> *) blk.
Jumping m blk -> Point (Header blk) -> m ()
Jumping.jgOnRollForward Jumping m blk
jumping (Header blk -> Point (Header blk)
forall block. HasHeader block => block -> Point block
blockPoint Header blk
hdr)
STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (DynamicEnv m blk -> WithOrigin SlotNo -> STM m ()
forall (m :: * -> *) blk.
DynamicEnv m blk -> WithOrigin SlotNo -> STM m ()
setLatestSlot DynamicEnv m blk
dynEnv (SlotNo -> WithOrigin SlotNo
forall t. t -> WithOrigin t
NotOrigin SlotNo
slotNo))
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> KnownIntersectionState blk
-> arrival
-> SlotNo
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> KnownIntersectionState blk
-> arrival
-> SlotNo
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
checkTime ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv InternalEnv m blk arrival judgment
intEnv KnownIntersectionState blk
kis arrival
arrival SlotNo
slotNo m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
-> (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime)
NoLongerIntersects ->
()
-> Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState ()
(Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful m blk () (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ Nat n
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n)
forall s (n :: N).
NoThunks s =>
Nat n
-> Stateful m blk s (ClientPipelinedStIdle 'Z)
-> Stateful m blk s (ClientPipelinedStIdle n)
drainThePipe Nat n
n
(Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n))
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
-> Stateful m blk () (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> BlockNo
-> (Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult)
-> Stateful m blk () (ClientPipelinedStIdle 'Z)
findIntersectionTop
ConfigEnv m blk
cfgEnv
DynamicEnv m blk
dynEnv
InternalEnv m blk arrival judgment
intEnv
(KnownIntersectionState blk -> BlockNo
forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo KnownIntersectionState blk
kis)
Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
forall blk.
BlockSupportsProtocol blk =>
Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
NoMoreIntersection
StillIntersects (LedgerView (BlockProtocol blk)
ledgerView, RelativeTime
hdrSlotTime) KnownIntersectionState blk
kis' -> do
KnownIntersectionState blk
kis'' <-
ConfigEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> RelativeTime
-> Their (Tip blk)
-> KnownIntersectionState blk
-> LedgerView (BlockProtocol blk)
-> m (KnownIntersectionState blk)
forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> RelativeTime
-> Their (Tip blk)
-> KnownIntersectionState blk
-> LedgerView (BlockProtocol blk)
-> m (KnownIntersectionState blk)
checkValid ConfigEnv m blk
cfgEnv InternalEnv m blk arrival judgment
intEnv Header blk
hdr RelativeTime
hdrSlotTime Their (Tip blk)
theirTip KnownIntersectionState blk
kis' LedgerView (BlockProtocol blk)
ledgerView
KnownIntersectionState blk
kis''' <- ConfigEnv m blk
-> DynamicEnv m blk
-> Header blk
-> KnownIntersectionState blk
-> m (KnownIntersectionState blk)
forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk)) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> Header blk
-> KnownIntersectionState blk
-> m (KnownIntersectionState blk)
checkLoP ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv Header blk
hdr KnownIntersectionState blk
kis''
STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
Jumping m blk -> KnownIntersectionState blk -> STM m ()
forall (m :: * -> *) blk.
Jumping m blk -> KnownIntersectionState blk -> STM m ()
updateJumpInfoSTM Jumping m blk
jumping KnownIntersectionState blk
kis'''
AnchoredFragment (Header blk) -> STM m ()
setCandidate (KnownIntersectionState blk -> AnchoredFragment (Header blk)
forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag KnownIntersectionState blk
kis''')
STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
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
$ HeaderMetricsTracer m -> (SlotNo, Time) -> STM m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith HeaderMetricsTracer m
headerMetricsTracer (SlotNo
slotNo, Time
arrivalTime)
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis'''
(Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep MkPipelineDecision
mkPipelineDecision Nat n
n Their (Tip blk)
theirTip
rollBackward ::
MkPipelineDecision
-> Nat n
-> Point blk
-> Their (Tip blk)
-> Stateful m blk
(KnownIntersectionState blk)
(ClientPipelinedStIdle n)
rollBackward :: forall (n :: N).
MkPipelineDecision
-> Nat n
-> Point blk
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
rollBackward MkPipelineDecision
mkPipelineDecision Nat n
n Point blk
rollBackPoint Their (Tip blk)
theirTip =
(KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (m :: * -> *) blk s
(st :: * -> * -> * -> (* -> *) -> * -> *).
(s -> m (Consensus st blk m)) -> Stateful m blk s st
Stateful ((KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n))
-> (KnownIntersectionState blk
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall a b. (a -> b) -> a -> b
$ \KnownIntersectionState blk
kis ->
m (Consensus (ClientPipelinedStIdle n) blk m)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a. m a -> m a
traceException
(m (Consensus (ClientPipelinedStIdle n) blk m)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> m (Consensus (ClientPipelinedStIdle n) blk m)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ let KnownIntersectionState {
Point blk
$sel:mostRecentIntersection:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> Point blk
mostRecentIntersection :: Point blk
mostRecentIntersection
, AnchoredFragment (Header blk)
ourFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: AnchoredFragment (Header blk)
ourFrag
, AnchoredFragment (Header blk)
theirFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag :: AnchoredFragment (Header blk)
theirFrag
, HeaderStateHistory blk
$sel:theirHeaderStateHistory:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> HeaderStateHistory blk
theirHeaderStateHistory :: HeaderStateHistory blk
theirHeaderStateHistory
, BlockNo
$sel:kBestBlockNo:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo :: BlockNo
kBestBlockNo
} = KnownIntersectionState blk
kis
in
case Point blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
forall blk.
(BlockSupportsProtocol blk, HasAnnTip blk) =>
Point blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
attemptRollback
Point blk
rollBackPoint
(AnchoredFragment (Header blk)
theirFrag, HeaderStateHistory blk
theirHeaderStateHistory)
of
Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
Nothing ->
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall (n :: N).
Nat n
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
terminateAfterDrain Nat n
n
(ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> ChainSyncClientResult
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$ Point blk
-> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
forall blk.
BlockSupportsProtocol blk =>
Point blk
-> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult
RolledBackPastIntersection
Point blk
rollBackPoint
(AnchoredFragment (Header blk) -> Our (Tip blk)
forall blk.
HasHeader (Header blk) =>
AnchoredFragment (Header blk) -> Our (Tip blk)
ourTipFromChain AnchoredFragment (Header blk)
ourFrag)
Their (Tip blk)
theirTip
Just (AnchoredFragment (Header blk)
theirFrag', HeaderStateHistory blk
theirHeaderStateHistory', Maybe (HeaderStateWithTime blk)
mOldestRewound) -> do
Maybe (HeaderStateWithTime blk)
-> (HeaderStateWithTime blk -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust Maybe (HeaderStateWithTime blk)
mOldestRewound ((HeaderStateWithTime blk -> m ()) -> m ())
-> (HeaderStateWithTime blk -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \HeaderStateWithTime blk
oldestRewound ->
HistoricityCheck m blk
-> HistoricalChainSyncMessage
-> HeaderStateWithTime blk
-> m (Either HistoricityException ())
forall (m :: * -> *) blk.
HistoricityCheck m blk
-> HistoricalChainSyncMessage
-> HeaderStateWithTime blk
-> m (Either HistoricityException ())
HistoricityCheck.judgeMessageHistoricity
HistoricityCheck m blk
historicityCheck
HistoricalChainSyncMessage
HistoricalMsgRollBackward
HeaderStateWithTime blk
oldestRewound m (Either HistoricityException ())
-> (Either HistoricityException () -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left HistoricityException
ex -> ChainSyncClientException -> m ()
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ChainSyncClientException -> m ())
-> ChainSyncClientException -> m ()
forall a b. (a -> b) -> a -> b
$ HistoricityException -> ChainSyncClientException
HistoricityError HistoricityException
ex
Right () -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
let mostRecentIntersection' :: Point blk
mostRecentIntersection' =
if Point (Header blk) -> AnchoredFragment (Header blk) -> Bool
forall block.
HasHeader block =>
Point block -> AnchoredFragment block -> Bool
AF.withinFragmentBounds
(Point blk -> Point (Header blk)
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point blk
rollBackPoint)
AnchoredFragment (Header blk)
ourFrag
then Point blk
rollBackPoint
else Point blk
mostRecentIntersection
kis' :: KnownIntersectionState blk
kis' =
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall blk.
(HasHeader blk, HasHeader (Header blk), HasAnnTip blk,
ConsensusProtocol (BlockProtocol blk), HasCallStack) =>
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
assertKnownIntersectionInvariants
(TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg)
(KnownIntersectionState blk -> KnownIntersectionState blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState {
$sel:mostRecentIntersection:KnownIntersectionState :: Point blk
mostRecentIntersection = Point blk
mostRecentIntersection'
, ourFrag :: AnchoredFragment (Header blk)
ourFrag = AnchoredFragment (Header blk)
ourFrag
, theirFrag :: AnchoredFragment (Header blk)
theirFrag = AnchoredFragment (Header blk)
theirFrag'
, $sel:theirHeaderStateHistory:KnownIntersectionState :: HeaderStateHistory blk
theirHeaderStateHistory = HeaderStateHistory blk
theirHeaderStateHistory'
, BlockNo
$sel:kBestBlockNo:KnownIntersectionState :: BlockNo
kBestBlockNo :: BlockNo
kBestBlockNo
}
STM m () -> m ()
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
Jumping m blk -> KnownIntersectionState blk -> STM m ()
forall (m :: * -> *) blk.
Jumping m blk -> KnownIntersectionState blk -> STM m ()
updateJumpInfoSTM Jumping m blk
jumping KnownIntersectionState blk
kis'
AnchoredFragment (Header blk) -> STM m ()
setCandidate AnchoredFragment (Header blk)
theirFrag'
DynamicEnv m blk -> WithOrigin SlotNo -> STM m ()
forall (m :: * -> *) blk.
DynamicEnv m blk -> WithOrigin SlotNo -> STM m ()
setLatestSlot DynamicEnv m blk
dynEnv (Point blk -> WithOrigin SlotNo
forall {k} (block :: k). Point block -> WithOrigin SlotNo
pointSlot Point blk
rollBackPoint)
Jumping m blk -> WithOrigin SlotNo -> m ()
forall (m :: * -> *) blk.
Jumping m blk -> WithOrigin SlotNo -> m ()
Jumping.jgOnRollBackward Jumping m blk
jumping (Point blk -> WithOrigin SlotNo
forall {k} (block :: k). Point block -> WithOrigin SlotNo
pointSlot Point blk
rollBackPoint)
KnownIntersectionState blk
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState KnownIntersectionState blk
kis' (Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m))
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
-> m (Consensus (ClientPipelinedStIdle n) blk m)
forall a b. (a -> b) -> a -> b
$
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
forall (n :: N).
MkPipelineDecision
-> Nat n
-> Their (Tip blk)
-> Stateful
m blk (KnownIntersectionState blk) (ClientPipelinedStIdle n)
nextStep MkPipelineDecision
mkPipelineDecision Nat n
n Their (Tip blk)
theirTip
updateJumpInfoSTM ::
Jumping.Jumping m blk
-> KnownIntersectionState blk
-> STM m ()
updateJumpInfoSTM :: forall (m :: * -> *) blk.
Jumping m blk -> KnownIntersectionState blk -> STM m ()
updateJumpInfoSTM Jumping m blk
jumping kis :: KnownIntersectionState blk
kis@KnownIntersectionState{AnchoredFragment (Header blk)
ourFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: AnchoredFragment (Header blk)
ourFrag} =
Jumping m blk -> JumpInfo blk -> STM m ()
forall (m :: * -> *) blk. Jumping m blk -> JumpInfo blk -> STM m ()
Jumping.jgUpdateJumpInfo Jumping m blk
jumping JumpInfo
{ jMostRecentIntersection :: Point blk
jMostRecentIntersection = KnownIntersectionState blk -> Point blk
forall blk. KnownIntersectionState blk -> Point blk
mostRecentIntersection KnownIntersectionState blk
kis
, jOurFragment :: AnchoredFragment (Header blk)
jOurFragment = AnchoredFragment (Header blk)
ourFrag
, jTheirFragment :: AnchoredFragment (Header blk)
jTheirFragment = KnownIntersectionState blk -> AnchoredFragment (Header blk)
forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag KnownIntersectionState blk
kis
, jTheirHeaderStateHistory :: HeaderStateHistory blk
jTheirHeaderStateHistory = KnownIntersectionState blk -> HeaderStateHistory blk
forall blk. KnownIntersectionState blk -> HeaderStateHistory blk
theirHeaderStateHistory KnownIntersectionState blk
kis
}
checkKnownInvalid ::
forall m blk arrival judgment.
( IOLike m
, LedgerSupportsProtocol blk
)
=> ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> m ()
checkKnownInvalid :: forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> m ()
checkKnownInvalid ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv InternalEnv m blk arrival judgment
intEnv Header blk
hdr = case ChainHash blk
scrutinee of
ChainHash blk
GenesisHash -> () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
BlockHash HeaderHash blk
hash -> do
HeaderHash blk -> Maybe (ExtValidationError blk)
isInvalidBlock <- STM m (HeaderHash blk -> Maybe (ExtValidationError blk))
-> m (HeaderHash blk -> Maybe (ExtValidationError blk))
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (HeaderHash blk -> Maybe (ExtValidationError blk))
-> m (HeaderHash blk -> Maybe (ExtValidationError blk)))
-> STM m (HeaderHash blk -> Maybe (ExtValidationError blk))
-> m (HeaderHash blk -> Maybe (ExtValidationError blk))
forall a b. (a -> b) -> a -> b
$ WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk))
-> HeaderHash blk -> Maybe (ExtValidationError blk)
forall a. WithFingerprint a -> a
forgetFingerprint (WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk))
-> HeaderHash blk -> Maybe (ExtValidationError blk))
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
-> STM m (HeaderHash blk -> Maybe (ExtValidationError blk))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock
Maybe (ExtValidationError blk)
-> (ExtValidationError blk -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust (HeaderHash blk -> Maybe (ExtValidationError blk)
isInvalidBlock HeaderHash blk
hash) ((ExtValidationError blk -> m ()) -> m ())
-> (ExtValidationError blk -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \ExtValidationError blk
reason ->
ChainSyncClientException -> m ()
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect (ChainSyncClientException -> m ())
-> ChainSyncClientException -> m ()
forall a b. (a -> b) -> a -> b
$ Point blk
-> HeaderHash blk
-> ExtValidationError blk
-> ChainSyncClientException
forall blk.
LedgerSupportsProtocol blk =>
Point blk
-> HeaderHash blk
-> ExtValidationError blk
-> ChainSyncClientException
InvalidBlock (Header blk -> Point blk
forall blk. HasHeader (Header blk) => Header blk -> Point blk
headerPoint Header blk
hdr) HeaderHash blk
hash ExtValidationError blk
reason
where
ConfigEnv {
ChainDbView m blk
$sel:chainDbView:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> ChainDbView m blk
chainDbView :: ChainDbView m blk
chainDbView
, DiffusionPipeliningSupport
$sel:getDiffusionPipeliningSupport:ConfigEnv :: forall (m :: * -> *) blk.
ConfigEnv m blk -> DiffusionPipeliningSupport
getDiffusionPipeliningSupport :: DiffusionPipeliningSupport
getDiffusionPipeliningSupport
} = ConfigEnv m blk
cfgEnv
ChainDbView {
STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
$sel:getIsInvalidBlock:ChainDbView :: forall (m :: * -> *) blk.
ChainDbView m blk
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock :: STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock
} = ChainDbView m blk
chainDbView
DynamicEnv {
$sel:version:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> NodeToNodeVersion
version = NodeToNodeVersion
_version
} = DynamicEnv m blk
dynEnv
InternalEnv {
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
$sel:disconnect:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect :: forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect
} = InternalEnv m blk arrival judgment
intEnv
scrutinee :: ChainHash blk
scrutinee = case DiffusionPipeliningSupport
getDiffusionPipeliningSupport of
DiffusionPipeliningSupport
DiffusionPipeliningOff -> HeaderHash blk -> ChainHash blk
forall {k} (b :: k). HeaderHash b -> ChainHash b
BlockHash (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr)
DiffusionPipeliningSupport
DiffusionPipeliningOn -> Header blk -> ChainHash blk
forall blk. GetPrevHash blk => Header blk -> ChainHash blk
headerPrevHash Header blk
hdr
checkTime ::
forall m blk arrival judgment.
( IOLike m
, LedgerSupportsProtocol blk
)
=> ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> KnownIntersectionState blk
-> arrival
-> SlotNo
-> m (UpdatedIntersectionState blk (LedgerView (BlockProtocol blk), RelativeTime))
checkTime :: forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> InternalEnv m blk arrival judgment
-> KnownIntersectionState blk
-> arrival
-> SlotNo
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
checkTime ConfigEnv m blk
cfgEnv DynamicEnv m blk
dynEnv InternalEnv m blk arrival judgment
intEnv =
\KnownIntersectionState blk
kis arrival
arrival SlotNo
slotNo -> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
forall a. m a -> m a
pauseBucket (m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime)))
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
forall a b. (a -> b) -> a -> b
$ WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk), RelativeTime))
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
forall (m :: * -> *) blk a.
Monad m =>
WithEarlyExit m (Intersects blk a)
-> m (UpdatedIntersectionState blk a)
castEarlyExitIntersects (WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk), RelativeTime))
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime)))
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk), RelativeTime))
-> m (UpdatedIntersectionState
blk (LedgerView (BlockProtocol blk), RelativeTime))
forall a b. (a -> b) -> a -> b
$ do
Intersects KnownIntersectionState blk
kis2 (LedgerState blk
lst, RelativeTime
slotTime) <- KnownIntersectionState blk
-> arrival
-> WithEarlyExit m (Intersects blk (LedgerState blk, RelativeTime))
checkArrivalTime KnownIntersectionState blk
kis arrival
arrival
Intersects KnownIntersectionState blk
kis3 LedgerView (BlockProtocol blk)
ledgerView <- case SlotNo -> LedgerState blk -> Maybe (LedgerView (BlockProtocol blk))
projectLedgerView SlotNo
slotNo LedgerState blk
lst of
Just LedgerView (BlockProtocol blk)
ledgerView -> Intersects blk (LedgerView (BlockProtocol blk))
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk)))
forall a. a -> WithEarlyExit m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Intersects blk (LedgerView (BlockProtocol blk))
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk))))
-> Intersects blk (LedgerView (BlockProtocol blk))
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk)))
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk
-> LedgerView (BlockProtocol blk)
-> Intersects blk (LedgerView (BlockProtocol blk))
forall blk a. KnownIntersectionState blk -> a -> Intersects blk a
Intersects KnownIntersectionState blk
kis2 LedgerView (BlockProtocol blk)
ledgerView
Maybe (LedgerView (BlockProtocol blk))
Nothing -> do
m () -> WithEarlyExit m ()
forall (m :: * -> *) a. Monad m => m a -> WithEarlyExit m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
EarlyExit.lift (m () -> WithEarlyExit m ()) -> m () -> WithEarlyExit m ()
forall a b. (a -> b) -> a -> b
$
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith (ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer ConfigEnv m blk
cfgEnv)
(TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ SlotNo -> TraceChainSyncClientEvent blk
forall blk. SlotNo -> TraceChainSyncClientEvent blk
TraceWaitingBeyondForecastHorizon SlotNo
slotNo
Intersects blk (LedgerView (BlockProtocol blk))
res <- KnownIntersectionState blk
-> (LedgerState blk -> Maybe (LedgerView (BlockProtocol blk)))
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk)))
forall a.
KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> WithEarlyExit m (Intersects blk a)
readLedgerState KnownIntersectionState blk
kis2 (SlotNo -> LedgerState blk -> Maybe (LedgerView (BlockProtocol blk))
projectLedgerView SlotNo
slotNo)
m () -> WithEarlyExit m ()
forall (m :: * -> *) a. Monad m => m a -> WithEarlyExit m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
EarlyExit.lift (m () -> WithEarlyExit m ()) -> m () -> WithEarlyExit m ()
forall a b. (a -> b) -> a -> b
$
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith (ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer ConfigEnv m blk
cfgEnv)
(TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ SlotNo -> TraceChainSyncClientEvent blk
forall blk. SlotNo -> TraceChainSyncClientEvent blk
TraceAccessingForecastHorizon SlotNo
slotNo
Intersects blk (LedgerView (BlockProtocol blk))
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk)))
forall a. a -> WithEarlyExit m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Intersects blk (LedgerView (BlockProtocol blk))
res
Intersects blk (LedgerView (BlockProtocol blk), RelativeTime)
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk), RelativeTime))
forall a. a -> WithEarlyExit m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Intersects blk (LedgerView (BlockProtocol blk), RelativeTime)
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk), RelativeTime)))
-> Intersects blk (LedgerView (BlockProtocol blk), RelativeTime)
-> WithEarlyExit
m (Intersects blk (LedgerView (BlockProtocol blk), RelativeTime))
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk
-> (LedgerView (BlockProtocol blk), RelativeTime)
-> Intersects blk (LedgerView (BlockProtocol blk), RelativeTime)
forall blk a. KnownIntersectionState blk -> a -> Intersects blk a
Intersects KnownIntersectionState blk
kis3 (LedgerView (BlockProtocol blk)
ledgerView, RelativeTime
slotTime)
where
ConfigEnv {
TopLevelConfig blk
$sel:cfg:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg
, ChainDbView m blk
$sel:chainDbView:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> ChainDbView m blk
chainDbView :: ChainDbView m blk
chainDbView
} = ConfigEnv m blk
cfgEnv
ChainDbView {
Point blk -> STM m (Maybe (ExtLedgerState blk))
$sel:getPastLedger:ChainDbView :: forall (m :: * -> *) blk.
ChainDbView m blk
-> Point blk -> STM m (Maybe (ExtLedgerState blk))
getPastLedger :: Point blk -> STM m (Maybe (ExtLedgerState blk))
getPastLedger
} = ChainDbView m blk
chainDbView
InternalEnv {
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
$sel:disconnect:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect :: forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect
, HeaderInFutureCheck m blk arrival judgment
$sel:headerInFutureCheck:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck :: HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck
, KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
$sel:intersectsWithCurrentChain:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain :: KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain
} = InternalEnv m blk arrival judgment
intEnv
InFutureCheck.HeaderInFutureCheck {
judgment -> m (Except HeaderArrivalException RelativeTime)
handleHeaderArrival :: judgment -> m (Except HeaderArrivalException RelativeTime)
handleHeaderArrival :: forall (m :: * -> *) blk arrival judgment.
HeaderInFutureCheck m blk arrival judgment
-> judgment -> m (Except HeaderArrivalException RelativeTime)
handleHeaderArrival
, LedgerConfig blk
-> LedgerState blk
-> arrival
-> Except PastHorizonException judgment
judgeHeaderArrival :: LedgerConfig blk
-> LedgerState blk
-> arrival
-> Except PastHorizonException judgment
judgeHeaderArrival :: forall (m :: * -> *) blk arrival judgment.
HeaderInFutureCheck m blk arrival judgment
-> LedgerConfig blk
-> LedgerState blk
-> arrival
-> Except PastHorizonException judgment
judgeHeaderArrival
} = HeaderInFutureCheck m blk arrival judgment
headerInFutureCheck
checkArrivalTime ::
KnownIntersectionState blk
-> arrival
-> WithEarlyExit m (Intersects blk (LedgerState blk, RelativeTime))
checkArrivalTime :: KnownIntersectionState blk
-> arrival
-> WithEarlyExit m (Intersects blk (LedgerState blk, RelativeTime))
checkArrivalTime KnownIntersectionState blk
kis arrival
arrival = do
Intersects KnownIntersectionState blk
kis' (LedgerState blk
lst, judgment
judgment) <- do
KnownIntersectionState blk
-> (LedgerState blk -> Maybe (LedgerState blk, judgment))
-> WithEarlyExit m (Intersects blk (LedgerState blk, judgment))
forall a.
KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> WithEarlyExit m (Intersects blk a)
readLedgerState KnownIntersectionState blk
kis ((LedgerState blk -> Maybe (LedgerState blk, judgment))
-> WithEarlyExit m (Intersects blk (LedgerState blk, judgment)))
-> (LedgerState blk -> Maybe (LedgerState blk, judgment))
-> WithEarlyExit m (Intersects blk (LedgerState blk, judgment))
forall a b. (a -> b) -> a -> b
$ \LedgerState blk
lst ->
case Except PastHorizonException judgment
-> Either PastHorizonException judgment
forall e a. Except e a -> Either e a
runExcept
(Except PastHorizonException judgment
-> Either PastHorizonException judgment)
-> Except PastHorizonException judgment
-> Either PastHorizonException judgment
forall a b. (a -> b) -> a -> b
$ LedgerConfig blk
-> LedgerState blk
-> arrival
-> Except PastHorizonException judgment
judgeHeaderArrival (TopLevelConfig blk -> LedgerConfig blk
forall blk. TopLevelConfig blk -> LedgerConfig blk
configLedger TopLevelConfig blk
cfg) LedgerState blk
lst arrival
arrival
of
Left PastHorizon{} -> Maybe (LedgerState blk, judgment)
forall a. Maybe a
Nothing
Right judgment
judgment -> (LedgerState blk, judgment) -> Maybe (LedgerState blk, judgment)
forall a. a -> Maybe a
Just (LedgerState blk
lst, judgment
judgment)
m (Intersects blk (LedgerState blk, RelativeTime))
-> WithEarlyExit m (Intersects blk (LedgerState blk, RelativeTime))
forall (m :: * -> *) a. Monad m => m a -> WithEarlyExit m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
EarlyExit.lift (m (Intersects blk (LedgerState blk, RelativeTime))
-> WithEarlyExit
m (Intersects blk (LedgerState blk, RelativeTime)))
-> m (Intersects blk (LedgerState blk, RelativeTime))
-> WithEarlyExit m (Intersects blk (LedgerState blk, RelativeTime))
forall a b. (a -> b) -> a -> b
$ judgment -> m (Except HeaderArrivalException RelativeTime)
handleHeaderArrival judgment
judgment m (Except HeaderArrivalException RelativeTime)
-> (Except HeaderArrivalException RelativeTime
-> Either HeaderArrivalException RelativeTime)
-> m (Either HeaderArrivalException RelativeTime)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> Except HeaderArrivalException RelativeTime
-> Either HeaderArrivalException RelativeTime
forall e a. Except e a -> Either e a
runExcept m (Either HeaderArrivalException RelativeTime)
-> (Either HeaderArrivalException RelativeTime
-> m (Intersects blk (LedgerState blk, RelativeTime)))
-> m (Intersects blk (LedgerState blk, RelativeTime))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left HeaderArrivalException
exn -> ChainSyncClientException
-> m (Intersects blk (LedgerState blk, RelativeTime))
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect (HeaderArrivalException -> ChainSyncClientException
InFutureHeaderExceedsClockSkew HeaderArrivalException
exn)
Right RelativeTime
slotTime -> Intersects blk (LedgerState blk, RelativeTime)
-> m (Intersects blk (LedgerState blk, RelativeTime))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Intersects blk (LedgerState blk, RelativeTime)
-> m (Intersects blk (LedgerState blk, RelativeTime)))
-> Intersects blk (LedgerState blk, RelativeTime)
-> m (Intersects blk (LedgerState blk, RelativeTime))
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk
-> (LedgerState blk, RelativeTime)
-> Intersects blk (LedgerState blk, RelativeTime)
forall blk a. KnownIntersectionState blk -> a -> Intersects blk a
Intersects KnownIntersectionState blk
kis' (LedgerState blk
lst, RelativeTime
slotTime)
readLedgerState ::
forall a.
KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> WithEarlyExit m (Intersects blk a)
readLedgerState :: forall a.
KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> WithEarlyExit m (Intersects blk a)
readLedgerState KnownIntersectionState blk
kis LedgerState blk -> Maybe a
prj = m (WithEarlyExit m (Intersects blk a))
-> WithEarlyExit m (Intersects blk a)
forall (m :: * -> *) x.
Monad m =>
m (WithEarlyExit m x) -> WithEarlyExit m x
castM (m (WithEarlyExit m (Intersects blk a))
-> WithEarlyExit m (Intersects blk a))
-> m (WithEarlyExit m (Intersects blk a))
-> WithEarlyExit m (Intersects blk a)
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> m (WithEarlyExit m (Intersects blk a))
forall a.
KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> m (WithEarlyExit m (Intersects blk a))
readLedgerStateHelper KnownIntersectionState blk
kis LedgerState blk -> Maybe a
prj
readLedgerStateHelper ::
forall a.
KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> m (WithEarlyExit m (Intersects blk a))
readLedgerStateHelper :: forall a.
KnownIntersectionState blk
-> (LedgerState blk -> Maybe a)
-> m (WithEarlyExit m (Intersects blk a))
readLedgerStateHelper KnownIntersectionState blk
kis LedgerState blk -> Maybe a
prj = STM m (WithEarlyExit m (Intersects blk a))
-> m (WithEarlyExit m (Intersects blk a))
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (WithEarlyExit m (Intersects blk a))
-> m (WithEarlyExit m (Intersects blk a)))
-> STM m (WithEarlyExit m (Intersects blk a))
-> m (WithEarlyExit m (Intersects blk a))
forall a b. (a -> b) -> a -> b
$ do
KnownIntersectionState blk
-> STM m (UpdatedIntersectionState blk ())
intersectsWithCurrentChain KnownIntersectionState blk
kis STM m (UpdatedIntersectionState blk ())
-> (UpdatedIntersectionState blk ()
-> STM m (WithEarlyExit m (Intersects blk a)))
-> STM m (WithEarlyExit m (Intersects blk a))
forall a b. STM m a -> (a -> STM m b) -> STM m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
UpdatedIntersectionState blk ()
NoLongerIntersects -> WithEarlyExit m (Intersects blk a)
-> STM m (WithEarlyExit m (Intersects blk a))
forall a. a -> STM m a
forall (m :: * -> *) a. Monad m => a -> m a
return WithEarlyExit m (Intersects blk a)
forall (m :: * -> *) a. Applicative m => WithEarlyExit m a
exitEarly
StillIntersects () KnownIntersectionState blk
kis' -> do
let KnownIntersectionState {
Point blk
$sel:mostRecentIntersection:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> Point blk
mostRecentIntersection :: Point blk
mostRecentIntersection
} = KnownIntersectionState blk
kis'
LedgerState blk
lst <-
(Maybe (ExtLedgerState blk) -> LedgerState blk)
-> STM m (Maybe (ExtLedgerState blk)) -> STM m (LedgerState blk)
forall a b. (a -> b) -> STM m a -> STM m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
(LedgerState blk
-> (ExtLedgerState blk -> LedgerState blk)
-> Maybe (ExtLedgerState blk)
-> LedgerState blk
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> LedgerState blk
forall a. HasCallStack => String -> a
error (String -> LedgerState blk) -> String -> LedgerState blk
forall a b. (a -> b) -> a -> b
$
String
"intersection not within last k blocks: "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Point blk -> String
forall a. Show a => a -> String
show Point blk
mostRecentIntersection
)
ExtLedgerState blk -> LedgerState blk
forall blk. ExtLedgerState blk -> LedgerState blk
ledgerState
)
(STM m (Maybe (ExtLedgerState blk)) -> STM m (LedgerState blk))
-> STM m (Maybe (ExtLedgerState blk)) -> STM m (LedgerState blk)
forall a b. (a -> b) -> a -> b
$ Point blk -> STM m (Maybe (ExtLedgerState blk))
getPastLedger Point blk
mostRecentIntersection
case LedgerState blk -> Maybe a
prj LedgerState blk
lst of
Maybe a
Nothing -> STM m (WithEarlyExit m (Intersects blk a))
forall a. STM m a
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
Just a
ledgerView ->
WithEarlyExit m (Intersects blk a)
-> STM m (WithEarlyExit m (Intersects blk a))
forall a. a -> STM m a
forall (m :: * -> *) a. Monad m => a -> m a
return (WithEarlyExit m (Intersects blk a)
-> STM m (WithEarlyExit m (Intersects blk a)))
-> WithEarlyExit m (Intersects blk a)
-> STM m (WithEarlyExit m (Intersects blk a))
forall a b. (a -> b) -> a -> b
$ Intersects blk a -> WithEarlyExit m (Intersects blk a)
forall a. a -> WithEarlyExit m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Intersects blk a -> WithEarlyExit m (Intersects blk a))
-> Intersects blk a -> WithEarlyExit m (Intersects blk a)
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk -> a -> Intersects blk a
forall blk a. KnownIntersectionState blk -> a -> Intersects blk a
Intersects KnownIntersectionState blk
kis' a
ledgerView
projectLedgerView ::
SlotNo
-> LedgerState blk
-> Maybe (LedgerView (BlockProtocol blk))
projectLedgerView :: SlotNo -> LedgerState blk -> Maybe (LedgerView (BlockProtocol blk))
projectLedgerView SlotNo
slot LedgerState blk
lst =
let forecast :: Forecast (LedgerView (BlockProtocol blk))
forecast = LedgerConfig blk
-> LedgerState blk -> Forecast (LedgerView (BlockProtocol blk))
forall blk.
(LedgerSupportsProtocol blk, HasCallStack) =>
LedgerConfig blk
-> LedgerState blk -> Forecast (LedgerView (BlockProtocol blk))
ledgerViewForecastAt (TopLevelConfig blk -> LedgerConfig blk
forall blk. TopLevelConfig blk -> LedgerConfig blk
configLedger TopLevelConfig blk
cfg) LedgerState blk
lst
in
case Except OutsideForecastRange (LedgerView (BlockProtocol blk))
-> Either OutsideForecastRange (LedgerView (BlockProtocol blk))
forall e a. Except e a -> Either e a
runExcept (Except OutsideForecastRange (LedgerView (BlockProtocol blk))
-> Either OutsideForecastRange (LedgerView (BlockProtocol blk)))
-> Except OutsideForecastRange (LedgerView (BlockProtocol blk))
-> Either OutsideForecastRange (LedgerView (BlockProtocol blk))
forall a b. (a -> b) -> a -> b
$ Forecast (LedgerView (BlockProtocol blk))
-> SlotNo
-> Except OutsideForecastRange (LedgerView (BlockProtocol blk))
forall a. Forecast a -> SlotNo -> Except OutsideForecastRange a
forecastFor Forecast (LedgerView (BlockProtocol blk))
forecast SlotNo
slot of
Right LedgerView (BlockProtocol blk)
ledgerView -> LedgerView (BlockProtocol blk)
-> Maybe (LedgerView (BlockProtocol blk))
forall a. a -> Maybe a
Just LedgerView (BlockProtocol blk)
ledgerView
Left OutsideForecastRange{} ->
Maybe (LedgerView (BlockProtocol blk))
forall a. Maybe a
Nothing
pauseBucket :: m a -> m a
pauseBucket :: forall a. m a -> m a
pauseBucket =
m () -> m () -> m a -> m a
forall a b c. m a -> m b -> m c -> m c
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> m b -> m c -> m c
bracket_
(LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbPause (DynamicEnv m blk -> LoPBucket m
forall (m :: * -> *) blk. DynamicEnv m blk -> LoPBucket m
loPBucket DynamicEnv m blk
dynEnv))
(LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbResume (DynamicEnv m blk -> LoPBucket m
forall (m :: * -> *) blk. DynamicEnv m blk -> LoPBucket m
loPBucket DynamicEnv m blk
dynEnv))
checkValid ::
forall m blk arrival judgment.
( IOLike m
, LedgerSupportsProtocol blk
)
=> ConfigEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> RelativeTime
-> Their (Tip blk)
-> KnownIntersectionState blk
-> LedgerView (BlockProtocol blk)
-> m (KnownIntersectionState blk)
checkValid :: forall (m :: * -> *) blk arrival judgment.
(IOLike m, LedgerSupportsProtocol blk) =>
ConfigEnv m blk
-> InternalEnv m blk arrival judgment
-> Header blk
-> RelativeTime
-> Their (Tip blk)
-> KnownIntersectionState blk
-> LedgerView (BlockProtocol blk)
-> m (KnownIntersectionState blk)
checkValid ConfigEnv m blk
cfgEnv InternalEnv m blk arrival judgment
intEnv Header blk
hdr RelativeTime
hdrSlotTime Their (Tip blk)
theirTip KnownIntersectionState blk
kis LedgerView (BlockProtocol blk)
ledgerView = do
let KnownIntersectionState {
Point blk
$sel:mostRecentIntersection:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> Point blk
mostRecentIntersection :: Point blk
mostRecentIntersection
, AnchoredFragment (Header blk)
ourFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
ourFrag :: AnchoredFragment (Header blk)
ourFrag
, AnchoredFragment (Header blk)
theirFrag :: forall blk.
KnownIntersectionState blk -> AnchoredFragment (Header blk)
theirFrag :: AnchoredFragment (Header blk)
theirFrag
, HeaderStateHistory blk
$sel:theirHeaderStateHistory:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> HeaderStateHistory blk
theirHeaderStateHistory :: HeaderStateHistory blk
theirHeaderStateHistory
, BlockNo
$sel:kBestBlockNo:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo :: BlockNo
kBestBlockNo
} = KnownIntersectionState blk
kis
let hdrPoint :: Point blk
hdrPoint = Header blk -> Point blk
forall blk. HasHeader (Header blk) => Header blk -> Point blk
headerPoint Header blk
hdr
HeaderStateHistory blk
theirHeaderStateHistory' <-
case Except (HeaderError blk) (HeaderStateHistory blk)
-> Either (HeaderError blk) (HeaderStateHistory blk)
forall e a. Except e a -> Either e a
runExcept
(Except (HeaderError blk) (HeaderStateHistory blk)
-> Either (HeaderError blk) (HeaderStateHistory blk))
-> Except (HeaderError blk) (HeaderStateHistory blk)
-> Either (HeaderError blk) (HeaderStateHistory blk)
forall a b. (a -> b) -> a -> b
$ TopLevelConfig blk
-> LedgerView (BlockProtocol blk)
-> Header blk
-> RelativeTime
-> HeaderStateHistory blk
-> Except (HeaderError blk) (HeaderStateHistory blk)
forall blk.
(BlockSupportsProtocol blk, ValidateEnvelope blk) =>
TopLevelConfig blk
-> LedgerView (BlockProtocol blk)
-> Header blk
-> RelativeTime
-> HeaderStateHistory blk
-> Except (HeaderError blk) (HeaderStateHistory blk)
validateHeader TopLevelConfig blk
cfg LedgerView (BlockProtocol blk)
ledgerView Header blk
hdr RelativeTime
hdrSlotTime HeaderStateHistory blk
theirHeaderStateHistory
of
Right HeaderStateHistory blk
theirHeaderStateHistory' -> HeaderStateHistory blk -> m (HeaderStateHistory blk)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return HeaderStateHistory blk
theirHeaderStateHistory'
Left HeaderError blk
vErr ->
ChainSyncClientException -> m (HeaderStateHistory blk)
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect
(ChainSyncClientException -> m (HeaderStateHistory blk))
-> ChainSyncClientException -> m (HeaderStateHistory blk)
forall a b. (a -> b) -> a -> b
$ Point blk
-> HeaderError blk
-> Our (Tip blk)
-> Their (Tip blk)
-> ChainSyncClientException
forall blk.
(BlockSupportsProtocol blk, ValidateEnvelope blk) =>
Point blk
-> HeaderError blk
-> Our (Tip blk)
-> Their (Tip blk)
-> ChainSyncClientException
HeaderError Point blk
hdrPoint HeaderError blk
vErr (AnchoredFragment (Header blk) -> Our (Tip blk)
forall blk.
HasHeader (Header blk) =>
AnchoredFragment (Header blk) -> Our (Tip blk)
ourTipFromChain AnchoredFragment (Header blk)
ourFrag) Their (Tip blk)
theirTip
let theirFrag' :: AnchoredFragment (Header blk)
theirFrag' = AnchoredFragment (Header blk)
theirFrag AnchoredFragment (Header blk)
-> Header blk -> AnchoredFragment (Header blk)
forall v a b.
Anchorable v a b =>
AnchoredSeq v a b -> b -> AnchoredSeq v a b
:> Header blk
hdr
mostRecentIntersection' :: Point blk
mostRecentIntersection'
| Just Header blk
ourSuccessor <-
Point (Header blk)
-> AnchoredFragment (Header blk) -> Maybe (Header blk)
forall block.
HasHeader block =>
Point block -> AnchoredFragment block -> Maybe block
AF.successorBlock (Point blk -> Point (Header blk)
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point blk
mostRecentIntersection) AnchoredFragment (Header blk)
ourFrag
, Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
ourSuccessor HeaderHash blk -> HeaderHash blk -> Bool
forall a. Eq a => a -> a -> Bool
== Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr
= Header blk -> Point blk
forall blk. HasHeader (Header blk) => Header blk -> Point blk
headerPoint Header blk
hdr
| Bool
otherwise
= Point blk
mostRecentIntersection
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith (ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer ConfigEnv m blk
cfgEnv) (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Header blk -> TraceChainSyncClientEvent blk
forall blk. Header blk -> TraceChainSyncClientEvent blk
TraceValidatedHeader Header blk
hdr
KnownIntersectionState blk -> m (KnownIntersectionState blk)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(KnownIntersectionState blk -> m (KnownIntersectionState blk))
-> KnownIntersectionState blk -> m (KnownIntersectionState blk)
forall a b. (a -> b) -> a -> b
$ ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall blk.
(HasHeader blk, HasHeader (Header blk), HasAnnTip blk,
ConsensusProtocol (BlockProtocol blk), HasCallStack) =>
ConsensusConfig (BlockProtocol blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
assertKnownIntersectionInvariants (TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
forall blk.
TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configConsensus TopLevelConfig blk
cfg)
(KnownIntersectionState blk -> KnownIntersectionState blk)
-> KnownIntersectionState blk -> KnownIntersectionState blk
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState {
$sel:mostRecentIntersection:KnownIntersectionState :: Point blk
mostRecentIntersection = Point blk
mostRecentIntersection'
, ourFrag :: AnchoredFragment (Header blk)
ourFrag = AnchoredFragment (Header blk)
ourFrag
, theirFrag :: AnchoredFragment (Header blk)
theirFrag = AnchoredFragment (Header blk)
theirFrag'
, $sel:theirHeaderStateHistory:KnownIntersectionState :: HeaderStateHistory blk
theirHeaderStateHistory = HeaderStateHistory blk
theirHeaderStateHistory'
, BlockNo
$sel:kBestBlockNo:KnownIntersectionState :: BlockNo
kBestBlockNo :: BlockNo
kBestBlockNo
}
where
ConfigEnv {
TopLevelConfig blk
$sel:cfg:ConfigEnv :: forall (m :: * -> *) blk. ConfigEnv m blk -> TopLevelConfig blk
cfg :: TopLevelConfig blk
cfg
} = ConfigEnv m blk
cfgEnv
InternalEnv {
forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
$sel:disconnect:InternalEnv :: forall (m :: * -> *) blk arrival judgment.
InternalEnv m blk arrival judgment
-> forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect :: forall (m' :: * -> *) a.
MonadThrow m' =>
ChainSyncClientException -> m' a
disconnect
} = InternalEnv m blk arrival judgment
intEnv
checkLoP ::
forall m blk.
( IOLike m
, HasHeader (Header blk) )
=> ConfigEnv m blk
-> DynamicEnv m blk
-> Header blk
-> KnownIntersectionState blk
-> m (KnownIntersectionState blk)
checkLoP :: forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk)) =>
ConfigEnv m blk
-> DynamicEnv m blk
-> Header blk
-> KnownIntersectionState blk
-> m (KnownIntersectionState blk)
checkLoP ConfigEnv{Tracer m (TraceChainSyncClientEvent blk)
$sel:tracer:ConfigEnv :: forall (m :: * -> *) blk.
ConfigEnv m blk -> Tracer m (TraceChainSyncClientEvent blk)
tracer :: Tracer m (TraceChainSyncClientEvent blk)
tracer} DynamicEnv{LoPBucket m
$sel:loPBucket:DynamicEnv :: forall (m :: * -> *) blk. DynamicEnv m blk -> LoPBucket m
loPBucket :: LoPBucket m
loPBucket} Header blk
hdr kis :: KnownIntersectionState blk
kis@KnownIntersectionState{BlockNo
$sel:kBestBlockNo:KnownIntersectionState :: forall blk. KnownIntersectionState blk -> BlockNo
kBestBlockNo :: BlockNo
kBestBlockNo} =
if Header blk -> BlockNo
forall b. HasHeader b => b -> BlockNo
blockNo Header blk
hdr BlockNo -> BlockNo -> Bool
forall a. Ord a => a -> a -> Bool
> BlockNo
kBestBlockNo
then do LoPBucket m -> m ()
forall (m :: * -> *). LoPBucket m -> m ()
lbGrantToken LoPBucket m
loPBucket
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Bool -> Header blk -> BlockNo -> TraceChainSyncClientEvent blk
forall blk.
Bool -> Header blk -> BlockNo -> TraceChainSyncClientEvent blk
TraceGaveLoPToken Bool
True Header blk
hdr BlockNo
kBestBlockNo
KnownIntersectionState blk -> m (KnownIntersectionState blk)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (KnownIntersectionState blk -> m (KnownIntersectionState blk))
-> KnownIntersectionState blk -> m (KnownIntersectionState blk)
forall a b. (a -> b) -> a -> b
$ KnownIntersectionState blk
kis{kBestBlockNo = blockNo hdr}
else do Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Bool -> Header blk -> BlockNo -> TraceChainSyncClientEvent blk
forall blk.
Bool -> Header blk -> BlockNo -> TraceChainSyncClientEvent blk
TraceGaveLoPToken Bool
False Header blk
hdr BlockNo
kBestBlockNo
KnownIntersectionState blk -> m (KnownIntersectionState blk)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure KnownIntersectionState blk
kis
data UpdatedIntersectionState blk a =
NoLongerIntersects
|
StillIntersects a !(KnownIntersectionState blk)
data Intersects blk a =
Intersects
(KnownIntersectionState blk)
a
castEarlyExitIntersects ::
Monad m
=> WithEarlyExit m (Intersects blk a)
-> m (UpdatedIntersectionState blk a)
castEarlyExitIntersects :: forall (m :: * -> *) blk a.
Monad m =>
WithEarlyExit m (Intersects blk a)
-> m (UpdatedIntersectionState blk a)
castEarlyExitIntersects =
(Maybe (Intersects blk a) -> UpdatedIntersectionState blk a)
-> m (Maybe (Intersects blk a))
-> m (UpdatedIntersectionState blk a)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe (Intersects blk a) -> UpdatedIntersectionState blk a
forall {blk} {a}.
Maybe (Intersects blk a) -> UpdatedIntersectionState blk a
cnv (m (Maybe (Intersects blk a))
-> m (UpdatedIntersectionState blk a))
-> (WithEarlyExit m (Intersects blk a)
-> m (Maybe (Intersects blk a)))
-> WithEarlyExit m (Intersects blk a)
-> m (UpdatedIntersectionState blk a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WithEarlyExit m (Intersects blk a) -> m (Maybe (Intersects blk a))
forall (m :: * -> *) a. WithEarlyExit m a -> m (Maybe a)
EarlyExit.withEarlyExit
where
cnv :: Maybe (Intersects blk a) -> UpdatedIntersectionState blk a
cnv = \case
Maybe (Intersects blk a)
Nothing -> UpdatedIntersectionState blk a
forall blk a. UpdatedIntersectionState blk a
NoLongerIntersects
Just (Intersects KnownIntersectionState blk
kis a
a) -> a -> KnownIntersectionState blk -> UpdatedIntersectionState blk a
forall blk a.
a -> KnownIntersectionState blk -> UpdatedIntersectionState blk a
StillIntersects a
a KnownIntersectionState blk
kis
mkOffsets :: SecurityParam -> Word64 -> [Word64]
mkOffsets :: SecurityParam -> Word64 -> [Word64]
mkOffsets (SecurityParam Word64
k) Word64
maxOffset =
[Word64
0] [Word64] -> [Word64] -> [Word64]
forall a. [a] -> [a] -> [a]
++ (Word64 -> Bool) -> [Word64] -> [Word64]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
l) [Word64 -> Word64
fib Word64
n | Word64
n <- [Word64
2..]] [Word64] -> [Word64] -> [Word64]
forall a. [a] -> [a] -> [a]
++ [Word64
l]
where
l :: Word64
l = Word64
k Word64 -> Word64 -> Word64
forall a. Ord a => a -> a -> a
`min` Word64
maxOffset
ourTipFromChain ::
HasHeader (Header blk)
=> AnchoredFragment (Header blk)
-> Our (Tip blk)
ourTipFromChain :: forall blk.
HasHeader (Header blk) =>
AnchoredFragment (Header blk) -> Our (Tip blk)
ourTipFromChain = Tip blk -> Our (Tip blk)
forall a. a -> Our a
Our (Tip blk -> Our (Tip blk))
-> (AnchoredFragment (Header blk) -> Tip blk)
-> AnchoredFragment (Header blk)
-> Our (Tip blk)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Anchor (Header blk) -> Tip blk
forall a b. (HeaderHash a ~ HeaderHash b) => Anchor a -> Tip b
AF.anchorToTip (Anchor (Header blk) -> Tip blk)
-> (AnchoredFragment (Header blk) -> Anchor (Header blk))
-> AnchoredFragment (Header blk)
-> Tip blk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnchoredFragment (Header blk) -> Anchor (Header blk)
forall v a b. Anchorable v a b => AnchoredSeq v a b -> a
AF.headAnchor
castM :: Monad m => m (WithEarlyExit m x) -> WithEarlyExit m x
castM :: forall (m :: * -> *) x.
Monad m =>
m (WithEarlyExit m x) -> WithEarlyExit m x
castM = WithEarlyExit m (WithEarlyExit m x) -> WithEarlyExit m x
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (WithEarlyExit m (WithEarlyExit m x) -> WithEarlyExit m x)
-> (m (WithEarlyExit m x) -> WithEarlyExit m (WithEarlyExit m x))
-> m (WithEarlyExit m x)
-> WithEarlyExit m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (WithEarlyExit m x) -> WithEarlyExit m (WithEarlyExit m x)
forall (m :: * -> *) a. Monad m => m a -> WithEarlyExit m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
EarlyExit.lift
attemptRollback ::
( BlockSupportsProtocol blk
, HasAnnTip blk
)
=> Point blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> Maybe
( AnchoredFragment (Header blk)
, HeaderStateHistory blk
,
Maybe (HeaderStateWithTime blk)
)
attemptRollback :: forall blk.
(BlockSupportsProtocol blk, HasAnnTip blk) =>
Point blk
-> (AnchoredFragment (Header blk), HeaderStateHistory blk)
-> Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
attemptRollback Point blk
rollBackPoint (AnchoredFragment (Header blk)
frag, HeaderStateHistory blk
state) = do
AnchoredFragment (Header blk)
frag' <- Point (Header blk)
-> AnchoredFragment (Header blk)
-> Maybe (AnchoredFragment (Header blk))
forall block.
HasHeader block =>
Point block
-> AnchoredFragment block -> Maybe (AnchoredFragment block)
AF.rollback (Point blk -> Point (Header blk)
forall {k1} {k2} (b :: k1) (b' :: k2).
Coercible (HeaderHash b) (HeaderHash b') =>
Point b -> Point b'
castPoint Point blk
rollBackPoint) AnchoredFragment (Header blk)
frag
(HeaderStateHistory blk
state', Maybe (HeaderStateWithTime blk)
oldestRewound) <- Point blk
-> HeaderStateHistory blk
-> Maybe (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
forall blk.
HasAnnTip blk =>
Point blk
-> HeaderStateHistory blk
-> Maybe (HeaderStateHistory blk, Maybe (HeaderStateWithTime blk))
HeaderStateHistory.rewind Point blk
rollBackPoint HeaderStateHistory blk
state
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
-> Maybe
(AnchoredFragment (Header blk), HeaderStateHistory blk,
Maybe (HeaderStateWithTime blk))
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (AnchoredFragment (Header blk)
frag', HeaderStateHistory blk
state', Maybe (HeaderStateWithTime blk)
oldestRewound)
invalidBlockRejector ::
forall m blk.
( IOLike m
, LedgerSupportsProtocol blk
)
=> Tracer m (TraceChainSyncClientEvent blk)
-> NodeToNodeVersion
-> DiffusionPipeliningSupport
-> STM m (WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk)))
-> STM m (AnchoredFragment (Header blk))
-> Watcher m
(WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk)))
Fingerprint
invalidBlockRejector :: forall (m :: * -> *) blk.
(IOLike m, LedgerSupportsProtocol blk) =>
Tracer m (TraceChainSyncClientEvent blk)
-> NodeToNodeVersion
-> DiffusionPipeliningSupport
-> STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
-> STM m (AnchoredFragment (Header blk))
-> Watcher
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
Fingerprint
invalidBlockRejector Tracer m (TraceChainSyncClientEvent blk)
tracer NodeToNodeVersion
_version DiffusionPipeliningSupport
pipelining STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock STM m (AnchoredFragment (Header blk))
getCandidate =
Watcher {
wFingerprint :: WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk))
-> Fingerprint
wFingerprint = WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk))
-> Fingerprint
forall a. WithFingerprint a -> Fingerprint
getFingerprint
, wInitial :: Maybe Fingerprint
wInitial = Maybe Fingerprint
forall a. Maybe a
Nothing
, wNotify :: WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk))
-> m ()
wNotify = (HeaderHash blk -> Maybe (ExtValidationError blk)) -> m ()
checkInvalid ((HeaderHash blk -> Maybe (ExtValidationError blk)) -> m ())
-> (WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk))
-> HeaderHash blk -> Maybe (ExtValidationError blk))
-> WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WithFingerprint (HeaderHash blk -> Maybe (ExtValidationError blk))
-> HeaderHash blk -> Maybe (ExtValidationError blk)
forall a. WithFingerprint a -> a
forgetFingerprint
, wReader :: STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
wReader = STM
m
(WithFingerprint
(HeaderHash blk -> Maybe (ExtValidationError blk)))
getIsInvalidBlock
}
where
checkInvalid :: (HeaderHash blk -> Maybe (ExtValidationError blk)) -> m ()
checkInvalid :: (HeaderHash blk -> Maybe (ExtValidationError blk)) -> m ()
checkInvalid HeaderHash blk -> Maybe (ExtValidationError blk)
isInvalidBlock = do
AnchoredFragment (Header blk)
theirFrag <- STM m (AnchoredFragment (Header blk))
-> m (AnchoredFragment (Header blk))
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically STM m (AnchoredFragment (Header blk))
getCandidate
((Header blk, ExtValidationError blk) -> m ())
-> Maybe (Header blk, ExtValidationError blk) -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Header blk -> ExtValidationError blk -> m ())
-> (Header blk, ExtValidationError blk) -> m ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Header blk -> ExtValidationError blk -> m ()
disconnect)
(Maybe (Header blk, ExtValidationError blk) -> m ())
-> Maybe (Header blk, ExtValidationError blk) -> m ()
forall a b. (a -> b) -> a -> b
$ (Header blk -> Maybe (Header blk, ExtValidationError blk))
-> [Header blk] -> Maybe (Header blk, ExtValidationError blk)
forall a b (f :: * -> *).
Foldable f =>
(a -> Maybe b) -> f a -> Maybe b
firstJust
(\Header blk
hdr -> (Header blk
hdr,) (ExtValidationError blk -> (Header blk, ExtValidationError blk))
-> Maybe (ExtValidationError blk)
-> Maybe (Header blk, ExtValidationError blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HeaderHash blk -> Maybe (ExtValidationError blk)
isInvalidBlock (Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
hdr))
([Header blk] -> Maybe (Header blk, ExtValidationError blk))
-> [Header blk] -> Maybe (Header blk, ExtValidationError blk)
forall a b. (a -> b) -> a -> b
$ ( case DiffusionPipeliningSupport
pipelining of
DiffusionPipeliningSupport
DiffusionPipeliningOn -> Int -> [Header blk] -> [Header blk]
forall a. Int -> [a] -> [a]
drop Int
1
DiffusionPipeliningSupport
DiffusionPipeliningOff -> [Header blk] -> [Header blk]
forall a. a -> a
id
)
([Header blk] -> [Header blk]) -> [Header blk] -> [Header blk]
forall a b. (a -> b) -> a -> b
$ AnchoredFragment (Header blk) -> [Header blk]
forall v a b. AnchoredSeq v a b -> [b]
AF.toNewestFirst AnchoredFragment (Header blk)
theirFrag
disconnect :: Header blk -> ExtValidationError blk -> m ()
disconnect :: Header blk -> ExtValidationError blk -> m ()
disconnect Header blk
invalidHeader ExtValidationError blk
reason = do
let ex :: ChainSyncClientException
ex =
Point blk
-> HeaderHash blk
-> ExtValidationError blk
-> ChainSyncClientException
forall blk.
LedgerSupportsProtocol blk =>
Point blk
-> HeaderHash blk
-> ExtValidationError blk
-> ChainSyncClientException
InvalidBlock
(Header blk -> Point blk
forall blk. HasHeader (Header blk) => Header blk -> Point blk
headerPoint Header blk
invalidHeader)
(Header blk -> HeaderHash blk
forall blk. HasHeader (Header blk) => Header blk -> HeaderHash blk
headerHash Header blk
invalidHeader)
ExtValidationError blk
reason
Tracer m (TraceChainSyncClientEvent blk)
-> TraceChainSyncClientEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncClientEvent blk)
tracer (TraceChainSyncClientEvent blk -> m ())
-> TraceChainSyncClientEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ ChainSyncClientException -> TraceChainSyncClientEvent blk
forall blk.
ChainSyncClientException -> TraceChainSyncClientEvent blk
TraceException ChainSyncClientException
ex
ChainSyncClientException -> m ()
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO ChainSyncClientException
ex
newtype Stateful m blk s st = Stateful (s -> m (Consensus st blk m))
continueWithState ::
NoThunks s
=> s
-> Stateful m blk s st
-> m (Consensus st blk m)
continueWithState :: forall s (m :: * -> *) blk
(st :: * -> * -> * -> (* -> *) -> * -> *).
NoThunks s =>
s -> Stateful m blk s st -> m (Consensus st blk m)
continueWithState !s
s (Stateful s -> m (Consensus st blk m)
f) =
Maybe String -> m (Consensus st blk m) -> m (Consensus st blk m)
forall a. HasCallStack => Maybe String -> a -> a
checkInvariant (ThunkInfo -> String
forall a. Show a => a -> String
show (ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks s
s) (m (Consensus st blk m) -> m (Consensus st blk m))
-> m (Consensus st blk m) -> m (Consensus st blk m)
forall a b. (a -> b) -> a -> b
$ s -> m (Consensus st blk m)
f s
s
data ChainSyncClientResult =
forall blk. BlockSupportsProtocol blk =>
ForkTooDeep
(Point blk)
(Our (Tip blk))
(Their (Tip blk))
|
forall blk. BlockSupportsProtocol blk =>
NoMoreIntersection
(Our (Tip blk))
(Their (Tip blk))
|
forall blk. BlockSupportsProtocol blk =>
RolledBackPastIntersection
(Point blk)
(Our (Tip blk))
(Their (Tip blk))
|
AskedToTerminate
deriving instance Show ChainSyncClientResult
instance Eq ChainSyncClientResult where
== :: ChainSyncClientResult -> ChainSyncClientResult -> Bool
(==)
(ForkTooDeep (Point blk
a :: Point blk) Our (Tip blk)
b Their (Tip blk)
c )
(ForkTooDeep (Point blk
a' :: Point blk') Our (Tip blk)
b' Their (Tip blk)
c')
| Just blk :~: blk
Refl <- forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @blk @blk'
= (Point blk
a, Our (Tip blk)
b, Their (Tip blk)
c) (Point blk, Our (Tip blk), Their (Tip blk))
-> (Point blk, Our (Tip blk), Their (Tip blk)) -> Bool
forall a. Eq a => a -> a -> Bool
== (Point blk
Point blk
a', Our (Tip blk)
Our (Tip blk)
b', Their (Tip blk)
Their (Tip blk)
c')
(==)
(NoMoreIntersection (Our (Tip blk)
a :: Our (Tip blk )) Their (Tip blk)
b )
(NoMoreIntersection (Our (Tip blk)
a' :: Our (Tip blk')) Their (Tip blk)
b')
| Just blk :~: blk
Refl <- forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @blk @blk'
= (Our (Tip blk)
a, Their (Tip blk)
b) (Our (Tip blk), Their (Tip blk))
-> (Our (Tip blk), Their (Tip blk)) -> Bool
forall a. Eq a => a -> a -> Bool
== (Our (Tip blk)
Our (Tip blk)
a', Their (Tip blk)
Their (Tip blk)
b')
(==)
(RolledBackPastIntersection (Point blk
a :: Point blk ) Our (Tip blk)
b Their (Tip blk)
c )
(RolledBackPastIntersection (Point blk
a' :: Point blk') Our (Tip blk)
b' Their (Tip blk)
c')
| Just blk :~: blk
Refl <- forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @blk @blk'
= (Point blk
a, Our (Tip blk)
b, Their (Tip blk)
c) (Point blk, Our (Tip blk), Their (Tip blk))
-> (Point blk, Our (Tip blk), Their (Tip blk)) -> Bool
forall a. Eq a => a -> a -> Bool
== (Point blk
Point blk
a', Our (Tip blk)
Our (Tip blk)
b', Their (Tip blk)
Their (Tip blk)
c')
ChainSyncClientResult
AskedToTerminate == ChainSyncClientResult
AskedToTerminate = Bool
True
ForkTooDeep{} == ChainSyncClientResult
_ = Bool
False
NoMoreIntersection{} == ChainSyncClientResult
_ = Bool
False
RolledBackPastIntersection{} == ChainSyncClientResult
_ = Bool
False
ChainSyncClientResult
AskedToTerminate == ChainSyncClientResult
_ = Bool
False
data ChainSyncClientException =
forall blk. (BlockSupportsProtocol blk, ValidateEnvelope blk) =>
(Point blk)
(HeaderError blk)
(Our (Tip blk))
(Their (Tip blk))
|
forall blk. BlockSupportsProtocol blk =>
InvalidIntersection
(Point blk)
(Our (Tip blk))
(Their (Tip blk))
|
forall blk. LedgerSupportsProtocol blk =>
InvalidBlock
(Point blk)
(HeaderHash blk)
(ExtValidationError blk)
|
!InFutureCheck.HeaderArrivalException
|
HistoricityError !HistoricityException
|
EmptyBucket
|
InvalidJumpResponse
| DensityTooLow
deriving instance Show ChainSyncClientException
instance Eq ChainSyncClientException where
== :: ChainSyncClientException -> ChainSyncClientException -> Bool
(==)
(HeaderError (Point blk
a :: Point blk ) HeaderError blk
b Our (Tip blk)
c Their (Tip blk)
d )
(HeaderError (Point blk
a' :: Point blk') HeaderError blk
b' Our (Tip blk)
c' Their (Tip blk)
d')
| Just blk :~: blk
Refl <- forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @blk @blk'
= (Point blk
a, HeaderError blk
b, Our (Tip blk)
c, Their (Tip blk)
d) (Point blk, HeaderError blk, Our (Tip blk), Their (Tip blk))
-> (Point blk, HeaderError blk, Our (Tip blk), Their (Tip blk))
-> Bool
forall a. Eq a => a -> a -> Bool
== (Point blk
Point blk
a', HeaderError blk
HeaderError blk
b', Our (Tip blk)
Our (Tip blk)
c', Their (Tip blk)
Their (Tip blk)
d')
(==)
(InvalidIntersection (Point blk
a :: Point blk ) Our (Tip blk)
b Their (Tip blk)
c )
(InvalidIntersection (Point blk
a' :: Point blk') Our (Tip blk)
b' Their (Tip blk)
c')
| Just blk :~: blk
Refl <- forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @blk @blk'
= (Point blk
a, Our (Tip blk)
b, Their (Tip blk)
c) (Point blk, Our (Tip blk), Their (Tip blk))
-> (Point blk, Our (Tip blk), Their (Tip blk)) -> Bool
forall a. Eq a => a -> a -> Bool
== (Point blk
Point blk
a', Our (Tip blk)
Our (Tip blk)
b', Their (Tip blk)
Their (Tip blk)
c')
(==)
(InvalidBlock (Point blk
a :: Point blk) HeaderHash blk
b ExtValidationError blk
c )
(InvalidBlock (Point blk
a' :: Point blk') HeaderHash blk
b' ExtValidationError blk
c')
| Just blk :~: blk
Refl <- forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @blk @blk'
= (Point blk
a, HeaderHash blk
b, ExtValidationError blk
c) (Point blk, HeaderHash blk, ExtValidationError blk)
-> (Point blk, HeaderHash blk, ExtValidationError blk) -> Bool
forall a. Eq a => a -> a -> Bool
== (Point blk
Point blk
a', HeaderHash blk
HeaderHash blk
b', ExtValidationError blk
ExtValidationError blk
c')
(==)
(InFutureHeaderExceedsClockSkew HeaderArrivalException
a )
(InFutureHeaderExceedsClockSkew HeaderArrivalException
a')
= HeaderArrivalException
a HeaderArrivalException -> HeaderArrivalException -> Bool
forall a. Eq a => a -> a -> Bool
== HeaderArrivalException
a'
(==)
(HistoricityError HistoricityException
a )
(HistoricityError HistoricityException
a')
= HistoricityException
a HistoricityException -> HistoricityException -> Bool
forall a. Eq a => a -> a -> Bool
== HistoricityException
a'
(==)
ChainSyncClientException
EmptyBucket ChainSyncClientException
EmptyBucket
= Bool
True
(==)
ChainSyncClientException
InvalidJumpResponse ChainSyncClientException
InvalidJumpResponse
= Bool
True
(==)
ChainSyncClientException
DensityTooLow ChainSyncClientException
DensityTooLow
= Bool
True
HeaderError{} == ChainSyncClientException
_ = Bool
False
InvalidIntersection{} == ChainSyncClientException
_ = Bool
False
InvalidBlock{} == ChainSyncClientException
_ = Bool
False
InFutureHeaderExceedsClockSkew{} == ChainSyncClientException
_ = Bool
False
HistoricityError{} == ChainSyncClientException
_ = Bool
False
ChainSyncClientException
EmptyBucket == ChainSyncClientException
_ = Bool
False
ChainSyncClientException
InvalidJumpResponse == ChainSyncClientException
_ = Bool
False
ChainSyncClientException
DensityTooLow == ChainSyncClientException
_ = Bool
False
instance Exception ChainSyncClientException
data TraceChainSyncClientEvent blk =
(Header blk)
|
TraceRolledBack (Point blk)
|
TraceFoundIntersection (Point blk) (Our (Tip blk)) (Their (Tip blk))
|
TraceException ChainSyncClientException
|
TraceTermination ChainSyncClientResult
|
(Header blk)
|
TraceWaitingBeyondForecastHorizon SlotNo
|
TraceAccessingForecastHorizon SlotNo
|
TraceGaveLoPToken Bool (Header blk) BlockNo
|
TraceOfferJump (Point blk)
|
TraceJumpResult (Jumping.JumpResult blk)
|
TraceJumpingWaitingForNextInstruction
|
TraceJumpingInstructionIs (Jumping.Instruction blk)
deriving instance
( BlockSupportsProtocol blk
, Eq (Header blk)
)
=> Eq (TraceChainSyncClientEvent blk)
deriving instance
( BlockSupportsProtocol blk
, Show (Header blk)
)
=> Show (TraceChainSyncClientEvent blk)