1
module Cardano.CLI.Shelley.Run.Governance
2
( ShelleyGovernanceCmdError
3
, renderShelleyGovernanceError
9
import qualified Data.Text as Text
11
import Control.Monad.Trans.Except.Extra (firstExceptT, left, newExceptT)
14
import Cardano.Api.Shelley
16
import Cardano.CLI.Shelley.Key (InputDecodeError, VerificationKeyOrHashOrFile,
17
readVerificationKeyOrHashOrFile, readVerificationKeyOrHashOrTextEnvFile)
18
import Cardano.CLI.Shelley.Parsers
19
import Cardano.CLI.Types
21
import qualified Shelley.Spec.Ledger.TxBody as Shelley
24
data ShelleyGovernanceCmdError
25
= ShelleyGovernanceCmdTextEnvReadError !(FileError TextEnvelopeError)
26
| ShelleyGovernanceCmdKeyReadError !(FileError InputDecodeError)
27
| ShelleyGovernanceCmdTextEnvWriteError !(FileError ())
28
| ShelleyGovernanceCmdEmptyUpdateProposalError
29
| ShelleyGovernanceCmdMIRCertificateKeyRewardMistmach
32
-- ^ Number of stake verification keys
34
-- ^ Number of reward amounts
37
renderShelleyGovernanceError :: ShelleyGovernanceCmdError -> Text
38
renderShelleyGovernanceError err =
40
ShelleyGovernanceCmdTextEnvReadError fileErr -> Text.pack (displayError fileErr)
41
ShelleyGovernanceCmdKeyReadError fileErr -> Text.pack (displayError fileErr)
42
ShelleyGovernanceCmdTextEnvWriteError fileErr -> Text.pack (displayError fileErr)
43
-- TODO: The equality check is still not working for empty update proposals.
44
ShelleyGovernanceCmdEmptyUpdateProposalError ->
45
"Empty update proposals are not allowed"
46
ShelleyGovernanceCmdMIRCertificateKeyRewardMistmach fp numVKeys numRwdAmts ->
47
"Error creating the MIR certificate at: " <> textShow fp
48
<> " The number of staking keys: " <> textShow numVKeys
49
<> " and the number of reward amounts: " <> textShow numRwdAmts
50
<> " are not equivalent."
52
textShow x = Text.pack (show x)
55
runGovernanceCmd :: GovernanceCmd -> ExceptT ShelleyGovernanceCmdError IO ()
56
runGovernanceCmd (GovernanceMIRPayStakeAddressesCertificate mirpot vKeys rewards out) =
57
runGovernanceMIRCertificatePayStakeAddrs mirpot vKeys rewards out
58
runGovernanceCmd (GovernanceMIRTransfer amt out direction) =
59
runGovernanceMIRCertificateTransfer amt out direction
60
runGovernanceCmd (GovernanceGenesisKeyDelegationCertificate genVk genDelegVk vrfVk out) =
61
runGovernanceGenesisKeyDelegationCertificate genVk genDelegVk vrfVk out
62
runGovernanceCmd (GovernanceUpdateProposal out eNo genVKeys ppUp) =
63
runGovernanceUpdateProposal out eNo genVKeys ppUp
65
runGovernanceMIRCertificatePayStakeAddrs
67
-> [StakeAddress] -- ^ Stake addresses
68
-> [Lovelace] -- ^ Corresponding reward amounts (same length)
70
-> ExceptT ShelleyGovernanceCmdError IO ()
71
runGovernanceMIRCertificatePayStakeAddrs mirPot sAddrs rwdAmts (OutputFile oFp) = do
73
unless (length sAddrs == length rwdAmts) $
74
left $ ShelleyGovernanceCmdMIRCertificateKeyRewardMistmach
75
oFp (length sAddrs) (length rwdAmts)
77
let sCreds = map stakeAddrToStakeCredential sAddrs
78
mirCert = makeMIRCertificate mirPot (StakeAddressesMIR $ zip sCreds rwdAmts)
80
firstExceptT ShelleyGovernanceCmdTextEnvWriteError
82
$ writeFileTextEnvelope oFp (Just mirCertDesc) mirCert
84
mirCertDesc :: TextEnvelopeDescr
85
mirCertDesc = "Move Instantaneous Rewards Certificate"
87
--TODO: expose a pattern for StakeAddress that give us the StakeCredential
88
stakeAddrToStakeCredential :: StakeAddress -> StakeCredential
89
stakeAddrToStakeCredential (StakeAddress _ scred) =
90
fromShelleyStakeCredential scred
92
runGovernanceMIRCertificateTransfer
96
-> ExceptT ShelleyGovernanceCmdError IO ()
97
runGovernanceMIRCertificateTransfer ll (OutputFile oFp) direction = do
98
mirCert <- case direction of
100
return . makeMIRCertificate Shelley.TreasuryMIR $ SendToReservesMIR ll
101
TransferToTreasury ->
102
return . makeMIRCertificate Shelley.ReservesMIR $ SendToTreasuryMIR ll
104
firstExceptT ShelleyGovernanceCmdTextEnvWriteError
106
$ writeFileTextEnvelope oFp (Just $ mirCertDesc direction) mirCert
108
mirCertDesc :: TransferDirection -> TextEnvelopeDescr
109
mirCertDesc TransferToTreasury = "MIR Certificate Send To Treasury"
110
mirCertDesc TransferToReserves = "MIR Certificate Send To Reserves"
113
runGovernanceGenesisKeyDelegationCertificate
114
:: VerificationKeyOrHashOrFile GenesisKey
115
-> VerificationKeyOrHashOrFile GenesisDelegateKey
116
-> VerificationKeyOrHashOrFile VrfKey
118
-> ExceptT ShelleyGovernanceCmdError IO ()
119
runGovernanceGenesisKeyDelegationCertificate genVkOrHashOrFp
122
(OutputFile oFp) = do
123
genesisVkHash <- firstExceptT ShelleyGovernanceCmdKeyReadError
125
$ readVerificationKeyOrHashOrTextEnvFile AsGenesisKey genVkOrHashOrFp
126
genesisDelVkHash <-firstExceptT ShelleyGovernanceCmdKeyReadError
128
$ readVerificationKeyOrHashOrTextEnvFile AsGenesisDelegateKey genDelVkOrHashOrFp
129
vrfVkHash <- firstExceptT ShelleyGovernanceCmdKeyReadError
131
$ readVerificationKeyOrHashOrFile AsVrfKey vrfVkOrHashOrFp
132
firstExceptT ShelleyGovernanceCmdTextEnvWriteError
134
$ writeFileTextEnvelope oFp (Just genKeyDelegCertDesc)
135
$ makeGenesisKeyDelegationCertificate genesisVkHash genesisDelVkHash vrfVkHash
137
genKeyDelegCertDesc :: TextEnvelopeDescr
138
genKeyDelegCertDesc = "Genesis Key Delegation Certificate"
140
runGovernanceUpdateProposal
143
-> [VerificationKeyFile]
144
-- ^ Genesis verification keys
145
-> ProtocolParametersUpdate
146
-> ExceptT ShelleyGovernanceCmdError IO ()
147
runGovernanceUpdateProposal (OutputFile upFile) eNo genVerKeyFiles upPprams = do
148
when (upPprams == mempty) $ left ShelleyGovernanceCmdEmptyUpdateProposalError
150
[ firstExceptT ShelleyGovernanceCmdTextEnvReadError . newExceptT $
152
(AsVerificationKey AsGenesisKey)
154
| VerificationKeyFile vkeyFile <- genVerKeyFiles ]
155
let genKeyHashes = map verificationKeyHash genVKeys
156
upProp = makeShelleyUpdateProposal upPprams genKeyHashes eNo
157
firstExceptT ShelleyGovernanceCmdTextEnvWriteError . newExceptT $
158
writeFileTextEnvelope upFile Nothing upProp