{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE OverloadedStrings #-}

module Ouroboros.Network.PeerSelection.Bootstrap
  ( UseBootstrapPeers (..)
  , isBootstrapPeersEnabled
  , requiresBootstrapPeers
  , isNodeAbleToMakeProgress
  ) where

import GHC.Generics (Generic)
import Ouroboros.Network.PeerSelection.LedgerPeers.Type
           (LedgerStateJudgement (..))
import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint)

data UseBootstrapPeers = DontUseBootstrapPeers
                       | UseBootstrapPeers [RelayAccessPoint]
  deriving (UseBootstrapPeers -> UseBootstrapPeers -> Bool
(UseBootstrapPeers -> UseBootstrapPeers -> Bool)
-> (UseBootstrapPeers -> UseBootstrapPeers -> Bool)
-> Eq UseBootstrapPeers
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
== :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
$c/= :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
/= :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
Eq, Int -> UseBootstrapPeers -> ShowS
[UseBootstrapPeers] -> ShowS
UseBootstrapPeers -> String
(Int -> UseBootstrapPeers -> ShowS)
-> (UseBootstrapPeers -> String)
-> ([UseBootstrapPeers] -> ShowS)
-> Show UseBootstrapPeers
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UseBootstrapPeers -> ShowS
showsPrec :: Int -> UseBootstrapPeers -> ShowS
$cshow :: UseBootstrapPeers -> String
show :: UseBootstrapPeers -> String
$cshowList :: [UseBootstrapPeers] -> ShowS
showList :: [UseBootstrapPeers] -> ShowS
Show, Eq UseBootstrapPeers
Eq UseBootstrapPeers =>
(UseBootstrapPeers -> UseBootstrapPeers -> Ordering)
-> (UseBootstrapPeers -> UseBootstrapPeers -> Bool)
-> (UseBootstrapPeers -> UseBootstrapPeers -> Bool)
-> (UseBootstrapPeers -> UseBootstrapPeers -> Bool)
-> (UseBootstrapPeers -> UseBootstrapPeers -> Bool)
-> (UseBootstrapPeers -> UseBootstrapPeers -> UseBootstrapPeers)
-> (UseBootstrapPeers -> UseBootstrapPeers -> UseBootstrapPeers)
-> Ord UseBootstrapPeers
UseBootstrapPeers -> UseBootstrapPeers -> Bool
UseBootstrapPeers -> UseBootstrapPeers -> Ordering
UseBootstrapPeers -> UseBootstrapPeers -> UseBootstrapPeers
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UseBootstrapPeers -> UseBootstrapPeers -> Ordering
compare :: UseBootstrapPeers -> UseBootstrapPeers -> Ordering
$c< :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
< :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
$c<= :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
<= :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
$c> :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
> :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
$c>= :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
>= :: UseBootstrapPeers -> UseBootstrapPeers -> Bool
$cmax :: UseBootstrapPeers -> UseBootstrapPeers -> UseBootstrapPeers
max :: UseBootstrapPeers -> UseBootstrapPeers -> UseBootstrapPeers
$cmin :: UseBootstrapPeers -> UseBootstrapPeers -> UseBootstrapPeers
min :: UseBootstrapPeers -> UseBootstrapPeers -> UseBootstrapPeers
Ord, (forall x. UseBootstrapPeers -> Rep UseBootstrapPeers x)
-> (forall x. Rep UseBootstrapPeers x -> UseBootstrapPeers)
-> Generic UseBootstrapPeers
forall x. Rep UseBootstrapPeers x -> UseBootstrapPeers
forall x. UseBootstrapPeers -> Rep UseBootstrapPeers x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. UseBootstrapPeers -> Rep UseBootstrapPeers x
from :: forall x. UseBootstrapPeers -> Rep UseBootstrapPeers x
$cto :: forall x. Rep UseBootstrapPeers x -> UseBootstrapPeers
to :: forall x. Rep UseBootstrapPeers x -> UseBootstrapPeers
Generic)

isBootstrapPeersEnabled :: UseBootstrapPeers -> Bool
isBootstrapPeersEnabled :: UseBootstrapPeers -> Bool
isBootstrapPeersEnabled UseBootstrapPeers
DontUseBootstrapPeers = Bool
False
isBootstrapPeersEnabled UseBootstrapPeers
_                     = Bool
True

-- | Determines if the system is in a sensitive state based on bootstrap peer
-- usage and ledger state.
--
-- * When bootstrap peers are not in use, the system is considered to never be
-- in a sensitive state.
-- * When bootstrap peers are in use and the ledger is in 'YoungEnough' state,
-- the system is not in a sensitive state.
-- * When bootstrap peers are in use and the ledger is in 'TooOld' state,
-- the system is considered to be in a sensitive state.
requiresBootstrapPeers :: UseBootstrapPeers -> LedgerStateJudgement -> Bool
requiresBootstrapPeers :: UseBootstrapPeers -> LedgerStateJudgement -> Bool
requiresBootstrapPeers UseBootstrapPeers
ubp LedgerStateJudgement
lsj =
  UseBootstrapPeers -> Bool
isBootstrapPeersEnabled UseBootstrapPeers
ubp Bool -> Bool -> Bool
&& LedgerStateJudgement
lsj LedgerStateJudgement -> LedgerStateJudgement -> Bool
forall a. Eq a => a -> a -> Bool
== LedgerStateJudgement
TooOld

-- | A node is able to make progress either if it isn't in a sensitive state
-- _or_ if it is in a sensitive state and has reached a clean state from which
-- it now only uses trustable peers
--
isNodeAbleToMakeProgress :: UseBootstrapPeers -> LedgerStateJudgement -> Bool -> Bool
isNodeAbleToMakeProgress :: UseBootstrapPeers -> LedgerStateJudgement -> Bool -> Bool
isNodeAbleToMakeProgress UseBootstrapPeers
ubp LedgerStateJudgement
lsj Bool
hasOnlyBootstrapPeers =
    Bool -> Bool
not (UseBootstrapPeers -> LedgerStateJudgement -> Bool
requiresBootstrapPeers UseBootstrapPeers
ubp LedgerStateJudgement
lsj) Bool -> Bool -> Bool
|| Bool
hasOnlyBootstrapPeers