From 2d12621982755b9441850bf6c1a4158cbf4237f6 Mon Sep 17 00:00:00 2001 From: John Ky Date: Tue, 10 Oct 2023 23:18:45 +1100 Subject: [PATCH] Do not allow submitting transactions older than current node era --- cardano-cli/cardano-cli.cabal | 1 + .../src/Cardano/CLI/EraBased/Run/Transaction.hs | 11 +++++------ .../CLI/Types/Errors/NodeEraMismatchError.hs | 13 +++++++++++++ .../src/Cardano/CLI/Types/Errors/TxCmdError.hs | 12 ++++++++---- 4 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 cardano-cli/src/Cardano/CLI/Types/Errors/NodeEraMismatchError.hs diff --git a/cardano-cli/cardano-cli.cabal b/cardano-cli/cardano-cli.cabal index bb86a64ff2..865116686e 100644 --- a/cardano-cli/cardano-cli.cabal +++ b/cardano-cli/cardano-cli.cabal @@ -170,6 +170,7 @@ library Cardano.CLI.Types.Errors.ItnKeyConversionError Cardano.CLI.Types.Errors.KeyCmdError Cardano.CLI.Types.Errors.NodeCmdError + Cardano.CLI.Types.Errors.NodeEraMismatchError Cardano.CLI.Types.Errors.ProtocolParamsError Cardano.CLI.Types.Errors.QueryCmdError Cardano.CLI.Types.Errors.QueryCmdLocalStateQueryError diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs b/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs index b05505e7bf..1f5a99e3d4 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs @@ -38,6 +38,7 @@ import Cardano.CLI.Json.Friendly (friendlyTxBodyJson, friendlyTxBodyYa import Cardano.CLI.Read import Cardano.CLI.Types.Common import Cardano.CLI.Types.Errors.BootstrapWitnessError +import Cardano.CLI.Types.Errors.NodeEraMismatchError import Cardano.CLI.Types.Errors.TxCmdError import Cardano.CLI.Types.Errors.TxValidationError import Cardano.CLI.Types.Governance @@ -246,15 +247,13 @@ runTxBuildCmd & onLeft (left . TxCmdQueryConvenienceError . AcqFailure) & onLeft (left . TxCmdQueryConvenienceError . QceUnsupportedNtcVersion) - (nodeEraUTxO, _, eraHistory, systemStart, _, _, _) <- + (txEraUtxo, _, eraHistory, systemStart, _, _, _) <- lift (executeLocalStateQueryExpr localNodeConnInfo Nothing (queryStateForBalancedTx nodeEra allTxInputs [])) & onLeft (left . TxCmdQueryConvenienceError . AcqFailure) & onLeft (left . TxCmdQueryConvenienceError) - -- Why do we cast the era? The user can specify an era prior to the era that the node is currently in. - -- We cannot use the user specified era to construct a query against a node because it may differ - -- from the node's era and this will result in the 'QueryEraMismatch' failure. - txEraUtxo <- cardanoEraConstraints era $ pure (eraCast era nodeEraUTxO) & onLeft (left . TxCmdTxEraCastErr) + Refl <- testEquality era nodeEra + & hoistMaybe (TxCmdTxNodeEraMismatchError $ NodeEraMismatchError era nodeEra) scriptExecUnitsMap <- firstExceptT TxCmdTxExecUnitsErr $ hoistEither @@ -579,7 +578,7 @@ runTxBuild & onLeft (left . TxCmdQueryConvenienceError . QceUnsupportedNtcVersion) Refl <- testEquality era nodeEra - & hoistMaybe (TxCmdTxEraCastErr $ EraCastError ("nodeEra" :: Text) era nodeEra) + & hoistMaybe (TxCmdTxNodeEraMismatchError $ NodeEraMismatchError era nodeEra) let certs = case validatedTxCerts of diff --git a/cardano-cli/src/Cardano/CLI/Types/Errors/NodeEraMismatchError.hs b/cardano-cli/src/Cardano/CLI/Types/Errors/NodeEraMismatchError.hs new file mode 100644 index 0000000000..4c00bf7416 --- /dev/null +++ b/cardano-cli/src/Cardano/CLI/Types/Errors/NodeEraMismatchError.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE GADTs #-} + +module Cardano.CLI.Types.Errors.NodeEraMismatchError + ( NodeEraMismatchError(..) + ) where + +import Cardano.Api + +data NodeEraMismatchError = forall era nodeEra. + NodeEraMismatchError + { era :: !(CardanoEra era) + , nodeEra :: !(CardanoEra nodeEra) + } diff --git a/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs b/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs index 29e610e7b3..3ea8fa80bc 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Errors/TxCmdError.hs @@ -16,6 +16,7 @@ import Cardano.Api.Shelley import Cardano.CLI.Read import Cardano.CLI.Types.Common import Cardano.CLI.Types.Errors.BootstrapWitnessError +import Cardano.CLI.Types.Errors.NodeEraMismatchError import Cardano.CLI.Types.Errors.ProtocolParamsError import Cardano.CLI.Types.Errors.TxValidationError import Cardano.CLI.Types.Output @@ -68,7 +69,7 @@ data TxCmdError | TxCmdPParamExecutionUnitsNotAvailable | TxCmdPlutusScriptsRequireCardanoMode | TxCmdProtocolParametersNotPresentInTxBody - | TxCmdTxEraCastErr EraCastError + | TxCmdTxNodeEraMismatchError !NodeEraMismatchError | TxCmdQueryConvenienceError !QueryConvenienceError | TxCmdQueryNotScriptLocked !ScriptLockedTxInsError | TxCmdScriptDataError !ScriptDataError @@ -167,9 +168,12 @@ renderTxCmdError err = [ "Execution units not available in the protocol parameters. This is " , "likely due to not being in the Alonzo era" ] - TxCmdTxEraCastErr (EraCastError value fromEra toEra) -> - "Transactions can only be produced in the same era as the node. Mismatched eras of " - <> textShow value <> ". Requested era: " <> renderEra (AnyCardanoEra toEra) <> ", node era: " <> renderEra (AnyCardanoEra fromEra) <> "." + TxCmdTxNodeEraMismatchError (NodeEraMismatchError nodeEra valueEra) -> + cardanoEraConstraints nodeEra $ cardanoEraConstraints valueEra $ mconcat + [ "Transactions can only be produced in the same era as the node. Requested era: " + , renderEra (AnyCardanoEra valueEra) <> ", node era: " + , renderEra (AnyCardanoEra nodeEra) <> "." + ] TxCmdQueryConvenienceError e -> renderQueryConvenienceError e TxCmdQueryNotScriptLocked e ->