{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ouroboros.Network.PeerSelection.KnownPeers
(
KnownPeers
, invariant
, empty
, size
, insert
, delete
, toSet
, member
, setCurrentTime
, incrementFailCount
, resetFailCount
, lookupFailCount
, lookupTepidFlag
, setTepidFlag
, clearTepidFlag
, minGossipTime
, setGossipTime
, availableForGossip
, minConnectTime
, setConnectTime
, availableToConnect
) where
import qualified Data.List as List
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.OrdPSQ (OrdPSQ)
import qualified Data.OrdPSQ as PSQ
import Data.Semigroup (Min (..))
import Data.Set (Set)
import qualified Data.Set as Set
import Control.Exception (assert)
import Control.Monad.Class.MonadTime
data KnownPeers peeraddr = KnownPeers {
KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers :: !(Map peeraddr KnownPeerInfo),
KnownPeers peeraddr -> Set peeraddr
availableForGossip :: !(Set peeraddr),
KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextGossipTimes :: !(OrdPSQ peeraddr Time ()),
KnownPeers peeraddr -> Set peeraddr
availableToConnect :: !(Set peeraddr),
KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextConnectTimes :: !(OrdPSQ peeraddr Time ())
}
deriving Int -> KnownPeers peeraddr -> ShowS
[KnownPeers peeraddr] -> ShowS
KnownPeers peeraddr -> String
(Int -> KnownPeers peeraddr -> ShowS)
-> (KnownPeers peeraddr -> String)
-> ([KnownPeers peeraddr] -> ShowS)
-> Show (KnownPeers peeraddr)
forall peeraddr.
Show peeraddr =>
Int -> KnownPeers peeraddr -> ShowS
forall peeraddr. Show peeraddr => [KnownPeers peeraddr] -> ShowS
forall peeraddr. Show peeraddr => KnownPeers peeraddr -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KnownPeers peeraddr] -> ShowS
$cshowList :: forall peeraddr. Show peeraddr => [KnownPeers peeraddr] -> ShowS
show :: KnownPeers peeraddr -> String
$cshow :: forall peeraddr. Show peeraddr => KnownPeers peeraddr -> String
showsPrec :: Int -> KnownPeers peeraddr -> ShowS
$cshowsPrec :: forall peeraddr.
Show peeraddr =>
Int -> KnownPeers peeraddr -> ShowS
Show
data KnownPeerInfo = KnownPeerInfo {
KnownPeerInfo -> Int
knownPeerFailCount :: !Int,
KnownPeerInfo -> Bool
knownPeerTepid :: !Bool
}
deriving (KnownPeerInfo -> KnownPeerInfo -> Bool
(KnownPeerInfo -> KnownPeerInfo -> Bool)
-> (KnownPeerInfo -> KnownPeerInfo -> Bool) -> Eq KnownPeerInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KnownPeerInfo -> KnownPeerInfo -> Bool
$c/= :: KnownPeerInfo -> KnownPeerInfo -> Bool
== :: KnownPeerInfo -> KnownPeerInfo -> Bool
$c== :: KnownPeerInfo -> KnownPeerInfo -> Bool
Eq, Int -> KnownPeerInfo -> ShowS
[KnownPeerInfo] -> ShowS
KnownPeerInfo -> String
(Int -> KnownPeerInfo -> ShowS)
-> (KnownPeerInfo -> String)
-> ([KnownPeerInfo] -> ShowS)
-> Show KnownPeerInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KnownPeerInfo] -> ShowS
$cshowList :: [KnownPeerInfo] -> ShowS
show :: KnownPeerInfo -> String
$cshow :: KnownPeerInfo -> String
showsPrec :: Int -> KnownPeerInfo -> ShowS
$cshowsPrec :: Int -> KnownPeerInfo -> ShowS
Show)
invariant :: Ord peeraddr => KnownPeers peeraddr -> Bool
invariant :: KnownPeers peeraddr -> Bool
invariant KnownPeers{Map peeraddr KnownPeerInfo
Set peeraddr
OrdPSQ peeraddr Time ()
nextConnectTimes :: OrdPSQ peeraddr Time ()
availableToConnect :: Set peeraddr
nextGossipTimes :: OrdPSQ peeraddr Time ()
availableForGossip :: Set peeraddr
allPeers :: Map peeraddr KnownPeerInfo
nextConnectTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextGossipTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
availableToConnect :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableForGossip :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
..} =
Set peeraddr
availableForGossip
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Semigroup a => a -> a -> a
<> [peeraddr] -> Set peeraddr
forall a. Ord a => [a] -> Set a
Set.fromList (OrdPSQ peeraddr Time () -> [peeraddr]
forall k p v. OrdPSQ k p v -> [k]
PSQ.keys OrdPSQ peeraddr Time ()
nextGossipTimes)
Set peeraddr -> Set peeraddr -> Bool
forall a. Eq a => a -> a -> Bool
== Map peeraddr KnownPeerInfo -> Set peeraddr
forall k a. Map k a -> Set k
Map.keysSet Map peeraddr KnownPeerInfo
allPeers
Bool -> Bool -> Bool
&& Set peeraddr -> Bool
forall a. Set a -> Bool
Set.null
(Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Ord a => Set a -> Set a -> Set a
Set.intersection
Set peeraddr
availableForGossip
([peeraddr] -> Set peeraddr
forall a. Ord a => [a] -> Set a
Set.fromList (OrdPSQ peeraddr Time () -> [peeraddr]
forall k p v. OrdPSQ k p v -> [k]
PSQ.keys OrdPSQ peeraddr Time ()
nextGossipTimes)))
Bool -> Bool -> Bool
&& Set peeraddr
availableToConnect
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Semigroup a => a -> a -> a
<> [peeraddr] -> Set peeraddr
forall a. Ord a => [a] -> Set a
Set.fromList (OrdPSQ peeraddr Time () -> [peeraddr]
forall k p v. OrdPSQ k p v -> [k]
PSQ.keys OrdPSQ peeraddr Time ()
nextConnectTimes)
Set peeraddr -> Set peeraddr -> Bool
forall a. Eq a => a -> a -> Bool
== Map peeraddr KnownPeerInfo -> Set peeraddr
forall k a. Map k a -> Set k
Map.keysSet Map peeraddr KnownPeerInfo
allPeers
Bool -> Bool -> Bool
&& Set peeraddr -> Bool
forall a. Set a -> Bool
Set.null
(Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Ord a => Set a -> Set a -> Set a
Set.intersection
Set peeraddr
availableToConnect
([peeraddr] -> Set peeraddr
forall a. Ord a => [a] -> Set a
Set.fromList (OrdPSQ peeraddr Time () -> [peeraddr]
forall k p v. OrdPSQ k p v -> [k]
PSQ.keys OrdPSQ peeraddr Time ()
nextConnectTimes)))
empty :: KnownPeers peeraddr
empty :: KnownPeers peeraddr
empty =
KnownPeers :: forall peeraddr.
Map peeraddr KnownPeerInfo
-> Set peeraddr
-> OrdPSQ peeraddr Time ()
-> Set peeraddr
-> OrdPSQ peeraddr Time ()
-> KnownPeers peeraddr
KnownPeers {
allPeers :: Map peeraddr KnownPeerInfo
allPeers = Map peeraddr KnownPeerInfo
forall k a. Map k a
Map.empty,
availableForGossip :: Set peeraddr
availableForGossip = Set peeraddr
forall a. Set a
Set.empty,
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes = OrdPSQ peeraddr Time ()
forall k p v. OrdPSQ k p v
PSQ.empty,
availableToConnect :: Set peeraddr
availableToConnect = Set peeraddr
forall a. Set a
Set.empty,
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes = OrdPSQ peeraddr Time ()
forall k p v. OrdPSQ k p v
PSQ.empty
}
size :: KnownPeers peeraddr -> Int
size :: KnownPeers peeraddr -> Int
size = Map peeraddr KnownPeerInfo -> Int
forall k a. Map k a -> Int
Map.size (Map peeraddr KnownPeerInfo -> Int)
-> (KnownPeers peeraddr -> Map peeraddr KnownPeerInfo)
-> KnownPeers peeraddr
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers
toSet :: KnownPeers peeraddr -> Set peeraddr
toSet :: KnownPeers peeraddr -> Set peeraddr
toSet = Map peeraddr KnownPeerInfo -> Set peeraddr
forall k a. Map k a -> Set k
Map.keysSet (Map peeraddr KnownPeerInfo -> Set peeraddr)
-> (KnownPeers peeraddr -> Map peeraddr KnownPeerInfo)
-> KnownPeers peeraddr
-> Set peeraddr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers
member :: Ord peeraddr
=> peeraddr
-> KnownPeers peeraddr
-> Bool
member :: peeraddr -> KnownPeers peeraddr -> Bool
member peeraddr
peeraddr KnownPeers {Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers} =
peeraddr
peeraddr peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map peeraddr KnownPeerInfo
allPeers
insert :: Ord peeraddr
=> Set peeraddr
-> KnownPeers peeraddr
-> KnownPeers peeraddr
insert :: Set peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
insert Set peeraddr
peeraddrs
knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers {
Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers,
Set peeraddr
availableForGossip :: Set peeraddr
availableForGossip :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableForGossip,
Set peeraddr
availableToConnect :: Set peeraddr
availableToConnect :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableToConnect
} =
let knownPeers' :: KnownPeers peeraddr
knownPeers' = KnownPeers peeraddr
knownPeers {
allPeers :: Map peeraddr KnownPeerInfo
allPeers =
let <+> :: Map peeraddr KnownPeerInfo
-> Map peeraddr KnownPeerInfo -> Map peeraddr KnownPeerInfo
(<+>) = (KnownPeerInfo -> KnownPeerInfo -> KnownPeerInfo)
-> Map peeraddr KnownPeerInfo
-> Map peeraddr KnownPeerInfo
-> Map peeraddr KnownPeerInfo
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith KnownPeerInfo -> KnownPeerInfo -> KnownPeerInfo
forall p. KnownPeerInfo -> p -> KnownPeerInfo
mergePeerInfo in
Map peeraddr KnownPeerInfo
allPeers
Map peeraddr KnownPeerInfo
-> Map peeraddr KnownPeerInfo -> Map peeraddr KnownPeerInfo
<+> (peeraddr -> KnownPeerInfo)
-> Set peeraddr -> Map peeraddr KnownPeerInfo
forall k a. (k -> a) -> Set k -> Map k a
Map.fromSet peeraddr -> KnownPeerInfo
forall p. p -> KnownPeerInfo
newPeerInfo Set peeraddr
peeraddrs,
availableForGossip :: Set peeraddr
availableForGossip =
Set peeraddr
availableForGossip
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Semigroup a => a -> a -> a
<> (peeraddr -> Bool) -> Set peeraddr -> Set peeraddr
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.notMember` Map peeraddr KnownPeerInfo
allPeers) Set peeraddr
peeraddrs,
availableToConnect :: Set peeraddr
availableToConnect =
Set peeraddr
availableToConnect
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Semigroup a => a -> a -> a
<> (peeraddr -> Bool) -> Set peeraddr -> Set peeraddr
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.notMember` Map peeraddr KnownPeerInfo
allPeers) Set peeraddr
peeraddrs
}
in Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (KnownPeers peeraddr -> Bool
forall peeraddr. Ord peeraddr => KnownPeers peeraddr -> Bool
invariant KnownPeers peeraddr
knownPeers') KnownPeers peeraddr
knownPeers'
where
newPeerInfo :: p -> KnownPeerInfo
newPeerInfo p
_peeraddr =
KnownPeerInfo :: Int -> Bool -> KnownPeerInfo
KnownPeerInfo {
knownPeerFailCount :: Int
knownPeerFailCount = Int
0
, knownPeerTepid :: Bool
knownPeerTepid = Bool
False
}
mergePeerInfo :: KnownPeerInfo -> p -> KnownPeerInfo
mergePeerInfo KnownPeerInfo
old p
_new =
KnownPeerInfo :: Int -> Bool -> KnownPeerInfo
KnownPeerInfo {
knownPeerFailCount :: Int
knownPeerFailCount = KnownPeerInfo -> Int
knownPeerFailCount KnownPeerInfo
old
, knownPeerTepid :: Bool
knownPeerTepid = KnownPeerInfo -> Bool
knownPeerTepid KnownPeerInfo
old
}
delete :: Ord peeraddr
=> Set peeraddr
-> KnownPeers peeraddr
-> KnownPeers peeraddr
delete :: Set peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
delete Set peeraddr
peeraddrs
knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers {
Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers,
Set peeraddr
availableForGossip :: Set peeraddr
availableForGossip :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableForGossip,
OrdPSQ peeraddr Time ()
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextGossipTimes,
Set peeraddr
availableToConnect :: Set peeraddr
availableToConnect :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableToConnect,
OrdPSQ peeraddr Time ()
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextConnectTimes
} =
KnownPeers peeraddr
knownPeers {
allPeers :: Map peeraddr KnownPeerInfo
allPeers =
Map peeraddr KnownPeerInfo
-> Set peeraddr -> Map peeraddr KnownPeerInfo
forall k a. Ord k => Map k a -> Set k -> Map k a
Map.withoutKeys Map peeraddr KnownPeerInfo
allPeers Set peeraddr
peeraddrs,
availableForGossip :: Set peeraddr
availableForGossip =
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set peeraddr
availableForGossip Set peeraddr
peeraddrs,
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes =
(OrdPSQ peeraddr Time () -> peeraddr -> OrdPSQ peeraddr Time ())
-> OrdPSQ peeraddr Time ()
-> Set peeraddr
-> OrdPSQ peeraddr Time ()
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' ((peeraddr -> OrdPSQ peeraddr Time () -> OrdPSQ peeraddr Time ())
-> OrdPSQ peeraddr Time () -> peeraddr -> OrdPSQ peeraddr Time ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip peeraddr -> OrdPSQ peeraddr Time () -> OrdPSQ peeraddr Time ()
forall k p v. (Ord k, Ord p) => k -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.delete) OrdPSQ peeraddr Time ()
nextGossipTimes Set peeraddr
peeraddrs,
availableToConnect :: Set peeraddr
availableToConnect =
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set peeraddr
availableToConnect Set peeraddr
peeraddrs,
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes =
(OrdPSQ peeraddr Time () -> peeraddr -> OrdPSQ peeraddr Time ())
-> OrdPSQ peeraddr Time ()
-> Set peeraddr
-> OrdPSQ peeraddr Time ()
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' ((peeraddr -> OrdPSQ peeraddr Time () -> OrdPSQ peeraddr Time ())
-> OrdPSQ peeraddr Time () -> peeraddr -> OrdPSQ peeraddr Time ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip peeraddr -> OrdPSQ peeraddr Time () -> OrdPSQ peeraddr Time ()
forall k p v. (Ord k, Ord p) => k -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.delete) OrdPSQ peeraddr Time ()
nextConnectTimes Set peeraddr
peeraddrs
}
setCurrentTime :: Ord peeraddr
=> Time
-> KnownPeers peeraddr
-> KnownPeers peeraddr
setCurrentTime :: Time -> KnownPeers peeraddr -> KnownPeers peeraddr
setCurrentTime Time
now knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers { OrdPSQ peeraddr Time ()
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextGossipTimes, OrdPSQ peeraddr Time ()
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextConnectTimes }
| Just (Min Time
t) <- ((peeraddr, Time, (), OrdPSQ peeraddr Time ()) -> Min Time
forall a a c d. (a, a, c, d) -> Min a
f ((peeraddr, Time, (), OrdPSQ peeraddr Time ()) -> Min Time)
-> Maybe (peeraddr, Time, (), OrdPSQ peeraddr Time ())
-> Maybe (Min Time)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OrdPSQ peeraddr Time ()
-> Maybe (peeraddr, Time, (), OrdPSQ peeraddr Time ())
forall k p v.
(Ord k, Ord p) =>
OrdPSQ k p v -> Maybe (k, p, v, OrdPSQ k p v)
PSQ.minView OrdPSQ peeraddr Time ()
nextGossipTimes)
Maybe (Min Time) -> Maybe (Min Time) -> Maybe (Min Time)
forall a. Semigroup a => a -> a -> a
<> ((peeraddr, Time, (), OrdPSQ peeraddr Time ()) -> Min Time
forall a a c d. (a, a, c, d) -> Min a
f ((peeraddr, Time, (), OrdPSQ peeraddr Time ()) -> Min Time)
-> Maybe (peeraddr, Time, (), OrdPSQ peeraddr Time ())
-> Maybe (Min Time)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OrdPSQ peeraddr Time ()
-> Maybe (peeraddr, Time, (), OrdPSQ peeraddr Time ())
forall k p v.
(Ord k, Ord p) =>
OrdPSQ k p v -> Maybe (k, p, v, OrdPSQ k p v)
PSQ.minView OrdPSQ peeraddr Time ()
nextConnectTimes)
, Time
t Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
> Time
now
= KnownPeers peeraddr
knownPeers
where
f :: (a, a, c, d) -> Min a
f (a
_,a
t,c
_,d
_) = a -> Min a
forall a. a -> Min a
Min a
t
setCurrentTime Time
now knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers {
Set peeraddr
availableForGossip :: Set peeraddr
availableForGossip :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableForGossip,
OrdPSQ peeraddr Time ()
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextGossipTimes,
Set peeraddr
availableToConnect :: Set peeraddr
availableToConnect :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableToConnect,
OrdPSQ peeraddr Time ()
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextConnectTimes
} =
let knownPeers' :: KnownPeers peeraddr
knownPeers' =
KnownPeers peeraddr
knownPeers {
availableForGossip :: Set peeraddr
availableForGossip = Set peeraddr
availableForGossip',
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes = OrdPSQ peeraddr Time ()
nextGossipTimes',
availableToConnect :: Set peeraddr
availableToConnect = Set peeraddr
availableToConnect',
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes = OrdPSQ peeraddr Time ()
nextConnectTimes'
}
in Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (KnownPeers peeraddr -> Bool
forall peeraddr. Ord peeraddr => KnownPeers peeraddr -> Bool
invariant KnownPeers peeraddr
knownPeers') KnownPeers peeraddr
knownPeers'
where
([(peeraddr, Time, ())]
nowAvailableForGossip, OrdPSQ peeraddr Time ()
nextGossipTimes') =
Time
-> OrdPSQ peeraddr Time ()
-> ([(peeraddr, Time, ())], OrdPSQ peeraddr Time ())
forall k p v.
(Ord k, Ord p) =>
p -> OrdPSQ k p v -> ([(k, p, v)], OrdPSQ k p v)
PSQ.atMostView Time
now OrdPSQ peeraddr Time ()
nextGossipTimes
availableForGossip' :: Set peeraddr
availableForGossip' =
Set peeraddr
availableForGossip
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Semigroup a => a -> a -> a
<> [peeraddr] -> Set peeraddr
forall a. Ord a => [a] -> Set a
Set.fromList [ peeraddr
peeraddr | (peeraddr
peeraddr, Time
_, ()
_) <- [(peeraddr, Time, ())]
nowAvailableForGossip ]
([(peeraddr, Time, ())]
nowAvailableToConnect, OrdPSQ peeraddr Time ()
nextConnectTimes') =
Time
-> OrdPSQ peeraddr Time ()
-> ([(peeraddr, Time, ())], OrdPSQ peeraddr Time ())
forall k p v.
(Ord k, Ord p) =>
p -> OrdPSQ k p v -> ([(k, p, v)], OrdPSQ k p v)
PSQ.atMostView Time
now OrdPSQ peeraddr Time ()
nextConnectTimes
availableToConnect' :: Set peeraddr
availableToConnect' =
Set peeraddr
availableToConnect
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Semigroup a => a -> a -> a
<> [peeraddr] -> Set peeraddr
forall a. Ord a => [a] -> Set a
Set.fromList [ peeraddr
peeraddr | (peeraddr
peeraddr, Time
_, ()
_) <- [(peeraddr, Time, ())]
nowAvailableToConnect ]
incrementFailCount :: Ord peeraddr
=> peeraddr
-> KnownPeers peeraddr
-> (Int, KnownPeers peeraddr)
incrementFailCount :: peeraddr -> KnownPeers peeraddr -> (Int, KnownPeers peeraddr)
incrementFailCount peeraddr
peeraddr knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers{Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers} =
Bool -> (Int, KnownPeers peeraddr) -> (Int, KnownPeers peeraddr)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (peeraddr
peeraddr peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map peeraddr KnownPeerInfo
allPeers) ((Int, KnownPeers peeraddr) -> (Int, KnownPeers peeraddr))
-> (Int, KnownPeers peeraddr) -> (Int, KnownPeers peeraddr)
forall a b. (a -> b) -> a -> b
$
let allPeers' :: Map peeraddr KnownPeerInfo
allPeers' = (KnownPeerInfo -> Maybe KnownPeerInfo)
-> peeraddr
-> Map peeraddr KnownPeerInfo
-> Map peeraddr KnownPeerInfo
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update (KnownPeerInfo -> Maybe KnownPeerInfo
forall a. a -> Maybe a
Just (KnownPeerInfo -> Maybe KnownPeerInfo)
-> (KnownPeerInfo -> KnownPeerInfo)
-> KnownPeerInfo
-> Maybe KnownPeerInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KnownPeerInfo -> KnownPeerInfo
incr) peeraddr
peeraddr Map peeraddr KnownPeerInfo
allPeers
in (
KnownPeerInfo -> Int
knownPeerFailCount (Map peeraddr KnownPeerInfo
allPeers' Map peeraddr KnownPeerInfo -> peeraddr -> KnownPeerInfo
forall k a. Ord k => Map k a -> k -> a
Map.! peeraddr
peeraddr)
, KnownPeers peeraddr
knownPeers { allPeers :: Map peeraddr KnownPeerInfo
allPeers = Map peeraddr KnownPeerInfo
allPeers' }
)
where
incr :: KnownPeerInfo -> KnownPeerInfo
incr KnownPeerInfo
kpi = KnownPeerInfo
kpi { knownPeerFailCount :: Int
knownPeerFailCount = KnownPeerInfo -> Int
knownPeerFailCount KnownPeerInfo
kpi Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 }
resetFailCount :: Ord peeraddr
=> peeraddr
-> KnownPeers peeraddr
-> KnownPeers peeraddr
resetFailCount :: peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
resetFailCount peeraddr
peeraddr knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers{Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers} =
Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (peeraddr
peeraddr peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map peeraddr KnownPeerInfo
allPeers) (KnownPeers peeraddr -> KnownPeers peeraddr)
-> KnownPeers peeraddr -> KnownPeers peeraddr
forall a b. (a -> b) -> a -> b
$
KnownPeers peeraddr
knownPeers { allPeers :: Map peeraddr KnownPeerInfo
allPeers = (KnownPeerInfo -> Maybe KnownPeerInfo)
-> peeraddr
-> Map peeraddr KnownPeerInfo
-> Map peeraddr KnownPeerInfo
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update (\KnownPeerInfo
kpi -> KnownPeerInfo -> Maybe KnownPeerInfo
forall a. a -> Maybe a
Just KnownPeerInfo
kpi { knownPeerFailCount :: Int
knownPeerFailCount = Int
0 })
peeraddr
peeraddr Map peeraddr KnownPeerInfo
allPeers
}
lookupFailCount :: Ord peeraddr
=> peeraddr
-> KnownPeers peeraddr
-> Maybe Int
lookupFailCount :: peeraddr -> KnownPeers peeraddr -> Maybe Int
lookupFailCount peeraddr
peeraddr KnownPeers{Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers} =
KnownPeerInfo -> Int
knownPeerFailCount (KnownPeerInfo -> Int) -> Maybe KnownPeerInfo -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> peeraddr -> Map peeraddr KnownPeerInfo -> Maybe KnownPeerInfo
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peeraddr
peeraddr Map peeraddr KnownPeerInfo
allPeers
lookupTepidFlag :: Ord peeraddr
=> peeraddr
-> KnownPeers peeraddr
-> Maybe Bool
lookupTepidFlag :: peeraddr -> KnownPeers peeraddr -> Maybe Bool
lookupTepidFlag peeraddr
peeraddr KnownPeers{Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers} =
KnownPeerInfo -> Bool
knownPeerTepid (KnownPeerInfo -> Bool) -> Maybe KnownPeerInfo -> Maybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> peeraddr -> Map peeraddr KnownPeerInfo -> Maybe KnownPeerInfo
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peeraddr
peeraddr Map peeraddr KnownPeerInfo
allPeers
setTepidFlag' :: Ord peeraddr
=> Bool
-> peeraddr
-> KnownPeers peeraddr
-> KnownPeers peeraddr
setTepidFlag' :: Bool -> peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
setTepidFlag' Bool
val peeraddr
peeraddr knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers{Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers} =
Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (peeraddr
peeraddr peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map peeraddr KnownPeerInfo
allPeers) (KnownPeers peeraddr -> KnownPeers peeraddr)
-> KnownPeers peeraddr -> KnownPeers peeraddr
forall a b. (a -> b) -> a -> b
$
KnownPeers peeraddr
knownPeers { allPeers :: Map peeraddr KnownPeerInfo
allPeers = (KnownPeerInfo -> Maybe KnownPeerInfo)
-> peeraddr
-> Map peeraddr KnownPeerInfo
-> Map peeraddr KnownPeerInfo
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update (\KnownPeerInfo
kpi -> KnownPeerInfo -> Maybe KnownPeerInfo
forall a. a -> Maybe a
Just KnownPeerInfo
kpi { knownPeerTepid :: Bool
knownPeerTepid = Bool
val })
peeraddr
peeraddr Map peeraddr KnownPeerInfo
allPeers
}
clearTepidFlag :: Ord peeraddr
=> peeraddr
-> KnownPeers peeraddr
-> KnownPeers peeraddr
clearTepidFlag :: peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
clearTepidFlag = Bool -> peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
forall peeraddr.
Ord peeraddr =>
Bool -> peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
setTepidFlag' Bool
False
setTepidFlag :: Ord peeraddr
=> peeraddr
-> KnownPeers peeraddr
-> KnownPeers peeraddr
setTepidFlag :: peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
setTepidFlag = Bool -> peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
forall peeraddr.
Ord peeraddr =>
Bool -> peeraddr -> KnownPeers peeraddr -> KnownPeers peeraddr
setTepidFlag' Bool
True
minGossipTime :: Ord peeraddr => KnownPeers peeraddr -> Maybe Time
minGossipTime :: KnownPeers peeraddr -> Maybe Time
minGossipTime KnownPeers {
Set peeraddr
availableForGossip :: Set peeraddr
availableForGossip :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableForGossip,
OrdPSQ peeraddr Time ()
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextGossipTimes
}
| Set peeraddr -> Bool
forall a. Set a -> Bool
Set.null Set peeraddr
availableForGossip
, Just (peeraddr
_k, Time
t, ()
_, OrdPSQ peeraddr Time ()
_psq) <- OrdPSQ peeraddr Time ()
-> Maybe (peeraddr, Time, (), OrdPSQ peeraddr Time ())
forall k p v.
(Ord k, Ord p) =>
OrdPSQ k p v -> Maybe (k, p, v, OrdPSQ k p v)
PSQ.minView OrdPSQ peeraddr Time ()
nextGossipTimes
= Time -> Maybe Time
forall a. a -> Maybe a
Just Time
t
| Bool
otherwise
= Maybe Time
forall a. Maybe a
Nothing
setGossipTime :: Ord peeraddr
=> Set peeraddr
-> Time
-> KnownPeers peeraddr
-> KnownPeers peeraddr
setGossipTime :: Set peeraddr -> Time -> KnownPeers peeraddr -> KnownPeers peeraddr
setGossipTime Set peeraddr
peeraddrs Time
time
knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers {
Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers,
Set peeraddr
availableForGossip :: Set peeraddr
availableForGossip :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableForGossip,
OrdPSQ peeraddr Time ()
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextGossipTimes
} =
Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert ((peeraddr -> Bool) -> Set peeraddr -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map peeraddr KnownPeerInfo
allPeers) Set peeraddr
peeraddrs) (KnownPeers peeraddr -> KnownPeers peeraddr)
-> KnownPeers peeraddr -> KnownPeers peeraddr
forall a b. (a -> b) -> a -> b
$
let knownPeers' :: KnownPeers peeraddr
knownPeers' = KnownPeers peeraddr
knownPeers {
availableForGossip :: Set peeraddr
availableForGossip =
Set peeraddr
availableForGossip
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Ord a => Set a -> Set a -> Set a
Set.\\ Set peeraddr
peeraddrs,
nextGossipTimes :: OrdPSQ peeraddr Time ()
nextGossipTimes =
(OrdPSQ peeraddr Time () -> peeraddr -> OrdPSQ peeraddr Time ())
-> OrdPSQ peeraddr Time ()
-> Set peeraddr
-> OrdPSQ peeraddr Time ()
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (\OrdPSQ peeraddr Time ()
psq peeraddr
peeraddr -> peeraddr
-> Time -> () -> OrdPSQ peeraddr Time () -> OrdPSQ peeraddr Time ()
forall k p v.
(Ord k, Ord p) =>
k -> p -> v -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.insert peeraddr
peeraddr Time
time () OrdPSQ peeraddr Time ()
psq)
OrdPSQ peeraddr Time ()
nextGossipTimes
Set peeraddr
peeraddrs
}
in Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (KnownPeers peeraddr -> Bool
forall peeraddr. Ord peeraddr => KnownPeers peeraddr -> Bool
invariant KnownPeers peeraddr
knownPeers') KnownPeers peeraddr
knownPeers'
minConnectTime :: Ord peeraddr
=> KnownPeers peeraddr
-> Maybe Time
minConnectTime :: KnownPeers peeraddr -> Maybe Time
minConnectTime KnownPeers { OrdPSQ peeraddr Time ()
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextConnectTimes }
| Just (peeraddr
_k, Time
t, ()
_, OrdPSQ peeraddr Time ()
_psq) <- OrdPSQ peeraddr Time ()
-> Maybe (peeraddr, Time, (), OrdPSQ peeraddr Time ())
forall k p v.
(Ord k, Ord p) =>
OrdPSQ k p v -> Maybe (k, p, v, OrdPSQ k p v)
PSQ.minView OrdPSQ peeraddr Time ()
nextConnectTimes
= Time -> Maybe Time
forall a. a -> Maybe a
Just Time
t
| Bool
otherwise
= Maybe Time
forall a. Maybe a
Nothing
setConnectTime :: Ord peeraddr
=> Set peeraddr
-> Time
-> KnownPeers peeraddr
-> KnownPeers peeraddr
setConnectTime :: Set peeraddr -> Time -> KnownPeers peeraddr -> KnownPeers peeraddr
setConnectTime Set peeraddr
peeraddrs Time
time
knownPeers :: KnownPeers peeraddr
knownPeers@KnownPeers {
Map peeraddr KnownPeerInfo
allPeers :: Map peeraddr KnownPeerInfo
allPeers :: forall peeraddr. KnownPeers peeraddr -> Map peeraddr KnownPeerInfo
allPeers,
Set peeraddr
availableToConnect :: Set peeraddr
availableToConnect :: forall peeraddr. KnownPeers peeraddr -> Set peeraddr
availableToConnect,
OrdPSQ peeraddr Time ()
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes :: forall peeraddr. KnownPeers peeraddr -> OrdPSQ peeraddr Time ()
nextConnectTimes
} =
Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert ((peeraddr -> Bool) -> Set peeraddr -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (peeraddr -> Map peeraddr KnownPeerInfo -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map peeraddr KnownPeerInfo
allPeers) Set peeraddr
peeraddrs) (KnownPeers peeraddr -> KnownPeers peeraddr)
-> KnownPeers peeraddr -> KnownPeers peeraddr
forall a b. (a -> b) -> a -> b
$
let knownPeers' :: KnownPeers peeraddr
knownPeers' = KnownPeers peeraddr
knownPeers {
availableToConnect :: Set peeraddr
availableToConnect =
Set peeraddr
availableToConnect
Set peeraddr -> Set peeraddr -> Set peeraddr
forall a. Ord a => Set a -> Set a -> Set a
Set.\\ Set peeraddr
peeraddrs,
nextConnectTimes :: OrdPSQ peeraddr Time ()
nextConnectTimes =
(OrdPSQ peeraddr Time () -> peeraddr -> OrdPSQ peeraddr Time ())
-> OrdPSQ peeraddr Time ()
-> Set peeraddr
-> OrdPSQ peeraddr Time ()
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (\OrdPSQ peeraddr Time ()
psq peeraddr
peeraddr -> peeraddr
-> Time -> () -> OrdPSQ peeraddr Time () -> OrdPSQ peeraddr Time ()
forall k p v.
(Ord k, Ord p) =>
k -> p -> v -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.insert peeraddr
peeraddr Time
time () OrdPSQ peeraddr Time ()
psq)
OrdPSQ peeraddr Time ()
nextConnectTimes
Set peeraddr
peeraddrs
}
in Bool -> KnownPeers peeraddr -> KnownPeers peeraddr
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (KnownPeers peeraddr -> Bool
forall peeraddr. Ord peeraddr => KnownPeers peeraddr -> Bool
invariant KnownPeers peeraddr
knownPeers') KnownPeers peeraddr
knownPeers'