diff --git a/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs b/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs index c59ace374a..6fb0c46e26 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/Run/Transaction.hs @@ -56,7 +56,7 @@ import Cardano.CLI.Types.TxFeature import qualified Ouroboros.Network.Protocol.LocalStateQuery.Type as Consensus import qualified Ouroboros.Network.Protocol.LocalTxSubmission.Client as Net.Tx -import Control.Monad (forM) +import Control.Monad (forM, when) import Data.Aeson ((.=)) import qualified Data.Aeson as Aeson import Data.Aeson.Encode.Pretty (encodePretty) @@ -80,6 +80,7 @@ import Data.Type.Equality (TestEquality (..)) import GHC.Exts (IsList (..)) import Lens.Micro ((^.)) import qualified System.IO as IO +import Control.Exception (throwIO) runTransactionCmds :: Cmd.TransactionCmds era -> ExceptT TxCmdError IO () runTransactionCmds = \case @@ -198,6 +199,38 @@ runTransactionBuildCmd first TxCmdProposalError <$> readTxGovernanceActions eon proposalFiles + -- Extract return addresses from proposals and check that the return address in each proposal is registered + + let returnAddrHashes = Set.fromList --queryStakeAddresses used bellow takes a Set of StakeCredential + [ StakeCredentialByKey returnAddrHash + | (proposal, _) <- proposals + , let (_, returnAddrHash, _) = fromProposalProcedure eon proposal -- fromProposalProcedure needs to be adjusted so that it works with script hashes. + ] + + let treasuryWithdrawalAddresses = Set.fromList + [ stakeCred + | (proposal, _) <- proposals + , let (_, _, govAction) = fromProposalProcedure eon proposal + , TreasuryWithdrawal withdrawalsList _ <- [govAction] -- Match on TreasuryWithdrawal action + , (_, stakeCred, _) <- withdrawalsList -- Extract each stake credential in treasury withdrawals + ] + + let allAddrHashes = Set.union returnAddrHashes treasuryWithdrawalAddresses + + queryResult <- liftIO $ executeLocalStateQueryExpr localNodeConnInfo Consensus.VolatileTip $ + queryStakeAddresses eon allAddrHashes networkId + + let unregisteredAddresses = case queryResult of + Right (Right (Right (balances, _))) -> + filter (\stakeCred -> not (Map.member (makeStakeAddress networkId stakeCred) balances)) (Set.toList allAddrHashes) + _ -> Set.toList allAddrHashes -- If query failed, add to the unregistered addresses list. + + -- WIP: This is a temporary solution to handle error message. + when (not (null unregisteredAddresses)) $ liftIO $ do + let errMsg = "Error: One or more stake addresses in proposals is not registered: " ++ show unregisteredAddresses + IO.hPutStrLn IO.stderr errMsg + throwIO $ userError errMsg + -- the same collateral input can be used for several plutus scripts let filteredTxinsc = nubOrd txinsc