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

Incorporate CIP-129 #1087

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
6 changes: 6 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,9 @@ if impl (ghc >= 9.12)
-- https://github.com/fizruk/http-api-data/pull/146
, http-api-data:base


source-repository-package
type: git
location: https://github.com/IntersectMBO/cardano-api.git
tag: cc7535791ee480e7644acc3283c58e4a2f44e85d
subdir: cardano-api
13 changes: 13 additions & 0 deletions cardano-cli/cardano-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ library
Cardano.CLI.EraIndependent.Address.Info.Run
Cardano.CLI.EraIndependent.Address.Option
Cardano.CLI.EraIndependent.Address.Run
Cardano.CLI.EraIndependent.Cip.Cip129.Command
Cardano.CLI.EraIndependent.Cip.Cip129.Conversion
Cardano.CLI.EraIndependent.Cip.Cip129.Options
Cardano.CLI.EraIndependent.Cip.Cip129.Run
Cardano.CLI.EraIndependent.Cip.Command
Cardano.CLI.EraIndependent.Cip.Common
Cardano.CLI.EraIndependent.Cip.Options
Cardano.CLI.EraIndependent.Cip.Run
Cardano.CLI.EraIndependent.Debug.CheckNodeConfiguration.Command
Cardano.CLI.EraIndependent.Debug.CheckNodeConfiguration.Run
Cardano.CLI.EraIndependent.Debug.Command
Expand Down Expand Up @@ -179,6 +187,10 @@ library
Cardano.CLI.Orphan
Cardano.CLI.Parser
Cardano.CLI.Read
Cardano.CLI.Read.Committee.ColdKey
Cardano.CLI.Read.Committee.HotKey
Cardano.CLI.Read.DRep
Cardano.CLI.Read.GovernanceActionId
Cardano.CLI.Render
Cardano.CLI.Run
Cardano.CLI.TopHandler
Expand Down Expand Up @@ -279,6 +291,7 @@ library
transformers-except ^>=0.1.3,
unliftio-core,
utf8-string,
validation,
vector,
yaml,

Expand Down
3 changes: 3 additions & 0 deletions cardano-cli/src/Cardano/CLI/Command.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Cardano.CLI.Compatible.Command
import Cardano.CLI.EraBased.Command
import Cardano.CLI.EraBased.Query.Command
import Cardano.CLI.EraIndependent.Address.Command
import Cardano.CLI.EraIndependent.Cip.Command (CipFormatCmds)
import Cardano.CLI.EraIndependent.Debug.Command
import Cardano.CLI.EraIndependent.Hash.Command (HashCmds)
import Cardano.CLI.EraIndependent.Key.Command
Expand Down Expand Up @@ -37,6 +38,8 @@ data ClientCommand
forall era. QueryCommands (QueryCmds era)
| -- | Legacy shelley-based Commands
LegacyCmds LegacyCmds
| -- | Miscellaneous commands
CipFormatCmds CipFormatCmds
| CliPingCommand PingCmd
| CliDebugCmds DebugCmds
| forall a. Help ParserPrefs (ParserInfo a)
Expand Down
1 change: 1 addition & 0 deletions cardano-cli/src/Cardano/CLI/EraBased/Common/Option.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,7 @@ pKesVerificationKey =
Left err@(Bech32DataPartToBytesError _) -> Left (docToString $ prettyError err)
Left err@(Bech32DeserialiseFromBytesError _) -> Left (docToString $ prettyError err)
Left err@(Bech32WrongPrefix _ _) -> Left (docToString $ prettyError err)
Left err@(Bech32UnexpectedHeader _ _) -> Left (docToString $ prettyError err)
-- The input was not valid Bech32. Attempt to deserialise it as hex.
Left (Bech32DecodingError _) ->
first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module Cardano.CLI.EraBased.Governance.DRep.Command
, GovernanceDRepRetirementCertificateCmdArgs (..)
, GovernanceDRepUpdateCertificateCmdArgs (..)
, GovernanceDRepMetadataHashCmdArgs (..)
, DRepIdOutputFormat (..)
, DRepMetadataSource (..)
)
where
Expand Down Expand Up @@ -43,7 +44,7 @@ data GovernanceDRepIdCmdArgs era
= GovernanceDRepIdCmdArgs
{ eon :: !(ConwayEraOnwards era)
, vkeySource :: !(VerificationKeyOrHashOrFile DRepKey)
, idOutputFormat :: !IdOutputFormat
, idOutputFormat :: !DRepIdOutputFormat
, mOutFile :: !(Maybe (File () Out))
}

