From 05ab38bf1f2a8d9d4721f4b0c850784dd37b2ebe Mon Sep 17 00:00:00 2001 From: Armando Santos Date: Mon, 19 Feb 2024 15:38:02 +0000 Subject: [PATCH] Churn BootstrapPeers --- ouroboros-network/CHANGELOG.md | 5 + .../src/Ouroboros/Network/Diffusion/P2P.hs | 1 + .../Ouroboros/Network/PeerSelection/Churn.hs | 94 ++++++++++++------- .../Network/PeerSelection/Governor/Monitor.hs | 14 +-- 4 files changed, 75 insertions(+), 39 deletions(-) diff --git a/ouroboros-network/CHANGELOG.md b/ouroboros-network/CHANGELOG.md index e8542960a96..63e71346f7f 100644 --- a/ouroboros-network/CHANGELOG.md +++ b/ouroboros-network/CHANGELOG.md @@ -58,6 +58,11 @@ * Fix `targetPeers` monitoring action to use the correct set of local peers when in sensitive mode. +* Forget non-established bootstrap peers when transitioning from + `TooOld` state to `YoungEnough` + +* Implemented Churn for bootstrap peers + ## 0.11.0.0 -- 2023-01-22 ### Breaking changes diff --git a/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs b/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs index 661be62e6d8..d92c7fef30d 100644 --- a/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs +++ b/ouroboros-network/src/Ouroboros/Network/Diffusion/P2P.hs @@ -1023,6 +1023,7 @@ runM Interfaces daBlockFetchMode daPeerSelectionTargets peerSelectionTargetsVar + daReadUseBootstrapPeers -- -- Two functions only used in InitiatorAndResponder mode diff --git a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs index d57829cd4da..42c8fbab65c 100644 --- a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs +++ b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Churn.hs @@ -16,6 +16,7 @@ import System.Random import Ouroboros.Network.BlockFetch (FetchMode (..)) import Ouroboros.Network.Diffusion.Policies (closeConnectionTimeout) +import Ouroboros.Network.PeerSelection.Bootstrap (UseBootstrapPeers (..)) import Ouroboros.Network.PeerSelection.Governor.Types hiding (targets) import Ouroboros.Network.PeerSelection.PeerMetric @@ -45,9 +46,11 @@ peerChurnGovernor :: forall m peeraddr. -> STM m FetchMode -> PeerSelectionTargets -> StrictTVar m PeerSelectionTargets + -> STM m UseBootstrapPeers -> m Void peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeout - _metrics churnModeVar inRng getFetchMode base peerSelectionVar = do + _metrics churnModeVar inRng getFetchMode base peerSelectionVar + getUseBootstrapPeers = do -- Wait a while so that not only the closest peers have had the time -- to become warm. startTs0 <- getMonotonicTime @@ -55,8 +58,11 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou -- The intention is to give local root peers give head start and avoid -- giving advantage to hostile and quick root peers. threadDelay 3 - mode <- atomically updateChurnMode - atomically $ increaseActivePeers mode + (mode, ubp) <- atomically ((,) <$> updateChurnMode + <*> getUseBootstrapPeers) + atomically $ do + increaseActivePeers mode + increaseEstablishedPeers mode ubp endTs0 <- getMonotonicTime fuzzyDelay inRng (endTs0 `diffTime` startTs0) >>= go @@ -73,7 +79,7 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou -- TODO: #3396 revisit the policy for genesis increaseActivePeers :: ChurnMode -> STM m () - increaseActivePeers mode = do + increaseActivePeers mode = modifyTVar peerSelectionVar (\targets -> targets { targetNumberOfActivePeers = case mode of @@ -84,7 +90,7 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou }) decreaseActivePeers :: ChurnMode -> STM m () - decreaseActivePeers mode = do + decreaseActivePeers mode = modifyTVar peerSelectionVar (\targets -> targets { targetNumberOfActivePeers = case mode of @@ -94,8 +100,30 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou min 1 (targetNumberOfActivePeers base - 1) }) + increaseEstablishedPeers :: ChurnMode -> UseBootstrapPeers -> STM m () + increaseEstablishedPeers mode ubp = + modifyTVar peerSelectionVar (\targets -> targets { + targetNumberOfEstablishedPeers = + case (mode, ubp) of + (ChurnModeBulkSync, UseBootstrapPeers _) -> + min (targetNumberOfActivePeers targets + 1) + (targetNumberOfEstablishedPeers base) + _ -> targetNumberOfEstablishedPeers base + }) + + decreaseEstablished :: ChurnMode -> UseBootstrapPeers -> STM m () + decreaseEstablished mode ubp = + modifyTVar peerSelectionVar (\targets -> targets { + targetNumberOfEstablishedPeers = + case (mode, ubp) of + (ChurnModeBulkSync, UseBootstrapPeers _) -> + min (targetNumberOfActivePeers targets) (targetNumberOfEstablishedPeers base - 1) + _ -> decrease (targetNumberOfEstablishedPeers base - targetNumberOfActivePeers base) + + targetNumberOfActivePeers base + }) + increaseActiveBigLedgerPeers :: ChurnMode -> STM m () - increaseActiveBigLedgerPeers mode = do + increaseActiveBigLedgerPeers mode = modifyTVar peerSelectionVar (\targets -> targets { -- TODO: when chain-skipping will be implemented and chain-sync client -- will take into account big ledger peers, we don't need pattern @@ -110,7 +138,7 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou }) decreaseActiveBigLedgerPeers :: ChurnMode -> STM m () - decreaseActiveBigLedgerPeers mode = do + decreaseActiveBigLedgerPeers mode = modifyTVar peerSelectionVar (\targets -> targets { targetNumberOfActiveBigLedgerPeers = case mode of @@ -125,11 +153,13 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou go !rng = do startTs <- getMonotonicTime - churnMode <- atomically updateChurnMode + (churnMode, ubp) <- atomically ((,) <$> updateChurnMode + <*> getUseBootstrapPeers) traceWith tracer $ TraceChurnMode churnMode - -- Purge the worst active peer(s). - atomically $ decreaseActivePeers churnMode + atomically $ do + -- Purge the worst active peer(s). + decreaseActivePeers churnMode -- Short delay, we may have no active peers right now threadDelay 1 @@ -151,25 +181,24 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou threadDelay 1 -- Forget the worst performing non-active peers. - atomically $ modifyTVar peerSelectionVar (\targets -> targets { - targetNumberOfRootPeers = - decrease (targetNumberOfRootPeers base - targetNumberOfEstablishedPeers base) - + targetNumberOfEstablishedPeers base - , targetNumberOfKnownPeers = - decrease (targetNumberOfKnownPeers base - targetNumberOfEstablishedPeers base) - + targetNumberOfEstablishedPeers base - , targetNumberOfEstablishedPeers = - decrease (targetNumberOfEstablishedPeers base - targetNumberOfActivePeers base) - + targetNumberOfActivePeers base - , targetNumberOfKnownBigLedgerPeers = - decrease (targetNumberOfKnownBigLedgerPeers base - - targetNumberOfEstablishedBigLedgerPeers base) - + targetNumberOfEstablishedBigLedgerPeers base - , targetNumberOfEstablishedBigLedgerPeers = - decrease (targetNumberOfEstablishedBigLedgerPeers base - - targetNumberOfActiveBigLedgerPeers base) - + targetNumberOfActiveBigLedgerPeers base - }) + atomically $ do + decreaseEstablished churnMode ubp + modifyTVar peerSelectionVar (\targets -> targets { + targetNumberOfRootPeers = + decrease (targetNumberOfRootPeers base - targetNumberOfEstablishedPeers base) + + targetNumberOfEstablishedPeers base + , targetNumberOfKnownPeers = + decrease (targetNumberOfKnownPeers base - targetNumberOfEstablishedPeers base) + + targetNumberOfEstablishedPeers base + , targetNumberOfKnownBigLedgerPeers = + decrease (targetNumberOfKnownBigLedgerPeers base - + targetNumberOfEstablishedBigLedgerPeers base) + + targetNumberOfEstablishedBigLedgerPeers base + , targetNumberOfEstablishedBigLedgerPeers = + decrease (targetNumberOfEstablishedBigLedgerPeers base - + targetNumberOfActiveBigLedgerPeers base) + + targetNumberOfActiveBigLedgerPeers base + }) -- Give the governor time to properly demote them. threadDelay $ 1 + closeConnectionTimeout @@ -185,9 +214,10 @@ peerChurnGovernor tracer deadlineChurnInterval bulkChurnInterval psOverallTimeou threadDelay $ 1 + psOverallTimeout -- Pick new non-active peers - atomically $ modifyTVar peerSelectionVar (\targets -> targets { - targetNumberOfEstablishedPeers = targetNumberOfEstablishedPeers base - , targetNumberOfEstablishedBigLedgerPeers = targetNumberOfEstablishedBigLedgerPeers base + atomically $ do + increaseEstablishedPeers churnMode ubp + modifyTVar peerSelectionVar (\targets -> targets { + targetNumberOfEstablishedBigLedgerPeers = targetNumberOfEstablishedBigLedgerPeers base }) endTs <- getMonotonicTime diff --git a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Monitor.hs b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Monitor.hs index 2c509c5b193..80d6f95fe39 100644 --- a/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Monitor.hs +++ b/ouroboros-network/src/Ouroboros/Network/PeerSelection/Governor/Monitor.hs @@ -557,9 +557,9 @@ localRoots actions@PeerSelectionActions{ readLocalRootPeers monitorBootstrapPeersFlag :: ( MonadSTM m , Ord peeraddr ) - => PeerSelectionActions peeraddr peerconn m - -> PeerSelectionState peeraddr peerconn - -> Guarded (STM m) (TimedDecision m peeraddr peerconn) + => PeerSelectionActions peeraddr peerconn m + -> PeerSelectionState peeraddr peerconn + -> Guarded (STM m) (TimedDecision m peeraddr peerconn) monitorBootstrapPeersFlag PeerSelectionActions { readUseBootstrapPeers } st@PeerSelectionState { bootstrapPeersFlag , knownPeers @@ -573,9 +573,9 @@ monitorBootstrapPeersFlag PeerSelectionActions { readUseBootstrapPeers } check (ubp /= bootstrapPeersFlag) let nonEstablishedBootstrapPeers = PublicRootPeers.getBootstrapPeers publicRootPeers - `Set.difference` + Set.\\ EstablishedPeers.toSet establishedPeers - `Set.difference` + Set.\\ (inProgressPromoteCold <> inProgressPromoteWarm) return $ \_now -> Decision { @@ -654,9 +654,9 @@ monitorLedgerStateJudgement PeerSelectionActions{ readLedgerStateJudgement } YoungEnough -> do let nonEstablishedBootstrapPeers = PublicRootPeers.getBootstrapPeers publicRootPeers - `Set.difference` + Set.\\ EstablishedPeers.toSet establishedPeers - `Set.difference` + Set.\\ (inProgressPromoteCold <> inProgressPromoteWarm) return (\_ -> st { ledgerStateJudgement = lsj