Skip to content

Commit

Permalink
Same system start time for all nodes in the integration test cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
rvl committed Jun 15, 2020
1 parent 1c4c588 commit 5803d9b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 30 deletions.
70 changes: 43 additions & 27 deletions lib/shelley/src/Cardano/Wallet/Shelley/Launch.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ module Cardano.Wallet.Shelley.Launch
withCluster
, withBFTNode
, withStakePool
, NodeConfig (..)
, singleNodeConfig

-- * Utils
, NetworkConfiguration (..)
Expand Down Expand Up @@ -98,7 +100,7 @@ import Data.Text
import Data.Text.Class
( ToText (..) )
import Data.Time.Clock
( getCurrentTime )
( UTCTime, addUTCTime, getCurrentTime )
import GHC.TypeLits
( SomeNat (..), someNatVal )
import Options.Applicative
Expand Down Expand Up @@ -264,8 +266,10 @@ withCluster
-- ^ Action to run with the cluster up
-> IO a
withCluster tr severity n action = bracketTracer' tr "withCluster" $ do
systemStart <- addUTCTime 1 <$> getCurrentTime
ports <- randomUnusedTCPPorts (n + 1)
withBFTNode tr severity (head $ rotate ports) $ \socket block0 params -> do
let bftCfg = NodeConfig severity systemStart (head $ rotate ports)
withBFTNode tr bftCfg $ \socket block0 params -> do
waitForSocket tr socket
waitGroup <- newChan
doneGroup <- newChan
Expand All @@ -284,7 +288,8 @@ withCluster tr severity n action = bracketTracer' tr "withCluster" $ do

forM_ (zip [0..] $ tail $ rotate ports) $ \(idx, (port, peers)) -> do
link =<< async (handle onException $ do
withStakePool tr severity idx (port, peers) $ do
let spCfg = NodeConfig severity systemStart (port, peers)
withStakePool tr idx spCfg $ do
writeChan waitGroup $ Right port
readChan doneGroup)

Expand All @@ -306,23 +311,29 @@ withCluster tr severity n action = bracketTracer' tr "withCluster" $ do
rotate :: Ord a => [a] -> [(a, [a])]
rotate = nub . fmap (\(x:xs) -> (x, sort xs)) . permutations

-- | Configuration parameters which update the @node.config@ test data file.
data NodeConfig = NodeConfig
{ minSeverity :: Severity -- ^ Minimum logging severity
, systemStart :: UTCTime -- ^ Genesis block start time
, nodePeers :: (Int, [Int]) -- ^ A list of ports used by peers and this node
} deriving (Show)

withBFTNode
:: Tracer IO ClusterLog
-- ^ Trace for subprocess control logging
-> Severity
-- ^ Minimal logging severity
-> (Int, [Int])
-- ^ A list of ports used by peers and this pool.
-> NodeConfig
-> (FilePath -> Block -> (NetworkParameters, NodeVersionData) -> IO a)
-- ^ Callback function with genesis parameters
-> IO a
withBFTNode tr severity (port, peers) action = bracketTracer' tr "withBFTNode" $
withBFTNode tr (NodeConfig severity systemStart (port, peers)) action =
bracketTracer' tr "withBFTNode" $
withTempDir tr name $ \dir -> do
[vrfPrv, kesPrv, opCert] <- forM
["node-vrf.skey", "node-kes.skey", "node.opcert"]
(\f -> copyFile (source </> f) (dir </> f) $> (dir </> f))

(config, block0, networkParams, versionData) <- genConfig dir severity
(config, block0, networkParams, versionData)
<- genConfig dir severity systemStart
topology <- genTopology dir peers
let socket = genSocketPath dir

Expand All @@ -346,21 +357,25 @@ withBFTNode tr severity (port, peers) action = bracketTracer' tr "withBFTNode" $

name = "bft-node"

singleNodeConfig :: Severity -> IO NodeConfig
singleNodeConfig severity = do
systemStart <- getCurrentTime
pure $ NodeConfig severity systemStart (0, [])

-- | Populates the configuration directory of a stake pool @cardano-node@. Sets
-- up a transaction which can be used to register the pool.
setupStakePoolData
:: Tracer IO ClusterLog
-> FilePath
-> Severity
-> (Int, [Int])
-> NodeConfig
-> IO (Command, FilePath, FilePath)
setupStakePoolData tr dir severity (port, peers) = do
setupStakePoolData tr dir (NodeConfig severity systemStart (port, peers)) = do
-- Node configuration
(opPrv, opPub, opCount) <- genOperatorKeyPair tr dir
(vrfPrv, vrfPub) <- genVrfKeyPair tr dir
(kesPrv, kesPub) <- genKesKeyPair tr dir
opCert <- issueOpCert tr dir kesPub opPrv opCount
(config, _, _, _) <- genConfig dir severity
(config, _, _, _) <- genConfig dir severity systemStart
topology <- genTopology dir peers

