Skip to content

Commit

Permalink
Merge pull request #374 from input-output-hk/ch/governance-action-view
Browse files Browse the repository at this point in the history
Add `conway governance action view`
  • Loading branch information
carlhammann authored Oct 16, 2023
2 parents a6034e5 + f88da54 commit ab97695
Show file tree
Hide file tree
Showing 18 changed files with 325 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Cardano.CLI.EraBased.Commands.Governance.Actions
, GovernanceActionCreateConstitutionCmdArgs(..)
, GovernanceActionCreateNoConfidenceCmdArgs(..)
, GovernanceActionInfoCmdArgs(..)
, GovernanceActionViewCmdArgs(..)
, GovernanceActionProtocolParametersUpdateCmdArgs(..)
, GovernanceActionTreasuryWithdrawalCmdArgs(..)
, renderGovernanceActionCmds
Expand All @@ -33,6 +34,7 @@ data GovernanceActionCmds era
| GovernanceActionProtocolParametersUpdateCmd !(GovernanceActionProtocolParametersUpdateCmdArgs era)
| GovernanceActionTreasuryWithdrawalCmd !(GovernanceActionTreasuryWithdrawalCmdArgs era)
| GovernanceActionInfoCmd !(GovernanceActionInfoCmdArgs era)
| GovernanceActionViewCmd !(GovernanceActionViewCmdArgs era)
deriving Show

data GoveranceActionUpdateCommitteeCmdArgs era
Expand Down Expand Up @@ -110,6 +112,14 @@ data GovernanceActionTreasuryWithdrawalCmdArgs era
, outFile :: !(File () Out)
} deriving Show

data GovernanceActionViewCmdArgs era
= GovernanceActionViewCmdArgs
{ eon :: !(ConwayEraOnwards era)
, actionFile :: !(ProposalFile In)
, outFormat :: !GovernanceActionViewOutputFormat
, mOutFile :: !(Maybe (File () Out))
} deriving Show

renderGovernanceActionCmds :: GovernanceActionCmds era -> Text
renderGovernanceActionCmds = ("governance action " <>) . \case
GovernanceActionCreateConstitutionCmd {} ->
Expand All @@ -130,6 +140,9 @@ renderGovernanceActionCmds = ("governance action " <>) . \case
GovernanceActionInfoCmd {} ->
"create-info"

GovernanceActionViewCmd {} ->
"view"

data AnyStakeIdentifier
= AnyStakeKey (VerificationKeyOrHashOrFile StakeKey)
| AnyStakePoolKey (VerificationKeyOrHashOrFile StakePoolKey)
Expand Down
12 changes: 12 additions & 0 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,18 @@ pTxViewOutputFormat =
, Opt.value TxViewOutputFormatJson
]

pGovernanceActionViewOutputFormat :: Parser GovernanceActionViewOutputFormat
pGovernanceActionViewOutputFormat =
Opt.option readGovernanceActionViewOutputFormat $ mconcat
[ Opt.long "output-format"
, Opt.metavar "STRING"
, Opt.help $ mconcat
[ "Optional governance action view output format. Accepted output formats are \"json\" "
, "and \"yaml\" (default is \"json\")."
]
, Opt.value GovernanceActionViewOutputFormatJson
]

pMaybeOutputFile :: Parser (Maybe (File content Out))
pMaybeOutputFile =
optional $ fmap File $ Opt.strOption $ mconcat
Expand Down
17 changes: 17 additions & 0 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/Governance/Actions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,25 @@ pGovernanceActionCmds era =
, pGovernanceActionNoConfidenceCmd era
, pGovernanceActionProtocolParametersUpdateCmd era
, pGovernanceActionTreasuryWithdrawalCmd era
, pGovernanceActionViewCmd era
]

pGovernanceActionViewCmd
:: CardanoEra era
-> Maybe (Parser (Cmd.GovernanceActionCmds era))
pGovernanceActionViewCmd era = do
eon <- forEraMaybeEon era
return
$ subParser "view"
$ Opt.info
( fmap Cmd.GovernanceActionViewCmd
$ Cmd.GovernanceActionViewCmdArgs eon
<$> pFileInDirection "action-file" "Path to action file."
<*> pGovernanceActionViewOutputFormat
<*> pMaybeOutputFile
)
$ Opt.progDesc "View a governance action."

pGovernanceActionNewInfoCmd
:: CardanoEra era
-> Maybe (Parser (Cmd.GovernanceActionCmds era))
Expand Down
24 changes: 24 additions & 0 deletions cardano-cli/src/Cardano/CLI/EraBased/Run/Governance/Actions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Cardano.Api.Shelley

