{-# LANGUAGE NamedFieldPuns     #-}

{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications   #-}

module Test.Ouroboros.Network.PeerSelection.LocalRootPeers
  ( arbitraryLocalRootPeers
  , restrictKeys
  , tests
  , LocalRootPeers (..)
  , HotValency (..)
  , WarmValency (..)
  ) where

import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Set (Set)
import Data.Set qualified as Set

import Ouroboros.Network.PeerSelection.Governor
import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency (..),
           LocalRootConfig (..), LocalRootPeers (..), WarmValency (..))
import Ouroboros.Network.PeerSelection.State.LocalRootPeers qualified as LocalRootPeers

import Test.Ouroboros.Network.PeerSelection.Instances
import Test.Ouroboros.Network.Utils (ShrinkCarefully, prop_shrink_nonequal,
           prop_shrink_valid, renderRanges)

import Test.QuickCheck
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.QuickCheck (testProperty)


tests :: TestTree
tests :: TestTree
tests =
  TestName -> [TestTree] -> TestTree
testGroup TestName
"Ouroboros.Network.PeerSelection"
  [ TestName -> [TestTree] -> TestTree
testGroup TestName
"LocalRootPeers"
    [ TestName
-> (LocalRootPeers NoExtraFlags PeerAddr -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"arbitrary"    (forall extraFlags.
Arbitrary extraFlags =>
LocalRootPeers extraFlags PeerAddr -> Property
prop_arbitrary_LocalRootPeers @NoExtraFlags)
    , TestName
-> (LocalRootPeers NoExtraFlags PeerAddr -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"fromToGroups" (forall extraFlags.
Eq extraFlags =>
LocalRootPeers extraFlags PeerAddr -> Bool
prop_fromToGroups @NoExtraFlags)
    , TestName
-> ([(HotValency, WarmValency,
      Map PeerAddr (LocalRootConfig NoExtraFlags))]
    -> Bool)
-> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"fromGroups"   (forall extraFlags.
[(HotValency, WarmValency,
  Map PeerAddr (LocalRootConfig extraFlags))]
-> Bool
prop_fromGroups @NoExtraFlags)
    , TestName
-> (ShrinkCarefully (LocalRootPeers NoExtraFlags PeerAddr)
    -> Property)
-> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"shrink"       (forall extraFlags.
(Eq extraFlags, Show extraFlags, Arbitrary extraFlags) =>
ShrinkCarefully (LocalRootPeers extraFlags PeerAddr) -> Property
prop_shrink_LocalRootPeers @NoExtraFlags)
    , TestName
-> (LocalRootPeers NoExtraFlags PeerAddr
    -> PeerSelectionTargets -> Property)
-> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"clampToLimit" (forall extraFlags.
Arbitrary extraFlags =>
LocalRootPeers extraFlags PeerAddr
-> PeerSelectionTargets -> Property
prop_clampToLimit @NoExtraFlags)
    ]
  ]

type NoExtraFlags = ()

-- | Check that we can forcibly bring the localRootPeers into compliance
-- with the governor's state invariant, which requires that the local
-- root peers fit within the current targets.
--
-- The precondition on the targets is that they are sane.
-- See sanePeerSelectionTargets.
prop_clampToLimit
  :: Arbitrary extraFlags
  => LocalRootPeers extraFlags PeerAddr
  -> PeerSelectionTargets
  -> Property
prop_clampToLimit :: forall extraFlags.
Arbitrary extraFlags =>
LocalRootPeers extraFlags PeerAddr
-> PeerSelectionTargets -> Property
prop_clampToLimit LocalRootPeers extraFlags PeerAddr
localRootPeers PeerSelectionTargets
targets =

    let sizeLimit :: Int
sizeLimit       = PeerSelectionTargets -> Int
targetNumberOfKnownPeers PeerSelectionTargets
targets
        localRootPeers' :: LocalRootPeers extraFlags PeerAddr
localRootPeers' = Int
-> LocalRootPeers extraFlags PeerAddr
-> LocalRootPeers extraFlags PeerAddr
forall peeraddr extraFlags.
Ord peeraddr =>
Int
-> LocalRootPeers extraFlags peeraddr
-> LocalRootPeers extraFlags peeraddr
LocalRootPeers.clampToLimit Int
sizeLimit LocalRootPeers extraFlags PeerAddr
localRootPeers

     in TestName -> Property -> Property
forall prop. Testable prop => TestName -> prop -> Property
counterexample (TestName
"sizeLimit   = " TestName -> TestName -> TestName
forall a. [a] -> [a] -> [a]
++ Int -> TestName
forall a. Show a => a -> TestName
show Int
sizeLimit) (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$

        LocalRootPeers extraFlags PeerAddr -> Int
forall extraFlags peeraddr.
LocalRootPeers extraFlags peeraddr -> Int
LocalRootPeers.size LocalRootPeers extraFlags PeerAddr
localRootPeers'
          Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
sizeLimit
                 (LocalRootPeers extraFlags PeerAddr -> Int
forall extraFlags peeraddr.
LocalRootPeers extraFlags peeraddr -> Int
LocalRootPeers.size LocalRootPeers extraFlags PeerAddr
localRootPeers)

arbitraryLocalRootPeers :: (Ord peeraddr, Arbitrary extraFlags)
                        => Set peeraddr -> Gen (LocalRootPeers extraFlags peeraddr)
arbitraryLocalRootPeers :: forall peeraddr extraFlags.
(Ord peeraddr, Arbitrary extraFlags) =>
Set peeraddr -> Gen (LocalRootPeers extraFlags peeraddr)
arbitraryLocalRootPeers Set peeraddr
peeraddrs = do
    -- divide into a few disjoint groups
    ngroups     <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1, Int
5 :: Int)
    gassignment <- vectorOf (Set.size peeraddrs) (choose (1, ngroups))
    advertise   <- vectorOf (Set.size peeraddrs) arbitrary
    let groups = Map Int (Map peeraddr (LocalRootConfig extraFlags))
-> [Map peeraddr (LocalRootConfig extraFlags)]
forall k a. Map k a -> [a]
Map.elems (Map Int (Map peeraddr (LocalRootConfig extraFlags))
 -> [Map peeraddr (LocalRootConfig extraFlags)])
-> Map Int (Map peeraddr (LocalRootConfig extraFlags))
-> [Map peeraddr (LocalRootConfig extraFlags)]
forall a b. (a -> b) -> a -> b
$
                 (Map peeraddr (LocalRootConfig extraFlags)
 -> Map peeraddr (LocalRootConfig extraFlags)
 -> Map peeraddr (LocalRootConfig extraFlags))
-> [(Int, Map peeraddr (LocalRootConfig extraFlags))]
-> Map Int (Map peeraddr (LocalRootConfig extraFlags))
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith Map peeraddr (LocalRootConfig extraFlags)
-> Map peeraddr (LocalRootConfig extraFlags)
-> Map peeraddr (LocalRootConfig extraFlags)
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union
                   [ (Int
gn, peeraddr
-> LocalRootConfig extraFlags
-> Map peeraddr (LocalRootConfig extraFlags)
forall k a. k -> a -> Map k a
Map.singleton peeraddr
p LocalRootConfig extraFlags
a)
                   | (peeraddr
p, Int
gn, LocalRootConfig extraFlags
a) <- [peeraddr]
-> [Int]
-> [LocalRootConfig extraFlags]
-> [(peeraddr, Int, LocalRootConfig extraFlags)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (Set peeraddr -> [peeraddr]
forall a. Set a -> [a]
Set.toList Set peeraddr
peeraddrs)
                                         [Int]
gassignment
                                         [LocalRootConfig extraFlags]
advertise
                   ]
    targets <- mapM (\Map peeraddr (LocalRootConfig extraFlags)
g -> do
                      warmValency <- Int -> WarmValency
WarmValency (Int -> WarmValency) -> Gen Int -> Gen WarmValency
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0, Map peeraddr (LocalRootConfig extraFlags) -> Int
forall k a. Map k a -> Int
Map.size Map peeraddr (LocalRootConfig extraFlags)
g)
                      hotValency <- HotValency <$> choose (0, getWarmValency warmValency)
                      return (hotValency, warmValency)
                    ) groups

    return (LocalRootPeers.fromGroups (zipWith (\(HotValency
h, WarmValency
w) Map peeraddr (LocalRootConfig extraFlags)
g -> (HotValency
h, WarmValency
w, Map peeraddr (LocalRootConfig extraFlags)
g))
                                               targets
                                               groups))

instance Arbitrary HotValency where
  arbitrary :: Gen HotValency
arbitrary = Int -> HotValency
HotValency (Int -> HotValency) -> Gen Int -> Gen HotValency
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int
forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary WarmValency where
  arbitrary :: Gen WarmValency
arbitrary = Int -> WarmValency
WarmValency (Int -> WarmValency) -> Gen Int -> Gen WarmValency
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int
forall a. Arbitrary a => Gen a
arbitrary

instance (Arbitrary extraFlags, Arbitrary peeraddr, Ord peeraddr) =>
         Arbitrary (LocalRootPeers extraFlags peeraddr) where
    arbitrary :: Gen (LocalRootPeers extraFlags peeraddr)
arbitrary = do
        peeraddrs <- (Int -> Int) -> Gen (Set peeraddr) -> Gen (Set peeraddr)
forall a. (Int -> Int) -> Gen a -> Gen a
scale (Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
4) Gen (Set peeraddr)
forall a. Arbitrary a => Gen a
arbitrary
        arbitraryLocalRootPeers peeraddrs

    shrink :: LocalRootPeers extraFlags peeraddr
-> [LocalRootPeers extraFlags peeraddr]
shrink LocalRootPeers extraFlags peeraddr
lrps =
        ([(HotValency, WarmValency,
   Map peeraddr (LocalRootConfig extraFlags))]
 -> LocalRootPeers extraFlags peeraddr)
-> [[(HotValency, WarmValency,
      Map peeraddr (LocalRootConfig extraFlags))]]
-> [LocalRootPeers extraFlags peeraddr]
forall a b. (a -> b) -> [a] -> [b]
map [(HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags peeraddr
forall peeraddr extraFlags.
Ord peeraddr =>
[(HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags peeraddr
LocalRootPeers.fromGroups ([(HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))]
-> [[(HotValency, WarmValency,
      Map peeraddr (LocalRootConfig extraFlags))]]
forall a. Arbitrary a => a -> [a]
shrink (LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
LocalRootPeers.toGroups LocalRootPeers extraFlags peeraddr
lrps))

restrictKeys :: Ord peeraddr
             => LocalRootPeers extraFlags peeraddr
             -> Set peeraddr
             -> LocalRootPeers extraFlags peeraddr
restrictKeys :: forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr
-> Set peeraddr -> LocalRootPeers extraFlags peeraddr
restrictKeys LocalRootPeers extraFlags peeraddr
lrps Set peeraddr
ks =
    [(HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags peeraddr
forall peeraddr extraFlags.
Ord peeraddr =>
[(HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags peeraddr
LocalRootPeers.fromGroups
  ([(HotValency, WarmValency,
   Map peeraddr (LocalRootConfig extraFlags))]
 -> LocalRootPeers extraFlags peeraddr)
-> (LocalRootPeers extraFlags peeraddr
    -> [(HotValency, WarmValency,
         Map peeraddr (LocalRootConfig extraFlags))])
-> LocalRootPeers extraFlags peeraddr
-> LocalRootPeers extraFlags peeraddr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))
 -> (HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags)))
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
forall a b. (a -> b) -> [a] -> [b]
map (\(HotValency
h, WarmValency
w, Map peeraddr (LocalRootConfig extraFlags)
g) -> (HotValency
h, WarmValency
w, Map peeraddr (LocalRootConfig extraFlags)
-> Set peeraddr -> Map peeraddr (LocalRootConfig extraFlags)
forall k a. Ord k => Map k a -> Set k -> Map k a
Map.restrictKeys Map peeraddr (LocalRootConfig extraFlags)
g Set peeraddr
ks))
  ([(HotValency, WarmValency,
   Map peeraddr (LocalRootConfig extraFlags))]
 -> [(HotValency, WarmValency,
      Map peeraddr (LocalRootConfig extraFlags))])
-> (LocalRootPeers extraFlags peeraddr
    -> [(HotValency, WarmValency,
         Map peeraddr (LocalRootConfig extraFlags))])
-> LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
LocalRootPeers.toGroups
  (LocalRootPeers extraFlags peeraddr
 -> LocalRootPeers extraFlags peeraddr)
-> LocalRootPeers extraFlags peeraddr
-> LocalRootPeers extraFlags peeraddr
forall a b. (a -> b) -> a -> b
$ LocalRootPeers extraFlags peeraddr
lrps

prop_arbitrary_LocalRootPeers :: Arbitrary extraFlags => LocalRootPeers extraFlags PeerAddr -> Property
prop_arbitrary_LocalRootPeers :: forall extraFlags.
Arbitrary extraFlags =>
LocalRootPeers extraFlags PeerAddr -> Property
prop_arbitrary_LocalRootPeers LocalRootPeers extraFlags PeerAddr
lrps =
    TestName -> [TestName] -> Property -> Property
forall prop.
Testable prop =>
TestName -> [TestName] -> prop -> Property
tabulate TestName
"total size"    [TestName
size] (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
    TestName -> [TestName] -> Property -> Property
forall prop.
Testable prop =>
TestName -> [TestName] -> prop -> Property
tabulate TestName
"num groups"    [TestName
numGroups] (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
    TestName -> [TestName] -> Property -> Property
forall prop.
Testable prop =>
TestName -> [TestName] -> prop -> Property
tabulate TestName
"group size"    [TestName]
sizeGroups (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
    TestName -> [TestName] -> Bool -> Property
forall prop.
Testable prop =>
TestName -> [TestName] -> prop -> Property
tabulate TestName
"targets"       [TestName]
targets (Bool -> Property) -> Bool -> Property
forall a b. (a -> b) -> a -> b
$

    LocalRootPeers extraFlags PeerAddr -> Bool
forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr -> Bool
LocalRootPeers.invariant LocalRootPeers extraFlags PeerAddr
lrps
  where
    thrd :: (a, b, c) -> c
thrd (a
_, b
_, c
c) = c
c
    size :: TestName
size       = Int -> Int -> TestName
renderRanges Int
5 (LocalRootPeers extraFlags PeerAddr -> Int
forall extraFlags peeraddr.
LocalRootPeers extraFlags peeraddr -> Int
LocalRootPeers.size LocalRootPeers extraFlags PeerAddr
lrps)
    numGroups :: TestName
numGroups  = Int -> TestName
forall a. Show a => a -> TestName
show ([(HotValency, WarmValency,
  Map PeerAddr (LocalRootConfig extraFlags))]
-> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (LocalRootPeers extraFlags PeerAddr
-> [(HotValency, WarmValency,
     Map PeerAddr (LocalRootConfig extraFlags))]
forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
LocalRootPeers.toGroups LocalRootPeers extraFlags PeerAddr
lrps))
    sizeGroups :: [TestName]
sizeGroups = ((HotValency, WarmValency, Set PeerAddr) -> TestName)
-> [(HotValency, WarmValency, Set PeerAddr)] -> [TestName]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> TestName
forall a. Show a => a -> TestName
show (Int -> TestName)
-> ((HotValency, WarmValency, Set PeerAddr) -> Int)
-> (HotValency, WarmValency, Set PeerAddr)
-> TestName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set PeerAddr -> Int
forall a. Set a -> Int
Set.size (Set PeerAddr -> Int)
-> ((HotValency, WarmValency, Set PeerAddr) -> Set PeerAddr)
-> (HotValency, WarmValency, Set PeerAddr)
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HotValency, WarmValency, Set PeerAddr) -> Set PeerAddr
forall {a} {b} {c}. (a, b, c) -> c
thrd) (LocalRootPeers extraFlags PeerAddr
-> [(HotValency, WarmValency, Set PeerAddr)]
forall extraFlags peeraddr.
LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency, Set peeraddr)]
LocalRootPeers.toGroupSets LocalRootPeers extraFlags PeerAddr
lrps)
    targets :: [TestName]
targets    = [ case () of
                    NoExtraFlags
_ | HotValency
h HotValency -> HotValency -> Bool
forall a. Eq a => a -> a -> Bool
== HotValency
0                        -> TestName
"none active"
                      | WarmValency
w WarmValency -> WarmValency -> Bool
forall a. Eq a => a -> a -> Bool
== WarmValency
0                        -> TestName
"none established"
                      | HotValency
h HotValency -> HotValency -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> HotValency
HotValency (Set PeerAddr -> Int
forall a. Set a -> Int
Set.size Set PeerAddr
g)  -> TestName
"all active"
                      | WarmValency
w WarmValency -> WarmValency -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> WarmValency
WarmValency (Set PeerAddr -> Int
forall a. Set a -> Int
Set.size Set PeerAddr
g) -> TestName
"all established"
                      | Bool
otherwise                     -> TestName
"some"
                 | (HotValency
h, WarmValency
w, Set PeerAddr
g) <- LocalRootPeers extraFlags PeerAddr
-> [(HotValency, WarmValency, Set PeerAddr)]
forall extraFlags peeraddr.
LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency, Set peeraddr)]
LocalRootPeers.toGroupSets LocalRootPeers extraFlags PeerAddr
lrps ]


prop_shrink_LocalRootPeers
  :: ( Eq extraFlags
     , Show extraFlags
     , Arbitrary extraFlags
     )
  => ShrinkCarefully (LocalRootPeers extraFlags PeerAddr)
  -> Property
prop_shrink_LocalRootPeers :: forall extraFlags.
(Eq extraFlags, Show extraFlags, Arbitrary extraFlags) =>
ShrinkCarefully (LocalRootPeers extraFlags PeerAddr) -> Property
prop_shrink_LocalRootPeers ShrinkCarefully (LocalRootPeers extraFlags PeerAddr)
x =
      (LocalRootPeers extraFlags PeerAddr -> Bool)
-> ShrinkCarefully (LocalRootPeers extraFlags PeerAddr) -> Property
forall a prop.
(Arbitrary a, Show a, Testable prop) =>
(a -> prop) -> ShrinkCarefully a -> Property
prop_shrink_valid LocalRootPeers extraFlags PeerAddr -> Bool
forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr -> Bool
LocalRootPeers.invariant ShrinkCarefully (LocalRootPeers extraFlags PeerAddr)
x
 Property -> Property -> Property
forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. ShrinkCarefully (LocalRootPeers extraFlags PeerAddr) -> Property
forall a.
(Arbitrary a, Eq a, Show a) =>
ShrinkCarefully a -> Property
prop_shrink_nonequal ShrinkCarefully (LocalRootPeers extraFlags PeerAddr)
x

prop_fromGroups :: [(HotValency, WarmValency, Map PeerAddr (LocalRootConfig extraFlags))]
                -> Bool
prop_fromGroups :: forall extraFlags.
[(HotValency, WarmValency,
  Map PeerAddr (LocalRootConfig extraFlags))]
-> Bool
prop_fromGroups = LocalRootPeers extraFlags PeerAddr -> Bool
forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr -> Bool
LocalRootPeers.invariant (LocalRootPeers extraFlags PeerAddr -> Bool)
-> ([(HotValency, WarmValency,
      Map PeerAddr (LocalRootConfig extraFlags))]
    -> LocalRootPeers extraFlags PeerAddr)
-> [(HotValency, WarmValency,
     Map PeerAddr (LocalRootConfig extraFlags))]
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(HotValency, WarmValency,
  Map PeerAddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags PeerAddr
forall peeraddr extraFlags.
Ord peeraddr =>
[(HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags peeraddr
LocalRootPeers.fromGroups

prop_fromToGroups
  :: Eq extraFlags
  => LocalRootPeers extraFlags PeerAddr
  -> Bool
prop_fromToGroups :: forall extraFlags.
Eq extraFlags =>
LocalRootPeers extraFlags PeerAddr -> Bool
prop_fromToGroups LocalRootPeers extraFlags PeerAddr
lrps =
    [(HotValency, WarmValency,
  Map PeerAddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags PeerAddr
forall peeraddr extraFlags.
Ord peeraddr =>
[(HotValency, WarmValency,
  Map peeraddr (LocalRootConfig extraFlags))]
-> LocalRootPeers extraFlags peeraddr
LocalRootPeers.fromGroups (LocalRootPeers extraFlags PeerAddr
-> [(HotValency, WarmValency,
     Map PeerAddr (LocalRootConfig extraFlags))]
forall peeraddr extraFlags.
Ord peeraddr =>
LocalRootPeers extraFlags peeraddr
-> [(HotValency, WarmValency,
     Map peeraddr (LocalRootConfig extraFlags))]
LocalRootPeers.toGroups LocalRootPeers extraFlags PeerAddr
lrps) LocalRootPeers extraFlags PeerAddr
-> LocalRootPeers extraFlags PeerAddr -> Bool
forall a. Eq a => a -> a -> Bool
== LocalRootPeers extraFlags PeerAddr
lrps