From 95bb7cf67acc572db9aade552e2c00dffee915c0 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Thu, 24 Oct 2024 14:22:17 +0200 Subject: [PATCH 01/13] Add temporary SRP stanza --- cabal.project | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cabal.project b/cabal.project index bf0e6636d6f..213d79efab9 100644 --- a/cabal.project +++ b/cabal.project @@ -32,6 +32,20 @@ packages: trace-resources trace-forward +source-repository-package + type: git + location: https://github.com/IntersectMBO/cardano-api + tag: d5e0a292ae459deff35fa00fbecb63133a3dcf9c + subdir: cardano-api + --sha256: sha256-AZeK0hiM+dROd4EUncCLnu9ONtnUGonS9ly2NdIJXVA= + +source-repository-package + type: git + location: https://github.com/IntersectMBO/cardano-cli + tag: d854349759700ad18089ae84f6157e1ba9f0b8b2 + subdir: cardano-cli + --sha256: sha256-7Nrh5i4hs/cgSOTBnicXQLfcOcClo/Ml0yuPBI2BRv8= + extra-packages: Cabal program-options From a722af14a482586ba9ae22ac7de9875586765b2e Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 23 Oct 2024 16:58:58 +0200 Subject: [PATCH 02/13] Update `hprop_ledger_events_info_action` to work with the new checks --- .gitattributes | 1 + cardano-testnet/cardano-testnet.cabal | 2 +- cardano-testnet/src/Testnet/Process/Run.hs | 12 ++++ .../Cardano/Testnet/Test/Gov/InfoAction.hs | 68 ++++++++++++------- .../files/sample-proposal-anchor | 5 ++ 5 files changed, 61 insertions(+), 27 deletions(-) create mode 100644 cardano-testnet/test/cardano-testnet-test/files/sample-proposal-anchor diff --git a/.gitattributes b/.gitattributes index 6370e879f22..f0c6ee73bf2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,3 +5,4 @@ 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 diff --git a/cardano-testnet/cardano-testnet.cabal b/cardano-testnet/cardano-testnet.cabal index 65dc8812e7e..6ec394b425e 100644 --- a/cardano-testnet/cardano-testnet.cabal +++ b/cardano-testnet/cardano-testnet.cabal @@ -220,7 +220,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 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/Gov/InfoAction.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/InfoAction.hs index a1567dfc74d..5c9d6f81104 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,13 +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" - H.writeFile proposalAnchorFile "dummy anchor data" + 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 @@ -132,31 +135,44 @@ hprop_ledger_events_info_action = integrationRetryWorkspace 2 "info-hash" $ \tem , "--tx-file", stakeCertTxSignedFp ] - -- 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/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 From e061d41461e4266dee4e442bcea54524baca5e0e Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 23 Oct 2024 18:23:12 +0200 Subject: [PATCH 03/13] Update `hprop_constitutional_committee_add_new` to work with the new checks --- .../Testnet/Test/Gov/CommitteeAddNew.hs | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) 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 4071e9ade89..eee2cc3d19a 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,16 +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 "dummy anchor data" - 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" @@ -179,30 +180,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 From a839d37384b54e7d1ff72e9889225076c8df6815 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 23 Oct 2024 18:51:03 +0200 Subject: [PATCH 04/13] Update `hprop_ledger_events_propose_new_constitution` to work with the new checks --- .gitattributes | 1 + .../Test/Gov/ProposeNewConstitution.hs | 78 ++++++++++++------- .../files/sample-constitution-anchor | 50 ++++++++++++ 3 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 cardano-testnet/test/cardano-testnet-test/files/sample-constitution-anchor diff --git a/.gitattributes b/.gitattributes index f0c6ee73bf2..5a706b986af 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,3 +6,4 @@ 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/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/ProposeNewConstitution.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/ProposeNewConstitution.hs index f692fc690cb..72d249af958 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 @@ -101,18 +103,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" - consitutionFile <- H.note $ gov "sample-constitution" constitutionActionFp <- H.note $ gov "constitution.action" - H.writeFile proposalAnchorFile "dummy anchor data" - H.writeFile consitutionFile "dummy constitution data" + 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", consitutionFile + [ "hash", "anchor-data", "--file-binary", constitutionAnchorFile ] proposalAnchorDataHash <- execCli' execConfig - [ "hash", "anchor-data", "--file-text", proposalAnchorFile + [ "hash", "anchor-data", "--file-binary", proposalAnchorFile ] -- Register stake address @@ -165,33 +168,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/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 From 0cc8eedfb2e02e658d5c38f1a7ace483bd71584f Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Thu, 24 Oct 2024 13:14:51 +0200 Subject: [PATCH 05/13] Update `makeActivityChangeProposal` to work with the new checks --- cardano-testnet/cardano-testnet.cabal | 4 +- .../src/Testnet/Process/Cli/DRep.hs | 70 +++++++++++-------- .../Cardano/Testnet/Test/Gov/DRepActivity.hs | 5 +- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/cardano-testnet/cardano-testnet.cabal b/cardano-testnet/cardano-testnet.cabal index 6ec394b425e..8188ab96c21 100644 --- a/cardano-testnet/cardano-testnet.cabal +++ b/cardano-testnet/cardano-testnet.cabal @@ -36,7 +36,7 @@ library , ansi-terminal , bytestring , cardano-api ^>= 10.1 - , cardano-cli ^>= 10.1 + , cardano-cli:{cardano-cli, cardano-cli-test-lib} ^>= 10.1 , cardano-crypto-class , cardano-crypto-wrapper , cardano-git-rev ^>= 0.2.2 @@ -65,6 +65,7 @@ library , hedgehog-extras ^>= 0.6.4 , lens-aeson , microlens + , monad-control , mono-traversable , mtl , network @@ -240,6 +241,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 e24d67e4d00..34982bdd9af 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,42 +365,52 @@ makeActivityChangeProposal execConfig epochStateView ceo work baseDir <- H.createDirectoryIfMissing work - proposalAnchorFile <- H.note $ baseDir "sample-proposal-anchor" - H.writeFile proposalAnchorFile "dummy anchor data" + 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/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/DRepActivity.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/DRepActivity.hs index 87a3cb874ce..9ae15a9ded3 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. From 3133042573042c08b8005bb7bc70a45291dbca9b Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Thu, 24 Oct 2024 13:28:44 +0200 Subject: [PATCH 06/13] Update `hprop_ledger_events_treasury_withdrawal` to work with the new checks --- .../Testnet/Test/Gov/TreasuryWithdrawal.hs | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) 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 83877be9692..9565a878361 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,13 +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" - H.writeFile proposalAnchorFile "dummy anchor data" + 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 @@ -140,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" From 9924169c8f63667ee79559d1446c298c8ef4ab8c Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Thu, 24 Oct 2024 16:25:15 +0200 Subject: [PATCH 07/13] Add test to check `transaction build` fails with wrong hash --- cardano-testnet/cardano-testnet.cabal | 1 + .../Test/Gov/TransactionBuildWrongHash.hs | 175 ++++++++++++++++++ .../cardano-testnet-test.hs | 2 + 3 files changed, 178 insertions(+) create mode 100644 cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TransactionBuildWrongHash.hs diff --git a/cardano-testnet/cardano-testnet.cabal b/cardano-testnet/cardano-testnet.cabal index 8188ab96c21..d692878fa9d 100644 --- a/cardano-testnet/cardano-testnet.cabal +++ b/cardano-testnet/cardano-testnet.cabal @@ -205,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.TransactionBuildWrongHash Cardano.Testnet.Test.Gov.TreasuryDonation Cardano.Testnet.Test.Gov.TreasuryGrowth Cardano.Testnet.Test.Gov.TreasuryWithdrawal diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TransactionBuildWrongHash.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TransactionBuildWrongHash.hs new file mode 100644 index 00000000000..661402485fd --- /dev/null +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TransactionBuildWrongHash.hs @@ -0,0 +1,175 @@ +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} + +module Cardano.Testnet.Test.Gov.TransactionBuildWrongHash + ( hprop_transaction_build_wrong_hash + ) where + +import Cardano.Api as Api + +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 = conwayEraOnwardsToShelleyBasedEra 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 + + void $ execCli' execConfig + [ eraName, "stake-address", "registration-certificate" + , "--stake-verification-key-file", stakeVkeyFp + , "--key-reg-deposit-amt", show @Int 0 -- TODO: why this needs to be 0???? + , "--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 ++ "/")] + + 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", 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.assert ("Hashes do not match!" `Text.isInfixOf` Text.pack stderrOutput) + ) 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..74ac4d3038f 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.TransactionBuildWrongHash 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] From 312398c028e8386c29d1f4b71149bf7ecaa74924 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 29 Oct 2024 12:05:17 +0100 Subject: [PATCH 08/13] Patch for CI --- flake.nix | 9 +++++++++ nix/haskell.nix | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) 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 ec137f41207..d95cb22787f 100644 --- a/nix/haskell.nix +++ b/nix/haskell.nix @@ -4,6 +4,7 @@ { haskell-nix , incl , CHaP +, macOS-security }: let @@ -279,7 +280,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: From 6aea8914dd71a36f4531dd87224c0f000b7fcb83 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 29 Oct 2024 18:18:09 +0100 Subject: [PATCH 09/13] Renamed `TransactionBuildWrongHash` to `Transaction.HashMismatch` --- cardano-testnet/cardano-testnet.cabal | 2 +- .../HashMismatch.hs} | 2 +- .../test/cardano-testnet-test/cardano-testnet-test.hs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/{TransactionBuildWrongHash.hs => Transaction/HashMismatch.hs} (99%) diff --git a/cardano-testnet/cardano-testnet.cabal b/cardano-testnet/cardano-testnet.cabal index d692878fa9d..5d0a2264f06 100644 --- a/cardano-testnet/cardano-testnet.cabal +++ b/cardano-testnet/cardano-testnet.cabal @@ -205,7 +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.TransactionBuildWrongHash + Cardano.Testnet.Test.Gov.Transaction.HashMismatch Cardano.Testnet.Test.Gov.TreasuryDonation Cardano.Testnet.Test.Gov.TreasuryGrowth Cardano.Testnet.Test.Gov.TreasuryWithdrawal diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TransactionBuildWrongHash.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs similarity index 99% rename from cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TransactionBuildWrongHash.hs rename to cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs index 661402485fd..d29cb6124e8 100644 --- a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/TransactionBuildWrongHash.hs +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs @@ -5,7 +5,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} -module Cardano.Testnet.Test.Gov.TransactionBuildWrongHash +module Cardano.Testnet.Test.Gov.Transaction.HashMismatch ( hprop_transaction_build_wrong_hash ) where 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 74ac4d3038f..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,7 +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.TransactionBuildWrongHash as WrongHash +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 From 1f2c0947beb6d183f1f601d968264c503b3e4a06 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 15 Nov 2024 11:55:44 +0100 Subject: [PATCH 10/13] Use `assertWith` instead of `assert` --- .../Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index d29cb6124e8..76dbef6bd28 100644 --- 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 @@ -171,5 +171,5 @@ hprop_transaction_build_wrong_hash = integrationRetryWorkspace 2 "wrong-hash" $ H.note_ stderrOutput - H.assert ("Hashes do not match!" `Text.isInfixOf` Text.pack stderrOutput) + H.assertWith (Text.pack stderrOutput) ("Hashes do not match!" `Text.isInfixOf`) ) From 065d2b4235c3c4e06770ad8c0990ca69ba356986 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 15 Nov 2024 12:38:20 +0100 Subject: [PATCH 11/13] Use `getKeyDeposit` instead of hard-coded `0` --- .../Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index 76dbef6bd28..09684a1db8a 100644 --- 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 @@ -10,6 +10,7 @@ module Cardano.Testnet.Test.Gov.Transaction.HashMismatch ) where import Cardano.Api as Api +import Cardano.Api.Ledger (Coin (unCoin)) import Cardano.Testnet @@ -93,11 +94,12 @@ hprop_transaction_build_wrong_hash = integrationRetryWorkspace 2 "wrong-hash" $ 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 @Int 0 -- TODO: why this needs to be 0???? + , "--key-reg-deposit-amt", show $ unCoin keyDeposit , "--out-file", stakeCertFp ] From 9cdf55aa3ade87ae9a972b24afa8e5d04f7be0c7 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 15 Nov 2024 12:48:04 +0100 Subject: [PATCH 12/13] Use `getMinGovActionDeposit` instead of hard-coded value --- .../Cardano/Testnet/Test/Gov/Transaction/HashMismatch.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index 09684a1db8a..02acf3cef06 100644 --- 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 @@ -144,12 +144,14 @@ hprop_transaction_build_wrong_hash = integrationRetryWorkspace 2 "wrong-hash" $ ( \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 @Int 1_000_000 -- TODO: Get this from the node + , "--governance-action-deposit", show minDepositAmount , "--deposit-return-stake-verification-key-file", stakeVkeyFp , "--anchor-url", "ipfs://" ++ proposalAnchorDataIpfsHash , "--anchor-data-hash", tamperedHash From 49efdb9085993be95c67b84e5b5d3b3fc874d629 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 15 Nov 2024 13:14:35 +0100 Subject: [PATCH 13/13] Reduce test workspace prefix length --- .../Test/Cli/Transaction/RegisterDeregisterStakeAddress.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c86946976ae..4ecd320e35b 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 @@ -35,7 +35,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