Expand Down Expand Up @@ -112,3 +113,8 @@ renderGovernanceDRepCmds = \case
"governance drep update-certificate"
GovernanceDRepMetadataHashCmd{} ->
"governance drep metadata-hash"

data DRepIdOutputFormat
= IdOutputFormat IdOutputFormat
| DRepCIP129OutputFormat
deriving (Eq, Show)
12 changes: 8 additions & 4 deletions cardano-cli/src/Cardano/CLI/EraBased/Governance/DRep/Option.hs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,16 @@ pGovernanceDRepKeyIdCmd era = do
)
$ Opt.progDesc "Generate a drep id."

pDRepIdOutputFormat :: Parser IdOutputFormat
pDRepIdOutputFormat :: Parser DRepIdOutputFormat
pDRepIdOutputFormat =
asum [make IdOutputFormatHex "hex", make IdOutputFormatBech32 "bech32"]
<|> pure default_
asum
[ make (IdOutputFormat IdOutputFormatHex) "hex"
, make (IdOutputFormat IdOutputFormatBech32) "bech32"
, make DRepCIP129OutputFormat "cip129"
, pure default_
]
where
default_ = IdOutputFormatBech32
default_ = IdOutputFormat IdOutputFormatBech32
make format flag_ =
Opt.flag' format $
mconcat
Expand Down
9 changes: 7 additions & 2 deletions cardano-cli/src/Cardano/CLI/EraBased/Governance/DRep/Run.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ where

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

import Cardano.CLI.EraBased.Governance.DRep.Command qualified as Cmd
import Cardano.CLI.EraIndependent.Hash.Command qualified as Cmd
Expand Down Expand Up @@ -93,8 +94,12 @@ runGovernanceDRepIdCmd

content <-
pure $ case idOutputFormat of
IdOutputFormatHex -> serialiseToRawBytesHex drepVerKeyHash
IdOutputFormatBech32 -> Text.encodeUtf8 $ serialiseToBech32 drepVerKeyHash
Cmd.IdOutputFormat IdOutputFormatHex -> serialiseToRawBytesHex drepVerKeyHash
Cmd.IdOutputFormat IdOutputFormatBech32 -> Text.encodeUtf8 $ serialiseToBech32 drepVerKeyHash
Cmd.DRepCIP129OutputFormat ->
let DRepKeyHash kh = drepVerKeyHash
keyCredential = L.KeyHashObj kh
in Text.encodeUtf8 $ serialiseToBech32CIP129 keyCredential

lift (writeByteStringOutput mOutFile content)
& onLeft (left . WriteFileError)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Cardano.CLI.EraIndependent.Cip.Cip129.Command
( Cip129 (..)
, renderCip129Command
)
where

import Cardano.CLI.EraIndependent.Cip.Common

import Data.Text (Text)

data Cip129
= Cip129DRep Input Output
| Cip129CommitteeHotKey Input Output
| Cip129CommitteeColdKey Input Output
| Cip129GovernanceAction Input Output

