Skip to content
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

Add metadata validation, hash checking, and URL support to stake-pool registration-certificate, and hash checking and URL support to stake-pool metadata-hash #932

Merged
merged 13 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cardano-cli/cardano-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ test-suite cardano-cli-test
Test.Cli.Pioneers.Exercise5
Test.Cli.Pioneers.Exercise6
Test.Cli.Pipes
Test.Cli.Shelley.Certificates.StakePool
Test.Cli.Shelley.Run.Hash
Test.Cli.Shelley.Run.Query
Test.Cli.Shelley.Transaction.Build
Expand Down
6 changes: 3 additions & 3 deletions cardano-cli/src/Cardano/CLI/Commands/Hash.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@ data HashCmds
= HashAnchorDataCmd !HashAnchorDataCmdArgs
| HashScriptCmd !HashScriptCmdArgs

data HashGoal
data HashGoal hash
= -- | The hash is written to stdout
HashToStdout
| -- | The hash to check against
CheckHash !(L.SafeHash L.StandardCrypto L.AnchorData)
CheckHash !hash
| -- | The output file to which the hash is written
HashToFile !(File () Out)
deriving Show

data HashAnchorDataCmdArgs
= HashAnchorDataCmdArgs
{ toHash :: !AnchorDataHashSource
, hashGoal :: !HashGoal
, hashGoal :: !(HashGoal (L.SafeHash L.StandardCrypto L.AnchorData))
}
deriving Show

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ module Cardano.CLI.EraBased.Commands.Governance.DRep
, GovernanceDRepUpdateCertificateCmdArgs (..)
, GovernanceDRepMetadataHashCmdArgs (..)
, DRepMetadataSource (..)
, DRepHashGoal (..)
)
where

import Cardano.Api
import qualified Cardano.Api.Ledger as L

import Cardano.CLI.Commands.Hash (HashGoal)
import Cardano.CLI.Types.Common
import Cardano.CLI.Types.Key

Expand Down Expand Up @@ -56,6 +56,7 @@ data GovernanceDRepRegistrationCertificateCmdArgs era
:: !( Maybe
( PotentiallyCheckedAnchor
DRepMetadataUrl
(L.Anchor L.StandardCrypto)
)
)
, outFile :: !(File () Out)
Expand All @@ -77,6 +78,7 @@ data GovernanceDRepUpdateCertificateCmdArgs era
:: Maybe
( PotentiallyCheckedAnchor
DRepMetadataUrl
(L.Anchor L.StandardCrypto)
)
, outFile :: !(File () Out)
}
Expand All @@ -85,23 +87,14 @@ data GovernanceDRepMetadataHashCmdArgs era
= GovernanceDRepMetadataHashCmdArgs
{ eon :: !(ConwayEraOnwards era)
, drepMetadataSource :: !DRepMetadataSource
, hashGoal :: !DRepHashGoal
, hashGoal :: !(HashGoal (Hash DRepMetadata))
}

data DRepMetadataSource
= DrepMetadataFileIn !(DRepMetadataFile In)
| DrepMetadataURL !L.Url
deriving Show

data DRepHashGoal
= -- | The hash is written to stdout
DRepHashToStdout
| -- | The hash to check against
CheckDRepHash !(Hash DRepMetadata)
| -- | The output file to which the hash is written
DRepHashToFile !(File () Out)
deriving Show

renderGovernanceDRepCmds
:: ()
=> GovernanceDRepCmds era
Expand Down
15 changes: 12 additions & 3 deletions cardano-cli/src/Cardano/CLI/EraBased/Commands/StakePool.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ module Cardano.CLI.EraBased.Commands.StakePool
, StakePoolIdCmdArgs (..)
, StakePoolMetadataHashCmdArgs (..)
, StakePoolRegistrationCertificateCmdArgs (..)
, StakePoolMetadataSource (..)
)
where

import Cardano.Api.Ledger (Coin)
import qualified Cardano.Api.Ledger as L
import Cardano.Api.Shelley hiding (QueryInShelleyBasedEra (..))

import Cardano.CLI.Commands.Hash (HashGoal)
import Cardano.CLI.Types.Common
import Cardano.CLI.Types.Key

Expand Down Expand Up @@ -48,11 +51,16 @@ data StakePoolIdCmdArgs era

