Skip to content

Commit 8e6d399

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 7c2e364 + 3029579 commit 8e6d399

File tree

15 files changed

+405
-333
lines changed

15 files changed

+405
-333
lines changed

cardano-testnet/src/Cardano/Testnet.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module Cardano.Testnet (
1515
-- * Configuration
1616
Conf(..),
1717
TmpAbsolutePath(..),
18-
YamlFilePath(..),
18+
NodeConfigurationYaml(..),
1919
mkConf,
2020
makeLogDir,
2121
makeSocketDir,

cardano-testnet/src/Parsers/Cardano.hs

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
module Parsers.Cardano
2-
( CardanoOptions(..)
3-
, cmdCardano
2+
( cmdCardano
43
) where
54

65
import Cardano.CLI.Environment
@@ -17,14 +16,13 @@ import Testnet.Process.Cli
1716
import Testnet.Property.Utils
1817
import Testnet.Runtime (readNodeLoggingFormat)
1918
import Testnet.Start.Cardano
19+
import Testnet.Start.Types
2020

21-
newtype CardanoOptions = CardanoOptions
22-
{ testnetOptions :: CardanoTestnetOptions
23-
} deriving (Eq, Show)
2421

2522
optsTestnet :: EnvCli -> Parser CardanoTestnetOptions
2623
optsTestnet envCli = CardanoTestnetOptions
27-
<$> pNumBftAndSpoNodes
24+
-- TODO <$> (OA.many pSpo <|> pNumSpoNodes)
25+
<$> pNumSpoNodes
2826
<*> pLegacyCardanoEra envCli
2927
<*> OA.option auto
3028
( OA.long "epoch-length"
@@ -64,19 +62,41 @@ optsTestnet envCli = CardanoTestnetOptions
6462
<> OA.value (cardanoNodeLoggingFormat cardanoDefaultTestnetOptions)
6563
)
6664

67-
pNumBftAndSpoNodes :: Parser [TestnetNodeOptions]
68-
pNumBftAndSpoNodes =
65+
pNumSpoNodes :: Parser [TestnetNodeOptions]
66+
pNumSpoNodes =
6967
OA.option
70-
((`L.replicate` SpoTestnetNodeOptions []) <$> auto)
71-
( OA.long "num-pool-nodes"
72-
<> OA.help "Number of pool nodes"
73-
<> OA.metavar "COUNT"
74-
<> OA.showDefault
75-
<> OA.value (cardanoNodes cardanoDefaultTestnetOptions)
68+
((`L.replicate` SpoTestnetNodeOptions Nothing []) <$> auto)
69+
( OA.long "num-pool-nodes"
70+
<> OA.help "Number of pool nodes. Note this uses a default node configuration for all nodes."
71+
<> OA.metavar "COUNT"
72+
<> OA.showDefault
73+
<> OA.value (cardanoNodes cardanoDefaultTestnetOptions)
74+
)
75+
76+
77+
_pSpo :: Parser TestnetNodeOptions
78+
_pSpo =
79+
SpoTestnetNodeOptions . Just
80+
<$> parseNodeConfigFile
81+
<*> pure [] -- TODO: Consider adding support for extra args
82+
83+
parseNodeConfigFile :: Parser NodeConfigurationYaml
84+
parseNodeConfigFile = NodeConfigurationYaml <$>
85+
strOption
86+
(mconcat
87+
[ long "configuration-file"
88+
, metavar "NODE-CONFIGURATION"
89+
, help helpText
90+
, completer (bashCompleter "file")
91+
]
7692
)
93+
where
94+
helpText = unwords
95+
[ "Configuration file for the cardano-node(s)."
96+
, "Specify a configuration file per node you want to have in the cluster."
97+
, "Or use num-pool-nodes to use cardano-testnet's default configuration."
98+
]
7799

78-
optsCardano :: EnvCli -> Parser CardanoOptions
79-
optsCardano envCli = CardanoOptions <$> optsTestnet envCli
80100

81-
cmdCardano :: EnvCli -> Mod CommandFields CardanoOptions
82-
cmdCardano envCli = command' "cardano" "Start a testnet in any era" (optsCardano envCli)
101+
cmdCardano :: EnvCli -> Mod CommandFields CardanoTestnetOptions
102+
cmdCardano envCli = command' "cardano" "Start a testnet in any era" (optsTestnet envCli)

cardano-testnet/src/Parsers/Run.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ opts envCli = Opt.info (commands envCli <**> helper) idm
3030
-- by allowing the user to start testnets in any era (excluding Byron)
3131
-- via StartCardanoTestnet
3232
data CardanoTestnetCommands
33-
= StartCardanoTestnet CardanoOptions
33+
= StartCardanoTestnet CardanoTestnetOptions
3434
| GetVersion VersionOptions
3535
| Help ParserPrefs (ParserInfo CardanoTestnetCommands) HelpOptions
3636

@@ -50,6 +50,6 @@ runTestnetCmd = \case
5050
Help pPrefs pInfo cmdOpts -> runHelpOptions pPrefs pInfo cmdOpts
5151

5252

53-
runCardanoOptions :: CardanoOptions -> IO ()
53+
runCardanoOptions :: CardanoTestnetOptions -> IO ()
5454
runCardanoOptions options =
55-
runTestnet $ cardanoTestnet (testnetOptions options)
55+
runTestnet $ cardanoTestnet options

cardano-testnet/src/Testnet/Components/Configuration.hs

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{-# LANGUAGE GADTs #-}
22
{-# LANGUAGE OverloadedStrings #-}
3-
3+
{-# LANGUAGE TypeApplications #-}
44

55
module Testnet.Components.Configuration
66
( createConfigYaml
7+
, createSPOGenesisAndFiles
78
, mkTopologyConfig
89
) where
910

@@ -15,29 +16,40 @@ import Cardano.Node.Types
1516
import Ouroboros.Network.PeerSelection.LedgerPeers
1617
import Ouroboros.Network.PeerSelection.State.LocalRootPeers
1718

19+
import Control.Monad
20+
import Control.Monad.Catch (MonadCatch)
1821
import Control.Monad.IO.Class (MonadIO)
22+
import Data.Aeson
1923
import qualified Data.Aeson as Aeson
2024
import qualified Data.ByteString.Lazy as LBS
25+
import qualified Data.HashMap.Lazy as HM
2126
import qualified Data.List as List
2227
import Data.String
28+
import Data.Time
2329
import GHC.Stack (HasCallStack)
2430
import qualified GHC.Stack as GHC
2531
import System.FilePath.Posix ((</>))
2632

2733
import Hedgehog
34+
import qualified Hedgehog as H
35+
import qualified Hedgehog.Extras.Stock.Aeson as J
36+
import qualified Hedgehog.Extras.Stock.Time as DTC
37+
import qualified Hedgehog.Extras.Test.Base as H
38+
import qualified Hedgehog.Extras.Test.File as H
2839

2940
import Testnet.Defaults
3041
import Testnet.Filepath
42+
import Testnet.Process.Run (execCli_)
3143
import Testnet.Property.Utils
44+
import Testnet.Start.Types
45+
3246

3347
createConfigYaml
3448
:: (MonadTest m, MonadIO m, HasCallStack)
3549
=> TmpAbsolutePath
3650
-> AnyCardanoEra
3751
-> m LBS.ByteString
38-
createConfigYaml tempAbsPath anyCardanoEra' = GHC.withFrozenCallStack $ do
39-
let tempAbsPath' = unTmpAbsPath tempAbsPath
40-
52+
createConfigYaml (TmpAbsolutePath tempAbsPath') anyCardanoEra' = GHC.withFrozenCallStack $ do
4153
-- Add Byron, Shelley and Alonzo genesis hashes to node configuration
4254
-- TODO: These genesis filepaths should not be hardcoded. Using the cli as a library
4355
-- rather as an executable will allow us to get the genesis files paths in a more
@@ -58,6 +70,79 @@ createConfigYaml tempAbsPath anyCardanoEra' = GHC.withFrozenCallStack $ do
5870
]
5971

6072

73+
createSPOGenesisAndFiles
74+
:: (MonadTest m, MonadCatch m, MonadIO m, HasCallStack)
75+
=> CardanoTestnetOptions
76+
-> UTCTime -- ^ Start time
77+
-> TmpAbsolutePath
78+
-> m FilePath -- ^ Shelley genesis directory
79+
createSPOGenesisAndFiles testnetOptions startTime (TmpAbsolutePath tempAbsPath') = do
80+
let testnetMagic = cardanoTestnetMagic testnetOptions
81+
numPoolNodes = length $ cardanoNodes testnetOptions
82+
-- TODO: Even this is cumbersome. You need to know where to put the initial
83+
-- shelley genesis for create-staked to use.
84+
createStakedInitialGenesisFile = tempAbsPath' </> "genesis.spec.json"
85+
86+
-- TODO: We need to read the genesis files into Haskell and modify them
87+
-- based on cardano-testnet's cli parameters
88+
89+
-- We create the initial genesis file to avoid having to re-write the genesis file later
90+
-- with the parameters we want. The user must provide genesis files or we will use a default.
91+
-- We should *never* be modifying the genesis file after cardano-testnet is run because this
92+
-- is sure to be a source of confusion if users provide genesis files and we are mutating them
93+
-- without their knowledge.
94+
let shelleyGenesis :: LBS.ByteString
95+
shelleyGenesis = encode $ defaultShelleyGenesis startTime testnetOptions
96+
97+
H.evalIO $ LBS.writeFile createStakedInitialGenesisFile shelleyGenesis
98+
99+
-- TODO: Remove this rewrite.
100+
-- 50 second epochs
101+
-- Epoch length should be "10 * k / f" where "k = securityParam, f = activeSlotsCoeff"
102+
H.rewriteJsonFile createStakedInitialGenesisFile $ J.rewriteObject
103+
( HM.insert "securityParam" (toJSON @Int 5) -- TODO: USE config p arameter
104+
. HM.adjust
105+
(J.rewriteObject
106+
$ HM.adjust
107+
(J.rewriteObject (HM.insert "major" (toJSON @Int 8)))
108+
"protocolVersion"
109+
) "protocolParams"
110+
. HM.insert "rho" (toJSON @Double 0.1)
111+
. HM.insert "tau" (toJSON @Double 0.1)
112+
. HM.insert "updateQuorum" (toJSON @Int 2)
113+
)
114+
115+
execCli_
116+
[ "genesis", "create-staked"
117+
, "--genesis-dir", tempAbsPath'
118+
, "--testnet-magic", show @Int testnetMagic
119+
, "--gen-pools", show @Int numPoolNodes
120+
, "--supply", "1000000000000"
121+
, "--supply-delegated", "1000000000000"
122+
, "--gen-stake-delegs", "3"
123+
, "--gen-utxo-keys", "3"
124+
, "--start-time", DTC.formatIso8601 startTime
125+
]
126+
127+
-- Here we move all of the keys etc generated by create-staked
128+
-- for the nodes to use
129+
130+
-- Move all genesis related files
131+
132+
genesisByronDir <- H.createDirectoryIfMissing $ tempAbsPath' </> "byron"
133+
genesisShelleyDir <- H.createDirectoryIfMissing $ tempAbsPath' </> "shelley"
134+
135+
files <- H.listDirectory tempAbsPath'
136+
forM_ files $ \file -> do
137+
H.note file
138+
139+
H.renameFile (tempAbsPath' </> "byron-gen-command/genesis.json") (genesisByronDir </> "genesis.json")
140+
H.renameFile (tempAbsPath' </> "genesis.alonzo.json") (genesisShelleyDir </> "genesis.alonzo.json")
141+
H.renameFile (tempAbsPath' </> "genesis.conway.json") (genesisShelleyDir </> "genesis.conway.json")
142+
H.renameFile (tempAbsPath' </> "genesis.json") (genesisShelleyDir </> "genesis.json")
143+
144+
return genesisShelleyDir
145+
61146
ifaceAddress :: String
62147
ifaceAddress = "127.0.0.1"
63148

cardano-testnet/src/Testnet/Defaults.hs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Testnet.Defaults
88
, defaultByronProtocolParamsJsonValue
99
, defaultYamlConfig
1010
, defaultConwayGenesis
11+
, defaultShelleyGenesis
1112
, defaultYamlHardforkViaConfig
1213
, defaultMainnetTopology
1314
) where
@@ -22,6 +23,7 @@ import Cardano.Ledger.BaseTypes
2223
import Cardano.Ledger.Coin
2324
import Cardano.Ledger.Conway.Genesis
2425
import Cardano.Ledger.Crypto (StandardCrypto)
26+
import Cardano.Ledger.Shelley.Genesis
2527
import Cardano.Node.Configuration.Topology
2628
import Cardano.Tracing.Config
2729

@@ -37,9 +39,12 @@ import qualified Data.Map.Strict as Map
3739
import Data.Proxy
3840
import Data.Ratio
3941
import Data.Scientific
42+
import Data.Time (UTCTime)
4043
import qualified Data.Vector as Vector
4144
import Data.Word
4245

46+
import Testnet.Start.Types
47+
4348

4449
instance Api.Error AlonzoGenesisError where
4550
displayError (AlonzoGenErrCostModels e) =
@@ -401,6 +406,23 @@ defaultByronProtocolParamsJsonValue =
401406
, "updateVoteThd" .= toJSON @String "1000000000000"
402407
]
403408

409+
defaultShelleyGenesis
410+
:: UTCTime
411+
-> CardanoTestnetOptions
412+
-> Api.ShelleyGenesis StandardCrypto
413+
defaultShelleyGenesis startTime testnetOptions =
414+
let testnetMagic = cardanoTestnetMagic testnetOptions
415+
slotLength = cardanoSlotLength testnetOptions
416+
epochLength = cardanoEpochLength testnetOptions
417+
maxLovelaceLovelaceSupply = cardanoMaxSupply testnetOptions
418+
in Api.shelleyGenesisDefaults
419+
{ Api.sgNetworkMagic = fromIntegral testnetMagic
420+
, Api.sgSlotLength = secondsToNominalDiffTimeMicro $ realToFrac slotLength
421+
, Api.sgEpochLength = EpochSize $ fromIntegral epochLength
422+
, Api.sgMaxLovelaceSupply = maxLovelaceLovelaceSupply
423+
, Api.sgSystemStart = startTime
424+
}
425+
404426
defaultMainnetTopology :: NetworkTopology
405427
defaultMainnetTopology =
406428
let single = RemoteAddress

0 commit comments

Comments
 (0)