import Cardano.CLI.EraBased.Commands.Governance.Actions
import qualified Cardano.CLI.EraBased.Commands.Governance.Actions as Cmd
import Cardano.CLI.Json.Friendly
import Cardano.CLI.Read
import Cardano.CLI.Types.Common
import Cardano.CLI.Types.Errors.GovernanceActionsError
Expand Down Expand Up @@ -52,6 +53,29 @@ runGovernanceActionCmds = \case
GovernanceActionInfoCmd args ->
runGovernanceActionInfoCmd args

GovernanceActionViewCmd args ->
runGovernanceActionViewCmd args

runGovernanceActionViewCmd :: ()
=> GovernanceActionViewCmdArgs era
-> ExceptT GovernanceActionsError IO ()
runGovernanceActionViewCmd
Cmd.GovernanceActionViewCmdArgs
{ Cmd.outFormat
, Cmd.actionFile
, Cmd.mOutFile
, Cmd.eon
} = do
proposal <- firstExceptT GovernanceActionsCmdReadTextEnvelopeFileError . newExceptT $ readProposal eon actionFile
firstExceptT GovernanceActionsCmdWriteFileError . newExceptT $
friendlyProposal
(case outFormat of
GovernanceActionViewOutputFormatJson -> FriendlyJson
GovernanceActionViewOutputFormatYaml -> FriendlyYaml)
mOutFile
eon
proposal

runGovernanceActionInfoCmd :: ()
=> GovernanceActionInfoCmdArgs era
-> ExceptT GovernanceActionsError IO ()
Expand Down
12 changes: 5 additions & 7 deletions cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ import Cardano.Api.Shelley

import qualified Cardano.CLI.EraBased.Commands.Transaction as Cmd
import Cardano.CLI.EraBased.Run.Genesis
import Cardano.CLI.Json.Friendly (friendlyTxBodyJson, friendlyTxBodyYaml, friendlyTxJson,
friendlyTxYaml)
import Cardano.CLI.Json.Friendly (FriendlyFormat (..), friendlyTx, friendlyTxBody)
import Cardano.CLI.Read
import Cardano.CLI.Types.Common
import Cardano.CLI.Types.Errors.BootstrapWitnessError
Expand Down Expand Up @@ -1185,16 +1184,15 @@ runTransactionViewCmd
-- is arguably not part of the transaction body.
firstExceptT TxCmdWriteFileError . newExceptT $
case outputFormat of
TxViewOutputFormatYaml -> friendlyTxBodyYaml mOutFile era txbody
TxViewOutputFormatJson -> friendlyTxBodyJson mOutFile era txbody
TxViewOutputFormatYaml -> friendlyTxBody FriendlyYaml mOutFile era txbody
TxViewOutputFormatJson -> friendlyTxBody FriendlyJson mOutFile era txbody
InputTxFile (File txFilePath) -> do
txFile <- liftIO $ fileOrPipe txFilePath
InAnyCardanoEra era tx <- lift (readFileTx txFile) & onLeft (left . TxCmdCddlError)
firstExceptT TxCmdWriteFileError . newExceptT $
case outputFormat of
TxViewOutputFormatYaml -> friendlyTxYaml mOutFile era tx
TxViewOutputFormatJson -> friendlyTxJson mOutFile era tx

TxViewOutputFormatYaml -> friendlyTx FriendlyYaml mOutFile era tx
TxViewOutputFormatJson -> friendlyTx FriendlyJson mOutFile era tx

-- ----------------------------------------------------------------------------
-- Witness commands
Expand Down
116 changes: 66 additions & 50 deletions cardano-cli/src/Cardano/CLI/Json/Friendly.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,30 @@
{-# LANGUAGE TypeOperators #-}

-- | User-friendly pretty-printing for textual user interfaces (TUI)
module Cardano.CLI.Json.Friendly (friendlyTxYaml, friendlyTxBodyYaml, friendlyTxJson, friendlyTxBodyJson) where
module Cardano.CLI.Json.Friendly
( friendlyTx
, friendlyTxBody
, friendlyProposal
, FriendlyFormat(..)
) where

import Cardano.Api as Api
import Cardano.Api.Byron (KeyWitness (ByronKeyWitness))
import qualified Cardano.Api.Ledger as Ledger
import Cardano.Api.Shelley (Address (ShelleyAddress), Hash (..),
KeyWitness (ShelleyBootstrapWitness, ShelleyKeyWitness), ShelleyLedgerEra,
StakeAddress (..), fromShelleyPaymentCredential, fromShelleyStakeReference,
toShelleyLovelace, toShelleyStakeCredential)
KeyWitness (ShelleyBootstrapWitness, ShelleyKeyWitness), Proposal (Proposal),
ShelleyLedgerEra, StakeAddress (..), fromShelleyPaymentCredential,
fromShelleyStakeReference, toShelleyLovelace, toShelleyStakeCredential)