data StakePoolMetadataHashCmdArgs era
= StakePoolMetadataHashCmdArgs
{ poolMetadataFile :: !(StakePoolMetadataFile In)
, mOutFile :: !(Maybe (File () Out))
{ poolMetadataSource :: !StakePoolMetadataSource
, hashGoal :: !(HashGoal (Hash StakePoolMetadata))
}
deriving Show

data StakePoolMetadataSource
= StakePoolMetadataFileIn !(StakePoolMetadataFile In)
| StakePoolMetadataURL !L.Url
deriving Show

data StakePoolRegistrationCertificateCmdArgs era
= StakePoolRegistrationCertificateCmdArgs
{ sbe :: !(ShelleyBasedEra era)
Expand All @@ -73,7 +81,8 @@ data StakePoolRegistrationCertificateCmdArgs era
-- ^ Pool owner verification staking key(s).
, relays :: ![StakePoolRelay]
-- ^ Stake pool relays.
, mMetadata :: !(Maybe StakePoolMetadataReference)
, mMetadata
:: !(Maybe (PotentiallyCheckedAnchor StakePoolMetadataReference StakePoolMetadataReference))
-- ^ Stake pool metadata.
, network :: !NetworkId
, outFile :: !(File () Out)
Expand Down
37 changes: 23 additions & 14 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2683,12 +2683,11 @@ pPort =
, Opt.help "The stake pool relay's port"
]

pStakePoolMetadataReference :: Parser (Maybe StakePoolMetadataReference)
pStakePoolMetadataReference :: Parser StakePoolMetadataReference
pStakePoolMetadataReference =
optional $
StakePoolMetadataReference
<$> pStakePoolMetadataUrl
<*> pStakePoolMetadataHash
StakePoolMetadataReference
<$> pStakePoolMetadataUrl
<*> pStakePoolMetadataHash

pStakePoolMetadataUrl :: Parser Text
pStakePoolMetadataUrl =
Expand Down Expand Up @@ -2724,7 +2723,11 @@ pStakePoolRegistrationParserRequirements envCli =
<*> pRewardAcctVerificationKeyOrFile
<*> some pPoolOwnerVerificationKeyOrFile
<*> many pPoolRelay
<*> pStakePoolMetadataReference
<*> optional
( pPotentiallyCheckedAnchorData
pMustCheckStakeMetadataHash
pStakePoolMetadataReference
)
<*> pNetworkId envCli

pProtocolParametersUpdate :: Parser ProtocolParametersUpdate
Expand Down Expand Up @@ -3547,16 +3550,19 @@ pAnchorUrl =
ProposalUrl
<$> pUrl "anchor-url" "Anchor URL"

pExpectedHash :: Parser (L.SafeHash L.StandardCrypto L.AnchorData)
pExpectedHash =
Opt.option readSafeHash $
pExpectedAnchorDataHash :: Parser (L.SafeHash L.StandardCrypto L.AnchorData)
pExpectedAnchorDataHash = pExpectedHash id "anchor data"

pExpectedHash :: (L.SafeHash L.StandardCrypto L.AnchorData -> a) -> String -> Parser a
pExpectedHash adaptor hashedDataName =
Opt.option (adaptor <$> readSafeHash) $
mconcat
[ Opt.long "expected-hash"
, Opt.metavar "HASH"
, Opt.help $
mconcat
[ "Expected hash for the anchor data for verification purposes. "
, "If provided, the hash of the anchor data will be compared to this value."
[ "Expected hash for the " ++ hashedDataName ++ ", for verification purposes. "
, "If provided, the hash of the " ++ hashedDataName ++ " will be compared to this value."
]
]

Expand Down Expand Up @@ -3586,9 +3592,9 @@ pMustCheckHash flagSuffix' dataName' hashParamName' urlParamName' =
]

pPotentiallyCheckedAnchorData
:: Parser (MustCheckHash anchorDataType)
-> Parser (L.Anchor L.StandardCrypto)
-> Parser (PotentiallyCheckedAnchor anchorDataType)
:: Parser (MustCheckHash anchorType)
-> Parser anchor
-> Parser (PotentiallyCheckedAnchor anchorType anchor)
pPotentiallyCheckedAnchorData mustCheckHash anchorData =
PotentiallyCheckedAnchor
<$> anchorData
Expand All @@ -3603,6 +3609,9 @@ pMustCheckConstitutionHash = pMustCheckHash "constitution-hash" "constitution" "
pMustCheckMetadataHash :: Parser (MustCheckHash DRepMetadataUrl)
pMustCheckMetadataHash = pMustCheckHash "drep-metadata-hash" "DRep metadata" "--drep-metadata-hash" "--drep-metadata-url"

pMustCheckStakeMetadataHash :: Parser (MustCheckHash StakePoolMetadataReference)
pMustCheckStakeMetadataHash = pMustCheckHash "metadata-hash" "stake pool metadata" "--metadata-hash" "--metadata-url"

pPreviousGovernanceAction :: Parser (Maybe (TxId, Word16))
pPreviousGovernanceAction =
optional $
Expand Down
22 changes: 7 additions & 15 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/Governance/DRep.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import Cardano.Api.Ledger (extractHash)
import qualified Cardano.Api.Ledger as L
import Cardano.Api.Shelley (Hash (DRepMetadataHash))

import Cardano.CLI.Commands.Hash (HashGoal (..))
import Cardano.CLI.Environment
import Cardano.CLI.EraBased.Commands.Governance.DRep
import Cardano.CLI.EraBased.Options.Common
import Cardano.CLI.Parser
import Cardano.CLI.Read
import Cardano.CLI.Types.Common
import Cardano.CLI.Types.Common hiding (CheckHash)
import Cardano.CLI.Types.Key
import Cardano.Ledger.SafeHash (castSafeHash)

Expand Down Expand Up @@ -134,16 +135,7 @@ pDrepMetadataUrl =

pExpectedDrepMetadataHash :: Parser (Hash DRepMetadata)
pExpectedDrepMetadataHash =
Opt.option (DRepMetadataHash . extractHash . castSafeHash <$> readSafeHash) $
mconcat
[ Opt.long "expected-hash"
, Opt.metavar "HASH"
, Opt.help $
mconcat
[ "Expected hash for the DRep metadata, for verification purposes. "
, "If provided, the hash of the DRep metadata is compared to this value."
]
]
pExpectedHash (DRepMetadataHash . extractHash . castSafeHash) "DRep metadata"

pDrepMetadataHash :: Parser (L.SafeHash L.StandardCrypto L.AnchorData)
pDrepMetadataHash =
Expand Down Expand Up @@ -210,13 +202,13 @@ pGovernanceDrepMetadataHashCmd era = do
$ Opt.progDesc
"Calculate the hash of a metadata file, optionally checking the obtained hash against an expected value."

pDRepHashGoal :: Parser DRepHashGoal
pDRepHashGoal :: Parser (HashGoal (Hash DRepMetadata))
pDRepHashGoal =
asum
[ CheckDRepHash <$> pExpectedDrepMetadataHash
, DRepHashToFile <$> pOutputFile
[ CheckHash <$> pExpectedDrepMetadataHash
, HashToFile <$> pOutputFile
]
<|> pure DRepHashToStdout
<|> pure HashToStdout

pDRepMetadataSource :: Parser DRepMetadataSource
pDRepMetadataSource =
Expand Down
40 changes: 36 additions & 4 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/StakePool.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ module Cardano.CLI.EraBased.Options.StakePool
where

import Cardano.Api
import qualified Cardano.Api.Ledger as L
import Cardano.Api.Shelley (Hash (StakePoolMetadataHash))

import qualified Cardano.CLI.Commands.Hash as Cmd
import Cardano.CLI.Environment (EnvCli (..))
import qualified Cardano.CLI.EraBased.Commands.StakePool as Cmd
import Cardano.CLI.EraBased.Options.Common
import qualified Cardano.Ledger.SafeHash as L

import qualified Data.Foldable as F
import Options.Applicative hiding (help, str)
import qualified Options.Applicative as Opt

Expand All @@ -42,7 +47,10 @@ pStakePoolCmds era envCli =
, Just $
subParser "metadata-hash" $
Opt.info pStakePoolMetadataHashCmd $
Opt.progDesc "Print the hash of pool metadata."
Opt.progDesc
( "Calculate the hash of a stake pool metadata file,"
<> " optionally checking the obtained hash against an expected value."
)
]

pStakePoolId
Expand All @@ -61,8 +69,28 @@ pStakePoolMetadataHashCmd
pStakePoolMetadataHashCmd =
fmap Cmd.StakePoolMetadataHashCmd $
Cmd.StakePoolMetadataHashCmdArgs
<$> pPoolMetadataFile
<*> pMaybeOutputFile
<$> pPoolMetadataSource
<*> pPoolMetadataHashGoal

pPoolMetadataSource :: Parser Cmd.StakePoolMetadataSource
pPoolMetadataSource =
F.asum
[ Cmd.StakePoolMetadataFileIn <$> pPoolMetadataFile
, Cmd.StakePoolMetadataURL
<$> pUrl "pool-metadata-url" "URL pointing to the JSON Metadata file to hash."
]

pPoolMetadataHashGoal :: Parser (Cmd.HashGoal (Hash StakePoolMetadata))
pPoolMetadataHashGoal =
F.asum
[ Cmd.CheckHash <$> pExpectedStakePoolMetadataHash
, Cmd.HashToFile <$> pOutputFile
]
<|> pure Cmd.HashToStdout

pExpectedStakePoolMetadataHash :: Parser (Hash StakePoolMetadata)
palas marked this conversation as resolved.
Show resolved Hide resolved
pExpectedStakePoolMetadataHash =
pExpectedHash (StakePoolMetadataHash . L.extractHash . L.castSafeHash) "stake pool metadata"

pStakePoolRegistrationCertificateCmd
:: ()
Expand All @@ -84,7 +112,11 @@ pStakePoolRegistrationCertificateCmd era envCli = do
<*> pRewardAcctVerificationKeyOrFile
<*> some pPoolOwnerVerificationKeyOrFile
<*> many pPoolRelay
<*> pStakePoolMetadataReference
<*> optional
( pPotentiallyCheckedAnchorData
pMustCheckStakeMetadataHash
pStakePoolMetadataReference
)
<*> pNetworkId envCli
<*> pOutputFile
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ carryHashChecks checkHash anchor checkType =
L.AnchorData
<$> fetchURLErrorToGovernanceActionError
checkType
(getByteStringFromURL httpsAndIpfsSchemas $ L.anchorUrl anchor)
(getByteStringFromURL httpsAndIpfsSchemas $ L.urlToText $ L.anchorUrl anchor)
let hash = L.hashAnchorData anchorData
when (hash /= L.anchorDataHash anchor) $
left $
Expand Down
14 changes: 7 additions & 7 deletions cardano-cli/src/Cardano/CLI/EraBased/Run/Governance/DRep.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ where
import Cardano.Api
import qualified Cardano.Api.Ledger as L

import Cardano.CLI.EraBased.Commands.Governance.DRep (DRepHashGoal (..))
import qualified Cardano.CLI.Commands.Hash as Cmd
import qualified Cardano.CLI.EraBased.Commands.Governance.DRep as Cmd
import qualified Cardano.CLI.EraBased.Run.Key as Key
import Cardano.CLI.Run.Hash (allSchemas, getByteStringFromURL, httpsAndIpfsSchemas)
Expand Down Expand Up @@ -187,15 +187,15 @@ runGovernanceDRepMetadataHashCmd
Cmd.DrepMetadataFileIn metadataFile ->
firstExceptT ReadFileError . newExceptT $ readByteStringFile metadataFile
Cmd.DrepMetadataURL urlText ->
fetchURLToGovernanceCmdError $ getByteStringFromURL allSchemas urlText
fetchURLToGovernanceCmdError $ getByteStringFromURL allSchemas $ L.urlToText urlText
let (_metadata, metadataHash) = hashDRepMetadata metadataBytes
case hashGoal of
CheckDRepHash expectedHash
Cmd.CheckHash expectedHash
| metadataHash /= expectedHash ->
left $ GovernanceCmdHashMismatchError expectedHash metadataHash
| otherwise -> liftIO $ putStrLn "Hashes match!"
DRepHashToFile outFile -> writeOutput (Just outFile) metadataHash
DRepHashToStdout -> writeOutput Nothing metadataHash
Cmd.HashToFile outFile -> writeOutput (Just outFile) metadataHash
Cmd.HashToStdout -> writeOutput Nothing metadataHash
where
writeOutput
:: MonadIO m
Expand All @@ -215,7 +215,7 @@ runGovernanceDRepMetadataHashCmd
-- | Check the hash of the anchor data against the hash in the anchor if
-- checkHash is set to CheckHash.
carryHashChecks
:: PotentiallyCheckedAnchor DRepMetadataUrl
:: PotentiallyCheckedAnchor DRepMetadataUrl (L.Anchor L.StandardCrypto)
-- ^ The information about anchor data and whether to check the hash (see 'PotentiallyCheckedAnchor')
-> ExceptT HashCheckError IO ()
carryHashChecks potentiallyCheckedAnchor =
Expand All @@ -225,7 +225,7 @@ carryHashChecks potentiallyCheckedAnchor =
L.AnchorData
<$> withExceptT
FetchURLError
(getByteStringFromURL httpsAndIpfsSchemas $ L.anchorUrl anchor)
(getByteStringFromURL httpsAndIpfsSchemas $ L.urlToText $ L.anchorUrl anchor)
let hash = L.hashAnchorData anchorData
when (hash /= L.anchorDataHash anchor) $
left $
Expand Down
Loading
Loading