diff --git a/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/PeerSelection/MockEnvironment.hs b/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/PeerSelection/MockEnvironment.hs index 3bcf299bc6..696b8ea7c3 100644 --- a/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/PeerSelection/MockEnvironment.hs +++ b/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/PeerSelection/MockEnvironment.hs @@ -657,8 +657,8 @@ tracerTracePeerSelection = contramap f tracerTestTraceEvent f a@(TraceUseBootstrapPeersChanged !_) = GovernorEvent a f a@(TraceOutboundGovernorCriticalFailure !_) = GovernorEvent a f a@(TraceDebugState !_ !_) = GovernorEvent a - f a@(TraceChurnAction !_) = GovernorEvent a - f a@(TraceChurnTimeout !_) = GovernorEvent a + f a@(TraceChurnAction !_ !_) = GovernorEvent a + f a@(TraceChurnTimeout !_ !_) = GovernorEvent a tracerDebugPeerSelection :: Tracer (IOSim s) (DebugPeerSelection PeerAddr) tracerDebugPeerSelection = GovernorDebug `contramap` tracerTestTraceEvent diff --git a/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet.hs b/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet.hs index ead14c6d28..22a4aaf408 100644 --- a/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet.hs +++ b/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet.hs @@ -3471,14 +3471,14 @@ prop_churn_notimeouts diffScript = <$> events where noChurnTimeout :: TracePeerSelection NtNAddr -> Bool - noChurnTimeout (TraceChurnTimeout DecreasedActivePeers) = False - noChurnTimeout (TraceChurnTimeout DecreasedActiveBigLedgerPeers) = False - noChurnTimeout (TraceChurnTimeout DecreasedEstablishedPeers) = False - noChurnTimeout (TraceChurnTimeout DecreasedEstablishedBigLedgerPeers) = False - noChurnTimeout (TraceChurnTimeout DecreasedKnownPeers) = False - noChurnTimeout (TraceChurnTimeout DecreasedKnownBigLedgerPeers) = False - noChurnTimeout TraceChurnTimeout {} = True - noChurnTimeout _ = True + noChurnTimeout (TraceChurnTimeout DecreasedActivePeers _) = False + noChurnTimeout (TraceChurnTimeout DecreasedActiveBigLedgerPeers _) = False + noChurnTimeout (TraceChurnTimeout DecreasedEstablishedPeers _) = False + noChurnTimeout (TraceChurnTimeout DecreasedEstablishedBigLedgerPeers _) = False + noChurnTimeout (TraceChurnTimeout DecreasedKnownPeers _) = False + noChurnTimeout (TraceChurnTimeout DecreasedKnownBigLedgerPeers _) = False + noChurnTimeout TraceChurnTimeout {} = True + noChurnTimeout _ = True -- | Verify that churn trace consists of repeated list of actions: @@ -3526,9 +3526,9 @@ prop_churn_steps bearerInfo diffScript = in counterexample (intercalate "\n" (show <$> evsList)) . churnTracePredicate . mapMaybe (\case - (_, TraceChurnAction a) -> Just a - (_, TraceChurnTimeout a) -> Just a - _ -> Nothing) + (_, TraceChurnAction a _) -> Just a + (_, TraceChurnTimeout a _) -> Just a + _ -> Nothing) $ evsList ) <$> events diff --git a/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet/Simulation/Node.hs b/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet/Simulation/Node.hs index a8747cd45f..21f1161a04 100644 --- a/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet/Simulation/Node.hs +++ b/ouroboros-network/sim-tests-lib/Test/Ouroboros/Network/Testnet/Simulation/Node.hs @@ -1257,6 +1257,7 @@ diffusionSimulation . tracerWithTime $ nodeTracer , Diff.P2P.dtTracePeerSelectionCounters = nullTracer + , Diff.P2P.dtTraceChurnCounters = nullTracer , Diff.P2P.dtPeerSelectionActionsTracer = contramap DiffusionPeerSelectionActionsTrace . tracerWithName ntnAddr diff --git a/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs b/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs index 2aa57f17a3..2a513ae06b 100644 --- a/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs +++ b/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs @@ -170,6 +170,9 @@ data TracersExtra ntnAddr ntnVersion ntnVersionData , dtTracePeerSelectionCounters :: Tracer m PeerSelectionCounters + , dtTraceChurnCounters + :: Tracer m Governor.ChurnCounters + , dtPeerSelectionActionsTracer :: Tracer m (PeerSelectionActionsTrace ntnAddr ntnVersion) @@ -223,6 +226,7 @@ nullTracers = , dtTracePublicRootPeersTracer = nullTracer , dtTraceLedgerPeersTracer = nullTracer , dtTracePeerSelectionTracer = nullTracer + , dtTraceChurnCounters = nullTracer , dtDebugPeerSelectionInitiatorTracer = nullTracer , dtDebugPeerSelectionInitiatorResponderTracer = nullTracer , dtTracePeerSelectionCounters = nullTracer @@ -598,6 +602,7 @@ runM Interfaces } TracersExtra { dtTracePeerSelectionTracer + , dtTraceChurnCounters , dtDebugPeerSelectionInitiatorTracer , dtDebugPeerSelectionInitiatorResponderTracer , dtTracePeerSelectionCounters @@ -1010,6 +1015,7 @@ runM Interfaces -- let peerChurnGovernor' = Governor.peerChurnGovernor dtTracePeerSelectionTracer + dtTraceChurnCounters daDeadlineChurnInterval daBulkChurnInterval (policyPeerShareOverallTimeout peerSelectionPolicy) diff --git a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs index 1aad8ae5fc..381e86c906 100644 --- a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs +++ b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs @@ -6,7 +6,10 @@ -- | This subsystem manages the discovery and selection of /upstream/ peers. -- -module Ouroboros.Network.PeerSelection.Churn (peerChurnGovernor) where +module Ouroboros.Network.PeerSelection.Churn + ( peerChurnGovernor + , ChurnCounters (..) + ) where import Data.Void (Void) @@ -31,6 +34,8 @@ import Ouroboros.Network.PeerSelection.PeerMetric type ModifyPeerSelectionTargets = PeerSelectionTargets -> PeerSelectionTargets type CheckPeerSelectionCounters = PeerSelectionCounters -> PeerSelectionTargets -> Bool +data ChurnCounters = ChurnCounter ChurnAction Int + -- | Churn governor. -- -- At every churn interval decrease active peers for a short while (1s), so that @@ -46,6 +51,7 @@ peerChurnGovernor :: forall m peeraddr. , MonadCatch m ) => Tracer m (TracePeerSelection peeraddr) + -> Tracer m ChurnCounters -> DiffTime -- ^ the base for churn interval in the deadline mode. -> DiffTime @@ -63,7 +69,7 @@ peerChurnGovernor :: forall m peeraddr. -> STM m PeerSelectionCounters -> STM m UseBootstrapPeers -> m Void -peerChurnGovernor tracer +peerChurnGovernor tracer churnTracer deadlineChurnInterval bulkChurnInterval requestPeersTimeout _metrics churnModeVar inRng getFetchMode base peerSelectionVar readCounters @@ -100,6 +106,8 @@ peerChurnGovernor tracer updateTargets :: ChurnAction -- ^ churn actions for tracing + -> (PeerSelectionCounters -> Int) + -- ^ counter getter -> DiffTime -- ^ timeout -> ModifyPeerSelectionTargets @@ -107,24 +115,34 @@ peerChurnGovernor tracer -> CheckPeerSelectionCounters -- ^ check counters -> m () - updateTargets churnAction timeoutDelay modifyTargets checkCounters = do + updateTargets churnAction getCounter timeoutDelay modifyTargets checkCounters = do -- update targets, and return the new targets - targets <- atomically $ stateTVar peerSelectionVar ((\a -> (a, a)) . modifyTargets) + (c, targets) <- atomically $ + (,) <$> (getCounter <$> readCounters) + <*> stateTVar peerSelectionVar ((\a -> (a, a)) . modifyTargets) -- create timeout and block on counters bracketOnError (registerDelayCancellable timeoutDelay) (\(_readTimeout, cancelTimeout) -> cancelTimeout) (\( readTimeout, cancelTimeout) -> do -- block until counters reached the targets, or the timeout fires - a <- atomically $ runFirstToFinish $ - FirstToFinish ((readCounters>>= check . flip checkCounters targets) $> True) - <> - FirstToFinish (readTimeout >>= \case TimeoutPending -> retry - _ -> pure False) - if a - then cancelTimeout - >> traceWith tracer (TraceChurnAction churnAction) - else traceWith tracer (TraceChurnTimeout churnAction) + a <- atomically $ do + counters <- readCounters + runFirstToFinish $ + FirstToFinish (check (checkCounters counters targets) $> (Right $ getCounter counters )) + <> + FirstToFinish (readTimeout >>= \case TimeoutPending -> retry + _ -> pure (Left $ getCounter counters)) + case a of + Right c' -> do + let r = c' - c + traceWith tracer (TraceChurnAction churnAction r) + traceWith churnTracer (ChurnCounter churnAction r) + Left c' -> do + cancelTimeout + let r = c' - c + traceWith tracer (TraceChurnTimeout churnAction r) + traceWith churnTracer (ChurnCounter churnAction r) ) -- @@ -406,72 +424,84 @@ peerChurnGovernor tracer -- Purge the worst active peers. updateTargets DecreasedActivePeers + numberOfActivePeers deactivateTimeout -- chainsync might timeout after 5mins (decreaseActivePeers churnMode) checkActivePeersDecreased -- Pick new active peers. updateTargets IncreasedActivePeers + numberOfActivePeers shortTimeout (increaseActivePeers churnMode) checkActivePeersIncreased -- Purge the worst active big ledger peers. updateTargets DecreasedActiveBigLedgerPeers + numberOfActiveBigLedgerPeers deactivateTimeout -- chainsync might timeout after 5mins (decreaseActiveBigLedgerPeers churnMode) (checkActiveBigLedgerPeersDecreased) -- Pick new active big ledger peers. updateTargets IncreasedActiveBigLedgerPeers + numberOfActiveBigLedgerPeers shortTimeout (increaseActiveBigLedgerPeers churnMode) checkActiveBigLedgerPeersIncreased -- Forget the worst performing established peers. updateTargets DecreasedEstablishedPeers + numberOfEstablishedPeers (1 + closeConnectionTimeout) (decreaseEstablishedPeers churnMode ubp) (checkEstablishedPeersDecreased) -- Forget the worst performing established big ledger peers. updateTargets DecreasedEstablishedBigLedgerPeers + numberOfEstablishedBigLedgerPeers (1 + closeConnectionTimeout) decreaseEstablishedBigLedgerPeers checkEstablishedBigLedgerPeersDecreased -- Forget the worst performing known peers (root peers, ledger peers) updateTargets DecreasedKnownPeers + numberOfKnownPeers shortTimeout decreaseKnownPeers checkKnownPeersDecreased -- Pick new known peers updateTargets IncreasedKnownPeers + numberOfKnownPeers (2 * requestPeersTimeout + shortTimeout) increaseKnownPeers checkKnownPeersIncreased -- Forget the worst performing known big ledger peers. updateTargets DecreasedKnownBigLedgerPeers + numberOfKnownBigLedgerPeers shortTimeout decreaseKnownBigLedgerPeers checkKnownBigLedgerPeersDecreased -- Pick new known big ledger peers updateTargets IncreasedKnownBigLedgerPeers + numberOfKnownBigLedgerPeers (2 * requestPeersTimeout + shortTimeout) increaseKnownBigLedgerPeers checkKnownBigLedgerPeersIncreased -- Pick new non-active peers updateTargets IncreasedEstablishedPeers + numberOfEstablishedPeers churnEstablishConnectionTimeout (increaseEstablishedPeers churnMode ubp) checkEstablishedPeersIncreased -- Pick new non-active big ledger peers updateTargets IncreasedEstablishedBigLedgerPeers + numberOfEstablishedBigLedgerPeers churnEstablishConnectionTimeout increaseEstablishedBigLedgerPeers checkEstablishedBigLedgerPeersIncreased diff --git a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor.hs b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor.hs index a8aa8d14ef..95a19a7da6 100644 --- a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor.hs +++ b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor.hs @@ -22,6 +22,7 @@ module Ouroboros.Network.PeerSelection.Governor , peerSelectionGovernor -- * Peer churn governor , peerChurnGovernor + , ChurnCounters (..) -- * Internals exported for testing , assertPeerSelectionState , sanePeerSelectionTargets @@ -52,7 +53,8 @@ import Control.Monad.Class.MonadTimer.SI import Control.Tracer (Tracer (..), traceWith) import System.Random -import Ouroboros.Network.PeerSelection.Churn (peerChurnGovernor) +import Ouroboros.Network.PeerSelection.Churn (ChurnCounters (..), + 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 diff --git a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Types.hs b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Types.hs index ccd318d56e..e237246d22 100644 --- a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Types.hs +++ b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Types.hs @@ -1344,8 +1344,8 @@ data TracePeerSelection peeraddr = | TraceChurnWait DiffTime | TraceChurnMode ChurnMode - | TraceChurnAction ChurnAction - | TraceChurnTimeout ChurnAction + | TraceChurnAction ChurnAction Int + | TraceChurnTimeout ChurnAction Int | TraceLedgerStateJudgementChanged LedgerStateJudgement | TraceOnlyBootstrapPeers