renderCip129Command :: Cip129 -> Text
renderCip129Command (Cip129DRep{}) = "cip-129 drep"
renderCip129Command (Cip129CommitteeHotKey{}) = "cip-129 committee-hot-key"
renderCip129Command (Cip129CommitteeColdKey{}) = "cip-129 committee-cold-key"
renderCip129Command (Cip129GovernanceAction{}) = "cip-129 governance-action-id"
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{-# LANGUAGE DataKinds #-}

module Cardano.CLI.EraIndependent.Cip.Cip129.Conversion
( encodeCip129DrepVerficationKeyText
, encodeCip129CommitteeColdVerficationKeyText
, encodeCip129CommitteeHotVerficationKeyText
, encodeCip129GovernanceActionIdText
)
where

import Cardano.Api.Ledger (StandardCrypto)
import Cardano.Api.Ledger qualified as L
import Cardano.Api.Shelley

import Cardano.CLI.Read.Committee.ColdKey
import Cardano.CLI.Read.Committee.HotKey
import Cardano.CLI.Read.DRep

import Data.Text

encodeCip129DrepVerficationKeyText :: AnyDrepVerificationKey -> Text
encodeCip129DrepVerficationKeyText = serialiseToBech32CIP129 . anyDrepVerificationKeyToCredential

anyDrepVerificationKeyToCredential
:: AnyDrepVerificationKey -> L.Credential L.DRepRole StandardCrypto
anyDrepVerificationKeyToCredential drepKey =
case drepKey of
AnyDrepVerificationKey vk ->
let DRepKeyHash hash = verificationKeyHash vk
in L.KeyHashObj hash
AnyDrepExtendedVerificationKey vk ->
let DRepExtendedKeyHash hash = verificationKeyHash vk
in L.KeyHashObj hash

encodeCip129CommitteeHotVerficationKeyText :: AnyCommitteeHotVerificationKey -> Text
encodeCip129CommitteeHotVerficationKeyText = serialiseToBech32CIP129 . anyCommitteeHotVerificationKeyToCredential

anyCommitteeHotVerificationKeyToCredential
:: AnyCommitteeHotVerificationKey -> L.Credential L.HotCommitteeRole StandardCrypto
anyCommitteeHotVerificationKeyToCredential committeeHotKey =
case committeeHotKey of
AnyCommitteeHotVerificationKey vk ->
let CommitteeHotKeyHash hash = verificationKeyHash vk
in L.KeyHashObj hash
AnyCommitteeHotExtendedVerificationKey vk ->
let CommitteeHotExtendedKeyHash hash = verificationKeyHash vk
in L.KeyHashObj hash

encodeCip129CommitteeColdVerficationKeyText :: AnyCommitteeColdVerificationKey -> Text
encodeCip129CommitteeColdVerficationKeyText = serialiseToBech32CIP129 . anyCommitteeColdVerificationKeyToCredential

anyCommitteeColdVerificationKeyToCredential
:: AnyCommitteeColdVerificationKey -> L.Credential L.ColdCommitteeRole StandardCrypto
anyCommitteeColdVerificationKeyToCredential committeeColdKey =
case committeeColdKey of
AnyCommitteeColdVerificationKey vk ->
let CommitteeColdKeyHash hash = verificationKeyHash vk
in L.KeyHashObj hash
AnyCommitteeColdExtendedVerificationKey vk ->
let CommitteeColdExtendedKeyHash hash = verificationKeyHash vk
in L.KeyHashObj hash

encodeCip129GovernanceActionIdText :: L.GovActionId StandardCrypto -> Text
encodeCip129GovernanceActionIdText = serialiseToBech32CIP129
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module Cardano.CLI.EraIndependent.Cip.Cip129.Options
( pCip129
)
where

import Cardano.CLI.EraIndependent.Cip.Command
import Cardano.CLI.EraIndependent.Cip.Common

import Control.Applicative
import Options.Applicative qualified as Opt

pCip129 :: Opt.Parser CipFormatCmds
pCip129 =
Cip129
<$> asum
[ pCip129Drep
, pCip129CommitteeHotKey
, pCip129CommitteeColdKey
, pCip129GovernanceAction
]

pCip129Drep :: Opt.Parser Cip129
pCip129Drep =
Cip129DRep
<$> pInput
<*> pOutput
where
pInput =
asum
[ pInputFile "drep-file" "Input hex/bech32/text envelope drep file"
, pInputHexText "drep-hex" "HEX" "Input hex encoded drep"
, pInputBech32Text "drep-bech32" "BECH32" "Input bech32 encoded drep"
]

pCip129CommitteeHotKey :: Opt.Parser Cip129
pCip129CommitteeHotKey =
Cip129CommitteeHotKey
<$> pInput
<*> pOutput
where
pInput =
asum
[ pInputFile "committee-hot-key-file" "Input hex/bech32/text envelope committee hot key file"
, pInputHexText "committee-hot-key-hex" "HEX" "Input hex encoded committee hot key"
, pInputBech32Text "committee-hot-key-bech32" "BECH32" "Input bech32 encoded committee hot key"
]

pCip129CommitteeColdKey :: Opt.Parser Cip129
pCip129CommitteeColdKey =
Cip129CommitteeColdKey
<$> pInput
<*> pOutput
where
pInput =
asum
[ pInputFile "committee-cold-key-file" "Input hex/bech32/text envelope committee cold key file"
, pInputHexText "committee-cold-key-hex" "HEX" "Input hex encoded committee cold key"
, pInputBech32Text "committee-cold-key-bech32" "BECH32" "Input bech32 encoded committee cold key"
]

pCip129GovernanceAction :: Opt.Parser Cip129
pCip129GovernanceAction =
Cip129GovernanceAction
<$> pInput
<*> pOutput
where
pInput =
asum
[ pInputFile "governance-action-file" "Input hex/bech32/text envelope governance action file"
, pInputHexText "governance-action-hex" "HEX" "Input hex encoded governance action"
, pInputBech32Text "governance-action-bech32" "BECH32" "Input bech32 encoded governance action"
]

pOutput :: Opt.Parser Output
pOutput =
asum
[ pOutputFile "output-file" "Output file"
, pOutputText "output-text" "Output text"
]
78 changes: 78 additions & 0 deletions cardano-cli/src/Cardano/CLI/EraIndependent/Cip/Cip129/Run.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{-# LANGUAGE RankNTypes #-}

module Cardano.CLI.EraIndependent.Cip.Cip129.Run
( runCip129
)
where

import Cardano.Api

import Cardano.CLI.Compatible.Exception
import Cardano.CLI.EraIndependent.Cip.Cip129.Command
import Cardano.CLI.EraIndependent.Cip.Cip129.Conversion
import Cardano.CLI.EraIndependent.Cip.Common
import Cardano.CLI.Orphan ()
import Cardano.CLI.Read
import Cardano.CLI.Read.Committee.ColdKey
import Cardano.CLI.Read.Committee.HotKey
import Cardano.CLI.Read.DRep
import Cardano.CLI.Read.GovernanceActionId

import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.ByteString.Char8 qualified as BSC
import Data.Text.Encoding qualified as Text
import Data.Validation qualified as Valid
import System.IO

runCip129 :: Cip129 -> CIO e ()
runCip129 (Cip129DRep inp out) = do
k <- case inp of
InputTextEnvelopeFile (File textEnvFp) -> do
f <- liftIO $ fileOrPipe textEnvFp
fromEitherIOCli $ readDrepVerificationKeyFile f
InputHexText t -> do
fromEitherCli . Valid.toEither $ readDRepHexVerificationKeyText t
InputBech32Text t -> do
fromEitherCli . Valid.toEither $ readDRepBech32VerificationKeyText t
let cip129Output = Text.encodeUtf8 $ encodeCip129DrepVerficationKeyText k
renderOutput cip129Output out
runCip129 (Cip129CommitteeHotKey inp out) = do
k <- case inp of
InputTextEnvelopeFile (File textEnvFp) -> do
f <- liftIO $ fileOrPipe textEnvFp
fromEitherIOCli $ readCommitteeHotVerificationKeyFile f
InputHexText t ->
fromEitherCli . Valid.toEither $ readCommitteeHotHexVerificationKeyText t
InputBech32Text t ->
fromEitherCli . Valid.toEither $ readCommitteeHotBech32VerificationKeyText t
let cip129Output = Text.encodeUtf8 $ encodeCip129CommitteeHotVerficationKeyText k
renderOutput cip129Output out
runCip129 (Cip129CommitteeColdKey inp out) = do
k <- case inp of
InputTextEnvelopeFile (File textEnvFp) -> do
f <- liftIO $ fileOrPipe textEnvFp
fromEitherIOCli $ readCommitteeColdVerificationKeyFile f
InputHexText t ->
fromEitherCli . Valid.toEither $ readCommitteeColdHexVerificationKeyText t
InputBech32Text t ->
fromEitherCli . Valid.toEither $ readCommitteeColdBech32VerificationKeyText t
let cip129Output = Text.encodeUtf8 $ encodeCip129CommitteeColdVerficationKeyText k
renderOutput cip129Output out
runCip129 (Cip129GovernanceAction inp out) =
case inp of
InputHexText t -> do
govId <- fromEitherCli $ readGoveranceActionIdHexText t
let cip129Output = Text.encodeUtf8 $ encodeCip129GovernanceActionIdText govId
renderOutput cip129Output out
InputBech32Text{} ->
throwCliError $ InputError "Bech32 encoded Governance Action Id is not supported"
InputTextEnvelopeFile{} ->
throwCliError $ InputError "TextEnvelope encoded Governance Action Id is not supported"

renderOutput :: ByteString -> Output -> CIO e ()
renderOutput cip129Output out = case out of
OutputText -> do
liftIO $ BSC.hPutStrLn stdout cip129Output
OutputFile (File fp) -> do
liftIO $ BS.writeFile fp cip129Output
Loading
Loading