import qualified Cardano.Ledger.Conway.Governance as Gov
import qualified Cardano.Ledger.Conway.TxCert as ConwayLedger
import qualified Cardano.Ledger.Credential as Shelley
import qualified Cardano.Ledger.Shelley.API as Shelley

import Control.Monad.Trans (MonadIO)
import Data.Aeson (Value (..), object, toJSON, (.=))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Encode.Pretty as Aeson
import qualified Data.Aeson.Key as Aeson
import qualified Data.Aeson.Types as Aeson
import qualified Data.ByteString.Char8 as BSC
Expand All @@ -42,70 +50,78 @@ import Data.Yaml.Pretty (setConfCompare)
import qualified Data.Yaml.Pretty as Yaml
import GHC.Real (denominator)
import GHC.Unicode (isAlphaNum)
import qualified Data.Aeson.Encode.Pretty as Aeson
import Control.Monad.Trans (MonadIO)

jsonConfig :: Aeson.Config
jsonConfig = Aeson.defConfig {Aeson.confCompare = compare}
data FriendlyFormat = FriendlyJson | FriendlyYaml

friendlyTxJson ::
(MonadIO m)
=> Maybe (File () Out)
-> CardanoEra era
-> Tx era
friendly ::
(MonadIO m, Aeson.ToJSON a)
=> FriendlyFormat
-> Maybe (File () Out)
-> a
-> m (Either (FileError e) ())
friendlyTxJson mOutFile era =
cardanoEraConstraints era $
writeLazyByteStringOutput mOutFile .
Aeson.encodePretty' jsonConfig .
object .
friendlyTx era
friendly FriendlyJson mOutFile = writeLazyByteStringOutput mOutFile . Aeson.encodePretty' jsonConfig
friendly FriendlyYaml mOutFile = writeByteStringOutput mOutFile . Yaml.encodePretty yamlConfig

friendlyTxBodyJson ::
(MonadIO m)
=> Maybe (File () Out)
-> CardanoEra era
-> TxBody era
-> m (Either (FileError e) ())
friendlyTxBodyJson mOutFile era =
cardanoEraConstraints era $
writeLazyByteStringOutput mOutFile .
Aeson.encodePretty' jsonConfig .
object .
friendlyTxBody era
jsonConfig :: Aeson.Config
jsonConfig = Aeson.defConfig {Aeson.confCompare = compare}

yamlConfig :: Yaml.Config
yamlConfig = Yaml.defConfig & setConfCompare compare

friendlyTxYaml ::
friendlyTx ::
(MonadIO m)
=> Maybe (File () Out)
=> FriendlyFormat
-> Maybe (File () Out)
-> CardanoEra era
-> Tx era
-> m (Either (FileError e) ())
friendlyTxYaml mOutFile era =
friendlyTx format mOutFile era =
cardanoEraConstraints era $
writeByteStringOutput mOutFile .
Yaml.encodePretty yamlConfig .
object .
friendlyTx era
friendly format mOutFile . object . friendlyTxImpl era

friendlyTxBodyYaml ::
friendlyTxBody ::
(MonadIO m)
=> Maybe (File () Out)
=> FriendlyFormat
-> Maybe (File () Out)
-> CardanoEra era
-> TxBody era
-> m (Either (FileError e) ())
friendlyTxBodyYaml mOutFile era =
friendlyTxBody format mOutFile era =
cardanoEraConstraints era $
writeByteStringOutput mOutFile .
Yaml.encodePretty yamlConfig .
object .
friendlyTxBody era
friendly format mOutFile . object . friendlyTxBodyImpl era

friendlyProposal ::
(MonadIO m)
=> FriendlyFormat
-> Maybe (File () Out)
-> ConwayEraOnwards era
-> Proposal era
-> m (Either (FileError e) ())
friendlyProposal format mOutFile era =
conwayEraOnwardsConstraints era $
friendly format mOutFile . object . friendlyProposalImpl era

friendlyProposalImpl :: ConwayEraOnwards era -> Proposal era -> [Aeson.Pair]
friendlyProposalImpl
era
(Proposal
(Gov.ProposalProcedure
{ Gov.pProcDeposit
, Gov.pProcReturnAddr
, Gov.pProcGovAction
, Gov.pProcAnchor
}
)
) = conwayEraOnwardsConstraints era
[ "deposit" .= pProcDeposit
, "return address" .= pProcReturnAddr
, "governance action" .= pProcGovAction
, "anchor" .= pProcAnchor
]

