From f73c6fd2e2c453491b6783fb4d143bf4f71d3fae Mon Sep 17 00:00:00 2001 From: Armando Santos Date: Tue, 13 Sep 2022 18:08:35 +0100 Subject: [PATCH] Refactored DiffusionScript --- .../test/Test/Ouroboros/Network/Testnet.hs | 14 +- .../Network/Testnet/Simulation/Node.hs | 424 +++++++++--------- 2 files changed, 211 insertions(+), 227 deletions(-) diff --git a/ouroboros-network/test/Test/Ouroboros/Network/Testnet.hs b/ouroboros-network/test/Test/Ouroboros/Network/Testnet.hs index e891d47fe25..153015bb255 100644 --- a/ouroboros-network/test/Test/Ouroboros/Network/Testnet.hs +++ b/ouroboros-network/test/Test/Ouroboros/Network/Testnet.hs @@ -590,7 +590,7 @@ prop_peer_selection_trace_coverage defaultBearerInfo diffScript = prop_diffusion_nolivelock :: AbsBearerInfo -> DiffusionScript -> Property -prop_diffusion_nolivelock defaultBearerInfo diffScript@(DiffusionScript l) = +prop_diffusion_nolivelock defaultBearerInfo diffScript@(DiffusionScript _ l) = let sim :: forall s . IOSim s Void sim = diffusionSimulation (toBearerInfo defaultBearerInfo) diffScript @@ -1122,8 +1122,8 @@ prop_diffusion_target_active_root defaultBearerInfo diffScript = prop_hot_diffusion_target_active_public :: NonFailingAbsBearerInfo -> HotDiffusionScript -> Property -prop_hot_diffusion_target_active_public defaultBearerInfo (HotDiffusionScript hds) = - prop_diffusion_target_active_public (unNFBI defaultBearerInfo) (DiffusionScript hds) +prop_hot_diffusion_target_active_public defaultBearerInfo (HotDiffusionScript sa hds) = + prop_diffusion_target_active_public (unNFBI defaultBearerInfo) (DiffusionScript sa hds) -- | This test checks the percentage of local root peers that, at some point, -- become active, when using the 'HotDiffusionScript' generator. @@ -1131,8 +1131,8 @@ prop_hot_diffusion_target_active_public defaultBearerInfo (HotDiffusionScript hd prop_hot_diffusion_target_active_local :: NonFailingAbsBearerInfo -> HotDiffusionScript -> Property -prop_hot_diffusion_target_active_local defaultBearerInfo (HotDiffusionScript hds) = - prop_diffusion_target_active_local (unNFBI defaultBearerInfo) (DiffusionScript hds) +prop_hot_diffusion_target_active_local defaultBearerInfo (HotDiffusionScript sa hds) = + prop_diffusion_target_active_local (unNFBI defaultBearerInfo) (DiffusionScript sa hds) -- | This test checks the percentage of root peers that, at some point, -- become active, when using the 'HotDiffusionScript' generator. @@ -1140,8 +1140,8 @@ prop_hot_diffusion_target_active_local defaultBearerInfo (HotDiffusionScript hds prop_hot_diffusion_target_active_root :: NonFailingAbsBearerInfo -> HotDiffusionScript -> Property -prop_hot_diffusion_target_active_root defaultBearerInfo (HotDiffusionScript hds) = - prop_diffusion_target_active_root (unNFBI defaultBearerInfo) (DiffusionScript hds) +prop_hot_diffusion_target_active_root defaultBearerInfo (HotDiffusionScript sa hds) = + prop_diffusion_target_active_root (unNFBI defaultBearerInfo) (DiffusionScript sa hds) -- | A variant of -- 'Test.Ouroboros.Network.PeerSelection.prop_governor_target_established_local' diff --git a/ouroboros-network/test/Test/Ouroboros/Network/Testnet/Simulation/Node.hs b/ouroboros-network/test/Test/Ouroboros/Network/Testnet/Simulation/Node.hs index cb3990585de..64c76ee189c 100644 --- a/ouroboros-network/test/Test/Ouroboros/Network/Testnet/Simulation/Node.hs +++ b/ouroboros-network/test/Test/Ouroboros/Network/Testnet/Simulation/Node.hs @@ -40,7 +40,7 @@ import Control.Tracer (Tracer, nullTracer, traceWith) import qualified Data.ByteString.Lazy as BL import Data.Foldable (traverse_) import Data.IP (IP (..), toIPv4, toIPv6) -import Data.List (delete, intersperse, nub, (\\)) +import Data.List (delete, nub, (\\), intercalate) import Data.Map (Map) import qualified Data.Map as Map import Data.Set (Set) @@ -98,7 +98,6 @@ import Test.QuickCheck (Arbitrary (..), Gen, Property, choose, chooseInt, counterexample, frequency, oneof, property, shrinkList, sized, sublistOf, suchThat, vectorOf, (.&&.)) - -- | Diffusion Simulator Arguments -- -- Contains all necessary randomly generated values needed to run diffusion in @@ -108,52 +107,71 @@ data SimArgs = SimArgs { saSlot :: DiffTime -- ^ 'randomBlockGenerationArgs' slot duration argument - , saSeed :: Int - -- ^ 'randomBlockGenerationArgs' seed argument , saQuota :: Int -- ^ 'randomBlockGenerationArgs' quota value - , saMbTime :: Maybe DiffTime + } + +instance Show SimArgs where + show SimArgs { saSlot, saQuota } = + unwords [ "SimArgs" + , show saSlot + , show saQuota + ] + +-- | Diffusion Simulator Node Arguments +-- +-- Contains all necessary randomly generated values needed to run a node in +-- simulation. +-- +data NodeArgs = + NodeArgs + { naSeed :: Int + -- ^ 'randomBlockGenerationArgs' seed argument + , naMbTime :: Maybe DiffTime -- ^ 'LimitsAndTimeouts' argument - , saRelays :: [RelayAccessPoint] + , naRelays :: [RelayAccessPoint] -- ^ 'Interfaces' relays auxiliary value - , saDomainMap :: Map Domain [IP] + , naDomainMap :: Map Domain [IP] -- ^ 'Interfaces' 'iDomainMap' value - , saAddr :: NtNAddr + , naAddr :: NtNAddr -- ^ 'Arguments' 'aIPAddress' value - , saLocalRootPeers :: [(Int, Map RelayAccessPoint PeerAdvertise)] + , naLocalRootPeers :: [(Int, Map RelayAccessPoint PeerAdvertise)] -- ^ 'Arguments' 'LocalRootPeers' values - , saLocalSelectionTargets :: PeerSelectionTargets + , naLocalSelectionTargets :: PeerSelectionTargets -- ^ 'Arguments' 'aLocalSelectionTargets' value - , saDNSTimeoutScript :: Script DNSTimeout + , naDNSTimeoutScript :: Script DNSTimeout -- ^ 'Arguments' 'aDNSTimeoutScript' value - , saDNSLookupDelayScript :: Script DNSLookupDelay + , naDNSLookupDelayScript :: Script DNSLookupDelay -- ^ 'Arguments' 'aDNSLookupDelayScript' value } -instance Show SimArgs where - show SimArgs { saSlot, saSeed, saQuota, saMbTime, saRelays, saDomainMap, - saAddr, saLocalRootPeers, saLocalSelectionTargets, - saDNSTimeoutScript, saDNSLookupDelayScript } = - concat $ intersperse " " [ "SimArgs" - , show saSlot - , "(" ++ show saSeed ++ ")" - , show saQuota - , "(" ++ show saMbTime ++ ")" - , show saRelays - , "(Map.fromList [" ++ Map.foldMapWithKey (\domain ips -> "(" ++ show domain ++ ", " ++ showIPs ips ++ ")") saDomainMap ++ "])" - , "(" ++ show saAddr ++ ")" - , show saLocalRootPeers - , show saLocalSelectionTargets - , "(" ++ show saDNSTimeoutScript ++ ")" - , "(" ++ show saDNSLookupDelayScript ++ ")" - ] +instance Show NodeArgs where + show NodeArgs { naSeed, naMbTime, naRelays, naDomainMap, + naAddr, naLocalRootPeers, naLocalSelectionTargets, + naDNSTimeoutScript, naDNSLookupDelayScript } = + unwords [ "NodeArgs" + , "(" ++ show naSeed ++ ")" + , "(" ++ show naMbTime ++ ")" + , show naRelays + , "(Map.fromList [" + ++ Map.foldMapWithKey + (\domain ips + -> "(" ++ show domain ++ ", " ++ showIPs ips ++ ")") + naDomainMap + ++ "])" + , "(" ++ show naAddr ++ ")" + , show naLocalRootPeers + , show naLocalSelectionTargets + , "(" ++ show naDNSTimeoutScript ++ ")" + , "(" ++ show naDNSLookupDelayScript ++ ")" + ] where showIPs :: [IP] -> String showIPs ips = "[" - ++ concat (intersperse ", " (map (\ip -> "read \"" ++ show ip ++ "\"") ips)) + ++ intercalate ", " + (map (\ip -> "read \"" ++ show ip ++ "\"") ips) ++ "]" - data Command = JoinNetwork DiffTime (Maybe NtNAddr) | Kill DiffTime | Reconfigure DiffTime @@ -239,13 +257,93 @@ fixupCommands (jn@(JoinNetwork _ _):t) = jn : go jn t _ -> cmd : go cmd cmds fixupCommands (_:t) = fixupCommands t +-- | Given a NtNAddr generate the necessary things to run in Simulation +-- +genSimArgs :: [RelayAccessPoint] + -> Gen SimArgs +genSimArgs raps = do + -- Slot length needs to be greater than 0 else we get a livelock on + -- the IOSim. + -- + -- Quota values matches mainnet, so a slot length of 1s and 1 / 20 + -- chance that someone gets to make a block + let bgaSlotDuration = secondsToDiffTime 1 + numberOfNodes = length [ r | r@(RelayAccessAddress _ _) <- raps ] + quota = 20 `div` numberOfNodes + + return + $ SimArgs + { saSlot = bgaSlotDuration + , saQuota = quota + } + +-- | Given a NtNAddr generate the necessary things to run a node in +-- Simulation +genNodeArgs :: [RelayAccessPoint] + -> Int + -> ( [RelayAccessPoint] + -> RelayAccessPoint + -> Gen [(Int, Map RelayAccessPoint PeerAdvertise)] ) + -> (NtNAddr, RelayAccessPoint) + -> Gen NodeArgs +genNodeArgs raps minConnected genLocalRootPeers (ntnAddr, rap) = do + -- Slot length needs to be greater than 0 else we get a livelock on + -- the IOSim. + -- + -- Quota values matches mainnet, so a slot length of 1s and 1 / 20 + -- chance that someone gets to make a block + let rapsWithoutSelf = delete rap raps + (RelayAccessAddress rapIP _) = rap + seed <- arbitrary + + dMap <- genDomainMap rapsWithoutSelf rapIP + + -- These values approximately correspond to false positive + -- thresholds for streaks of empty slots with 99% probability, + -- 99.9% probability up to 99.999% probability. + -- t = T_s [log (1-Y) / log (1-f)] + -- Y = [0.99, 0.999...] + -- + -- T_s = slot length of 1s. + -- f = 0.05 + -- The timeout is randomly picked per bearer to avoid all bearers + -- going down at the same time in case of a long streak of empty + -- slots. TODO: workaround until peer selection governor. + -- Taken from ouroboros-consensus/src/Ouroboros/Consensus/Node.hs + mustReplyTimeout <- Just <$> oneof (pure <$> [90, 135, 180, 224, 269]) + + lrp <- genLocalRootPeers rapsWithoutSelf rap + relays <- sublistOf rapsWithoutSelf + + -- Make sure our targets for active peers cover the maximum of peers + -- one generated + peerSelectionTargets <- arbitrary `suchThat` hasActive minConnected + + dnsTimeout <- arbitrary + dnsLookupDelay <- arbitrary + + return + $ NodeArgs + { naSeed = seed + , naMbTime = mustReplyTimeout + , naRelays = relays + , naDomainMap = dMap + , naAddr = ntnAddr + , naLocalRootPeers = lrp + , naLocalSelectionTargets = peerSelectionTargets + , naDNSTimeoutScript = dnsTimeout + , naDNSLookupDelayScript = dnsLookupDelay + } + where + hasActive :: Int -> PeerSelectionTargets -> Bool + hasActive minConn (PeerSelectionTargets _ _ _ y) = y > minConn + -- | Multinode Diffusion Simulator Script -- -- List of 'SimArgs'. Each element of the list represents one running node. -- -newtype DiffusionScript = DiffusionScript { - dsToRun :: [(SimArgs, [Command])] - } deriving Show +data DiffusionScript = DiffusionScript SimArgs [(NodeArgs, [Command])] + deriving Show -- | Multinode Diffusion Simulator Script -- @@ -253,7 +351,7 @@ newtype DiffusionScript = DiffusionScript { -- or can not be connected to one another. These nodes can also randomly die or -- have their local configuration changed. -- -genNonHotDiffusionScript :: Gen [(SimArgs, [Command])] +genNonHotDiffusionScript :: Gen (SimArgs, [(NodeArgs, [Command])]) genNonHotDiffusionScript = do -- Limit the number of nodes to run in Simulation otherwise it is going -- to take very long time for tests to run @@ -261,13 +359,14 @@ genNonHotDiffusionScript = do raps <- nub <$> vectorOf size arbitrary let toRunRaps = [ r | r@(RelayAccessAddress _ _) <- raps ] - toRun <- mapM (genSimArgs raps) + simArgs <- genSimArgs raps + toRun <- mapM (genNodeArgs raps 0 genLocalRootPeers) [ (ntnToPeerAddr ip p, r) | r@(RelayAccessAddress ip p) <- toRunRaps ] comands <- mapM (genLocalRootPeers raps >=> genCommands) toRunRaps - return (zip toRun comands) + return (simArgs, zip toRun comands) where -- | Generate Local Root Peers -- @@ -296,60 +395,6 @@ genNonHotDiffusionScript = do return lrpGroups - -- | Given a NtNAddr generate the necessary things to run in Simulation - genSimArgs :: [RelayAccessPoint] - -> (NtNAddr, RelayAccessPoint) - -> Gen SimArgs - genSimArgs raps (ntnAddr, rap) = do - -- Slot length needs to be greater than 0 else we get a livelock on - -- the IOSim. - -- - -- Quota values matches mainnet, so a slot length of 1s and 1 / 20 - -- chance that someone gets to make a block - let rapsWithoutSelf = delete rap raps - bgaSlotDuration = secondsToDiffTime 1 - numberOfNodes = length [ r | r@(RelayAccessAddress _ _) <- raps ] - quota = 20 `div` numberOfNodes - (RelayAccessAddress rapIP _) = rap - seed <- arbitrary - - dMap <- genDomainMap rapsWithoutSelf rapIP - - -- These values approximately correspond to false positive - -- thresholds for streaks of empty slots with 99% probability, - -- 99.9% probability up to 99.999% probability. - -- t = T_s [log (1-Y) / log (1-f)] - -- Y = [0.99, 0.999...] - -- - -- T_s = slot length of 1s. - -- f = 0.05 - -- The timeout is randomly picked per bearer to avoid all bearers - -- going down at the same time in case of a long streak of empty - -- slots. TODO: workaround until peer selection governor. - -- Taken from ouroboros-consensus/src/Ouroboros/Consensus/Node.hs - mustReplyTimeout <- Just <$> oneof (pure <$> [90, 135, 180, 224, 269]) - - lrp <- genLocalRootPeers rapsWithoutSelf rap - relays <- sublistOf rapsWithoutSelf - - peerSelectionTargets <- arbitrary - dnsTimeout <- arbitrary - dnsLookupDelay <- arbitrary - - return SimArgs - { saSlot = bgaSlotDuration - , saSeed = seed - , saQuota = quota - , saMbTime = mustReplyTimeout - , saRelays = relays - , saDomainMap = dMap - , saAddr = ntnAddr - , saLocalRootPeers = lrp - , saLocalSelectionTargets = peerSelectionTargets - , saDNSTimeoutScript = dnsTimeout - , saDNSLookupDelayScript = dnsLookupDelay - } - -- | Multinode Hot Diffusion Simulator Script -- -- Tries to generate a network with at most 2 nodes that should @@ -358,10 +403,7 @@ genNonHotDiffusionScript = do -- active connections. These nodes can not randomly die or have their local -- configuration changed. Their local root peers consist of a single group. -- --- TODO: Refactor and abstract common parts with the --- 'genNonHotDiffusionScript' generator --- -genHotDiffusionScript :: Gen [(SimArgs, [Command])] +genHotDiffusionScript :: Gen (SimArgs, [(NodeArgs, [Command])]) genHotDiffusionScript = do -- Since we want to maximize active peers in tests we want to have @@ -381,20 +423,18 @@ genHotDiffusionScript = do -- Nodes are not killed comands = repeat [JoinNetwork 0 Nothing] - toRun <- mapM (genSimArgs allRaps minConnected) + simArgs <- genSimArgs allRaps + toRun <- mapM (genNodeArgs allRaps minConnected genLocalRootPeers) [ (ntnToPeerAddr ip p, r) | r@(RelayAccessAddress ip p) <- toRunRaps ] - return (zip toRun comands) + return (simArgs, zip toRun comands) where isRelayAccessAddress :: RelayAccessPoint -> Bool isRelayAccessAddress RelayAccessAddress{} = True isRelayAccessAddress _ = False - hasActive :: Int -> PeerSelectionTargets -> Bool - hasActive minConnected (PeerSelectionTargets _ _ _ y) = y > minConnected - -- | Generate Local Root Peers -- This only generates 1 group genLocalRootPeers :: [RelayAccessPoint] @@ -413,75 +453,16 @@ genHotDiffusionScript = do return [(target, relayGroupsMap)] - -- | Given a NtNAddr generate the necessary things to run in Simulation - genSimArgs :: [RelayAccessPoint] - -> Int - -> (NtNAddr, RelayAccessPoint) - -> Gen SimArgs - genSimArgs raps minConnected (ntnAddr, rap) = do - -- Slot length needs to be greater than 0 else we get a livelock on - -- the IOSim. - -- - -- Quota values matches mainnet, so a slot length of 1s and 1 / 20 - -- chance that someone gets to make a block - let rapsWithoutSelf = delete rap raps - bgaSlotDuration = secondsToDiffTime 1 - numberOfNodes = length [ r | r@(RelayAccessAddress _ _) <- raps ] - quota = 20 `div` numberOfNodes - (RelayAccessAddress rapIP _) = rap - seed <- arbitrary - - dMap <- genDomainMap rapsWithoutSelf rapIP - - -- These values approximately correspond to false positive - -- thresholds for streaks of empty slots with 99% probability, - -- 99.9% probability up to 99.999% probability. - -- t = T_s [log (1-Y) / log (1-f)] - -- Y = [0.99, 0.999...] - -- - -- T_s = slot length of 1s. - -- f = 0.05 - -- The timeout is randomly picked per bearer to avoid all bearers - -- going down at the same time in case of a long streak of empty - -- slots. TODO: workaround until peer selection governor. - -- Taken from ouroboros-consensus/src/Ouroboros/Consensus/Node.hs - mustReplyTimeout <- Just <$> oneof (pure <$> [90, 135, 180, 224, 269]) - - lrp <- genLocalRootPeers rapsWithoutSelf rap - relays <- sublistOf rapsWithoutSelf - - -- Make sure our targets for active peers cover the maximum of peers - -- one generated - peerSelectionTargets <- arbitrary `suchThat` hasActive minConnected - - dnsTimeout <- arbitrary - dnsLookupDelay <- arbitrary - - return - $ SimArgs - { saSlot = bgaSlotDuration - , saSeed = seed - , saQuota = quota - , saMbTime = mustReplyTimeout - , saRelays = relays - , saDomainMap = dMap - , saAddr = ntnAddr - , saLocalRootPeers = lrp - , saLocalSelectionTargets = peerSelectionTargets - , saDNSTimeoutScript = dnsTimeout - , saDNSLookupDelayScript = dnsLookupDelay - } - instance Arbitrary DiffusionScript where - arbitrary = DiffusionScript + arbitrary = uncurry DiffusionScript <$> frequency [ (1, genNonHotDiffusionScript) , (1, genHotDiffusionScript) ] - shrink (DiffusionScript []) = [] - shrink (DiffusionScript ((sargs, cmds):s)) = do + shrink (DiffusionScript _ []) = [] + shrink (DiffusionScript sargs ((nargs, cmds):s)) = do shrinkedCmds <- fixupCommands <$> shrinkList shrinkCommand cmds - DiffusionScript ss <- shrink (DiffusionScript s) - return (DiffusionScript ((sargs, shrinkedCmds) : ss)) + DiffusionScript sa ss <- shrink (DiffusionScript sargs s) + return (DiffusionScript sa ((nargs, shrinkedCmds) : ss)) where shrinkDelay = map fromRational . shrink . toRational @@ -496,38 +477,37 @@ instance Arbitrary DiffusionScript where -- -- List of 'SimArgs'. Each element of the list represents one running node. -- -newtype HotDiffusionScript = HotDiffusionScript { - hdsToRun :: [(SimArgs, [Command])] - } deriving Show +data HotDiffusionScript = HotDiffusionScript SimArgs [(NodeArgs, [Command])] + deriving Show instance Arbitrary HotDiffusionScript where - arbitrary = HotDiffusionScript <$> genHotDiffusionScript - shrink (HotDiffusionScript hds) = - [ HotDiffusionScript ds - | DiffusionScript ds <- shrink (DiffusionScript hds) ] + arbitrary = uncurry HotDiffusionScript <$> genHotDiffusionScript + shrink (HotDiffusionScript sargs hds) = + [ HotDiffusionScript sa ds + | DiffusionScript sa ds <- shrink (DiffusionScript sargs hds) ] -- Tests if the fixupCommand is idempotent. -- Note that the generator for DiffusionScript already fixups the Command list. -- prop_diffusionScript_fixupCommands :: DiffusionScript -> Property -prop_diffusionScript_fixupCommands (DiffusionScript []) = property True -prop_diffusionScript_fixupCommands (DiffusionScript ((_, cmds): t)) = +prop_diffusionScript_fixupCommands (DiffusionScript _ []) = property True +prop_diffusionScript_fixupCommands (DiffusionScript sa ((_, cmds): t)) = counterexample ("Failed with cmds: " ++ show cmds ++ "\n" ++ "fixupCommands cmds = " ++ show (fixupCommands cmds) ) $ fixupCommands cmds == cmds - .&&. prop_diffusionScript_fixupCommands (DiffusionScript t) + .&&. prop_diffusionScript_fixupCommands (DiffusionScript sa t) -- Tests if the fixupCommand outputs valid command scripts. -- -- Note that the generator for DiffusionScript already fixups the Command list. -- prop_diffusionScript_commandScript_valid :: DiffusionScript -> Property -prop_diffusionScript_commandScript_valid (DiffusionScript []) = property True -prop_diffusionScript_commandScript_valid (DiffusionScript ((_, cmds): t)) = +prop_diffusionScript_commandScript_valid (DiffusionScript _ []) = property True +prop_diffusionScript_commandScript_valid (DiffusionScript sa ((_, cmds): t)) = counterexample ("Failed with cmds: " ++ show cmds) $ isValid cmds - .&&. prop_diffusionScript_commandScript_valid (DiffusionScript t) + .&&. prop_diffusionScript_commandScript_valid (DiffusionScript sa t) where isValid :: [Command] -> Property isValid [] = property True @@ -587,20 +567,20 @@ diffusionSimulation -> m Void diffusionSimulation defaultBearerInfo - (DiffusionScript args) + (DiffusionScript simArgs nodeArgs) tracersExtraWithTimeName diffSimTracerWithTimName = withSnocket nullTracer defaultBearerInfo Map.empty $ \ntnSnocket _ -> withSnocket nullTracer defaultBearerInfo Map.empty $ \ntcSnocket _ -> do - let dnsMaps = map (\(sa, _) - -> (saAddr sa, fmap (, 0) <$> saDomainMap sa)) - args + let dnsMaps = map (\(na, _) + -> (naAddr na, fmap (, 0) <$> naDomainMap na)) + nodeArgs dnsMapVarMap <- Map.fromList <$> mapM (mapM (newTVarIO @m)) dnsMaps withAsyncAll - (map (uncurry (runCommand Nothing ntnSnocket ntcSnocket dnsMapVarMap)) - args) + (map (uncurry (runCommand Nothing ntnSnocket ntcSnocket dnsMapVarMap simArgs)) + nodeArgs) $ \nodes -> do (_, x) <- waitAny nodes return x @@ -617,64 +597,65 @@ diffusionSimulation -- ^ Node to client Snocket -> Map NtNAddr (StrictTVar m (Map Domain [(IP, TTL)])) -- ^ Map of domain map TVars to be updated in case a node changes its IP - -> SimArgs -- ^ Simulation arguments needed in order to run a single node + -> SimArgs -- ^ Simulation arguments needed in order to run a simulation + -> NodeArgs -- ^ Simulation arguments needed in order to run a single node -> [Command] -- ^ List of commands/actions to perform for a single node -> m Void - runCommand Nothing ntnSnocket ntcSnocket dMapVarMap simArgs [] = do + runCommand Nothing ntnSnocket ntcSnocket dMapVarMap sArgs nArgs [] = do threadDelay 3600 - traceWith (diffSimTracerWithTimName (saAddr simArgs)) TrRunning - runCommand Nothing ntnSnocket ntcSnocket dMapVarMap simArgs [] - runCommand (Just (_, _)) ntnSnocket ntcSnocket dMapVarMap simArgs [] = do + traceWith (diffSimTracerWithTimName (naAddr nArgs)) TrRunning + runCommand Nothing ntnSnocket ntcSnocket dMapVarMap sArgs nArgs [] + runCommand (Just (_, _)) ntnSnocket ntcSnocket dMapVarMap sArgs nArgs [] = do -- We shouldn't block this thread waiting -- on the async since this will lead to a deadlock -- as thread returns 'Void'. threadDelay 3600 - traceWith (diffSimTracerWithTimName (saAddr simArgs)) TrRunning - runCommand Nothing ntnSnocket ntcSnocket dMapVarMap simArgs [] - runCommand Nothing ntnSnocket ntcSnocket dMapVarMap simArgs + traceWith (diffSimTracerWithTimName (naAddr nArgs)) TrRunning + runCommand Nothing ntnSnocket ntcSnocket dMapVarMap sArgs nArgs [] + runCommand Nothing ntnSnocket ntcSnocket dMapVarMap sArgs nArgs (JoinNetwork delay Nothing:cs) = do threadDelay delay - traceWith (diffSimTracerWithTimName (saAddr simArgs)) TrJoiningNetwork - lrpVar <- newTVarIO $ saLocalRootPeers simArgs - let dnsMapVar = dMapVarMap Map.! saAddr simArgs - withAsync (runNode simArgs ntnSnocket ntcSnocket lrpVar dnsMapVar) $ \nodeAsync -> - runCommand (Just (nodeAsync, lrpVar)) ntnSnocket ntcSnocket dMapVarMap simArgs cs - runCommand Nothing ntnSnocket ntcSnocket dMapVarMap simArgs + traceWith (diffSimTracerWithTimName (naAddr nArgs)) TrJoiningNetwork + lrpVar <- newTVarIO $ naLocalRootPeers nArgs + let dnsMapVar = dMapVarMap Map.! naAddr nArgs + withAsync (runNode sArgs nArgs ntnSnocket ntcSnocket lrpVar dnsMapVar) $ \nodeAsync -> + runCommand (Just (nodeAsync, lrpVar)) ntnSnocket ntcSnocket dMapVarMap sArgs nArgs cs + runCommand Nothing ntnSnocket ntcSnocket dMapVarMap sArgs nArgs (JoinNetwork delay (Just ip):cs) = do threadDelay delay - let simArgs' = simArgs { saAddr = ip } + let nArgs' = nArgs { naAddr = ip } traceWith (diffSimTracerWithTimName ip) TrJoiningNetwork - lrpVar <- newTVarIO $ saLocalRootPeers simArgs' + lrpVar <- newTVarIO $ naLocalRootPeers nArgs' -- Updating DomainMap entry now that the node is having a new IP - let dnsMapVar = dMapVarMap Map.! saAddr simArgs - let dMapVarMap' = Map.delete (saAddr simArgs) dMapVarMap + let dnsMapVar = dMapVarMap Map.! naAddr nArgs + let dMapVarMap' = Map.delete (naAddr nArgs) dMapVarMap dMapVarMap'' = Map.insert ip dnsMapVar dMapVarMap' - withAsync (runNode simArgs' ntnSnocket ntcSnocket lrpVar dnsMapVar) + withAsync (runNode sArgs nArgs' ntnSnocket ntcSnocket lrpVar dnsMapVar) $ \nodeAsync -> - withAsync (updateDomainMap delay (saAddr simArgs) ip dMapVarMap'') + withAsync (updateDomainMap delay (naAddr nArgs) ip dMapVarMap'') $ \_ -> runCommand (Just (nodeAsync, lrpVar)) ntnSnocket ntcSnocket - dMapVarMap'' simArgs' cs - runCommand _ _ _ _ _ (JoinNetwork _ _:_) = + dMapVarMap'' sArgs nArgs' cs + runCommand _ _ _ _ _ _ (JoinNetwork _ _:_) = error "runCommand: Impossible happened" - runCommand (Just (async, _)) ntnSnocket ntcSnocket dMapVarMap simArgs + runCommand (Just (async, _)) ntnSnocket ntcSnocket dMapVarMap sArgs nArgs (Kill delay:cs) = do threadDelay delay - traceWith (diffSimTracerWithTimName (saAddr simArgs)) TrKillingNode + traceWith (diffSimTracerWithTimName (naAddr nArgs)) TrKillingNode cancel async - runCommand Nothing ntnSnocket ntcSnocket dMapVarMap simArgs cs - runCommand _ _ _ _ _ (Kill _:_) = do + runCommand Nothing ntnSnocket ntcSnocket dMapVarMap sArgs nArgs cs + runCommand _ _ _ _ _ _ (Kill _:_) = do error "runCommand: Impossible happened" - runCommand Nothing _ _ _ _ (Reconfigure _ _:_) = + runCommand Nothing _ _ _ _ _ (Reconfigure _ _:_) = error "runCommand: Impossible happened" - runCommand (Just (async, lrpVar)) ntnSnocket ntcSnocket dMapVarMap simArgs + runCommand (Just (async, lrpVar)) ntnSnocket ntcSnocket dMapVarMap sArgs nArgs (Reconfigure delay newLrp:cs) = do threadDelay delay - traceWith (diffSimTracerWithTimName (saAddr simArgs)) TrReconfigurionNode + traceWith (diffSimTracerWithTimName (naAddr nArgs)) TrReconfigurionNode _ <- atomically $ writeTVar lrpVar newLrp - runCommand (Just (async, lrpVar)) ntnSnocket ntcSnocket dMapVarMap simArgs + runCommand (Just (async, lrpVar)) ntnSnocket ntcSnocket dMapVarMap sArgs nArgs cs updateDomainMap :: DiffTime @@ -704,6 +685,7 @@ diffusionSimulation updateDomainMap _ _ _ _ = return () runNode :: SimArgs + -> NodeArgs -> Snocket m (FD m NtNAddr) NtNAddr -> Snocket m (FD m NtCAddr) NtCAddr -> StrictTVar m [(Int, Map RelayAccessPoint PeerAdvertise)] @@ -711,14 +693,16 @@ diffusionSimulation -> m Void runNode SimArgs { saSlot = bgaSlotDuration - , saSeed = seed , saQuota = quota - , saMbTime = mustReplyTimeout - , saRelays = raps - , saAddr = rap - , saLocalSelectionTargets = peerSelectionTargets - , saDNSTimeoutScript = dnsTimeout - , saDNSLookupDelayScript = dnsLookupDelay + } + NodeArgs + { naSeed = seed + , naMbTime = mustReplyTimeout + , naRelays = raps + , naAddr = rap + , naLocalSelectionTargets = peerSelectionTargets + , naDNSTimeoutScript = dnsTimeout + , naDNSLookupDelayScript = dnsLookupDelay } ntnSnocket ntcSnocket