{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
#if __GLASGOW_HASKELL__ < 904
{-# OPTIONS_GHC -Wno-name-shadowing #-}
#endif
module Ouroboros.Cardano.PeerSelection.Churn (peerChurnGovernor) where
import Data.Void (Void)
import Control.Concurrent.Class.MonadSTM.Strict
import Control.Monad.Class.MonadThrow
import Control.Monad.Class.MonadTime.SI
import Control.Monad.Class.MonadTimer.SI
import Control.Tracer (traceWith)
import System.Random
import Cardano.Network.ConsensusMode (ConsensusMode (..))
import Cardano.Network.PeerSelection.Bootstrap (UseBootstrapPeers (..))
import Cardano.Network.Types (LedgerStateJudgement (..))
import Control.Applicative (Alternative)
import Data.Functor (($>))
import Data.Monoid.Synchronisation (FirstToFinish (..))
import Ouroboros.Cardano.Network.LedgerPeerConsensusInterface qualified as Cardano
import Ouroboros.Cardano.Network.PeerSelection.Churn.ExtraArguments qualified as Churn
import Ouroboros.Cardano.Network.Types (ChurnMode (..))
import Ouroboros.Network.BlockFetch (FetchMode (..), PraosFetchMode (..))
import Ouroboros.Network.Diffusion.Policies (churnEstablishConnectionTimeout,
closeConnectionTimeout, deactivateTimeout)
import Ouroboros.Network.PeerSelection.Churn (CheckPeerSelectionCounters,
ChurnCounters (..), ModifyPeerSelectionTargets, PeerChurnArgs (..))
import Ouroboros.Network.PeerSelection.Governor.Types hiding (targets)
import Ouroboros.Network.PeerSelection.LedgerPeers.Type
import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency (..))
data ChurnRegime = ChurnDefault
| ChurnPraosSync
| ChurnBootstrapPraosSync
getPeerSelectionTargets
:: ConsensusMode
-> LedgerStateJudgement
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
getPeerSelectionTargets :: ConsensusMode
-> LedgerStateJudgement
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
getPeerSelectionTargets ConsensusMode
consensus LedgerStateJudgement
lsj PeerSelectionTargets
deadlineTargets PeerSelectionTargets
syncTargets =
case (ConsensusMode
consensus, LedgerStateJudgement
lsj) of
(ConsensusMode
GenesisMode, LedgerStateJudgement
TooOld) -> PeerSelectionTargets
syncTargets
(ConsensusMode, LedgerStateJudgement)
_otherwise -> PeerSelectionTargets
deadlineTargets
pickChurnRegime :: ConsensusMode -> ChurnMode -> UseBootstrapPeers -> ChurnRegime
pickChurnRegime :: ConsensusMode -> ChurnMode -> UseBootstrapPeers -> ChurnRegime
pickChurnRegime ConsensusMode
consensus ChurnMode
churn UseBootstrapPeers
ubp =
case (ChurnMode
churn, UseBootstrapPeers
ubp, ConsensusMode
consensus) of
(ChurnMode
ChurnModeNormal, UseBootstrapPeers
_, ConsensusMode
_) -> ChurnRegime
ChurnDefault
(ChurnMode
_, UseBootstrapPeers
_, ConsensusMode
GenesisMode) -> ChurnRegime
ChurnDefault
(ChurnMode
ChurnModeBulkSync, UseBootstrapPeers [RelayAccessPoint]
_, ConsensusMode
_) -> ChurnRegime
ChurnBootstrapPraosSync
(ChurnMode
ChurnModeBulkSync, UseBootstrapPeers
_, ConsensusMode
_) -> ChurnRegime
ChurnPraosSync
peerChurnGovernor
:: forall m extraState extraFlags extraCounters extraPeers peeraddr.
( MonadDelay m
, Alternative (STM m)
, MonadTimer m
, MonadCatch m
)
=> PeerChurnArgs
m
(Churn.ExtraArguments m)
extraState
extraFlags
extraPeers
(Cardano.LedgerPeersConsensusInterface m)
extraCounters
peeraddr
-> m Void
peerChurnGovernor :: forall (m :: * -> *) extraState extraFlags extraCounters extraPeers
peeraddr.
(MonadDelay m, Alternative (STM m), MonadTimer m, MonadCatch m) =>
PeerChurnArgs
m
(ExtraArguments m)
extraState
extraFlags
extraPeers
(LedgerPeersConsensusInterface m)
extraCounters
peeraddr
-> m Void
peerChurnGovernor PeerChurnArgs {
pcaPeerSelectionTracer :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> Tracer
m
(TracePeerSelection extraDebugState extraFlags extraPeers peeraddr)
pcaPeerSelectionTracer = Tracer
m (TracePeerSelection extraState extraFlags extraPeers peeraddr)
tracer,
pcaChurnTracer :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> Tracer m ChurnCounters
pcaChurnTracer = Tracer m ChurnCounters
churnTracer,
pcaDeadlineInterval :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> DiffTime
pcaDeadlineInterval = DiffTime
deadlineChurnInterval,
pcaBulkInterval :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> DiffTime
pcaBulkInterval = DiffTime
bulkChurnInterval,
pcaPeerRequestTimeout :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> DiffTime
pcaPeerRequestTimeout = DiffTime
requestPeersTimeout,
pcaRng :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> StdGen
pcaRng = StdGen
inRng,
pcaPeerSelectionVar :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> StrictTVar m PeerSelectionTargets
pcaPeerSelectionVar = StrictTVar m PeerSelectionTargets
peerSelectionVar,
pcaReadCounters :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> STM m (PeerSelectionCounters extraCounters)
pcaReadCounters = STM m (PeerSelectionCounters extraCounters)
readCounters,
getLedgerStateCtx :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> LedgerPeersConsensusInterface extraAPI m
getLedgerStateCtx = LedgerPeersConsensusInterface {
lpExtraAPI :: forall extraAPI (m :: * -> *).
LedgerPeersConsensusInterface extraAPI m -> extraAPI
lpExtraAPI = Cardano.LedgerPeersConsensusInterface {
STM m LedgerStateJudgement
getLedgerStateJudgement :: STM m LedgerStateJudgement
getLedgerStateJudgement :: forall (m :: * -> *).
LedgerPeersConsensusInterface m -> STM m LedgerStateJudgement
Cardano.getLedgerStateJudgement
}
},
STM m HotValency
getLocalRootHotTarget :: STM m HotValency
getLocalRootHotTarget :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> STM m HotValency
getLocalRootHotTarget,
PeerSelectionTargets
getOriginalPeerTargets :: PeerSelectionTargets
getOriginalPeerTargets :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> PeerSelectionTargets
getOriginalPeerTargets,
getExtraArgs :: forall (m :: * -> *) extraArgs extraDebugState extraFlags
extraPeers extraAPI extraCounters peeraddr.
PeerChurnArgs
m
extraArgs
extraDebugState
extraFlags
extraPeers
extraAPI
extraCounters
peeraddr
-> extraArgs
getExtraArgs = Churn.ExtraArguments {
modeVar :: forall (m :: * -> *). ExtraArguments m -> StrictTVar m ChurnMode
Churn.modeVar = StrictTVar m ChurnMode
churnModeVar,
readFetchMode :: forall (m :: * -> *). ExtraArguments m -> STM m FetchMode
Churn.readFetchMode = STM m FetchMode
getFetchMode,
readUseBootstrap :: forall (m :: * -> *). ExtraArguments m -> STM m UseBootstrapPeers
Churn.readUseBootstrap = STM m UseBootstrapPeers
getUseBootstrapPeers,
consensusMode :: forall (m :: * -> *). ExtraArguments m -> ConsensusMode
Churn.consensusMode = ConsensusMode
consensusMode,
PeerSelectionTargets
genesisPeerTargets :: PeerSelectionTargets
genesisPeerTargets :: forall (m :: * -> *). ExtraArguments m -> PeerSelectionTargets
Churn.genesisPeerTargets
}
} = do
startTs0 <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
threadDelay 3
atomically $ do
(churnMode, ledgerStateJudgement, useBootstrapPeers, ltt)
<- (,,,) <$> updateChurnMode <*> getLedgerStateJudgement <*> getUseBootstrapPeers <*> getLocalRootHotTarget
let regime = ConsensusMode -> ChurnMode -> UseBootstrapPeers -> ChurnRegime
pickChurnRegime ConsensusMode
consensusMode ChurnMode
churnMode UseBootstrapPeers
useBootstrapPeers
targets = ConsensusMode
-> LedgerStateJudgement
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
getPeerSelectionTargets ConsensusMode
consensusMode LedgerStateJudgement
ledgerStateJudgement PeerSelectionTargets
getOriginalPeerTargets PeerSelectionTargets
genesisPeerTargets
modifyTVar peerSelectionVar ( increaseActivePeers regime ltt targets
. increaseEstablishedPeers regime ltt targets)
endTs0 <- getMonotonicTime
fuzzyDelay inRng (endTs0 `diffTime` startTs0) >>= churnLoop
where
updateChurnMode :: STM m ChurnMode
updateChurnMode :: STM m ChurnMode
updateChurnMode = do
fm <- STM m FetchMode
getFetchMode
let mode = case FetchMode
fm of
PraosFetchMode PraosFetchMode
FetchModeDeadline -> ChurnMode
ChurnModeNormal
PraosFetchMode PraosFetchMode
FetchModeBulkSync -> ChurnMode
ChurnModeBulkSync
FetchMode
FetchModeGenesis -> ChurnMode
ChurnModeBulkSync
writeTVar churnModeVar mode
return mode
updateTargets
:: ChurnAction
-> (PeerSelectionCounters extraCounters -> Int)
-> DiffTime
-> (ChurnRegime -> HotValency -> PeerSelectionTargets -> ModifyPeerSelectionTargets)
-> CheckPeerSelectionCounters extraCounters
-> m ()
updateTargets :: ChurnAction
-> (PeerSelectionCounters extraCounters -> Int)
-> DiffTime
-> (ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets)
-> CheckPeerSelectionCounters extraCounters
-> m ()
updateTargets ChurnAction
churnAction PeerSelectionCounters extraCounters -> Int
getCounter DiffTime
timeoutDelay ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
modifyTargets CheckPeerSelectionCounters extraCounters
checkCounters = do
startTime <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
(c, targets) <- atomically $ do
churnMode <- updateChurnMode
ltt <- getLocalRootHotTarget
lsj <- getLedgerStateJudgement
regime <- pickChurnRegime consensusMode churnMode <$> getUseBootstrapPeers
let targets = ConsensusMode
-> LedgerStateJudgement
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
getPeerSelectionTargets ConsensusMode
consensusMode LedgerStateJudgement
lsj PeerSelectionTargets
getOriginalPeerTargets PeerSelectionTargets
genesisPeerTargets
(,) <$> (getCounter <$> readCounters)
<*> stateTVar peerSelectionVar ((\PeerSelectionTargets
a -> (PeerSelectionTargets
a, PeerSelectionTargets
a)) . modifyTargets regime ltt targets)
bracketOnError (registerDelayCancellable timeoutDelay)
(\(STM m TimeoutState
_readTimeout, m ()
cancelTimeout) -> m ()
cancelTimeout)
(\( STM m TimeoutState
readTimeout, m ()
cancelTimeout) -> do
a <- STM m (Either Int Int) -> m (Either Int Int)
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (Either Int Int) -> m (Either Int Int))
-> STM m (Either Int Int) -> m (Either Int Int)
forall a b. (a -> b) -> a -> b
$ do
counters <- STM m (PeerSelectionCounters extraCounters)
readCounters
runFirstToFinish $
FirstToFinish (check (checkCounters counters targets) $> (Right $ getCounter counters ))
<>
FirstToFinish (readTimeout >>= \case TimeoutState
TimeoutPending -> STM m (Either Int Int)
forall a. STM m a
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
TimeoutState
_ -> Either Int Int -> STM m (Either Int Int)
forall a. a -> STM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> Either Int Int
forall a b. a -> Either a b
Left (Int -> Either Int Int) -> Int -> Either Int Int
forall a b. (a -> b) -> a -> b
$ PeerSelectionCounters extraCounters -> Int
getCounter PeerSelectionCounters extraCounters
counters))
case a of
Right Int
c' -> do
let r :: Int
r = Int
c' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
c
endTime <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
traceWith tracer (TraceChurnAction (endTime `diffTime` startTime) churnAction r)
traceWith churnTracer (ChurnCounter churnAction r)
Left Int
c' -> do
endTime <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
cancelTimeout
let r = Int
c' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
c
traceWith tracer (TraceChurnTimeout (endTime `diffTime` startTime) churnAction r)
traceWith churnTracer (ChurnCounter churnAction r)
)
increaseActivePeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
increaseActivePeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
increaseActivePeers ChurnRegime
regime (HotValency Int
ltt) PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfActivePeers =
case regime of
ChurnRegime
ChurnDefault -> PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
base
ChurnRegime
_otherwise -> Int -> Int -> Int
forall a. Ord a => a -> a -> a
min ((Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
ltt) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
base) }
checkActivePeersIncreased :: CheckPeerSelectionCounters extraCounters
checkActivePeersIncreased :: CheckPeerSelectionCounters extraCounters
checkActivePeersIncreased
PeerSelectionCounters { Int
numberOfActivePeers :: Int
numberOfActivePeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfActivePeers }
PeerSelectionTargets { Int
targetNumberOfActivePeers :: PeerSelectionTargets -> Int
targetNumberOfActivePeers :: Int
targetNumberOfActivePeers }
=
Int
numberOfActivePeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
targetNumberOfActivePeers
decreaseActivePeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
decreaseActivePeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
decreaseActivePeers ChurnRegime
regime (HotValency Int
ltt) PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfActivePeers =
case regime of
ChurnRegime
ChurnDefault -> Int -> Int
decrease (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
base
ChurnRegime
_otherwise -> Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
ltt) (PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
base Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) }
checkActivePeersDecreased :: CheckPeerSelectionCounters extraCounters
checkActivePeersDecreased :: CheckPeerSelectionCounters extraCounters
checkActivePeersDecreased
PeerSelectionCounters { Int
numberOfActivePeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfActivePeers :: Int
numberOfActivePeers }
PeerSelectionTargets { Int
targetNumberOfActivePeers :: PeerSelectionTargets -> Int
targetNumberOfActivePeers :: Int
targetNumberOfActivePeers }
=
Int
numberOfActivePeers
Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
targetNumberOfActivePeers
increaseEstablishedPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
increaseEstablishedPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
increaseEstablishedPeers ChurnRegime
regime HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfEstablishedPeers =
case regime of
ChurnRegime
ChurnBootstrapPraosSync -> Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
targets Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
(PeerSelectionTargets -> Int
targetNumberOfEstablishedPeers PeerSelectionTargets
base)
ChurnRegime
_otherwise -> PeerSelectionTargets -> Int
targetNumberOfEstablishedPeers PeerSelectionTargets
base }
checkEstablishedPeersIncreased :: CheckPeerSelectionCounters extraCounters
checkEstablishedPeersIncreased :: CheckPeerSelectionCounters extraCounters
checkEstablishedPeersIncreased
PeerSelectionCounters { Int
numberOfEstablishedPeers :: Int
numberOfEstablishedPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfEstablishedPeers }
PeerSelectionTargets { Int
targetNumberOfEstablishedPeers :: PeerSelectionTargets -> Int
targetNumberOfEstablishedPeers :: Int
targetNumberOfEstablishedPeers }
=
Int
numberOfEstablishedPeers
Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
targetNumberOfEstablishedPeers
increaseEstablishedBigLedgerPeers
:: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
increaseEstablishedBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
increaseEstablishedBigLedgerPeers ChurnRegime
_ HotValency
_ PeerSelectionTargets
base
PeerSelectionTargets
targets
=
PeerSelectionTargets
targets { targetNumberOfEstablishedBigLedgerPeers = targetNumberOfEstablishedBigLedgerPeers base }
checkEstablishedBigLedgerPeersIncreased
:: CheckPeerSelectionCounters extraCounters
checkEstablishedBigLedgerPeersIncreased :: CheckPeerSelectionCounters extraCounters
checkEstablishedBigLedgerPeersIncreased
PeerSelectionCounters { Int
numberOfEstablishedBigLedgerPeers :: Int
numberOfEstablishedBigLedgerPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfEstablishedBigLedgerPeers }
PeerSelectionTargets { Int
targetNumberOfEstablishedBigLedgerPeers :: PeerSelectionTargets -> Int
targetNumberOfEstablishedBigLedgerPeers :: Int
targetNumberOfEstablishedBigLedgerPeers }
=
Int
numberOfEstablishedBigLedgerPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
targetNumberOfEstablishedBigLedgerPeers
decreaseEstablishedPeers
:: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
decreaseEstablishedPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
decreaseEstablishedPeers ChurnRegime
regime HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfEstablishedPeers =
case regime of
ChurnRegime
ChurnBootstrapPraosSync -> Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
targets)
(PeerSelectionTargets -> Int
targetNumberOfEstablishedPeers PeerSelectionTargets
base Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
ChurnRegime
_otherwise -> Int -> Int
decrease (PeerSelectionTargets -> Int
targetNumberOfEstablishedPeers PeerSelectionTargets
base Int -> Int -> Int
forall a. Num a => a -> a -> a
- PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
base)
Int -> Int -> Int
forall a. Num a => a -> a -> a
+ PeerSelectionTargets -> Int
targetNumberOfActivePeers PeerSelectionTargets
base }
checkEstablishedPeersDecreased
:: CheckPeerSelectionCounters extraCounters
checkEstablishedPeersDecreased :: CheckPeerSelectionCounters extraCounters
checkEstablishedPeersDecreased
PeerSelectionCounters { Int
numberOfEstablishedPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfEstablishedPeers :: Int
numberOfEstablishedPeers }
PeerSelectionTargets { Int
targetNumberOfEstablishedPeers :: PeerSelectionTargets -> Int
targetNumberOfEstablishedPeers :: Int
targetNumberOfEstablishedPeers }
=
Int
numberOfEstablishedPeers
Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
targetNumberOfEstablishedPeers
increaseActiveBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
increaseActiveBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
increaseActiveBigLedgerPeers ChurnRegime
regime HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfActiveBigLedgerPeers =
let praosSyncTargets = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
1 (PeerSelectionTargets -> Int
targetNumberOfActiveBigLedgerPeers PeerSelectionTargets
base)
in case regime of
ChurnRegime
ChurnBootstrapPraosSync -> Int
praosSyncTargets
ChurnRegime
ChurnPraosSync -> Int
praosSyncTargets
ChurnRegime
ChurnDefault -> PeerSelectionTargets -> Int
targetNumberOfActiveBigLedgerPeers PeerSelectionTargets
base }
checkActiveBigLedgerPeersIncreased
:: CheckPeerSelectionCounters extraCounters
checkActiveBigLedgerPeersIncreased :: CheckPeerSelectionCounters extraCounters
checkActiveBigLedgerPeersIncreased
PeerSelectionCounters { Int
numberOfActiveBigLedgerPeers :: Int
numberOfActiveBigLedgerPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfActiveBigLedgerPeers }
PeerSelectionTargets { Int
targetNumberOfActiveBigLedgerPeers :: PeerSelectionTargets -> Int
targetNumberOfActiveBigLedgerPeers :: Int
targetNumberOfActiveBigLedgerPeers }
=
Int
numberOfActiveBigLedgerPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
targetNumberOfActiveBigLedgerPeers
decreaseActiveBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
decreaseActiveBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
decreaseActiveBigLedgerPeers ChurnRegime
regime HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfActiveBigLedgerPeers =
let praosSyncTargets = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
1 (PeerSelectionTargets -> Int
targetNumberOfActiveBigLedgerPeers PeerSelectionTargets
base)
in case regime of
ChurnRegime
ChurnBootstrapPraosSync -> Int
praosSyncTargets
ChurnRegime
ChurnPraosSync -> Int
praosSyncTargets
ChurnRegime
ChurnDefault -> Int -> Int
decrease (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ PeerSelectionTargets -> Int
targetNumberOfActiveBigLedgerPeers PeerSelectionTargets
base }
checkActiveBigLedgerPeersDecreased
:: CheckPeerSelectionCounters extraCounters
checkActiveBigLedgerPeersDecreased :: CheckPeerSelectionCounters extraCounters
checkActiveBigLedgerPeersDecreased
PeerSelectionCounters { Int
numberOfActiveBigLedgerPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfActiveBigLedgerPeers :: Int
numberOfActiveBigLedgerPeers }
PeerSelectionTargets { Int
targetNumberOfActiveBigLedgerPeers :: PeerSelectionTargets -> Int
targetNumberOfActiveBigLedgerPeers :: Int
targetNumberOfActiveBigLedgerPeers }
=
Int
numberOfActiveBigLedgerPeers
Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
targetNumberOfActiveBigLedgerPeers
decreaseEstablishedBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
decreaseEstablishedBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
decreaseEstablishedBigLedgerPeers ChurnRegime
_ HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfEstablishedBigLedgerPeers =
decrease (targetNumberOfEstablishedBigLedgerPeers base -
targetNumberOfActiveBigLedgerPeers base)
+ targetNumberOfActiveBigLedgerPeers base
}
checkEstablishedBigLedgerPeersDecreased
:: CheckPeerSelectionCounters extraCounters
checkEstablishedBigLedgerPeersDecreased :: CheckPeerSelectionCounters extraCounters
checkEstablishedBigLedgerPeersDecreased
PeerSelectionCounters { Int
numberOfEstablishedBigLedgerPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfEstablishedBigLedgerPeers :: Int
numberOfEstablishedBigLedgerPeers }
PeerSelectionTargets { Int
targetNumberOfEstablishedBigLedgerPeers :: PeerSelectionTargets -> Int
targetNumberOfEstablishedBigLedgerPeers :: Int
targetNumberOfEstablishedBigLedgerPeers }
=
Int
numberOfEstablishedBigLedgerPeers
Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
targetNumberOfEstablishedBigLedgerPeers
decreaseKnownPeers
:: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
decreaseKnownPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
decreaseKnownPeers ChurnRegime
_ HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfRootPeers =
decrease (targetNumberOfRootPeers base - targetNumberOfEstablishedPeers base)
+ targetNumberOfEstablishedPeers base
, targetNumberOfKnownPeers =
decrease (targetNumberOfKnownPeers base - targetNumberOfEstablishedPeers base)
+ targetNumberOfEstablishedPeers base
}
checkKnownPeersDecreased
:: PeerSelectionCounters extraCounters -> PeerSelectionTargets -> Bool
checkKnownPeersDecreased :: CheckPeerSelectionCounters extraCounters
checkKnownPeersDecreased
PeerSelectionCounters { Int
numberOfKnownPeers :: Int
numberOfKnownPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfKnownPeers }
PeerSelectionTargets { Int
targetNumberOfKnownPeers :: PeerSelectionTargets -> Int
targetNumberOfKnownPeers :: Int
targetNumberOfKnownPeers }
=
Int
numberOfKnownPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
targetNumberOfKnownPeers
decreaseKnownBigLedgerPeers
:: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
decreaseKnownBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
decreaseKnownBigLedgerPeers ChurnRegime
_ HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfKnownBigLedgerPeers =
decrease (targetNumberOfKnownBigLedgerPeers base -
targetNumberOfEstablishedBigLedgerPeers base)
+ targetNumberOfEstablishedBigLedgerPeers base
}
checkKnownBigLedgerPeersDecreased
:: PeerSelectionCounters extraCounters -> PeerSelectionTargets -> Bool
checkKnownBigLedgerPeersDecreased :: CheckPeerSelectionCounters extraCounters
checkKnownBigLedgerPeersDecreased
PeerSelectionCounters { Int
numberOfKnownBigLedgerPeers :: Int
numberOfKnownBigLedgerPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfKnownBigLedgerPeers }
PeerSelectionTargets { Int
targetNumberOfKnownBigLedgerPeers :: PeerSelectionTargets -> Int
targetNumberOfKnownBigLedgerPeers :: Int
targetNumberOfKnownBigLedgerPeers }
= Int
numberOfKnownBigLedgerPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
targetNumberOfKnownBigLedgerPeers
increaseKnownPeers
:: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
increaseKnownPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
increaseKnownPeers ChurnRegime
_ HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfRootPeers = targetNumberOfRootPeers base
, targetNumberOfKnownPeers = targetNumberOfKnownPeers base
}
checkKnownPeersIncreased
:: CheckPeerSelectionCounters extraCounters
checkKnownPeersIncreased :: CheckPeerSelectionCounters extraCounters
checkKnownPeersIncreased
PeerSelectionCounters { Int
numberOfRootPeers :: Int
numberOfRootPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfRootPeers,
Int
numberOfKnownPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfKnownPeers :: Int
numberOfKnownPeers }
PeerSelectionTargets { Int
targetNumberOfRootPeers :: PeerSelectionTargets -> Int
targetNumberOfRootPeers :: Int
targetNumberOfRootPeers,
Int
targetNumberOfKnownPeers :: PeerSelectionTargets -> Int
targetNumberOfKnownPeers :: Int
targetNumberOfKnownPeers }
=
Int
numberOfRootPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
targetNumberOfRootPeers
Bool -> Bool -> Bool
&& Int
numberOfKnownPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
targetNumberOfKnownPeers
increaseKnownBigLedgerPeers
:: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> ModifyPeerSelectionTargets
increaseKnownBigLedgerPeers :: ChurnRegime
-> HotValency
-> PeerSelectionTargets
-> PeerSelectionTargets
-> PeerSelectionTargets
increaseKnownBigLedgerPeers ChurnRegime
_ HotValency
_ PeerSelectionTargets
base PeerSelectionTargets
targets =
PeerSelectionTargets
targets {
targetNumberOfKnownBigLedgerPeers = targetNumberOfKnownBigLedgerPeers base
}
checkKnownBigLedgerPeersIncreased
:: CheckPeerSelectionCounters extraCounters
checkKnownBigLedgerPeersIncreased :: CheckPeerSelectionCounters extraCounters
checkKnownBigLedgerPeersIncreased
PeerSelectionCounters { Int
numberOfKnownBigLedgerPeers :: forall extraCounters. PeerSelectionCounters extraCounters -> Int
numberOfKnownBigLedgerPeers :: Int
numberOfKnownBigLedgerPeers }
PeerSelectionTargets { Int
targetNumberOfKnownBigLedgerPeers :: PeerSelectionTargets -> Int
targetNumberOfKnownBigLedgerPeers :: Int
targetNumberOfKnownBigLedgerPeers }
=
Int
numberOfKnownBigLedgerPeers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
targetNumberOfKnownBigLedgerPeers
churnLoop :: StdGen -> m Void
churnLoop :: StdGen -> m Void
churnLoop !StdGen
rng = do
startTs <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
churnMode <- atomically updateChurnMode
traceWith tracer $ TraceChurnMode churnMode
updateTargets DecreasedActiveBigLedgerPeers
numberOfActiveBigLedgerPeers
deactivateTimeout
decreaseActiveBigLedgerPeers
checkActiveBigLedgerPeersDecreased
updateTargets IncreasedActiveBigLedgerPeers
numberOfActiveBigLedgerPeers
shortTimeout
increaseActiveBigLedgerPeers
checkActiveBigLedgerPeersIncreased
updateTargets DecreasedEstablishedBigLedgerPeers
numberOfEstablishedBigLedgerPeers
(1 + closeConnectionTimeout)
decreaseEstablishedBigLedgerPeers
checkEstablishedBigLedgerPeersDecreased
updateTargets DecreasedKnownBigLedgerPeers
numberOfKnownBigLedgerPeers
shortTimeout
decreaseKnownBigLedgerPeers
checkKnownBigLedgerPeersDecreased
updateTargets IncreasedKnownBigLedgerPeers
numberOfKnownBigLedgerPeers
(2 * requestPeersTimeout + shortTimeout)
increaseKnownBigLedgerPeers
checkKnownBigLedgerPeersIncreased
updateTargets IncreasedEstablishedBigLedgerPeers
numberOfEstablishedBigLedgerPeers
churnEstablishConnectionTimeout
increaseEstablishedBigLedgerPeers
checkEstablishedBigLedgerPeersIncreased
updateTargets DecreasedActivePeers
numberOfActivePeers
deactivateTimeout
decreaseActivePeers
checkActivePeersDecreased
updateTargets IncreasedActivePeers
numberOfActivePeers
shortTimeout
increaseActivePeers
checkActivePeersIncreased
updateTargets DecreasedEstablishedPeers
numberOfEstablishedPeers
(1 + closeConnectionTimeout)
decreaseEstablishedPeers
checkEstablishedPeersDecreased
updateTargets DecreasedKnownPeers
numberOfKnownPeers
shortTimeout
decreaseKnownPeers
checkKnownPeersDecreased
updateTargets IncreasedKnownPeers
numberOfKnownPeers
(2 * requestPeersTimeout + shortTimeout)
increaseKnownPeers
checkKnownPeersIncreased
updateTargets IncreasedEstablishedPeers
numberOfEstablishedPeers
churnEstablishConnectionTimeout
increaseEstablishedPeers
checkEstablishedPeersIncreased
endTs <- getMonotonicTime
fuzzyDelay rng (endTs `diffTime` startTs) >>= churnLoop
fuzzyDelay :: StdGen -> DiffTime -> m StdGen
fuzzyDelay :: StdGen -> DiffTime -> m StdGen
fuzzyDelay StdGen
rng DiffTime
execTime = do
mode <- STM m FetchMode -> m FetchMode
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically STM m FetchMode
getFetchMode
case (mode, consensusMode) of
(PraosFetchMode PraosFetchMode
FetchModeDeadline, ConsensusMode
_) -> StdGen -> DiffTime -> m StdGen
longDelay StdGen
rng DiffTime
execTime
(FetchMode
_, ConsensusMode
GenesisMode) -> StdGen -> DiffTime -> m StdGen
longDelay StdGen
rng DiffTime
execTime
(FetchMode, ConsensusMode)
_otherwise -> StdGen -> DiffTime -> m StdGen
shortDelay StdGen
rng DiffTime
execTime
fuzzyDelay' :: DiffTime -> Double -> StdGen -> DiffTime -> m StdGen
fuzzyDelay' :: DiffTime -> Double -> StdGen -> DiffTime -> m StdGen
fuzzyDelay' DiffTime
baseDelay Double
maxFuzz StdGen
rng DiffTime
execTime = do
let (Double
fuzz, StdGen
rng') = (Double, Double) -> StdGen -> (Double, StdGen)
forall g. RandomGen g => (Double, Double) -> g -> (Double, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (Double
0, Double
maxFuzz) StdGen
rng
delay :: DiffTime
delay = Double -> DiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
fuzz DiffTime -> DiffTime -> DiffTime
forall a. Num a => a -> a -> a
+ DiffTime
baseDelay DiffTime -> DiffTime -> DiffTime
forall a. Num a => a -> a -> a
- DiffTime
execTime
Tracer
m (TracePeerSelection extraState extraFlags extraPeers peeraddr)
-> TracePeerSelection extraState extraFlags extraPeers peeraddr
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
m (TracePeerSelection extraState extraFlags extraPeers peeraddr)
tracer (TracePeerSelection extraState extraFlags extraPeers peeraddr
-> m ())
-> TracePeerSelection extraState extraFlags extraPeers peeraddr
-> m ()
forall a b. (a -> b) -> a -> b
$ DiffTime
-> TracePeerSelection extraState extraFlags extraPeers peeraddr
forall extraDebugState extraFlags extraPeers peeraddr.
DiffTime
-> TracePeerSelection
extraDebugState extraFlags extraPeers peeraddr
TraceChurnWait DiffTime
delay
DiffTime -> m ()
forall (m :: * -> *). MonadDelay m => DiffTime -> m ()
threadDelay DiffTime
delay
StdGen -> m StdGen
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return StdGen
rng'
longDelay :: StdGen -> DiffTime -> m StdGen
longDelay :: StdGen -> DiffTime -> m StdGen
longDelay = DiffTime -> Double -> StdGen -> DiffTime -> m StdGen
fuzzyDelay' DiffTime
deadlineChurnInterval Double
600
shortDelay :: StdGen -> DiffTime -> m StdGen
shortDelay :: StdGen -> DiffTime -> m StdGen
shortDelay = DiffTime -> Double -> StdGen -> DiffTime -> m StdGen
fuzzyDelay' DiffTime
bulkChurnInterval Double
60
shortTimeout :: DiffTime
shortTimeout :: DiffTime
shortTimeout = DiffTime
60
decrease :: Int -> Int
decrease :: Int -> Int
decrease Int
v = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 (Int
v Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
5)