friendlyTx :: IsCardanoEra era => CardanoEra era -> Tx era -> [Aeson.Pair]
friendlyTx era (Tx body witnesses) =
("witnesses" .= map friendlyKeyWitness witnesses) : friendlyTxBody era body
friendlyTxImpl :: IsCardanoEra era => CardanoEra era -> Tx era -> [Aeson.Pair]
friendlyTxImpl era (Tx body witnesses) =
("witnesses" .= map friendlyKeyWitness witnesses) : friendlyTxBodyImpl era body

friendlyKeyWitness :: KeyWitness era -> Aeson.Value
friendlyKeyWitness =
Expand All @@ -117,8 +133,8 @@ friendlyKeyWitness =
ShelleyKeyWitness _era (Shelley.WitVKey key signature) ->
["key" .= textShow key, "signature" .= textShow signature]

friendlyTxBody :: IsCardanoEra era => CardanoEra era -> TxBody era -> [Aeson.Pair]
friendlyTxBody
friendlyTxBodyImpl :: IsCardanoEra era => CardanoEra era -> TxBody era -> [Aeson.Pair]
friendlyTxBodyImpl
era
(TxBody
TxBodyContent
Expand Down
13 changes: 13 additions & 0 deletions cardano-cli/src/Cardano/CLI/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module Cardano.CLI.Parser
, readStringOfMaxLength
, readURIOfMaxLength
, eDNSName
, readGovernanceActionViewOutputFormat
) where

import Cardano.CLI.Types.Common
Expand Down Expand Up @@ -62,6 +63,18 @@ readTxViewOutputFormat = do
, ". Accepted output formats are \"json\" and \"yaml\"."
]

readGovernanceActionViewOutputFormat :: Opt.ReadM GovernanceActionViewOutputFormat
readGovernanceActionViewOutputFormat = do
s <- Opt.str @String
case s of
"json" -> pure GovernanceActionViewOutputFormatJson
"yaml" -> pure GovernanceActionViewOutputFormatYaml
_ ->
fail $ mconcat
[ "Invalid governance action view output format: " <> show s
, ". Accepted output formats are \"json\" and \"yaml\"."
]

readURIOfMaxLength :: Int -> Opt.ReadM Text
readURIOfMaxLength maxLen =
Text.pack <$> readStringOfMaxLength maxLen
Expand Down
8 changes: 4 additions & 4 deletions cardano-cli/src/Cardano/CLI/Read.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module Cardano.CLI.Read
, readTxGovernanceActions
, constitutionHashSourceToHash
, proposalHashSourceToHash
, readProposal

-- * FileOrPipe
, FileOrPipe
Expand Down Expand Up @@ -826,15 +827,14 @@ readTxGovernanceActions _ [] = return $ Right []
readTxGovernanceActions era files = runExceptT $ do
w <- forEraMaybeEon era
& hoistMaybe (ConstitutionNotSupportedInEra $ cardanoEraConstraints era $ AnyCardanoEra era)
newExceptT $ sequence <$> mapM (readProposal w) files
newExceptT $ sequence <$> mapM (fmap (first ConstitutionErrorFile) . readProposal w) files

readProposal
:: ConwayEraOnwards era
-> ProposalFile In
-> IO (Either ConstitutionError (Proposal era))
-> IO (Either (FileError TextEnvelopeError) (Proposal era))
readProposal w fp =
first ConstitutionErrorFile
<$> conwayEraOnwardsConstraints w (readFileTextEnvelope AsProposal fp)
conwayEraOnwardsConstraints w (readFileTextEnvelope AsProposal fp)

constitutionHashSourceToHash :: ()
=> ConstitutionHashSource
Expand Down
5 changes: 5 additions & 0 deletions cardano-cli/src/Cardano/CLI/Types/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module Cardano.CLI.Types.Common
, GenesisDir(..)
, GenesisFile (..)
, GenesisKeyFile(..)
, GovernanceActionViewOutputFormat(..)
, InputTxBodyOrTxFile (..)
, KeyOutputFormat(..)
, MetadataFile(..)
Expand Down Expand Up @@ -465,6 +466,10 @@ data TxViewOutputFormat
| TxViewOutputFormatYaml
deriving Show

data GovernanceActionViewOutputFormat
= GovernanceActionViewOutputFormatJson
| GovernanceActionViewOutputFormatYaml
deriving Show
--
-- Shelley CLI flag/option data types
--
Expand Down
Loading

0 comments on commit ab97695

Please sign in to comment.