-
Notifications
You must be signed in to change notification settings - Fork 720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test SPOs cannot vote protocol parameter change proposals #5871
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,10 +13,13 @@ module Testnet.Process.Cli.DRep | |
, registerDRep | ||
, delegateToDRep | ||
, getLastPParamUpdateActionId | ||
, makeActivityChangeProposal | ||
) where | ||
|
||
import Cardano.Api hiding (Certificate, TxBody) | ||
import Cardano.Api.Ledger (EpochInterval (EpochInterval)) | ||
import Cardano.Api.Ledger (EpochInterval (EpochInterval, unEpochInterval)) | ||
|
||
import Cardano.Testnet (maybeExtractGovernanceActionIndex) | ||
|
||
import Prelude | ||
|
||
|
@@ -26,12 +29,15 @@ import qualified Data.Aeson as Aeson | |
import qualified Data.Aeson.Lens as AL | ||
import Data.Text (Text) | ||
import qualified Data.Text as Text | ||
import Data.Typeable (Typeable) | ||
import Data.Word (Word32) | ||
import GHC.Exts (fromString) | ||
import GHC.Stack | ||
import Lens.Micro ((^?)) | ||
import System.FilePath ((</>)) | ||
|
||
import Testnet.Components.Query | ||
import Testnet.Process.Cli.Keys (cliStakeAddressKeyGen) | ||
import Testnet.Process.Cli.Transaction | ||
import Testnet.Process.Run (execCli', execCliStdoutToJson) | ||
import Testnet.Types | ||
|
@@ -329,3 +335,86 @@ getLastPParamUpdateActionId execConfig = do | |
actionIx <- evalMaybe mActionIx | ||
txId <- evalMaybe mTxId | ||
return (Just (Text.unpack txId, fromIntegral actionIx)) | ||
|
||
-- | 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) | ||
=> H.ExecConfig -- ^ Specifies the CLI execution configuration. | ||
-> EpochStateView -- ^ Current epoch state view for transaction building. It can be obtained | ||
-- using the 'getEpochStateView' function. | ||
-> ConwayEraOnwards era -- ^ The 'ConwayEraOnwards' witness for current era. | ||
-> FilePath -- ^ Base directory path where generated files will be stored. | ||
-> String -- ^ Name for the subfolder that will be created under 'work' folder. | ||
-> Maybe (String, Word32) -- ^ The transaction id and the index of the previosu governance action if any. | ||
-> EpochInterval -- ^ The target DRep activity interval to be set by the proposal. | ||
-> PaymentKeyInfo -- ^ Wallet that will pay for the transaction. | ||
-> EpochInterval -- ^ Number of epochs to wait for the proposal to be registered by the chain. | ||
-> m (String, Word32) -- ^ The transaction id and the index of the governance action. | ||
makeActivityChangeProposal execConfig epochStateView ceo work prefix | ||
prevGovActionInfo drepActivity wallet timeout = do | ||
|
||
let sbe = conwayEraOnwardsToShelleyBasedEra ceo | ||
era = toCardanoEra sbe | ||
cEra = AnyCardanoEra era | ||
|
||
baseDir <- H.createDirectoryIfMissing $ work </> prefix | ||
|
||
let stakeVkeyFp = baseDir </> "stake.vkey" | ||
stakeSKeyFp = baseDir </> "stake.skey" | ||
|
||
cliStakeAddressKeyGen | ||
$ KeyPair { verificationKey = File stakeVkeyFp | ||
, signingKey = File stakeSKeyFp | ||
} | ||
|
||
proposalAnchorFile <- H.note $ baseDir </> "sample-proposal-anchor" | ||
H.writeFile proposalAnchorFile "dummy anchor data" | ||
|
||
proposalAnchorDataHash <- execCli' execConfig | ||
[ "conway", "governance" | ||
, "hash", "anchor-data", "--file-text", proposalAnchorFile | ||
] | ||
|
||
minDRepDeposit <- getMinDRepDeposit epochStateView ceo | ||
|
||
proposalFile <- H.note $ baseDir </> "sample-proposal-anchor" | ||
|
||
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 | ||
] | ||
|
||
proposalBody <- H.note $ baseDir </> "tx.body" | ||
txIn <- findLargestUtxoForPaymentKey epochStateView sbe wallet | ||
|
||
void $ execCli' execConfig | ||
[ "conway", "transaction", "build" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't hardcode |
||
, "--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) [SomeKeyPair $ paymentKeyInfoPair wallet] | ||
|
||
submitTx execConfig cEra signedProposalTx | ||
|
||
governanceActionTxId <- retrieveTransactionId execConfig signedProposalTx | ||
|
||
governanceActionIndex <- | ||
H.nothingFailM $ watchEpochStateUpdate epochStateView timeout $ \(anyNewEpochState, _, _) -> | ||
return $ maybeExtractGovernanceActionIndex (fromString governanceActionTxId) anyNewEpochState | ||
|
||
return (governanceActionTxId, governanceActionIndex) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/PParamChangeFailsSPO.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE FlexibleContexts #-} | ||
{-# LANGUAGE NamedFieldPuns #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE ScopedTypeVariables #-} | ||
|
||
module Cardano.Testnet.Test.Gov.PParamChangeFailsSPO | ||
( hprop_check_pparam_fails_spo | ||
) where | ||
|
||
import Cardano.Api as Api | ||
import Cardano.Api.Ledger (EpochInterval (EpochInterval)) | ||
|
||
import Cardano.Testnet | ||
|
||
import Prelude | ||
|
||
import Control.Monad.Catch (MonadCatch) | ||
import Data.Typeable (Typeable) | ||
import Data.Word (Word32) | ||
import System.FilePath ((</>)) | ||
|
||
import Testnet.Components.Query | ||
import Testnet.Defaults (defaultSpoColdKeyPair, defaultSpoKeys) | ||
import Testnet.Process.Cli.DRep | ||
import qualified Testnet.Process.Cli.SPO as SPO | ||
import Testnet.Process.Cli.Transaction (failToSubmitTx, signTx) | ||
import Testnet.Process.Run (mkExecConfig) | ||
import Testnet.Property.Util (integrationWorkspace) | ||
import Testnet.Types | ||
|
||
import Hedgehog (Property, annotateShow) | ||
import qualified Hedgehog.Extras as H | ||
import Hedgehog.Internal.Property (MonadTest) | ||
import Hedgehog.Internal.Source (HasCallStack, withFrozenCallStack) | ||
|
||
-- | Test that SPOs cannot vote on a Protocol Parameter change | ||
-- | Execute me with: | ||
-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/PParam change fails for SPO/"'@ | ||
hprop_check_pparam_fails_spo :: Property | ||
hprop_check_pparam_fails_spo = integrationWorkspace "test-pparam-spo" $ \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:wallet1:_wallet2:_ | ||
, 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" | ||
|
||
|
||
let propVotes :: [(String, Int)] | ||
propVotes = zip (concatMap (uncurry replicate) [(1, "yes")]) [1..] | ||
annotateShow propVotes | ||
|
||
(governanceActionTxId, governanceActionIndex) <- | ||
makeActivityChangeProposal execConfig epochStateView ceo baseDir "proposal" | ||
Nothing (EpochInterval 3) wallet0 (EpochInterval 2) | ||
|
||
failToVoteChangeProposalWithSPOs ceo execConfig epochStateView baseDir "vote" | ||
governanceActionTxId governanceActionIndex propVotes wallet1 | ||
|
||
-- | Cast votes for a governance action with SPO keys. | ||
failToVoteChangeProposalWithSPOs | ||
:: (HasCallStack, MonadTest m, MonadIO m, MonadCatch m, H.MonadAssertion m, Typeable era) | ||
=> ConwayEraOnwards era -- ^ The conway era onwards witness for the era in which the | ||
-- transaction will be constructed. | ||
-> H.ExecConfig -- ^ Specifies the CLI execution configuration.v | ||
-> EpochStateView -- ^ Current epoch state view for transaction building. It can be obtained | ||
-- using the 'getEpochStateView' function. | ||
-> FilePath -- ^ Base directory path where generated files will be stored. | ||
-> String -- ^ Name for the subfolder that will be created under 'work' folder. | ||
-> String -- ^ The transaction id of the governance action to vote. | ||
-> Word32 -- ^ The index of the governance action to vote. | ||
-> [([Char], Int)] -- ^ Votes to be casted for the proposal. Each tuple contains the index | ||
-- of the default SPO that will make the vote and the type of the vote | ||
-- (i.e: "yes", "no", "abstain"). | ||
-> PaymentKeyInfo -- ^ Wallet that will pay for the transaction. | ||
-> m () | ||
failToVoteChangeProposalWithSPOs ceo execConfig epochStateView work prefix | ||
governanceActionTxId governanceActionIndex votes wallet = withFrozenCallStack $ do | ||
baseDir <- H.createDirectoryIfMissing $ work </> prefix | ||
|
||
let sbe = conwayEraOnwardsToShelleyBasedEra ceo | ||
era = toCardanoEra sbe | ||
cEra = AnyCardanoEra era | ||
|
||
voteFiles <- SPO.generateVoteFiles ceo execConfig baseDir "vote-files" | ||
governanceActionTxId governanceActionIndex | ||
[(defaultSpoKeys idx, vote) | (vote, idx) <- votes] | ||
|
||
voteTxBodyFp <- createVotingTxBody execConfig epochStateView sbe baseDir "vote-tx-body" | ||
voteFiles wallet | ||
|
||
let signingKeys = SomeKeyPair (paymentKeyInfoPair wallet):(SomeKeyPair . defaultSpoColdKeyPair . snd <$> votes) | ||
voteTxFp <- signTx execConfig cEra baseDir "signed-vote-tx" voteTxBodyFp signingKeys | ||
|
||
failToSubmitTx execConfig cEra voteTxFp "DisallowedVoters" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't hardcode
"conway"
here. Also food for thought, if we continue implementing functions like this, we are going to have a lot of boiler plate. What about we introduce a callback function that directly modifies thePParamsUpdate ledgerera
type and then serialize to disk?