-- Pool registration
Expand Down Expand Up @@ -401,23 +416,22 @@ setupStakePoolData tr dir severity (port, peers) = do
withStakePool
:: Tracer IO ClusterLog
-- ^ Trace for subprocess control logging
-> Severity
-- ^ Minimal logging severity
-> Int
-- ^ Unique stake pool number
-> (Int, [Int])
-- ^ A list of ports used by peers and this pool.
-> NodeConfig
-> IO a
-- ^ Callback function called once the pool has started.
-> IO a
withStakePool tr severity idx (port, peers) action = bracketTracer' tr "withStakePool" $ do
let name = "stake-pool-" ++ show idx
withStakePool tr idx cfg action =
bracketTracer' tr "withStakePool" $
withTempDir tr name $ \dir -> do
(cmd, opPub, tx) <- setupStakePoolData tr dir severity (port, peers)
(cmd, opPub, tx) <- setupStakePoolData tr dir cfg
withCardanoNodeProcess tr name cmd $ do
submitTx tr name tx
timeout 120 ("pool registration", waitUntilRegistered tr name opPub)
action
where
name = "stake-pool-" ++ show idx

withCardanoNodeProcess
:: Tracer IO ClusterLog
Expand All @@ -435,16 +449,18 @@ genConfig
-- ^ A top-level directory where to put the configuration.
-> Severity
-- ^ Minimum severity level for logging
-> UTCTime
-- ^ Genesis block start time
-> IO (FilePath, Block, NetworkParameters, NodeVersionData)
genConfig dir severity = do
genConfig dir severity systemStart = do
-- we need to specify genesis file location every run in tmp
Yaml.decodeFileThrow (source </> "node.config")
>>= withObject (addGenesisFilePath (T.pack nodeGenesisFile))
>>= withObject (addMinSeverity (T.pack $ show severity))
>>= Yaml.encodeFile (dir </> "node.config")

Yaml.decodeFileThrow @_ @Aeson.Value (source </> "genesis.yaml")
>>= withObject updateStartTime
>>= withObject (updateSystemStart systemStart)
>>= Aeson.encodeFile nodeGenesisFile

(genesisData :: ShelleyGenesis TPraosStandardCrypto)
Expand Down Expand Up @@ -834,12 +850,12 @@ oneMillionAda = 1_000_000_000_000

-- | Add a "systemStart" field in a given object with the current POSIX time as a
-- value.
updateStartTime
:: Aeson.Object
updateSystemStart
:: UTCTime
-> Aeson.Object
-> IO Aeson.Object
updateStartTime m = do
time <- getCurrentTime
pure $ HM.insert "systemStart" (toJSON time) m
updateSystemStart systemStart =
pure . HM.insert "systemStart" (toJSON systemStart)

-- | Add a "GenesisFile" field in a given object with the current path of
-- genesis.json in tmp dir as value.
Expand Down
8 changes: 5 additions & 3 deletions lib/shelley/test/unit/Cardano/Wallet/Shelley/NetworkSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Cardano.Wallet.Primitive.Types
import Cardano.Wallet.Shelley.Compatibility
( NodeVersionData )
import Cardano.Wallet.Shelley.Launch
( withBFTNode )
( singleNodeConfig, withBFTNode )
import Cardano.Wallet.Shelley.Network
( NetworkLayerLog (..), withNetworkLayer )
import Control.Retry
Expand Down Expand Up @@ -68,8 +68,10 @@ spec = describe "getTxParameters" $ do
withTestNode
:: (NetworkParameters -> FilePath -> NodeVersionData -> IO a)
-> IO a
withTestNode action = withBFTNode nullTracer Error (0, []) $
\sock _block0 (np, vData) -> action np sock vData
withTestNode action = do
cfg <- singleNodeConfig Error
withBFTNode nullTracer cfg $ \sock _block0 (np, vData) ->
action np sock vData

isMsgProtocolParams :: NetworkLayerLog -> Maybe ProtocolParameters
isMsgProtocolParams (MsgProtocolParameters pp) = Just pp
Expand Down

0 comments on commit 5803d9b

Please sign in to comment.