diff --git a/.gitattributes b/.gitattributes index 6370e879f22..5a706b986af 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,3 +5,5 @@ configuration/cardano/mainnet-alonzo-genesis.json text eol=lf configuration/cardano/mainnet-byron-genesis.json text eol=lf configuration/cardano/mainnet-conway-genesis.json text eol=lf configuration/cardano/mainnet-shelley-genesis.json text eol=lf +cardano-testnet/test/cardano-testnet-test/files/sample-proposal-anchor text eol=lf +cardano-testnet/test/cardano-testnet-test/files/sample-constitution-anchor text eol=lf diff --git a/cardano-testnet/cardano-testnet.cabal b/cardano-testnet/cardano-testnet.cabal index e63951e3c34..981721072d8 100644 --- a/cardano-testnet/cardano-testnet.cabal +++ b/cardano-testnet/cardano-testnet.cabal @@ -36,7 +36,7 @@ library , ansi-terminal , bytestring , cardano-api ^>= 10.6 - , cardano-cli ^>= 10.2 + , cardano-cli:{cardano-cli, cardano-cli-test-lib} ^>= 10.2 , cardano-crypto-class , cardano-crypto-wrapper , cardano-git-rev ^>= 0.2.2 @@ -65,6 +65,7 @@ library , hedgehog-extras >= 0.6.4 && <0.6.5.1 , lens-aeson , microlens + , monad-control , mono-traversable , mtl , network @@ -204,6 +205,7 @@ test-suite cardano-testnet-test Cardano.Testnet.Test.Gov.PredefinedAbstainDRep Cardano.Testnet.Test.Gov.ProposeNewConstitution Cardano.Testnet.Test.Gov.ProposeNewConstitutionSPO + Cardano.Testnet.Test.Gov.Transaction.HashMismatch Cardano.Testnet.Test.Gov.TreasuryDonation Cardano.Testnet.Test.Gov.TreasuryGrowth Cardano.Testnet.Test.Gov.TreasuryWithdrawal @@ -220,7 +222,7 @@ test-suite cardano-testnet-test , base16-bytestring , bytestring , cardano-api:{cardano-api, internal} - , cardano-cli + , cardano-cli:{cardano-cli, cardano-cli-test-lib} , cardano-crypto-class , cardano-ledger-conway , cardano-ledger-core @@ -240,6 +242,7 @@ test-suite cardano-testnet-test , lens , lens-aeson , microlens + , monad-control , mtl , process , regex-compat diff --git a/cardano-testnet/src/Testnet/Process/Cli/DRep.hs b/cardano-testnet/src/Testnet/Process/Cli/DRep.hs index cf3a1ba7c31..5f3b5e3f4e7 100644 --- a/cardano-testnet/src/Testnet/Process/Cli/DRep.hs +++ b/cardano-testnet/src/Testnet/Process/Cli/DRep.hs @@ -1,5 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} @@ -26,6 +27,7 @@ import Prelude import Control.Monad (forM, void) import Control.Monad.Catch (MonadCatch) +import Control.Monad.Trans.Control (MonadBaseControl) import qualified Data.Aeson as Aeson import qualified Data.Aeson.Lens as AL import Data.Text (Text) @@ -35,11 +37,13 @@ import Data.Word (Word16) import GHC.Exts (fromString) import GHC.Stack import Lens.Micro ((^?)) +import System.Directory (makeAbsolute) import System.FilePath (()) +import Test.Cardano.CLI.Hash (serveFilesWhile) import Testnet.Components.Query import Testnet.Process.Cli.Transaction -import Testnet.Process.Run (execCli', execCliStdoutToJson) +import Testnet.Process.Run (addEnvVarsToConfig, execCli', execCliStdoutToJson) import Testnet.Types import Hedgehog (MonadTest, evalMaybe) @@ -339,7 +343,7 @@ getLastPParamUpdateActionId execConfig = do -- | Create a proposal to change the DRep activity interval. -- Return the transaction id and the index of the governance action. makeActivityChangeProposal - :: (HasCallStack, H.MonadAssertion m, MonadTest m, MonadCatch m, MonadIO m, Typeable era) + :: (HasCallStack, MonadBaseControl IO m, H.MonadAssertion m, MonadTest m, MonadCatch m, MonadIO m, Typeable era) => H.ExecConfig -- ^ Specifies the CLI execution configuration. -> EpochStateView -- ^ Current epoch state view for transaction building. It can be obtained -- using the 'getEpochStateView' function. @@ -361,44 +365,52 @@ makeActivityChangeProposal execConfig epochStateView ceo work baseDir <- H.createDirectoryIfMissing work - proposalAnchorFile <- H.note $ baseDir "sample-proposal-anchor" - H.writeFile proposalAnchorFile $ - unlines [ "These are the reasons: " , "" , "1. First" , "2. Second " , "3. Third" ] - + let proposalAnchorDataIpfsHash = "QmexFJuEn5RtnHEqpxDcqrazdHPzAwe7zs2RxHLfMH5gBz" + proposalAnchorFile <- H.noteM $ liftIO $ makeAbsolute $ "test" "cardano-testnet-test" "files" "sample-proposal-anchor" proposalAnchorDataHash <- execCli' execConfig - [ "hash", "anchor-data", "--file-text", proposalAnchorFile + [ "hash", "anchor-data", "--file-binary", proposalAnchorFile ] - minDRepDeposit <- getMinDRepDeposit epochStateView ceo + proposalFile <- H.note $ baseDir "proposa-file" - proposalFile <- H.note $ baseDir "sample-proposal-anchor" + minDRepDeposit <- getMinDRepDeposit epochStateView ceo - void $ execCli' execConfig $ - [ "conway", "governance", "action", "create-protocol-parameters-update" - , "--testnet" - , "--governance-action-deposit", show @Integer minDRepDeposit - , "--deposit-return-stake-verification-key-file", stakeVkeyFp - ] ++ concatMap (\(prevGovernanceActionTxId, prevGovernanceActionIndex) -> - [ "--prev-governance-action-tx-id", prevGovernanceActionTxId - , "--prev-governance-action-index", show prevGovernanceActionIndex - ]) prevGovActionInfo ++ - [ "--drep-activity", show (unEpochInterval drepActivity) - , "--anchor-url", "https://tinyurl.com/3wrwb2as" - , "--anchor-data-hash", proposalAnchorDataHash - , "--out-file", proposalFile - ] + let relativeUrl = ["ipfs", proposalAnchorDataIpfsHash] proposalBody <- H.note $ baseDir "tx.body" txIn <- findLargestUtxoForPaymentKey epochStateView sbe wallet - void $ execCli' execConfig - [ "conway", "transaction", "build" - , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet - , "--tx-in", Text.unpack $ renderTxIn txIn - , "--proposal-file", proposalFile - , "--out-file", proposalBody - ] + -- Create temporary HTTP server with files required by the call to `cardano-cli` + -- In this case, the server emulates an IPFS gateway + serveFilesWhile + [(relativeUrl, proposalAnchorFile)] + ( \port -> do + let execConfig' = addEnvVarsToConfig execConfig [("IPFS_GATEWAY_URI", "http://localhost:" ++ show port ++ "/")] + void $ execCli' execConfig' $ + [ "conway", "governance", "action", "create-protocol-parameters-update" + , "--testnet" + , "--governance-action-deposit", show @Integer minDRepDeposit + , "--deposit-return-stake-verification-key-file", stakeVkeyFp + ] ++ concatMap (\(prevGovernanceActionTxId, prevGovernanceActionIndex) -> + [ "--prev-governance-action-tx-id", prevGovernanceActionTxId + , "--prev-governance-action-index", show prevGovernanceActionIndex + ]) prevGovActionInfo ++ + [ "--drep-activity", show (unEpochInterval drepActivity) + , "--anchor-url", "ipfs://" ++ proposalAnchorDataIpfsHash + , "--anchor-data-hash", proposalAnchorDataHash + , "--check-anchor-data" + , "--out-file", proposalFile + ] + + void $ execCli' execConfig' + [ "conway", "transaction", "build" + , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet + , "--tx-in", Text.unpack $ renderTxIn txIn + , "--proposal-file", proposalFile + , "--out-file", proposalBody + ] + ) signedProposalTx <- signTx execConfig cEra baseDir "signed-proposal" (File proposalBody) [Some $ paymentKeyInfoPair wallet] diff --git a/cardano-testnet/src/Testnet/Process/Run.hs b/cardano-testnet/src/Testnet/Process/Run.hs index 8c0be2f8612..87f160873f8 100644 --- a/cardano-testnet/src/Testnet/Process/Run.hs +++ b/cardano-testnet/src/Testnet/Process/Run.hs @@ -18,6 +18,7 @@ module Testnet.Process.Run , mkExecConfigOffline , ProcessError(..) , ExecutableError(..) + , addEnvVarsToConfig ) where import Prelude @@ -33,6 +34,7 @@ import qualified Data.Aeson as Aeson import qualified Data.ByteString.Lazy as LBS import Data.Function import qualified Data.List as List +import Data.Maybe (fromMaybe) import Data.Monoid (Last (..)) import Data.String (fromString) import qualified Data.Text as Text @@ -193,6 +195,16 @@ mkExecConfig tempBaseAbsPath sprocket networkId = do , H.execConfigCwd = Last $ Just tempBaseAbsPath } +-- | Adds environment variables to an 'ExecConfig' that may already +-- have some environment variables set. This is done by prepending the new +-- environment variables to the existing ones. +addEnvVarsToConfig :: H.ExecConfig -> [(String, String)] -> H.ExecConfig +addEnvVarsToConfig execConfig newEnvVars = + execConfig { H.execConfigEnv = Last $ Just $ newEnvVars <> prevEnvVars } + where + prevEnvVars :: [(String, String)] + prevEnvVars = fromMaybe [] . getLast $ H.execConfigEnv execConfig + -- | Creates an 'ExecConfig' that can be used to run a process offline. -- e.g cardano-cli without a node running. mkExecConfigOffline :: () diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Transaction/RegisterDeregisterStakeAddress.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Transaction/RegisterDeregisterStakeAddress.hs index a27e01a1f89..d864f61db17 100644 --- a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Transaction/RegisterDeregisterStakeAddress.hs +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/Transaction/RegisterDeregisterStakeAddress.hs @@ -40,7 +40,7 @@ import qualified Hedgehog.Extras as H -- | Execute me with: -- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/register deregister stake address in transaction build/"'@ hprop_tx_register_deregister_stake_address :: Property -hprop_tx_register_deregister_stake_address = integrationWorkspace "register-deregister-stake-address" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do +hprop_tx_register_deregister_stake_address = integrationWorkspace "register-deregister-stake-addr" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do -- Start a local test net conf@Conf { tempAbsPath } <- mkConf tempAbsBasePath' let tempAbsPath' = unTmpAbsPath tempAbsPath diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/CommitteeAddNew.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/CommitteeAddNew.hs index cc60d11aa78..63fb3164dfb 100644 --- a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/CommitteeAddNew.hs +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/CommitteeAddNew.hs @@ -33,8 +33,10 @@ import qualified Data.Text as Text import GHC.Exts (IsList (..)) import GHC.Stack import Lens.Micro +import System.Directory (makeAbsolute) import System.FilePath (()) +import Test.Cardano.CLI.Hash (serveFilesWhile) import Testnet.Components.Configuration import Testnet.Components.Query import Testnet.Defaults @@ -44,7 +46,7 @@ import Testnet.Process.Cli.Keys import qualified Testnet.Process.Cli.SPO as SPO import Testnet.Process.Cli.SPO (createStakeKeyRegistrationCertificate) import Testnet.Process.Cli.Transaction -import Testnet.Process.Run (execCli', mkExecConfig) +import Testnet.Process.Run (addEnvVarsToConfig, execCli', mkExecConfig) import Testnet.Property.Util (integrationWorkspace) import Testnet.Start.Types (GenesisOptions (..), cardanoNumPools) import Testnet.Types @@ -106,17 +108,15 @@ hprop_constitutional_committee_add_new = integrationWorkspace "constitutional-co H.note_ $ "Foldblocks config file: " <> unFile configurationFile gov <- H.createDirectoryIfMissing $ work "governance" - proposalAnchorFp <- H.note $ gov "sample-proposal-anchor" - proposalDataFp <- H.note $ gov "sample-proposal-data" - updateCommitteeFp <- H.note $ gov "update-cc.action" - H.writeFile proposalAnchorFp $ - unlines [ "These are the reasons: " , "" , "1. First" , "2. Second " , "3. Third" ] - H.writeFile proposalDataFp "dummy proposal data" + let proposalAnchorDataIpfsHash = "QmexFJuEn5RtnHEqpxDcqrazdHPzAwe7zs2RxHLfMH5gBz" + proposalAnchorFile <- H.noteM $ liftIO $ makeAbsolute $ "test" "cardano-testnet-test" "files" "sample-proposal-anchor" + + updateCommitteeFp <- H.note $ gov "update-cc.action" proposalAnchorDataHash <- execCli' execConfig [ "hash", "anchor-data" - , "--file-text", proposalAnchorFp + , "--file-text", proposalAnchorFile ] let ccColdSKeyFp n = gov "cc-" <> show n <> "-cold.skey" @@ -183,30 +183,42 @@ hprop_constitutional_committee_add_new = integrationWorkspace "constitutional-co EpochNo epochNo <- H.noteShowM $ getCurrentEpochNo epochStateView let ccExpiryEpoch = epochNo + 200 - _ <- execCli' execConfig $ - [ eraName, "governance", "action" , "update-committee" - , "--testnet" - , "--anchor-url", "https://tinyurl.com/3wrwb2as" - , "--anchor-data-hash", proposalAnchorDataHash - , "--governance-action-deposit", show minGovActDeposit - , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys - , "--threshold", "0.2" - , "--out-file", updateCommitteeFp - ] - <> concatMap - (\fp -> ["--add-cc-cold-verification-key-file", fp, "--epoch", show ccExpiryEpoch]) - ccColdKeyFps + let relativeUrl = ["ipfs", proposalAnchorDataIpfsHash] txbodyFp <- H.note $ work "tx.body" txin1' <- findLargestUtxoForPaymentKey epochStateView sbe wallet0 - void $ execCli' execConfig - [ eraName, "transaction", "build" - , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet0 - , "--tx-in", Text.unpack $ renderTxIn txin1' - , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show @Int 5_000_000 - , "--proposal-file", updateCommitteeFp - , "--out-file", txbodyFp - ] + + -- Create temporary HTTP server with files required by the call to `cardano-cli` + -- In this case, the server emulates an IPFS gateway + serveFilesWhile + [(relativeUrl, proposalAnchorFile)] + ( \port -> do + let execConfig' = addEnvVarsToConfig execConfig [("IPFS_GATEWAY_URI", "http://localhost:" ++ show port ++ "/")] + + void $ execCli' execConfig' $ + [ eraName, "governance", "action" , "update-committee" + , "--testnet" + , "--anchor-url", "ipfs://" ++ proposalAnchorDataIpfsHash + , "--anchor-data-hash", proposalAnchorDataHash + , "--check-anchor-data" + , "--governance-action-deposit", show minGovActDeposit + , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys + , "--threshold", "0.2" + , "--out-file", updateCommitteeFp + ] + <> concatMap + (\fp -> ["--add-cc-cold-verification-key-file", fp, "--epoch", show ccExpiryEpoch]) + ccColdKeyFps + + void $ execCli' execConfig' + [ eraName, "transaction", "build" + , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet0 + , "--tx-in", Text.unpack $ renderTxIn txin1' + , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show @Int 5_000_000 + , "--proposal-file", updateCommitteeFp + , "--out-file", txbodyFp + ] + ) -- double check that we're starting with an empty committee committeeMembers <- getCommitteeMembers epochStateView ceo diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/DRepActivity.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/DRepActivity.hs index 20eb2b5c9a5..a1f499356f5 100644 --- a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/DRepActivity.hs +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/DRepActivity.hs @@ -24,6 +24,7 @@ import Prelude import Control.Monad import Control.Monad.Catch (MonadCatch) +import Control.Monad.Trans.Control (MonadBaseControl) import Data.Data (Typeable) import Data.Default.Class import qualified Data.Map as Map @@ -197,8 +198,8 @@ hprop_check_drep_activity = integrationWorkspace "test-activity" $ \tempAbsBaseP -- and issues the specified votes using default DReps. Optionally, it also -- waits checks the expected effect of the proposal. activityChangeProposalTest - :: forall m t era . (HasCallStack, MonadTest m, MonadIO m, H.MonadAssertion m, MonadCatch m, Foldable t, Typeable era, - EraGov (ShelleyLedgerEra era), ConwayEraPParams (ShelleyLedgerEra era)) + :: forall m t era . (HasCallStack, MonadBaseControl IO m, MonadTest m, MonadIO m, H.MonadAssertion m, + MonadCatch m, Foldable t, Typeable era, EraGov (ShelleyLedgerEra era), ConwayEraPParams (ShelleyLedgerEra era)) => H.ExecConfig -- ^ Specifies the CLI execution configuration. -> EpochStateView -- ^ Current epoch state view for transaction building. It can be obtained -- using the 'getEpochStateView' function. diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/InfoAction.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/InfoAction.hs index dd8b3645b12..4c961ba4e2c 100644 --- a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/InfoAction.hs +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/InfoAction.hs @@ -31,13 +31,15 @@ import Data.String import qualified Data.Text as Text import Data.Word import GHC.Stack +import System.Directory (makeAbsolute) import System.FilePath (()) +import Test.Cardano.CLI.Hash (serveFilesWhile) import Testnet.Components.Query import Testnet.Defaults import Testnet.Process.Cli.Keys import Testnet.Process.Cli.SPO (createStakeKeyRegistrationCertificate) -import Testnet.Process.Run (execCli', mkExecConfig) +import Testnet.Process.Run (addEnvVarsToConfig, execCli', mkExecConfig) import Testnet.Property.Util (integrationRetryWorkspace) import Testnet.Start.Types import Testnet.Types @@ -85,15 +87,14 @@ hprop_ledger_events_info_action = integrationRetryWorkspace 2 "info-hash" $ \tem H.note_ $ "Foldblocks config file: " <> unFile configurationFile gov <- H.createDirectoryIfMissing $ work "governance" - proposalAnchorFile <- H.note $ work gov "sample-proposal-anchor" - infoActionFp <- H.note $ work gov "info.action" - -- pls configure your editors to trim trailing whitespace >.> - H.writeFile proposalAnchorFile $ - unlines [ "These are the reasons: " , "" , "1. First" , "2. Second " , "3. Third" ] + let proposalAnchorDataIpfsHash = "QmexFJuEn5RtnHEqpxDcqrazdHPzAwe7zs2RxHLfMH5gBz" + proposalAnchorFile <- H.noteM $ liftIO $ makeAbsolute $ "test" "cardano-testnet-test" "files" "sample-proposal-anchor" + + infoActionFp <- H.note $ work gov "info.action" proposalAnchorDataHash <- execCli' execConfig - [ "hash", "anchor-data", "--file-text", proposalAnchorFile + [ "hash", "anchor-data", "--file-binary", proposalAnchorFile ] -- Register stake address @@ -137,31 +138,44 @@ hprop_ledger_events_info_action = integrationRetryWorkspace 2 "info-hash" $ \tem -- make sure that stake registration cert gets into a block _ <- waitForBlocks epochStateView 1 - -- Create info action proposal - - void $ execCli' execConfig - [ eraName, "governance", "action", "create-info" - , "--testnet" - , "--governance-action-deposit", show @Int 1_000_000 -- TODO: Get this from the node - , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys - , "--anchor-url", "https://tinyurl.com/3wrwb2as" - , "--anchor-data-hash", proposalAnchorDataHash - , "--out-file", infoActionFp - ] + let relativeUrl = ["ipfs", proposalAnchorDataIpfsHash] txbodyFp <- H.note $ work "tx.body" txbodySignedFp <- H.note $ work "tx.body.signed" - txin2 <- findLargestUtxoForPaymentKey epochStateView sbe wallet1 - - H.noteM_ $ execCli' execConfig - [ eraName, "transaction", "build" - , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet1 - , "--tx-in", Text.unpack $ renderTxIn txin2 - , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show @Int 5_000_000 - , "--proposal-file", infoActionFp - , "--out-file", txbodyFp - ] + -- Create temporary HTTP server with files required by the call to `cardano-cli` + -- In this case, the server emulates an IPFS gateway + serveFilesWhile + [(relativeUrl, proposalAnchorFile)] + ( \port -> do + let execConfig' = addEnvVarsToConfig execConfig [("IPFS_GATEWAY_URI", "http://localhost:" ++ show port ++ "/")] + + void $ + execCli' + execConfig' + [ eraName, "governance", "action", "create-info" + , "--testnet" + , "--governance-action-deposit", show @Int 1_000_000 -- TODO: Get this from the node + , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys + , "--anchor-url", "ipfs://" ++ proposalAnchorDataIpfsHash + , "--anchor-data-hash", proposalAnchorDataHash + , "--check-anchor-data" + , "--out-file", infoActionFp + ] + + txin2 <- findLargestUtxoForPaymentKey epochStateView sbe wallet1 + + void $ + execCli' + execConfig' + [ eraName, "transaction", "build" + , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet1 + , "--tx-in", Text.unpack $ renderTxIn txin2 + , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show @Int 5_000_000 + , "--proposal-file", infoActionFp + , "--out-file", txbodyFp + ] + ) void $ execCli' execConfig [ eraName, "transaction", "sign" diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/ProposeNewConstitution.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/ProposeNewConstitution.hs index de60bc4d1cd..716c46c8ba9 100644 --- a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/ProposeNewConstitution.hs +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/ProposeNewConstitution.hs @@ -30,8 +30,10 @@ import Data.String import qualified Data.Text as Text import GHC.Exts (IsList (..)) import Lens.Micro +import System.Directory (makeAbsolute) import System.FilePath (()) +import Test.Cardano.CLI.Hash (serveFilesWhile) import Testnet.Components.Configuration import Testnet.Components.Query import Testnet.Defaults @@ -40,7 +42,7 @@ import Testnet.Process.Cli.DRep import Testnet.Process.Cli.Keys import Testnet.Process.Cli.SPO (createStakeKeyRegistrationCertificate) import Testnet.Process.Cli.Transaction -import Testnet.Process.Run (execCli', mkExecConfig) +import Testnet.Process.Run (addEnvVarsToConfig, execCli', mkExecConfig) import Testnet.Property.Util (integrationWorkspace) import Testnet.Start.Types import Testnet.Types @@ -102,21 +104,19 @@ hprop_ledger_events_propose_new_constitution = integrationWorkspace "propose-new -- Create Conway constitution gov <- H.createDirectoryIfMissing $ work "governance" - proposalAnchorFile <- H.note $ gov "sample-proposal-anchor" - constitutionFile <- H.note $ gov "sample-constitution" constitutionActionFp <- H.note $ gov "constitution.action" - H.writeFile proposalAnchorFile $ - unlines [ "These are the reasons: " , "" , "1. First" , "2. Second " , "3. Third" ] - H.copyFile - "test/cardano-testnet-test/files/input/sample-constitution.txt" - constitutionFile + let proposalAnchorDataIpfsHash = "QmexFJuEn5RtnHEqpxDcqrazdHPzAwe7zs2RxHLfMH5gBz" + proposalAnchorFile <- H.noteM $ liftIO $ makeAbsolute $ "test" "cardano-testnet-test" "files" "sample-proposal-anchor" + let constitutionAnchorDataIpfsHash = "QmXGkenkhh3NsotVwbNGToGsPuvJLgRT9aAz5ToyKAqdWP" + constitutionAnchorFile <- H.noteM $ liftIO $ makeAbsolute $ "test" "cardano-testnet-test" "files" "sample-proposal-anchor" + constitutionHash <- execCli' execConfig - [ "hash", "anchor-data", "--file-text", constitutionFile + [ "hash", "anchor-data", "--file-binary", constitutionAnchorFile ] proposalAnchorDataHash <- execCli' execConfig - [ "hash", "anchor-data", "--file-text", proposalAnchorFile + [ "hash", "anchor-data", "--file-binary", proposalAnchorFile ] -- Register stake address @@ -169,33 +169,48 @@ hprop_ledger_events_propose_new_constitution = integrationWorkspace "propose-new , "--script-file", guardRailScriptFp ] - minDRepDeposit <- getMinDRepDeposit epochStateView ceo - void $ execCli' execConfig - [ "conway", "governance", "action", "create-constitution" - , "--testnet" - , "--governance-action-deposit", show minDRepDeposit - , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys - , "--anchor-url", "https://tinyurl.com/3wrwb2as" - , "--anchor-data-hash", proposalAnchorDataHash - , "--constitution-url", "https://tinyurl.com/2pahcy6z" - , "--constitution-hash", constitutionHash - , "--constitution-script-hash", constitutionScriptHash - , "--out-file", constitutionActionFp - ] + let relativeUrlProposal = ["ipfs", proposalAnchorDataIpfsHash] + relativeUrlConstitution = ["ipfs", constitutionAnchorDataIpfsHash] txbodyFp <- H.note $ work "tx.body" + minDRepDeposit <- getMinDRepDeposit epochStateView ceo - H.noteShowM_ $ waitForBlocks epochStateView 1 - txin2 <- findLargestUtxoForPaymentKey epochStateView sbe wallet1 - - void $ execCli' execConfig - [ "conway", "transaction", "build" - , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet1 - , "--tx-in", Text.unpack $ renderTxIn txin2 - , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show @Int 5_000_000 - , "--proposal-file", constitutionActionFp - , "--out-file", txbodyFp + -- Create temporary HTTP server with files required by the call to `cardano-cli` + -- In this case, the server emulates an IPFS gateway + serveFilesWhile + [ (relativeUrlProposal, proposalAnchorFile) + , (relativeUrlConstitution, constitutionAnchorFile) ] + ( \port -> do + let execConfig' = addEnvVarsToConfig execConfig [("IPFS_GATEWAY_URI", "http://localhost:" ++ show port ++ "/")] + + void $ execCli' execConfig' + [ "conway", "governance", "action", "create-constitution" + , "--testnet" + , "--governance-action-deposit", show minDRepDeposit + , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys + , "--anchor-url", "ipfs://" ++ proposalAnchorDataIpfsHash + , "--anchor-data-hash", proposalAnchorDataHash + , "--check-anchor-data" + , "--constitution-url", "ipfs://" ++ constitutionAnchorDataIpfsHash + , "--constitution-hash", constitutionHash + , "--check-constitution-hash" + , "--constitution-script-hash", constitutionScriptHash + , "--out-file", constitutionActionFp + ] + + H.noteShowM_ $ waitForBlocks epochStateView 1 + txin2 <- findLargestUtxoForPaymentKey epochStateView sbe wallet1 + + void $ execCli' execConfig' + [ "conway", "transaction", "build" + , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet1 + , "--tx-in", Text.unpack $ renderTxIn txin2 + , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show @Int 5_000_000 + , "--proposal-file", constitutionActionFp + , "--out-file", txbodyFp + ] + ) signedProposalTx <- signTx execConfig cEra gov "signed-proposal" (File txbodyFp) [Some $ paymentKeyInfoPair wallet1] diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs new file mode 100644 index 00000000000..25e9e2eed2c --- /dev/null +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs @@ -0,0 +1,179 @@ +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} + +module Cardano.Testnet.Test.Gov.Transaction.HashMismatch + ( hprop_transaction_build_wrong_hash + ) where + +import Cardano.Api as Api +import Cardano.Api.Ledger (Coin (unCoin)) + +import Cardano.Testnet + +import Prelude + +import Control.Monad +import Data.Default.Class +import qualified Data.Text as Text +import GHC.IO.Exception (ExitCode (ExitFailure)) +import System.Directory (makeAbsolute) +import System.FilePath (()) + +import Test.Cardano.CLI.Hash (serveFilesWhile, tamperBase16Hash) +import Testnet.Components.Query +import Testnet.Process.Cli.Keys +import Testnet.Process.Run (addEnvVarsToConfig, execCli', execCliAny, mkExecConfig) +import Testnet.Property.Util (integrationRetryWorkspace) +import Testnet.Start.Types +import Testnet.Types + +import Hedgehog +import qualified Hedgehog as H +import qualified Hedgehog.Extras as H + +-- | Execute me with: +-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/Transaction Build Wrong Hash/'@ +hprop_transaction_build_wrong_hash :: Property +hprop_transaction_build_wrong_hash = integrationRetryWorkspace 2 "wrong-hash" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do + + conf@Conf { tempAbsPath } <- H.noteShowM $ mkConf tempAbsBasePath' + let tempAbsPath' = unTmpAbsPath tempAbsPath + tempBaseAbsPath = makeTmpBaseAbsPath tempAbsPath + + work <- H.createDirectoryIfMissing $ tempAbsPath' "work" + + let ceo = ConwayEraOnwardsConway + sbe = convert ceo + asbe = AnyShelleyBasedEra sbe + eraName = eraToString sbe + fastTestnetOptions = def { cardanoNodeEra = asbe } + shelleyOptions = def { genesisEpochLength = 200 } + + TestnetRuntime + { testnetMagic + , testnetNodes + , wallets=wallet0:wallet1:_ + , configurationFile + } + <- cardanoTestnetDefault fastTestnetOptions shelleyOptions conf + + node <- H.headM testnetNodes + poolSprocket1 <- H.noteShow $ nodeSprocket node + execConfig <- mkExecConfig tempBaseAbsPath poolSprocket1 testnetMagic + let socketPath = nodeSocketPath node + + epochStateView <- getEpochStateView configurationFile socketPath + + H.note_ $ "Sprocket: " <> show poolSprocket1 + H.note_ $ "Abs path: " <> tempAbsBasePath' + H.note_ $ "Socketpath: " <> unFile socketPath + H.note_ $ "Foldblocks config file: " <> unFile configurationFile + + gov <- H.createDirectoryIfMissing $ work "governance" + + let proposalAnchorDataIpfsHash = "QmexFJuEn5RtnHEqpxDcqrazdHPzAwe7zs2RxHLfMH5gBz" + proposalAnchorFile <- H.noteM $ liftIO $ makeAbsolute $ "test" "cardano-testnet-test" "files" "sample-proposal-anchor" + + infoActionFp <- H.note $ work gov "info.action" + + proposalAnchorDataHash <- execCli' execConfig + [ "hash", "anchor-data", "--file-binary", proposalAnchorFile + ] + + let stakeVkeyFp = gov "stake.vkey" + stakeSKeyFp = gov "stake.skey" + stakeCertFp = gov "stake.regcert" + stakeKeys = KeyPair { verificationKey = File stakeVkeyFp + , signingKey = File stakeSKeyFp + } + + cliStakeAddressKeyGen stakeKeys + + -- Register stake address + keyDeposit <- getKeyDeposit epochStateView ceo + + void $ execCli' execConfig + [ eraName, "stake-address", "registration-certificate" + , "--stake-verification-key-file", stakeVkeyFp + , "--key-reg-deposit-amt", show $ unCoin keyDeposit + , "--out-file", stakeCertFp + ] + + stakeCertTxBodyFp <- H.note $ work "stake.registration.txbody" + stakeCertTxSignedFp <- H.note $ work "stake.registration.tx" + + txin1 <- findLargestUtxoForPaymentKey epochStateView sbe wallet0 + + void $ execCli' execConfig + [ eraName, "transaction", "build" + , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet0 + , "--tx-in", Text.unpack $ renderTxIn txin1 + , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet1) <> "+" <> show @Int 10_000_000 + , "--certificate-file", stakeCertFp + , "--witness-override", show @Int 2 + , "--out-file", stakeCertTxBodyFp + ] + + void $ execCli' execConfig + [ eraName, "transaction", "sign" + , "--tx-body-file", stakeCertTxBodyFp + , "--signing-key-file", signingKeyFp $ paymentKeyInfoPair wallet0 + , "--signing-key-file", stakeSKeyFp + , "--out-file", stakeCertTxSignedFp + ] + + void $ execCli' execConfig + [ eraName, "transaction", "submit" + , "--tx-file", stakeCertTxSignedFp + ] + + let relativeUrl = ["ipfs", proposalAnchorDataIpfsHash] + + txbodyFp <- H.note $ work "tx.body" + + tamperedHash <- H.evalMaybe $ tamperBase16Hash proposalAnchorDataHash + + -- Create temporary HTTP server with files required by the call to `cardano-cli` + -- In this case, the server emulates an IPFS gateway + serveFilesWhile + [(relativeUrl, proposalAnchorFile)] + ( \port -> do + let execConfig' = addEnvVarsToConfig execConfig [("IPFS_GATEWAY_URI", "http://localhost:" ++ show port ++ "/")] + + minDepositAmount <- getMinGovActionDeposit epochStateView ceo + + void $ + execCli' + execConfig' + [ eraName, "governance", "action", "create-info" + , "--testnet" + , "--governance-action-deposit", show minDepositAmount + , "--deposit-return-stake-verification-key-file", stakeVkeyFp + , "--anchor-url", "ipfs://" ++ proposalAnchorDataIpfsHash + , "--anchor-data-hash", tamperedHash + , "--out-file", infoActionFp + ] + + txin2 <- findLargestUtxoForPaymentKey epochStateView sbe wallet1 + + (exitCode, _, stderrOutput) <- + execCliAny + execConfig' + [ eraName, "transaction", "build" + , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet1 + , "--tx-in", Text.unpack $ renderTxIn txin2 + , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show @Int 5_000_000 + , "--proposal-file", infoActionFp + , "--out-file", txbodyFp + ] + + exitCode H.=== ExitFailure 1 + + H.note_ stderrOutput + + H.assertWith (Text.pack stderrOutput) ("Hashes do not match!" `Text.isInfixOf`) + ) diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TreasuryWithdrawal.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TreasuryWithdrawal.hs index 6415f302200..586948cba13 100644 --- a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TreasuryWithdrawal.hs +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TreasuryWithdrawal.hs @@ -35,13 +35,15 @@ import qualified Data.Map.Strict as M import qualified Data.Text as Text import GHC.Stack import Lens.Micro +import System.Directory (makeAbsolute) import System.FilePath (()) +import Test.Cardano.CLI.Hash (serveFilesWhile) import Testnet.Components.Query import Testnet.Defaults import Testnet.Process.Cli.Keys (cliStakeAddressKeyGen) import Testnet.Process.Cli.SPO (createStakeKeyRegistrationCertificate) -import Testnet.Process.Run (execCli', mkExecConfig) +import Testnet.Process.Run (addEnvVarsToConfig, execCli', mkExecConfig) import Testnet.Property.Util (integrationRetryWorkspace) import Testnet.Start.Types import Testnet.Types @@ -88,15 +90,14 @@ hprop_ledger_events_treasury_withdrawal = integrationRetryWorkspace 2 "treasury H.note_ $ "Foldblocks config file: " <> unFile configurationFile gov <- H.createDirectoryIfMissing $ work "governance" - proposalAnchorFile <- H.note $ work gov "sample-proposal-anchor" - treasuryWithdrawalActionFp <- H.note $ work gov "treasury-withdrawal.action" - -- pls configure your editors to trim trailing whitespace >.> - H.writeFile proposalAnchorFile $ - unlines [ "These are the reasons: " , "" , "1. First" , "2. Second " , "3. Third" ] + let proposalAnchorDataIpfsHash = "QmexFJuEn5RtnHEqpxDcqrazdHPzAwe7zs2RxHLfMH5gBz" + proposalAnchorFile <- H.noteM $ liftIO $ makeAbsolute $ "test" "cardano-testnet-test" "files" "sample-proposal-anchor" + + treasuryWithdrawalActionFp <- H.note $ work gov "treasury-withdrawal.action" proposalAnchorDataHash <- execCli' execConfig - [ "hash", "anchor-data", "--file-text", proposalAnchorFile + [ "hash", "anchor-data", "--file-binary", proposalAnchorFile ] txin2 <- findLargestUtxoForPaymentKey epochStateView sbe wallet1 @@ -142,35 +143,45 @@ hprop_ledger_events_treasury_withdrawal = integrationRetryWorkspace 2 "treasury -- {{{ Create treasury withdrawal let withdrawalAmount = 3_300_777 :: Integer govActionDeposit <- getMinDRepDeposit epochStateView ceo - void $ execCli' execConfig - [ eraName, "governance", "action", "create-treasury-withdrawal" - , "--testnet" - , "--anchor-url", "https://tinyurl.com/3wrwb2as" - , "--anchor-data-hash", proposalAnchorDataHash - , "--governance-action-deposit", show govActionDeposit - , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys - , "--transfer", show withdrawalAmount - , "--funds-receiving-stake-verification-key-file", verificationKeyFp stakeKeys - , "--out-file", treasuryWithdrawalActionFp - ] + let relativeUrl = ["ipfs", proposalAnchorDataIpfsHash] txbodyFp <- H.note $ work "tx.body" txbodySignedFp <- H.note $ work "tx.body.signed" - -- wait for one block before using wallet0 again - _ <- waitForBlocks epochStateView 1 - txin3 <- findLargestUtxoForPaymentKey epochStateView sbe wallet0 - - void $ execCli' execConfig - [ eraName, "transaction", "build" - , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet0 - , "--tx-in", Text.unpack $ renderTxIn txin3 - , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet1) <> "+" <> show @Int 5_000_000 - , "--proposal-file", treasuryWithdrawalActionFp - , "--out-file", txbodyFp - ] + -- Create temporary HTTP server with files required by the call to `cardano-cli` + -- In this case, the server emulates an IPFS gateway + serveFilesWhile + [(relativeUrl, proposalAnchorFile)] + ( \port -> do + let execConfig' = addEnvVarsToConfig execConfig [("IPFS_GATEWAY_URI", "http://localhost:" ++ show port ++ "/")] + void $ execCli' execConfig' + [ eraName, "governance", "action", "create-treasury-withdrawal" + , "--testnet" + , "--anchor-url", "ipfs://" ++ proposalAnchorDataIpfsHash + , "--anchor-data-hash", proposalAnchorDataHash + , "--governance-action-deposit", show govActionDeposit + , "--deposit-return-stake-verification-key-file", verificationKeyFp stakeKeys + , "--transfer", show withdrawalAmount + , "--funds-receiving-stake-verification-key-file", verificationKeyFp stakeKeys + , "--out-file", treasuryWithdrawalActionFp + ] + + -- wait for one block before using wallet0 again + _ <- waitForBlocks epochStateView 1 + + txin3 <- findLargestUtxoForPaymentKey epochStateView sbe wallet0 + + void $ execCli' execConfig' + [ eraName, "transaction", "build" + , "--change-address", Text.unpack $ paymentKeyInfoAddr wallet0 + , "--tx-in", Text.unpack $ renderTxIn txin3 + , "--tx-out", Text.unpack (paymentKeyInfoAddr wallet1) <> "+" <> show @Int 5_000_000 + , "--proposal-file", treasuryWithdrawalActionFp + , "--out-file", txbodyFp + ] + ) void $ execCli' execConfig [ eraName, "transaction", "sign" diff --git a/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs b/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs index 8e993360147..0afabc4625c 100644 --- a/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs +++ b/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs @@ -20,6 +20,7 @@ import qualified Cardano.Testnet.Test.Gov.GovActionTimeout as Gov import qualified Cardano.Testnet.Test.Gov.InfoAction as LedgerEvents import qualified Cardano.Testnet.Test.Gov.PParamChangeFailsSPO as Gov import qualified Cardano.Testnet.Test.Gov.ProposeNewConstitution as Gov +import qualified Cardano.Testnet.Test.Gov.Transaction.HashMismatch as WrongHash import qualified Cardano.Testnet.Test.Gov.TreasuryDonation as Gov import qualified Cardano.Testnet.Test.Gov.TreasuryWithdrawal as Gov import qualified Cardano.Testnet.Test.Node.Shutdown @@ -68,6 +69,7 @@ tests = do , ignoreOnMacAndWindows "Treasury Withdrawal" Gov.hprop_ledger_events_treasury_withdrawal , ignoreOnWindows "PParam change fails for SPO" Gov.hprop_check_pparam_fails_spo , ignoreOnWindows "InfoAction" LedgerEvents.hprop_ledger_events_info_action + , ignoreOnWindows "Transaction Build Wrong Hash" WrongHash.hprop_transaction_build_wrong_hash ] , T.testGroup "Plutus" [ ignoreOnWindows "PlutusV3" Cardano.Testnet.Test.Cli.Conway.Plutus.hprop_plutus_v3] diff --git a/cardano-testnet/test/cardano-testnet-test/files/sample-constitution-anchor b/cardano-testnet/test/cardano-testnet-test/files/sample-constitution-anchor new file mode 100644 index 00000000000..4dbb452e8e6 --- /dev/null +++ b/cardano-testnet/test/cardano-testnet-test/files/sample-constitution-anchor @@ -0,0 +1,50 @@ +Preamble + +We, the zaniest inhabitants of the peculiar and bewildering land of Barataria, in honor of our illustrious Governor, Sancho Panza, renowned for his comically charming ordinances, do hereby present this Constitution to tickle your fancy and uphold the values of laughter, merriment, and the pursuit of hilarity for all our citizens. + +Article I: The Right to Absurdity + +Wine-Watering Rights: Every Baratarian shall have the inalienable right to water down their wine as they see fit, provided they can still manage a tipsy jig. + +Fashion Freedom: Citizens are encouraged to dress inappropriately for the sheer joy of it, as long as it does not involve the use of sharp objects, poisonous animals, or explosives. + +Article II: The Role of Government: Keeping It Lighthearted + +Official Clown: There shall be an official court jester whose duty is to make the Governor laugh at least once a day. Failure to amuse may result in banishment to a neighboring kingdom. + +Puns and Pranks: All government proceedings shall include at least one pun and one harmless prank per session to maintain the mirthful spirit of Barataria. + +Article III: The Economic Circus + +Foolish Redistribution: The government shall engage in a monthly "wealth lottery," redistributing riches by catapulting bags of gold into the air and letting them fall where they may. + +Tax Deductions for Silly Hats: Citizens who wear absurd hats shall receive generous tax deductions, fostering creativity and fashion-forward thinking. + +Article IV: Justice, Comedy, and the Absurd + +Trial by Tickling: In the interest of justice and merriment, all trials shall include a "tickle test" to determine guilt or innocence. Giggles are considered a sign of innocence. + +Innocent Until Proven Clueless: It shall be presumed that every Baratarian is innocent of any wrongdoing until they can convincingly demonstrate their utter cluelessness in court. + +Article V: Education and Clown Colleges + +Clown Colleges for All: Barataria shall establish Clown Colleges to ensure that every citizen has the opportunity to master the art of clowning and perform slapstick humor. + +Silly Science: Research grants shall be awarded to projects that explore the science of whoopee cushions, banana peels, and rubber chickens. + +Article VI: Defense and Pranks + +Pillow Fort Defense: Barataria's defense strategy shall revolve around building impregnable pillow forts and inviting would-be invaders to epic pillow fights to resolve conflicts. + +War Declarations through Whoopie Cushions: Before declaring war, Barataria shall send a diplomatic envoy to the offending nation armed only with whoopee cushions to express our discontent. + +Article VII: Amendments and Clown-novations + +Whimsical Amendments: Amendments to this Constitution shall be proposed in the form of a joke or a riddle, and they must receive a hearty laugh from at least three-quarters of the citizens to be adopted. +Article VIII: Final Pratfalls + +Ratification with a Pie in the Face: This Constitution shall be ratified in a grand ceremony involving a pie in the face of the official ratifier, ensuring a silly and sticky beginning for Barataria. + +Effective Clowning Date: This Constitution shall come into effect immediately upon the eruption of the first uncontrollable fit of laughter. + +In witness whereof, we, the undersigned jesters, pranksters, and merrymakers, do hereby establish and adopt this Constitution to make Barataria a haven of hilarity, where laughter reigns supreme, and seriousness is only allowed on April Fool's Day. \ No newline at end of file diff --git a/cardano-testnet/test/cardano-testnet-test/files/sample-proposal-anchor b/cardano-testnet/test/cardano-testnet-test/files/sample-proposal-anchor new file mode 100644 index 00000000000..5ccd92f3867 --- /dev/null +++ b/cardano-testnet/test/cardano-testnet-test/files/sample-proposal-anchor @@ -0,0 +1,5 @@ +These are the reasons: + +1. First +2. Second +3. Third diff --git a/flake.nix b/flake.nix index 0d63226bc9f..5b253a234c1 100644 --- a/flake.nix +++ b/flake.nix @@ -89,6 +89,11 @@ inherit (iohkNix.lib) prefixNamesWith; removeRecurse = lib.filterAttrsRecursive (n: _: n != "recurseForDerivations"); + macOS-security = pkgs: + # make `/usr/bin/security` available in `PATH`, which is needed for stack + # on darwin which calls this binary to find certificates + pkgs.writeScriptBin "security" ''exec /usr/bin/security "$@"''; + supportedSystems = import ./nix/supported-systems.nix; defaultSystem = head supportedSystems; customConfig = recursiveUpdate @@ -145,6 +150,9 @@ inherit (pkgs.stdenv) hostPlatform; project = pkgs.cardanoNodeProject; + macOS-security = + utils.writeScriptBin "security" ''exec /usr/bin/security "$@"''; + # This is used by `nix develop .` to open a devShell devShells = let @@ -401,6 +409,7 @@ inherit (final) haskell-nix; inherit (std) incl; inherit CHaP; + macOS-security = macOS-security (final.pkgs); }).appendModule [ customConfig.haskellNix ]; diff --git a/nix/haskell.nix b/nix/haskell.nix index 0d85d2415a4..e9aca8fe2dc 100644 --- a/nix/haskell.nix +++ b/nix/haskell.nix @@ -4,6 +4,7 @@ { haskell-nix , incl , CHaP +, macOS-security }: let @@ -282,7 +283,11 @@ let unset TMPDIR export TMPDIR=$(mktemp -d) export TMP=$TMPDIR - ''; + '' + (if pkgs.stdenv.hostPlatform.isDarwin + then '' + export PATH=${macOS-security}/bin:$PATH + '' + else ''''); packages.cardano-testnet.components.tests.cardano-testnet-golden.preCheck = let # This define files included in the directory that will be passed to `H.getProjectBase` for this test: