diff --git a/cabal.project b/cabal.project index 8d34ceba70..8ea76f51e6 100644 --- a/cabal.project +++ b/cabal.project @@ -60,3 +60,10 @@ write-ghc-environment-files: always -- Do NOT add more source-repository-package stanzas here unless they are strictly -- temporary! Please read the section in CONTRIBUTING about updating dependencies. +source-repository-package + type: git + location: https://github.com/IntersectMBO/cardano-api + tag: 6f8d4cad30416f8e74090e7ad3cb3a249c0eb68a + --sha256: sha256-Qx/mALvadNt8wwD+z4r4kPRgdSAJi+WAnTK2M57qop0= + subdir: + cardano-api \ No newline at end of file diff --git a/cardano-cli/cardano-cli.cabal b/cardano-cli/cardano-cli.cabal index 3b2060459c..a37a92093f 100644 --- a/cardano-cli/cardano-cli.cabal +++ b/cardano-cli/cardano-cli.cabal @@ -117,8 +117,13 @@ library Cardano.CLI.EraBased.Run.StakePool Cardano.CLI.EraBased.Run.TextView Cardano.CLI.EraBased.Run.Transaction + Cardano.CLI.EraBased.Script.Certificate.Read + Cardano.CLI.EraBased.Script.Certificate.Types Cardano.CLI.EraBased.Script.Mint.Read Cardano.CLI.EraBased.Script.Mint.Types + Cardano.CLI.EraBased.Script.Spend.Read + Cardano.CLI.EraBased.Script.Spend.Types + Cardano.CLI.EraBased.Script.Types Cardano.CLI.EraBased.Transaction.HashCheck Cardano.CLI.Helpers Cardano.CLI.IO.Lazy @@ -364,6 +369,7 @@ test-suite cardano-cli-test Test.Cli.Shelley.Run.Hash Test.Cli.Shelley.Run.Query Test.Cli.Shelley.Transaction.Build + Test.Cli.Shelley.Transaction.Compatible.Build Test.Cli.VerificationKey ghc-options: diff --git a/cardano-cli/src/Cardano/CLI/Compatible/Transaction.hs b/cardano-cli/src/Cardano/CLI/Compatible/Transaction.hs index 52d169d10a..4d776163ec 100644 --- a/cardano-cli/src/Cardano/CLI/Compatible/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/Compatible/Transaction.hs @@ -2,6 +2,7 @@ {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} module Cardano.CLI.Compatible.Transaction @@ -21,16 +22,24 @@ import Cardano.Api.Shelley hiding (VotingProcedures) import Cardano.CLI.Environment import Cardano.CLI.EraBased.Options.Common hiding (pRefScriptFp, pTxOutDatum) import Cardano.CLI.EraBased.Run.Transaction +import Cardano.CLI.EraBased.Script.Certificate.Read +import Cardano.CLI.EraBased.Script.Certificate.Types +import Cardano.CLI.EraBased.Script.Types import Cardano.CLI.Parser import Cardano.CLI.Read import Cardano.CLI.Types.Common import Cardano.CLI.Types.Errors.BootstrapWitnessError import Cardano.CLI.Types.Errors.TxCmdError import Cardano.CLI.Types.Governance +import Cardano.CLI.Types.TxFeature +import Data.Bifunctor (first) import Data.Foldable import Data.Function +import qualified Data.Map.Strict as Map +import Data.Maybe import Data.Text (Text) +import GHC.Exts (IsList (..)) import Options.Applicative import qualified Options.Applicative as Opt @@ -59,11 +68,12 @@ pCompatibleSignedTransaction env sbe = <$> many pTxInOnly <*> many (pTxOutEraAware sbe) <*> pFeatured (toCardanoEra sbe) (optional pUpdateProposalFile) - <*> pFeatured (toCardanoEra sbe) (many (pProposalFile sbe ManualBalance)) + <*> pFeatured (toCardanoEra sbe) (many (pProposalFile ManualBalance)) <*> pVoteFiles sbe ManualBalance <*> many pWitnessSigningData <*> optional (pNetworkId env) <*> pTxFee + <*> many (pCertificateFile ManualBalance) <*> pOutputFile pTxInOnly :: Parser TxIn @@ -178,13 +188,15 @@ data CompatibleTransactionCmds era (Maybe NetworkId) !Coin -- ^ Tx fee + ![(CertificateFile, Maybe CliCertificateScriptRequirements)] + -- ^ stake registering certs !(File () Out) renderCompatibleTransactionCmd :: CompatibleTransactionCmds era -> Text renderCompatibleTransactionCmd _ = "" data CompatibleTransactionError - = CompatibleTxOutError !TxCmdError + = CompatibleTxCmdError !TxCmdError | CompatibleWitnessError !ReadWitnessSigningDataError | CompatiblePParamsConversionError !ProtocolParametersConversionError | CompatibleBootstrapWitnessError !BootstrapWitnessError @@ -193,10 +205,12 @@ data CompatibleTransactionError | CompatibleProposalError !ProposalError | CompatibleVoteError !VoteError | forall era. CompatibleVoteMergeError !(VotesMergingConflict era) + | CompatibleScriptWitnessError !ScriptWitnessError + | CompatibleScriptWitnessReadError !(FileError CliScriptWitnessError) instance Error CompatibleTransactionError where prettyError = \case - CompatibleTxOutError e -> renderTxCmdError e + CompatibleTxCmdError e -> renderTxCmdError e CompatibleWitnessError e -> renderReadWitnessSigningDataError e CompatiblePParamsConversionError e -> prettyError e CompatibleBootstrapWitnessError e -> renderBootstrapWitnessError e @@ -205,9 +219,13 @@ instance Error CompatibleTransactionError where CompatibleProposalError e -> pshow e CompatibleVoteError e -> pshow e CompatibleVoteMergeError e -> pshow e + CompatibleScriptWitnessError e -> renderScriptWitnessError e + CompatibleScriptWitnessReadError e -> prettyError e runCompatibleTransactionCmd - :: CompatibleTransactionCmds era -> ExceptT CompatibleTransactionError IO () + :: forall era + . CompatibleTransactionCmds era + -> ExceptT CompatibleTransactionError IO () runCompatibleTransactionCmd ( CreateCompatibleSignedTransaction sbe @@ -219,12 +237,72 @@ runCompatibleTransactionCmd witnesses mNetworkId fee + certificates outputFp ) = do sks <- firstExceptT CompatibleWitnessError $ mapM (newExceptT . readWitnessSigningData) witnesses - allOuts <- firstExceptT CompatibleTxOutError $ mapM (toTxOutInAnyEra sbe) outs + allOuts <- firstExceptT CompatibleTxCmdError $ mapM (toTxOutInAnyEra sbe) outs + certFilesAndMaybeScriptWits <- + firstExceptT CompatibleScriptWitnessReadError $ + readCertificateScriptWitnesses sbe certificates + + certsAndMaybeScriptWits :: [(Certificate era, Maybe (ScriptWitness WitCtxStake era))] <- + shelleyBasedEraConstraints sbe $ + sequence + [ fmap + (,cswScriptWitness <$> mSwit) + ( firstExceptT CompatibleFileError . newExceptT $ + readFileTextEnvelope AsCertificate (File certFile) + ) + | (CertificateFile certFile, mSwit) <- certFilesAndMaybeScriptWits + ] + + (protocolUpdates, votes) :: (AnyProtocolUpdate era, AnyVote era) <- + caseShelleyToBabbageOrConwayEraOnwards + ( const $ do + prop <- maybe (pure $ NoPParamsUpdate sbe) readUpdateProposalFile mUpdateProposal + return (prop, NoVotes) + ) + ( \w -> do + prop <- maybe (pure $ NoPParamsUpdate sbe) readProposalProcedureFile mProposalProcedure + votesAndWits <- + firstExceptT CompatibleVoteError . newExceptT $ + readVotingProceduresFiles w mVotes + votingProcedures <- + firstExceptT CompatibleVoteMergeError . hoistEither $ + mkTxVotingProcedures votesAndWits + return (prop, VotingProcedures w votingProcedures) + ) + sbe + + let certsRefInputs = + [ refInput + | (_, Just sWit) <- certsAndMaybeScriptWits + , refInput <- maybeToList $ getScriptWitnessReferenceInput sWit + ] + + votesRefInputs = + [ refInput + | VotingProcedures _ (TxVotingProcedures _ (BuildTxWith voteMap)) <- [votes] + , sWit <- Map.elems voteMap + , refInput <- maybeToList $ getScriptWitnessReferenceInput sWit + ] + + proposalsRefInputs = + [ refInput + | ProposalProcedures _ (TxProposalProcedures _ (BuildTxWith proposalMap)) <- [protocolUpdates] + , sWit <- Map.elems proposalMap + , refInput <- maybeToList $ getScriptWitnessReferenceInput sWit + ] + + validatedRefInputs <- + liftEither . first CompatibleTxCmdError . validateTxInsReference $ + certsRefInputs <> votesRefInputs <> proposalsRefInputs + let txCerts = convertCertificates certsAndMaybeScriptWits + + -- this body is only for witnesses apiTxBody <- firstExceptT CompatibleTxBodyError $ hoistEither $ @@ -233,39 +311,52 @@ runCompatibleTransactionCmd & setTxIns (map (,BuildTxWith (KeyWitness KeyWitnessForSpending)) ins) & setTxOuts allOuts & setTxFee (TxFeeExplicit sbe fee) + & setTxCertificates txCerts + & setTxInsReference validatedRefInputs let (sksByron, sksShelley) = partitionSomeWitnesses $ map categoriseSomeSigningWitness sks byronWitnesses <- - firstExceptT CompatibleBootstrapWitnessError $ - hoistEither (mkShelleyBootstrapWitnesses sbe mNetworkId apiTxBody sksByron) + firstExceptT CompatibleBootstrapWitnessError . hoistEither $ + mkShelleyBootstrapWitnesses sbe mNetworkId apiTxBody sksByron let newShelleyKeyWits = map (makeShelleyKeyWitness sbe apiTxBody) sksShelley allKeyWits = newShelleyKeyWits ++ byronWitnesses - (protocolUpdates, votes) <- - caseShelleyToBabbageOrConwayEraOnwards - ( const $ do - prop <- maybe (return $ NoPParamsUpdate sbe) readUpdateProposalFile mUpdateProposal - return (prop, NoVotes) - ) - ( \w -> do - prop <- maybe (return $ NoPParamsUpdate sbe) readProposalProcedureFile mProposalProcedure - votesAndWits <- firstExceptT CompatibleVoteError $ newExceptT $ readVotingProceduresFiles w mVotes - votingProcedures <- - firstExceptT CompatibleVoteMergeError $ hoistEither $ mkTxVotingProcedures votesAndWits - return (prop, VotingProcedures w votingProcedures) - ) - sbe - signedTx <- firstExceptT CompatiblePParamsConversionError . hoistEither $ - -- FIXME https://github.com/IntersectMBO/cardano-cli/pull/972 - createCompatibleSignedTx sbe ins allOuts allKeyWits fee protocolUpdates votes TxCertificatesNone + createCompatibleSignedTx sbe ins allOuts allKeyWits fee protocolUpdates votes txCerts firstExceptT CompatibleFileError $ newExceptT $ writeTxFileTextEnvelopeCddl sbe outputFp signedTx + where + convertCertificates + :: [(Certificate era, Maybe (ScriptWitness WitCtxStake era))] + -> TxCertificates BuildTx era + convertCertificates certsAndScriptWitnesses = + TxCertificates sbe certs $ BuildTxWith reqWits + where + certs = map fst certsAndScriptWitnesses + reqWits = fromList $ mapMaybe convert' certsAndScriptWitnesses + convert' + :: (Certificate era, Maybe (ScriptWitness WitCtxStake era)) + -> Maybe (StakeCredential, Witness WitCtxStake era) + convert' (cert, mScriptWitnessFiles) = do + sCred <- selectStakeCredentialWitness cert + Just . (sCred,) $ case mScriptWitnessFiles of + Just sWit -> ScriptWitness ScriptWitnessForStakeAddr sWit + Nothing -> KeyWitness KeyWitnessForStakeAddr + + validateTxInsReference + :: [TxIn] + -> Either TxCmdError (TxInsReference era) + validateTxInsReference [] = return TxInsReferenceNone + validateTxInsReference allRefIns = do + let era = toCardanoEra era + eraMismatchError = Left $ TxCmdTxFeatureMismatch (anyCardanoEra era) TxFeatureReferenceInputs + w <- maybe eraMismatchError Right $ forEraMaybeEon era + pure $ TxInsReference w allRefIns readUpdateProposalFile :: Featured ShelleyToBabbageEra era (Maybe UpdateProposalFile) diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Commands/Transaction.hs b/cardano-cli/src/Cardano/CLI/EraBased/Commands/Transaction.hs index f6898c8c30..0d61de4995 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Commands/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Commands/Transaction.hs @@ -25,7 +25,9 @@ import qualified Cardano.Api.Experimental as Exp import Cardano.Api.Ledger (Coin) import Cardano.Api.Shelley +import Cardano.CLI.EraBased.Script.Certificate.Types (CliCertificateScriptRequirements) import Cardano.CLI.EraBased.Script.Mint.Types +import Cardano.CLI.EraBased.Script.Spend.Types (CliSpendScriptRequirements) import Cardano.CLI.Types.Common import Cardano.CLI.Types.Governance @@ -49,7 +51,7 @@ data TransactionBuildRawCmdArgs era = TransactionBuildRawCmdArgs { eon :: !(ShelleyBasedEra era) , mScriptValidity :: !(Maybe ScriptValidity) -- ^ Mark script as expected to pass or fail validation - , txIns :: ![(TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn))] + , txIns :: ![(TxIn, Maybe CliSpendScriptRequirements)] -- ^ Transaction inputs with optional spending scripts , readOnlyRefIns :: ![TxIn] -- ^ Read only reference inputs @@ -70,7 +72,7 @@ data TransactionBuildRawCmdArgs era = TransactionBuildRawCmdArgs -- ^ Transaction validity upper bound , fee :: !Coin -- ^ Transaction fee - , certificates :: ![(CertificateFile, Maybe (ScriptWitnessFiles WitCtxStake))] + , certificates :: ![(CertificateFile, Maybe CliCertificateScriptRequirements)] -- ^ Certificates with potential script witness , withdrawals :: ![(StakeAddress, Coin, Maybe (ScriptWitnessFiles WitCtxStake))] , metadataSchema :: !TxMetadataJsonSchema @@ -96,7 +98,7 @@ data TransactionBuildCmdArgs era = TransactionBuildCmdArgs -- ^ Mark script as expected to pass or fail validation , mOverrideWitnesses :: !(Maybe Word) -- ^ Override the required number of tx witnesses - , txins :: ![(TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn))] + , txins :: ![(TxIn, Maybe CliSpendScriptRequirements)] -- ^ Transaction inputs with optional spending scripts , readOnlyReferenceInputs :: ![TxIn] -- ^ Read only reference inputs @@ -118,7 +120,7 @@ data TransactionBuildCmdArgs era = TransactionBuildCmdArgs -- ^ Transaction validity lower bound , mValidityUpperBound :: !(TxValidityUpperBound era) -- ^ Transaction validity upper bound - , certificates :: ![(CertificateFile, Maybe (ScriptWitnessFiles WitCtxStake))] + , certificates :: ![(CertificateFile, Maybe CliCertificateScriptRequirements)] -- ^ Certificates with potential script witness , withdrawals :: ![(StakeAddress, Coin, Maybe (ScriptWitnessFiles WitCtxStake))] -- ^ Withdrawals with potential script witness @@ -144,7 +146,7 @@ data TransactionBuildEstimateCmdArgs era = TransactionBuildEstimateCmdArgs , mByronWitnesses :: !(Maybe Int) , protocolParamsFile :: !ProtocolParamsFile , totalUTxOValue :: !Value - , txins :: ![(TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn))] + , txins :: ![(TxIn, Maybe CliSpendScriptRequirements)] -- ^ Transaction inputs with optional spending scripts , readOnlyReferenceInputs :: ![TxIn] -- ^ Read only reference inputs @@ -164,7 +166,7 @@ data TransactionBuildEstimateCmdArgs era = TransactionBuildEstimateCmdArgs -- ^ Transaction validity lower bound , mValidityUpperBound :: !(TxValidityUpperBound era) -- ^ Transaction validity upper bound - , certificates :: ![(CertificateFile, Maybe (ScriptWitnessFiles WitCtxStake))] + , certificates :: ![(CertificateFile, Maybe CliCertificateScriptRequirements)] -- ^ Certificates with potential script witness , withdrawals :: ![(StakeAddress, Coin, Maybe (ScriptWitnessFiles WitCtxStake))] -- ^ Withdrawals with potential script witness diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs b/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs index 4d113ffa75..0c34d305de 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Options/Common.hs @@ -18,7 +18,11 @@ import qualified Cardano.Api.Network as Consensus import Cardano.Api.Shelley import Cardano.CLI.Environment (EnvCli (..), envCliAnyEon) +import Cardano.CLI.EraBased.Script.Certificate.Types (CliCertificateScriptRequirements) +import qualified Cardano.CLI.EraBased.Script.Certificate.Types as Certifying import Cardano.CLI.EraBased.Script.Mint.Types +import Cardano.CLI.EraBased.Script.Spend.Types (CliSpendScriptRequirements) +import qualified Cardano.CLI.EraBased.Script.Spend.Types as PlutusSpend import Cardano.CLI.Parser import Cardano.CLI.Read import Cardano.CLI.Types.Common @@ -1029,18 +1033,42 @@ pPlutusMintScriptWitnessData _sbe _witctx autoBalanceExecUnits = ) ) +pSimpleScriptOrPlutusSpendingScriptWitness + :: ShelleyBasedEra era + -> BalanceTxExecUnits + -> String + -- ^ Script flag prefix + -> Maybe String + -- ^ Potential deprecated script flag prefix + -> String + -- ^ Help text + -> Parser CliSpendScriptRequirements +pSimpleScriptOrPlutusSpendingScriptWitness sbe autoBalanceExecUnits scriptFlagPrefix scriptFlagPrefixDeprecated help = + PlutusSpend.createSimpleOrPlutusScriptFromCliArgs + <$> pScriptFor + (scriptFlagPrefix ++ "-script-file") + ((++ "-script-file") <$> scriptFlagPrefixDeprecated) + ("The file containing the script to witness " ++ help) + <*> optional + ( (,,) + <$> pScriptDatumOrFileSpendingCip69 sbe scriptFlagPrefix + <*> pScriptRedeemerOrFile scriptFlagPrefix + <*> ( case autoBalanceExecUnits of + AutoBalance -> pure (ExecutionUnits 0 0) + ManualBalance -> pExecutionUnits scriptFlagPrefix + ) + ) + pScriptWitnessFiles - :: forall witctx era - . ShelleyBasedEra era - -> WitCtx witctx + :: forall witctx + . WitCtx witctx -> BalanceTxExecUnits - -- ^ Use the @execution-units@ flag. -> String -- ^ Script flag prefix -> Maybe String -> String -> Parser (ScriptWitnessFiles witctx) -pScriptWitnessFiles sbe witctx autoBalanceExecUnits scriptFlagPrefix scriptFlagPrefixDeprecated help = +pScriptWitnessFiles witctx autoBalanceExecUnits scriptFlagPrefix scriptFlagPrefixDeprecated help = toScriptWitnessFiles <$> pScriptFor (scriptFlagPrefix ++ "-script-file") @@ -1048,7 +1076,7 @@ pScriptWitnessFiles sbe witctx autoBalanceExecUnits scriptFlagPrefix scriptFlagP ("The file containing the script to witness " ++ help) <*> optional ( (,,) - <$> cip69Modification sbe + <$> pure (excludeTxInScriptWitnesses witctx) <*> pScriptRedeemerOrFile scriptFlagPrefix <*> ( case autoBalanceExecUnits of AutoBalance -> pure (ExecutionUnits 0 0) @@ -1056,11 +1084,20 @@ pScriptWitnessFiles sbe witctx autoBalanceExecUnits scriptFlagPrefix scriptFlagP ) ) where - cip69Modification :: ShelleyBasedEra era -> Parser (ScriptDatumOrFile witctx) - cip69Modification = - caseShelleyToBabbageOrConwayEraOnwards - (const $ pScriptDatumOrFile scriptFlagPrefix witctx) - (const $ pScriptDatumOrFileCip69 scriptFlagPrefix witctx) + excludeTxInScriptWitnesses :: WitCtx witctx -> ScriptDatumOrFile witctx + excludeTxInScriptWitnesses WitCtxStake = NoScriptDatumOrFileForStake + excludeTxInScriptWitnesses WitCtxMint = + error $ + mconcat + [ "pScriptWitnessFiles.excludeTxInScriptWitnesses: Should be impossible as " + , "mint script witnesses are handled by the pMintMultiAsset parser." + ] + excludeTxInScriptWitnesses WitCtxTxIn = + error $ + mconcat + [ "pScriptWitnessFiles.excludeTxInScriptWitnesses: Should be impossible as " + , "tx in script witnesses are handled by the pSimpleScriptOrPlutusSpendingScriptWitness parser." + ] toScriptWitnessFiles :: ScriptFile @@ -1138,6 +1175,42 @@ pScriptDatumOrFile scriptFlagPrefix witctx = , Opt.help "Inline datum present at transaction input." ] +pScriptDatumOrFileSpendingCip69 + :: ShelleyBasedEra era -> String -> Parser PlutusSpend.ScriptDatumOrFileSpending +pScriptDatumOrFileSpendingCip69 sbe scriptFlagPrefix = + caseShelleyToBabbageOrConwayEraOnwards + (const datumMandatory) + (const datumOptional) + sbe + where + datumMandatory = + asum + [ PlutusSpend.PotentialDatum . Just + <$> datumParser + , pInlineDatumPresent + ] + + datumOptional = + asum + [ PlutusSpend.PotentialDatum + <$> optional datumParser + , pInlineDatumPresent + ] + + datumParser = + pScriptDataOrFile + (scriptFlagPrefix ++ "-datum") + "The script datum." + "The script datum file." + + pInlineDatumPresent :: Parser PlutusSpend.ScriptDatumOrFileSpending + pInlineDatumPresent = + flag' PlutusSpend.InlineDatum $ + mconcat + [ long (scriptFlagPrefix ++ "-inline-datum-present") + , Opt.help "Inline datum present at transaction input." + ] + pScriptDataOrFile :: String -- ^ data flag prefix @@ -1208,14 +1281,13 @@ pVoteFiles pVoteFiles sbe bExUnits = caseShelleyToBabbageOrConwayEraOnwards (const $ pure []) - (const . many $ pVoteFile sbe bExUnits) + (const . many $ pVoteFile bExUnits) sbe pVoteFile - :: ShelleyBasedEra era - -> BalanceTxExecUnits + :: BalanceTxExecUnits -> Parser (VoteFile In, Maybe (ScriptWitnessFiles WitCtxStake)) -pVoteFile sbe balExUnits = +pVoteFile balExUnits = (,) <$> pFileInDirection "vote-file" "Filepath of the vote." <*> optional (pVoteScriptOrReferenceScriptWitness balExUnits) @@ -1224,7 +1296,6 @@ pVoteFile sbe balExUnits = :: BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxStake) pVoteScriptOrReferenceScriptWitness bExUnits = pScriptWitnessFiles - sbe WitCtxStake bExUnits "vote" @@ -1239,14 +1310,13 @@ pProposalFiles pProposalFiles sbe balExUnits = caseShelleyToBabbageOrConwayEraOnwards (const $ pure []) - (const $ many (pProposalFile sbe balExUnits)) + (const $ many (pProposalFile balExUnits)) sbe pProposalFile - :: ShelleyBasedEra era - -> BalanceTxExecUnits + :: BalanceTxExecUnits -> Parser (ProposalFile In, Maybe (ScriptWitnessFiles WitCtxStake)) -pProposalFile sbe balExUnits = +pProposalFile balExUnits = (,) <$> pFileInDirection "proposal-file" "Filepath of the proposal." <*> optional (pProposingScriptOrReferenceScriptWitness balExUnits) @@ -1255,7 +1325,6 @@ pProposalFile sbe balExUnits = :: BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxStake) pProposingScriptOrReferenceScriptWitness bExUnits = pScriptWitnessFiles - sbe WitCtxStake bExUnits "proposal" @@ -1408,10 +1477,9 @@ pTxBuildOutputOptions = "Where to write the script cost information." pCertificateFile - :: ShelleyBasedEra era - -> BalanceTxExecUnits - -> Parser (CertificateFile, Maybe (ScriptWitnessFiles WitCtxStake)) -pCertificateFile sbe balanceExecUnits = + :: BalanceTxExecUnits + -> Parser (CertificateFile, Maybe CliCertificateScriptRequirements) +pCertificateFile balanceExecUnits = (,) <$> ( fmap CertificateFile $ asum @@ -1422,16 +1490,14 @@ pCertificateFile sbe balanceExecUnits = <*> optional (pCertifyingScriptOrReferenceScriptWit balanceExecUnits) where pCertifyingScriptOrReferenceScriptWit - :: BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxStake) + :: BalanceTxExecUnits -> Parser CliCertificateScriptRequirements pCertifyingScriptOrReferenceScriptWit bExecUnits = - pScriptWitnessFiles - sbe - WitCtxStake + pCertificatePlutusScriptWitness balanceExecUnits "certificate" Nothing "the use of the certificate." - <|> pPlutusStakeReferenceScriptWitnessFiles "certificate-" bExecUnits + <|> pCertificateReferencePlutusScriptWitness "certificate-" bExecUnits helpText = mconcat @@ -1440,6 +1506,35 @@ pCertificateFile sbe balanceExecUnits = , "stake key certificates etc). Optionally specify a script witness." ] +pCertificatePlutusScriptWitness + :: BalanceTxExecUnits -> String -> Maybe String -> String -> Parser CliCertificateScriptRequirements +pCertificatePlutusScriptWitness bExecUnits scriptFlagPrefix scriptFlagPrefixDeprecated help = + Certifying.createSimpleOrPlutusScriptFromCliArgs + <$> pScriptFor + (scriptFlagPrefix ++ "-script-file") + ((++ "-script-file") <$> scriptFlagPrefixDeprecated) + ("The file containing the script to witness " ++ help) + <*> optional + ( (,) + <$> pScriptRedeemerOrFile scriptFlagPrefix + <*> ( case bExecUnits of + AutoBalance -> pure (ExecutionUnits 0 0) + ManualBalance -> pExecutionUnits scriptFlagPrefix + ) + ) + +pCertificateReferencePlutusScriptWitness + :: String -> BalanceTxExecUnits -> Parser CliCertificateScriptRequirements +pCertificateReferencePlutusScriptWitness prefix autoBalanceExecUnits = + Certifying.createPlutusReferenceScriptFromCliArgs + <$> pReferenceTxIn prefix "plutus" + <*> pPlutusScriptLanguage prefix + <*> pScriptRedeemerOrFile (prefix ++ "reference-tx-in") + <*> ( case autoBalanceExecUnits of + AutoBalance -> pure (ExecutionUnits 0 0) + ManualBalance -> pExecutionUnits $ prefix ++ "reference-tx-in" + ) + pPoolMetadataFile :: Parser (StakePoolMetadataFile In) pPoolMetadataFile = File <$> parseFilePath "pool-metadata-file" "Filepath of the pool metadata." @@ -1484,14 +1579,13 @@ pMetadataFile = ] pWithdrawal - :: ShelleyBasedEra era - -> BalanceTxExecUnits + :: BalanceTxExecUnits -> Parser ( StakeAddress , Lovelace , Maybe (ScriptWitnessFiles WitCtxStake) ) -pWithdrawal sbe balance = +pWithdrawal balance = (\(stakeAddr, lovelace) maybeScriptFp -> (stakeAddr, lovelace, maybeScriptFp)) <$> Opt.option (readerFromParsecParser parseWithdrawal) @@ -1504,7 +1598,6 @@ pWithdrawal sbe balance = pWithdrawalScriptOrReferenceScriptWit :: Parser (ScriptWitnessFiles WitCtxStake) pWithdrawalScriptOrReferenceScriptWit = pScriptWitnessFiles - sbe WitCtxStake balance "withdrawal" @@ -1527,7 +1620,6 @@ pWithdrawal sbe balance = pPlutusStakeReferenceScriptWitnessFilesVotingProposing :: String -> BalanceTxExecUnits - -- ^ Use the @execution-units@ flag. -> Parser (ScriptWitnessFiles WitCtxStake) pPlutusStakeReferenceScriptWitnessFilesVotingProposing prefix autoBalanceExecUnits = PlutusReferenceScriptWitnessFiles @@ -1543,7 +1635,6 @@ pPlutusStakeReferenceScriptWitnessFilesVotingProposing prefix autoBalanceExecUni pPlutusStakeReferenceScriptWitnessFiles :: String -> BalanceTxExecUnits - -- ^ Use the @execution-units@ flag. -> Parser (ScriptWitnessFiles WitCtxStake) pPlutusStakeReferenceScriptWitnessFiles prefix autoBalanceExecUnits = PlutusReferenceScriptWitnessFiles @@ -1935,7 +2026,7 @@ pTxSubmitFile = parseFilePath "tx-file" "Filepath of the transaction you intend pTxIn :: ShelleyBasedEra era -> BalanceTxExecUnits - -> Parser (TxIn, Maybe (ScriptWitnessFiles WitCtxTxIn)) + -> Parser (TxIn, Maybe PlutusSpend.CliSpendScriptRequirements) pTxIn sbe balance = (,) <$> Opt.option @@ -1944,57 +2035,35 @@ pTxIn sbe balance = <> Opt.metavar "TX-IN" <> Opt.help "TxId#TxIx" ) - <*> optional - ( pPlutusReferenceScriptWitness sbe balance - <|> pSimpleReferenceSpendingScriptWitess - <|> pEmbeddedPlutusScriptWitness - ) + <*> ( optional + ( pPlutusReferenceSpendScriptWitness balance + <|> pSimpleReferenceSpendingScriptWitess + <|> pOnDiskSimpleOrPlutusScriptWitness + ) + ) where - pSimpleReferenceSpendingScriptWitess :: Parser (ScriptWitnessFiles WitCtxTxIn) + pSimpleReferenceSpendingScriptWitess :: Parser CliSpendScriptRequirements pSimpleReferenceSpendingScriptWitess = - createSimpleReferenceScriptWitnessFiles + PlutusSpend.createSimpleReferenceScriptFromCliArgs <$> pReferenceTxIn "simple-script-" "simple" - where - createSimpleReferenceScriptWitnessFiles - :: TxIn - -> ScriptWitnessFiles WitCtxTxIn - createSimpleReferenceScriptWitnessFiles refTxIn = - let simpleLang = AnyScriptLanguage SimpleScriptLanguage - in SimpleReferenceScriptWitnessFiles refTxIn simpleLang - - pPlutusReferenceScriptWitness - :: ShelleyBasedEra era -> BalanceTxExecUnits -> Parser (ScriptWitnessFiles WitCtxTxIn) - pPlutusReferenceScriptWitness sbe' autoBalanceExecUnits = - caseShelleyToBabbageOrConwayEraOnwards - ( const $ - PlutusReferenceScriptWitnessFiles - <$> pReferenceTxIn "spending-" "plutus" - <*> pPlutusScriptLanguage "spending-" - <*> pScriptDatumOrFile "spending-reference-tx-in" WitCtxTxIn - <*> pScriptRedeemerOrFile "spending-reference-tx-in" - <*> ( case autoBalanceExecUnits of - AutoBalance -> pure (ExecutionUnits 0 0) - ManualBalance -> pExecutionUnits "spending-reference-tx-in" - ) - ) - ( const $ - PlutusReferenceScriptWitnessFiles - <$> pReferenceTxIn "spending-" "plutus" - <*> pPlutusScriptLanguage "spending-" - <*> pScriptDatumOrFileCip69 "spending-reference-tx-in" WitCtxTxIn - <*> pScriptRedeemerOrFile "spending-reference-tx-in" - <*> ( case autoBalanceExecUnits of - AutoBalance -> pure (ExecutionUnits 0 0) - ManualBalance -> pExecutionUnits "spending-reference-tx-in" - ) - ) - sbe' - pEmbeddedPlutusScriptWitness :: Parser (ScriptWitnessFiles WitCtxTxIn) - pEmbeddedPlutusScriptWitness = - pScriptWitnessFiles + pPlutusReferenceSpendScriptWitness + :: BalanceTxExecUnits -> Parser CliSpendScriptRequirements + pPlutusReferenceSpendScriptWitness autoBalanceExecUnits = + PlutusSpend.createPlutusReferenceScriptFromCliArgs + <$> pReferenceTxIn "spending-" "plutus" + <*> pPlutusScriptLanguage "spending-" + <*> pScriptDatumOrFileSpendingCip69 sbe "spending-reference-tx-in" + <*> pScriptRedeemerOrFile "spending-reference-tx-in" + <*> ( case autoBalanceExecUnits of + AutoBalance -> pure (ExecutionUnits 0 0) + ManualBalance -> pExecutionUnits "spending-reference-tx-in" + ) + + pOnDiskSimpleOrPlutusScriptWitness :: Parser CliSpendScriptRequirements + pOnDiskSimpleOrPlutusScriptWitness = + pSimpleScriptOrPlutusSpendingScriptWitness sbe - WitCtxTxIn balance "tx-in" (Just "txin") diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Options/Transaction.hs b/cardano-cli/src/Cardano/CLI/EraBased/Options/Transaction.hs index 9dc963024b..d8432e4ae7 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Options/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Options/Transaction.hs @@ -185,8 +185,8 @@ pTransactionBuildCmd sbe envCli = do <*> optional (pMintMultiAsset sbe AutoBalance) <*> optional pInvalidBefore <*> pInvalidHereafter sbe - <*> many (pCertificateFile sbe AutoBalance) - <*> many (pWithdrawal sbe AutoBalance) + <*> many (pCertificateFile AutoBalance) + <*> many (pWithdrawal AutoBalance) <*> pTxMetadataJsonSchema <*> many ( pScriptFor @@ -245,8 +245,8 @@ pTransactionBuildEstimateCmd eon' _envCli = do <*> optional (pMintMultiAsset sbe ManualBalance) <*> optional pInvalidBefore <*> pInvalidHereafter sbe - <*> many (pCertificateFile sbe ManualBalance) - <*> many (pWithdrawal sbe ManualBalance) + <*> many (pCertificateFile ManualBalance) + <*> many (pWithdrawal ManualBalance) <*> optional pTotalCollateral <*> optional pReferenceScriptSize <*> pTxMetadataJsonSchema @@ -289,8 +289,8 @@ pTransactionBuildRaw era' = <*> optional pInvalidBefore <*> pInvalidHereafter era' <*> pTxFee - <*> many (pCertificateFile era' ManualBalance) - <*> many (pWithdrawal era' ManualBalance) + <*> many (pCertificateFile ManualBalance) + <*> many (pWithdrawal ManualBalance) <*> pTxMetadataJsonSchema <*> many (pScriptFor "auxiliary-script-file" Nothing "Filepath of auxiliary script(s)") <*> many pMetadataFile diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Run/Query.hs b/cardano-cli/src/Cardano/CLI/EraBased/Run/Query.hs index ea0940b854..b974969d91 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Run/Query.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Run/Query.hs @@ -933,10 +933,15 @@ runQueryStakeAddressInfoCmd writeStakeAddressInfo sbe said mOutFile --- | Container for data returned by 'callQueryStakeAddressInfoCmd' +-- | Container for data returned by 'callQueryStakeAddressInfoCmd' where: +-- rewards: is the map of stake addresses to poolid and rewards balance +-- deposits: is the current the stake address registration deposit +-- gaDeposits: is a map of governance actions and their deposits associated to the reward account +-- delegatees: is a map of stake addresses and their delegation preference data StakeAddressInfoData = StakeAddressInfoData { rewards :: DelegationsAndRewards , deposits :: Map StakeAddress Lovelace + , gaDeposits :: Map (L.GovActionId L.StandardCrypto) Lovelace , delegatees :: Map StakeAddress (L.DRep L.StandardCrypto) } @@ -974,13 +979,35 @@ callQueryStakeAddressInfoCmd stakeDelegDeposits <- easyRunQuery (queryStakeDelegDeposits beo stakeAddr) - stakeVoteDelegatees <- monoidForEraInEonA era $ \ceo -> - easyRunQuery (queryStakeVoteDelegatees ceo stakeAddr) + (stakeVoteDelegatees, gaDeposits) <- + caseShelleyToBabbageOrConwayEraOnwards + (const $ pure (Map.empty, Map.empty)) + ( \ceo -> do + stakeVoteDelegatees <- easyRunQuery (queryStakeVoteDelegatees ceo stakeAddr) + + govActionStates :: (Seq.Seq (L.GovActionState (ShelleyLedgerEra era))) <- + easyRunQuery $ queryProposals ceo Set.empty + + let gaDeposits = + conwayEraOnwardsConstraints ceo $ + Map.fromList + [ (L.gasId gas, L.pProcDeposit proc) + | gas <- toList govActionStates + , let proc = L.gasProposalProcedure gas + , let rewardAccount = L.pProcReturnAddr proc + stakeCredential :: Api.StakeCredential = fromShelleyStakeCredential $ L.raCredential rewardAccount + , stakeCredential == fromShelleyStakeCredential addr + ] + + return (stakeVoteDelegatees, gaDeposits) + ) + (convert beo) pure $ StakeAddressInfoData (DelegationsAndRewards (stakeRewardAccountBalances, stakePools)) (Map.mapKeys (makeStakeAddress networkId) stakeDelegDeposits) + gaDeposits (Map.mapKeys (makeStakeAddress networkId) stakeVoteDelegatees) & onLeft (left . QueryCmdAcquireFailure) & onLeft left @@ -997,6 +1024,7 @@ writeStakeAddressInfo ( StakeAddressInfoData { rewards = DelegationsAndRewards (stakeAccountBalances, stakePools) , deposits = stakeDelegDeposits + , gaDeposits = gaDeposits , delegatees = voteDelegatees } ) @@ -1028,6 +1056,7 @@ writeStakeAddressInfo , "voteDelegation" .= fmap friendlyDRep mDRep , "rewardAccountBalance" .= mBalance , "delegationDeposit" .= mDeposit + , "govActionDeposits" .= gaDeposits ] ) merged diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs b/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs index 56f4247f8b..44dd0fbff5 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs @@ -48,8 +48,12 @@ import Cardano.CLI.EraBased.Commands.Transaction import qualified Cardano.CLI.EraBased.Commands.Transaction as Cmd import Cardano.CLI.EraBased.Run.Genesis.Common (readProtocolParameters) import Cardano.CLI.EraBased.Run.Query +import Cardano.CLI.EraBased.Script.Certificate.Read +import Cardano.CLI.EraBased.Script.Certificate.Types (CertificateScriptWitness (..)) import Cardano.CLI.EraBased.Script.Mint.Read import Cardano.CLI.EraBased.Script.Mint.Types +import Cardano.CLI.EraBased.Script.Spend.Read +import Cardano.CLI.EraBased.Script.Spend.Types (SpendScriptWitness (..)) import Cardano.CLI.EraBased.Transaction.HashCheck (checkCertificateHashes, checkProposalHashes, checkVotingProcedureHashes) import Cardano.CLI.Orphans () @@ -154,15 +158,20 @@ runTransactionBuildCmd , localNodeSocketPath = nodeSocketPath } - inputsAndMaybeScriptWits <- firstExceptT TxCmdScriptWitnessError $ readScriptWitnessFiles eon txins + txinsAndMaybeScriptWits <- + firstExceptT TxCmdCliSpendingScriptWitnessError $ + readSpendScriptWitnesses eon txins + + let spendingScriptWitnesses = mapMaybe (fmap sswScriptWitness . snd) txinsAndMaybeScriptWits + certFilesAndMaybeScriptWits <- - firstExceptT TxCmdScriptWitnessError $ readScriptWitnessFiles eon certificates + firstExceptT TxCmdCliScriptWitnessError $ readCertificateScriptWitnesses eon certificates -- TODO: Conway Era - How can we make this more composable? certsAndMaybeScriptWits <- sequence [ fmap - (,mSwit) + (,cswScriptWitness <$> mSwit) ( firstExceptT TxCmdReadTextViewFileError . newExceptT $ shelleyBasedEraConstraints eon $ readFileTextEnvelope AsCertificate (File certFile) @@ -257,15 +266,15 @@ runTransactionBuildCmd let allReferenceInputs = getAllReferenceInputs - inputsAndMaybeScriptWits + spendingScriptWitnesses (map mswScriptWitness $ snd usedToGetReferenceInputs) - certsAndMaybeScriptWits + (mapMaybe snd certsAndMaybeScriptWits) withdrawalsAndMaybeScriptWits votingProceduresAndMaybeScriptWits proposals readOnlyReferenceInputs - let inputsThatRequireWitnessing = [input | (input, _) <- inputsAndMaybeScriptWits] + let inputsThatRequireWitnessing = [input | (input, _) <- txins] allTxInputs = inputsThatRequireWitnessing ++ allReferenceInputs ++ filteredTxinsc AnyCardanoEra nodeEra <- @@ -298,7 +307,7 @@ runTransactionBuildCmd nodeSocketPath networkId mScriptValidity - inputsAndMaybeScriptWits + txinsAndMaybeScriptWits readOnlyReferenceInputs filteredTxinsc mReturnCollateral @@ -401,12 +410,14 @@ runTransactionBuildEstimateCmd -- TODO change type ledgerPParams <- firstExceptT TxCmdProtocolParamsError $ readProtocolParameters sbe protocolParamsFile - inputsAndMaybeScriptWits <- - firstExceptT TxCmdScriptWitnessError $ - readScriptWitnessFiles sbe txins + + txInsAndMaybeScriptWits <- + firstExceptT TxCmdCliSpendingScriptWitnessError $ + readSpendScriptWitnesses sbe txins + certFilesAndMaybeScriptWits <- - firstExceptT TxCmdScriptWitnessError $ - readScriptWitnessFiles sbe certificates + firstExceptT TxCmdCliScriptWitnessError $ + readCertificateScriptWitnesses sbe certificates withdrawalsAndMaybeScriptWits <- firstExceptT TxCmdScriptWitnessError $ @@ -460,7 +471,7 @@ runTransactionBuildEstimateCmd -- TODO change type shelleyBasedEraConstraints sbe $ sequence [ fmap - (,mSwit) + (,cswScriptWitness <$> mSwit) ( firstExceptT TxCmdReadTextViewFileError . newExceptT $ readFileTextEnvelope AsCertificate (File certFile) ) @@ -473,7 +484,7 @@ runTransactionBuildEstimateCmd -- TODO change type sbe mScriptValidity (Just ledgerPParams) - inputsAndMaybeScriptWits + txInsAndMaybeScriptWits readOnlyRefIns filteredTxinsc mReturnCollateral @@ -642,12 +653,13 @@ runTransactionBuildRawCmd , currentTreasuryValueAndDonation , txBodyOutFile } = do - inputsAndMaybeScriptWits <- - firstExceptT TxCmdScriptWitnessError $ - readScriptWitnessFiles eon txIns + txInsAndMaybeScriptWits <- + firstExceptT TxCmdCliSpendingScriptWitnessError $ + readSpendScriptWitnesses eon txIns + certFilesAndMaybeScriptWits <- - firstExceptT TxCmdScriptWitnessError $ - readScriptWitnessFiles eon certificates + firstExceptT TxCmdCliScriptWitnessError $ + readCertificateScriptWitnesses eon certificates withdrawalsAndMaybeScriptWits <- firstExceptT TxCmdScriptWitnessError $ @@ -706,7 +718,7 @@ runTransactionBuildRawCmd shelleyBasedEraConstraints eon $ sequence [ fmap - (,mSwit) + (,cswScriptWitness <$> mSwit) ( firstExceptT TxCmdReadTextViewFileError . newExceptT $ readFileTextEnvelope AsCertificate (File certFile) ) @@ -717,7 +729,7 @@ runTransactionBuildRawCmd runTxBuildRaw eon mScriptValidity - inputsAndMaybeScriptWits + txInsAndMaybeScriptWits readOnlyRefIns filteredTxinsc mReturnCollateral @@ -747,7 +759,7 @@ runTxBuildRaw => ShelleyBasedEra era -> Maybe ScriptValidity -- ^ Mark script as expected to pass or fail validation - -> [(TxIn, Maybe (ScriptWitness WitCtxTxIn era))] + -> [(TxIn, Maybe (SpendScriptWitness era))] -- ^ TxIn with potential script witness -> [TxIn] -- ^ Read only reference inputs @@ -834,7 +846,7 @@ constructTxBodyContent . ShelleyBasedEra era -> Maybe ScriptValidity -> Maybe (L.PParams (ShelleyLedgerEra era)) - -> [(TxIn, Maybe (ScriptWitness WitCtxTxIn era))] + -> [(TxIn, Maybe (SpendScriptWitness era))] -- ^ TxIn with potential script witness -> [TxIn] -- ^ Read only reference inputs @@ -896,9 +908,9 @@ constructTxBodyContent do let allReferenceInputs = getAllReferenceInputs - inputsAndMaybeScriptWits + (map sswScriptWitness $ mapMaybe snd inputsAndMaybeScriptWits) (map mswScriptWitness $ snd valuesWithScriptWits) - certsAndMaybeScriptWits + (mapMaybe snd certsAndMaybeScriptWits) withdrawals votingProcedures proposals @@ -976,7 +988,7 @@ runTxBuild -> NetworkId -> Maybe ScriptValidity -- ^ Mark script as expected to pass or fail validation - -> [(TxIn, Maybe (ScriptWitness WitCtxTxIn era))] + -> [(TxIn, Maybe (SpendScriptWitness era))] -- ^ Read only reference inputs -> [TxIn] -- ^ TxIn with potential script witness @@ -1043,9 +1055,9 @@ runTxBuild let allReferenceInputs = getAllReferenceInputs - inputsAndMaybeScriptWits + (map sswScriptWitness $ mapMaybe snd inputsAndMaybeScriptWits) (map mswScriptWitness $ snd valuesWithScriptWits) - certsAndMaybeScriptWits + (mapMaybe snd certsAndMaybeScriptWits) withdrawals votingProcedures proposals @@ -1177,17 +1189,17 @@ txFeatureMismatchPure era feature = Left (TxCmdTxFeatureMismatch (anyCardanoEra era) feature) validateTxIns - :: [(TxIn, Maybe (ScriptWitness WitCtxTxIn era))] + :: [(TxIn, Maybe (SpendScriptWitness era))] -> [(TxIn, BuildTxWith BuildTx (Witness WitCtxTxIn era))] validateTxIns = map convertTxIn where convertTxIn - :: (TxIn, Maybe (ScriptWitness WitCtxTxIn era)) + :: (TxIn, Maybe (SpendScriptWitness era)) -> (TxIn, BuildTxWith BuildTx (Witness WitCtxTxIn era)) convertTxIn (txin, mScriptWitness) = case mScriptWitness of Just sWit -> - (txin, BuildTxWith $ ScriptWitness ScriptWitnessForSpending sWit) + (txin, BuildTxWith $ ScriptWitness ScriptWitnessForSpending $ sswScriptWitness sWit) Nothing -> (txin, BuildTxWith $ KeyWitness KeyWitnessForSpending) @@ -1210,9 +1222,9 @@ validateTxInsReference sbe allRefIns = do & maybe (txFeatureMismatchPure (toCardanoEra sbe) TxFeatureReferenceInputs) Right getAllReferenceInputs - :: [(TxIn, Maybe (ScriptWitness WitCtxTxIn era))] + :: [ScriptWitness WitCtxTxIn era] -> [ScriptWitness WitCtxMint era] - -> [(Certificate era, Maybe (ScriptWitness WitCtxStake era))] + -> [ScriptWitness WitCtxStake era] -> [(StakeAddress, Lovelace, Maybe (ScriptWitness WitCtxStake era))] -> [(VotingProcedures era, Maybe (ScriptWitness WitCtxStake era))] -> [(Proposal era, Maybe (ScriptWitness WitCtxStake era))] @@ -1220,16 +1232,16 @@ getAllReferenceInputs -- ^ Read only reference inputs -> [TxIn] getAllReferenceInputs - txins + spendingWitnesses mintWitnesses - certFiles + certScriptWitnesses withdrawals votingProceduresAndMaybeScriptWits propProceduresAnMaybeScriptWits readOnlyRefIns = do - let txinsWitByRefInputs = [getScriptWitnessReferenceInput sWit | (_, Just sWit) <- txins] + let txinsWitByRefInputs = map getScriptWitnessReferenceInput spendingWitnesses mintingRefInputs = map getScriptWitnessReferenceInput mintWitnesses - certsWitByRefInputs = [getScriptWitnessReferenceInput sWit | (_, Just sWit) <- certFiles] + certsWitByRefInputs = map getScriptWitnessReferenceInput certScriptWitnesses withdrawalsWitByRefInputs = [getScriptWitnessReferenceInput sWit | (_, _, Just sWit) <- withdrawals] votesWitByRefInputs = [getScriptWitnessReferenceInput sWit | (_, Just sWit) <- votingProceduresAndMaybeScriptWits] propsWitByRefInputs = [getScriptWitnessReferenceInput sWit | (_, Just sWit) <- propProceduresAnMaybeScriptWits] diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Script/Certificate/Read.hs b/cardano-cli/src/Cardano/CLI/EraBased/Script/Certificate/Read.hs new file mode 100644 index 0000000000..01c5d8860b --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/EraBased/Script/Certificate/Read.hs @@ -0,0 +1,110 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TupleSections #-} + +module Cardano.CLI.EraBased.Script.Certificate.Read + ( readCertificateScriptWitness + , readCertificateScriptWitnesses + ) +where + +import Cardano.Api +import Cardano.Api.Shelley + +import Cardano.CLI.EraBased.Script.Certificate.Types +import Cardano.CLI.EraBased.Script.Types +import Cardano.CLI.Read +import Cardano.CLI.Types.Common + +import Control.Monad + +readCertificateScriptWitnesses + :: MonadIOTransError (FileError CliScriptWitnessError) t m + => ShelleyBasedEra era + -> [(CertificateFile, Maybe CliCertificateScriptRequirements)] + -> t m [(CertificateFile, Maybe (CertificateScriptWitness era))] +readCertificateScriptWitnesses sbe = + mapM + ( \(certFile, mSWit) -> do + (certFile,) <$> forM mSWit (readCertificateScriptWitness sbe) + ) + +readCertificateScriptWitness + :: MonadIOTransError (FileError CliScriptWitnessError) t m + => ShelleyBasedEra era -> CliCertificateScriptRequirements -> t m (CertificateScriptWitness era) +readCertificateScriptWitness sbe certScriptReq = + case certScriptReq of + OnDiskSimpleScript scriptFp -> do + let sFp = unFile scriptFp + s <- + modifyError (fmap SimpleScriptWitnessDecodeError) $ + readFileSimpleScript sFp + case s of + SimpleScript ss -> do + return $ + CertificateScriptWitness $ + SimpleScriptWitness (sbeToSimpleScriptLanguageInEra sbe) $ + SScript ss + OnDiskPlutusScript (OnDiskPlutusScriptCliArgs scriptFp redeemerFile execUnits) -> do + let plutusScriptFp = unFile scriptFp + plutusScript <- + modifyError (fmap PlutusScriptWitnessDecodeError) $ + readFilePlutusScript plutusScriptFp + redeemer <- + modifyError (FileError plutusScriptFp . PlutusScriptWitnessRedeemerError) $ + readScriptDataOrFile redeemerFile + case plutusScript of + AnyPlutusScript lang script -> do + let pScript = PScript script + sLangSupported <- + modifyError (FileError plutusScriptFp) + $ hoistMaybe + ( PlutusScriptWitnessLanguageNotSupportedInEra + (AnyPlutusScriptVersion lang) + (shelleyBasedEraConstraints sbe $ AnyShelleyBasedEra sbe) + ) + $ scriptLanguageSupportedInEra sbe + $ PlutusScriptLanguage lang + return $ + CertificateScriptWitness $ + PlutusScriptWitness + sLangSupported + lang + pScript + NoScriptDatumForStake + redeemer + execUnits + OnDiskPlutusRefScript (PlutusRefScriptCliArgs refTxIn anyPlutusScriptVersion redeemerFile execUnits) -> do + case anyPlutusScriptVersion of + AnyPlutusScriptVersion lang -> do + let pScript = PReferenceScript refTxIn + redeemer <- + -- TODO: Implement a new error type to capture this. FileError is not representative of cases + -- where we do not have access to the script. + modifyError + ( FileError "Reference script filepath not available" + . PlutusScriptWitnessRedeemerError + ) + $ readScriptDataOrFile redeemerFile + sLangSupported <- + -- TODO: Implement a new error type to capture this. FileError is not representative of cases + -- where we do not have access to the script. + modifyError (FileError "Reference script filepath not available") + $ hoistMaybe + ( PlutusScriptWitnessLanguageNotSupportedInEra + (AnyPlutusScriptVersion lang) + (shelleyBasedEraConstraints sbe $ AnyShelleyBasedEra sbe) + ) + $ scriptLanguageSupportedInEra sbe + $ PlutusScriptLanguage lang + + return $ + CertificateScriptWitness $ + PlutusScriptWitness + sLangSupported + lang + pScript + NoScriptDatumForStake + redeemer + execUnits diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Script/Certificate/Types.hs b/cardano-cli/src/Cardano/CLI/EraBased/Script/Certificate/Types.hs new file mode 100644 index 0000000000..44a6fdb782 --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/EraBased/Script/Certificate/Types.hs @@ -0,0 +1,63 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GADTs #-} + +module Cardano.CLI.EraBased.Script.Certificate.Types + ( CertificateScriptWitness (..) + , CliCertificateScriptRequirements (..) + , PlutusScriptCliArgs (..) + , PlutusRefScriptCliArgs (..) + , createSimpleOrPlutusScriptFromCliArgs + , createPlutusReferenceScriptFromCliArgs + ) +where + +import Cardano.Api + +import Cardano.CLI.Types.Common (ScriptDataOrFile) + +newtype CertificateScriptWitness era + = CertificateScriptWitness {cswScriptWitness :: ScriptWitness WitCtxStake era} + deriving Show + +data CliCertificateScriptRequirements + = OnDiskPlutusScript PlutusScriptCliArgs + | OnDiskSimpleScript (File ScriptInAnyLang In) + | OnDiskPlutusRefScript PlutusRefScriptCliArgs + deriving Show + +data PlutusScriptCliArgs + = OnDiskPlutusScriptCliArgs + (File ScriptInAnyLang In) + ScriptDataOrFile + -- ^ Redeemer + ExecutionUnits + deriving Show + +createSimpleOrPlutusScriptFromCliArgs + :: File ScriptInAnyLang In + -> Maybe (ScriptDataOrFile, ExecutionUnits) + -> CliCertificateScriptRequirements +createSimpleOrPlutusScriptFromCliArgs scriptFp (Just (redeemer, execUnits)) = + OnDiskPlutusScript $ OnDiskPlutusScriptCliArgs scriptFp redeemer execUnits +createSimpleOrPlutusScriptFromCliArgs scriptFp Nothing = + OnDiskSimpleScript scriptFp + +data PlutusRefScriptCliArgs + = PlutusRefScriptCliArgs + TxIn + -- ^ TxIn with reference script + AnyPlutusScriptVersion + ScriptDataOrFile + -- ^ Redeemer + ExecutionUnits + deriving Show + +createPlutusReferenceScriptFromCliArgs + :: TxIn + -> AnyPlutusScriptVersion + -> ScriptDataOrFile + -> ExecutionUnits + -> CliCertificateScriptRequirements +createPlutusReferenceScriptFromCliArgs txIn version redeemer execUnits = + OnDiskPlutusRefScript $ PlutusRefScriptCliArgs txIn version redeemer execUnits diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Read.hs b/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Read.hs index 5b40eb1690..67044d6f77 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Read.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Read.hs @@ -11,6 +11,7 @@ import Cardano.Api import Cardano.Api.Shelley import Cardano.CLI.EraBased.Script.Mint.Types +import Cardano.CLI.EraBased.Script.Types import Cardano.CLI.Read readMintScriptWitness @@ -27,7 +28,7 @@ readMintScriptWitness sbe (OnDiskSimpleOrPlutusScript simpleOrPlutus) = let polId = PolicyId $ hashScript s return $ MintScriptWitnessWithPolicyId polId $ - SimpleScriptWitness (sbeToSimpleScriptLangInEra sbe) $ + SimpleScriptWitness (sbeToSimpleScriptLanguageInEra sbe) $ SScript ss OnDiskPlutusScriptCliArgs plutusScriptFp redeemerFile execUnits -> do let sFp = unFile plutusScriptFp @@ -65,7 +66,7 @@ readMintScriptWitness sbe (OnDiskSimpleRefScript (SimpleRefScriptCliArgs refTxIn return $ MintScriptWitnessWithPolicyId polId $ SimpleScriptWitness - (sbeToSimpleScriptLangInEra sbe) + (sbeToSimpleScriptLanguageInEra sbe) (SReferenceScript refTxIn) readMintScriptWitness sbe @@ -100,13 +101,3 @@ readMintScriptWitness NoScriptDatumForMint redeemer execUnits - --- TODO: Remove me when exposed from cardano-api -sbeToSimpleScriptLangInEra - :: ShelleyBasedEra era -> ScriptLanguageInEra SimpleScript' era -sbeToSimpleScriptLangInEra ShelleyBasedEraShelley = SimpleScriptInShelley -sbeToSimpleScriptLangInEra ShelleyBasedEraAllegra = SimpleScriptInAllegra -sbeToSimpleScriptLangInEra ShelleyBasedEraMary = SimpleScriptInMary -sbeToSimpleScriptLangInEra ShelleyBasedEraAlonzo = SimpleScriptInAlonzo -sbeToSimpleScriptLangInEra ShelleyBasedEraBabbage = SimpleScriptInBabbage -sbeToSimpleScriptLangInEra ShelleyBasedEraConway = SimpleScriptInConway diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Types.hs b/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Types.hs index 192e4ed0f3..a081d0cab9 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Types.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Script/Mint/Types.hs @@ -4,8 +4,7 @@ {-# LANGUAGE LambdaCase #-} module Cardano.CLI.EraBased.Script.Mint.Types - ( CliScriptWitnessError (..) - , CliMintScriptRequirements (..) + ( CliMintScriptRequirements (..) , SimpleOrPlutusScriptCliArgs (..) , createSimpleOrPlutusScriptFromCliArgs , PlutusRefScriptCliArgs (..) @@ -19,9 +18,6 @@ where import Cardano.Api import Cardano.CLI.Types.Common (ScriptDataOrFile) -import Cardano.CLI.Types.Errors.PlutusScriptDecodeError -import Cardano.CLI.Types.Errors.ScriptDataError -import Cardano.CLI.Types.Errors.ScriptDecodeError -- We always need the policy id when constructing a transaction that mints. -- In the case of reference scripts, the user currently must provide the policy id (script hash) @@ -45,6 +41,7 @@ data SimpleOrPlutusScriptCliArgs | OnDiskPlutusScriptCliArgs (File ScriptInAnyLang In) ScriptDataOrFile + -- ^ Redeemer ExecutionUnits deriving Show @@ -88,19 +85,3 @@ createPlutusReferenceScriptFromCliArgs -> CliMintScriptRequirements createPlutusReferenceScriptFromCliArgs txin scriptVersion scriptData execUnits polid = OnDiskPlutusRefScript $ PlutusRefScriptCliArgs txin scriptVersion scriptData execUnits polid - -data CliScriptWitnessError - = SimpleScriptWitnessDecodeError ScriptDecodeError - | PlutusScriptWitnessDecodeError PlutusScriptDecodeError - | PlutusScriptWitnessLanguageNotSupportedInEra - AnyPlutusScriptVersion - AnyShelleyBasedEra - | PlutusScriptWitnessRedeemerError ScriptDataError - -instance Error CliScriptWitnessError where - prettyError = \case - SimpleScriptWitnessDecodeError err -> prettyError err - PlutusScriptWitnessDecodeError err -> prettyError err - PlutusScriptWitnessLanguageNotSupportedInEra version era -> - "Plutus script version " <> pshow version <> " is not supported in era " <> pshow era - PlutusScriptWitnessRedeemerError err -> renderScriptDataError err diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Script/Spend/Read.hs b/cardano-cli/src/Cardano/CLI/EraBased/Script/Spend/Read.hs new file mode 100644 index 0000000000..f3540d7132 --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/EraBased/Script/Spend/Read.hs @@ -0,0 +1,148 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE TupleSections #-} + +module Cardano.CLI.EraBased.Script.Spend.Read + ( CliSpendScriptWitnessError + , readSpendScriptWitness + , readSpendScriptWitnesses + ) +where + +import Cardano.Api +import Cardano.Api.Shelley + +import Cardano.CLI.EraBased.Script.Spend.Types +import Cardano.CLI.EraBased.Script.Types +import Cardano.CLI.Read + +import Control.Monad + +data CliSpendScriptWitnessError + = CliScriptWitnessError CliScriptWitnessError + | CliSpendScriptWitnessDatumError ScriptDataError + +instance Error CliSpendScriptWitnessError where + prettyError = \case + CliScriptWitnessError e -> prettyError e + CliSpendScriptWitnessDatumError e -> renderScriptDataError e + +readSpendScriptWitnesses + :: MonadIOTransError (FileError CliSpendScriptWitnessError) t m + => ShelleyBasedEra era + -> [(TxIn, Maybe CliSpendScriptRequirements)] + -> t m [(TxIn, Maybe (SpendScriptWitness era))] +readSpendScriptWitnesses eon = + mapM + ( \(txin, mSWit) -> do + (txin,) <$> forM mSWit (readSpendScriptWitness eon) + ) + +readSpendScriptWitness + :: MonadIOTransError (FileError CliSpendScriptWitnessError) t m + => ShelleyBasedEra era -> CliSpendScriptRequirements -> t m (SpendScriptWitness era) +readSpendScriptWitness sbe spendScriptReq = + case spendScriptReq of + OnDiskSimpleOrPlutusScript (OnDiskSimpleCliArgs simpleFp) -> do + let sFp = unFile simpleFp + s <- + modifyError (fmap (CliScriptWitnessError . SimpleScriptWitnessDecodeError)) $ + readFileSimpleScript sFp + case s of + SimpleScript ss -> do + return $ + SpendScriptWitness $ + SimpleScriptWitness (sbeToSimpleScriptLanguageInEra sbe) $ + SScript ss + OnDiskSimpleOrPlutusScript + (OnDiskPlutusScriptCliArgs plutusScriptFp mScriptDatum redeemerFile execUnits) -> do + let sFp = unFile plutusScriptFp + plutusScript <- + modifyError (fmap (CliScriptWitnessError . PlutusScriptWitnessDecodeError)) $ + readFilePlutusScript $ + unFile plutusScriptFp + redeemer <- + modifyError (FileError sFp . (CliScriptWitnessError . PlutusScriptWitnessRedeemerError)) $ + readScriptDataOrFile redeemerFile + case plutusScript of + AnyPlutusScript lang script -> do + let pScript = PScript script + sLangSupported <- + modifyError (FileError sFp) + $ hoistMaybe + ( CliScriptWitnessError $ + PlutusScriptWitnessLanguageNotSupportedInEra + (AnyPlutusScriptVersion lang) + (shelleyBasedEraConstraints sbe $ AnyShelleyBasedEra sbe) + ) + $ scriptLanguageSupportedInEra sbe + $ PlutusScriptLanguage lang + mDatum <- handlePotentialScriptDatum mScriptDatum + return $ + SpendScriptWitness $ + PlutusScriptWitness + sLangSupported + lang + pScript + mDatum + redeemer + execUnits + OnDiskSimpleRefScript (SimpleRefScriptArgs refTxIn) -> + return $ + SpendScriptWitness $ + SimpleScriptWitness + (sbeToSimpleScriptLanguageInEra sbe) + (SReferenceScript refTxIn) + OnDiskPlutusRefScript + (PlutusRefScriptCliArgs refTxIn anyPlutusScriptVersion mScriptDatum redeemerFile execUnits) -> + case anyPlutusScriptVersion of + AnyPlutusScriptVersion lang -> do + let pScript = PReferenceScript refTxIn + redeemer <- + -- TODO: Implement a new error type to capture this. FileError is not representative of cases + -- where we do not have access to the script. + modifyError + ( FileError "Reference script filepath not available" + . CliScriptWitnessError + . PlutusScriptWitnessRedeemerError + ) + $ readScriptDataOrFile redeemerFile + sLangSupported <- + -- TODO: Implement a new error type to capture this. FileError is not representative of cases + -- where we do not have access to the script. + modifyError (FileError "Reference script filepath not available") + $ hoistMaybe + ( CliScriptWitnessError $ + PlutusScriptWitnessLanguageNotSupportedInEra + (AnyPlutusScriptVersion lang) + (shelleyBasedEraConstraints sbe $ AnyShelleyBasedEra sbe) + ) + $ scriptLanguageSupportedInEra sbe + $ PlutusScriptLanguage lang + + mDatum <- handlePotentialScriptDatum mScriptDatum + return $ + SpendScriptWitness $ + PlutusScriptWitness + sLangSupported + lang + pScript + mDatum + redeemer + execUnits + +handlePotentialScriptDatum + :: MonadIOTransError (FileError CliSpendScriptWitnessError) t m + => ScriptDatumOrFileSpending + -> t m (ScriptDatum WitCtxTxIn) +handlePotentialScriptDatum InlineDatum = return InlineScriptDatum +handlePotentialScriptDatum (PotentialDatum mDatum) = + ScriptDatumForTxIn + <$> forM + mDatum + ( \datumFp -> + modifyError (FileError (show datumFp) . CliSpendScriptWitnessDatumError) $ + readScriptDataOrFile datumFp + ) diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Script/Spend/Types.hs b/cardano-cli/src/Cardano/CLI/EraBased/Script/Spend/Types.hs new file mode 100644 index 0000000000..3f715c5de9 --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/EraBased/Script/Spend/Types.hs @@ -0,0 +1,82 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GADTs #-} + +module Cardano.CLI.EraBased.Script.Spend.Types + ( CliSpendScriptRequirements (..) + , PlutusRefScriptCliArgs (..) + , SimpleOrPlutusScriptCliArgs (..) + , ScriptDatumOrFileSpending (..) + , SimpleRefScriptCliArgs (..) + , SpendScriptWitness (..) + , createSimpleOrPlutusScriptFromCliArgs + , createPlutusReferenceScriptFromCliArgs + , createSimpleReferenceScriptFromCliArgs + ) +where + +import Cardano.Api + +import Cardano.CLI.Types.Common (ScriptDataOrFile) + +newtype SpendScriptWitness era + = SpendScriptWitness {sswScriptWitness :: ScriptWitness WitCtxTxIn era} + deriving Show + +data CliSpendScriptRequirements + = OnDiskSimpleOrPlutusScript SimpleOrPlutusScriptCliArgs + | OnDiskSimpleRefScript SimpleRefScriptCliArgs + | OnDiskPlutusRefScript PlutusRefScriptCliArgs + deriving Show + +data SimpleOrPlutusScriptCliArgs + = OnDiskPlutusScriptCliArgs + (File ScriptInAnyLang In) + ScriptDatumOrFileSpending + -- ^ Optional Datum (CIP-69) + ScriptDataOrFile + -- ^ Redeemer + ExecutionUnits + | OnDiskSimpleCliArgs + (File ScriptInAnyLang In) + deriving Show + +createSimpleOrPlutusScriptFromCliArgs + :: File ScriptInAnyLang In + -> Maybe (ScriptDatumOrFileSpending, ScriptDataOrFile, ExecutionUnits) + -> CliSpendScriptRequirements +createSimpleOrPlutusScriptFromCliArgs scriptFp (Just (datumFile, redeemerFile, execUnits)) = + OnDiskSimpleOrPlutusScript $ OnDiskPlutusScriptCliArgs scriptFp datumFile redeemerFile execUnits +createSimpleOrPlutusScriptFromCliArgs scriptFp Nothing = OnDiskSimpleOrPlutusScript $ OnDiskSimpleCliArgs scriptFp + +newtype SimpleRefScriptCliArgs = SimpleRefScriptArgs TxIn deriving Show + +createSimpleReferenceScriptFromCliArgs :: TxIn -> CliSpendScriptRequirements +createSimpleReferenceScriptFromCliArgs = OnDiskSimpleRefScript . SimpleRefScriptArgs + +data PlutusRefScriptCliArgs + = PlutusRefScriptCliArgs + TxIn + -- ^ TxIn with reference script + AnyPlutusScriptVersion + ScriptDatumOrFileSpending + -- ^ Optional Datum (CIP-69) + ScriptDataOrFile + -- ^ Redeemer + ExecutionUnits + deriving Show + +createPlutusReferenceScriptFromCliArgs + :: TxIn + -> AnyPlutusScriptVersion + -> ScriptDatumOrFileSpending + -> ScriptDataOrFile + -> ExecutionUnits + -> CliSpendScriptRequirements +createPlutusReferenceScriptFromCliArgs txin v mDatum redeemer execUnits = + OnDiskPlutusRefScript $ PlutusRefScriptCliArgs txin v mDatum redeemer execUnits + +data ScriptDatumOrFileSpending + = PotentialDatum (Maybe ScriptDataOrFile) + | InlineDatum + deriving Show diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Script/Types.hs b/cardano-cli/src/Cardano/CLI/EraBased/Script/Types.hs new file mode 100644 index 0000000000..39f6f5e736 --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/EraBased/Script/Types.hs @@ -0,0 +1,29 @@ +{-# LANGUAGE LambdaCase #-} + +module Cardano.CLI.EraBased.Script.Types + ( -- * Errors + CliScriptWitnessError (..) + ) +where + +import Cardano.Api + +import Cardano.CLI.Types.Errors.PlutusScriptDecodeError +import Cardano.CLI.Types.Errors.ScriptDataError +import Cardano.CLI.Types.Errors.ScriptDecodeError + +data CliScriptWitnessError + = SimpleScriptWitnessDecodeError ScriptDecodeError + | PlutusScriptWitnessDecodeError PlutusScriptDecodeError + | PlutusScriptWitnessLanguageNotSupportedInEra + AnyPlutusScriptVersion + AnyShelleyBasedEra + | PlutusScriptWitnessRedeemerError ScriptDataError + +instance Error CliScriptWitnessError where + prettyError = \case + SimpleScriptWitnessDecodeError err -> prettyError err + PlutusScriptWitnessDecodeError err -> prettyError err + PlutusScriptWitnessLanguageNotSupportedInEra version era -> + "Plutus script version " <> pshow version <> " is not supported in era " <> pshow era + PlutusScriptWitnessRedeemerError err -> renderScriptDataError err diff --git a/cardano-cli/src/Cardano/CLI/Types/Common.hs b/cardano-cli/src/Cardano/CLI/Types/Common.hs index d23ee97f2b..13f70d91a8 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Common.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Common.hs @@ -431,8 +431,9 @@ data ScriptWitnessFiles witctx where -> ScriptRedeemerOrFile -> ExecutionUnits -> ScriptWitnessFiles witctx - -- NB: This no longer is used for minting scripts - -- Use MintScriptWitnessWithPolicyId instead + -- | This no longer is used for minting or spending + -- scripts. + -- Use MintScriptWitnessWithPolicyId or SpendScriptWitness instead PlutusReferenceScriptWitnessFiles :: TxIn -> AnyPlutusScriptVersion @@ -441,8 +442,9 @@ data ScriptWitnessFiles witctx where -> ExecutionUnits -- ^ For minting reference scripts -> ScriptWitnessFiles witctx - -- NB: This no longer is used for minting scripts - -- Use MintScriptWitnessWithPolicyId instead + -- | This no longer is used for minting or spending + -- scripts + -- Use MintScriptWitnessWithPolicyId or SpendScriptWitness instead SimpleReferenceScriptWitnessFiles :: TxIn -> AnyScriptLanguage diff --git a/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs b/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs index 4e57677428..47f77f0c16 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs @@ -19,7 +19,8 @@ import Cardano.Api.Consensus (EraMismatch (..)) import qualified Cardano.Api.Ledger as L import Cardano.Api.Shelley -import Cardano.CLI.EraBased.Script.Mint.Types +import Cardano.CLI.EraBased.Script.Spend.Read +import Cardano.CLI.EraBased.Script.Types import Cardano.CLI.Read import Cardano.CLI.Types.Common import Cardano.CLI.Types.Errors.BootstrapWitnessError @@ -52,6 +53,7 @@ data TxCmdError | TxCmdProtocolParamsError ProtocolParamsError | TxCmdScriptFileError (FileError ScriptDecodeError) | TxCmdCliScriptWitnessError !(FileError CliScriptWitnessError) + | TxCmdCliSpendingScriptWitnessError !(FileError CliSpendScriptWitnessError) | TxCmdKeyFileError (FileError InputDecodeError) | TxCmdReadTextViewFileError !(FileError TextEnvelopeError) | TxCmdReadWitnessSigningDataError !ReadWitnessSigningDataError @@ -109,6 +111,8 @@ renderTxCmdError = \case prettyError fileErr TxCmdCliScriptWitnessError cliScriptWitnessErr -> prettyError cliScriptWitnessErr + TxCmdCliSpendingScriptWitnessError cliSpendScriptWitnessErr -> + prettyError cliSpendScriptWitnessErr TxCmdKeyFileError fileErr -> prettyError fileErr TxCmdReadWitnessSigningDataError witSignDataErr -> 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 03d43386d5..f36b007fc7 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help.cli @@ -10857,6 +10857,25 @@ Usage: cardano-cli compatible shelley transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -10971,6 +10990,25 @@ Usage: cardano-cli compatible allegra transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -11085,6 +11123,25 @@ Usage: cardano-cli compatible mary transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -11207,6 +11264,25 @@ Usage: cardano-cli compatible alonzo transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -11339,6 +11415,25 @@ Usage: cardano-cli compatible babbage transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -11522,6 +11617,25 @@ Usage: cardano-cli compatible conway transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_allegra_transaction_signed-transaction.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_allegra_transaction_signed-transaction.cli index 7fa52d36d8..027999d93e 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_allegra_transaction_signed-transaction.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_allegra_transaction_signed-transaction.cli @@ -8,6 +8,25 @@ Usage: cardano-cli compatible allegra transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -28,5 +47,44 @@ Available options: --testnet-magic NATURAL Specify a testnet magic id. This overrides the CARDANO_NODE_NETWORK_ID environment variable --fee LOVELACE The fee amount in Lovelace. + --certificate-file FILEPATH + Filepath of the certificate. This encompasses all + types of certificates (stake pool certificates, stake + key certificates etc). Optionally specify a script + witness. + --certificate-script-file FILEPATH + The file containing the script to witness the use of + the certificate. + --certificate-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-execution-units (INT, INT) + The time and space units needed by the script. + --certificate-tx-in-reference TX-IN + TxId#TxIx - Specify a reference input. The reference + input must have a plutus reference script attached. + --certificate-plutus-script-v2 + Specify a plutus script v2 reference script. + --certificate-plutus-script-v3 + Specify a plutus script v3 reference script. + --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-reference-tx-in-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-reference-tx-in-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-reference-tx-in-execution-units (INT, INT) + The time and space units needed by the script. --out-file FILEPATH The output file. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_alonzo_transaction_signed-transaction.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_alonzo_transaction_signed-transaction.cli index 5e647a582e..2de56e22fd 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_alonzo_transaction_signed-transaction.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_alonzo_transaction_signed-transaction.cli @@ -16,6 +16,25 @@ Usage: cardano-cli compatible alonzo transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -63,5 +82,44 @@ Available options: --testnet-magic NATURAL Specify a testnet magic id. This overrides the CARDANO_NODE_NETWORK_ID environment variable --fee LOVELACE The fee amount in Lovelace. + --certificate-file FILEPATH + Filepath of the certificate. This encompasses all + types of certificates (stake pool certificates, stake + key certificates etc). Optionally specify a script + witness. + --certificate-script-file FILEPATH + The file containing the script to witness the use of + the certificate. + --certificate-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-execution-units (INT, INT) + The time and space units needed by the script. + --certificate-tx-in-reference TX-IN + TxId#TxIx - Specify a reference input. The reference + input must have a plutus reference script attached. + --certificate-plutus-script-v2 + Specify a plutus script v2 reference script. + --certificate-plutus-script-v3 + Specify a plutus script v3 reference script. + --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-reference-tx-in-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-reference-tx-in-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-reference-tx-in-execution-units (INT, INT) + The time and space units needed by the script. --out-file FILEPATH The output file. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_babbage_transaction_signed-transaction.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_babbage_transaction_signed-transaction.cli index d33e357626..69b7bddb79 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_babbage_transaction_signed-transaction.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_babbage_transaction_signed-transaction.cli @@ -19,6 +19,25 @@ Usage: cardano-cli compatible babbage transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -79,5 +98,44 @@ Available options: --testnet-magic NATURAL Specify a testnet magic id. This overrides the CARDANO_NODE_NETWORK_ID environment variable --fee LOVELACE The fee amount in Lovelace. + --certificate-file FILEPATH + Filepath of the certificate. This encompasses all + types of certificates (stake pool certificates, stake + key certificates etc). Optionally specify a script + witness. + --certificate-script-file FILEPATH + The file containing the script to witness the use of + the certificate. + --certificate-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-execution-units (INT, INT) + The time and space units needed by the script. + --certificate-tx-in-reference TX-IN + TxId#TxIx - Specify a reference input. The reference + input must have a plutus reference script attached. + --certificate-plutus-script-v2 + Specify a plutus script v2 reference script. + --certificate-plutus-script-v3 + Specify a plutus script v3 reference script. + --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-reference-tx-in-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-reference-tx-in-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-reference-tx-in-execution-units (INT, INT) + The time and space units needed by the script. --out-file FILEPATH The output file. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_conway_transaction_signed-transaction.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_conway_transaction_signed-transaction.cli index ac1af03a73..0f8d10407c 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_conway_transaction_signed-transaction.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_conway_transaction_signed-transaction.cli @@ -51,6 +51,25 @@ Usage: cardano-cli compatible conway transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -174,5 +193,44 @@ Available options: --testnet-magic NATURAL Specify a testnet magic id. This overrides the CARDANO_NODE_NETWORK_ID environment variable --fee LOVELACE The fee amount in Lovelace. + --certificate-file FILEPATH + Filepath of the certificate. This encompasses all + types of certificates (stake pool certificates, stake + key certificates etc). Optionally specify a script + witness. + --certificate-script-file FILEPATH + The file containing the script to witness the use of + the certificate. + --certificate-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-execution-units (INT, INT) + The time and space units needed by the script. + --certificate-tx-in-reference TX-IN + TxId#TxIx - Specify a reference input. The reference + input must have a plutus reference script attached. + --certificate-plutus-script-v2 + Specify a plutus script v2 reference script. + --certificate-plutus-script-v3 + Specify a plutus script v3 reference script. + --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-reference-tx-in-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-reference-tx-in-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-reference-tx-in-execution-units (INT, INT) + The time and space units needed by the script. --out-file FILEPATH The output file. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_mary_transaction_signed-transaction.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_mary_transaction_signed-transaction.cli index e745bab720..8ae77ecdcb 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_mary_transaction_signed-transaction.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_mary_transaction_signed-transaction.cli @@ -8,6 +8,25 @@ Usage: cardano-cli compatible mary transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -28,5 +47,44 @@ Available options: --testnet-magic NATURAL Specify a testnet magic id. This overrides the CARDANO_NODE_NETWORK_ID environment variable --fee LOVELACE The fee amount in Lovelace. + --certificate-file FILEPATH + Filepath of the certificate. This encompasses all + types of certificates (stake pool certificates, stake + key certificates etc). Optionally specify a script + witness. + --certificate-script-file FILEPATH + The file containing the script to witness the use of + the certificate. + --certificate-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-execution-units (INT, INT) + The time and space units needed by the script. + --certificate-tx-in-reference TX-IN + TxId#TxIx - Specify a reference input. The reference + input must have a plutus reference script attached. + --certificate-plutus-script-v2 + Specify a plutus script v2 reference script. + --certificate-plutus-script-v3 + Specify a plutus script v3 reference script. + --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-reference-tx-in-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-reference-tx-in-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-reference-tx-in-execution-units (INT, INT) + The time and space units needed by the script. --out-file FILEPATH The output file. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_shelley_transaction_signed-transaction.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_shelley_transaction_signed-transaction.cli index 3489c81c35..3644cd9167 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_shelley_transaction_signed-transaction.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/compatible_shelley_transaction_signed-transaction.cli @@ -8,6 +8,25 @@ Usage: cardano-cli compatible shelley transaction signed-transaction | --testnet-magic NATURAL ] --fee LOVELACE + [ + --certificate-file FILEPATH + [ --certificate-script-file FILEPATH + [ + ( --certificate-redeemer-cbor-file CBOR_FILE + | --certificate-redeemer-file JSON_FILE + | --certificate-redeemer-value JSON_VALUE + ) + --certificate-execution-units (INT, INT)] + | --certificate-tx-in-reference TX-IN + ( --certificate-plutus-script-v2 + | --certificate-plutus-script-v3 + ) + ( --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + | --certificate-reference-tx-in-redeemer-file JSON_FILE + | --certificate-reference-tx-in-redeemer-value JSON_VALUE + ) + --certificate-reference-tx-in-execution-units (INT, INT) + ]] --out-file FILEPATH Create a simple signed transaction. @@ -28,5 +47,44 @@ Available options: --testnet-magic NATURAL Specify a testnet magic id. This overrides the CARDANO_NODE_NETWORK_ID environment variable --fee LOVELACE The fee amount in Lovelace. + --certificate-file FILEPATH + Filepath of the certificate. This encompasses all + types of certificates (stake pool certificates, stake + key certificates etc). Optionally specify a script + witness. + --certificate-script-file FILEPATH + The file containing the script to witness the use of + the certificate. + --certificate-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-execution-units (INT, INT) + The time and space units needed by the script. + --certificate-tx-in-reference TX-IN + TxId#TxIx - Specify a reference input. The reference + input must have a plutus reference script attached. + --certificate-plutus-script-v2 + Specify a plutus script v2 reference script. + --certificate-plutus-script-v3 + Specify a plutus script v3 reference script. + --certificate-reference-tx-in-redeemer-cbor-file CBOR_FILE + The script redeemer file. The file has to be in CBOR + format. + --certificate-reference-tx-in-redeemer-file JSON_FILE + The script redeemer file. The file must follow the + detailed JSON schema for script data. + --certificate-reference-tx-in-redeemer-value JSON_VALUE + The script redeemer value. There is no schema: + (almost) any JSON value is supported, including + top-level strings and numbers. + --certificate-reference-tx-in-execution-units (INT, INT) + The time and space units needed by the script. --out-file FILEPATH The output file. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-test/Test/Cli/Shelley/Transaction/Compatible/Build.hs b/cardano-cli/test/cardano-cli-test/Test/Cli/Shelley/Transaction/Compatible/Build.hs new file mode 100644 index 0000000000..fd6e6e7344 --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/Test/Cli/Shelley/Transaction/Compatible/Build.hs @@ -0,0 +1,102 @@ +{-# LANGUAGE ScopedTypeVariables #-} + +module Test.Cli.Shelley.Transaction.Compatible.Build where + +import Cardano.Api.Eras +import Cardano.Api.Pretty + +import Control.Monad.Catch (MonadCatch) +import Control.Monad.IO.Class +import Data.Aeson (Value) +import qualified Data.Aeson as A +import Data.Char (toLower) +import Data.String (IsString (..)) +import GHC.Stack + +import Test.Cardano.CLI.Util + +import Hedgehog +import qualified Hedgehog.Extras as H + +inputDir :: FilePath +inputDir = "test/cardano-cli-test/files/input/shelley/transaction" + +-- | Execute me with: +-- @cabal test cardano-cli-test --test-options '-p "/conway transaction build one voter many votes/"'@ +hprop_compatible_conway_transaction_build_one_voter_many_votes :: Property +hprop_compatible_conway_transaction_build_one_voter_many_votes = propertyOnce $ H.moduleWorkspace "tmp" $ \tempDir -> do + refOutFile <- H.noteTempFile tempDir "reference_tx.traw" + outFile <- H.noteTempFile tempDir "tx.traw" + let eraName = map toLower . docToString $ pretty ConwayEra + + let args = + [ "--tx-in" + , "6e8c947816e82627aeccb55300074f2894a2051332f62a1c8954e7b588a18be7#0" + , "--tx-out" + , "addr_test1vpfwv0ezc5g8a4mkku8hhy3y3vp92t7s3ul8g778g5yegsgalc6gc+24910487859" + , "--fee" + , "178569" + , "--certificate-file" + , "test/cardano-cli-golden/files/golden/shelley/stake-address/reg-certificate-2.json" + , "--certificate-script-file" + , "test/cardano-cli-golden/files/input/AlwaysSucceeds.plutus" + , "--certificate-redeemer-value" + , "0" + , "--certificate-execution-units" + , "(0,0)" + ] + + -- reference transaction + _ <- + execCardanoCLI $ + [ eraName + , "transaction" + , "build-raw" + ] + <> args + <> [ "--out-file" + , refOutFile + ] + + -- tested compatible transaction + _ <- + execCardanoCLI $ + [ "compatible" + , eraName + , "transaction" + , "signed-transaction" + ] + <> args + <> [ "--out-file" + , outFile + ] + + assertTxFilesEqual refOutFile outFile + +assertTxFilesEqual + :: forall m + . (HasCallStack, MonadIO m, MonadTest m, MonadCatch m) + => FilePath + -- ^ expected + -> FilePath + -- ^ tested + -> m () +assertTxFilesEqual f1 f2 = withFrozenCallStack $ do + tx1 <- viewTx f1 + tx2 <- viewTx f2 + + tx1 === tx2 + where + -- deserialise a transaction from JSON file into a Value + viewTx :: HasCallStack => FilePath -> m Value + viewTx f = + withFrozenCallStack $ + H.leftFailM $ + A.eitherDecode . fromString + <$> execCardanoCLI + [ "debug" + , "transaction" + , "view" + , "--tx-body-file" + , f + ] diff --git a/flake.nix b/flake.nix index 1d02fb3a8d..354cae70cb 100644 --- a/flake.nix +++ b/flake.nix @@ -161,18 +161,21 @@ ${exportCliPath} cp -r ${filteredProjectBase}/* .. '' + (if isDarwin - then '' + then '' export PATH=${macOS-security}/bin:$PATH '' else ''''); packages.cardano-cli.components.tests.cardano-cli-test.preCheck = let # This define files included in the directory that will be passed to `H.getProjectBase` for this test: - filteredProjectBase = inputs.incl ./. mainnetConfigFiles; + filteredProjectBase = inputs.incl ./. (mainnetConfigFiles ++ [ + "cardano-cli/test/cardano-cli-golden/files/golden/shelley/stake-address/reg-certificate-2.json" + "cardano-cli/test/cardano-cli-golden/files/input/AlwaysSucceeds.plutus" + ]); in '' ${exportCliPath} cp -r ${filteredProjectBase}/* .. '' + (if isDarwin - then '' + then '' export PATH=${macOS-security}/bin:$PATH '' else '''');