{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
#if __GLASGOW_HASKELL__ < 904
{-# OPTIONS_GHC -Wno-name-shadowing #-}
#endif
module Ouroboros.Network.PeerSelection.Governor
(
PeerSelectionPolicy (..)
, PeerSelectionTargets (..)
, ConsensusModePeerTargets (..)
, PeerSelectionActions (..)
, PeerSelectionInterfaces (..)
, PeerStateActions (..)
, TracePeerSelection (..)
, ChurnAction (..)
, DebugPeerSelection (..)
, AssociationMode (..)
, readAssociationMode
, DebugPeerSelectionState (..)
, peerSelectionGovernor
, PeerChurnArgs (..)
, peerChurnGovernor
, ChurnCounters (..)
, assertPeerSelectionState
, sanePeerSelectionTargets
, establishedPeersStatus
, PeerSelectionState (..)
, PublicPeerSelectionState (..)
, makePublicPeerSelectionStateVar
, PeerSelectionView (..)
, PeerSelectionCounters
, PeerSelectionSetsWithSizes
, peerSelectionStateToCounters
, emptyPeerSelectionCounters
, nullPeerSelectionTargets
, emptyPeerSelectionState
, ChurnMode (..)
, peerSelectionStateToView
) where
import Data.Foldable (traverse_)
import Data.Hashable
import Data.Map.Strict (Map)
import Data.Set qualified as Set
import Data.Void (Void)
import Control.Applicative (Alternative ((<|>)))
import Control.Concurrent.Class.MonadSTM.Strict
import Control.Concurrent.JobPool (JobPool)
import Control.Concurrent.JobPool qualified as JobPool
import Control.Monad.Class.MonadAsync
import Control.Monad.Class.MonadThrow
import Control.Monad.Class.MonadTime.SI
import Control.Monad.Class.MonadTimer.SI
import Control.Tracer (Tracer (..), traceWith)
import System.Random
import Ouroboros.Network.ConsensusMode
import Ouroboros.Network.PeerSelection.Bootstrap (UseBootstrapPeers (..))
import Ouroboros.Network.PeerSelection.Churn (ChurnCounters (..),
PeerChurnArgs (..), peerChurnGovernor)
import Ouroboros.Network.PeerSelection.Governor.ActivePeers qualified as ActivePeers
import Ouroboros.Network.PeerSelection.Governor.BigLedgerPeers qualified as BigLedgerPeers
import Ouroboros.Network.PeerSelection.Governor.EstablishedPeers qualified as EstablishedPeers
import Ouroboros.Network.PeerSelection.Governor.KnownPeers qualified as KnownPeers
import Ouroboros.Network.PeerSelection.Governor.Monitor qualified as Monitor
import Ouroboros.Network.PeerSelection.Governor.RootPeers qualified as RootPeers
import Ouroboros.Network.PeerSelection.Governor.Types
import Ouroboros.Network.PeerSelection.LedgerPeers.Type
(MinBigLedgerPeersForTrustedState (..), UseLedgerPeers (..))
import Ouroboros.Network.PeerSelection.LocalRootPeers
(OutboundConnectionsState (..))
import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing (..))
import Ouroboros.Network.PeerSelection.State.EstablishedPeers qualified as EstablishedPeers
import Ouroboros.Network.PeerSelection.State.KnownPeers qualified as KnownPeers
import Ouroboros.Network.PeerSelection.State.LocalRootPeers qualified as LocalRootPeers
peerSelectionGovernor :: ( Alternative (STM m)
, MonadAsync m
, MonadDelay m
, MonadLabelledSTM m
, MonadMask m
, MonadTimer m
, Ord peeraddr
, Show peerconn
, Hashable peeraddr
)
=> Tracer m (TracePeerSelection peeraddr)
-> Tracer m (DebugPeerSelection peeraddr)
-> Tracer m PeerSelectionCounters
-> StdGen
-> ConsensusMode
-> MinBigLedgerPeersForTrustedState
-> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionPolicy peeraddr m
-> PeerSelectionInterfaces peeraddr peerconn m
-> m Void
peerSelectionGovernor :: forall (m :: * -> *) peeraddr peerconn.
(Alternative (STM m), MonadAsync m, MonadDelay m,
MonadLabelledSTM m, MonadMask m, MonadTimer m, Ord peeraddr,
Show peerconn, Hashable peeraddr) =>
Tracer m (TracePeerSelection peeraddr)
-> Tracer m (DebugPeerSelection peeraddr)
-> Tracer m PeerSelectionCounters
-> StdGen
-> ConsensusMode
-> MinBigLedgerPeersForTrustedState
-> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionPolicy peeraddr m
-> PeerSelectionInterfaces peeraddr peerconn m
-> m Void
peerSelectionGovernor Tracer m (TracePeerSelection peeraddr)
tracer Tracer m (DebugPeerSelection peeraddr)
debugTracer Tracer m PeerSelectionCounters
countersTracer StdGen
fuzzRng ConsensusMode
consensusMode MinBigLedgerPeersForTrustedState
minActiveBigLedgerPeers PeerSelectionActions peeraddr peerconn m
actions PeerSelectionPolicy peeraddr m
policy PeerSelectionInterfaces peeraddr peerconn m
interfaces =
(JobPool () m (Completion m peeraddr peerconn) -> m Void) -> m Void
forall group (m :: * -> *) a b.
(MonadAsync m, MonadThrow m, MonadLabelledSTM m) =>
(JobPool group m a -> m b) -> m b
JobPool.withJobPool ((JobPool () m (Completion m peeraddr peerconn) -> m Void)
-> m Void)
-> (JobPool () m (Completion m peeraddr peerconn) -> m Void)
-> m Void
forall a b. (a -> b) -> a -> b
$ \JobPool () m (Completion m peeraddr peerconn)
jobPool ->
Tracer m (TracePeerSelection peeraddr)
-> Tracer m (DebugPeerSelection peeraddr)
-> Tracer m PeerSelectionCounters
-> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionPolicy peeraddr m
-> PeerSelectionInterfaces peeraddr peerconn m
-> JobPool () m (Completion m peeraddr peerconn)
-> PeerSelectionState peeraddr peerconn
-> m Void
forall (m :: * -> *) peeraddr peerconn.
(Alternative (STM m), MonadAsync m, MonadDelay m, MonadMask m,
MonadTimer m, Ord peeraddr, Show peerconn, Hashable peeraddr) =>
Tracer m (TracePeerSelection peeraddr)
-> Tracer m (DebugPeerSelection peeraddr)
-> Tracer m PeerSelectionCounters
-> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionPolicy peeraddr m
-> PeerSelectionInterfaces peeraddr peerconn m
-> JobPool () m (Completion m peeraddr peerconn)
-> PeerSelectionState peeraddr peerconn
-> m Void
peerSelectionGovernorLoop
Tracer m (TracePeerSelection peeraddr)
tracer
Tracer m (DebugPeerSelection peeraddr)
debugTracer
Tracer m PeerSelectionCounters
countersTracer
PeerSelectionActions peeraddr peerconn m
actions
PeerSelectionPolicy peeraddr m
policy
PeerSelectionInterfaces peeraddr peerconn m
interfaces
JobPool () m (Completion m peeraddr peerconn)
jobPool
(StdGen
-> ConsensusMode
-> MinBigLedgerPeersForTrustedState
-> PeerSelectionState peeraddr peerconn
forall peeraddr peerconn.
StdGen
-> ConsensusMode
-> MinBigLedgerPeersForTrustedState
-> PeerSelectionState peeraddr peerconn
emptyPeerSelectionState StdGen
fuzzRng ConsensusMode
consensusMode MinBigLedgerPeersForTrustedState
minActiveBigLedgerPeers)
peerSelectionGovernorLoop :: forall m peeraddr peerconn.
( Alternative (STM m)
, MonadAsync m
, MonadDelay m
, MonadMask m
, MonadTimer m
, Ord peeraddr
, Show peerconn
, Hashable peeraddr
)
=> Tracer m (TracePeerSelection peeraddr)
-> Tracer m (DebugPeerSelection peeraddr)
-> Tracer m PeerSelectionCounters
-> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionPolicy peeraddr m
-> PeerSelectionInterfaces peeraddr peerconn m
-> JobPool () m (Completion m peeraddr peerconn)
-> PeerSelectionState peeraddr peerconn
-> m Void
peerSelectionGovernorLoop :: forall (m :: * -> *) peeraddr peerconn.
(Alternative (STM m), MonadAsync m, MonadDelay m, MonadMask m,
MonadTimer m, Ord peeraddr, Show peerconn, Hashable peeraddr) =>
Tracer m (TracePeerSelection peeraddr)
-> Tracer m (DebugPeerSelection peeraddr)
-> Tracer m PeerSelectionCounters
-> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionPolicy peeraddr m
-> PeerSelectionInterfaces peeraddr peerconn m
-> JobPool () m (Completion m peeraddr peerconn)
-> PeerSelectionState peeraddr peerconn
-> m Void
peerSelectionGovernorLoop Tracer m (TracePeerSelection peeraddr)
tracer
Tracer m (DebugPeerSelection peeraddr)
debugTracer
Tracer m PeerSelectionCounters
countersTracer
PeerSelectionActions peeraddr peerconn m
actions
PeerSelectionPolicy peeraddr m
policy
interfaces :: PeerSelectionInterfaces peeraddr peerconn m
interfaces@PeerSelectionInterfaces {
StrictTVar m PeerSelectionCounters
countersVar :: StrictTVar m PeerSelectionCounters
countersVar :: forall peeraddr peerconn (m :: * -> *).
PeerSelectionInterfaces peeraddr peerconn m
-> StrictTVar m PeerSelectionCounters
countersVar,
StrictTVar m (PublicPeerSelectionState peeraddr)
publicStateVar :: StrictTVar m (PublicPeerSelectionState peeraddr)
publicStateVar :: forall peeraddr peerconn (m :: * -> *).
PeerSelectionInterfaces peeraddr peerconn m
-> StrictTVar m (PublicPeerSelectionState peeraddr)
publicStateVar,
StrictTVar m (PeerSelectionState peeraddr peerconn)
debugStateVar :: StrictTVar m (PeerSelectionState peeraddr peerconn)
debugStateVar :: forall peeraddr peerconn (m :: * -> *).
PeerSelectionInterfaces peeraddr peerconn m
-> StrictTVar m (PeerSelectionState peeraddr peerconn)
debugStateVar
}
JobPool () m (Completion m peeraddr peerconn)
jobPool
PeerSelectionState peeraddr peerconn
pst = do
PeerSelectionState peeraddr peerconn -> Time -> m Void
loop PeerSelectionState peeraddr peerconn
pst (DiffTime -> Time
Time DiffTime
0) m Void -> (SomeException -> m Void) -> m Void
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` (\SomeException
e -> Tracer m (TracePeerSelection peeraddr)
-> TracePeerSelection peeraddr -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TracePeerSelection peeraddr)
tracer (SomeException -> TracePeerSelection peeraddr
forall peeraddr. SomeException -> TracePeerSelection peeraddr
TraceOutboundGovernorCriticalFailure SomeException
e) m () -> m Void -> m Void
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> SomeException -> m Void
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO SomeException
e)
where
loop :: PeerSelectionState peeraddr peerconn
-> Time
-> m Void
loop :: PeerSelectionState peeraddr peerconn -> Time -> m Void
loop !PeerSelectionState peeraddr peerconn
st !Time
dbgUpdateAt = PeerSelectionState peeraddr peerconn -> m Void -> m Void
forall peeraddr peerconn a.
Ord peeraddr =>
PeerSelectionState peeraddr peerconn -> a -> a
assertPeerSelectionState PeerSelectionState peeraddr peerconn
st (m Void -> m Void) -> m Void -> m Void
forall a b. (a -> b) -> a -> b
$ do
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 (PublicPeerSelectionState peeraddr)
-> PublicPeerSelectionState peeraddr -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m (PublicPeerSelectionState peeraddr)
publicStateVar (PeerSelectionState peeraddr peerconn
-> PublicPeerSelectionState peeraddr
forall peeraddr peerconn.
PeerSelectionState peeraddr peerconn
-> PublicPeerSelectionState peeraddr
toPublicState PeerSelectionState peeraddr peerconn
st)
blockedAt <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
case bootstrapPeersTimeout st of
Maybe Time
Nothing -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just Time
t
| Time
blockedAt Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
>= Time
t -> BootstrapPeersCriticalTimeoutError -> m ()
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO BootstrapPeersCriticalTimeoutError
BootstrapPeersCriticalTimeoutError
| Bool
otherwise -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
dbgUpdateAt' <- if dbgUpdateAt <= blockedAt
then do
atomically $ writeTVar debugStateVar st
return $ 83 `addTime` blockedAt
else return dbgUpdateAt
let knownPeers' = Time -> KnownPeers peeraddr -> KnownPeers peeraddr
forall peeraddr.
Ord peeraddr =>
Time -> KnownPeers peeraddr -> KnownPeers peeraddr
KnownPeers.setCurrentTime Time
blockedAt (PeerSelectionState peeraddr peerconn -> KnownPeers peeraddr
forall peeraddr peerconn.
PeerSelectionState peeraddr peerconn -> KnownPeers peeraddr
knownPeers PeerSelectionState peeraddr peerconn
st)
establishedPeers' = Time
-> EstablishedPeers peeraddr peerconn
-> EstablishedPeers peeraddr peerconn
forall peeraddr peerconn.
Ord peeraddr =>
Time
-> EstablishedPeers peeraddr peerconn
-> EstablishedPeers peeraddr peerconn
EstablishedPeers.setCurrentTime Time
blockedAt (PeerSelectionState peeraddr peerconn
-> EstablishedPeers peeraddr peerconn
forall peeraddr peerconn.
PeerSelectionState peeraddr peerconn
-> EstablishedPeers peeraddr peerconn
establishedPeers PeerSelectionState peeraddr peerconn
st)
st' = PeerSelectionState peeraddr peerconn
st { knownPeers = knownPeers',
establishedPeers = establishedPeers' }
timedDecision <- evalGuardedDecisions blockedAt st'
now <- getMonotonicTime
let Decision { decisionTrace, decisionJobs, decisionState = st'' } =
timedDecision now
mbCounters <- atomically $ do
let peerSelectionView = PeerSelectionState peeraddr peerconn
-> PeerSelectionSetsWithSizes peeraddr
forall peeraddr peerconn.
Ord peeraddr =>
PeerSelectionState peeraddr peerconn
-> PeerSelectionSetsWithSizes peeraddr
peerSelectionStateToView PeerSelectionState peeraddr peerconn
st''
associationMode <- readAssociationMode (readUseLedgerPeers interfaces)
(peerSharing actions)
(bootstrapPeersFlag st'')
updateOutboundConnectionsState
actions
(outboundConnectionsState associationMode peerSelectionView st'')
counters <- readTVar countersVar
let !counters' = (Set peeraddr, Int) -> Int
forall a b. (a, b) -> b
snd ((Set peeraddr, Int) -> Int)
-> PeerSelectionSetsWithSizes peeraddr -> PeerSelectionCounters
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PeerSelectionSetsWithSizes peeraddr
peerSelectionView
if counters' /= counters
then writeTVar countersVar counters'
>> return (Just counters')
else return Nothing
traverse_ (traceWith countersTracer) mbCounters
traverse_ (traceWith tracer) decisionTrace
mapM_ (JobPool.forkJob jobPool) decisionJobs
loop st'' dbgUpdateAt'
evalGuardedDecisions :: Time
-> PeerSelectionState peeraddr peerconn
-> m (TimedDecision m peeraddr peerconn)
evalGuardedDecisions :: Time
-> PeerSelectionState peeraddr peerconn
-> m (TimedDecision m peeraddr peerconn)
evalGuardedDecisions Time
blockedAt PeerSelectionState peeraddr peerconn
st = do
inboundPeers <- PeerSelectionActions peeraddr peerconn m
-> m (Map peeraddr PeerSharing)
forall peeraddr peerconn (m :: * -> *).
PeerSelectionActions peeraddr peerconn m
-> m (Map peeraddr PeerSharing)
readInboundPeers PeerSelectionActions peeraddr peerconn m
actions
case guardedDecisions blockedAt st inboundPeers of
GuardedSkip Maybe Time
_ ->
[Char] -> m (TimedDecision m peeraddr peerconn)
forall a. HasCallStack => [Char] -> a
error [Char]
"peerSelectionGovernorLoop: impossible: nothing to do"
Guarded Maybe Time
Nothing STM m (TimedDecision m peeraddr peerconn)
decisionAction -> do
Tracer m (DebugPeerSelection peeraddr)
-> DebugPeerSelection peeraddr -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (DebugPeerSelection peeraddr)
debugTracer (Time
-> Maybe DiffTime
-> PeerSelectionState peeraddr peerconn
-> DebugPeerSelection peeraddr
forall peeraddr peerconn.
Show peerconn =>
Time
-> Maybe DiffTime
-> PeerSelectionState peeraddr peerconn
-> DebugPeerSelection peeraddr
TraceGovernorState Time
blockedAt Maybe DiffTime
forall a. Maybe a
Nothing PeerSelectionState peeraddr peerconn
st)
STM m (TimedDecision m peeraddr peerconn)
-> m (TimedDecision m peeraddr peerconn)
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically STM m (TimedDecision m peeraddr peerconn)
decisionAction
Guarded (Just Time
wakeupAt) STM m (TimedDecision m peeraddr peerconn)
decisionAction -> do
let wakeupIn :: DiffTime
wakeupIn = Time -> Time -> DiffTime
diffTime Time
wakeupAt Time
blockedAt
Tracer m (DebugPeerSelection peeraddr)
-> DebugPeerSelection peeraddr -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (DebugPeerSelection peeraddr)
debugTracer (Time
-> Maybe DiffTime
-> PeerSelectionState peeraddr peerconn
-> DebugPeerSelection peeraddr
forall peeraddr peerconn.
Show peerconn =>
Time
-> Maybe DiffTime
-> PeerSelectionState peeraddr peerconn
-> DebugPeerSelection peeraddr
TraceGovernorState Time
blockedAt (DiffTime -> Maybe DiffTime
forall a. a -> Maybe a
Just DiffTime
wakeupIn) PeerSelectionState peeraddr peerconn
st)
(readTimeout, cancelTimeout) <- DiffTime -> m (STM m TimeoutState, m ())
forall (m :: * -> *).
MonadTimer m =>
DiffTime -> m (STM m TimeoutState, m ())
registerDelayCancellable DiffTime
wakeupIn
let wakeup = STM m TimeoutState
readTimeout STM m TimeoutState
-> (TimeoutState -> STM m (TimedDecision m peeraddr peerconn))
-> STM m (TimedDecision m peeraddr peerconn)
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 TimeoutState
TimeoutPending -> STM m (TimedDecision m peeraddr peerconn)
forall a. STM m a
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
TimeoutState
_ -> TimedDecision m peeraddr peerconn
-> STM m (TimedDecision m peeraddr peerconn)
forall a. a -> STM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PeerSelectionState peeraddr peerconn
-> TimedDecision m peeraddr peerconn
forall peeraddr peerconn (m :: * -> *).
PeerSelectionState peeraddr peerconn
-> TimedDecision m peeraddr peerconn
wakeupDecision PeerSelectionState peeraddr peerconn
st))
timedDecision <- atomically (decisionAction <|> wakeup)
cancelTimeout
return timedDecision
guardedDecisions :: Time
-> PeerSelectionState peeraddr peerconn
-> Map peeraddr PeerSharing
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
guardedDecisions :: Time
-> PeerSelectionState peeraddr peerconn
-> Map peeraddr PeerSharing
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
guardedDecisions Time
blockedAt PeerSelectionState peeraddr peerconn
st Map peeraddr PeerSharing
inboundPeers =
PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.monitorBootstrapPeersFlag PeerSelectionActions peeraddr peerconn m
actions PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.monitorLedgerStateJudgement PeerSelectionActions peeraddr peerconn m
actions PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr) =>
PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.waitForSystemToQuiesce PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.connections PeerSelectionActions peeraddr peerconn m
actions PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> JobPool () m (Completion m peeraddr peerconn)
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
MonadSTM m =>
JobPool () m (Completion m peeraddr peerconn)
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.jobs JobPool () m (Completion m peeraddr peerconn)
jobPool PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionState peeraddr peerconn
-> PeerSelectionActions peeraddr peerconn m
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
MonadSTM m =>
PeerSelectionState peeraddr peerconn
-> PeerSelectionActions peeraddr peerconn m
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.ledgerPeerSnapshotChange PeerSelectionState peeraddr peerconn
st PeerSelectionActions peeraddr peerconn m
actions
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.targetPeers PeerSelectionActions peeraddr peerconn m
actions PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall peeraddr peerconn (m :: * -> *).
(MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
Monitor.localRoots PeerSelectionActions peeraddr peerconn m
actions PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> Time
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> Time
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
BigLedgerPeers.belowTarget PeerSelectionActions peeraddr peerconn m
actions Time
blockedAt PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> MkGuardedDecision peeraddr peerconn m
forall (m :: * -> *) peeraddr peerconn.
(Alternative (STM m), MonadSTM m, Ord peeraddr, HasCallStack) =>
MkGuardedDecision peeraddr peerconn m
BigLedgerPeers.aboveTarget PeerSelectionPolicy peeraddr m
policy PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> Time
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> Time
-> PeerSelectionState peeraddr peerconn
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
RootPeers.belowTarget PeerSelectionActions peeraddr peerconn m
actions Time
blockedAt PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> Time
-> Map peeraddr PeerSharing
-> MkGuardedDecision peeraddr peerconn m
forall (m :: * -> *) peeraddr peerconn.
(MonadAsync m, MonadTimer m, Ord peeraddr, Hashable peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> Time
-> Map peeraddr PeerSharing
-> MkGuardedDecision peeraddr peerconn m
KnownPeers.belowTarget PeerSelectionActions peeraddr peerconn m
actions Time
blockedAt
Map peeraddr PeerSharing
inboundPeers PeerSelectionPolicy peeraddr m
policy PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> MkGuardedDecision peeraddr peerconn m
forall (m :: * -> *) peeraddr peerconn.
(MonadSTM m, Ord peeraddr, HasCallStack) =>
MkGuardedDecision peeraddr peerconn m
KnownPeers.aboveTarget PeerSelectionPolicy peeraddr m
policy PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
forall peeraddr peerconn (m :: * -> *).
(Alternative (STM m), MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
EstablishedPeers.belowTarget PeerSelectionActions peeraddr peerconn m
actions PeerSelectionPolicy peeraddr m
policy PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
forall peeraddr peerconn (m :: * -> *).
(Alternative (STM m), MonadSTM m, Ord peeraddr) =>
PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
EstablishedPeers.aboveTarget PeerSelectionActions peeraddr peerconn m
actions PeerSelectionPolicy peeraddr m
policy PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
forall peeraddr peerconn (m :: * -> *).
(Alternative (STM m), MonadDelay m, MonadSTM m, Ord peeraddr,
HasCallStack) =>
PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
ActivePeers.belowTarget PeerSelectionActions peeraddr peerconn m
actions PeerSelectionPolicy peeraddr m
policy PeerSelectionState peeraddr peerconn
st
Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
-> Guarded (STM m) (TimedDecision m peeraddr peerconn)
forall a. Semigroup a => a -> a -> a
<> PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
forall peeraddr peerconn (m :: * -> *).
(Alternative (STM m), MonadSTM m, Ord peeraddr, HasCallStack) =>
PeerSelectionActions peeraddr peerconn m
-> MkGuardedDecision peeraddr peerconn m
ActivePeers.aboveTarget PeerSelectionActions peeraddr peerconn m
actions PeerSelectionPolicy peeraddr m
policy PeerSelectionState peeraddr peerconn
st
wakeupDecision :: PeerSelectionState peeraddr peerconn
-> TimedDecision m peeraddr peerconn
wakeupDecision :: forall peeraddr peerconn (m :: * -> *).
PeerSelectionState peeraddr peerconn
-> TimedDecision m peeraddr peerconn
wakeupDecision PeerSelectionState peeraddr peerconn
st Time
_now =
Decision {
decisionTrace :: [TracePeerSelection peeraddr]
decisionTrace = [TracePeerSelection peeraddr
forall peeraddr. TracePeerSelection peeraddr
TraceGovernorWakeup],
decisionState :: PeerSelectionState peeraddr peerconn
decisionState = PeerSelectionState peeraddr peerconn
st { stdGen = fst (split (stdGen st)) } ,
decisionJobs :: [Job () m (Completion m peeraddr peerconn)]
decisionJobs = []
}
readAssociationMode
:: MonadSTM m
=> STM m UseLedgerPeers
-> PeerSharing
-> UseBootstrapPeers
-> STM m AssociationMode
readAssociationMode :: forall (m :: * -> *).
MonadSTM m =>
STM m UseLedgerPeers
-> PeerSharing -> UseBootstrapPeers -> STM m AssociationMode
readAssociationMode
STM m UseLedgerPeers
readUseLedgerPeers
PeerSharing
peerSharing
UseBootstrapPeers
useBootstrapPeers
=
do useLedgerPeers <- STM m UseLedgerPeers
readUseLedgerPeers
pure $
case (useLedgerPeers, peerSharing, useBootstrapPeers) of
(UseLedgerPeers
DontUseLedgerPeers, PeerSharing
PeerSharingDisabled, UseBootstrapPeers
DontUseBootstrapPeers)
-> AssociationMode
LocalRootsOnly
(UseLedgerPeers
DontUseLedgerPeers, PeerSharing
PeerSharingDisabled, UseBootstrapPeers [RelayAccessPoint]
config)
| [RelayAccessPoint] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [RelayAccessPoint]
config
-> AssociationMode
LocalRootsOnly
(UseLedgerPeers, PeerSharing, UseBootstrapPeers)
_ -> AssociationMode
Unrestricted
outboundConnectionsState
:: Ord peeraddr
=> AssociationMode
-> PeerSelectionSetsWithSizes peeraddr
-> PeerSelectionState peeraddr peerconn
-> OutboundConnectionsState
outboundConnectionsState :: forall peeraddr peerconn.
Ord peeraddr =>
AssociationMode
-> PeerSelectionSetsWithSizes peeraddr
-> PeerSelectionState peeraddr peerconn
-> OutboundConnectionsState
outboundConnectionsState
AssociationMode
associationMode
PeerSelectionView {
viewEstablishedPeers :: forall a. PeerSelectionView a -> a
viewEstablishedPeers = (Set peeraddr
viewEstablishedPeers, Int
_),
viewEstablishedBootstrapPeers :: forall a. PeerSelectionView a -> a
viewEstablishedBootstrapPeers = (Set peeraddr
viewEstablishedBootstrapPeers, Int
_),
viewActiveBootstrapPeers :: forall a. PeerSelectionView a -> a
viewActiveBootstrapPeers = (Set peeraddr
viewActiveBootstrapPeers, Int
_),
viewActiveBigLedgerPeers :: forall a. PeerSelectionView a -> a
viewActiveBigLedgerPeers = (Set peeraddr
_, Int
activeNumBigLedgerPeers)
}
PeerSelectionState {
ConsensusMode
consensusMode :: ConsensusMode
consensusMode :: forall peeraddr peerconn.
PeerSelectionState peeraddr peerconn -> ConsensusMode
consensusMode,
LocalRootPeers peeraddr
localRootPeers :: LocalRootPeers peeraddr
localRootPeers :: forall peeraddr peerconn.
PeerSelectionState peeraddr peerconn -> LocalRootPeers peeraddr
localRootPeers,
UseBootstrapPeers
bootstrapPeersFlag :: forall peeraddr peerconn.
PeerSelectionState peeraddr peerconn -> UseBootstrapPeers
bootstrapPeersFlag :: UseBootstrapPeers
bootstrapPeersFlag,
MinBigLedgerPeersForTrustedState
minBigLedgerPeersForTrustedState :: MinBigLedgerPeersForTrustedState
minBigLedgerPeersForTrustedState :: forall peeraddr peerconn.
PeerSelectionState peeraddr peerconn
-> MinBigLedgerPeersForTrustedState
minBigLedgerPeersForTrustedState
}
=
case (AssociationMode
associationMode, UseBootstrapPeers
bootstrapPeersFlag, ConsensusMode
consensusMode) of
(AssociationMode
LocalRootsOnly, UseBootstrapPeers
_, ConsensusMode
_)
|
Set peeraddr
viewEstablishedPeers Set peeraddr -> Set peeraddr -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` Set peeraddr
trustableLocalRootSet
-> OutboundConnectionsState
TrustedStateWithExternalPeers
| Bool
otherwise
-> OutboundConnectionsState
UntrustedState
(AssociationMode
Unrestricted, UseBootstrapPeers {}, ConsensusMode
_)
|
Set peeraddr
viewEstablishedPeers Set peeraddr -> Set peeraddr -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` (Set peeraddr
viewEstablishedBootstrapPeers Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Semigroup a => a -> a -> a
<> Set peeraddr
trustableLocalRootSet)
, Bool -> Bool
not (Set peeraddr -> Bool
forall a. Set a -> Bool
Set.null Set peeraddr
viewActiveBootstrapPeers)
-> OutboundConnectionsState
TrustedStateWithExternalPeers
| Bool
otherwise
-> OutboundConnectionsState
UntrustedState
(AssociationMode
Unrestricted, UseBootstrapPeers
DontUseBootstrapPeers, ConsensusMode
PraosMode)
-> OutboundConnectionsState
UntrustedState
(AssociationMode
Unrestricted, UseBootstrapPeers
DontUseBootstrapPeers, ConsensusMode
GenesisMode)
| Int
activeNumBigLedgerPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= MinBigLedgerPeersForTrustedState -> Int
getMinBigLedgerPeersForTrustedState MinBigLedgerPeersForTrustedState
minBigLedgerPeersForTrustedState
-> OutboundConnectionsState
TrustedStateWithExternalPeers
| Bool
otherwise
-> OutboundConnectionsState
UntrustedState
where
trustableLocalRootSet :: Set peeraddr
trustableLocalRootSet = LocalRootPeers peeraddr -> Set peeraddr
forall peeraddr. LocalRootPeers peeraddr -> Set peeraddr
LocalRootPeers.trustableKeysSet LocalRootPeers peeraddr
localRootPeers