From f88a65db80bcdf03c9e693eec0187a9adbf5af75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Fri, 12 Jan 2024 12:37:44 +1100 Subject: [PATCH 01/10] CI: Limit to a single Haskell job on macOS --- .github/workflows/haskell.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 296d120a23b..6598a2aabfd 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -25,9 +25,16 @@ jobs: strategy: fail-fast: false matrix: + # If you edit these versions, make sure the version in the lonely macos-latest job below is updated accordingly ghc: ["9.2.8", "9.6.3"] cabal: ["3.10.2.1"] - os: [macos-latest, windows-latest, ubuntu-latest] + os: [windows-latest, ubuntu-latest] + include: + # Using include, to make sure only be one macOS job, even if the matrix gets expanded later on. + # We want a single job, because macOS runners are scarce. + - os: macos-latest + cabal: "3.10.2.1" + ghc: "9.6.3" env: # Modify this value to "invalidate" the cabal cache. From bb54e75268085a21ed198854c54ff408ef72e620 Mon Sep 17 00:00:00 2001 From: John Ky Date: Thu, 11 Jan 2024 01:05:33 +1100 Subject: [PATCH 02/10] Delete unused function renderApplyMempoolPayloadErr --- cardano-submit-api/cardano-submit-api.cabal | 1 - .../src/Cardano/TxSubmit/ErrorRender.hs | 54 +------------------ 2 files changed, 1 insertion(+), 54 deletions(-) diff --git a/cardano-submit-api/cardano-submit-api.cabal b/cardano-submit-api/cardano-submit-api.cabal index 4dc5ccd39ee..1ade42cb153 100644 --- a/cardano-submit-api/cardano-submit-api.cabal +++ b/cardano-submit-api/cardano-submit-api.cabal @@ -43,7 +43,6 @@ library , cardano-binary , cardano-cli ^>= 8.18.0.0 , cardano-crypto-class ^>= 2.1.2 - , cardano-ledger-byron ^>= 1.0 , formatting , http-media , iohk-monitoring diff --git a/cardano-submit-api/src/Cardano/TxSubmit/ErrorRender.hs b/cardano-submit-api/src/Cardano/TxSubmit/ErrorRender.hs index 0fa109cf298..a6dc1537deb 100644 --- a/cardano-submit-api/src/Cardano/TxSubmit/ErrorRender.hs +++ b/cardano-submit-api/src/Cardano/TxSubmit/ErrorRender.hs @@ -2,8 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} module Cardano.TxSubmit.ErrorRender - ( renderApplyMempoolPayloadErr - , renderEraMismatch + ( renderEraMismatch ) where -- This file contains error renders. They should have been defined at a lower level, with the error @@ -11,60 +10,9 @@ module Cardano.TxSubmit.ErrorRender -- They will be defined here for now and then moved where they are supposed to be once they -- are working. -import Cardano.Api - -import Cardano.Chain.Byron.API (ApplyMempoolPayloadErr (..)) -import Cardano.Chain.UTxO.UTxO (UTxOError (..)) -import Cardano.Chain.UTxO.Validation (TxValidationError (..), UTxOValidationError (..)) import Data.Text (Text) -import Formatting (build, sformat, stext, (%)) import Ouroboros.Consensus.Cardano.Block (EraMismatch (..)) -renderApplyMempoolPayloadErr :: ApplyMempoolPayloadErr -> Text -renderApplyMempoolPayloadErr err = - case err of - MempoolTxErr ve -> renderValidationError ve - MempoolDlgErr {} -> "Delegation error" - MempoolUpdateProposalErr {} -> "Update proposal error" - MempoolUpdateVoteErr {} -> "Update vote error" - -renderValidationError :: UTxOValidationError -> Text -renderValidationError ve = - case ve of - UTxOValidationTxValidationError tve -> renderTxValidationError tve - UTxOValidationUTxOError ue -> renderUTxOError ue - -renderTxValidationError :: TxValidationError -> Text -renderTxValidationError tve = - "Tx Validation: " <> - case tve of - TxValidationLovelaceError txt e -> - sformat ("Lovelace error " % stext % ": " % build) txt e - TxValidationFeeTooSmall tx expected actual -> - sformat ("Tx " % build % " fee " % build % "too low, expected " % build) tx actual expected - TxValidationWitnessWrongSignature wit pmid sig -> - sformat ("Bad witness " % build % " for signature " % stext % " protocol magic id " % stext) wit (textShow sig) (textShow pmid) - TxValidationWitnessWrongKey wit addr -> - sformat ("Bad witness " % build % " for address " % build) wit addr - TxValidationMissingInput tx -> - sformat ("Validation cannot find input tx " % build) tx - -- Fields are - TxValidationNetworkMagicMismatch expected actual -> - mconcat [ "Bad network magic ", textShow actual, ", expected ", textShow expected ] - TxValidationTxTooLarge expected actual -> - mconcat [ "Tx is ", textShow actual, " bytes, but expected < ", textShow expected, " bytes" ] - TxValidationUnknownAddressAttributes -> - "Unknown address attributes" - TxValidationUnknownAttributes -> - "Unknown attributes" - -renderUTxOError :: UTxOError -> Text -renderUTxOError ue = - "UTxOError: " <> - case ue of - UTxOMissingInput tx -> sformat ("Lookup of tx " % build % " failed") tx - UTxOOverlappingUnion -> "Union or two overlapping UTxO sets" - renderEraMismatch :: EraMismatch -> Text renderEraMismatch EraMismatch{ledgerEraName, otherEraName} = "The era of the node and the tx do not match. " <> From 47958c3581f02ed333f4dda3bcc8b812a2c777e7 Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Thu, 16 Nov 2023 16:10:00 +0000 Subject: [PATCH 03/10] wb | cardano-topology as a library with unit testing --- .../cardano-topology/app/cardano-topology.hs | 184 ++++ bench/cardano-topology/cardano-topology.cabal | 39 +- bench/cardano-topology/cardano-topology.hs | 377 -------- .../cardano-topology/data/bench-dense-52.json | 898 ++++++++++++++++++ .../data/ci-test-nomadcwqa.json | 40 + .../data/ci-test-nomadperf.json | 40 + bench/cardano-topology/data/ci-test.json | 27 + .../data/default-nomadcwqa.json | 100 ++ .../data/default-nomadperf.json | 100 ++ bench/cardano-topology/data/default.json | 71 ++ .../src/Cardano/Benchmarking/Topology.hs | 227 +++++ .../Cardano/Benchmarking/Topology/Types.hs | 97 ++ bench/cardano-topology/test/Main.hs | 243 +++++ 13 files changed, 2065 insertions(+), 378 deletions(-) create mode 100644 bench/cardano-topology/app/cardano-topology.hs delete mode 100644 bench/cardano-topology/cardano-topology.hs create mode 100644 bench/cardano-topology/data/bench-dense-52.json create mode 100644 bench/cardano-topology/data/ci-test-nomadcwqa.json create mode 100644 bench/cardano-topology/data/ci-test-nomadperf.json create mode 100644 bench/cardano-topology/data/ci-test.json create mode 100644 bench/cardano-topology/data/default-nomadcwqa.json create mode 100644 bench/cardano-topology/data/default-nomadperf.json create mode 100644 bench/cardano-topology/data/default.json create mode 100644 bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs create mode 100644 bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs create mode 100644 bench/cardano-topology/test/Main.hs diff --git a/bench/cardano-topology/app/cardano-topology.hs b/bench/cardano-topology/app/cardano-topology.hs new file mode 100644 index 00000000000..5f59461a4ae --- /dev/null +++ b/bench/cardano-topology/app/cardano-topology.hs @@ -0,0 +1,184 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TupleSections #-} +{-# OPTIONS_GHC -Wno-partial-fields -Wno-name-shadowing #-} + +{- HLINT ignore "Redundant id" -} +{- HLINT ignore "Use concatMap" -} + +-------------------------------------------------------------------------------- + +import Prelude hiding (id) + +import qualified System.IO as IO + +import qualified Data.Aeson as Aeson +import qualified Data.ByteString.Lazy.Char8 as LBS +import qualified Data.GraphViz as G +import qualified Data.GraphViz.Attributes.Complete as G +import qualified Data.GraphViz.Printing as G +import qualified Data.Text.Lazy.IO as T +import Options.Applicative + +import qualified Cardano.Benchmarking.Topology as Topo + +-------------------------------------------------------------------------------- + +main :: IO () +main = do + (coreNodesParams, topoJson, topoDot, withExplorer) <- execParser cliOpts + let cores = Topo.mkCoreNodes coreNodesParams + relays = [ + Topo.mkExplorer (Topo.AWS Topo.EU_CENTRAL_1) cores + | withExplorer + ] + writeTopo cores relays topoJson + maybe (pure ()) (writeDot cores) topoDot + +-------------------------------------------------------------------------------- + +-- | Locations have a default AWS region that are the ones cardano-ops is using. +cliLocation :: String -> Either String Topo.Location +cliLocation = \case + "LO" -> Right Topo.Loopback + "AP" -> Right (Topo.AWS Topo.AP_SOUTHEAST_2) + "EU" -> Right (Topo.AWS Topo.EU_CENTRAL_1) + "US" -> Right (Topo.AWS Topo.US_EAST_2) + str -> Left $ "Unknown Location: \"" ++ str ++ "\" + +cliOpts :: ParserInfo (Topo.CoreNodesParams, FilePath, Maybe FilePath, Bool) +cliOpts = info (cliParser <**> helper) + ( fullDesc + <> progDesc "Cardano topology generator" + <> header "make-topology - generate Cardano node topologies" ) + where + cliParser :: Parser (Topo.CoreNodesParams, FilePath, Maybe FilePath, Bool) + cliParser = + (,,,) + <$> subparser coreNodesParamsParser + <*> strOption + ( long "topology-output" + <> help "Topology file to write" + <> metavar "OUTFILE" ) + <*> optional + (strOption + ( long "dot-output" + <> help "Dot file to write" + <> metavar "OUTFILE" )) + <*> flag False True + ( long "with-explorer" + <> help "Add an explorer to the topology") + + coreNodesParamsParser = + command "torus" + (info + (Topo.Torus + <$> parseSize + <*> some parseLocation + <*> parseRoleSelector) + (progDesc "Toroidal mesh" + <> fullDesc + <> header "Generate a toroidal mesh topology")) + <> + command "line" + (info + (Topo.Line + <$> parseSize + <*> parseLocation + <*> parseRoleSelector) + (progDesc "Line" + <> fullDesc + <> header "Generate a line topology")) + <> + command "uni-circle" + (info + (Topo.UniCircle + <$> parseSize + <*> parseLocation + <*> parseRoleSelector) + (progDesc "Unidirectional circle" + <> fullDesc + <> header "Generate a unidirectional circle topology")) + + parseSize = + option auto + ( long "size" + <> metavar "SIZE" + <> help "Node count" ) + + parseLocation = + option (eitherReader cliLocation) + ( long "loc" + <> help "Region (at least one)" + <> metavar "LOCNAME" ) + + parseRoleSelector = + roleSelector <$> + flag False True + ( long "with-bft-node-0" + <> help "Include a BFT node-0") + + roleSelector withBft = \case + -- TODO: prepare for deprecation of BFT nodes by switching 1 & 0 + 1 -> Just 1 -- Normal pools are just that -- a single pool + 0 -> if withBft + then Nothing -- The BFT node has no pools + else Just 1 -- Dense pools are denoted by any amount >1 + _ -> Just 2 + +-------------------------------------------------------------------------------- + +--- * To JSON topology +--- +writeTopo :: [Topo.Node] -> [Topo.Node] -> FilePath -> IO () +writeTopo cores relays f = + IO.withFile f IO.WriteMode $ \hnd -> + LBS.hPutStrLn hnd . Aeson.encode $ Topo.Topology cores relays + +-------------------------------------------------------------------------------- + +--- * To Graphviz +--- +writeDot :: [Topo.Node] -> FilePath -> IO () +writeDot topo f = + IO.withFile f IO.WriteMode $ \hnd -> + T.hPutStrLn hnd $ + G.renderDot $ G.toDot $ + uncurry (G.graphElemsToDot params) (toGV topo) + where + params = G.nonClusteredParams + { G.globalAttributes = + [ G.GraphAttrs + [G.Scale $ G.DVal 5] + ] + , G.fmtNode = + \(_, Topo.Node{..})-> + [ G.FillColor . G.toColorList . (:[]) $ + case nodeId of + 0 -> G.RGB 250 250 150 + 1 -> G.RGB 150 250 250 + _ -> locationColor region + , G.Style [G.SItem G.Filled []] + ] + } + +toGV :: [Topo.Node] -> ([(String, Topo.Node)], [(String, String, String)]) +toGV xs = (,) + ((\n@Topo.Node{..} -> ("node-" <> show nodeId, n)) <$> xs) + (concat $ + (\Topo.Node{..} -> + ("node-" <> show nodeId, , "") + . ("node-" <>) + . show <$> producers + ) + <$> + xs + ) + +locationColor :: Topo.Location -> G.Color +locationColor = \case + (Topo.AWS Topo.AP_SOUTHEAST_2) -> G.RGB 250 200 200 + (Topo.AWS Topo.EU_CENTRAL_1) -> G.RGB 200 200 250 + (Topo.AWS Topo.US_EAST_1) -> G.RGB 200 250 200 + (Topo.AWS Topo.US_EAST_2) -> G.RGB 200 250 200 + Topo.Loopback -> G.RGB 200 200 250 diff --git a/bench/cardano-topology/cardano-topology.cabal b/bench/cardano-topology/cardano-topology.cabal index ba0c59c4ef4..4ce6c7227e1 100644 --- a/bench/cardano-topology/cardano-topology.cabal +++ b/bench/cardano-topology/cardano-topology.cabal @@ -13,6 +13,14 @@ license: Apache-2.0 license-files: LICENSE NOTICE build-type: Simple +extra-source-files: README.md +data-files: data/bench-dense-52.json + data/ci-test-nomadcwqa.json + data/ci-test-nomadperf.json + data/ci-test.json + data/default-nomadcwqa.json + data/default-nomadperf.json + data/default.json common project-config build-depends: base >= 4.14 && < 5 @@ -25,10 +33,21 @@ common project-config -Wno-unticked-promoted-constructors -Wpartial-fields -Wredundant-constraints + -Wwarn=deprecations + +library + import: project-config + hs-source-dirs: src + exposed-modules: Cardano.Benchmarking.Topology + , Cardano.Benchmarking.Topology.Types + build-depends: base >=4.12 && <5 + , aeson + , bytestring + , text executable cardano-topology import: project-config - hs-source-dirs: . + hs-source-dirs: app/ main-is: cardano-topology.hs ghc-options: -threaded -rtsopts @@ -40,3 +59,21 @@ executable cardano-topology , optparse-applicative-fork , split , text + , cardano-topology + +test-suite cardano-topology-test + import: project-config + hs-source-dirs: test/ + main-is: Main.hs + type: exitcode-stdio-1.0 + other-modules: Paths_cardano_topology + autogen-modules: Paths_cardano_topology + build-depends: base + , aeson + , bytestring + , tasty + , tasty-hunit + , cardano-topology + ghc-options: -threaded + -rtsopts + "-with-rtsopts=-T" diff --git a/bench/cardano-topology/cardano-topology.hs b/bench/cardano-topology/cardano-topology.hs deleted file mode 100644 index 51e182a20b3..00000000000 --- a/bench/cardano-topology/cardano-topology.hs +++ /dev/null @@ -1,377 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE TupleSections #-} -{-# OPTIONS_GHC -Wno-partial-fields -Wno-name-shadowing #-} - -{- HLINT ignore "Redundant id" -} -{- HLINT ignore "Use concatMap" -} - -import Prelude hiding (id) - -import Data.Aeson -import Data.Function ((&)) -import qualified Data.GraphViz as G -import qualified Data.GraphViz.Attributes.Complete as G -import qualified Data.GraphViz.Printing as G -import Data.List (tails) -import Data.Maybe (isJust) -import qualified Data.Text.Lazy.IO as T -import qualified Data.ByteString.Lazy.Char8 as LBS -import GHC.Generics - -import Options.Applicative - -import qualified System.IO as IO - - -data TopoParams - = Torus - { tpSize :: Int - , tpLocations :: [Location] - , tpIdPools :: Int -> Maybe Int - } - | Line - { tpSize :: Int - , tpLocation :: Location - , tpIdPools :: Int -> Maybe Int - } - | UniCircle - { tpSize :: Int - , tpLocation :: Location - , tpIdPools :: Int -> Maybe Int - } - -data Spec = Spec - { id :: Int - , loc :: Location - , mpools :: Maybe Int - , links :: [Int] - } - deriving (Generic, Show) - -data Location - = LO | AP | EU | US - deriving (Bounded, Eq, Enum, Ord, Read, Show) - -mkTopology :: TopoParams -> [Spec] -mkTopology Torus{..} = - concat phase3 - where - specIds = [0..(tpSize - 1)] - specLocs = take tpSize $ cycle tpLocations - - -- Assign locations and pool counts; set initial links. - phase0 = zipWith mkInitial specIds specLocs - -- Split into per-location lists. - phase1 = [ filter ((== l) . loc) phase0 - | l <- tpLocations ] - & filter (not . null) - -- Establish intra-location connections. - phase2 = intraConnectRing (tpSize < 6) True <$> phase1 - -- Establish inter-location connections. - phase3 = if length phase2 > 1 - then interConnect phase2 - else phase2 - - interConnect :: [[Spec]] -> [[Spec]] - interConnect xss = - case nlocs of - 0 -> xss - 1 -> xss - _ -> take nlocs $ - fmap linker (tails $ cycle xss) - where - nlocs = length xss - linker (xs:xss') = - [ x { links = ids <> links x } - | (x, i) <- zip xs [0..] - , let ids = idOf i <$> rings ] - where rings = take (nlocs - 1) $ cycle <$> xss' - idOf n xs' = id (xs' !! n) - linker [] = error "Invariant failure: empty list of specs" - - mkInitial :: Int -> Location -> Spec - mkInitial id loc = - Spec{ links = [] - , mpools = tpIdPools id - , ..} - -mkTopology Line{..} = - breakLoop tpSize phase1 - where - specIds = [0..(tpSize - 1)] - -- Assign locations and pool counts; set initial links. - phase0 = mkInitial <$> specIds - -- Connect into a ring - phase1 = intraConnectRing False True phase0 - - mkInitial :: Int -> Spec - mkInitial id = - Spec{ links = [] - , mpools = tpIdPools id - , loc = tpLocation - , ..} - -mkTopology UniCircle{..} = - phase1 - where - specIds = [0..(tpSize - 1)] - -- Assign locations and pool counts; set initial links. - phase0 = mkInitial <$> specIds - -- Connect into a ring - phase1 = intraConnectRing False False phase0 - - mkInitial :: Int -> Spec - mkInitial id = - Spec{ links = [] - , mpools = tpIdPools id - , loc = tpLocation - , ..} - -breakLoop :: Int -> [Spec] -> [Spec] -breakLoop tpSize - = updateHead (filterLinks (/= tpSize - 1)) - . updateLast (filterLinks (/= 0)) - -filterLinks :: (Int -> Bool) -> Spec -> Spec -filterLinks f s@Spec{..} = s { links = filter f links } - -intraConnectRing :: Bool -> Bool -> [Spec] -> [Spec] -intraConnectRing withChords bidirectional specs = - case len of - 0 -> [] - 1 -> specs - 2 -> connect 1 - specs - _ -> connect 1 -- next - $ if not bidirectional - then specs - else connect (len - 1) -- prev - $ if not withChords - then specs - else connect (len `div` 3) -- chord 1 - $ if len < 9 - then specs - else connect ((len * 2) `div` 3) -- chord 2 - specs - where - len = length specs - connect :: Int -> [Spec] -> [Spec] - connect offt xs = - take (length xs) $ - fmap linker (tails ring) - where linker (x:xs') = - x { links = idOf (offt - 1) xs' - : links x } - linker [] = error "Invariant failure: empty list of specs" - ring = cycle xs - idOf n xs' = id (xs' !! n) - -main :: IO () -main = do - (topoParams, topoJson, topoDot, withExplorer) <- execParser opts - - let topoSpec = mkTopology topoParams - cores = mkNode <$> topoSpec - relays = [ mkExplorer (locationRegion EU) cores - | withExplorer ] - - writeTopo cores relays topoJson - maybe (pure ()) (writeDot topoSpec) topoDot - where - opts = info (cliParser <**> helper) - ( fullDesc - <> progDesc "Cardano topology generator" - <> header "make-topology - generate Cardano node topologies" ) - - cliParser :: Parser (TopoParams, FilePath, Maybe FilePath, Bool) - cliParser = - (,,,) - <$> subparser topoParamsParser - <*> strOption - ( long "topology-output" - <> help "Topology file to write" - <> metavar "OUTFILE" ) - <*> optional - (strOption - ( long "dot-output" - <> help "Dot file to write" - <> metavar "OUTFILE" )) - <*> flag False True - ( long "with-explorer" - <> help "Add an explorer to the topology") - - topoParamsParser = - command "torus" - (info - (Torus - <$> parseSize - <*> some parseLocation - <*> parseRoleSelector) - (progDesc "Toroidal mesh" - <> fullDesc - <> header "Generate a toroidal mesh topology")) - <> - command "line" - (info - (Line - <$> parseSize - <*> parseLocation - <*> parseRoleSelector) - (progDesc "Line" - <> fullDesc - <> header "Generate a line topology")) - <> - command "uni-circle" - (info - (UniCircle - <$> parseSize - <*> parseLocation - <*> parseRoleSelector) - (progDesc "Unidirectional circle" - <> fullDesc - <> header "Generate a unidirectional circle topology")) - - parseSize = - option auto - ( long "size" - <> metavar "SIZE" - <> help "Node count" ) - - parseLocation = - option auto - ( long "loc" - <> help "Region (at least one)" - <> metavar "LOCNAME" ) - - parseRoleSelector = - roleSelector <$> - flag False True - ( long "with-bft-node-0" - <> help "Include a BFT node-0") - - roleSelector withBft = \case - -- TODO: prepare for deprecation of BFT nodes by switching 1 & 0 - 1 -> Just 1 -- Normal pools are just that -- a single pool - 0 -> if withBft - then Nothing -- The BFT node has no pools - else Just 1 -- Dense pools are denoted by any amount >1 - _ -> Just 2 - ---- * To JSON topology ---- -writeTopo :: [Node] -> [Node] -> FilePath -> IO () -writeTopo cores relays f = - IO.withFile f IO.WriteMode $ \hnd -> - LBS.hPutStrLn hnd . encode $ Topology cores relays - -mkNode :: Spec -> Node -mkNode Spec{..} = Node{..} - where - name = idName nodeId - org = "IOHK" - nodeId = id - pools = mpools - stakePool = isJust mpools - region = locationRegion loc - producers = idName <$> links - -mkExplorer :: String -> [Node] -> Node -mkExplorer region cores = Node{ name = "explorer" - , ..} - where - org = "IOHK" - nodeId = length cores - pools = Nothing - stakePool = False - producers = name <$> cores - -data Topology = Topology - { coreNodes :: [Node] - , relayNodes :: [Node] - } - deriving (Generic, Show) - -data Node = Node - { name :: String - , org :: String - , region :: String - , producers :: [String] - , nodeId :: Int - , pools :: Maybe Int - , stakePool :: Bool - } - deriving (Generic, Show) - -instance ToJSON Topology -instance ToJSON Node where - toEncoding = genericToEncoding defaultOptions { omitNothingFields = True } - ---- * To Graphviz ---- -writeDot :: [Spec] -> FilePath -> IO () -writeDot topo f = - IO.withFile f IO.WriteMode $ \hnd -> - T.hPutStrLn hnd $ - G.renderDot $ G.toDot $ - uncurry (G.graphElemsToDot params) (toGV topo) - where - params = G.nonClusteredParams - { G.globalAttributes = - [ G.GraphAttrs - [G.Scale $ G.DVal 5] - ] - , G.fmtNode = - \(_, Spec{..})-> - [ G.FillColor . G.toColorList . (:[]) $ - case id of - 0 -> G.RGB 250 250 150 - 1 -> G.RGB 150 250 250 - _ -> locationColor loc - , G.Style [G.SItem G.Filled []] - ] - } - -toGV :: [Spec] -> ([(String, Spec)], [(String, String, String)]) -toGV xs = - (,) ((\s@Spec{..} -> ("node-" <> show id, s)) <$> xs) - (concat $ - (\Spec{..} -> ("node-" <> show id, , "") - . ("node-" <>) - . show <$> links) <$> xs) - ---- * Aux ---- --- | Update the first element of a list, if it exists. --- O(1). -updateHead :: (a -> a) -> [a] -> [a] -updateHead _ [] = [] -updateHead f (a : as) = f a : as - --- | Update the last element of a list, if it exists. --- O(n). -updateLast :: (a -> a) -> [a] -> [a] -updateLast _ [] = [] -updateLast f (a : as) = loop a as - -- Using a helper function to minimize the pattern matching. - where - loop a [] = [f a] - loop a (b : bs) = a : loop b bs - -idName :: Int -> String -idName = ("node-" <>) . show - -locationRegion :: Location -> String -locationRegion = \case - EU -> "eu-central-1" - AP -> "ap-southeast-2" - US -> "us-east-2" - LO -> "loopback" - -locationColor :: Location -> G.Color -locationColor = \case - AP -> G.RGB 250 200 200 - EU -> G.RGB 200 200 250 - US -> G.RGB 200 250 200 - LO -> G.RGB 200 200 250 diff --git a/bench/cardano-topology/data/bench-dense-52.json b/bench/cardano-topology/data/bench-dense-52.json new file mode 100644 index 00000000000..0956047f9fd --- /dev/null +++ b/bench/cardano-topology/data/bench-dense-52.json @@ -0,0 +1,898 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": null, + "producers": [ + "node-1", + "node-2", + "node-3", + "node-51", + "node-18", + "node-36" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-3", + "nodeId": 3, + "org": "IOHK", + "pools": 2, + "stakePool": null, + "producers": [ + "node-4", + "node-5", + "node-6", + "node-0", + "node-21", + "node-39" + ], + "region": "eu-central-1" + }, + { + "name": "node-6", + "nodeId": 6, + "org": "IOHK", + "pools": 2, + "stakePool": null, + "producers": [ + "node-7", + "node-8", + "node-9", + "node-3", + "node-24", + "node-42" + ], + "region": "eu-central-1" + }, + { + "name": "node-9", + "nodeId": 9, + "org": "IOHK", + "pools": 2, + "stakePool": null, + "producers": [ + "node-10", + "node-11", + "node-12", + "node-6", + "node-27", + "node-45" + ], + "region": "eu-central-1" + }, + { + "name": "node-12", + "nodeId": 12, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-13", + "node-14", + "node-15", + "node-9", + "node-30", + "node-48" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-15", + "nodeId": 15, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-16", + "node-17", + "node-18", + "node-12", + "node-33", + "node-51" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-18", + "nodeId": 18, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-19", + "node-20", + "node-21", + "node-15", + "node-36", + "node-0" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-21", + "nodeId": 21, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-22", + "node-23", + "node-24", + "node-18", + "node-39", + "node-3" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-24", + "nodeId": 24, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-25", + "node-26", + "node-27", + "node-21", + "node-42", + "node-6" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-27", + "nodeId": 27, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-28", + "node-29", + "node-30", + "node-24", + "node-45", + "node-9" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-30", + "nodeId": 30, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-31", + "node-32", + "node-33", + "node-27", + "node-48", + "node-12" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-33", + "nodeId": 33, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-34", + "node-35", + "node-36", + "node-30", + "node-51", + "node-15" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-36", + "nodeId": 36, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-37", + "node-38", + "node-39", + "node-33", + "node-0", + "node-18" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-39", + "nodeId": 39, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-40", + "node-41", + "node-42", + "node-36", + "node-3", + "node-21" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-42", + "nodeId": 42, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-43", + "node-44", + "node-45", + "node-39", + "node-6", + "node-24" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-45", + "nodeId": 45, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-46", + "node-47", + "node-48", + "node-42", + "node-9", + "node-27" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-48", + "nodeId": 48, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-49", + "node-50", + "node-51", + "node-45", + "node-12", + "node-30" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-51", + "nodeId": 51, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-1", + "node-2", + "node-0", + "node-48", + "node-15", + "node-33" + ], + "region": "eu-central-1", + "stakePool": null + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-2", + "node-0", + "node-4", + "node-49", + "node-16", + "node-34" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-4", + "nodeId": 4, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-5", + "node-3", + "node-7", + "node-1", + "node-19", + "node-37" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-7", + "nodeId": 7, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-8", + "node-6", + "node-10", + "node-4", + "node-22", + "node-40" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-10", + "nodeId": 10, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-11", + "node-9", + "node-13", + "node-7", + "node-25", + "node-43" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-13", + "nodeId": 13, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-14", + "node-12", + "node-16", + "node-10", + "node-28", + "node-46" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-16", + "nodeId": 16, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-17", + "node-15", + "node-19", + "node-13", + "node-31", + "node-49" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-19", + "nodeId": 19, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-20", + "node-18", + "node-22", + "node-16", + "node-34", + "node-1" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-22", + "nodeId": 22, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-23", + "node-21", + "node-25", + "node-19", + "node-37", + "node-4" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-25", + "nodeId": 25, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-26", + "node-24", + "node-28", + "node-22", + "node-40", + "node-7" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-28", + "nodeId": 28, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-29", + "node-27", + "node-31", + "node-25", + "node-43", + "node-10" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-31", + "nodeId": 31, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-32", + "node-30", + "node-34", + "node-28", + "node-46", + "node-13" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-34", + "nodeId": 34, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-35", + "node-33", + "node-37", + "node-31", + "node-49", + "node-16" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-37", + "nodeId": 37, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-38", + "node-36", + "node-40", + "node-34", + "node-1", + "node-19" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-40", + "nodeId": 40, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-41", + "node-39", + "node-43", + "node-37", + "node-4", + "node-22" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-43", + "nodeId": 43, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-44", + "node-42", + "node-46", + "node-40", + "node-7", + "node-25" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-46", + "nodeId": 46, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-47", + "node-45", + "node-49", + "node-43", + "node-10", + "node-28" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-49", + "nodeId": 49, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-50", + "node-48", + "node-1", + "node-46", + "node-13", + "node-31" + ], + "region": "ap-southeast-2", + "stakePool": null + }, + { + "name": "node-2", + "nodeId": 2, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-0", + "node-1", + "node-5", + "node-50", + "node-17", + "node-35" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-5", + "nodeId": 5, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-3", + "node-4", + "node-8", + "node-2", + "node-20", + "node-38" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-8", + "nodeId": 8, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-6", + "node-7", + "node-11", + "node-5", + "node-23", + "node-41" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-11", + "nodeId": 11, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-9", + "node-10", + "node-14", + "node-8", + "node-26", + "node-44" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-14", + "nodeId": 14, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-12", + "node-13", + "node-17", + "node-11", + "node-29", + "node-47" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-17", + "nodeId": 17, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-15", + "node-16", + "node-20", + "node-14", + "node-32", + "node-50" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-20", + "nodeId": 20, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-18", + "node-19", + "node-23", + "node-17", + "node-35", + "node-2" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-23", + "nodeId": 23, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-21", + "node-22", + "node-26", + "node-20", + "node-38", + "node-5" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-26", + "nodeId": 26, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-24", + "node-25", + "node-29", + "node-23", + "node-41", + "node-8" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-29", + "nodeId": 29, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-27", + "node-28", + "node-32", + "node-26", + "node-44", + "node-11" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-32", + "nodeId": 32, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-30", + "node-31", + "node-35", + "node-29", + "node-47", + "node-14" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-35", + "nodeId": 35, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-33", + "node-34", + "node-38", + "node-32", + "node-50", + "node-17" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-38", + "nodeId": 38, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-36", + "node-37", + "node-41", + "node-35", + "node-2", + "node-20" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-41", + "nodeId": 41, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-39", + "node-40", + "node-44", + "node-38", + "node-5", + "node-23" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-44", + "nodeId": 44, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-42", + "node-43", + "node-47", + "node-41", + "node-8", + "node-26" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-47", + "nodeId": 47, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-45", + "node-46", + "node-50", + "node-44", + "node-11", + "node-29" + ], + "region": "us-east-2", + "stakePool": null + }, + { + "name": "node-50", + "nodeId": 50, + "org": "IOHK", + "pools": 2, + "producers": [ + "node-48", + "node-49", + "node-2", + "node-47", + "node-14", + "node-32" + ], + "region": "us-east-2", + "stakePool": null + } + ], + "relayNodes": [ + { + "name": "explorer", + "nodeId": 52, + "org": "IOHK", + "producers": [ + "node-0", + "node-1", + "node-2", + "node-3", + "node-4", + "node-5", + "node-6", + "node-7", + "node-8", + "node-9", + "node-10", + "node-11", + "node-12", + "node-13", + "node-14", + "node-15", + "node-16", + "node-17", + "node-18", + "node-19", + "node-20", + "node-21", + "node-22", + "node-23", + "node-24", + "node-25", + "node-26", + "node-27", + "node-28", + "node-29", + "node-30", + "node-31", + "node-32", + "node-33", + "node-34", + "node-35", + "node-36", + "node-37", + "node-38", + "node-39", + "node-40", + "node-41", + "node-42", + "node-43", + "node-44", + "node-45", + "node-46", + "node-47", + "node-48", + "node-49", + "node-50", + "node-51" + ], + "region": "eu-central-1" + } + ] +} diff --git a/bench/cardano-topology/data/ci-test-nomadcwqa.json b/bench/cardano-topology/data/ci-test-nomadcwqa.json new file mode 100644 index 00000000000..00ccbb9bc1c --- /dev/null +++ b/bench/cardano-topology/data/ci-test-nomadcwqa.json @@ -0,0 +1,40 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-0" + ], + "region": "us-east-2", + "stakePool": true + } + ], + "relayNodes": [ + { + "name": "explorer", + "nodeId": 2, + "org": "IOHK", + "pools": null, + "producers": [ + "node-0", + "node-1" + ], + "region": "eu-central-1", + "stakePool": false + } + ] +} diff --git a/bench/cardano-topology/data/ci-test-nomadperf.json b/bench/cardano-topology/data/ci-test-nomadperf.json new file mode 100644 index 00000000000..00ccbb9bc1c --- /dev/null +++ b/bench/cardano-topology/data/ci-test-nomadperf.json @@ -0,0 +1,40 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-0" + ], + "region": "us-east-2", + "stakePool": true + } + ], + "relayNodes": [ + { + "name": "explorer", + "nodeId": 2, + "org": "IOHK", + "pools": null, + "producers": [ + "node-0", + "node-1" + ], + "region": "eu-central-1", + "stakePool": false + } + ] +} diff --git a/bench/cardano-topology/data/ci-test.json b/bench/cardano-topology/data/ci-test.json new file mode 100644 index 00000000000..d58cb6575b2 --- /dev/null +++ b/bench/cardano-topology/data/ci-test.json @@ -0,0 +1,27 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1" + ], + "region": "loopback", + "stakePool": true + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-0" + ], + "region": "loopback", + "stakePool": true + } + ], + "relayNodes": [] +} diff --git a/bench/cardano-topology/data/default-nomadcwqa.json b/bench/cardano-topology/data/default-nomadcwqa.json new file mode 100644 index 00000000000..8d9344e5286 --- /dev/null +++ b/bench/cardano-topology/data/default-nomadcwqa.json @@ -0,0 +1,100 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1", + "node-2", + "node-4" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-2", + "nodeId": 2, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-3", + "node-4", + "node-0" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-4", + "nodeId": 4, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-5", + "node-0", + "node-2" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-0", + "node-3", + "node-5" + ], + "region": "us-east-2", + "stakePool": true + }, + { + "name": "node-3", + "nodeId": 3, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-2", + "node-5", + "node-1" + ], + "region": "us-east-2", + "stakePool": true + }, + { + "name": "node-5", + "nodeId": 5, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-4", + "node-1", + "node-3" + ], + "region": "us-east-2", + "stakePool": true + } + ], + "relayNodes": [ + { + "name": "explorer", + "nodeId": 6, + "org": "IOHK", + "pools": null, + "producers": [ + "node-0", + "node-2", + "node-4", + "node-1", + "node-3", + "node-5" + ], + "region": "eu-central-1", + "stakePool": false + } + ] +} diff --git a/bench/cardano-topology/data/default-nomadperf.json b/bench/cardano-topology/data/default-nomadperf.json new file mode 100644 index 00000000000..96de795d5f0 --- /dev/null +++ b/bench/cardano-topology/data/default-nomadperf.json @@ -0,0 +1,100 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1", + "node-2", + "node-3" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-3", + "nodeId": 3, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-4", + "node-5", + "node-0" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-2", + "node-0", + "node-4" + ], + "region": "us-east-2", + "stakePool": true + }, + { + "name": "node-4", + "nodeId": 4, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-5", + "node-3", + "node-1" + ], + "region": "us-east-2", + "stakePool": true + }, + { + "name": "node-2", + "nodeId": 2, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-0", + "node-1", + "node-5" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-5", + "nodeId": 5, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-3", + "node-4", + "node-2" + ], + "region": "ap-southeast-2", + "stakePool": true + } + ], + "relayNodes": [ + { + "name": "explorer", + "nodeId": 6, + "org": "IOHK", + "pools": null, + "producers": [ + "node-0", + "node-3", + "node-1", + "node-4", + "node-2", + "node-5" + ], + "region": "eu-central-1", + "stakePool": false + } + ] +} diff --git a/bench/cardano-topology/data/default.json b/bench/cardano-topology/data/default.json new file mode 100644 index 00000000000..0b52fdd5927 --- /dev/null +++ b/bench/cardano-topology/data/default.json @@ -0,0 +1,71 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1" + ], + "region": "loopback", + "stakePool": true + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-2" + ], + "region": "loopback", + "stakePool": true + }, + { + "name": "node-2", + "nodeId": 2, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-3" + ], + "region": "loopback", + "stakePool": true + }, + { + "name": "node-3", + "nodeId": 3, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-4" + ], + "region": "loopback", + "stakePool": true + }, + { + "name": "node-4", + "nodeId": 4, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-5" + ], + "region": "loopback", + "stakePool": true + }, + { + "name": "node-5", + "nodeId": 5, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-0" + ], + "region": "loopback", + "stakePool": true + } + ], + "relayNodes": [] +} diff --git a/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs b/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs new file mode 100644 index 00000000000..2f04832a90f --- /dev/null +++ b/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs @@ -0,0 +1,227 @@ +{-# LANGUAGE RecordWildCards #-} +{-# OPTIONS_GHC -Wno-partial-fields -Wno-name-shadowing #-} + +-------------------------------------------------------------------------------- + +module Cardano.Benchmarking.Topology ( + Types.Topology (..) + , Types.Node (..) + , Types.Location (..) + , Types.AWSRegion (..) + , CoreNodesParams (..) + , mkTopology, mkCoreNodes, mkExplorer +) where + +import Prelude hiding (id) + +import Data.Function ((&)) +import Data.List (tails) +import Data.Maybe (isJust) + +import qualified Cardano.Benchmarking.Topology.Types as Types + +-------------------------------------------------------------------------------- + +-- | Three types of topologies for the core nodes. +data CoreNodesParams + -- FIXME: Currently not used ??? + = Line + { tpSize :: Int -- ^ Number of nodes to use. + , tpLocation :: Types.Location -- ^ Unique location to use. + , tpIdPools :: Int -> Maybe Int -- ^ Node i pool number. + } + | UniCircle + { tpSize :: Int -- ^ Number of nodes to use. + , tpLocation :: Types.Location -- ^ Unique location to use. + , tpIdPools :: Int -> Maybe Int -- ^ Node i pool number. + } + | Torus + { tpSize :: Int -- ^ Number of nodes to use. + , tpLocations :: [Types.Location] -- ^ Locations to use. + , tpIdPools :: Int -> Maybe Int -- ^ Node i pool number. + } + +-------------------------------------------------------------------------------- + +-- | Create a Topology, optional explorer node that connects to all core nodes. +mkTopology :: CoreNodesParams -> Maybe Types.Location -> Types.Topology +mkTopology coreNodesParams maybeExplorerLocation = + let coreNodes = mkCoreNodes coreNodesParams + in Types.Topology { + Types.coreNodes = coreNodes + , Types.relayNodes = case maybeExplorerLocation of + Nothing -> [] + (Just explorerLocation) -> [ mkExplorer explorerLocation coreNodes ] + } + +mkCoreNodes :: CoreNodesParams -> [Types.Node] +mkCoreNodes coreNodesParams = map mkNode (mkCoreNodes' coreNodesParams) + +mkExplorer :: Types.Location -> [Types.Node] -> Types.Node +mkExplorer explorerLocation coreNodes = + (Types.Node { + name = "explorer" + , nodeId = length coreNodes + , region = explorerLocation + , producers = map Types.name coreNodes + , org = "IOHK" + , pools = Nothing + , stakePool = Just False + }) + +-------------------------------------------------------------------------------- + +-- | Intermediate structure to work with Nodes producers by ID instead of name. +data Spec = Spec + { id :: Int + , loc :: Types.Location + , mpools :: Maybe Int + , links :: [Int] + } + deriving Show + +idName :: Int -> String +idName = ("node-" <>) . show + +mkNode :: Spec -> Types.Node +mkNode Spec{..} = Types.Node{..} where + name = idName nodeId + org = "IOHK" + nodeId = id + pools = mpools + stakePool = Just $ isJust mpools + region = loc + producers = idName <$> links + +mkCoreNodes' :: CoreNodesParams -> [Spec] +mkCoreNodes' Line{..} = breakLoop tpSize phase1 where + specIds = [0..(tpSize - 1)] + -- Assign locations and pool counts; set initial links. + phase0 = mkInitial <$> specIds + where + mkInitial :: Int -> Spec + mkInitial id = + Spec { + links = [] + , mpools = tpIdPools id + , loc = tpLocation + , .. + } + -- Connect into a ring + phase1 = intraConnectRing False True phase0 +mkCoreNodes' UniCircle{..} = phase1 where + specIds = [0..(tpSize - 1)] + -- Assign locations and pool counts; set initial links. + phase0 = mkInitial <$> specIds + where + mkInitial :: Int -> Spec + mkInitial id = + Spec { + links = [] + , mpools = tpIdPools id + , loc = tpLocation + , .. + } + -- Connect into a ring + phase1 = intraConnectRing False False phase0 +mkCoreNodes' Torus{..} = concat phase3 where + specIds = [0..(tpSize - 1)] + specLocs = take tpSize $ cycle tpLocations + -- Assign locations and pool counts; set initial links. + phase0 = zipWith mkInitial specIds specLocs + where + mkInitial :: Int -> Types.Location -> Spec + mkInitial id loc = + Spec { + links = [] + , mpools = tpIdPools id + , .. + } + -- Split into per-location lists. + phase1 = + [ + filter ((== l) . loc) phase0 + | l <- tpLocations + ] + & + filter (not . null) + -- Establish intra-location connections. + phase2 = intraConnectRing (tpSize < 6) True <$> phase1 + -- Establish inter-location connections. + phase3 = if length phase2 > 1 + then interConnect phase2 + else phase2 + interConnect :: [[Spec]] -> [[Spec]] + interConnect xss = + case nlocs of + 0 -> xss + 1 -> xss + _ -> take nlocs $ fmap linker (tails $ cycle xss) + where + nlocs = length xss + linker (xs:xss') = + [ x { links = ids <> links x } + | (x, i) <- zip xs [0..] + , let ids = idOf i <$> rings + ] + where + rings = take (nlocs - 1) $ cycle <$> xss' + idOf n xs' = id (xs' !! n) + linker [] = error "Invariant failure: empty list of specs" + +breakLoop :: Int -> [Spec] -> [Spec] +breakLoop tpSize + = updateHead (filterLinks (/= tpSize - 1)) + . updateLast (filterLinks (/= 0)) + +filterLinks :: (Int -> Bool) -> Spec -> Spec +filterLinks f s@Spec{..} = s { links = filter f links } + +intraConnectRing :: Bool -> Bool -> [Spec] -> [Spec] +intraConnectRing withChords bidirectional specs = + case len of + 0 -> [] + 1 -> specs + 2 -> connect 1 + specs + _ -> connect 1 -- next + $ if not bidirectional + then specs + else connect (len - 1) -- prev + $ if not withChords + then specs + else connect (len `div` 3) -- chord 1 + $ if len < 9 + then specs + else connect ((len * 2) `div` 3) -- chord 2 + specs + where + len = length specs + connect :: Int -> [Spec] -> [Spec] + connect offt xs = + take (length xs) $ + fmap linker (tails ring) + where linker (x:xs') = + x { links = idOf (offt - 1) xs' + : links x } + linker [] = error "Invariant failure: empty list of specs" + ring = cycle xs + idOf n xs' = id (xs' !! n) + +--- * Aux +--- +-- | Update the first element of a list, if it exists. +-- O(1). +updateHead :: (a -> a) -> [a] -> [a] +updateHead _ [] = [] +updateHead f (a : as) = f a : as + +-- | Update the last element of a list, if it exists. +-- O(n). +updateLast :: (a -> a) -> [a] -> [a] +updateLast _ [] = [] +updateLast f (a : as) = loop a as + -- Using a helper function to minimize the pattern matching. + where + loop a [] = [f a] + loop a (b : bs) = a : loop b bs diff --git a/bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs b/bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs new file mode 100644 index 00000000000..fe0d1f74095 --- /dev/null +++ b/bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs @@ -0,0 +1,97 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE DeriveGeneric #-} + +-------------------------------------------------------------------------------- + +module Cardano.Benchmarking.Topology.Types ( + Topology (..) + , Node (..) + , Location (..) + , AWSRegion (..) +) where + +import Prelude + +import GHC.Generics + +import qualified Data.Text as Text +import qualified Data.Aeson as Aeson + +-------------------------------------------------------------------------------- + +-- | A topology as it's used to define benchmarking profiles. +data Topology = Topology + { coreNodes :: [Node] + , relayNodes :: [Node] + } + deriving (Eq, Show, Generic) + +instance Aeson.ToJSON Topology + +instance Aeson.FromJSON Topology + +-------------------------------------------------------------------------------- + +-- | A node as it's used to define benchmarking profiles. +-- These nodes don't have remote addresses allocated, are referenced by name. +data Node = Node + { name :: String + , nodeId :: Int -- TODO: Swith to Word64 like Cardano.Topology ? + -- ^ Placement, not present in Cardano.Node.Configuration.Topology. + , region :: Location + -- ^ As Cardano.Node.Configuration.Topology but names not addresses. + , producers :: [String] + -- ^ Actually always "IOHK". + , org :: String + , pools :: Maybe Int + , stakePool :: Maybe Bool + } + deriving (Eq, Show, Generic) + +instance Aeson.ToJSON Node where +{-- + toEncoding = Aeson.genericToEncoding + Aeson.defaultOptions + { Aeson.omitNothingFields = True } +--} + +instance Aeson.FromJSON Node + +-------------------------------------------------------------------------------- + +-- | Location is either "loopback" used for local runs or an AWS Region name +-- used for cloud runs. +data Location = Loopback | AWS AWSRegion + deriving (Eq, Show, Generic) + +instance Aeson.ToJSON Location where + toJSON Loopback = Aeson.toJSON ("loopback" :: Text.Text) + toJSON (AWS r) = Aeson.toJSON r + +instance Aeson.FromJSON Location where + parseJSON v = + (Aeson.withText "Location" $ \case + -- Either "loopback" or an already defined AWS Region. + "loopback" -> return Loopback + _ -> AWS <$> Aeson.parseJSON v + ) + v + +-- | The AWS Regions we support (No Availability Zone, the "c" in "us-east-2c"). +data AWSRegion = AP_SOUTHEAST_2 | EU_CENTRAL_1 | US_EAST_1 | US_EAST_2 + deriving (Eq, Show, Generic) + +instance Aeson.ToJSON AWSRegion where + toJSON AP_SOUTHEAST_2 = Aeson.toJSON ("ap-southeast-2" :: Text.Text) + toJSON EU_CENTRAL_1 = Aeson.toJSON ("eu-central-1" :: Text.Text) + toJSON US_EAST_1 = Aeson.toJSON ("us-east-1" :: Text.Text) + toJSON US_EAST_2 = Aeson.toJSON ("us-east-2" :: Text.Text) + +instance Aeson.FromJSON AWSRegion where + parseJSON = Aeson.withText "AWSRegion" $ \t -> case t of + -- Actually only the ones cardano-ops is using. + "ap-southeast-2" -> return AP_SOUTHEAST_2 + "eu-central-1" -> return EU_CENTRAL_1 + "us-east-2" -> return US_EAST_2 + _ -> fail $ "Unknown AWSRegion: \"" ++ Text.unpack t ++ "\"" diff --git a/bench/cardano-topology/test/Main.hs b/bench/cardano-topology/test/Main.hs new file mode 100644 index 00000000000..239dcbeae2d --- /dev/null +++ b/bench/cardano-topology/test/Main.hs @@ -0,0 +1,243 @@ +{-# LANGUAGE Trustworthy #-} + +-------------------------------------------------------------------------------- +module Main (main) where + +import Prelude + +import Data.Maybe (fromJust) + +import qualified Data.Aeson as Aeson +import qualified Data.ByteString.Lazy as BSL +import qualified Test.Tasty as Tasty +import Test.Tasty.HUnit + +import qualified Cardano.Benchmarking.Topology as Topo +import qualified Cardano.Benchmarking.Topology.Types as Types + +import qualified Paths_cardano_topology as Paths + +-------------------------------------------------------------------------------- + +main :: IO () +main = Tasty.defaultMain tests + +tests :: Tasty.TestTree +tests = Tasty.testGroup "cardano-topology" + [ + topologyTypes + , topology + ] + + +topologyTypes :: Tasty.TestTree +topologyTypes = Tasty.testGroup + "Cardano.Benchmarking.Topology.Types" + [ testCase "Topology FromJson" $ do + fp <- Paths.getDataFileName "data/bench-dense-52.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + "Topology == (decode \"data/bench-dense-52.json\")" + (Right benchDense52) + ans + , testCase "Topology ToJson" $ do + fp <- Paths.getDataFileName "data/bench-dense-52.json" + bsl <- BSL.readFile fp + assertEqual + ("(encode Topology) == (decode \"" ++ fp ++ "\")") + (Aeson.encode benchDense52) + -- Decode-encode the same file so it has the same style. + (Aeson.encode $ + fromJust (Aeson.decode bsl :: (Maybe Types.Topology)) + ) + ] + +-- Create what profiles use and compare with previous profiles outputs. +topology :: Tasty.TestTree +topology = Tasty.testGroup + "Cardano.Benchmarking.Topology" + [ testCase "ci-test" $ do + fp <- Paths.getDataFileName "data/ci-test.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + ("UniCircle (ci-test loopback) == (decode \"" ++ fp ++ "\")") + ans + (Right $ Topo.mkTopology + (Topo.UniCircle + 2 + Types.Loopback + (\_ -> Just 1) + ) + Nothing + ) + , testCase "ci-test-nomadcwqa" $ do + fp <- Paths.getDataFileName "data/ci-test-nomadcwqa.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + ("Torus (ci-test nomadcwqa) == (decode \"" ++ fp ++ "\")") + ans + (Right $ Topo.mkTopology + (Topo.Torus + 2 + [ + Types.AWS Types.EU_CENTRAL_1 + , Types.AWS Types.US_EAST_2 + ] + (\_ -> Just 1) + ) + (Just (Types.AWS Types.EU_CENTRAL_1)) + ) + , testCase "ci-test-nomadperf" $ do + fp <- Paths.getDataFileName "data/ci-test-nomadperf.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + ("Torus (ci-test nomadcwqa) == (decode \"" ++ fp ++ "\")") + ans + (Right $ Topo.mkTopology + (Topo.Torus + 2 + [ + Types.AWS Types.EU_CENTRAL_1 + , Types.AWS Types.US_EAST_2 + , Types.AWS Types.AP_SOUTHEAST_2 + ] + (\_ -> Just 1) + ) + (Just (Types.AWS Types.EU_CENTRAL_1)) + ) + -- For some reason "default" for supervisor/local is using UniCircle and + -- Nomad/cloud runs it's using Torus. + , testCase "default" $ do + fp <- Paths.getDataFileName "data/default.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + ("UniCircle (loopback) == (decode \"" ++ fp ++ "\")") + ans + (Right $ Topo.mkTopology + (Topo.UniCircle + 6 + Types.Loopback + (\_ -> Just 1) + ) + Nothing + ) + , testCase "default-nomadcwqa" $ do + fp <- Paths.getDataFileName "data/default-nomadcwqa.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + ("Torus (default nomadcwqa) == (decode \"" ++ fp ++ "\")") + ans + (Right $ Topo.mkTopology + (Topo.Torus + 6 + [ + Types.AWS Types.EU_CENTRAL_1 + , Types.AWS Types.US_EAST_2 + ] + (\_ -> Just 1) + ) + (Just (Types.AWS Types.EU_CENTRAL_1)) + ) + , testCase "default-nomadperf" $ do + fp <- Paths.getDataFileName "data/default-nomadperf.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + ("Torus (default nomadperf) == (decode \"" ++ fp ++ "\")") + ans + (Right $ Topo.mkTopology + (Topo.Torus + 6 + [ + Types.AWS Types.EU_CENTRAL_1 + , Types.AWS Types.US_EAST_2 + , Types.AWS Types.AP_SOUTHEAST_2 + ] + (\_ -> Just 1) + ) + (Just (Types.AWS Types.EU_CENTRAL_1)) + ) + ] + +benchDense52 :: Types.Topology +benchDense52 = Types.Topology { + Types.coreNodes = [ + -- EU nodes x 18. + Types.Node {Types.name = "node-0", Types.nodeId = 0, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-1", "node-2", "node-3", "node-51","node-18","node-36"], Types.org = "IOHK", Types.pools = Nothing,Types.stakePool = Nothing} + , Types.Node {Types.name = "node-3", Types.nodeId = 3, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-4", "node-5", "node-6", "node-0", "node-21","node-39"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-6", Types.nodeId = 6, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-7", "node-8", "node-9", "node-3", "node-24","node-42"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-9", Types.nodeId = 9, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-10","node-11","node-12","node-6", "node-27","node-45"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-12", Types.nodeId = 12, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-13","node-14","node-15","node-9", "node-30","node-48"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-15", Types.nodeId = 15, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-16","node-17","node-18","node-12","node-33","node-51"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-18", Types.nodeId = 18, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-19","node-20","node-21","node-15","node-36","node-0" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-21", Types.nodeId = 21, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-22","node-23","node-24","node-18","node-39","node-3" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-24", Types.nodeId = 24, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-25","node-26","node-27","node-21","node-42","node-6" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-27", Types.nodeId = 27, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-28","node-29","node-30","node-24","node-45","node-9" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-30", Types.nodeId = 30, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-31","node-32","node-33","node-27","node-48","node-12"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-33", Types.nodeId = 33, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-34","node-35","node-36","node-30","node-51","node-15"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-36", Types.nodeId = 36, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-37","node-38","node-39","node-33","node-0", "node-18"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-39", Types.nodeId = 39, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-40","node-41","node-42","node-36","node-3", "node-21"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-42", Types.nodeId = 42, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-43","node-44","node-45","node-39","node-6", "node-24"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-45", Types.nodeId = 45, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-46","node-47","node-48","node-42","node-9", "node-27"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-48", Types.nodeId = 48, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-49","node-50","node-51","node-45","node-12","node-30"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-51", Types.nodeId = 51, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-1", "node-2", "node-0", "node-48","node-15","node-33"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + -- AP nodes x 17. + , Types.Node {Types.name = "node-1", Types.nodeId = 1, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-2", "node-0", "node-4", "node-49","node-16","node-34"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-4", Types.nodeId = 4, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-5", "node-3", "node-7", "node-1", "node-19","node-37"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-7", Types.nodeId = 7, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-8", "node-6", "node-10","node-4", "node-22","node-40"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-10", Types.nodeId = 10, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-11","node-9", "node-13","node-7", "node-25","node-43"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-13", Types.nodeId = 13, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-14","node-12","node-16","node-10","node-28","node-46"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-16", Types.nodeId = 16, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-17","node-15","node-19","node-13","node-31","node-49"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-19", Types.nodeId = 19, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-20","node-18","node-22","node-16","node-34","node-1" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-22", Types.nodeId = 22, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-23","node-21","node-25","node-19","node-37","node-4" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-25", Types.nodeId = 25, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-26","node-24","node-28","node-22","node-40","node-7" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-28", Types.nodeId = 28, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-29","node-27","node-31","node-25","node-43","node-10"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-31", Types.nodeId = 31, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-32","node-30","node-34","node-28","node-46","node-13"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-34", Types.nodeId = 34, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-35","node-33","node-37","node-31","node-49","node-16"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-37", Types.nodeId = 37, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-38","node-36","node-40","node-34","node-1", "node-19"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-40", Types.nodeId = 40, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-41","node-39","node-43","node-37","node-4", "node-22"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-43", Types.nodeId = 43, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-44","node-42","node-46","node-40","node-7", "node-25"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-46", Types.nodeId = 46, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-47","node-45","node-49","node-43","node-10","node-28"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-49", Types.nodeId = 49, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-50","node-48","node-1", "node-46","node-13","node-31"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + -- US nodes x 17. + , Types.Node {Types.name = "node-2", Types.nodeId = 2, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-0", "node-1", "node-5", "node-50","node-17","node-35"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-5", Types.nodeId = 5, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-3", "node-4", "node-8", "node-2", "node-20","node-38"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-8", Types.nodeId = 8, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-6", "node-7", "node-11","node-5", "node-23","node-41"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-11", Types.nodeId = 11, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-9", "node-10","node-14","node-8", "node-26","node-44"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-14", Types.nodeId = 14, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-12","node-13","node-17","node-11","node-29","node-47"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-17", Types.nodeId = 17, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-15","node-16","node-20","node-14","node-32","node-50"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-20", Types.nodeId = 20, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-18","node-19","node-23","node-17","node-35","node-2" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-23", Types.nodeId = 23, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-21","node-22","node-26","node-20","node-38","node-5" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-26", Types.nodeId = 26, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-24","node-25","node-29","node-23","node-41","node-8" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-29", Types.nodeId = 29, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-27","node-28","node-32","node-26","node-44","node-11"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-32", Types.nodeId = 32, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-30","node-31","node-35","node-29","node-47","node-14"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-35", Types.nodeId = 35, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-33","node-34","node-38","node-32","node-50","node-17"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-38", Types.nodeId = 38, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-36","node-37","node-41","node-35","node-2", "node-20"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-41", Types.nodeId = 41, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-39","node-40","node-44","node-38","node-5", "node-23"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-44", Types.nodeId = 44, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-42","node-43","node-47","node-41","node-8", "node-26"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-47", Types.nodeId = 47, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-45","node-46","node-50","node-44","node-11","node-29"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-50", Types.nodeId = 50, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-48","node-49","node-2", "node-47","node-14","node-32"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + ] +, Types.relayNodes = [ + Types.Node { + Types.name = "explorer" + , Types.nodeId = 52 + , Types.region = Types.AWS Types.EU_CENTRAL_1 + , Types.producers = [ + "node-0", "node-1", "node-2", "node-3", "node-4" + , "node-5", "node-6", "node-7", "node-8", "node-9" + , "node-10","node-11","node-12","node-13","node-14" + , "node-15","node-16","node-17","node-18","node-19" + , "node-20","node-21","node-22","node-23","node-24" + , "node-25","node-26","node-27","node-28","node-29" + , "node-30","node-31","node-32","node-33","node-34" + , "node-35","node-36","node-37","node-38","node-39" + , "node-40","node-41","node-42","node-43","node-44" + , "node-45","node-46","node-47","node-48","node-49" + , "node-50","node-51" + ] + , Types.org = "IOHK" + , Types.pools = Nothing + , Types.stakePool = Nothing + } + ] +} From 5cee2e89aeb628f5fc39140a7940c73e814209ca Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Tue, 28 Nov 2023 19:03:08 +0000 Subject: [PATCH 04/10] wb | use the AWS region when creating the topology --- .../cardano-topology/app/cardano-topology.hs | 12 +++++- .../cardano-topology/data/bench-dense-52.json | 34 ++++++++--------- .../data/ci-test-nomadperf.json | 2 +- .../data/default-nomadperf.json | 4 +- .../Cardano/Benchmarking/Topology/Types.hs | 2 +- bench/cardano-topology/test/Main.hs | 38 +++++++++---------- nix/workbench/backend/nomad-job.nix | 6 ++- nix/workbench/backend/nomad/cloud.sh | 38 ------------------- nix/workbench/profile/prof0-defaults.jq | 2 +- nix/workbench/profile/prof1-variants.jq | 22 +++++------ 10 files changed, 66 insertions(+), 94 deletions(-) diff --git a/bench/cardano-topology/app/cardano-topology.hs b/bench/cardano-topology/app/cardano-topology.hs index 5f59461a4ae..e409a5f9a1e 100644 --- a/bench/cardano-topology/app/cardano-topology.hs +++ b/bench/cardano-topology/app/cardano-topology.hs @@ -37,14 +37,22 @@ main = do -------------------------------------------------------------------------------- --- | Locations have a default AWS region that are the ones cardano-ops is using. +-- | Locations from the CLI are parsed first using the "legacy mode" for +-- backward compatiblity, in this mode locations have a default AWS region that +-- are the ones cardano-ops is using. The new format is either "loopback" or a +-- supported AWS Region. cliLocation :: String -> Either String Topo.Location cliLocation = \case + -- Legacy mode. "LO" -> Right Topo.Loopback "AP" -> Right (Topo.AWS Topo.AP_SOUTHEAST_2) "EU" -> Right (Topo.AWS Topo.EU_CENTRAL_1) "US" -> Right (Topo.AWS Topo.US_EAST_2) - str -> Left $ "Unknown Location: \"" ++ str ++ "\" + -- New format. + str -> Aeson.eitherDecode + -- Make the string JSON valid by enclosing it with quotes. + (LBS.pack $ "\"" ++ str ++ "\"") + cliOpts :: ParserInfo (Topo.CoreNodesParams, FilePath, Maybe FilePath, Bool) cliOpts = info (cliParser <**> helper) diff --git a/bench/cardano-topology/data/bench-dense-52.json b/bench/cardano-topology/data/bench-dense-52.json index 0956047f9fd..557b42c166e 100644 --- a/bench/cardano-topology/data/bench-dense-52.json +++ b/bench/cardano-topology/data/bench-dense-52.json @@ -573,7 +573,7 @@ "node-17", "node-35" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -589,7 +589,7 @@ "node-20", "node-38" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -605,7 +605,7 @@ "node-23", "node-41" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -621,7 +621,7 @@ "node-26", "node-44" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -637,7 +637,7 @@ "node-29", "node-47" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -653,7 +653,7 @@ "node-32", "node-50" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -669,7 +669,7 @@ "node-35", "node-2" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -685,7 +685,7 @@ "node-38", "node-5" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -701,7 +701,7 @@ "node-41", "node-8" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -717,7 +717,7 @@ "node-44", "node-11" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -733,7 +733,7 @@ "node-47", "node-14" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -749,7 +749,7 @@ "node-50", "node-17" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -765,7 +765,7 @@ "node-2", "node-20" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -781,7 +781,7 @@ "node-5", "node-23" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -797,7 +797,7 @@ "node-8", "node-26" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -813,7 +813,7 @@ "node-11", "node-29" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null }, { @@ -829,7 +829,7 @@ "node-14", "node-32" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": null } ], diff --git a/bench/cardano-topology/data/ci-test-nomadperf.json b/bench/cardano-topology/data/ci-test-nomadperf.json index 00ccbb9bc1c..12d693a4344 100644 --- a/bench/cardano-topology/data/ci-test-nomadperf.json +++ b/bench/cardano-topology/data/ci-test-nomadperf.json @@ -19,7 +19,7 @@ "producers": [ "node-0" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": true } ], diff --git a/bench/cardano-topology/data/default-nomadperf.json b/bench/cardano-topology/data/default-nomadperf.json index 96de795d5f0..47920aeb04b 100644 --- a/bench/cardano-topology/data/default-nomadperf.json +++ b/bench/cardano-topology/data/default-nomadperf.json @@ -36,7 +36,7 @@ "node-0", "node-4" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": true }, { @@ -49,7 +49,7 @@ "node-3", "node-1" ], - "region": "us-east-2", + "region": "us-east-1", "stakePool": true }, { diff --git a/bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs b/bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs index fe0d1f74095..be5f9d9ad72 100644 --- a/bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs +++ b/bench/cardano-topology/src/Cardano/Benchmarking/Topology/Types.hs @@ -90,8 +90,8 @@ instance Aeson.ToJSON AWSRegion where instance Aeson.FromJSON AWSRegion where parseJSON = Aeson.withText "AWSRegion" $ \t -> case t of - -- Actually only the ones cardano-ops is using. "ap-southeast-2" -> return AP_SOUTHEAST_2 "eu-central-1" -> return EU_CENTRAL_1 + "us-east-1" -> return US_EAST_1 "us-east-2" -> return US_EAST_2 _ -> fail $ "Unknown AWSRegion: \"" ++ Text.unpack t ++ "\"" diff --git a/bench/cardano-topology/test/Main.hs b/bench/cardano-topology/test/Main.hs index 239dcbeae2d..e704ddaa9ca 100644 --- a/bench/cardano-topology/test/Main.hs +++ b/bench/cardano-topology/test/Main.hs @@ -98,7 +98,7 @@ topology = Tasty.testGroup 2 [ Types.AWS Types.EU_CENTRAL_1 - , Types.AWS Types.US_EAST_2 + , Types.AWS Types.US_EAST_1 , Types.AWS Types.AP_SOUTHEAST_2 ] (\_ -> Just 1) @@ -149,7 +149,7 @@ topology = Tasty.testGroup 6 [ Types.AWS Types.EU_CENTRAL_1 - , Types.AWS Types.US_EAST_2 + , Types.AWS Types.US_EAST_1 , Types.AWS Types.AP_SOUTHEAST_2 ] (\_ -> Just 1) @@ -199,23 +199,23 @@ benchDense52 = Types.Topology { , Types.Node {Types.name = "node-46", Types.nodeId = 46, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-47","node-45","node-49","node-43","node-10","node-28"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} , Types.Node {Types.name = "node-49", Types.nodeId = 49, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-50","node-48","node-1", "node-46","node-13","node-31"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} -- US nodes x 17. - , Types.Node {Types.name = "node-2", Types.nodeId = 2, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-0", "node-1", "node-5", "node-50","node-17","node-35"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-5", Types.nodeId = 5, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-3", "node-4", "node-8", "node-2", "node-20","node-38"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-8", Types.nodeId = 8, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-6", "node-7", "node-11","node-5", "node-23","node-41"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-11", Types.nodeId = 11, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-9", "node-10","node-14","node-8", "node-26","node-44"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-14", Types.nodeId = 14, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-12","node-13","node-17","node-11","node-29","node-47"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-17", Types.nodeId = 17, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-15","node-16","node-20","node-14","node-32","node-50"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-20", Types.nodeId = 20, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-18","node-19","node-23","node-17","node-35","node-2" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-23", Types.nodeId = 23, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-21","node-22","node-26","node-20","node-38","node-5" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-26", Types.nodeId = 26, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-24","node-25","node-29","node-23","node-41","node-8" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-29", Types.nodeId = 29, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-27","node-28","node-32","node-26","node-44","node-11"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-32", Types.nodeId = 32, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-30","node-31","node-35","node-29","node-47","node-14"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-35", Types.nodeId = 35, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-33","node-34","node-38","node-32","node-50","node-17"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-38", Types.nodeId = 38, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-36","node-37","node-41","node-35","node-2", "node-20"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-41", Types.nodeId = 41, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-39","node-40","node-44","node-38","node-5", "node-23"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-44", Types.nodeId = 44, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-42","node-43","node-47","node-41","node-8", "node-26"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-47", Types.nodeId = 47, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-45","node-46","node-50","node-44","node-11","node-29"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-50", Types.nodeId = 50, Types.region = Types.AWS Types.US_EAST_2, Types.producers = ["node-48","node-49","node-2", "node-47","node-14","node-32"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-2", Types.nodeId = 2, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-0", "node-1", "node-5", "node-50","node-17","node-35"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-5", Types.nodeId = 5, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-3", "node-4", "node-8", "node-2", "node-20","node-38"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-8", Types.nodeId = 8, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-6", "node-7", "node-11","node-5", "node-23","node-41"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-11", Types.nodeId = 11, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-9", "node-10","node-14","node-8", "node-26","node-44"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-14", Types.nodeId = 14, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-12","node-13","node-17","node-11","node-29","node-47"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-17", Types.nodeId = 17, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-15","node-16","node-20","node-14","node-32","node-50"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-20", Types.nodeId = 20, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-18","node-19","node-23","node-17","node-35","node-2" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-23", Types.nodeId = 23, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-21","node-22","node-26","node-20","node-38","node-5" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-26", Types.nodeId = 26, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-24","node-25","node-29","node-23","node-41","node-8" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-29", Types.nodeId = 29, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-27","node-28","node-32","node-26","node-44","node-11"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-32", Types.nodeId = 32, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-30","node-31","node-35","node-29","node-47","node-14"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-35", Types.nodeId = 35, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-33","node-34","node-38","node-32","node-50","node-17"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-38", Types.nodeId = 38, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-36","node-37","node-41","node-35","node-2", "node-20"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-41", Types.nodeId = 41, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-39","node-40","node-44","node-38","node-5", "node-23"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-44", Types.nodeId = 44, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-42","node-43","node-47","node-41","node-8", "node-26"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-47", Types.nodeId = 47, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-45","node-46","node-50","node-44","node-11","node-29"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-50", Types.nodeId = 50, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-48","node-49","node-2", "node-47","node-14","node-32"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} ] , Types.relayNodes = [ Types.Node { diff --git a/nix/workbench/backend/nomad-job.nix b/nix/workbench/backend/nomad-job.nix index 576ccbc2248..a3f96ccdad2 100644 --- a/nix/workbench/backend/nomad-job.nix +++ b/nix/workbench/backend/nomad-job.nix @@ -197,8 +197,10 @@ let # A list of datacenters in the region which are eligible for task # placement. This must be provided, and does not have a default. - # SRE: Only 3 Nomad datacenters exist actually. - datacenters = [ "eu-central-1" "us-east-2" "ap-southeast-2" ]; + # What we currently have available: + # - Cardano World cluster: "eu-central-1", "us-east-2" + # - Dedicated P&T cluster: "eu-central-1", "us-east-1", and "ap-southeast-2" + datacenters = [ "ap-southeast-2" "eu-central-1" "us-east-1" "us-east-2" ]; # Specifies user-defined constraints on the task. This can be provided # multiple times to define additional constraints. diff --git a/nix/workbench/backend/nomad/cloud.sh b/nix/workbench/backend/nomad/cloud.sh index 88bef56757c..8c3a7a517fa 100644 --- a/nix/workbench/backend/nomad/cloud.sh +++ b/nix/workbench/backend/nomad/cloud.sh @@ -409,44 +409,6 @@ allocate-run-nomadcloud() { then fatal "Envar \"WB_SHELL_PROFILE\" is empty!" else - ######################################################################## - # Fix for region mismatches ############################################ - ######################################################################## - # If value profile, "value-nomadperf", topology was imported from - # cardano-ops / nixops that was already using "us-east-1", but not - # "default-nomadperf", "ci-test-nomadperf" and "ci-bench" that is generated - # by `cardano-topology` (Haskell project in bench/). - # - Cardano World cluster: "eu-central-1", "us-east-2" - # - Workbench (Nix level): "eu-central-1", "us-east-2", and "ap-southeast-2" - # - Dedicated P&T cluster: "eu-central-1", "us-east-1", and "ap-southeast-2" - if echo "${WB_SHELL_PROFILE}" | grep --quiet "\-nomadperf" - then - jq \ - " \ - .[\"job\"][\"${nomad_job_name}\"][\"datacenters\"] \ - |= \ - [\"eu-central-1\", \"us-east-1\", \"ap-southeast-2\"] \ - " \ - "${dir}"/nomad/nomad-job.json \ - | \ - sponge "${dir}"/nomad/nomad-job.json - # Nix creates a Nomad Job file with affinities taken from node-specs.json - jq \ - " \ - .[\"job\"][\"${nomad_job_name}\"][\"group\"] \ - |= with_entries( \ - if (.value.affinity.value == \"us-east-2\") \ - then \ - (.value.affinity.value |= \"us-east-1\") \ - else \ - (.) \ - end \ - ) \ - " \ - "${dir}"/nomad/nomad-job.json \ - | \ - sponge "${dir}"/nomad/nomad-job.json - fi ############################################################################ # Unique placement: ######################################################## ############################################################################ diff --git a/nix/workbench/profile/prof0-defaults.jq b/nix/workbench/profile/prof0-defaults.jq index f8abc26189a..c0a79eddb0f 100644 --- a/nix/workbench/profile/prof0-defaults.jq +++ b/nix/workbench/profile/prof0-defaults.jq @@ -11,7 +11,7 @@ def era_defaults($era): ## Cluster topology and composition: , composition: - { locations: ["LO"] + { locations: ["loopback"] , n_bft_hosts: 0 , n_singular_hosts: 5 , n_dense_hosts: 1 diff --git a/nix/workbench/profile/prof1-variants.jq b/nix/workbench/profile/prof1-variants.jq index 29a64bf74bb..5753a8fda23 100644 --- a/nix/workbench/profile/prof1-variants.jq +++ b/nix/workbench/profile/prof1-variants.jq @@ -169,30 +169,30 @@ def all_profile_variants: } } as $chainsync_cluster | - # "qa" class Nomad Nodes in ["eu-central-1", "us-east-2"] datacenters + # "qa" class Nodes of Cardano World Nomad cluster { composition: - { locations: ["EU", "US"] + { locations: ["eu-central-1", "us-east-2"] , topology: "torus" , with_explorer: true } } as $nomad_cardano_world_qa | - # nomad_perf using cardano-ops "dense" topology - # Can only be used with the 52 + explorer value profile! + # P&T exclusive Nomad cluster Nodes { composition: - { locations: ["EU", "US", "AP"] - , topology: "dense" + { locations: ["eu-central-1", "us-east-1", "ap-southeast-2"] + , topology: "torus" , with_explorer: true } - } as $nomad_perf_dense + } as $nomad_perf_torus | - # P&T Nomad cluster Nodes in ["eu-central-1", "us-east-2", "ap-southeast-2"] datacenters + # nomad_perf using cardano-ops "dense" topology + # Can only be used with the 52 + explorer value profile! { composition: - { locations: ["EU", "US", "AP"] - , topology: "torus" + { locations: ["eu-central-1", "us-east-1", "ap-southeast-2"] + , topology: "dense" , with_explorer: true } - } as $nomad_perf_torus + } as $nomad_perf_dense | ## ### Definition vocabulary: filtering From 7b6e964f15dce62b428a2c9cd5f72068bc6386c6 Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Fri, 1 Dec 2023 13:25:19 +0000 Subject: [PATCH 05/10] wb | add torus-dense topology --- .../cardano-topology/app/cardano-topology.hs | 30 +- bench/cardano-topology/cardano-topology.cabal | 3 +- .../cardano-topology/data/bench-torus-52.json | 796 ++++++++++++++++++ ...ense-52.json => bench-torus-dense-52.json} | 216 ++--- .../data/ci-test-nomadcwqa.json | 2 +- .../data/ci-test-nomadperf.json | 2 +- .../data/default-nomadcwqa.json | 6 +- .../data/default-nomadperf.json | 6 +- .../src/Cardano/Benchmarking/Topology.hs | 181 +++- bench/cardano-topology/test/Main.hs | 137 +-- nix/workbench/profile/prof1-variants.jq | 2 +- nix/workbench/topology/bench-dense-52.csv | 312 ------- nix/workbench/topology/bench-dense-52.json | 1 - nix/workbench/topology/bench-dense-52.nix | 19 - nix/workbench/topology/topology.sh | 87 +- 15 files changed, 1195 insertions(+), 605 deletions(-) create mode 100644 bench/cardano-topology/data/bench-torus-52.json rename bench/cardano-topology/data/{bench-dense-52.json => bench-torus-dense-52.json} (86%) delete mode 100644 nix/workbench/topology/bench-dense-52.csv delete mode 100644 nix/workbench/topology/bench-dense-52.json delete mode 100644 nix/workbench/topology/bench-dense-52.nix diff --git a/bench/cardano-topology/app/cardano-topology.hs b/bench/cardano-topology/app/cardano-topology.hs index e409a5f9a1e..108371bdd4d 100644 --- a/bench/cardano-topology/app/cardano-topology.hs +++ b/bench/cardano-topology/app/cardano-topology.hs @@ -78,16 +78,6 @@ cliOpts = info (cliParser <**> helper) <> help "Add an explorer to the topology") coreNodesParamsParser = - command "torus" - (info - (Topo.Torus - <$> parseSize - <*> some parseLocation - <*> parseRoleSelector) - (progDesc "Toroidal mesh" - <> fullDesc - <> header "Generate a toroidal mesh topology")) - <> command "line" (info (Topo.Line @@ -107,6 +97,26 @@ cliOpts = info (cliParser <**> helper) (progDesc "Unidirectional circle" <> fullDesc <> header "Generate a unidirectional circle topology")) + <> + command "torus" + (info + (Topo.Torus + <$> parseSize + <*> some parseLocation + <*> parseRoleSelector) + (progDesc "Toroidal mesh" + <> fullDesc + <> header "Generate a toroidal mesh topology")) + <> + command "torus-dense" + (info + (Topo.TorusDense + <$> parseSize + <*> some parseLocation + <*> parseRoleSelector) + (progDesc "Toroidal mesh (dense)" + <> fullDesc + <> header "Generate a toroidal mesh topology (dense)")) parseSize = option auto diff --git a/bench/cardano-topology/cardano-topology.cabal b/bench/cardano-topology/cardano-topology.cabal index 4ce6c7227e1..e6909cefaf6 100644 --- a/bench/cardano-topology/cardano-topology.cabal +++ b/bench/cardano-topology/cardano-topology.cabal @@ -14,7 +14,8 @@ license-files: LICENSE NOTICE build-type: Simple extra-source-files: README.md -data-files: data/bench-dense-52.json +data-files: data/bench-torus-52.json + data/bench-torus-dense-52.json data/ci-test-nomadcwqa.json data/ci-test-nomadperf.json data/ci-test.json diff --git a/bench/cardano-topology/data/bench-torus-52.json b/bench/cardano-topology/data/bench-torus-52.json new file mode 100644 index 00000000000..a8e2ea1cc05 --- /dev/null +++ b/bench/cardano-topology/data/bench-torus-52.json @@ -0,0 +1,796 @@ +{ + "coreNodes": [ + { + "name": "node-0", + "nodeId": 0, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1", + "node-2", + "node-3", + "node-51" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-3", + "nodeId": 3, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-4", + "node-5", + "node-6", + "node-0" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-6", + "nodeId": 6, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-7", + "node-8", + "node-9", + "node-3" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-9", + "nodeId": 9, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-10", + "node-11", + "node-12", + "node-6" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-12", + "nodeId": 12, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-13", + "node-14", + "node-15", + "node-9" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-15", + "nodeId": 15, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-16", + "node-17", + "node-18", + "node-12" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-18", + "nodeId": 18, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-19", + "node-20", + "node-21", + "node-15" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-21", + "nodeId": 21, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-22", + "node-23", + "node-24", + "node-18" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-24", + "nodeId": 24, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-25", + "node-26", + "node-27", + "node-21" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-27", + "nodeId": 27, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-28", + "node-29", + "node-30", + "node-24" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-30", + "nodeId": 30, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-31", + "node-32", + "node-33", + "node-27" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-33", + "nodeId": 33, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-34", + "node-35", + "node-36", + "node-30" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-36", + "nodeId": 36, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-37", + "node-38", + "node-39", + "node-33" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-39", + "nodeId": 39, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-40", + "node-41", + "node-42", + "node-36" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-42", + "nodeId": 42, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-43", + "node-44", + "node-45", + "node-39" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-45", + "nodeId": 45, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-46", + "node-47", + "node-48", + "node-42" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-48", + "nodeId": 48, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-49", + "node-50", + "node-51", + "node-45" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-51", + "nodeId": 51, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-1", + "node-2", + "node-0", + "node-48" + ], + "region": "eu-central-1", + "stakePool": true + }, + { + "name": "node-1", + "nodeId": 1, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-2", + "node-0", + "node-4", + "node-49" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-4", + "nodeId": 4, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-5", + "node-3", + "node-7", + "node-1" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-7", + "nodeId": 7, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-8", + "node-6", + "node-10", + "node-4" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-10", + "nodeId": 10, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-11", + "node-9", + "node-13", + "node-7" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-13", + "nodeId": 13, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-14", + "node-12", + "node-16", + "node-10" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-16", + "nodeId": 16, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-17", + "node-15", + "node-19", + "node-13" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-19", + "nodeId": 19, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-20", + "node-18", + "node-22", + "node-16" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-22", + "nodeId": 22, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-23", + "node-21", + "node-25", + "node-19" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-25", + "nodeId": 25, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-26", + "node-24", + "node-28", + "node-22" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-28", + "nodeId": 28, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-29", + "node-27", + "node-31", + "node-25" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-31", + "nodeId": 31, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-32", + "node-30", + "node-34", + "node-28" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-34", + "nodeId": 34, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-35", + "node-33", + "node-37", + "node-31" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-37", + "nodeId": 37, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-38", + "node-36", + "node-40", + "node-34" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-40", + "nodeId": 40, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-41", + "node-39", + "node-43", + "node-37" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-43", + "nodeId": 43, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-44", + "node-42", + "node-46", + "node-40" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-46", + "nodeId": 46, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-47", + "node-45", + "node-49", + "node-43" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-49", + "nodeId": 49, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-50", + "node-48", + "node-1", + "node-46" + ], + "region": "us-east-1", + "stakePool": true + }, + { + "name": "node-2", + "nodeId": 2, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-0", + "node-1", + "node-5", + "node-50" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-5", + "nodeId": 5, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-3", + "node-4", + "node-8", + "node-2" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-8", + "nodeId": 8, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-6", + "node-7", + "node-11", + "node-5" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-11", + "nodeId": 11, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-9", + "node-10", + "node-14", + "node-8" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-14", + "nodeId": 14, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-12", + "node-13", + "node-17", + "node-11" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-17", + "nodeId": 17, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-15", + "node-16", + "node-20", + "node-14" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-20", + "nodeId": 20, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-18", + "node-19", + "node-23", + "node-17" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-23", + "nodeId": 23, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-21", + "node-22", + "node-26", + "node-20" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-26", + "nodeId": 26, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-24", + "node-25", + "node-29", + "node-23" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-29", + "nodeId": 29, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-27", + "node-28", + "node-32", + "node-26" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-32", + "nodeId": 32, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-30", + "node-31", + "node-35", + "node-29" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-35", + "nodeId": 35, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-33", + "node-34", + "node-38", + "node-32" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-38", + "nodeId": 38, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-36", + "node-37", + "node-41", + "node-35" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-41", + "nodeId": 41, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-39", + "node-40", + "node-44", + "node-38" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-44", + "nodeId": 44, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-42", + "node-43", + "node-47", + "node-41" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-47", + "nodeId": 47, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-45", + "node-46", + "node-50", + "node-44" + ], + "region": "ap-southeast-2", + "stakePool": true + }, + { + "name": "node-50", + "nodeId": 50, + "org": "IOHK", + "pools": 1, + "producers": [ + "node-48", + "node-49", + "node-2", + "node-47" + ], + "region": "ap-southeast-2", + "stakePool": true + } + ], + "relayNodes": [ + { + "name": "explorer", + "nodeId": 52, + "org": "IOHK", + "pools": null, + "producers": [ + "node-0", + "node-1", + "node-2", + "node-3", + "node-4", + "node-5", + "node-6", + "node-7", + "node-8", + "node-9", + "node-10", + "node-11", + "node-12", + "node-13", + "node-14", + "node-15", + "node-16", + "node-17", + "node-18", + "node-19", + "node-20", + "node-21", + "node-22", + "node-23", + "node-24", + "node-25", + "node-26", + "node-27", + "node-28", + "node-29", + "node-30", + "node-31", + "node-32", + "node-33", + "node-34", + "node-35", + "node-36", + "node-37", + "node-38", + "node-39", + "node-40", + "node-41", + "node-42", + "node-43", + "node-44", + "node-45", + "node-46", + "node-47", + "node-48", + "node-49", + "node-50", + "node-51" + ], + "region": "eu-central-1", + "stakePool": null + } + ] +} diff --git a/bench/cardano-topology/data/bench-dense-52.json b/bench/cardano-topology/data/bench-torus-dense-52.json similarity index 86% rename from bench/cardano-topology/data/bench-dense-52.json rename to bench/cardano-topology/data/bench-torus-dense-52.json index 557b42c166e..a4e4bb80032 100644 --- a/bench/cardano-topology/data/bench-dense-52.json +++ b/bench/cardano-topology/data/bench-torus-dense-52.json @@ -4,7 +4,7 @@ "name": "node-0", "nodeId": 0, "org": "IOHK", - "pools": null, + "pools": 1, "producers": [ "node-1", "node-2", @@ -14,14 +14,13 @@ "node-36" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-3", "nodeId": 3, "org": "IOHK", - "pools": 2, - "stakePool": null, + "pools": 1, "producers": [ "node-4", "node-5", @@ -30,14 +29,14 @@ "node-21", "node-39" ], - "region": "eu-central-1" + "region": "eu-central-1", + "stakePool": true }, { "name": "node-6", "nodeId": 6, "org": "IOHK", - "pools": 2, - "stakePool": null, + "pools": 1, "producers": [ "node-7", "node-8", @@ -46,14 +45,14 @@ "node-24", "node-42" ], - "region": "eu-central-1" + "region": "eu-central-1", + "stakePool": true }, { "name": "node-9", "nodeId": 9, "org": "IOHK", - "pools": 2, - "stakePool": null, + "pools": 1, "producers": [ "node-10", "node-11", @@ -62,13 +61,14 @@ "node-27", "node-45" ], - "region": "eu-central-1" + "region": "eu-central-1", + "stakePool": true }, { "name": "node-12", "nodeId": 12, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-13", "node-14", @@ -78,13 +78,13 @@ "node-48" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-15", "nodeId": 15, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-16", "node-17", @@ -94,13 +94,13 @@ "node-51" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-18", "nodeId": 18, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-19", "node-20", @@ -110,13 +110,13 @@ "node-0" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-21", "nodeId": 21, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-22", "node-23", @@ -126,13 +126,13 @@ "node-3" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-24", "nodeId": 24, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-25", "node-26", @@ -142,13 +142,13 @@ "node-6" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-27", "nodeId": 27, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-28", "node-29", @@ -158,13 +158,13 @@ "node-9" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-30", "nodeId": 30, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-31", "node-32", @@ -174,13 +174,13 @@ "node-12" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-33", "nodeId": 33, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-34", "node-35", @@ -190,13 +190,13 @@ "node-15" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-36", "nodeId": 36, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-37", "node-38", @@ -206,13 +206,13 @@ "node-18" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-39", "nodeId": 39, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-40", "node-41", @@ -222,13 +222,13 @@ "node-21" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-42", "nodeId": 42, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-43", "node-44", @@ -238,13 +238,13 @@ "node-24" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-45", "nodeId": 45, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-46", "node-47", @@ -254,13 +254,13 @@ "node-27" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-48", "nodeId": 48, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-49", "node-50", @@ -270,13 +270,13 @@ "node-30" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-51", "nodeId": 51, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-1", "node-2", @@ -286,7 +286,7 @@ "node-33" ], "region": "eu-central-1", - "stakePool": null + "stakePool": true }, { "name": "node-1", @@ -302,13 +302,13 @@ "node-34" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-4", "nodeId": 4, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-5", "node-3", @@ -318,13 +318,13 @@ "node-37" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-7", "nodeId": 7, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-8", "node-6", @@ -334,13 +334,13 @@ "node-40" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-10", "nodeId": 10, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-11", "node-9", @@ -350,13 +350,13 @@ "node-43" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-13", "nodeId": 13, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-14", "node-12", @@ -366,13 +366,13 @@ "node-46" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-16", "nodeId": 16, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-17", "node-15", @@ -382,13 +382,13 @@ "node-49" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-19", "nodeId": 19, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-20", "node-18", @@ -398,13 +398,13 @@ "node-1" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-22", "nodeId": 22, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-23", "node-21", @@ -414,13 +414,13 @@ "node-4" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-25", "nodeId": 25, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-26", "node-24", @@ -430,13 +430,13 @@ "node-7" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-28", "nodeId": 28, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-29", "node-27", @@ -446,13 +446,13 @@ "node-10" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-31", "nodeId": 31, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-32", "node-30", @@ -462,13 +462,13 @@ "node-13" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-34", "nodeId": 34, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-35", "node-33", @@ -478,13 +478,13 @@ "node-16" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-37", "nodeId": 37, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-38", "node-36", @@ -494,13 +494,13 @@ "node-19" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-40", "nodeId": 40, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-41", "node-39", @@ -510,13 +510,13 @@ "node-22" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-43", "nodeId": 43, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-44", "node-42", @@ -526,13 +526,13 @@ "node-25" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-46", "nodeId": 46, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-47", "node-45", @@ -542,13 +542,13 @@ "node-28" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-49", "nodeId": 49, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-50", "node-48", @@ -558,13 +558,13 @@ "node-31" ], "region": "ap-southeast-2", - "stakePool": null + "stakePool": true }, { "name": "node-2", "nodeId": 2, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-0", "node-1", @@ -574,13 +574,13 @@ "node-35" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-5", "nodeId": 5, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-3", "node-4", @@ -590,13 +590,13 @@ "node-38" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-8", "nodeId": 8, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-6", "node-7", @@ -606,13 +606,13 @@ "node-41" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-11", "nodeId": 11, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-9", "node-10", @@ -622,13 +622,13 @@ "node-44" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-14", "nodeId": 14, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-12", "node-13", @@ -638,13 +638,13 @@ "node-47" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-17", "nodeId": 17, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-15", "node-16", @@ -654,13 +654,13 @@ "node-50" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-20", "nodeId": 20, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-18", "node-19", @@ -670,13 +670,13 @@ "node-2" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-23", "nodeId": 23, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-21", "node-22", @@ -686,13 +686,13 @@ "node-5" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-26", "nodeId": 26, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-24", "node-25", @@ -702,13 +702,13 @@ "node-8" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-29", "nodeId": 29, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-27", "node-28", @@ -718,13 +718,13 @@ "node-11" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-32", "nodeId": 32, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-30", "node-31", @@ -734,13 +734,13 @@ "node-14" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-35", "nodeId": 35, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-33", "node-34", @@ -750,13 +750,13 @@ "node-17" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-38", "nodeId": 38, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-36", "node-37", @@ -766,13 +766,13 @@ "node-20" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-41", "nodeId": 41, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-39", "node-40", @@ -782,13 +782,13 @@ "node-23" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-44", "nodeId": 44, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-42", "node-43", @@ -798,13 +798,13 @@ "node-26" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-47", "nodeId": 47, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-45", "node-46", @@ -814,13 +814,13 @@ "node-29" ], "region": "us-east-1", - "stakePool": null + "stakePool": true }, { "name": "node-50", "nodeId": 50, "org": "IOHK", - "pools": 2, + "pools": 1, "producers": [ "node-48", "node-49", @@ -830,7 +830,7 @@ "node-32" ], "region": "us-east-1", - "stakePool": null + "stakePool": true } ], "relayNodes": [ @@ -838,6 +838,7 @@ "name": "explorer", "nodeId": 52, "org": "IOHK", + "pools": null, "producers": [ "node-0", "node-1", @@ -892,7 +893,8 @@ "node-50", "node-51" ], - "region": "eu-central-1" + "region": "eu-central-1", + "stakePool": null } ] } diff --git a/bench/cardano-topology/data/ci-test-nomadcwqa.json b/bench/cardano-topology/data/ci-test-nomadcwqa.json index 00ccbb9bc1c..d3a696a41ba 100644 --- a/bench/cardano-topology/data/ci-test-nomadcwqa.json +++ b/bench/cardano-topology/data/ci-test-nomadcwqa.json @@ -34,7 +34,7 @@ "node-1" ], "region": "eu-central-1", - "stakePool": false + "stakePool": null } ] } diff --git a/bench/cardano-topology/data/ci-test-nomadperf.json b/bench/cardano-topology/data/ci-test-nomadperf.json index 12d693a4344..94135968f13 100644 --- a/bench/cardano-topology/data/ci-test-nomadperf.json +++ b/bench/cardano-topology/data/ci-test-nomadperf.json @@ -34,7 +34,7 @@ "node-1" ], "region": "eu-central-1", - "stakePool": false + "stakePool": null } ] } diff --git a/bench/cardano-topology/data/default-nomadcwqa.json b/bench/cardano-topology/data/default-nomadcwqa.json index 8d9344e5286..564020644ec 100644 --- a/bench/cardano-topology/data/default-nomadcwqa.json +++ b/bench/cardano-topology/data/default-nomadcwqa.json @@ -87,14 +87,14 @@ "pools": null, "producers": [ "node-0", - "node-2", - "node-4", "node-1", + "node-2", "node-3", + "node-4", "node-5" ], "region": "eu-central-1", - "stakePool": false + "stakePool": null } ] } diff --git a/bench/cardano-topology/data/default-nomadperf.json b/bench/cardano-topology/data/default-nomadperf.json index 47920aeb04b..986cb7c1fcb 100644 --- a/bench/cardano-topology/data/default-nomadperf.json +++ b/bench/cardano-topology/data/default-nomadperf.json @@ -87,14 +87,14 @@ "pools": null, "producers": [ "node-0", - "node-3", "node-1", - "node-4", "node-2", + "node-3", + "node-4", "node-5" ], "region": "eu-central-1", - "stakePool": false + "stakePool": null } ] } diff --git a/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs b/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs index 2f04832a90f..d6e56990fa7 100644 --- a/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs +++ b/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs @@ -15,14 +15,14 @@ module Cardano.Benchmarking.Topology ( import Prelude hiding (id) import Data.Function ((&)) -import Data.List (tails) +import Data.List (tails, sortOn) import Data.Maybe (isJust) import qualified Cardano.Benchmarking.Topology.Types as Types -------------------------------------------------------------------------------- --- | Three types of topologies for the core nodes. +-- | Four types of topologies for the core nodes. data CoreNodesParams -- FIXME: Currently not used ??? = Line @@ -40,6 +40,11 @@ data CoreNodesParams , tpLocations :: [Types.Location] -- ^ Locations to use. , tpIdPools :: Int -> Maybe Int -- ^ Node i pool number. } + | TorusDense + { tpSize :: Int -- ^ Number of nodes to use. + , tpLocations :: [Types.Location] -- ^ Locations to use. + , tpIdPools :: Int -> Maybe Int -- ^ Node i pool number. + } -------------------------------------------------------------------------------- @@ -63,10 +68,11 @@ mkExplorer explorerLocation coreNodes = name = "explorer" , nodeId = length coreNodes , region = explorerLocation - , producers = map Types.name coreNodes + -- Explorer producers sorted by numeric id, not region or something else. + , producers = map Types.name (sortOn Types.nodeId coreNodes) , org = "IOHK" , pools = Nothing - , stakePool = Just False + , stakePool = Nothing }) -------------------------------------------------------------------------------- @@ -83,6 +89,7 @@ data Spec = Spec idName :: Int -> String idName = ("node-" <>) . show +-- | Create a node from Spec adding the default values. mkNode :: Spec -> Types.Node mkNode Spec{..} = Types.Node{..} where name = idName nodeId @@ -95,23 +102,25 @@ mkNode Spec{..} = Types.Node{..} where mkCoreNodes' :: CoreNodesParams -> [Spec] mkCoreNodes' Line{..} = breakLoop tpSize phase1 where + -- Nodes' ids starting from zero. specIds = [0..(tpSize - 1)] - -- Assign locations and pool counts; set initial links. + -- Assign each node the location, an empty links list and pool count. phase0 = mkInitial <$> specIds where mkInitial :: Int -> Spec mkInitial id = Spec { - links = [] - , mpools = tpIdPools id - , loc = tpLocation - , .. + links = [] + , mpools = tpIdPools id + , loc = tpLocation + , .. } - -- Connect into a ring + -- Connect into a ring with bidirectional = true phase1 = intraConnectRing False True phase0 mkCoreNodes' UniCircle{..} = phase1 where + -- Nodes' ids starting from zero. specIds = [0..(tpSize - 1)] - -- Assign locations and pool counts; set initial links. + -- Assign each node the location, an empty links list and pool count. phase0 = mkInitial <$> specIds where mkInitial :: Int -> Spec @@ -122,31 +131,78 @@ mkCoreNodes' UniCircle{..} = phase1 where , loc = tpLocation , .. } - -- Connect into a ring + -- Connect into a ring with bidirectional = false phase1 = intraConnectRing False False phase0 -mkCoreNodes' Torus{..} = concat phase3 where - specIds = [0..(tpSize - 1)] - specLocs = take tpSize $ cycle tpLocations - -- Assign locations and pool counts; set initial links. +mkCoreNodes' Torus{..} = mkCoreNodesTorus tpSize tpLocations tpIdPools False +-- The dense Torus, with each node having 4 intra-region connections, needs +-- a minimun of nodes. +mkCoreNodes' TorusDense{..} = mkCoreNodesTorus tpSize tpLocations tpIdPools True + +mkCoreNodesTorus ::Int -> [Types.Location] -> (Int -> Maybe Int) -> Bool -> [Spec] +mkCoreNodesTorus tpSize' tpLocations' tpIdPools' dense = concat phase3 where + -- Nodes' ids starting from zero. + -- For the usual torus/dense topology it returns: + -- [ 0, 1, 2,.., 51 ] + specIds = [0..(tpSize' - 1)] + -- A list of repeating locations (in the same order). + -- For the usual torus/dense topology it returns: + -- [ "eu", "us", "ap", "eu", "us", "ap" .. "eu" ] + specLocs = take tpSize' $ cycle tpLocations' + -- Orderly (zip) assign the locations, an empty links list and pool count. + -- For the usual torus/dense topology it returns: + -- [ + -- ( 0,"eu"), ( 1,"us"), ( 2,"ap"), + -- .. + -- (45,"eu"), (46,"us"), (47,"ap"), + -- (48,"eu"), (49,"us"), (50,"ap"), (51,"eu") + -- ] phase0 = zipWith mkInitial specIds specLocs where mkInitial :: Int -> Types.Location -> Spec mkInitial id loc = Spec { links = [] - , mpools = tpIdPools id + , mpools = tpIdPools' id , .. } - -- Split into per-location lists. + -- Split into per-location lists (list of lists). + -- For the usual torus/dense topology it returns: + -- [ + -- [ (0,"eu"), (3,"eu"), .. (48,"eu"), (51,"eu") ] + -- [ (1,"us"), (4,"us"), .. (49,"us") ] + -- [ (2,"ap"), (5,"ap"), .. (50,"ap") ] + -- ] phase1 = - [ - filter ((== l) . loc) phase0 - | l <- tpLocations - ] - & - filter (not . null) - -- Establish intra-location connections. - phase2 = intraConnectRing (tpSize < 6) True <$> phase1 + [ + filter ((== l) . loc) phase0 + | l <- tpLocations' + ] + & + filter (not . null) + -- Establish intra-location connections for every location list. + -- For the usual torus topology: it first adds a connection to the + -- inmmediate next same-region node and one to the inmmediate previous + -- same-region node. + -- [ + -- Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51]} + -- , Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0]} + -- , Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3]} + -- ... + -- , Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42]} + -- , Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45]} + -- , Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48]} + -- ] + -- For the dense version of the Torus it add two more intra links: + -- [ + -- Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51,18,36]} + -- , Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0,21,39]} + -- , Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3,24,42]} + -- ... + -- , Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42, 9,27]} + -- , Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45,12,30]} + -- , Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48,15,33]} + -- ] + phase2 = intraConnectRing dense True <$> phase1 -- Establish inter-location connections. phase3 = if length phase2 > 1 then interConnect phase2 @@ -160,9 +216,9 @@ mkCoreNodes' Torus{..} = concat phase3 where where nlocs = length xss linker (xs:xss') = - [ x { links = ids <> links x } - | (x, i) <- zip xs [0..] - , let ids = idOf i <$> rings + [ x { links = ids <> links x } + | (x, i) <- zip xs [0..] + , let ids = idOf i <$> rings ] where rings = take (nlocs - 1) $ cycle <$> xss' @@ -177,19 +233,78 @@ breakLoop tpSize filterLinks :: (Int -> Bool) -> Spec -> Spec filterLinks f s@Spec{..} = s { links = filter f links } +{-- Examples: + +intraConnectRing False False $ +> map + (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) + [0,3..51] +[ + Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3]} +, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6]} +, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9]} +... +, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48]} +, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51]} +, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0]} +] + +intraConnectRing False True $ +> map + (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) + [0,3..51] +[ + Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51]} +, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0]} +, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3]} +... +, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42]} +, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45]} +, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48]} +] + +intraConnectRing True False $ +> map + (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) + [0,3..51] +[ + Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3]} +, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6]} +, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9]} +... +, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48]} +, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51]} +, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0]} +] + +intraConnectRing True True $ +> map + (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) + [0,3..51] +[ + Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51,18,36]} +, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0,21,39]} +, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3,24,42]} +... +, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42, 9,27]} +, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45,12,30]} +, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48,15,33]} +] + +--} intraConnectRing :: Bool -> Bool -> [Spec] -> [Spec] intraConnectRing withChords bidirectional specs = case len of 0 -> [] 1 -> specs - 2 -> connect 1 - specs + 2 -> connect 1 specs _ -> connect 1 -- next $ if not bidirectional then specs else connect (len - 1) -- prev $ if not withChords then specs + -- Add two more intra-region connections. else connect (len `div` 3) -- chord 1 $ if len < 9 then specs @@ -198,9 +313,7 @@ intraConnectRing withChords bidirectional specs = where len = length specs connect :: Int -> [Spec] -> [Spec] - connect offt xs = - take (length xs) $ - fmap linker (tails ring) + connect offt xs = take (length xs) $ fmap linker (tails ring) where linker (x:xs') = x { links = idOf (offt - 1) xs' : links x } diff --git a/bench/cardano-topology/test/Main.hs b/bench/cardano-topology/test/Main.hs index e704ddaa9ca..373586d97fb 100644 --- a/bench/cardano-topology/test/Main.hs +++ b/bench/cardano-topology/test/Main.hs @@ -29,23 +29,22 @@ tests = Tasty.testGroup "cardano-topology" , topology ] - topologyTypes :: Tasty.TestTree topologyTypes = Tasty.testGroup "Cardano.Benchmarking.Topology.Types" [ testCase "Topology FromJson" $ do - fp <- Paths.getDataFileName "data/bench-dense-52.json" + fp <- Paths.getDataFileName "data/bench-torus-dense-52.json" ans <- Aeson.eitherDecodeFileStrict fp assertEqual - "Topology == (decode \"data/bench-dense-52.json\")" - (Right benchDense52) + ("Topology == (decode \"" ++ fp ++ "\")") + (Right benchTorusDense52) ans , testCase "Topology ToJson" $ do - fp <- Paths.getDataFileName "data/bench-dense-52.json" + fp <- Paths.getDataFileName "data/bench-torus-dense-52.json" bsl <- BSL.readFile fp assertEqual ("(encode Topology) == (decode \"" ++ fp ++ "\")") - (Aeson.encode benchDense52) + (Aeson.encode benchTorusDense52) -- Decode-encode the same file so it has the same style. (Aeson.encode $ fromJust (Aeson.decode bsl :: (Maybe Types.Topology)) @@ -156,66 +155,84 @@ topology = Tasty.testGroup ) (Just (Types.AWS Types.EU_CENTRAL_1)) ) + , testCase "value-nomadperf" $ do + fp <- Paths.getDataFileName "data/bench-torus-dense-52.json" + ans <- Aeson.eitherDecodeFileStrict fp + assertEqual + ("TorusDense (value nomadperf) == (decode \"" ++ fp ++ "\")") + ans + (Right $ Topo.mkTopology + (Topo.TorusDense + 52 + [ + Types.AWS Types.EU_CENTRAL_1 + , Types.AWS Types.AP_SOUTHEAST_2 + , Types.AWS Types.US_EAST_1 + ] + (\_ -> Just 1) + ) + (Just (Types.AWS Types.EU_CENTRAL_1)) + ) ] -benchDense52 :: Types.Topology -benchDense52 = Types.Topology { +benchTorusDense52 :: Types.Topology +benchTorusDense52 = Types.Topology { Types.coreNodes = [ -- EU nodes x 18. - Types.Node {Types.name = "node-0", Types.nodeId = 0, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-1", "node-2", "node-3", "node-51","node-18","node-36"], Types.org = "IOHK", Types.pools = Nothing,Types.stakePool = Nothing} - , Types.Node {Types.name = "node-3", Types.nodeId = 3, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-4", "node-5", "node-6", "node-0", "node-21","node-39"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-6", Types.nodeId = 6, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-7", "node-8", "node-9", "node-3", "node-24","node-42"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-9", Types.nodeId = 9, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-10","node-11","node-12","node-6", "node-27","node-45"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-12", Types.nodeId = 12, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-13","node-14","node-15","node-9", "node-30","node-48"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-15", Types.nodeId = 15, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-16","node-17","node-18","node-12","node-33","node-51"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-18", Types.nodeId = 18, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-19","node-20","node-21","node-15","node-36","node-0" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-21", Types.nodeId = 21, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-22","node-23","node-24","node-18","node-39","node-3" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-24", Types.nodeId = 24, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-25","node-26","node-27","node-21","node-42","node-6" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-27", Types.nodeId = 27, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-28","node-29","node-30","node-24","node-45","node-9" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-30", Types.nodeId = 30, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-31","node-32","node-33","node-27","node-48","node-12"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-33", Types.nodeId = 33, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-34","node-35","node-36","node-30","node-51","node-15"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-36", Types.nodeId = 36, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-37","node-38","node-39","node-33","node-0", "node-18"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-39", Types.nodeId = 39, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-40","node-41","node-42","node-36","node-3", "node-21"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-42", Types.nodeId = 42, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-43","node-44","node-45","node-39","node-6", "node-24"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-45", Types.nodeId = 45, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-46","node-47","node-48","node-42","node-9", "node-27"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-48", Types.nodeId = 48, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-49","node-50","node-51","node-45","node-12","node-30"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-51", Types.nodeId = 51, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-1", "node-2", "node-0", "node-48","node-15","node-33"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + Types.Node {Types.name = "node-0", Types.nodeId = 0, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-1", "node-2", "node-3", "node-51","node-18","node-36"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-3", Types.nodeId = 3, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-4", "node-5", "node-6", "node-0", "node-21","node-39"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-6", Types.nodeId = 6, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-7", "node-8", "node-9", "node-3", "node-24","node-42"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-9", Types.nodeId = 9, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-10","node-11","node-12","node-6", "node-27","node-45"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-12", Types.nodeId = 12, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-13","node-14","node-15","node-9", "node-30","node-48"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-15", Types.nodeId = 15, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-16","node-17","node-18","node-12","node-33","node-51"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-18", Types.nodeId = 18, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-19","node-20","node-21","node-15","node-36","node-0" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-21", Types.nodeId = 21, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-22","node-23","node-24","node-18","node-39","node-3" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-24", Types.nodeId = 24, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-25","node-26","node-27","node-21","node-42","node-6" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-27", Types.nodeId = 27, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-28","node-29","node-30","node-24","node-45","node-9" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-30", Types.nodeId = 30, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-31","node-32","node-33","node-27","node-48","node-12"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-33", Types.nodeId = 33, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-34","node-35","node-36","node-30","node-51","node-15"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-36", Types.nodeId = 36, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-37","node-38","node-39","node-33","node-0", "node-18"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-39", Types.nodeId = 39, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-40","node-41","node-42","node-36","node-3", "node-21"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-42", Types.nodeId = 42, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-43","node-44","node-45","node-39","node-6", "node-24"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-45", Types.nodeId = 45, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-46","node-47","node-48","node-42","node-9", "node-27"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-48", Types.nodeId = 48, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-49","node-50","node-51","node-45","node-12","node-30"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-51", Types.nodeId = 51, Types.region = Types.AWS Types.EU_CENTRAL_1, Types.producers = ["node-1", "node-2", "node-0", "node-48","node-15","node-33"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} -- AP nodes x 17. - , Types.Node {Types.name = "node-1", Types.nodeId = 1, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-2", "node-0", "node-4", "node-49","node-16","node-34"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-4", Types.nodeId = 4, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-5", "node-3", "node-7", "node-1", "node-19","node-37"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-7", Types.nodeId = 7, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-8", "node-6", "node-10","node-4", "node-22","node-40"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-10", Types.nodeId = 10, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-11","node-9", "node-13","node-7", "node-25","node-43"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-13", Types.nodeId = 13, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-14","node-12","node-16","node-10","node-28","node-46"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-16", Types.nodeId = 16, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-17","node-15","node-19","node-13","node-31","node-49"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-19", Types.nodeId = 19, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-20","node-18","node-22","node-16","node-34","node-1" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-22", Types.nodeId = 22, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-23","node-21","node-25","node-19","node-37","node-4" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-25", Types.nodeId = 25, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-26","node-24","node-28","node-22","node-40","node-7" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-28", Types.nodeId = 28, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-29","node-27","node-31","node-25","node-43","node-10"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-31", Types.nodeId = 31, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-32","node-30","node-34","node-28","node-46","node-13"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-34", Types.nodeId = 34, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-35","node-33","node-37","node-31","node-49","node-16"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-37", Types.nodeId = 37, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-38","node-36","node-40","node-34","node-1", "node-19"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-40", Types.nodeId = 40, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-41","node-39","node-43","node-37","node-4", "node-22"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-43", Types.nodeId = 43, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-44","node-42","node-46","node-40","node-7", "node-25"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-46", Types.nodeId = 46, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-47","node-45","node-49","node-43","node-10","node-28"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-49", Types.nodeId = 49, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-50","node-48","node-1", "node-46","node-13","node-31"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-1", Types.nodeId = 1, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-2", "node-0", "node-4", "node-49","node-16","node-34"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-4", Types.nodeId = 4, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-5", "node-3", "node-7", "node-1", "node-19","node-37"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-7", Types.nodeId = 7, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-8", "node-6", "node-10","node-4", "node-22","node-40"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-10", Types.nodeId = 10, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-11","node-9", "node-13","node-7", "node-25","node-43"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-13", Types.nodeId = 13, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-14","node-12","node-16","node-10","node-28","node-46"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-16", Types.nodeId = 16, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-17","node-15","node-19","node-13","node-31","node-49"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-19", Types.nodeId = 19, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-20","node-18","node-22","node-16","node-34","node-1" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-22", Types.nodeId = 22, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-23","node-21","node-25","node-19","node-37","node-4" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-25", Types.nodeId = 25, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-26","node-24","node-28","node-22","node-40","node-7" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-28", Types.nodeId = 28, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-29","node-27","node-31","node-25","node-43","node-10"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-31", Types.nodeId = 31, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-32","node-30","node-34","node-28","node-46","node-13"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-34", Types.nodeId = 34, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-35","node-33","node-37","node-31","node-49","node-16"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-37", Types.nodeId = 37, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-38","node-36","node-40","node-34","node-1", "node-19"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-40", Types.nodeId = 40, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-41","node-39","node-43","node-37","node-4", "node-22"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-43", Types.nodeId = 43, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-44","node-42","node-46","node-40","node-7", "node-25"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-46", Types.nodeId = 46, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-47","node-45","node-49","node-43","node-10","node-28"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-49", Types.nodeId = 49, Types.region = Types.AWS Types.AP_SOUTHEAST_2, Types.producers = ["node-50","node-48","node-1", "node-46","node-13","node-31"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} -- US nodes x 17. - , Types.Node {Types.name = "node-2", Types.nodeId = 2, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-0", "node-1", "node-5", "node-50","node-17","node-35"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-5", Types.nodeId = 5, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-3", "node-4", "node-8", "node-2", "node-20","node-38"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-8", Types.nodeId = 8, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-6", "node-7", "node-11","node-5", "node-23","node-41"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-11", Types.nodeId = 11, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-9", "node-10","node-14","node-8", "node-26","node-44"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-14", Types.nodeId = 14, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-12","node-13","node-17","node-11","node-29","node-47"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-17", Types.nodeId = 17, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-15","node-16","node-20","node-14","node-32","node-50"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-20", Types.nodeId = 20, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-18","node-19","node-23","node-17","node-35","node-2" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-23", Types.nodeId = 23, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-21","node-22","node-26","node-20","node-38","node-5" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-26", Types.nodeId = 26, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-24","node-25","node-29","node-23","node-41","node-8" ], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-29", Types.nodeId = 29, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-27","node-28","node-32","node-26","node-44","node-11"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-32", Types.nodeId = 32, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-30","node-31","node-35","node-29","node-47","node-14"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-35", Types.nodeId = 35, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-33","node-34","node-38","node-32","node-50","node-17"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-38", Types.nodeId = 38, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-36","node-37","node-41","node-35","node-2", "node-20"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-41", Types.nodeId = 41, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-39","node-40","node-44","node-38","node-5", "node-23"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-44", Types.nodeId = 44, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-42","node-43","node-47","node-41","node-8", "node-26"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-47", Types.nodeId = 47, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-45","node-46","node-50","node-44","node-11","node-29"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} - , Types.Node {Types.name = "node-50", Types.nodeId = 50, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-48","node-49","node-2", "node-47","node-14","node-32"], Types.org = "IOHK", Types.pools = Just 2, Types.stakePool = Nothing} + , Types.Node {Types.name = "node-2", Types.nodeId = 2, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-0", "node-1", "node-5", "node-50","node-17","node-35"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-5", Types.nodeId = 5, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-3", "node-4", "node-8", "node-2", "node-20","node-38"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-8", Types.nodeId = 8, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-6", "node-7", "node-11","node-5", "node-23","node-41"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-11", Types.nodeId = 11, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-9", "node-10","node-14","node-8", "node-26","node-44"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-14", Types.nodeId = 14, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-12","node-13","node-17","node-11","node-29","node-47"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-17", Types.nodeId = 17, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-15","node-16","node-20","node-14","node-32","node-50"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-20", Types.nodeId = 20, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-18","node-19","node-23","node-17","node-35","node-2" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-23", Types.nodeId = 23, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-21","node-22","node-26","node-20","node-38","node-5" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-26", Types.nodeId = 26, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-24","node-25","node-29","node-23","node-41","node-8" ], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-29", Types.nodeId = 29, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-27","node-28","node-32","node-26","node-44","node-11"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-32", Types.nodeId = 32, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-30","node-31","node-35","node-29","node-47","node-14"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-35", Types.nodeId = 35, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-33","node-34","node-38","node-32","node-50","node-17"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-38", Types.nodeId = 38, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-36","node-37","node-41","node-35","node-2", "node-20"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-41", Types.nodeId = 41, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-39","node-40","node-44","node-38","node-5", "node-23"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-44", Types.nodeId = 44, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-42","node-43","node-47","node-41","node-8", "node-26"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-47", Types.nodeId = 47, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-45","node-46","node-50","node-44","node-11","node-29"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} + , Types.Node {Types.name = "node-50", Types.nodeId = 50, Types.region = Types.AWS Types.US_EAST_1, Types.producers = ["node-48","node-49","node-2", "node-47","node-14","node-32"], Types.org = "IOHK", Types.pools = Just 1, Types.stakePool = Just True} ] , Types.relayNodes = [ Types.Node { diff --git a/nix/workbench/profile/prof1-variants.jq b/nix/workbench/profile/prof1-variants.jq index 5753a8fda23..44e2afe3b92 100644 --- a/nix/workbench/profile/prof1-variants.jq +++ b/nix/workbench/profile/prof1-variants.jq @@ -189,7 +189,7 @@ def all_profile_variants: # Can only be used with the 52 + explorer value profile! { composition: { locations: ["eu-central-1", "us-east-1", "ap-southeast-2"] - , topology: "dense" + , topology: "torus-dense" , with_explorer: true } } as $nomad_perf_dense diff --git a/nix/workbench/topology/bench-dense-52.csv b/nix/workbench/topology/bench-dense-52.csv deleted file mode 100644 index b54dcfd2a57..00000000000 --- a/nix/workbench/topology/bench-dense-52.csv +++ /dev/null @@ -1,312 +0,0 @@ -node-0,eu,node-1,ap -node-0,eu,node-2,us -node-0,eu,node-3,eu -node-0,eu,node-18,eu -node-0,eu,node-36,eu -node-0,eu,node-51,eu -node-1,ap,node-0,eu -node-1,ap,node-2,us -node-1,ap,node-4,ap -node-1,ap,node-16,ap -node-1,ap,node-34,ap -node-1,ap,node-49,ap -node-2,us,node-0,eu -node-2,us,node-1,ap -node-2,us,node-5,us -node-2,us,node-17,us -node-2,us,node-35,us -node-2,us,node-50,us -node-3,eu,node-0,eu -node-3,eu,node-4,ap -node-3,eu,node-5,us -node-3,eu,node-6,eu -node-3,eu,node-21,eu -node-3,eu,node-39,eu -node-4,ap,node-1,ap -node-4,ap,node-3,eu -node-4,ap,node-5,us -node-4,ap,node-7,ap -node-4,ap,node-19,ap -node-4,ap,node-37,ap -node-5,us,node-2,us -node-5,us,node-3,eu -node-5,us,node-4,ap -node-5,us,node-8,us -node-5,us,node-20,us -node-5,us,node-38,us -node-6,eu,node-3,eu -node-6,eu,node-7,ap -node-6,eu,node-8,us -node-6,eu,node-9,eu -node-6,eu,node-24,eu -node-6,eu,node-42,eu -node-7,ap,node-4,ap -node-7,ap,node-6,eu -node-7,ap,node-8,us -node-7,ap,node-10,ap -node-7,ap,node-22,ap -node-7,ap,node-40,ap -node-8,us,node-5,us -node-8,us,node-6,eu -node-8,us,node-7,ap -node-8,us,node-11,us -node-8,us,node-23,us -node-8,us,node-41,us -node-9,eu,node-6,eu -node-9,eu,node-10,ap -node-9,eu,node-11,us -node-9,eu,node-12,eu -node-9,eu,node-27,eu -node-9,eu,node-45,eu -node-10,ap,node-7,ap -node-10,ap,node-9,eu -node-10,ap,node-11,us -node-10,ap,node-13,ap -node-10,ap,node-25,ap -node-10,ap,node-43,ap -node-11,us,node-8,us -node-11,us,node-9,eu -node-11,us,node-10,ap -node-11,us,node-14,us -node-11,us,node-26,us -node-11,us,node-44,us -node-12,eu,node-9,eu -node-12,eu,node-13,ap -node-12,eu,node-14,us -node-12,eu,node-15,eu -node-12,eu,node-30,eu -node-12,eu,node-48,eu -node-13,ap,node-10,ap -node-13,ap,node-12,eu -node-13,ap,node-14,us -node-13,ap,node-16,ap -node-13,ap,node-28,ap -node-13,ap,node-46,ap -node-14,us,node-11,us -node-14,us,node-12,eu -node-14,us,node-13,ap -node-14,us,node-17,us -node-14,us,node-29,us -node-14,us,node-47,us -node-15,eu,node-12,eu -node-15,eu,node-16,ap -node-15,eu,node-17,us -node-15,eu,node-18,eu -node-15,eu,node-33,eu -node-15,eu,node-51,eu -node-16,ap,node-13,ap -node-16,ap,node-15,eu -node-16,ap,node-17,us -node-16,ap,node-19,ap -node-16,ap,node-31,ap -node-16,ap,node-49,ap -node-17,us,node-14,us -node-17,us,node-15,eu -node-17,us,node-16,ap -node-17,us,node-20,us -node-17,us,node-32,us -node-17,us,node-50,us -node-18,eu,node-0,eu -node-18,eu,node-15,eu -node-18,eu,node-19,ap -node-18,eu,node-20,us -node-18,eu,node-21,eu -node-18,eu,node-36,eu -node-19,ap,node-1,ap -node-19,ap,node-16,ap -node-19,ap,node-18,eu -node-19,ap,node-20,us -node-19,ap,node-22,ap -node-19,ap,node-34,ap -node-20,us,node-2,us -node-20,us,node-17,us -node-20,us,node-18,eu -node-20,us,node-19,ap -node-20,us,node-23,us -node-20,us,node-35,us -node-21,eu,node-3,eu -node-21,eu,node-18,eu -node-21,eu,node-22,ap -node-21,eu,node-23,us -node-21,eu,node-24,eu -node-21,eu,node-39,eu -node-22,ap,node-4,ap -node-22,ap,node-19,ap -node-22,ap,node-21,eu -node-22,ap,node-23,us -node-22,ap,node-25,ap -node-22,ap,node-37,ap -node-23,us,node-5,us -node-23,us,node-20,us -node-23,us,node-21,eu -node-23,us,node-22,ap -node-23,us,node-26,us -node-23,us,node-38,us -node-24,eu,node-6,eu -node-24,eu,node-21,eu -node-24,eu,node-25,ap -node-24,eu,node-26,us -node-24,eu,node-27,eu -node-24,eu,node-42,eu -node-25,ap,node-7,ap -node-25,ap,node-22,ap -node-25,ap,node-24,eu -node-25,ap,node-26,us -node-25,ap,node-28,ap -node-25,ap,node-40,ap -node-26,us,node-8,us -node-26,us,node-23,us -node-26,us,node-24,eu -node-26,us,node-25,ap -node-26,us,node-29,us -node-26,us,node-41,us -node-27,eu,node-9,eu -node-27,eu,node-24,eu -node-27,eu,node-28,ap -node-27,eu,node-29,us -node-27,eu,node-30,eu -node-27,eu,node-45,eu -node-28,ap,node-10,ap -node-28,ap,node-25,ap -node-28,ap,node-27,eu -node-28,ap,node-29,us -node-28,ap,node-31,ap -node-28,ap,node-43,ap -node-29,us,node-11,us -node-29,us,node-26,us -node-29,us,node-27,eu -node-29,us,node-28,ap -node-29,us,node-32,us -node-29,us,node-44,us -node-30,eu,node-12,eu -node-30,eu,node-27,eu -node-30,eu,node-31,ap -node-30,eu,node-32,us -node-30,eu,node-33,eu -node-30,eu,node-48,eu -node-31,ap,node-13,ap -node-31,ap,node-28,ap -node-31,ap,node-30,eu -node-31,ap,node-32,us -node-31,ap,node-34,ap -node-31,ap,node-46,ap -node-32,us,node-14,us -node-32,us,node-29,us -node-32,us,node-30,eu -node-32,us,node-31,ap -node-32,us,node-35,us -node-32,us,node-47,us -node-33,eu,node-15,eu -node-33,eu,node-30,eu -node-33,eu,node-34,ap -node-33,eu,node-35,us -node-33,eu,node-36,eu -node-33,eu,node-51,eu -node-34,ap,node-16,ap -node-34,ap,node-31,ap -node-34,ap,node-33,eu -node-34,ap,node-35,us -node-34,ap,node-37,ap -node-34,ap,node-49,ap -node-35,us,node-17,us -node-35,us,node-32,us -node-35,us,node-33,eu -node-35,us,node-34,ap -node-35,us,node-38,us -node-35,us,node-50,us -node-36,eu,node-0,eu -node-36,eu,node-18,eu -node-36,eu,node-33,eu -node-36,eu,node-37,ap -node-36,eu,node-38,us -node-36,eu,node-39,eu -node-37,ap,node-1,ap -node-37,ap,node-19,ap -node-37,ap,node-34,ap -node-37,ap,node-36,eu -node-37,ap,node-38,us -node-37,ap,node-40,ap -node-38,us,node-2,us -node-38,us,node-20,us -node-38,us,node-35,us -node-38,us,node-36,eu -node-38,us,node-37,ap -node-38,us,node-41,us -node-39,eu,node-3,eu -node-39,eu,node-21,eu -node-39,eu,node-36,eu -node-39,eu,node-40,ap -node-39,eu,node-41,us -node-39,eu,node-42,eu -node-40,ap,node-4,ap -node-40,ap,node-22,ap -node-40,ap,node-37,ap -node-40,ap,node-39,eu -node-40,ap,node-41,us -node-40,ap,node-43,ap -node-41,us,node-5,us -node-41,us,node-23,us -node-41,us,node-38,us -node-41,us,node-39,eu -node-41,us,node-40,ap -node-41,us,node-44,us -node-42,eu,node-6,eu -node-42,eu,node-24,eu -node-42,eu,node-39,eu -node-42,eu,node-43,ap -node-42,eu,node-44,us -node-42,eu,node-45,eu -node-43,ap,node-7,ap -node-43,ap,node-25,ap -node-43,ap,node-40,ap -node-43,ap,node-42,eu -node-43,ap,node-44,us -node-43,ap,node-46,ap -node-44,us,node-8,us -node-44,us,node-26,us -node-44,us,node-41,us -node-44,us,node-42,eu -node-44,us,node-43,ap -node-44,us,node-47,us -node-45,eu,node-9,eu -node-45,eu,node-27,eu -node-45,eu,node-42,eu -node-45,eu,node-46,ap -node-45,eu,node-47,us -node-45,eu,node-48,eu -node-46,ap,node-10,ap -node-46,ap,node-28,ap -node-46,ap,node-43,ap -node-46,ap,node-45,eu -node-46,ap,node-47,us -node-46,ap,node-49,ap -node-47,us,node-11,us -node-47,us,node-29,us -node-47,us,node-44,us -node-47,us,node-45,eu -node-47,us,node-46,ap -node-47,us,node-50,us -node-48,eu,node-12,eu -node-48,eu,node-30,eu -node-48,eu,node-45,eu -node-48,eu,node-49,ap -node-48,eu,node-50,us -node-48,eu,node-51,eu -node-49,ap,node-1,ap -node-49,ap,node-13,ap -node-49,ap,node-31,ap -node-49,ap,node-46,ap -node-49,ap,node-48,eu -node-49,ap,node-50,us -node-50,us,node-2,us -node-50,us,node-14,us -node-50,us,node-32,us -node-50,us,node-47,us -node-50,us,node-48,eu -node-50,us,node-49,ap -node-51,eu,node-0,eu -node-51,eu,node-1,ap -node-51,eu,node-2,us -node-51,eu,node-15,eu -node-51,eu,node-33,eu -node-51,eu,node-48,eu diff --git a/nix/workbench/topology/bench-dense-52.json b/nix/workbench/topology/bench-dense-52.json deleted file mode 100644 index e87785f6ec5..00000000000 --- a/nix/workbench/topology/bench-dense-52.json +++ /dev/null @@ -1 +0,0 @@ -{"coreNodes":[{"name":"node-0","nodeId":0,"org":"IOHK","pools":null,"producers":["node-1","node-2","node-3","node-51","node-18","node-36"],"region":"eu-central-1"},{"name":"node-3","nodeId":3,"org":"IOHK","pools":2,"producers":["node-4","node-5","node-6","node-0","node-21","node-39"],"region":"eu-central-1"},{"name":"node-6","nodeId":6,"org":"IOHK","pools":2,"producers":["node-7","node-8","node-9","node-3","node-24","node-42"],"region":"eu-central-1"},{"name":"node-9","nodeId":9,"org":"IOHK","pools":2,"producers":["node-10","node-11","node-12","node-6","node-27","node-45"],"region":"eu-central-1"},{"name":"node-12","nodeId":12,"org":"IOHK","pools":2,"producers":["node-13","node-14","node-15","node-9","node-30","node-48"],"region":"eu-central-1"},{"name":"node-15","nodeId":15,"org":"IOHK","pools":2,"producers":["node-16","node-17","node-18","node-12","node-33","node-51"],"region":"eu-central-1"},{"name":"node-18","nodeId":18,"org":"IOHK","pools":2,"producers":["node-19","node-20","node-21","node-15","node-36","node-0"],"region":"eu-central-1"},{"name":"node-21","nodeId":21,"org":"IOHK","pools":2,"producers":["node-22","node-23","node-24","node-18","node-39","node-3"],"region":"eu-central-1"},{"name":"node-24","nodeId":24,"org":"IOHK","pools":2,"producers":["node-25","node-26","node-27","node-21","node-42","node-6"],"region":"eu-central-1"},{"name":"node-27","nodeId":27,"org":"IOHK","pools":2,"producers":["node-28","node-29","node-30","node-24","node-45","node-9"],"region":"eu-central-1"},{"name":"node-30","nodeId":30,"org":"IOHK","pools":2,"producers":["node-31","node-32","node-33","node-27","node-48","node-12"],"region":"eu-central-1"},{"name":"node-33","nodeId":33,"org":"IOHK","pools":2,"producers":["node-34","node-35","node-36","node-30","node-51","node-15"],"region":"eu-central-1"},{"name":"node-36","nodeId":36,"org":"IOHK","pools":2,"producers":["node-37","node-38","node-39","node-33","node-0","node-18"],"region":"eu-central-1"},{"name":"node-39","nodeId":39,"org":"IOHK","pools":2,"producers":["node-40","node-41","node-42","node-36","node-3","node-21"],"region":"eu-central-1"},{"name":"node-42","nodeId":42,"org":"IOHK","pools":2,"producers":["node-43","node-44","node-45","node-39","node-6","node-24"],"region":"eu-central-1"},{"name":"node-45","nodeId":45,"org":"IOHK","pools":2,"producers":["node-46","node-47","node-48","node-42","node-9","node-27"],"region":"eu-central-1"},{"name":"node-48","nodeId":48,"org":"IOHK","pools":2,"producers":["node-49","node-50","node-51","node-45","node-12","node-30"],"region":"eu-central-1"},{"name":"node-51","nodeId":51,"org":"IOHK","pools":2,"producers":["node-1","node-2","node-0","node-48","node-15","node-33"],"region":"eu-central-1"},{"name":"node-1","nodeId":1,"org":"IOHK","pools":1,"producers":["node-2","node-0","node-4","node-49","node-16","node-34"],"region":"ap-southeast-2"},{"name":"node-4","nodeId":4,"org":"IOHK","pools":2,"producers":["node-5","node-3","node-7","node-1","node-19","node-37"],"region":"ap-southeast-2"},{"name":"node-7","nodeId":7,"org":"IOHK","pools":2,"producers":["node-8","node-6","node-10","node-4","node-22","node-40"],"region":"ap-southeast-2"},{"name":"node-10","nodeId":10,"org":"IOHK","pools":2,"producers":["node-11","node-9","node-13","node-7","node-25","node-43"],"region":"ap-southeast-2"},{"name":"node-13","nodeId":13,"org":"IOHK","pools":2,"producers":["node-14","node-12","node-16","node-10","node-28","node-46"],"region":"ap-southeast-2"},{"name":"node-16","nodeId":16,"org":"IOHK","pools":2,"producers":["node-17","node-15","node-19","node-13","node-31","node-49"],"region":"ap-southeast-2"},{"name":"node-19","nodeId":19,"org":"IOHK","pools":2,"producers":["node-20","node-18","node-22","node-16","node-34","node-1"],"region":"ap-southeast-2"},{"name":"node-22","nodeId":22,"org":"IOHK","pools":2,"producers":["node-23","node-21","node-25","node-19","node-37","node-4"],"region":"ap-southeast-2"},{"name":"node-25","nodeId":25,"org":"IOHK","pools":2,"producers":["node-26","node-24","node-28","node-22","node-40","node-7"],"region":"ap-southeast-2"},{"name":"node-28","nodeId":28,"org":"IOHK","pools":2,"producers":["node-29","node-27","node-31","node-25","node-43","node-10"],"region":"ap-southeast-2"},{"name":"node-31","nodeId":31,"org":"IOHK","pools":2,"producers":["node-32","node-30","node-34","node-28","node-46","node-13"],"region":"ap-southeast-2"},{"name":"node-34","nodeId":34,"org":"IOHK","pools":2,"producers":["node-35","node-33","node-37","node-31","node-49","node-16"],"region":"ap-southeast-2"},{"name":"node-37","nodeId":37,"org":"IOHK","pools":2,"producers":["node-38","node-36","node-40","node-34","node-1","node-19"],"region":"ap-southeast-2"},{"name":"node-40","nodeId":40,"org":"IOHK","pools":2,"producers":["node-41","node-39","node-43","node-37","node-4","node-22"],"region":"ap-southeast-2"},{"name":"node-43","nodeId":43,"org":"IOHK","pools":2,"producers":["node-44","node-42","node-46","node-40","node-7","node-25"],"region":"ap-southeast-2"},{"name":"node-46","nodeId":46,"org":"IOHK","pools":2,"producers":["node-47","node-45","node-49","node-43","node-10","node-28"],"region":"ap-southeast-2"},{"name":"node-49","nodeId":49,"org":"IOHK","pools":2,"producers":["node-50","node-48","node-1","node-46","node-13","node-31"],"region":"ap-southeast-2"},{"name":"node-2","nodeId":2,"org":"IOHK","pools":2,"producers":["node-0","node-1","node-5","node-50","node-17","node-35"],"region":"us-east-1"},{"name":"node-5","nodeId":5,"org":"IOHK","pools":2,"producers":["node-3","node-4","node-8","node-2","node-20","node-38"],"region":"us-east-1"},{"name":"node-8","nodeId":8,"org":"IOHK","pools":2,"producers":["node-6","node-7","node-11","node-5","node-23","node-41"],"region":"us-east-1"},{"name":"node-11","nodeId":11,"org":"IOHK","pools":2,"producers":["node-9","node-10","node-14","node-8","node-26","node-44"],"region":"us-east-1"},{"name":"node-14","nodeId":14,"org":"IOHK","pools":2,"producers":["node-12","node-13","node-17","node-11","node-29","node-47"],"region":"us-east-1"},{"name":"node-17","nodeId":17,"org":"IOHK","pools":2,"producers":["node-15","node-16","node-20","node-14","node-32","node-50"],"region":"us-east-1"},{"name":"node-20","nodeId":20,"org":"IOHK","pools":2,"producers":["node-18","node-19","node-23","node-17","node-35","node-2"],"region":"us-east-1"},{"name":"node-23","nodeId":23,"org":"IOHK","pools":2,"producers":["node-21","node-22","node-26","node-20","node-38","node-5"],"region":"us-east-1"},{"name":"node-26","nodeId":26,"org":"IOHK","pools":2,"producers":["node-24","node-25","node-29","node-23","node-41","node-8"],"region":"us-east-1"},{"name":"node-29","nodeId":29,"org":"IOHK","pools":2,"producers":["node-27","node-28","node-32","node-26","node-44","node-11"],"region":"us-east-1"},{"name":"node-32","nodeId":32,"org":"IOHK","pools":2,"producers":["node-30","node-31","node-35","node-29","node-47","node-14"],"region":"us-east-1"},{"name":"node-35","nodeId":35,"org":"IOHK","pools":2,"producers":["node-33","node-34","node-38","node-32","node-50","node-17"],"region":"us-east-1"},{"name":"node-38","nodeId":38,"org":"IOHK","pools":2,"producers":["node-36","node-37","node-41","node-35","node-2","node-20"],"region":"us-east-1"},{"name":"node-41","nodeId":41,"org":"IOHK","pools":2,"producers":["node-39","node-40","node-44","node-38","node-5","node-23"],"region":"us-east-1"},{"name":"node-44","nodeId":44,"org":"IOHK","pools":2,"producers":["node-42","node-43","node-47","node-41","node-8","node-26"],"region":"us-east-1"},{"name":"node-47","nodeId":47,"org":"IOHK","pools":2,"producers":["node-45","node-46","node-50","node-44","node-11","node-29"],"region":"us-east-1"},{"name":"node-50","nodeId":50,"org":"IOHK","pools":2,"producers":["node-48","node-49","node-2","node-47","node-14","node-32"],"region":"us-east-1"}],"relayNodes":[{"name":"explorer","nodeId":52,"org":"IOHK","producers":["node-0","node-1","node-2","node-3","node-4","node-5","node-6","node-7","node-8","node-9","node-10","node-11","node-12","node-13","node-14","node-15","node-16","node-17","node-18","node-19","node-20","node-21","node-22","node-23","node-24","node-25","node-26","node-27","node-28","node-29","node-30","node-31","node-32","node-33","node-34","node-35","node-36","node-37","node-38","node-39","node-40","node-41","node-42","node-43","node-44","node-45","node-46","node-47","node-48","node-49","node-50","node-51"],"region":"eu-central-1"}]} diff --git a/nix/workbench/topology/bench-dense-52.nix b/nix/workbench/topology/bench-dense-52.nix deleted file mode 100644 index 8968e86f394..00000000000 --- a/nix/workbench/topology/bench-dense-52.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ coreNodes = [ { name = "node-0"; nodeId = 0; org = "IOHK"; pools = null; producers = [ "node-1" "node-2" "node-3" "node-51" "node-18" "node-36" ]; region = "eu-central-1"; } { name = "node-3"; nodeId = 3; org = "IOHK"; pools = 2; producers = [ "node-4" "node-5" "node-6" "node-0" "node-21" "node-39" ]; region = "eu-central-1"; } { name = "node-6"; nodeId = 6; org = "IOHK"; pools = 2; producers = [ "node-7" "node-8" "node-9" "node-3" "node-24" "node-42" ]; region = "eu-central-1"; } { name = "node-9"; nodeId = 9; org = "IOHK"; pools = 2; producers = [ "node-10" "node-11" "node-12" "node-6" "node-27" "node-45" ]; region = "eu-central-1"; } { name = "node-12"; nodeId = 12; org = "IOHK"; pools = 2; producers = [ "node-13" "node-14" "node-15" "node-9" "node-30" "node-48" ]; region = "eu-central-1"; } { name = "node-15"; nodeId = 15; org = "IOHK"; pools = 2; producers = [ "node-16" "node-17" "node-18" "node-12" "node-33" "node-51" ]; region = "eu-central-1"; } { name = "node-18"; nodeId = 18; org = "IOHK"; pools = 2; producers = [ "node-19" "node-20" "node-21" "node-15" "node-36" "node-0" ]; region = "eu-central-1"; } { name = "node-21"; nodeId = 21; org = "IOHK"; pools = 2; producers = [ "node-22" "node-23" "node-24" "node-18" "node-39" "node-3" ]; region = "eu-central-1"; } { name = "node-24"; nodeId = 24; org = "IOHK"; pools = 2; producers = [ "node-25" "node-26" "node-27" "node-21" "node-42" "node-6" ]; region = "eu-central-1"; } { name = "node-27"; nodeId = 27; org = "IOHK"; pools = 2; producers = [ "node-28" "node-29" "node-30" "node-24" "node-45" "node-9" ]; region = "eu-central-1"; } { name = "node-30"; nodeId = 30; org = "IOHK"; pools = 2; producers = [ "node-31" "node-32" "node-33" "node-27" "node-48" "node-12" ]; region = "eu-central-1"; } { name = "node-33"; nodeId = 33; org = "IOHK"; pools = 2; producers = [ "node-34" "node-35" "node-36" "node-30" "node-51" "node-15" ]; region = "eu-central-1"; } { name = "node-36"; nodeId = 36; org = "IOHK"; pools = 2; producers = [ "node-37" "node-38" "node-39" "node-33" "node-0" "node-18" ]; region = "eu-central-1"; } { name = "node-39"; nodeId = 39; org = "IOHK"; pools = 2; producers = [ "node-40" "node-41" "node-42" "node-36" "node-3" "node-21" ]; region = "eu-central-1"; } { name = "node-42"; nodeId = 42; org = "IOHK"; pools = 2; producers = [ "node-43" "node-44" "node-45" "node-39" "node-6" "node-24" ]; region = "eu-central-1"; } { name = "node-45"; nodeId = 45; org = "IOHK"; pools = 2; producers = [ "node-46" "node-47" "node-48" "node-42" "node-9" "node-27" ]; region = "eu-central-1"; } { name = "node-48"; nodeId = 48; org = "IOHK"; pools = 2; producers = [ "node-49" "node-50" "node-51" "node-45" "node-12" "node-30" ]; region = "eu-central-1"; } { name = "node-51"; nodeId = 51; org = "IOHK"; pools = 2; producers = [ "node-1" "node-2" "node-0" "node-48" "node-15" "node-33" ]; region = "eu-central-1"; } { name = "node-1"; nodeId = 1; org = "IOHK"; pools = 1; producers = [ "node-2" "node-0" "node-4" "node-49" "node-16" "node-34" ]; region = "ap-southeast-2"; } { name = "node-4"; nodeId = 4; org = "IOHK"; pools = 2; producers = [ "node-5" "node-3" "node-7" "node-1" "node-19" "node-37" ]; region = "ap-southeast-2"; } { name = "node-7"; nodeId = 7; org = "IOHK"; pools = 2; producers = [ "node-8" "node-6" "node-10" "node-4" "node-22" "node-40" ]; region = "ap-southeast-2"; } { name = "node-10"; nodeId = 10; org = "IOHK"; pools = 2; producers = [ "node-11" "node-9" "node-13" "node-7" "node-25" "node-43" ]; region = "ap-southeast-2"; } { name = "node-13"; nodeId = 13; org = "IOHK"; pools = 2; producers = [ "node-14" "node-12" "node-16" "node-10" "node-28" "node-46" ]; region = "ap-southeast-2"; } { name = "node-16"; nodeId = 16; org = "IOHK"; pools = 2; producers = [ "node-17" "node-15" "node-19" "node-13" "node-31" "node-49" ]; region = "ap-southeast-2"; } { name = "node-19"; nodeId = 19; org = "IOHK"; pools = 2; producers = [ "node-20" "node-18" "node-22" "node-16" "node-34" "node-1" ]; region = "ap-southeast-2"; } { name = "node-22"; nodeId = 22; org = "IOHK"; pools = 2; producers = [ "node-23" "node-21" "node-25" "node-19" "node-37" "node-4" ]; region = "ap-southeast-2"; } { name = "node-25"; nodeId = 25; org = "IOHK"; pools = 2; producers = [ "node-26" "node-24" "node-28" "node-22" "node-40" "node-7" ]; region = "ap-southeast-2"; } { name = "node-28"; nodeId = 28; org = "IOHK"; pools = 2; producers = [ "node-29" "node-27" "node-31" "node-25" "node-43" "node-10" ]; region = "ap-southeast-2"; } { name = "node-31"; nodeId = 31; org = "IOHK"; pools = 2; producers = [ "node-32" "node-30" "node-34" "node-28" "node-46" "node-13" ]; region = "ap-southeast-2"; } { name = "node-34"; nodeId = 34; org = "IOHK"; pools = 2; producers = [ "node-35" "node-33" "node-37" "node-31" "node-49" "node-16" ]; region = "ap-southeast-2"; } { name = "node-37"; nodeId = 37; org = "IOHK"; pools = 2; producers = [ "node-38" "node-36" "node-40" "node-34" "node-1" "node-19" ]; region = "ap-southeast-2"; } { name = "node-40"; nodeId = 40; org = "IOHK"; pools = 2; producers = [ "node-41" "node-39" "node-43" "node-37" "node-4" "node-22" ]; region = "ap-southeast-2"; } { name = "node-43"; nodeId = 43; org = "IOHK"; pools = 2; producers = [ "node-44" "node-42" "node-46" "node-40" "node-7" "node-25" ]; region = "ap-southeast-2"; } { name = "node-46"; nodeId = 46; org = "IOHK"; pools = 2; producers = [ "node-47" "node-45" "node-49" "node-43" "node-10" "node-28" ]; region = "ap-southeast-2"; } { name = "node-49"; nodeId = 49; org = "IOHK"; pools = 2; producers = [ "node-50" "node-48" "node-1" "node-46" "node-13" "node-31" ]; region = "ap-southeast-2"; } { name = "node-2"; nodeId = 2; org = "IOHK"; pools = 2; producers = [ "node-0" "node-1" "node-5" "node-50" "node-17" "node-35" ]; region = "us-east-1"; } { name = "node-5"; nodeId = 5; org = "IOHK"; pools = 2; producers = [ "node-3" "node-4" "node-8" "node-2" "node-20" "node-38" ]; region = "us-east-1"; } { name = "node-8"; nodeId = 8; org = "IOHK"; pools = 2; producers = [ "node-6" "node-7" "node-11" "node-5" "node-23" "node-41" ]; region = "us-east-1"; } { name = "node-11"; nodeId = 11; org = "IOHK"; pools = 2; producers = [ "node-9" "node-10" "node-14" "node-8" "node-26" "node-44" ]; region = "us-east-1"; } { name = "node-14"; nodeId = 14; org = "IOHK"; pools = 2; producers = [ "node-12" "node-13" "node-17" "node-11" "node-29" "node-47" ]; region = "us-east-1"; } { name = "node-17"; nodeId = 17; org = "IOHK"; pools = 2; producers = [ "node-15" "node-16" "node-20" "node-14" "node-32" "node-50" ]; region = "us-east-1"; } { name = "node-20"; nodeId = 20; org = "IOHK"; pools = 2; producers = [ "node-18" "node-19" "node-23" "node-17" "node-35" "node-2" ]; region = "us-east-1"; } { name = "node-23"; nodeId = 23; org = "IOHK"; pools = 2; producers = [ "node-21" "node-22" "node-26" "node-20" "node-38" "node-5" ]; region = "us-east-1"; } { name = "node-26"; nodeId = 26; org = "IOHK"; pools = 2; producers = [ "node-24" "node-25" "node-29" "node-23" "node-41" "node-8" ]; region = "us-east-1"; } { name = "node-29"; nodeId = 29; org = "IOHK"; pools = 2; producers = [ "node-27" "node-28" "node-32" "node-26" "node-44" "node-11" ]; region = "us-east-1"; } { name = "node-32"; nodeId = 32; org = "IOHK"; pools = 2; producers = [ "node-30" "node-31" "node-35" "node-29" "node-47" "node-14" ]; region = "us-east-1"; } { name = "node-35"; nodeId = 35; org = "IOHK"; pools = 2; producers = [ "node-33" "node-34" "node-38" "node-32" "node-50" "node-17" ]; region = "us-east-1"; } { name = "node-38"; nodeId = 38; org = "IOHK"; pools = 2; producers = [ "node-36" "node-37" "node-41" "node-35" "node-2" "node-20" ]; region = "us-east-1"; } { name = "node-41"; nodeId = 41; org = "IOHK"; pools = 2; producers = [ "node-39" "node-40" "node-44" "node-38" "node-5" "node-23" ]; region = "us-east-1"; } { name = "node-44"; nodeId = 44; org = "IOHK"; pools = 2; producers = [ "node-42" "node-43" "node-47" "node-41" "node-8" "node-26" ]; region = "us-east-1"; } { name = "node-47"; nodeId = 47; org = "IOHK"; pools = 2; producers = [ "node-45" "node-46" "node-50" "node-44" "node-11" "node-29" ]; region = "us-east-1"; } { name = "node-50"; nodeId = 50; org = "IOHK"; pools = 2; producers = [ "node-48" "node-49" "node-2" "node-47" "node-14" "node-32" ]; region = "us-east-1"; } ]; - relayNodes = [ - { - name = "explorer"; - nodeId = 52; - org = "IOHK"; - region = "eu-central-1"; - producers = - [ - "node-0" "node-1" "node-2" "node-3" "node-4" "node-5" "node-6" "node-7" "node-8" "node-9" - "node-10" "node-11" "node-12" "node-13" "node-14" "node-15" "node-16" "node-17" "node-18" "node-19" - "node-20" "node-21" "node-22" "node-23" "node-24" "node-25" "node-26" "node-27" "node-28" "node-29" - "node-30" "node-31" "node-32" "node-33" "node-34" "node-35" "node-36" "node-37" "node-38" "node-39" - "node-40" "node-41" "node-42" "node-43" "node-44" "node-45" "node-46" "node-47" "node-48" "node-49" - "node-50" "node-51" - ]; - } - ]; -} diff --git a/nix/workbench/topology/topology.sh b/nix/workbench/topology/topology.sh index 87cb13b2e89..b4c49029c71 100644 --- a/nix/workbench/topology/topology.sh +++ b/nix/workbench/topology/topology.sh @@ -52,59 +52,42 @@ case "${op}" in ## 0. Generate: # - if \ - test "${topology_name}" = "dense" \ - && test "${n_hosts}" = 52 \ - && jqtest .composition.with_explorer "${profile_json}" - then - # If the value profiles's 52 nodes dense topology we just copy it as - # it was imported from cardano-ops when switching to Nomad. - # The other difference is that the .dot file is generated here - # instead of by `cardano-topology`. - progress "topology" "Copying cardano-ops 52 nodes + explorer \"dense\" topology" - cp \ - "$(dirname "$(readlink -f "$0")")"/topology/bench-dense-52.json \ - "${outdir}"/topology.json - topology dot "${outdir}"/topology.json > "${outdir}"/topology.dot - else - mkdir -p "$outdir" - args=( --topology-output "$outdir"/topology.json - --dot-output "$outdir"/topology.dot - "$topology_name" - --size $n_hosts - $(jq '.composition.locations - | map("--loc " + .) - | join(" ") - ' --raw-output "$profile_json") - ) - if jqtest .composition.with_explorer $profile_json - then args+=('--with-explorer') - fi - progress "topology" "cardano-topology ${args[*]}" - cardano-topology "${args[@]}" - # Patch the nixops topology with the density information: - # This is only needed here, the dense topology was already imported - # from nixops / cardano-ops. - jq --slurpfile prof "$profile_json" ' - def nixops_topology_set_pool_density($topo; $density): - $topo * - { coreNodes: - ( .coreNodes - | map - ( . * - { pools: - (if .pools == null then 0 else - if .pools == 1 then 1 else - ([$density, 1] | max) end end) - } - ) - ) - }; - - nixops_topology_set_pool_density(.; $prof[0].dense_pool_density) - ' "$outdir"/topology.json | - sponge "$outdir"/topology.json + mkdir -p "$outdir" + args=( --topology-output "$outdir"/topology.json + --dot-output "$outdir"/topology.dot + "$topology_name" + --size $n_hosts + $(jq '.composition.locations + | map("--loc " + .) + | join(" ") + ' --raw-output "$profile_json") + ) + if jqtest .composition.with_explorer $profile_json + then args+=('--with-explorer') fi + progress "topology" "cardano-topology ${args[*]}" + cardano-topology "${args[@]}" + # Patch the nixops topology with the density information: + # This is only needed here, the dense topology was already imported + # from nixops / cardano-ops. + jq --slurpfile prof "$profile_json" ' + def nixops_topology_set_pool_density($topo; $density): + $topo * + { coreNodes: + ( .coreNodes + | map + ( . * + { pools: + (if .pools == null then 0 else + if .pools == 1 then 1 else + ([$density, 1] | max) end end) + } + ) + ) + }; + nixops_topology_set_pool_density(.; $prof[0].dense_pool_density) + ' "$outdir"/topology.json | + sponge "$outdir"/topology.json ## 1. Render GraphViz topology PDF: # From aee2945dd4c9859b951f2389337fc619b876dd03 Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Mon, 11 Dec 2023 14:53:57 +0000 Subject: [PATCH 06/10] wb | nomad: fix for plutus profiles with 52+1 nodes --- nix/workbench/backend/nomad/cloud.sh | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/nix/workbench/backend/nomad/cloud.sh b/nix/workbench/backend/nomad/cloud.sh index 8c3a7a517fa..85263391f56 100644 --- a/nix/workbench/backend/nomad/cloud.sh +++ b/nix/workbench/backend/nomad/cloud.sh @@ -50,12 +50,9 @@ backend_nomadcloud() { # Called by `run.sh` without exit trap (unlike `scenario_setup_exit_trap`)! start-cluster ) backend_nomad start-cluster "$@" - # If value profile on the dedicated P&T Nomad cluster on AWS extra checks - # to make sure the topology that was deployed is the correct one. - if \ - test "${WB_SHELL_PROFILE:0:15}" = 'value-nomadperf' \ - || \ - test "${WB_SHELL_PROFILE:0:26}" = 'value-oldtracing-nomadperf' + # If value/plutus profile on the dedicated P&T Nomad cluster on AWS extra + # checks to make sure the topology that was deployed is the correct one. + if jqtest '.composition.topology == "torus-dense"' "${dir}"/profile.json then # Show a big warning but let the run continue! check-deployment "${dir}" @@ -637,12 +634,9 @@ allocate-run-nomadcloud() { ######################################################################## # Reproducibility: ##################################################### ######################################################################## - # If value profile on "-nomadperf", using always the same placement! + # If value/plutus profile on "-nomadperf", using always the same placement! # This means node-N always runs on the same Nomad Client/AWS EC2 machine - if \ - test "${WB_SHELL_PROFILE:0:15}" = 'value-nomadperf' \ - || \ - test "${WB_SHELL_PROFILE:0:26}" = 'value-oldtracing-nomadperf' + if jqtest '.composition.topology == "torus-dense"' "${dir}"/profile.json then # A file with all the available Nomad Clients is needed! # This files is a list of Nomad Clients with a minimun of ".id", From c1ba3a090c21ac9c007d8bad2574aba4ad60838c Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Mon, 11 Dec 2023 14:44:29 +0000 Subject: [PATCH 07/10] wb | nomad: fix for check-deployment and helathchecks with P2P --- nix/workbench/backend/nomad-job.nix | 22 +++++++-------------- nix/workbench/backend/nomad.sh | 4 ++-- nix/workbench/backend/nomad/cloud.sh | 2 +- nix/workbench/nomad.sh | 28 +++++++++++++++++++++++++-- nix/workbench/service/healthcheck.nix | 12 +++++++++--- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/nix/workbench/backend/nomad-job.nix b/nix/workbench/backend/nomad-job.nix index a3f96ccdad2..64fd73b0aa8 100644 --- a/nix/workbench/backend/nomad-job.nix +++ b/nix/workbench/backend/nomad-job.nix @@ -342,8 +342,7 @@ let # environment variable that indicates which port your # application should bind to (envar only available for the # ports of current Tasks, not to resolve all port names). - # Names need to be "node#" instead of "node-#" (without "-"). - name = servicePortName; + name = servicePortName; # Cannot be used for envars ("-" to "_"). value = if portNum != null && portNum != 0 then @@ -465,7 +464,7 @@ let # the cluster. Names must adhere to RFC-1123 ยง2.1 and are limited to # alphanumeric and hyphen characters (i.e. [a-z0-9\-]), and be less # than 64 characters in length. - name = servicePortName; + name = servicePortName; # Cannot be used for envars ("-" to "_"). # Specifies a custom address to advertise in Consul or Nomad service # registration. If set, address_mode must be in auto mode. Useful # with interpolation - for example to advertise the public IP @@ -492,7 +491,7 @@ let # - host: Advertise the host port for this service. port must # match a port label specified in the network block. # Here we use "network"->"port"->"name" specified in the Group. - port = servicePortName; + port = servicePortName; # Cannot be used for envars ("-" to "_"). # Checks of type "script" need "consul" instead of "nomad" as # service provider, so as healthcheck we are using a supervisord # "program". @@ -949,7 +948,7 @@ let network_mode = "host"; # This can be used here but not with "exec"! - # All names of the form node#, without the "-", instead of node-# + # These name cannot be used for envars, "-" replaced with "_". ports = [ servicePortName ]; # A list of /container_path strings for tmpfs mount points. See @@ -980,8 +979,8 @@ let "tracer" # taskName # TODO: Which region? {region=null;} # node-spec - # (can't have "-") - "perftracer" # servicePortName + # These name cannot be used for envars, "-" is replaced with "_". + "perf-tracer" # servicePortName 0 # portNum ; } @@ -989,18 +988,11 @@ let ++ (lib.mapAttrsToList (_: nodeSpec: { - /* Nomad randomly changes '-' to '_', so switching all service/ports - # names to '_' - NOMAD_ADDR_node_0=192.168.2.125:30000 - NOMAD_ADDR_node_1=192.168.2.125:30001 - NOMAD_HOST_ADDR_node-0=192.168.2.125:30000 - NOMAD_HOST_ADDR_node-1=192.168.2.125:30001 - */ name = nodeSpec.name; value = valueF nodeSpec.name # taskName nodeSpec # node-spec - # (can't have "-") + # These name cannot be used for envars, "-" is replaced with "_". (nodeSpecToServicePortName nodeSpec) # servicePortName nodeSpec.port # portNum ; diff --git a/nix/workbench/backend/nomad.sh b/nix/workbench/backend/nomad.sh index ad30fc2e8af..43cf4a1e54a 100644 --- a/nix/workbench/backend/nomad.sh +++ b/nix/workbench/backend/nomad.sh @@ -450,12 +450,12 @@ backend_nomad() { do local node_name node_name=$(jq -r "map(select( .i == ${i} ))[0].name" "${dir}"/node-specs.json) - nomad service info -json "perfnode${i}" > "${dir}"/nomad/"${node_name}"/service-info.json & + nomad service info -json "perf-node-${i}" > "${dir}"/nomad/"${node_name}"/service-info.json & jobs_array+=("$!") done if ! test "${one_tracer_per_node}" = "true" then - nomad service info -json "perftracer" > "${dir}"/nomad/tracer/service-info.json & + nomad service info -json "perf-tracer" > "${dir}"/nomad/tracer/service-info.json & jobs_array+=("$!") fi # Wait and check! diff --git a/nix/workbench/backend/nomad/cloud.sh b/nix/workbench/backend/nomad/cloud.sh index 85263391f56..63001e3916d 100644 --- a/nix/workbench/backend/nomad/cloud.sh +++ b/nix/workbench/backend/nomad/cloud.sh @@ -572,7 +572,7 @@ allocate-run-nomadcloud() { # TODO/MAYBE: When not "value" profile, let the explorer run in any node? # resource wise. So more than one "ci-test", "ci-bench", "default" profile # can be run at the same time. This will need some changes to Nomad - # services names (currently all "perfnode#"). + # services names (currently all "perf-node-#" and maybe "perf-tracer"). # WARNING: By always using/placing the explorer node in the only machine # with more memory, we are sure runs do not overlap and no ports, etc are # clashing and interfering with benchmarks results! diff --git a/nix/workbench/nomad.sh b/nix/workbench/nomad.sh index fb2c673b2d2..16416f347b1 100644 --- a/nix/workbench/nomad.sh +++ b/nix/workbench/nomad.sh @@ -2248,9 +2248,33 @@ EOF echo " , \"producers\": [" local node_topology_file_path node_topology_file_path="$(dirname "${job_file}")"/../"${task_name}"/topology.json - # Grab producers from the fetched, after deployment, "topology.json" files + # Grab producers from the fetched, after deployment, "topology.json" files, merging P2P and non-P2P formats. local node_producers - node_producers=$(jq .Producers "${node_topology_file_path}") + # Merge non-P2P and P2P in the same {addr:"ADDR",port:0} format. + # P2P uses "address" instead of "addr" and is: + ### { + ### "localRoots": [ + ### { + ### "accessPoints": [ + ### { + ### "address": "10.0.0.1", + ### "port": 30001 + ### }, + ### { + ### "address": "10.0.0.2", + ### "port": 30002 + ### }, + # non-P2P is: + ### { + ### "Producers": [ + ### { + ### "addr": "10.0.0.1", + ### "port": 30001 + ### }, + node_producers=$(jq \ + '.Producers//[] + ((.localRoots[0].accessPoints//[]) | map({addr:.address,port:.port}))' \ + "${node_topology_file_path}" + ) local node_producers_keys node_producers_keys=$(echo "${node_producers}" | jq --raw-output 'keys | join (" ")') local node_producer_i=0 diff --git a/nix/workbench/service/healthcheck.nix b/nix/workbench/service/healthcheck.nix index 71916342f9b..64a82d55fae 100644 --- a/nix/workbench/service/healthcheck.nix +++ b/nix/workbench/service/healthcheck.nix @@ -215,11 +215,17 @@ let local node=$1 msg "Connectivity using 'cardano-cli ping' of \"''${node}\"'s Producers" local topology_path="../''${node}/topology.json" - local keys=$(${jq}/bin/jq --raw-output '.Producers | keys | join (" ")' "''${topology_path}") + # Merge non-P2P and P2P in the same {addr:"ADDR",port:0} format. + local producers + producers=$(${jq}/bin/jq '.Producers//[] + ((.localRoots[0].accessPoints//[]) | map({addr:.address,port:.port}))' "''${topology_path}") + local keys + keys=$(echo "''${producers}" | ${jq}/bin/jq --raw-output 'keys | join (" ")') for key in ''${keys[*]} do - local host=$(${jq}/bin/jq --raw-output ".Producers[''${key}].addr" "''${topology_path}") - local port=$(${jq}/bin/jq --raw-output ".Producers[''${key}].port" "''${topology_path}") + local host + host=$(echo "''${producers}" | ${jq}/bin/jq --raw-output ".[''${key}].addr") + local port + port=$(echo "''${producers}" | ${jq}/bin/jq --raw-output ".[''${key}].port") msg "Executing 'cardano-cli ping' to \"''${host}:''${port}\"" # If the ping fails the whole script must fail! ${cardano-cli}/bin/cardano-cli ping \ From 37e798078c9342be1a28b34ecde54686113b00dc Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Thu, 4 Jan 2024 14:23:54 +0000 Subject: [PATCH 08/10] wb | fix PIPESTATUS checking and show jq input when healthcheck fails --- nix/workbench/service/healthcheck.nix | 89 +++++++++++++++------------ 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/nix/workbench/service/healthcheck.nix b/nix/workbench/service/healthcheck.nix index 64a82d55fae..923094b3bf5 100644 --- a/nix/workbench/service/healthcheck.nix +++ b/nix/workbench/service/healthcheck.nix @@ -61,8 +61,8 @@ let ${coreutils}/bin/echo "- active_slots_coeff: ''${active_slots_coeff}" ${coreutils}/bin/echo "- active_slots: ''${active_slots}" - # Fetch all node names (Including "explorer" nodes) - ################################################### + # Fetch all defined node names (Including "explorer" nodes) + ########################################################### node_specs_nodes=$(${jq}/bin/jq --raw-output \ "keys | join (\" \")" \ @@ -76,8 +76,8 @@ let ${coreutils}/bin/echo "- Nodes: [''${node_specs_nodes[*]}]" ${coreutils}/bin/echo "- Pools: ''${node_specs_pools}" - # Look for deployed nodes and allocate healthcheck - ################################################## + # Look for locally deployed nodes and allocate healthcheck + ########################################################## nodes=() started_time=$(${coreutils}/bin/date +%s) @@ -140,7 +140,7 @@ let # Start individual nodes' healthchecks ###################################### - # Check that all available nodes are synced and past slot zero! + # Check that locally available nodes are synced and past slot zero! for node in ''${nodes[*]} do # Returns false if not synced and true when synced. @@ -152,10 +152,6 @@ let msg "Node "\"''${node}\"" is now synced!" done - # Ignore PIPE "errors", mixing 'jq', 'tac', 'grep' and/or 'head' - # will evetually throw a PIPE exception (see jq_node_stdout_last). - trap "${coreutils}/bin/echo \"trap PIPE\" >&2" PIPE - # This is an "explorer" node (only one node and generator). # If not an explorer node we don't keep unwanted stuff running! if test "''${#nodes[@]}" = "1" && test "''${nodes[0]}" = "explorer" && test "''${generator}" != "0" @@ -201,12 +197,10 @@ let msg "Done, bye!" fi - trap - PIPE - } ###################################################################### - # Network ############################################################ + # Network functions ################################################## ###################################################################### # TODO: latency_topology_producers "''${node}" @@ -238,7 +232,7 @@ let } ###################################################################### - # Node ############################################################### + # Node functions ##################################################### ###################################################################### function healthcheck_node_synced() { @@ -491,30 +485,40 @@ let # Gets the last "matching" JSON message from a Node's stdout file. # + # TL;DR; # To avoid reading the whole node's "stdout" file its contents are # reversed using `tac` (assuming `tac` is efficient) and piped to # `jq --unbuffered` that uses its "minimal support for I/O" using # 'inputs' to control over when inputs are read in combination with # the null input option '--null-input' to prevent one input from being # read implicitly. - # With all these, we can efficiently select the first occurrence like + # With all these, we can efficiently select the last occurrence like # this: "nth(0; inputs | select( INSERT_BLOCK_QUERY ))" # + # Extras: # Note that the log file is composed of one JSON object per line were # 'inputs' read one by one and we are using `--compact-output` to make # sure every output log message matched by `jq` is contained within a - # line. + # line. Also, the stdout of the node starts with some text that's + # echoed by node's start.sh script that is not valid JSON, so we use + # `grep` to filter only lines matching "{"... }". # - # Also, the stdout of the node starts with some text that's echoed by - # node's start.sh script that is not valid JSON, so we `grep` for - # "{"... }". We still need to check the exit code of these functions - # just in case because if it fails a query may have failed and the - # healthcheck should fail. This is tricky because when 'jq' finishes - # and exists `tac` or `grep` may throw the following error: + # We still need to check the exit code of these functions just in case + # because if it fails a query may have failed and the healthcheck + # should fail. This is tricky because when 'jq' finishes and exists + # `tac` or `grep` may throw the following error: # "writing output failed: Broken pipe" + # (We "want" broken pipe errors, that means that `tac` in combination + # with `grep` and `jq` are working as expected, lazy/efficiently). + # To obtain the `PIPESTATUS` of the whole command we avoid subshells, + # not assigning value directly, and redirect the result to a file. + # + # In case `jq` fails we are using 'fromjson' to get the input supplied + # to `jq` in the error messages for debugging purposes. + # https://github.com/jqlang/jq/issues/996#issuecomment-361778464 # # Finally filter for "null" inputs that are the output of 'nth(0;...)' - # if no occurrence. Return the empty "string" if no value. + # if no occurrence. Returns the empty "string" if no value. # # $1: node name # $2: jq's query string @@ -522,34 +526,37 @@ let local node=$1 local select=$2 local stdout_path="../''${node}/stdout" - local ans return_code=0 pipe_status=(0 0 0 0) - ans="$( \ - { ${coreutils}/bin/tac "''${stdout_path}" 2>/dev/null; } \ + # A file is needed to obtain both the response and PIPESTATUS + local ansfile_path=../''${node}/healthcheck/jq_node_stdout_last + local pipe_status=() + if ! \ + { ${coreutils}/bin/tac "''${stdout_path}" 2>/dev/null ; } \ | \ - { ${grep}/bin/grep -E "^{\".*}$" 2>/dev/null; } \ + { ${grep}/bin/grep --line-buffered --line-regexp "{.*}" 2>/dev/null ; } \ | \ - ${jq}/bin/jq \ - --compact-output \ - --unbuffered \ - --null-input \ - "nth(0; inputs | select(''${select}))" \ + ${jq}/bin/jq \ + --compact-output \ + --unbuffered \ + --null-input \ + --raw-input \ + "nth(0; inputs | \ + try \ + (fromjson | select(''${select})) \ + catch \ + (error(.)) \ + )" \ | \ ${jq}/bin/jq 'select(. != null)' \ - || \ - { return_code="$?"; pipe_status="''${PIPESTATUS[@]}"; } \ - )" - if test "''${return_code}" == 0 + > "''${ansfile_path}" then - ${coreutils}/bin/echo "''${ans}" - else # Ignore "writing output failed: Broken pipe" - if test "''${pipe_status[2]}" != 0 || test "''${pipe_status[3]}" != 0 || test "''${return_code}" != 141 + pipe_status+=("''${PIPESTATUS[@]}") + if test "''${pipe_status[2]}" != 0 || test "''${pipe_status[3]}" != 0 then - exit_22 "jq error: jq_node_stdout_last: ''${node}" - else - ${coreutils}/bin/echo "''${ans}" + exit_22 "unknown error: jq_node_stdout_last: ''${node}: ''${pipe_status[*]}" fi fi + ${coreutils}/bin/cat "''${ansfile_path}" } # This one exists with "write error: Broken pipe" From 960806b0d839ef1a2ed5bc8904dd7e109ac1deaf Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Thu, 11 Jan 2024 14:39:42 +0000 Subject: [PATCH 09/10] wb | nomad: mark token as expired 24 hours earlier --- nix/workbench/nomad.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nix/workbench/nomad.sh b/nix/workbench/nomad.sh index 16416f347b1..d31f45031ab 100644 --- a/nix/workbench/nomad.sh +++ b/nix/workbench/nomad.sh @@ -183,7 +183,9 @@ wb_nomad() { then local expire_time expire_time=$(echo "${token_lookup_response}" | jq -r .data.expire_time) - if test "$(date -u -d "${expire_time}" "+%s")" -ge "$(date -u "+%s")" + # Compare expire date with the actual date minus one day. + # This avoids a token expiring while a profile is running. + if test "$(date -u -d "${expire_time}" "+%s")" -ge "$(($(date -u "+%s") - 86400))" then true else From f1298d4f8b39bb06a7c08b539a85a9ce354d1661 Mon Sep 17 00:00:00 2001 From: Federico Mastellone Date: Fri, 12 Jan 2024 17:17:28 +0000 Subject: [PATCH 10/10] wb | incorporate review feedback and hlint to the original code --- .../cardano-topology/app/cardano-topology.hs | 13 +-- .../src/Cardano/Benchmarking/Topology.hs | 99 ++++++++++--------- 2 files changed, 54 insertions(+), 58 deletions(-) diff --git a/bench/cardano-topology/app/cardano-topology.hs b/bench/cardano-topology/app/cardano-topology.hs index 108371bdd4d..5945f4c1e1b 100644 --- a/bench/cardano-topology/app/cardano-topology.hs +++ b/bench/cardano-topology/app/cardano-topology.hs @@ -10,8 +10,6 @@ import Prelude hiding (id) -import qualified System.IO as IO - import qualified Data.Aeson as Aeson import qualified Data.ByteString.Lazy.Char8 as LBS import qualified Data.GraphViz as G @@ -149,9 +147,7 @@ cliOpts = info (cliParser <**> helper) --- * To JSON topology --- writeTopo :: [Topo.Node] -> [Topo.Node] -> FilePath -> IO () -writeTopo cores relays f = - IO.withFile f IO.WriteMode $ \hnd -> - LBS.hPutStrLn hnd . Aeson.encode $ Topo.Topology cores relays +writeTopo cores relays f = Aeson.encodeFile f (Topo.Topology cores relays) -------------------------------------------------------------------------------- @@ -159,10 +155,9 @@ writeTopo cores relays f = --- writeDot :: [Topo.Node] -> FilePath -> IO () writeDot topo f = - IO.withFile f IO.WriteMode $ \hnd -> - T.hPutStrLn hnd $ - G.renderDot $ G.toDot $ - uncurry (G.graphElemsToDot params) (toGV topo) + T.writeFile f $ + G.renderDot $ G.toDot $ + uncurry (G.graphElemsToDot params) (toGV topo) where params = G.nonClusteredParams { G.globalAttributes = diff --git a/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs b/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs index d6e56990fa7..43d610dd656 100644 --- a/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs +++ b/bench/cardano-topology/src/Cardano/Benchmarking/Topology.hs @@ -15,7 +15,7 @@ module Cardano.Benchmarking.Topology ( import Prelude hiding (id) import Data.Function ((&)) -import Data.List (tails, sortOn) +import Data.List (tails, sortOn, uncons) import Data.Maybe (isJust) import qualified Cardano.Benchmarking.Topology.Types as Types @@ -79,7 +79,7 @@ mkExplorer explorerLocation coreNodes = -- | Intermediate structure to work with Nodes producers by ID instead of name. data Spec = Spec - { id :: Int + { specId :: Int , loc :: Types.Location , mpools :: Maybe Int , links :: [Int] @@ -94,7 +94,7 @@ mkNode :: Spec -> Types.Node mkNode Spec{..} = Types.Node{..} where name = idName nodeId org = "IOHK" - nodeId = id + nodeId = specId pools = mpools stakePool = Just $ isJust mpools region = loc @@ -108,10 +108,10 @@ mkCoreNodes' Line{..} = breakLoop tpSize phase1 where phase0 = mkInitial <$> specIds where mkInitial :: Int -> Spec - mkInitial id = + mkInitial specId = Spec { links = [] - , mpools = tpIdPools id + , mpools = tpIdPools specId , loc = tpLocation , .. } @@ -124,10 +124,10 @@ mkCoreNodes' UniCircle{..} = phase1 where phase0 = mkInitial <$> specIds where mkInitial :: Int -> Spec - mkInitial id = + mkInitial specId = Spec { links = [] - , mpools = tpIdPools id + , mpools = tpIdPools specId , loc = tpLocation , .. } @@ -159,10 +159,10 @@ mkCoreNodesTorus tpSize' tpLocations' tpIdPools' dense = concat phase3 where phase0 = zipWith mkInitial specIds specLocs where mkInitial :: Int -> Types.Location -> Spec - mkInitial id loc = + mkInitial specId loc = Spec { links = [] - , mpools = tpIdPools' id + , mpools = tpIdPools' specId , .. } -- Split into per-location lists (list of lists). @@ -184,23 +184,23 @@ mkCoreNodesTorus tpSize' tpLocations' tpIdPools' dense = concat phase3 where -- inmmediate next same-region node and one to the inmmediate previous -- same-region node. -- [ - -- Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51]} - -- , Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0]} - -- , Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3]} + -- Spec {specId = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51]} + -- , Spec {specId = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0]} + -- , Spec {specId = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3]} -- ... - -- , Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42]} - -- , Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45]} - -- , Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48]} + -- , Spec {specId = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42]} + -- , Spec {specId = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45]} + -- , Spec {specId = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48]} -- ] -- For the dense version of the Torus it add two more intra links: -- [ - -- Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51,18,36]} - -- , Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0,21,39]} - -- , Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3,24,42]} + -- Spec {specId = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51,18,36]} + -- , Spec {specId = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0,21,39]} + -- , Spec {specId = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3,24,42]} -- ... - -- , Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42, 9,27]} - -- , Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45,12,30]} - -- , Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48,15,33]} + -- , Spec {specId = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42, 9,27]} + -- , Spec {specId = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45,12,30]} + -- , Spec {specId = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48,15,33]} -- ] phase2 = intraConnectRing dense True <$> phase1 -- Establish inter-location connections. @@ -222,7 +222,7 @@ mkCoreNodesTorus tpSize' tpLocations' tpIdPools' dense = concat phase3 where ] where rings = take (nlocs - 1) $ cycle <$> xss' - idOf n xs' = id (xs' !! n) + idOf n xs' = specId (xs' !! n) linker [] = error "Invariant failure: empty list of specs" breakLoop :: Int -> [Spec] -> [Spec] @@ -240,13 +240,13 @@ intraConnectRing False False $ (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) [0,3..51] [ - Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3]} -, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6]} -, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9]} + Spec {specId = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3]} +, Spec {specId = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6]} +, Spec {specId = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9]} ... -, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48]} -, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51]} -, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0]} +, Spec {specId = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48]} +, Spec {specId = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51]} +, Spec {specId = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0]} ] intraConnectRing False True $ @@ -254,13 +254,13 @@ intraConnectRing False True $ (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) [0,3..51] [ - Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51]} -, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0]} -, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3]} + Spec {specId = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51]} +, Spec {specId = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0]} +, Spec {specId = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3]} ... -, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42]} -, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45]} -, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48]} +, Spec {specId = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42]} +, Spec {specId = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45]} +, Spec {specId = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48]} ] intraConnectRing True False $ @@ -268,13 +268,13 @@ intraConnectRing True False $ (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) [0,3..51] [ - Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3]} -, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6]} -, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9]} + Spec {specId = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3]} +, Spec {specId = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6]} +, Spec {specId = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9]} ... -, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48]} -, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51]} -, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0]} +, Spec {specId = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48]} +, Spec {specId = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51]} +, Spec {specId = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0]} ] intraConnectRing True True $ @@ -282,13 +282,13 @@ intraConnectRing True True $ (\id' -> Spec id' (Types.AWS Types.EU_CENTRAL_1) Nothing []) [0,3..51] [ - Spec {id = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51,18,36]} -, Spec {id = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0,21,39]} -, Spec {id = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3,24,42]} + Spec {specId = 0, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 3,51,18,36]} +, Spec {specId = 3, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 6, 0,21,39]} +, Spec {specId = 6, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 9, 3,24,42]} ... -, Spec {id = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42, 9,27]} -, Spec {id = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45,12,30]} -, Spec {id = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48,15,33]} +, Spec {specId = 45, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [48,42, 9,27]} +, Spec {specId = 48, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [51,45,12,30]} +, Spec {specId = 51, loc = AWS EU_CENTRAL_1, mpools = Nothing, links = [ 0,48,15,33]} ] --} @@ -319,15 +319,16 @@ intraConnectRing withChords bidirectional specs = : links x } linker [] = error "Invariant failure: empty list of specs" ring = cycle xs - idOf n xs' = id (xs' !! n) + idOf n xs' = specId (xs' !! n) --- * Aux --- -- | Update the first element of a list, if it exists. -- O(1). updateHead :: (a -> a) -> [a] -> [a] -updateHead _ [] = [] -updateHead f (a : as) = f a : as +updateHead f xs = case uncons xs of + Nothing -> [] + Just (x,xs') -> f x:xs' -- | Update the last element of a list, if it exists. -- O(n).