From 6b55d51e4a0d1382ab9b39bc8852bfdaa23bf504 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Tue, 4 Jun 2024 21:49:25 +0200 Subject: [PATCH] Add test for timeout of gov actions --- cardano-testnet/cardano-testnet.cabal | 1 + .../Testnet/Test/Gov/GovActionTimeout.hs | 113 ++++++++++++++++++ .../cardano-testnet-test.hs | 2 + 3 files changed, 116 insertions(+) create mode 100644 cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/GovActionTimeout.hs diff --git a/cardano-testnet/cardano-testnet.cabal b/cardano-testnet/cardano-testnet.cabal index 1dcf59dcf99..b287e03f916 100644 --- a/cardano-testnet/cardano-testnet.cabal +++ b/cardano-testnet/cardano-testnet.cabal @@ -196,6 +196,7 @@ test-suite cardano-testnet-test Cardano.Testnet.Test.Gov.PParamChangeFailsSPO Cardano.Testnet.Test.Gov.ProposeNewConstitution Cardano.Testnet.Test.Gov.ProposeNewConstitutionSPO + Cardano.Testnet.Test.Gov.GovActionTimeout Cardano.Testnet.Test.Gov.TreasuryGrowth Cardano.Testnet.Test.Gov.TreasuryWithdrawal Cardano.Testnet.Test.Misc diff --git a/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/GovActionTimeout.hs b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/GovActionTimeout.hs new file mode 100644 index 00000000000..846b4117212 --- /dev/null +++ b/cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/GovActionTimeout.hs @@ -0,0 +1,113 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Cardano.Testnet.Test.Gov.GovActionTimeout + ( hprop_check_gov_action_timeout + ) where + +import Cardano.Api as Api +import Cardano.Api.Eon.ShelleyBasedEra (ShelleyLedgerEra) +import Cardano.Api.Ledger (EpochInterval (EpochInterval, unEpochInterval)) + +import Cardano.Ledger.Conway.Core (ConwayEraPParams, ppGovActionLifetimeL) +import Cardano.Ledger.Conway.Governance (ConwayGovState, cgsCurPParamsL) +import Cardano.Testnet + +import Prelude + +import Control.Monad (void) +import Data.String (fromString) +import Lens.Micro ((^.)) +import System.FilePath (()) + +import Testnet.Components.Query +import Testnet.Process.Cli.DRep (makeActivityChangeProposal) +import Testnet.Process.Run (mkExecConfig) +import Testnet.Property.Util (integrationWorkspace) +import Testnet.Types + +import Hedgehog (MonadTest, Property) +import qualified Hedgehog as H +import qualified Hedgehog.Extras as H + +-- | Test that SPOs cannot vote on a Protocol Parameter change +-- | Execute me with: +-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/Gov Action Timeout/"'@ +hprop_check_gov_action_timeout :: Property +hprop_check_gov_action_timeout = integrationWorkspace "gov-action-timeout" $ \tempAbsBasePath' -> + H.runWithDefaultWatchdog_ $ do + -- Start a local test net + conf@Conf { tempAbsPath } <- mkConf tempAbsBasePath' + let tempAbsPath' = unTmpAbsPath tempAbsPath + tempBaseAbsPath = makeTmpBaseAbsPath tempAbsPath + + work <- H.createDirectoryIfMissing $ tempAbsPath' "work" + + -- Create default testnet + let ceo = ConwayEraOnwardsConway + sbe = conwayEraOnwardsToShelleyBasedEra ceo + era = toCardanoEra sbe + cEra = AnyCardanoEra era + fastTestnetOptions = cardanoDefaultTestnetOptions + { cardanoEpochLength = 200 + , cardanoNodeEra = cEra + } + + TestnetRuntime + { testnetMagic + , poolNodes + , wallets=wallet0:_ + , configurationFile + } + <- cardanoTestnetDefault fastTestnetOptions conf + + PoolNode{poolRuntime} <- H.headM poolNodes + poolSprocket1 <- H.noteShow $ nodeSprocket poolRuntime + execConfig <- mkExecConfig tempBaseAbsPath poolSprocket1 testnetMagic + let socketPath = nodeSocketPath poolRuntime + + 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" + + baseDir <- H.createDirectoryIfMissing $ gov "output" + + -- Figure out expiration time for proposals + + govActionLifetime <- getGovActionLifetime epochStateView ceo + H.note_ $ "govActionLifetime: " <> show govActionLifetime + + -- Create a proposal + (governanceActionTxId, _governanceActionIndex) <- + makeActivityChangeProposal execConfig epochStateView ceo baseDir "proposal" + Nothing (EpochInterval 3) wallet0 (EpochInterval 2) + + -- Wait for proposal to expire + void $ waitForEpochs epochStateView (EpochInterval $ unEpochInterval govActionLifetime + 1) + + -- Check proposal expired + mGovernanceActionTxIx <- watchEpochStateUpdate epochStateView (EpochInterval 2) $ \(anyNewEpochState, _, _) -> + return $ maybeExtractGovernanceActionIndex (fromString governanceActionTxId) anyNewEpochState + + mGovernanceActionTxIx H.=== Nothing + +-- | Obtains the @govActionLifetime@ from the protocol parameters. +-- The @govActionLifetime@ or governance action maximum lifetime in epochs is +-- the number of epochs such that a governance action submitted during an epoch @e@ +-- expires if it is still not ratified as of the end of epoch: @e + govActionLifetime + 1@. +getGovActionLifetime :: (ConwayEraPParams (ShelleyLedgerEra era), H.MonadAssertion m, MonadTest m, MonadIO m) + => EpochStateView + -> ConwayEraOnwards era + -> m EpochInterval +getGovActionLifetime epochStateView ceo = do + govState :: ConwayGovState era <- getGovState epochStateView ceo + return $ govState ^. cgsCurPParamsL + . ppGovActionLifetimeL 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 5c4e1cafe44..0abd882d754 100644 --- a/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs +++ b/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs @@ -16,6 +16,7 @@ import qualified Cardano.Testnet.Test.FoldEpochState import qualified Cardano.Testnet.Test.Gov.CommitteeAddNew as Gov import qualified Cardano.Testnet.Test.Gov.DRepDeposit as Gov import qualified Cardano.Testnet.Test.Gov.DRepRetirement as Gov +import qualified Cardano.Testnet.Test.Gov.GovActionTimeout as Gov import qualified Cardano.Testnet.Test.Gov.NoConfidence as Gov import qualified Cardano.Testnet.Test.Gov.PParamChangeFailsSPO as Gov import qualified Cardano.Testnet.Test.Gov.ProposeNewConstitution as Gov @@ -59,6 +60,7 @@ tests = do , ignoreOnWindows "DRep Retirement" Gov.hprop_drep_retirement , ignoreOnMacAndWindows "Propose And Ratify New Constitution" Gov.hprop_ledger_events_propose_new_constitution , ignoreOnWindows "Propose New Constitution SPO" Gov.hprop_ledger_events_propose_new_constitution_spo + , ignoreOnWindows "Gov Action Timeout" Gov.hprop_check_gov_action_timeout , ignoreOnWindows "Treasury Withdrawal" Gov.hprop_ledger_events_treasury_withdrawal , ignoreOnWindows "PParam change fails for SPO" Gov.hprop_check_pparam_fails_spo -- FIXME Those tests are flaky