From c01cb9d90933d1def57a0d3687b549ba9bade473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Wed, 16 Oct 2024 11:28:33 +0200 Subject: [PATCH 1/4] Read: add function to compute hash of genesis file --- cardano-cli/src/Cardano/CLI/Read.hs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cardano-cli/src/Cardano/CLI/Read.hs b/cardano-cli/src/Cardano/CLI/Read.hs index dc5ab17416..204e9672bc 100644 --- a/cardano-cli/src/Cardano/CLI/Read.hs +++ b/cardano-cli/src/Cardano/CLI/Read.hs @@ -94,6 +94,9 @@ module Cardano.CLI.Read , readVoteDelegationTarget , readVerificationKeyOrHashOrFileOrScript , readVerificationKeySource + + -- * Genesis hashes + , readShelleyOnwardsGenesisAndHash ) where @@ -108,7 +111,7 @@ import Cardano.CLI.Types.Errors.ScriptDecodeError import Cardano.CLI.Types.Errors.StakeCredentialError import Cardano.CLI.Types.Governance import Cardano.CLI.Types.Key -import qualified Cardano.Crypto.Hash.Class as Crypto +import qualified Cardano.Crypto.Hash as Crypto import Prelude @@ -1227,3 +1230,13 @@ readVoteDelegationTarget voteDelegationTarget = pure L.DRepAlwaysAbstain VoteDelegationTargetOfNoConfidence -> pure L.DRepAlwaysNoConfidence + +--- | Read the given file and hashes its content using 'Blake2b_256' +readShelleyOnwardsGenesisAndHash + :: MonadIO m + => FilePath + -- ^ The file to read + -> m (Crypto.Hash Crypto.Blake2b_256 BS.ByteString) +readShelleyOnwardsGenesisAndHash path = do + content <- liftIO $ BS.readFile path + return $ Crypto.hashWith id content From 2df936bf686bc760294269e16c780049c5a116a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Mon, 30 Sep 2024 16:52:50 +0200 Subject: [PATCH 2/4] Add check-node-configuration command --- cardano-cli/cardano-cli.cabal | 2 + cardano-cli/src/Cardano/CLI/Commands/Debug.hs | 4 +- .../Commands/Debug/CheckNodeConfiguration.hs | 9 ++ cardano-cli/src/Cardano/CLI/Options/Debug.hs | 10 ++ cardano-cli/src/Cardano/CLI/Run/Debug.hs | 2 + .../CLI/Run/Debug/CheckNodeConfiguration.hs | 91 +++++++++++++++++++ .../Cardano/CLI/Types/Errors/DebugCmdError.hs | 52 +++++++++++ 7 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 cardano-cli/src/Cardano/CLI/Commands/Debug/CheckNodeConfiguration.hs create mode 100644 cardano-cli/src/Cardano/CLI/Run/Debug/CheckNodeConfiguration.hs diff --git a/cardano-cli/cardano-cli.cabal b/cardano-cli/cardano-cli.cabal index e27fe19994..8bcd44f719 100644 --- a/cardano-cli/cardano-cli.cabal +++ b/cardano-cli/cardano-cli.cabal @@ -60,6 +60,7 @@ library Cardano.CLI.Commands Cardano.CLI.Commands.Address Cardano.CLI.Commands.Debug + Cardano.CLI.Commands.Debug.CheckNodeConfiguration Cardano.CLI.Commands.Debug.LogEpochState Cardano.CLI.Commands.Debug.TransactionView Cardano.CLI.Commands.Hash @@ -141,6 +142,7 @@ library Cardano.CLI.Run.Address Cardano.CLI.Run.Address.Info Cardano.CLI.Run.Debug + Cardano.CLI.Run.Debug.CheckNodeConfiguration Cardano.CLI.Run.Debug.LogEpochState Cardano.CLI.Run.Debug.TransactionView Cardano.CLI.Run.Hash diff --git a/cardano-cli/src/Cardano/CLI/Commands/Debug.hs b/cardano-cli/src/Cardano/CLI/Commands/Debug.hs index c9c4e52b51..a2209d27c7 100644 --- a/cardano-cli/src/Cardano/CLI/Commands/Debug.hs +++ b/cardano-cli/src/Cardano/CLI/Commands/Debug.hs @@ -3,9 +3,11 @@ module Cardano.CLI.Commands.Debug ) where +import Cardano.CLI.Commands.Debug.CheckNodeConfiguration import Cardano.CLI.Commands.Debug.LogEpochState import Cardano.CLI.Commands.Debug.TransactionView data DebugCmds - = DebugLogEpochStateCmd LogEpochStateCmdArgs + = DebugCheckNodeConfigurationCmd CheckNodeConfigCmdArgs + | DebugLogEpochStateCmd LogEpochStateCmdArgs | DebugTransactionViewCmd TransactionViewCmdArgs diff --git a/cardano-cli/src/Cardano/CLI/Commands/Debug/CheckNodeConfiguration.hs b/cardano-cli/src/Cardano/CLI/Commands/Debug/CheckNodeConfiguration.hs new file mode 100644 index 0000000000..7aeb79dd4b --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/Commands/Debug/CheckNodeConfiguration.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE DataKinds #-} + +module Cardano.CLI.Commands.Debug.CheckNodeConfiguration where + +import Cardano.Api + +-- | Argument for the 'debug check-node-configuration' command. +newtype CheckNodeConfigCmdArgs = CheckNodeConfigCmdArgs (NodeConfigFile 'In) + deriving Show diff --git a/cardano-cli/src/Cardano/CLI/Options/Debug.hs b/cardano-cli/src/Cardano/CLI/Options/Debug.hs index 729b2650c9..6b05b2b7fb 100644 --- a/cardano-cli/src/Cardano/CLI/Options/Debug.hs +++ b/cardano-cli/src/Cardano/CLI/Options/Debug.hs @@ -14,6 +14,7 @@ where import Cardano.Api.Shelley hiding (QueryInShelleyBasedEra (..)) import Cardano.CLI.Commands.Debug +import Cardano.CLI.Commands.Debug.CheckNodeConfiguration import Cardano.CLI.Commands.Debug.LogEpochState import Cardano.CLI.Commands.Debug.TransactionView import Cardano.CLI.Environment @@ -47,6 +48,10 @@ pDebugCmds envCli = , " The log file format is line delimited JSON." , " The command will not terminate." ] + , subParser "check-node-configuration" $ + Opt.info pCheckNodeConfigurationCmdArgs $ + Opt.progDesc + "Check hashes and paths of genesis files in the given node configuration file." , subParser "transaction" $ Opt.info ( asum @@ -65,6 +70,11 @@ pDebugCmds envCli = <*> pFileOutDirection "out-file" "Output filepath of the log file. The log file format is line delimited JSON." + pCheckNodeConfigurationCmdArgs :: Parser DebugCmds + pCheckNodeConfigurationCmdArgs = + fmap DebugCheckNodeConfigurationCmd $ + CheckNodeConfigCmdArgs + <$> pNodeConfigurationFileIn pTransactionView :: Parser DebugCmds pTransactionView = fmap DebugTransactionViewCmd $ diff --git a/cardano-cli/src/Cardano/CLI/Run/Debug.hs b/cardano-cli/src/Cardano/CLI/Run/Debug.hs index 47363aa787..8816cd7a29 100644 --- a/cardano-cli/src/Cardano/CLI/Run/Debug.hs +++ b/cardano-cli/src/Cardano/CLI/Run/Debug.hs @@ -10,11 +10,13 @@ where import Cardano.Api import Cardano.CLI.Commands.Debug +import Cardano.CLI.Run.Debug.CheckNodeConfiguration (runCheckNodeConfig) import Cardano.CLI.Run.Debug.LogEpochState import Cardano.CLI.Run.Debug.TransactionView (runTransactionViewCmd) import Cardano.CLI.Types.Errors.DebugCmdError runDebugCmds :: DebugCmds -> ExceptT DebugCmdError IO () runDebugCmds = \case + DebugCheckNodeConfigurationCmd cmd -> runCheckNodeConfig cmd DebugLogEpochStateCmd cmd -> liftIO $ runLogEpochStateCmd cmd DebugTransactionViewCmd cmd -> firstExceptT DebugTxCmdError $ runTransactionViewCmd cmd diff --git a/cardano-cli/src/Cardano/CLI/Run/Debug/CheckNodeConfiguration.hs b/cardano-cli/src/Cardano/CLI/Run/Debug/CheckNodeConfiguration.hs new file mode 100644 index 0000000000..4c1f6ff552 --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/Run/Debug/CheckNodeConfiguration.hs @@ -0,0 +1,91 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Cardano.CLI.Run.Debug.CheckNodeConfiguration (runCheckNodeConfig) where + +import Cardano.Api +import qualified Cardano.Api.Byron as Byron + +import Cardano.CLI.Commands.Debug.CheckNodeConfiguration +import qualified Cardano.CLI.Read as Read +import Cardano.CLI.Types.Errors.DebugCmdError +import qualified Cardano.Crypto.Hash as Crypto + +import Control.Monad +import qualified Data.Text as Text +import qualified Data.Yaml as Yaml +import System.FilePath (takeDirectory, ()) + +runCheckNodeConfig :: CheckNodeConfigCmdArgs -> ExceptT DebugCmdError IO () +runCheckNodeConfig (CheckNodeConfigCmdArgs configFile) = do + nodeConfig :: NodeConfig <- liftIO $ Yaml.decodeFileThrow configFilePath + checkNodeGenesisConfiguration configFile nodeConfig + liftIO $ putStrLn $ "Successfully checked node configuration file: " <> configFilePath + where + configFilePath = unFile configFile + +checkNodeGenesisConfiguration + :: NodeConfigFile 'In + -- ^ The node configuration file path. It's not read by this function, but used for producing error messages. + -> NodeConfig + -- ^ The parsed node configuration file + -> ExceptT DebugCmdError IO () +checkNodeGenesisConfiguration configFile nodeConfig = do + let byronGenFile = adjustFilepath $ unFile $ ncByronGenesisFile nodeConfig + alonzoGenFile = adjustFilepath $ unFile $ ncAlonzoGenesisFile nodeConfig + shelleyGenFile = adjustFilepath $ unFile $ ncShelleyGenesisFile nodeConfig + conwayGenFile <- case ncConwayGenesisFile nodeConfig of + Nothing -> throwError $ DebugNodeConfigNoConwayFileCmdError configFilePath + Just conwayGenesisFile -> pure $ adjustFilepath $ unFile conwayGenesisFile + + liftIO $ putStrLn $ "Checking byron genesis file: " <> byronGenFile + + let expectedByronHash = unGenesisHashByron $ ncByronGenesisHash nodeConfig + expectedAlonzoHash = Crypto.hashToTextAsHex $ unGenesisHashAlonzo $ ncAlonzoGenesisHash nodeConfig + expectedShelleyHash = Crypto.hashToTextAsHex $ unGenesisHashShelley $ ncShelleyGenesisHash nodeConfig + expectedConwayHash <- case ncConwayGenesisHash nodeConfig of + Nothing -> throwError $ DebugNodeConfigNoConwayHashCmdError configFilePath + Just conwayGenesisHash -> pure $ Crypto.hashToTextAsHex $ unGenesisHashConway conwayGenesisHash + + (_, Byron.GenesisHash byronHash) <- + firstExceptT (DebugNodeConfigGenesisDataCmdError byronGenFile) $ + Byron.readGenesisData byronGenFile + let actualByronHash = Text.pack $ show byronHash + actualAlonzoHash <- Crypto.hashToTextAsHex <$> Read.readShelleyOnwardsGenesisAndHash alonzoGenFile + actualShelleyHash <- Crypto.hashToTextAsHex <$> Read.readShelleyOnwardsGenesisAndHash shelleyGenFile + actualConwayHash <- Crypto.hashToTextAsHex <$> Read.readShelleyOnwardsGenesisAndHash conwayGenFile + + when (actualByronHash /= expectedByronHash) $ + throwError $ + DebugNodeConfigWrongGenesisHashCmdError + configFilePath + byronGenFile + actualByronHash + expectedByronHash + when (actualAlonzoHash /= expectedAlonzoHash) $ + throwError $ + DebugNodeConfigWrongGenesisHashCmdError + configFilePath + alonzoGenFile + actualAlonzoHash + expectedAlonzoHash + when (actualShelleyHash /= expectedShelleyHash) $ + throwError $ + DebugNodeConfigWrongGenesisHashCmdError + configFilePath + shelleyGenFile + actualShelleyHash + expectedShelleyHash + when (actualConwayHash /= expectedConwayHash) $ + throwError $ + DebugNodeConfigWrongGenesisHashCmdError + configFilePath + conwayGenFile + actualConwayHash + expectedConwayHash + where + configFilePath = unFile configFile + -- We make the genesis filepath relative to the node configuration file, like the node does: + -- https://github.com/IntersectMBO/cardano-node/blob/9671e7b6a1b91f5a530722937949b86deafaad43/cardano-node/src/Cardano/Node/Configuration/POM.hs#L668 + -- Note that, if the genesis filepath is absolute, the node configuration file's directory is ignored (by property of ) + adjustFilepath f = takeDirectory configFilePath f diff --git a/cardano-cli/src/Cardano/CLI/Types/Errors/DebugCmdError.hs b/cardano-cli/src/Cardano/CLI/Types/Errors/DebugCmdError.hs index 5d71835441..4a715ee1c2 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Errors/DebugCmdError.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Errors/DebugCmdError.hs @@ -6,14 +6,66 @@ module Cardano.CLI.Types.Errors.DebugCmdError where import Cardano.Api +import qualified Cardano.Api.Byron as Byron import Cardano.CLI.Types.Errors.TxCmdError +import Data.Text (Text) +import qualified Data.Text.Lazy.Builder as Text +import Formatting.Buildable (build) + data DebugCmdError = DebugCmdFailed + | -- | @DebugNodeConfigGenesisDataCmdError filepath error@ represents an error when + -- reading the node configuration at @filepath@ + DebugNodeConfigGenesisDataCmdError !FilePath !Byron.GenesisDataError + | -- | @DebugNodeConfigWrongGenesisHashCmdError filepath eraGenesisPath actualHash expectedHash@ represents a user error + -- that the hash of @eraGenesisPath@ in @filepath@ is @actualHash@, whereas it should be @expectedHash@ + DebugNodeConfigWrongGenesisHashCmdError + !FilePath + -- ^ The file path of the node configuration file + !FilePath + -- ^ The file path of the era configuration file whose hash is wrong + !Text + -- ^ The actual hash (the hash found by hashing the genesis file) + !Text + -- ^ The expected hash (the hash mentioned in the configuration file) + | -- | @DebugNodeConfigNoConwayFileCmdError filepath@ represents a user error + -- that the genesis file for Conway in @filepath@ is not specified + DebugNodeConfigNoConwayFileCmdError + !FilePath + | -- | @DebugNodeConfigNoConwayHashCmdError filepath@ represents a user error + -- that the hash for the Conway genesis file in @filepath@ is not specified + DebugNodeConfigNoConwayHashCmdError + !FilePath + -- ^ The file path of the node configuration file | DebugTxCmdError !TxCmdError instance Error DebugCmdError where prettyError = \case DebugCmdFailed -> "Debug command failed" + DebugNodeConfigGenesisDataCmdError fp err -> + "Error reading node configuration at: " + <> pretty fp + <> ": " + <> pretty (Text.toLazyText $ build err) + DebugNodeConfigNoConwayFileCmdError fp -> + "Conway genesis file not specified in " + <> pretty fp + <> ". Please add a \"ConwayGenesisFile\" key to the file at " + <> pretty fp + DebugNodeConfigNoConwayHashCmdError fp -> + "Conway genesis hash not specified in " + <> pretty fp + <> ". Please add a \"ConwayGenesisHash\" key to the file at " + <> pretty fp + DebugNodeConfigWrongGenesisHashCmdError nodeFp genesisFp actualHash expectedHash -> + "Wrong genesis hash for " + <> pretty genesisFp + <> " in " + <> pretty nodeFp + <> ": when computing the hash, got: " + <> pretty actualHash + <> ", but the node configuration files states that this hash is expected: " + <> pretty expectedHash DebugTxCmdError err -> renderTxCmdError err From 51c05d7edefc7d552a0102a6857d0390cf4f9dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Thu, 3 Oct 2024 14:41:05 +0200 Subject: [PATCH 3/4] Adapt golden files --- .../test/cardano-cli-golden/files/golden/help.cli | 10 +++++++++- .../cardano-cli-golden/files/golden/help/debug.cli | 8 +++++++- .../golden/help/debug_check-node-configuration.cli | 8 ++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 cardano-cli/test/cardano-cli-golden/files/golden/help/debug_check-node-configuration.cli diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help.cli index f6f1dd2c7b..43b3c0f35a 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help.cli @@ -10613,7 +10613,11 @@ Usage: cardano-cli ping [-c|--count COUNT] Ping a cardano node either using node-to-node or node-to-client protocol. It negotiates a handshake and keeps sending keep alive messages. -Usage: cardano-cli debug (log-epoch-state | transaction) +Usage: cardano-cli debug + ( log-epoch-state + | check-node-configuration + | transaction + ) Debug commands @@ -10625,6 +10629,10 @@ Usage: cardano-cli debug log-epoch-state --socket-path SOCKET_PATH and log the epoch state to a file. The log file format is line delimited JSON. The command will not terminate. +Usage: cardano-cli debug check-node-configuration --node-configuration-file FILEPATH + + Check hashes and paths of genesis files in the given node configuration file. + Usage: cardano-cli debug transaction view Transaction commands diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/debug.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/debug.cli index 7f6cdf7153..08dc78c128 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/debug.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/debug.cli @@ -1,4 +1,8 @@ -Usage: cardano-cli debug (log-epoch-state | transaction) +Usage: cardano-cli debug + ( log-epoch-state + | check-node-configuration + | transaction + ) Debug commands @@ -10,4 +14,6 @@ Available commands: connect to a local node and log the epoch state to a file. The log file format is line delimited JSON. The command will not terminate. + check-node-configuration Check hashes and paths of genesis files in the given + node configuration file. transaction Transaction commands diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/debug_check-node-configuration.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/debug_check-node-configuration.cli new file mode 100644 index 0000000000..f4ffe775fe --- /dev/null +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/debug_check-node-configuration.cli @@ -0,0 +1,8 @@ +Usage: cardano-cli debug check-node-configuration --node-configuration-file FILEPATH + + Check hashes and paths of genesis files in the given node configuration file. + +Available options: + --node-configuration-file FILEPATH + Input filepath of the node configuration file. + -h,--help Show this help text From 38f2ef5a77278379d1ece1bcc447199e21e145df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Mon, 7 Oct 2024 21:37:52 +0200 Subject: [PATCH 4/4] check-node-configuration: add tests --- .gitattributes | 4 + cardano-cli/cardano-cli.cabal | 3 + .../Test/Cli/CheckNodeConfiguration.hs | 127 ++++++++ .../genesis.alonzo.spec.json | 194 ++++++++++++ .../genesis.byron.spec.json | 67 ++++ .../genesis.conway.spec.json | 42 +++ .../genesis.shelley.spec.json | 40 +++ .../check-node-configuration/node-config.json | 96 ++++++ .../check-node-configuration/node-config.yaml | 292 ++++++++++++++++++ 9 files changed, 865 insertions(+) create mode 100644 cardano-cli/test/cardano-cli-test/Test/Cli/CheckNodeConfiguration.hs create mode 100644 cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.alonzo.spec.json create mode 100644 cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.byron.spec.json create mode 100644 cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.conway.spec.json create mode 100644 cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.shelley.spec.json create mode 100644 cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.json create mode 100644 cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.yaml diff --git a/.gitattributes b/.gitattributes index fd9f75d876..891dbb3826 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,7 @@ cardano-cli/test/cardano-cli-golden/files/input/example_anchor_data.txt -text cardano-cli/test/cardano-cli-golden/files/input/example_anchor_data2.txt -text cardano-cli/test/cardano-cli-test/files/input/example_anchor_data.txt -text cardano-cli/test/cardano-cli-test/files/input/example_anchor_data2.txt -text +cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.alonzo.spec.json -text +cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.byron.spec.json -text +cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.conway.spec.json -text +cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.shelley.spec.json -text diff --git a/cardano-cli/cardano-cli.cabal b/cardano-cli/cardano-cli.cabal index 8bcd44f719..012438b1cb 100644 --- a/cardano-cli/cardano-cli.cabal +++ b/cardano-cli/cardano-cli.cabal @@ -308,6 +308,7 @@ test-suite cardano-cli-test type: exitcode-stdio-1.0 build-depends: aeson, + aeson-pretty, base16-bytestring, bech32 >=1.1.0, bytestring, @@ -329,10 +330,12 @@ test-suite cardano-cli-test text, time, transformers, + yaml, build-tool-depends: tasty-discover:tasty-discover other-modules: Test.Cli.AddCostModels + Test.Cli.CheckNodeConfiguration Test.Cli.CreateCardano Test.Cli.CreateTestnetData Test.Cli.DRepMetadata diff --git a/cardano-cli/test/cardano-cli-test/Test/Cli/CheckNodeConfiguration.hs b/cardano-cli/test/cardano-cli-test/Test/Cli/CheckNodeConfiguration.hs new file mode 100644 index 0000000000..26702064fe --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/Test/Cli/CheckNodeConfiguration.hs @@ -0,0 +1,127 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Test.Cli.CheckNodeConfiguration where + +import Cardano.Api + +import Control.Monad (forM_) +import qualified Data.Aeson as Aeson +import qualified Data.Aeson.Encode.Pretty as Aeson +import qualified Data.Aeson.Key as Aeson +import qualified Data.Aeson.KeyMap as Aeson +import qualified Data.ByteString.Lazy as LBS +import Data.List (isInfixOf) +import qualified Data.Text as Text +import qualified Data.Yaml as Yaml +import GHC.IO.Exception (ExitCode (..)) +import System.FilePath (()) + +import Test.Cardano.CLI.Util (FileSem, bracketSem, execCardanoCLI, execDetailCardanoCLI, + newFileSem) + +import Hedgehog (Property) +import qualified Hedgehog as H +import Hedgehog.Extras (propertyOnce) +import qualified Hedgehog.Extras as H + +-- | Semaphore protecting against locked file error, when running properties concurrently. +nodeConfigSem :: FileSem +nodeConfigSem = newFileSem "test/cardano-cli-test/files/input/check-node-configuration/node-config.json" +{-# NOINLINE nodeConfigSem #-} + +-- Execute this test with: +-- @cabal test cardano-cli-test --test-options '-p "/check node configuration success/"'@ +hprop_check_node_configuration_success :: Property +hprop_check_node_configuration_success = + propertyOnce $ do + -- We test that the command doesn't crash, because otherwise + -- execCardanoCLI would fail. + bracketSem nodeConfigSem $ \nodeConfigFile -> do + H.noteM_ $ + execCardanoCLI + [ "debug" + , "check-node-configuration" + , "--node-configuration-file" + , nodeConfigFile + ] + +data FiddleKind + = FiddleByron + | FiddleNonByron + deriving (Bounded, Enum) + +-- Execute this test with: +-- @cabal test cardano-cli-test --test-options '-p "/check node configuration failure/"'@ +hprop_check_node_configuration_failure :: Property +hprop_check_node_configuration_failure = do + let supplyValues :: [(FilePath, FiddleKind)] = + [ (path, fiddleKind) + | path <- + [ "test/cardano-cli-test/files/input/check-node-configuration/node-config.json" + , "test/cardano-cli-test/files/input/check-node-configuration/node-config.yaml" + ] + , fiddleKind <- [minBound .. maxBound] + ] + + propertyOnce $ forM_ supplyValues $ \(nodeConfigPath, fiddleKind) -> H.moduleWorkspace "tmp" $ \tempDir -> + bracketSem nodeConfigSem $ \_ -> do + let finalInputConfig = tempDir "node-config-changed.json" + -- TODO why is that writing to "AlonzoGenesisHash" writes one more 0 than specified here? (and hence the need for this hack) + wrongHash = Text.pack $ replicate (case fiddleKind of FiddleByron -> 65; FiddleNonByron -> 64) '0' + + -- Install the genesis files in the sandbox + forM_ + [AnyCardanoEra ByronEra, AnyCardanoEra AlonzoEra, AnyCardanoEra ConwayEra, AnyCardanoEra ShelleyEra] + $ \(AnyCardanoEra era) -> do + let filename = Text.unpack $ "genesis." <> Text.toLower (eraToStringKey era) <> ".spec.json" + genesisFile = "test/cardano-cli-test/files/input/check-node-configuration" filename + H.copyFile genesisFile (tempDir filename) + + -- We make a hash value incorrect, and check that + -- check-node-configuration fails. + + nodeConfigValue :: Aeson.Value <- Yaml.decodeFileThrow nodeConfigPath + nodeConfigObject :: Aeson.Object <- + case nodeConfigValue of + Aeson.Object obj -> pure obj + _ -> + do + H.note_ "Expected an Object, but got something else" + H.failure + + -- We make a hash value incorrect, and check that + -- check-node-configuration finds the mistake. + + -- Prepare file with incorrect hash + + let fiddledEraKey = + Aeson.fromText $ eraToGenesisHashKey $ case fiddleKind of + FiddleByron -> AnyCardanoEra ByronEra + FiddleNonByron -> AnyCardanoEra AlonzoEra + finalConfigObject = + Aeson.Object $ Aeson.insert fiddledEraKey (Aeson.String wrongHash) nodeConfigObject + + -- Write file with incorrect hash + liftIO $ LBS.writeFile finalInputConfig $ Aeson.encodePretty finalConfigObject + + (exitCode, _stdout, stderr) <- + H.noteShowM $ + execDetailCardanoCLI + [ "debug" + , "check-node-configuration" + , "--node-configuration-file" + , finalInputConfig + ] + + H.assertWith exitCode (ExitSuccess /=) + H.assertWith stderr ("Wrong genesis hash" `isInfixOf`) + +-- | The JSON key of the genesis hash for the given era. +eraToGenesisHashKey :: AnyCardanoEra -> Text.Text +eraToGenesisHashKey (AnyCardanoEra era) = eraToStringKey era <> "GenesisHash" + +-- | Part of the JSON keys associated with the given era. For example, +-- @eraToStringKey ByronEra@ returns @"Byron"@. +eraToStringKey :: CardanoEra a -> Text.Text +eraToStringKey = docToText . pretty diff --git a/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.alonzo.spec.json b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.alonzo.spec.json new file mode 100644 index 0000000000..cf8e5ef324 --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.alonzo.spec.json @@ -0,0 +1,194 @@ +{ + "lovelacePerUTxOWord": 34482, + "executionPrices": { + "prSteps": { + "numerator": 721, + "denominator": 10000000 + }, + "prMem": { + "numerator": 577, + "denominator": 10000 + } + }, + "maxTxExUnits": { + "exUnitsMem": 10000000, + "exUnitsSteps": 10000000000 + }, + "maxBlockExUnits": { + "exUnitsMem": 50000000, + "exUnitsSteps": 40000000000 + }, + "maxValueSize": 5000, + "collateralPercentage": 150, + "maxCollateralInputs": 3, + "costModels": { + "PlutusV1": { + "sha2_256-memory-arguments": 4, + "equalsString-cpu-arguments-constant": 1000, + "cekDelayCost-exBudgetMemory": 100, + "lessThanEqualsByteString-cpu-arguments-intercept": 103599, + "divideInteger-memory-arguments-minimum": 1, + "appendByteString-cpu-arguments-slope": 621, + "blake2b-cpu-arguments-slope": 29175, + "iData-cpu-arguments": 150000, + "encodeUtf8-cpu-arguments-slope": 1000, + "unBData-cpu-arguments": 150000, + "multiplyInteger-cpu-arguments-intercept": 61516, + "cekConstCost-exBudgetMemory": 100, + "nullList-cpu-arguments": 150000, + "equalsString-cpu-arguments-intercept": 150000, + "trace-cpu-arguments": 150000, + "mkNilData-memory-arguments": 32, + "lengthOfByteString-cpu-arguments": 150000, + "cekBuiltinCost-exBudgetCPU": 29773, + "bData-cpu-arguments": 150000, + "subtractInteger-cpu-arguments-slope": 0, + "unIData-cpu-arguments": 150000, + "consByteString-memory-arguments-intercept": 0, + "divideInteger-memory-arguments-slope": 1, + "divideInteger-cpu-arguments-model-arguments-slope": 118, + "listData-cpu-arguments": 150000, + "headList-cpu-arguments": 150000, + "chooseData-memory-arguments": 32, + "equalsInteger-cpu-arguments-intercept": 136542, + "sha3_256-cpu-arguments-slope": 82363, + "sliceByteString-cpu-arguments-slope": 5000, + "unMapData-cpu-arguments": 150000, + "lessThanInteger-cpu-arguments-intercept": 179690, + "mkCons-cpu-arguments": 150000, + "appendString-memory-arguments-intercept": 0, + "modInteger-cpu-arguments-model-arguments-slope": 118, + "ifThenElse-cpu-arguments": 1, + "mkNilPairData-cpu-arguments": 150000, + "lessThanEqualsInteger-cpu-arguments-intercept": 145276, + "addInteger-memory-arguments-slope": 1, + "chooseList-memory-arguments": 32, + "constrData-memory-arguments": 32, + "decodeUtf8-cpu-arguments-intercept": 150000, + "equalsData-memory-arguments": 1, + "subtractInteger-memory-arguments-slope": 1, + "appendByteString-memory-arguments-intercept": 0, + "lengthOfByteString-memory-arguments": 4, + "headList-memory-arguments": 32, + "listData-memory-arguments": 32, + "consByteString-cpu-arguments-intercept": 150000, + "unIData-memory-arguments": 32, + "remainderInteger-memory-arguments-minimum": 1, + "bData-memory-arguments": 32, + "lessThanByteString-cpu-arguments-slope": 248, + "encodeUtf8-memory-arguments-intercept": 0, + "cekStartupCost-exBudgetCPU": 100, + "multiplyInteger-memory-arguments-intercept": 0, + "unListData-memory-arguments": 32, + "remainderInteger-cpu-arguments-model-arguments-slope": 118, + "cekVarCost-exBudgetCPU": 29773, + "remainderInteger-memory-arguments-slope": 1, + "cekForceCost-exBudgetCPU": 29773, + "sha2_256-cpu-arguments-slope": 29175, + "equalsInteger-memory-arguments": 1, + "indexByteString-memory-arguments": 1, + "addInteger-memory-arguments-intercept": 1, + "chooseUnit-cpu-arguments": 150000, + "sndPair-cpu-arguments": 150000, + "cekLamCost-exBudgetCPU": 29773, + "fstPair-cpu-arguments": 150000, + "quotientInteger-memory-arguments-minimum": 1, + "decodeUtf8-cpu-arguments-slope": 1000, + "lessThanInteger-memory-arguments": 1, + "lessThanEqualsInteger-cpu-arguments-slope": 1366, + "fstPair-memory-arguments": 32, + "modInteger-memory-arguments-intercept": 0, + "unConstrData-cpu-arguments": 150000, + "lessThanEqualsInteger-memory-arguments": 1, + "chooseUnit-memory-arguments": 32, + "sndPair-memory-arguments": 32, + "addInteger-cpu-arguments-intercept": 197209, + "decodeUtf8-memory-arguments-slope": 8, + "equalsData-cpu-arguments-intercept": 150000, + "mapData-cpu-arguments": 150000, + "mkPairData-cpu-arguments": 150000, + "quotientInteger-cpu-arguments-constant": 148000, + "consByteString-memory-arguments-slope": 1, + "cekVarCost-exBudgetMemory": 100, + "indexByteString-cpu-arguments": 150000, + "unListData-cpu-arguments": 150000, + "equalsInteger-cpu-arguments-slope": 1326, + "cekStartupCost-exBudgetMemory": 100, + "subtractInteger-cpu-arguments-intercept": 197209, + "divideInteger-cpu-arguments-model-arguments-intercept": 425507, + "divideInteger-memory-arguments-intercept": 0, + "cekForceCost-exBudgetMemory": 100, + "blake2b-cpu-arguments-intercept": 2477736, + "remainderInteger-cpu-arguments-constant": 148000, + "tailList-cpu-arguments": 150000, + "encodeUtf8-cpu-arguments-intercept": 150000, + "equalsString-cpu-arguments-slope": 1000, + "lessThanByteString-memory-arguments": 1, + "multiplyInteger-cpu-arguments-slope": 11218, + "appendByteString-cpu-arguments-intercept": 396231, + "lessThanEqualsByteString-cpu-arguments-slope": 248, + "modInteger-memory-arguments-slope": 1, + "addInteger-cpu-arguments-slope": 0, + "equalsData-cpu-arguments-slope": 10000, + "decodeUtf8-memory-arguments-intercept": 0, + "chooseList-cpu-arguments": 150000, + "constrData-cpu-arguments": 150000, + "equalsByteString-memory-arguments": 1, + "cekApplyCost-exBudgetCPU": 29773, + "quotientInteger-memory-arguments-slope": 1, + "verifySignature-cpu-arguments-intercept": 3345831, + "unMapData-memory-arguments": 32, + "mkCons-memory-arguments": 32, + "sliceByteString-memory-arguments-slope": 1, + "sha3_256-memory-arguments": 4, + "ifThenElse-memory-arguments": 1, + "mkNilPairData-memory-arguments": 32, + "equalsByteString-cpu-arguments-slope": 247, + "appendString-cpu-arguments-intercept": 150000, + "quotientInteger-cpu-arguments-model-arguments-slope": 118, + "cekApplyCost-exBudgetMemory": 100, + "equalsString-memory-arguments": 1, + "multiplyInteger-memory-arguments-slope": 1, + "cekBuiltinCost-exBudgetMemory": 100, + "remainderInteger-memory-arguments-intercept": 0, + "sha2_256-cpu-arguments-intercept": 2477736, + "remainderInteger-cpu-arguments-model-arguments-intercept": 425507, + "lessThanEqualsByteString-memory-arguments": 1, + "tailList-memory-arguments": 32, + "mkNilData-cpu-arguments": 150000, + "chooseData-cpu-arguments": 150000, + "unBData-memory-arguments": 32, + "blake2b-memory-arguments": 4, + "iData-memory-arguments": 32, + "nullList-memory-arguments": 32, + "cekDelayCost-exBudgetCPU": 29773, + "subtractInteger-memory-arguments-intercept": 1, + "lessThanByteString-cpu-arguments-intercept": 103599, + "consByteString-cpu-arguments-slope": 1000, + "appendByteString-memory-arguments-slope": 1, + "trace-memory-arguments": 32, + "divideInteger-cpu-arguments-constant": 148000, + "cekConstCost-exBudgetCPU": 29773, + "encodeUtf8-memory-arguments-slope": 8, + "quotientInteger-cpu-arguments-model-arguments-intercept": 425507, + "mapData-memory-arguments": 32, + "appendString-cpu-arguments-slope": 1000, + "modInteger-cpu-arguments-constant": 148000, + "verifySignature-cpu-arguments-slope": 1, + "unConstrData-memory-arguments": 32, + "quotientInteger-memory-arguments-intercept": 0, + "equalsByteString-cpu-arguments-constant": 150000, + "sliceByteString-memory-arguments-intercept": 0, + "mkPairData-memory-arguments": 32, + "equalsByteString-cpu-arguments-intercept": 112536, + "appendString-memory-arguments-slope": 1, + "lessThanInteger-cpu-arguments-slope": 497, + "modInteger-cpu-arguments-model-arguments-intercept": 425507, + "modInteger-memory-arguments-minimum": 1, + "sha3_256-cpu-arguments-intercept": 0, + "verifySignature-memory-arguments": 1, + "cekLamCost-exBudgetMemory": 100, + "sliceByteString-cpu-arguments-intercept": 150000 + } + } +} \ No newline at end of file diff --git a/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.byron.spec.json b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.byron.spec.json new file mode 100644 index 0000000000..ea042a887f --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.byron.spec.json @@ -0,0 +1,67 @@ +{ "bootStakeholders": + { "b27e2f6f43c514b48dc54146aa9c833a9336b6a192bbaefcc86976b1": 1 + , "b8e58728bf6e97b9643a4dc3d3ed570c374b4a6ab2392b09ec0d2b7a": 1 + , "dc2d4cd362901934f57978b304ecffd4c5f0f0e12e1d74e25cdb70a2": 1 + } +, "heavyDelegation": + { "b27e2f6f43c514b48dc54146aa9c833a9336b6a192bbaefcc86976b1": + { "omega": 0 + , "issuerPk": + "nrKQzT2f8Znpqz5zvd0ZhYayxKU7R3A3VHnt6IC3/1pXKYCu6iqwhLU8pPL++kIRPv0R1SbVv5+3oCbq/hVaxw==" + , "delegatePk": + "7IYLIMJXnnJZ8ACjqlKWBqQDiHxCnZHOzaGMoG93LglCTiNF6ZvqCQFddFr0KE/bwlTrbudnlUiLBZwoA21ZQQ==" + , "cert": + "f47220508c842a3ff6715b8609e9d0a25a5216232556cd3b078c119b9a70251db1d1b4bf4c687b57a3d26406a793905da6dfa9b355448ff58403dbccdac29700" + } + , "b8e58728bf6e97b9643a4dc3d3ed570c374b4a6ab2392b09ec0d2b7a": + { "omega": 0 + , "issuerPk": + "SqZC7VDUEVjohd4oA/cCWwQ10O86cTSTwuEi7mnMlFE/RyWPPwKRg+GOjqvlzxbzROcq2I/F/uCliGhbw/Bomg==" + , "delegatePk": + "Y4IehadFSAp42OhHk10f4DGDNmt5WPmx5nc/pmYVAkUekR+drgAJFvdJwQF6fw5BI2qrNugyv4885OU+N48Bhg==" + , "cert": + "d147bca31bdb9dd4192d011f77493ab003fbf6c100c5224b9d6c02e29ac938c470f8e2e90cf8691e352e9ad34b976a046488d3c2c6c585bad84ed1b8f3cccd0c" + } + , "dc2d4cd362901934f57978b304ecffd4c5f0f0e12e1d74e25cdb70a2": + { "omega": 0 + , "issuerPk": + "oCsC4/VktOZJszLf8Sv7PcSxxOUg8FoT6kNfjRhH2hvdj1333ZDo6peY9R6X6bsNJu+miWaHTFpX+S6PxPKliA==" + , "delegatePk": + "YkmGY7Hc3q6+FIaMA4VaYAm678A060meLSyaxCN8tIENFMUbgagyMhyKHdxX4IYJgvCtDhHM8QZog2eIBshqcQ==" + , "cert": + "0ce99634240fd2b9f752ea7b455b2f48d1ede9c3577c7a4b3b3d3b45420c4db8e3eae28de4d540f097e1013002b349d39e9f57dd40c7c58b0e762a781cdd7008" + } + } +, "startTime": 1725364917 +, "nonAvvmBalances": + { "2657WMsDfac5ah3fb2ATLUj14dT4n17EKtCJM4arCN5pvtminQ3xC8tw7NuPM1LPJ": + "2666666667" + , "2657WMsDfac75KY9LWADyVJnnqrrEMzhUtBgtnQmYpYKqKUgusw9uf6xBDJTn2mtH": + "2666666667" + , "2657WMsDfac7BkYDRZRq59BbLLJ91u3Mj254B2iLcuLffgjt4feALNfgDc7KMTn48": + "2666666667" + } +, "blockVersionData": + { "scriptVersion": 0 + , "slotDuration": "1000" + , "maxBlockSize": "2000000" + , "maxHeaderSize": "2000000" + , "maxTxSize": "4096" + , "maxProposalSize": "700" + , "mpcThd": "20000000000000" + , "heavyDelThd": "300000000000" + , "updateVoteThd": "1000000000000" + , "updateProposalThd": "100000000000000" + , "updateImplicit": "10000" + , "softforkRule": + { "initThd": "900000000000000" + , "minThd": "600000000000000" + , "thdDecrement": "50000000000000" + } + , "txFeePolicy": + { "summand": "155381000000000" , "multiplier": "43946000000" } + , "unlockStakeEpoch": "18446744073709551615" + } +, "protocolConsts": { "k": 10 , "protocolMagic": 42 } +, "avvmDistr": {} +} \ No newline at end of file diff --git a/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.conway.spec.json b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.conway.spec.json new file mode 100644 index 0000000000..cb36a9387f --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.conway.spec.json @@ -0,0 +1,42 @@ +{ + "poolVotingThresholds": { + "committeeNormal": 0, + "committeeNoConfidence": 0, + "hardForkInitiation": 0, + "motionNoConfidence": 0, + "ppSecurityGroup": 0 + }, + "dRepVotingThresholds": { + "motionNoConfidence": 0, + "committeeNormal": 0, + "committeeNoConfidence": 0, + "updateToConstitution": 0, + "hardForkInitiation": 0, + "ppNetworkGroup": 0, + "ppEconomicGroup": 0, + "ppTechnicalGroup": 0, + "ppGovGroup": 0, + "treasuryWithdrawal": 0 + }, + "committeeMinSize": 0, + "committeeMaxTermLength": 0, + "govActionLifetime": 0, + "govActionDeposit": 0, + "dRepDeposit": 0, + "dRepActivity": 0, + "minFeeRefScriptCostPerByte": 0, + "plutusV3CostModel": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + "constitution": { + "anchor": { + "url": "", + "dataHash": "0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "committee": { + "members": { + "keyHash-4e88cc2d27c364aaf90648a87dfb95f8ee103ba67fa1f12f5e86c42a": 1, + "scriptHash-4e88cc2d27c364aaf90648a87dfb95f8ee103ba67fa1f12f5e86c42a": 2 + }, + "threshold": 0.5 + } +} diff --git a/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.shelley.spec.json b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.shelley.spec.json new file mode 100644 index 0000000000..8b74e0201c --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/genesis.shelley.spec.json @@ -0,0 +1,40 @@ +{ + "activeSlotsCoeff": 0.99, + "systemStart": "2020-01-01T00:20:40Z", + "genDelegs": {}, + "updateQuorum": 12, + "maxMajorPV": 25446, + "maxLovelaceSupply": 100000000, + "initialFunds": {}, + "networkMagic": 403, + "networkId": "Testnet", + "epochLength": 21600, + "securityParam": 2160, + "slotLength": 20, + "slotsPerKESPeriod": 216000, + "maxKESEvolutions": 1080000, + "protocolParams": { + "a0": 0, + "decentralisationParam": 0.99, + "eMax": 0, + "extraEntropy": { + "tag": "NeutralNonce" + }, + "keyDeposit": 0, + "maxBlockBodySize": 2097152, + "maxBlockHeaderSize": 8192, + "maxTxSize": 2048, + "minFeeA": 0, + "minFeeB": 0, + "minUTxOValue": 1, + "minPoolCost": 100, + "nOpt": 100, + "poolDeposit": 0, + "protocolVersion": { + "major": 0, + "minor": 0 + }, + "rho": 0, + "tau": 0 + } +} diff --git a/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.json b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.json new file mode 100644 index 0000000000..355d0d8be1 --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.json @@ -0,0 +1,96 @@ +{ + "AlonzoGenesisFile": "genesis.alonzo.spec.json", + "AlonzoGenesisHash": "2418fe881f57d2f5851a018214634aa6d1b7f10f130c3bdf8c13210c0ed2fd02", + "ByronGenesisFile": "genesis.byron.spec.json", + "ByronGenesisHash": "b91cb9a87b244fbb6f8d60a809475705594b6aa9a9aa5dcb6be8020549def9f5", + "ConwayGenesisFile": "genesis.conway.spec.json", + "ConwayGenesisHash": "65d481eec0b24ef90f7bbeaf6933fdf9629ce89afe88238e5da4ec79977a28d1", + "EnableLogMetrics": false, + "EnableLogging": true, + "EnableP2P": false, + "ExperimentalHardForksEnabled": true, + "ExperimentalProtocolsEnabled": true, + "LastKnownBlockVersion-Alt": 0, + "LastKnownBlockVersion-Major": 2, + "LastKnownBlockVersion-Minor": 0, + "MaxConcurrencyBulkSync": 1, + "MaxConcurrencyDeadline": 2, + "PBftSignatureThreshold": 0.6, + "Protocol": "Cardano", + "RequiresNetworkMagic": "RequiresMagic", + "ShelleyGenesisFile": "genesis.shelley.spec.json", + "ShelleyGenesisHash": "9ae14531b6f0a3cd958b050310fd9fca9474b94c85fc9a2f79f9353f4ed0cf7f", + "SocketPath": "db/node.socket", + "TestShelleyHardForkAtEpoch": 0, + "TraceBlockFetchClient": false, + "TraceBlockFetchDecisions": false, + "TraceBlockFetchProtocol": false, + "TraceBlockFetchProtocolSerialised": false, + "TraceBlockFetchServer": false, + "TraceBlockchainTime": true, + "TraceChainDb": true, + "TraceChainSyncBlockServer": false, + "TraceChainSyncClient": false, + "TraceChainSyncHeaderServer": false, + "TraceChainSyncProtocol": false, + "TraceConnectionManager": true, + "TraceDnsResolver": true, + "TraceDnsSubscription": true, + "TraceErrorPolicy": true, + "TraceForge": true, + "TraceHandshake": false, + "TraceIpSubscription": true, + "TraceLocalChainSyncProtocol": false, + "TraceLocalConnectionManager": false, + "TraceLocalErrorPolicy": true, + "TraceLocalHandshake": false, + "TraceLocalRootPeers": true, + "TraceLocalServer": false, + "TraceLocalTxSubmissionProtocol": false, + "TraceLocalTxSubmissionServer": false, + "TraceMempool": true, + "TraceMux": false, + "TracePeerSelection": true, + "TracePeerSelectionActions": true, + "TracePublicRootPeers": true, + "TraceServer": true, + "TraceTxInbound": false, + "TraceTxOutbound": false, + "TraceTxSubmissionProtocol": false, + "TurnOnLogMetrics": false, + "defaultBackends": [ + "KatipBK" + ], + "defaultScribes": [ + [ + "FileSK", + "logs/mainnet.log" + ], + [ + "StdoutSK", + "stdout" + ] + ], + "minSeverity": "Debug", + "options": {}, + "rotation": { + "rpKeepFilesNum": 3, + "rpLogLimitBytes": 5000000, + "rpMaxAgeHours": 24 + }, + "setupBackends": [ + "KatipBK" + ], + "setupScribes": [ + { + "scFormat": "ScJson", + "scKind": "FileSK", + "scName": "logs/node.log" + }, + { + "scFormat": "ScJson", + "scKind": "StdoutSK", + "scName": "stdout" + } + ] +} \ No newline at end of file diff --git a/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.yaml b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.yaml new file mode 100644 index 0000000000..48542dcfcb --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/files/input/check-node-configuration/node-config.yaml @@ -0,0 +1,292 @@ +################################################################################ +# Mainnet Cardano Node Configuration + +##### Locations ##### + +AlonzoGenesisFile: genesis.alonzo.spec.json +AlonzoGenesisHash: 2418fe881f57d2f5851a018214634aa6d1b7f10f130c3bdf8c13210c0ed2fd02 +ByronGenesisFile: genesis.byron.spec.json +ByronGenesisHash: b91cb9a87b244fbb6f8d60a809475705594b6aa9a9aa5dcb6be8020549def9f5 +ConwayGenesisFile: genesis.conway.spec.json +ConwayGenesisHash: 65d481eec0b24ef90f7bbeaf6933fdf9629ce89afe88238e5da4ec79977a28d1 +ShelleyGenesisFile: genesis.shelley.spec.json +ShelleyGenesisHash: 9ae14531b6f0a3cd958b050310fd9fca9474b94c85fc9a2f79f9353f4ed0cf7f + +EnableP2P: true + +##### Core protocol parameters ##### + +Protocol: Cardano + +# The mainnet does not include the network magic into addresses. Testnets do. +RequiresNetworkMagic: RequiresNoMagic + +##### Update system parameters ##### + +# This protocol version number gets used by block producing nodes as part +# of the system for agreeing on and synchronising protocol updates. +# +# See https://github.com/intersectmbo/cardano-node/blob/master/cardano-node/src/Cardano/Node/Protocol/Cardano.hs#L199 +LastKnownBlockVersion-Major: 3 +LastKnownBlockVersion-Minor: 0 +LastKnownBlockVersion-Alt: 0 +MaxKnownMajorProtocolVersion: 2 + +##### Network Configuration ##### + +PeerSharing: True +TargetNumberOfActivePeers: 20 +TargetNumberOfEstablishedPeers: 50 +TargetNumberOfKnownPeers: 150 +TargetNumberOfRootPeers: 60 + +##### Version Information ##### + +MinNodeVersion: 8.12.0 + +##### Logging configuration ##### + +# Enable or disable logging overall +TurnOnLogging: True + +# Enable the collection of various OS metrics such as memory and CPU use. +# These metrics are traced in the context name: 'cardano.node.metrics' and can +# be directed to the logs or monitoring backends. +TurnOnLogMetrics: True + +# Global logging severity filter. Messages must have at least this severity to +# pass. Typical values would be Warning, Notice, Info or Debug. +minSeverity: Info + +# Log items can be rendered with more or less verbose detail. +# Verbosity ranges from MinimalVerbosity, NormalVerbosity to MaximalVerbosity +TracingVerbosity: NormalVerbosity + +# The system supports a number of backends for logging and monitoring. +# This setting lists the backends that will be available to use in the +# configuration below. The logging backend is called Katip. +setupBackends: + - KatipBK + +# This specifies the default backends that trace output is sent to if it +# is not specifically configured to be sent to other backends. +defaultBackends: + - KatipBK + +# EKG is a simple metrics monitoring system. Uncomment the following to enable +# this backend and listen on the given local port and point your web browser to +# http://localhost:12788/ +hasEKG: 12788 + +# The Prometheus monitoring system exports EKG metrics. Uncomment the following +# to listen on the given port. Output is provided on +# http://localhost:12789/metrics +# hasPrometheus: +# - "127.0.0.1" +# - 12789 + +# To enable the legacy 'TraceForwarder' backend, uncomment the following setting. Log +# items are then forwarded based on an entry in 'mapBackends' to a separate +# process running a 'TraceAcceptor'. +# Example using UNIX pipes: +# traceForwardTo: +# tag: RemotePipe +# contents: "logs/pipe" +# +# Example using Windows named pipes: +# traceForwardTo: +# tag: RemotePipe +# contents: "\\\\.\\pipe\\acceptor" +# +# Example using network socket: +# traceForwardTo: +# tag: RemoteSocket +# contents: +# - "127.0.0.1" +# - "2997" + +# For the Katip logging backend we must set up outputs (called scribes) +# The available types of scribe are: +# FileSK for files +# StdoutSK/StderrSK for stdout/stderr +# JournalSK for systemd's journal system +# DevNullSK ignores all output +# The scribe output format can be ScText or ScJson. Log rotation settings can +# be specified in the defaults below or overridden on a per-scribe basis here. +setupScribes: + - scKind: StdoutSK + scName: stdout + scFormat: ScText + scRotation: null + +# For the Katip logging backend this specifies the default scribes that trace +# output is sent to if it is not configured to be sent to other scribes. +defaultScribes: + - - StdoutSK + - stdout + +# The default file rotation settings for katip scribes, unless overridden +# in the setupScribes above for specific scribes. +rotation: + rpLogLimitBytes: 5000000 + rpKeepFilesNum: 10 + rpMaxAgeHours: 24 + + +##### Coarse grained logging control ##### + +# Trace output from whole subsystems can be enabled/disabled using the following +# settings. This provides fairly coarse grained control, but it is relatively +# efficient at filtering out unwanted trace output. + +TraceAcceptPolicy: True + +# Trace BlockFetch client. +TraceBlockFetchClient: False + +# Trace BlockFetch decisions made by the BlockFetch client. +TraceBlockFetchDecisions: False + +# Trace BlockFetch protocol messages. +TraceBlockFetchProtocol: False + +# Serialised Trace BlockFetch protocol messages. +TraceBlockFetchProtocolSerialised: False + +# Trace BlockFetch server. +TraceBlockFetchServer: False + +# Trace BlockchainTime. +# TraceBlockchainTime: False + +# Verbose tracer of ChainDB +TraceChainDb: True + +# Trace ChainSync client. +TraceChainSyncClient: False + +# Trace ChainSync server (blocks). +TraceChainSyncBlockServer: False + +# Trace ChainSync server (headers). +TraceChainSyncHeaderServer: False + +# Trace ChainSync protocol messages. +TraceChainSyncProtocol: False + +TraceConnectionManager: True + +# Trace DNS Resolver messages. +TraceDNSResolver: True + +# Trace DNS Subscription messages. +TraceDNSSubscription: True + +TraceDiffusionInitialization: True + +# Trace error policy resolution. +TraceErrorPolicy: True + +# Trace local error policy resolution. +TraceLocalErrorPolicy: True + +# Trace block forging. +TraceForge: True + +# Trace Handshake protocol messages. +TraceHandshake: True + +# Trace IP Subscription messages. +TraceIpSubscription: True + +TraceLedgerPeers: True + +TraceLocalRootPeers: True + +TraceInboundGovernor: True + +TracePeerSelection: True + +TracePeerSelectionActions: True + +TracePublicRootPeers: True + +TraceServer: True + + +# Trace local ChainSync protocol messages. +TraceLocalChainSyncProtocol: False + +# Trace local connection manager messages. +TraceLocalConnectionManager: True + +# Trace local Handshake protocol messages. +TraceLocalHandshake: True + +# Trace local TxSubmission protocol messages. +TraceLocalTxSubmissionProtocol: False + +# Trace local TxSubmission server. +TraceLocalTxSubmissionServer: False + +# Trace mempool. +TraceMempool: False + +# Trace Mux Events. +TraceMux: False + +# Trace TxSubmission server (inbound transactions). +TraceTxInbound: False + +# Trace TxSubmission client (outbound transactions). +TraceTxOutbound: False + +# Trace TxSubmission protocol messages. +TraceTxSubmissionProtocol: False + +##### Fine grained logging control ##### + +# It is also possible to have more fine grained control over filtering of +# trace output, and to match and route trace output to particular backends. +# This is less efficient than the coarse trace filters above but provides +# much more precise control. + +options: + + # This routes metrics matching specific names to particular backends. + # This overrides the 'defaultBackends' listed above. And note that it is + # an override and not an extension so anything matched here will not + # go to the default backend, only to the explicitly listed backends. + mapBackends: + cardano.node.metrics: + - EKGViewBK + + cardano.node.resources: + - EKGViewBK + + # # redirects traced values to a specific scribe which is identified by its + # # type and its name, separated by "::": + # mapScribes: + # cardano.node.metrics: + # - "FileSK::logs/mainnet.log" + mapSubtrace: + cardano.node.metrics: + subtrace: Neutral + +hasPrometheus: + - 127.0.0.1 + - 12798 + +# Set or unset the mempool capacity override in number of bytes. +# +# This is intended for testing, and for low-resource machines to run with a smaller mempool. +# Please note that running with a large mempool is NOT recommended. The mempool is a +# just a network communication buffer and all the advice on "buffer bloat" applies, see: +# https://en.wikipedia.org/wiki/Bufferbloat +# The default size is two blocks, which is generally enough to ensure full blocks. +# +# MempoolCapacityBytesOverride: Integer | NoOverride +# +# Examples: +# MempoolCapacityBytesOverride: 1000000 (1MB) +# MempoolCapacityBytesOverride: NoOverride (default)