diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Commands/Governance/Vote.hs b/cardano-cli/src/Cardano/CLI/EraBased/Commands/Governance/Vote.hs index a65e335989..05d379e1b5 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Commands/Governance/Vote.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Commands/Governance/Vote.hs @@ -32,7 +32,13 @@ data GovernanceVoteCreateCmdArgs era , voteChoice :: Vote , governanceAction :: (TxId, Word16) , votingStakeCredentialSource :: AnyVotingStakeVerificationKeyOrHashOrFile - , mAnchor :: Maybe (VoteUrl, L.SafeHash L.StandardCrypto L.AnchorData) + , mAnchor + :: !( Maybe + ( PotentiallyCheckedAnchor + VoteUrl + (VoteUrl, L.SafeHash L.StandardCrypto L.AnchorData) + ) + ) , outFile :: VoteFile Out } diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs b/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs index 5a0c73927b..8353e6581a 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs @@ -3612,6 +3612,9 @@ pMustCheckMetadataHash = pMustCheckHash "drep-metadata-hash" "DRep metadata" "-- pMustCheckStakeMetadataHash :: Parser (MustCheckHash StakePoolMetadataReference) pMustCheckStakeMetadataHash = pMustCheckHash "metadata-hash" "stake pool metadata" "--metadata-hash" "--metadata-url" +pMustCheckVoteUrl :: Parser (MustCheckHash VoteUrl) +pMustCheckVoteUrl = pMustCheckHash "anchor-data-hash" "vote anchor data" "--anchor-data-hash" "--anchor-url" + pMustCheckResignationMetadataHash :: Parser (MustCheckHash ResignationMetadataUrl) pMustCheckResignationMetadataHash = pMustCheckHash diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Options/Governance/Vote.hs b/cardano-cli/src/Cardano/CLI/EraBased/Options/Governance/Vote.hs index f896d36fd0..8b5f7f94b3 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Options/Governance/Vote.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Options/Governance/Vote.hs @@ -51,7 +51,11 @@ pGovernanceVoteCreateCmdArgs cOnwards = <$> pVoteChoice <*> pGovernanceActionId <*> pAnyVotingStakeVerificationKeyOrHashOrFile - <*> optional pVoteAnchor + <*> optional + ( pPotentiallyCheckedAnchorData + pMustCheckVoteUrl + pVoteAnchor + ) <*> pFileOutDirection "out-file" "Output filepath of the vote." pAnyVotingStakeVerificationKeyOrHashOrFile :: Parser AnyVotingStakeVerificationKeyOrHashOrFile diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Run/Governance/Vote.hs b/cardano-cli/src/Cardano/CLI/EraBased/Run/Governance/Vote.hs index ccba3d3d27..9414bd5775 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Run/Governance/Vote.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Run/Governance/Vote.hs @@ -17,6 +17,7 @@ import Cardano.Api.Shelley import qualified Cardano.CLI.EraBased.Commands.Governance.Vote as Cmd import Cardano.CLI.Read (readSingleVote) +import Cardano.CLI.Run.Hash (carryHashChecks) import Cardano.CLI.Types.Common import Cardano.CLI.Types.Errors.CmdError import Cardano.CLI.Types.Errors.GovernanceVoteCmdError @@ -26,6 +27,7 @@ import Cardano.CLI.Types.Key import Data.Aeson.Encode.Pretty import Data.Function import qualified Data.Yaml.Pretty as Yaml +import Lens.Micro (_Just, over) runGovernanceVoteCmds :: () @@ -53,14 +55,24 @@ runGovernanceVoteCreateCmd , outFile } = do let (govActionTxId, govActionIndex) = governanceAction - let sbe = conwayEraOnwardsToShelleyBasedEra eon -- TODO: Conway era - update vote creation related function to take ConwayEraOnwards - voteProcedure <- case mAnchor of + sbe = conwayEraOnwardsToShelleyBasedEra eon -- TODO: Conway era - update vote creation related function to take ConwayEraOnwards + mAnchor' = + over + (_Just . _pcaAnchor) + (\(VoteUrl url, voteHash) -> L.Anchor{L.anchorUrl = url, L.anchorDataHash = voteHash}) + mAnchor + + mapM_ + (withExceptT GovernanceVoteCmdResignationCertHashCheckError . carryHashChecks) + mAnchor' + + voteProcedure <- case mAnchor' of Nothing -> pure $ createVotingProcedure eon voteChoice Nothing - Just (VoteUrl url, voteHash) -> shelleyBasedEraConstraints sbe $ do - let voteAnchor = L.Anchor{L.anchorUrl = url, L.anchorDataHash = voteHash} - VotingProcedure votingProcedureWithoutAnchor = createVotingProcedure eon voteChoice Nothing - votingProcedureWithAnchor = VotingProcedure $ votingProcedureWithoutAnchor{L.vProcAnchor = L.SJust voteAnchor} - pure votingProcedureWithAnchor + Just voteAnchor -> + shelleyBasedEraConstraints sbe $ + let VotingProcedure votingProcedureWithoutAnchor = createVotingProcedure eon voteChoice Nothing + votingProcedureWithAnchor = VotingProcedure $ votingProcedureWithoutAnchor{L.vProcAnchor = L.SJust (pcaAnchor voteAnchor)} + in return votingProcedureWithAnchor shelleyBasedEraConstraints sbe $ do voter <- firstExceptT GovernanceVoteCmdReadVerificationKeyError $ case votingStakeCredentialSource of diff --git a/cardano-cli/src/Cardano/CLI/Types/Common.hs b/cardano-cli/src/Cardano/CLI/Types/Common.hs index 082fae1313..32f9a1eaa7 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Common.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Common.hs @@ -90,6 +90,7 @@ module Cardano.CLI.Types.Common , DRepMetadataUrl , ResignationMetadataUrl , PotentiallyCheckedAnchor (..) + , _pcaAnchor ) where @@ -104,6 +105,7 @@ import Data.String (IsString) import Data.Text (Text) import qualified Data.Text as Text import Data.Word (Word64) +import Lens.Micro.Type (Traversal) -- | Determines the direction in which the MIR certificate will transfer ADA. data TransferDirection @@ -665,3 +667,12 @@ data PotentiallyCheckedAnchor anchorType anchor -- ^ Whether to check the hash or not (CheckHash for checking or TrustHash for not checking) } deriving (Eq, Show) + +_pcaAnchor + :: Traversal + (PotentiallyCheckedAnchor anchorType anchor) + (PotentiallyCheckedAnchor anchorType anchor') + anchor + anchor' +_pcaAnchor f pca@(PotentiallyCheckedAnchor{pcaAnchor = pcaAnchor'}) = + (\newAnchor -> pca{pcaAnchor = newAnchor}) <$> f pcaAnchor' diff --git a/cardano-cli/src/Cardano/CLI/Types/Errors/GovernanceVoteCmdError.hs b/cardano-cli/src/Cardano/CLI/Types/Errors/GovernanceVoteCmdError.hs index 820db0f949..38c0bb114b 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Errors/GovernanceVoteCmdError.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Errors/GovernanceVoteCmdError.hs @@ -8,7 +8,9 @@ import Cardano.Api.Shelley import Cardano.Binary (DecoderError) import Cardano.CLI.Read (VoteError) +import Cardano.CLI.Types.Errors.HashCmdError (HashCheckError) +import Control.Exception (displayException) import qualified Data.Text.Lazy.Builder as TL import qualified Formatting.Buildable as B @@ -18,6 +20,7 @@ data GovernanceVoteCmdError | GovernanceVoteCmdCredentialDecodeError !DecoderError | GovernanceVoteCmdWriteError !(FileError ()) | GovernanceVoteCmdReadVoteTextError !VoteError + | GovernanceVoteCmdResignationCertHashCheckError !HashCheckError deriving Show instance Error GovernanceVoteCmdError where @@ -32,5 +35,8 @@ instance Error GovernanceVoteCmdError where "Cannot write vote: " <> prettyError e GovernanceVoteCmdReadVoteTextError e -> "Cannot read vote text: " <> prettyError e + GovernanceVoteCmdResignationCertHashCheckError hashCheckErr -> + "Error while checking resignation certificate metadata hash: " + <> pretty (displayException hashCheckErr) where renderDecoderError = pretty . TL.toLazyText . B.build diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help.cli index e1518cc590..4965c21ef7 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help.cli @@ -7054,7 +7054,8 @@ Usage: cardano-cli conway governance vote create (--yes | --no | --abstain) | --cc-hot-script-hash HASH ) [--anchor-url TEXT - --anchor-data-hash HASH] + --anchor-data-hash HASH + [--check-anchor-data-hash]] --out-file FILEPATH Vote creation. @@ -9054,7 +9055,8 @@ Usage: cardano-cli latest governance vote create (--yes | --no | --abstain) | --cc-hot-script-hash HASH ) [--anchor-url TEXT - --anchor-data-hash HASH] + --anchor-data-hash HASH + [--check-anchor-data-hash]] --out-file FILEPATH Vote creation. diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_governance_vote_create.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_governance_vote_create.cli index f1b7d836d3..06805ac988 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_governance_vote_create.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_governance_vote_create.cli @@ -14,7 +14,8 @@ Usage: cardano-cli conway governance vote create (--yes | --no | --abstain) | --cc-hot-script-hash HASH ) [--anchor-url TEXT - --anchor-data-hash HASH] + --anchor-data-hash HASH + [--check-anchor-data-hash]] --out-file FILEPATH Vote creation. @@ -50,5 +51,10 @@ Available options: --anchor-url TEXT Vote anchor URL --anchor-data-hash HASH Hash of the vote anchor data (obtain it with "cardano-cli hash anchor-data ..."). + --check-anchor-data-hash Verify that the expected vote anchor data hash + provided in --anchor-data-hash matches the hash of + the file downloaded from the URL provided in + --anchor-url (this parameter will download the file + from the URL) --out-file FILEPATH Output filepath of the vote. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_governance_vote_create.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_governance_vote_create.cli index fb93ae26f9..9e85abcfbc 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_governance_vote_create.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_governance_vote_create.cli @@ -14,7 +14,8 @@ Usage: cardano-cli latest governance vote create (--yes | --no | --abstain) | --cc-hot-script-hash HASH ) [--anchor-url TEXT - --anchor-data-hash HASH] + --anchor-data-hash HASH + [--check-anchor-data-hash]] --out-file FILEPATH Vote creation. @@ -50,5 +51,10 @@ Available options: --anchor-url TEXT Vote anchor URL --anchor-data-hash HASH Hash of the vote anchor data (obtain it with "cardano-cli hash anchor-data ..."). + --check-anchor-data-hash Verify that the expected vote anchor data hash + provided in --anchor-data-hash matches the hash of + the file downloaded from the URL provided in + --anchor-url (this parameter will download the file + from the URL) --out-file FILEPATH Output filepath of the vote. -h,--help Show this help text