diff --git a/cardano-api/cardano-api.cabal b/cardano-api/cardano-api.cabal index 65cd169de19..c8ff0fb8f38 100644 --- a/cardano-api/cardano-api.cabal +++ b/cardano-api/cardano-api.cabal @@ -68,9 +68,10 @@ library Cardano.Api.GenesisParameters Cardano.Api.Hash Cardano.Api.HasTypeProxy + Cardano.Api.InMode + Cardano.Api.IO Cardano.Api.IPC Cardano.Api.IPC.Monad - Cardano.Api.InMode Cardano.Api.IPC.Version Cardano.Api.Json Cardano.Api.Keys.Byron diff --git a/cardano-api/src/Cardano/Api.hs b/cardano-api/src/Cardano/Api.hs index 8b117fc6b94..e214e00d197 100644 --- a/cardano-api/src/Cardano/Api.hs +++ b/cardano-api/src/Cardano/Api.hs @@ -33,6 +33,21 @@ module Cardano.Api ( cardanoEraStyle, shelleyBasedToCardanoEra, + -- ** IO + OutputFile(..), + + writeByteStringFileWithOwnerPermissions, + writeByteStringFile, + writeByteStringOutput, + + writeLazyByteStringFileWithOwnerPermissions, + writeLazyByteStringFile, + writeLazyByteStringOutput, + + writeTextFileWithOwnerPermissions, + writeTextFile, + writeTextOutput, + -- ** Deprecated Byron, Shelley, @@ -523,7 +538,6 @@ module Cardano.Api ( deserialiseFromTextEnvelope, readFileTextEnvelope, writeFileTextEnvelope, - writeFileTextEnvelopeWithOwnerPermissions, readTextEnvelopeFromFile, readTextEnvelopeOfTypeFromFile, @@ -800,6 +814,7 @@ import Cardano.Api.GenesisParameters import Cardano.Api.Hash import Cardano.Api.HasTypeProxy import Cardano.Api.InMode +import Cardano.Api.IO import Cardano.Api.IPC import Cardano.Api.IPC.Monad import Cardano.Api.Keys.Byron diff --git a/cardano-api/src/Cardano/Api/IO.hs b/cardano-api/src/Cardano/Api/IO.hs new file mode 100644 index 00000000000..223002bff96 --- /dev/null +++ b/cardano-api/src/Cardano/Api/IO.hs @@ -0,0 +1,161 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Cardano.Api.IO + ( OutputFile(..) + + , writeByteStringFileWithOwnerPermissions + , writeByteStringFile + , writeByteStringOutput + + , writeLazyByteStringFileWithOwnerPermissions + , writeLazyByteStringFile + , writeLazyByteStringOutput + + , writeTextFileWithOwnerPermissions + , writeTextFile + , writeTextOutput + + ) where + +#if !defined(mingw32_HOST_OS) +#define UNIX +#endif + +#ifdef UNIX +import Control.Exception (IOException, bracket, bracketOnError, try) +import System.Directory () +import System.IO (hClose) +import System.Posix.Files (ownerModes, setFdOwnerAndGroup) +import System.Posix.IO (OpenMode (..), closeFd, defaultFileFlags, fdToHandle, openFd) +import System.Posix.User (getRealUserID) +#else +import Control.Exception (bracketOnError) +import System.Directory (removeFile, renameFile) +import System.FilePath (splitFileName, (<.>)) +import System.IO (hClose, openTempFile) +#endif + +import Cardano.Api.Error (FileError (..)) + +import Control.Monad.Except (runExceptT) +import Control.Monad.IO.Class (MonadIO (..)) +import Control.Monad.Trans.Except.Extra (handleIOExceptT) +import Data.Aeson.Types (FromJSON, ToJSON) +import Data.ByteString (ByteString) +import qualified Data.ByteString.Char8 as BS +import qualified Data.ByteString.Char8 as BSC +import qualified Data.ByteString.Lazy as LBS +import qualified Data.ByteString.Lazy as LBSC +import Data.String (IsString) +import Data.Text (Text) +import qualified Data.Text.IO as Text +import GHC.Generics (Generic) +import System.IO (Handle) + +handleFileForWritingWithOwnerPermission + :: FilePath + -> (Handle -> IO ()) + -> IO (Either (FileError ()) ()) +handleFileForWritingWithOwnerPermission path f = do +#ifdef UNIX + -- On a unix based system, we grab a file descriptor and set ourselves as owner. + -- Since we're holding the file descriptor at this point, we can be sure that + -- what we're about to write to is owned by us if an error didn't occur. + user <- getRealUserID + ownedFile <- try $ + -- We only close the FD on error here, otherwise we let it leak out, since + -- it will be immediately turned into a Handle (which will be closed when + -- the Handle is closed) + bracketOnError + (openFd path WriteOnly (Just ownerModes) defaultFileFlags) + closeFd + (\fd -> setFdOwnerAndGroup fd user (-1) >> pure fd) + case ownedFile of + Left (err :: IOException) -> do + pure $ Left $ FileIOError path err + Right fd -> do + bracket + (fdToHandle fd) + hClose + (runExceptT . handleIOExceptT (FileIOError path) . f) +#else + -- On something other than unix, we make a _new_ file, and since we created it, + -- we must own it. We then place it at the target location. Unfortunately this + -- won't work correctly with pseudo-files. + bracketOnError + (openTempFile targetDir $ targetFile <.> "tmp") + (\(tmpPath, h) -> do + hClose h >> removeFile tmpPath + return . Left $ FileErrorTempFile path tmpPath h) + (\(tmpPath, h) -> do + f h + hClose h + renameFile tmpPath path + return $ Right ()) + where + (targetDir, targetFile) = splitFileName path +#endif + +newtype OutputFile = OutputFile + { unOutputFile :: FilePath + } + deriving Generic + deriving newtype (Eq, Ord, Show, IsString, ToJSON, FromJSON) + +writeByteStringFile :: MonadIO m => FilePath -> ByteString -> m (Either (FileError ()) ()) +writeByteStringFile fp bs = runExceptT $ + handleIOExceptT (FileIOError fp) $ BS.writeFile fp bs + +writeByteStringFileWithOwnerPermissions + :: FilePath + -> BS.ByteString + -> IO (Either (FileError ()) ()) +writeByteStringFileWithOwnerPermissions fp bs = + handleFileForWritingWithOwnerPermission fp $ \h -> + BS.hPut h bs + +writeByteStringOutput :: MonadIO m => Maybe FilePath -> ByteString -> m (Either (FileError ()) ()) +writeByteStringOutput mOutput bs = runExceptT $ + case mOutput of + Just fp -> handleIOExceptT (FileIOError fp) $ BS.writeFile fp bs + Nothing -> liftIO $ BSC.putStr bs + +writeLazyByteStringFile :: MonadIO m => FilePath -> LBS.ByteString -> m (Either (FileError ()) ()) +writeLazyByteStringFile fp bs = runExceptT $ + handleIOExceptT (FileIOError fp) $ LBS.writeFile fp bs + +writeLazyByteStringFileWithOwnerPermissions + :: FilePath + -> LBS.ByteString + -> IO (Either (FileError ()) ()) +writeLazyByteStringFileWithOwnerPermissions fp lbs = + handleFileForWritingWithOwnerPermission fp $ \h -> + LBS.hPut h lbs + +writeLazyByteStringOutput :: MonadIO m => Maybe FilePath -> LBS.ByteString -> m (Either (FileError ()) ()) +writeLazyByteStringOutput mOutput bs = runExceptT $ + case mOutput of + Just fp -> handleIOExceptT (FileIOError fp) $ LBS.writeFile fp bs + Nothing -> liftIO $ LBSC.putStr bs + +writeTextFile :: MonadIO m => FilePath -> Text -> m (Either (FileError ()) ()) +writeTextFile fp t = runExceptT $ + handleIOExceptT (FileIOError fp) $ Text.writeFile fp t + +writeTextFileWithOwnerPermissions + :: FilePath + -> Text + -> IO (Either (FileError ()) ()) +writeTextFileWithOwnerPermissions fp t = + handleFileForWritingWithOwnerPermission fp $ \h -> + Text.hPutStr h t + +writeTextOutput :: MonadIO m => Maybe FilePath -> Text -> m (Either (FileError ()) ()) +writeTextOutput mOutput t = runExceptT $ + case mOutput of + Just fp -> handleIOExceptT (FileIOError fp) $ Text.writeFile fp t + Nothing -> liftIO $ Text.putStr t diff --git a/cardano-api/src/Cardano/Api/SerialiseTextEnvelope.hs b/cardano-api/src/Cardano/Api/SerialiseTextEnvelope.hs index 693e55551d9..8d7cda7db8f 100644 --- a/cardano-api/src/Cardano/Api/SerialiseTextEnvelope.hs +++ b/cardano-api/src/Cardano/Api/SerialiseTextEnvelope.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} @@ -6,10 +5,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} -#if !defined(mingw32_HOST_OS) -#define UNIX -#endif - -- | TextEnvelope Serialisation -- module Cardano.Api.SerialiseTextEnvelope @@ -23,7 +18,6 @@ module Cardano.Api.SerialiseTextEnvelope , deserialiseFromTextEnvelope , readFileTextEnvelope , writeFileTextEnvelope - , writeFileTextEnvelopeWithOwnerPermissions , readTextEnvelopeFromFile , readTextEnvelopeOfTypeFromFile , textEnvelopeToJSON @@ -60,24 +54,10 @@ import Cardano.Binary (DecoderError) import Cardano.Api.Error import Cardano.Api.HasTypeProxy +import Cardano.Api.IO import Cardano.Api.SerialiseCBOR import Cardano.Api.Utils (readFileBlocking) -#ifdef UNIX -import Control.Exception (IOException, bracket, bracketOnError, try) -import System.Directory () -import System.IO (hClose) -import System.Posix.Files (ownerModes, setFdOwnerAndGroup) -import System.Posix.IO (OpenMode (..), closeFd, defaultFileFlags, fdToHandle, openFd) -import System.Posix.User (getRealUserID) -#else -import Control.Exception (bracketOnError) -import System.Directory (removeFile, renameFile) -import System.FilePath (splitFileName, (<.>)) -import System.IO (hClose, openTempFile) -#endif - - -- ---------------------------------------------------------------------------- -- Text envelopes -- @@ -226,74 +206,13 @@ deserialiseFromTextEnvelopeAnyOf types te = matching (FromSomeType ttoken _f) = actualType == textEnvelopeType ttoken -writeFileWithOwnerPermissions - :: FilePath - -> LBS.ByteString - -> IO (Either (FileError ()) ()) -#ifdef UNIX --- On a unix based system, we grab a file descriptor and set ourselves as owner. --- Since we're holding the file descriptor at this point, we can be sure that --- what we're about to write to is owned by us if an error didn't occur. -writeFileWithOwnerPermissions path a = do - user <- getRealUserID - ownedFile <- try $ - -- We only close the FD on error here, otherwise we let it leak out, since - -- it will be immediately turned into a Handle (which will be closed when - -- the Handle is closed) - bracketOnError - (openFd path WriteOnly (Just ownerModes) defaultFileFlags) - closeFd - (\fd -> setFdOwnerAndGroup fd user (-1) >> pure fd) - case ownedFile of - Left (err :: IOException) -> do - pure $ Left $ FileIOError path err - Right fd -> do - bracket - (fdToHandle fd) - hClose - (\handle -> runExceptT $ handleIOExceptT (FileIOError path) $ LBS.hPut handle a) -#else --- On something other than unix, we make a _new_ file, and since we created it, --- we must own it. We then place it at the target location. Unfortunately this --- won't work correctly with pseudo-files. -writeFileWithOwnerPermissions targetPath a = - bracketOnError - (openTempFile targetDir $ targetFile <.> "tmp") - (\(tmpPath, fHandle) -> do - hClose fHandle >> removeFile tmpPath - return . Left $ FileErrorTempFile targetPath tmpPath fHandle) - (\(tmpPath, fHandle) -> do - LBS.hPut fHandle a - hClose fHandle - renameFile tmpPath targetPath - return $ Right ()) - where - (targetDir, targetFile) = splitFileName targetPath -#endif - writeFileTextEnvelope :: HasTextEnvelope a => FilePath -> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ()) -writeFileTextEnvelope path mbDescr a = - runExceptT $ do - handleIOExceptT (FileIOError path) $ LBS.writeFile path content - where - content = textEnvelopeToJSON mbDescr a - - -writeFileTextEnvelopeWithOwnerPermissions - :: HasTextEnvelope a - => FilePath - -> Maybe TextEnvelopeDescr - -> a - -> IO (Either (FileError ()) ()) -writeFileTextEnvelopeWithOwnerPermissions targetPath mbDescr a = - writeFileWithOwnerPermissions targetPath content - where - content = textEnvelopeToJSON mbDescr a - +writeFileTextEnvelope outputFile mbDescr a = + writeLazyByteStringFile outputFile (textEnvelopeToJSON mbDescr a) textEnvelopeToJSON :: HasTextEnvelope a => Maybe TextEnvelopeDescr -> a -> LBS.ByteString textEnvelopeToJSON mbDescr a = diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs b/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs index c017a614309..36a8a4f1b4e 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Commands.hs @@ -514,11 +514,6 @@ data MetadataFile = MetadataFileJSON FilePath deriving Show -newtype OutputFile = OutputFile - { unOutputFile :: FilePath - } - deriving Show - newtype PoolMetadataFile = PoolMetadataFile { unPoolMetadataFile :: FilePath } deriving Show diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Address.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Address.hs index b7563d11c80..c42790cecc4 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Address.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Address.hs @@ -26,7 +26,7 @@ import Cardano.CLI.Shelley.Key (PaymentVerifier (..), StakeIdentifier StakeVerifier (..), VerificationKeyTextOrFile, VerificationKeyTextOrFileError (..), generateKeyPair, readVerificationKeyOrFile, readVerificationKeyTextOrFileAnyOf, renderVerificationKeyTextOrFileError) -import Cardano.CLI.Shelley.Parsers (AddressCmd (..), AddressKeyType (..), OutputFile (..)) +import Cardano.CLI.Shelley.Parsers (AddressCmd (..), AddressKeyType (..)) import Cardano.CLI.Shelley.Run.Address.Info (ShelleyAddressInfoError, runAddressInfo) import Cardano.CLI.Shelley.Run.Read import Cardano.CLI.Types @@ -91,8 +91,8 @@ writePaymentKeyFiles -> ExceptT ShelleyAddressCmdError IO () writePaymentKeyFiles (VerificationKeyFile vkeyPath) (SigningKeyFile skeyPath) vkey skey = do firstExceptT ShelleyAddressCmdWriteFileError $ do - newExceptT $ writeFileTextEnvelope skeyPath (Just skeyDesc) skey - newExceptT $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + newExceptT $ writeLazyByteStringFile skeyPath $ textEnvelopeToJSON (Just skeyDesc) skey + newExceptT $ writeLazyByteStringFile vkeyPath $ textEnvelopeToJSON (Just vkeyDesc) vkey where skeyDesc, vkeyDesc :: TextEnvelopeDescr skeyDesc = "Payment Signing Key" diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Address/Info.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Address/Info.hs index 6d1f16ed934..aa98e9f0c4f 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Address/Info.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Address/Info.hs @@ -5,7 +5,6 @@ module Cardano.CLI.Shelley.Run.Address.Info ) where import Cardano.Api -import Cardano.CLI.Shelley.Parsers (OutputFile (..)) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Trans.Except (ExceptT) diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Genesis.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Genesis.hs index ab54da7f573..5c21c4204a3 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Genesis.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Genesis.hs @@ -238,10 +238,12 @@ runGenesisKeyGenGenesis (VerificationKeyFile vkeyPath) let vkey = getVerificationKey skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope skeyPath (Just skeyDesc) skey + $ writeLazyByteStringFile skeyPath + $ textEnvelopeToJSON (Just skeyDesc) skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + $ writeLazyByteStringFile vkeyPath + $ textEnvelopeToJSON (Just vkeyDesc) vkey where skeyDesc, vkeyDesc :: TextEnvelopeDescr skeyDesc = "Genesis Signing Key" @@ -259,13 +261,16 @@ runGenesisKeyGenDelegate (VerificationKeyFile vkeyPath) let vkey = getVerificationKey skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope skeyPath (Just skeyDesc) skey + $ writeLazyByteStringFile skeyPath + $ textEnvelopeToJSON (Just skeyDesc) skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + $ writeLazyByteStringFile vkeyPath + $ textEnvelopeToJSON (Just vkeyDesc) vkey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope ocertCtrPath (Just certCtrDesc) + $ writeLazyByteStringFile ocertCtrPath + $ textEnvelopeToJSON (Just certCtrDesc) $ OperationalCertificateIssueCounter initialCounter (castVerificationKey vkey) -- Cast to a 'StakePoolKey' @@ -288,10 +293,12 @@ runGenesisKeyGenDelegateVRF (VerificationKeyFile vkeyPath) let vkey = getVerificationKey skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope skeyPath (Just skeyDesc) skey + $ writeLazyByteStringFile skeyPath + $ textEnvelopeToJSON (Just skeyDesc) skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + $ writeLazyByteStringFile vkeyPath + $ textEnvelopeToJSON (Just vkeyDesc) vkey where skeyDesc, vkeyDesc :: TextEnvelopeDescr skeyDesc = "VRF Signing Key" @@ -306,10 +313,12 @@ runGenesisKeyGenUTxO (VerificationKeyFile vkeyPath) let vkey = getVerificationKey skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope skeyPath (Just skeyDesc) skey + $ writeLazyByteStringFile skeyPath + $ textEnvelopeToJSON (Just skeyDesc) skey firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT - $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + $ writeLazyByteStringFile vkeyPath + $ textEnvelopeToJSON (Just vkeyDesc) vkey where skeyDesc, vkeyDesc :: TextEnvelopeDescr skeyDesc = "Genesis Initial UTxO Signing Key" @@ -362,9 +371,9 @@ runGenesisVerKey (VerificationKeyFile vkeyPath) (SigningKeyFile skeyPath) = do firstExceptT ShelleyGenesisCmdGenesisFileError . newExceptT . liftIO $ case vkey of - AGenesisKey vk -> writeFileTextEnvelope vkeyPath Nothing vk - AGenesisDelegateKey vk -> writeFileTextEnvelope vkeyPath Nothing vk - AGenesisUTxOKey vk -> writeFileTextEnvelope vkeyPath Nothing vk + AGenesisKey vk -> writeLazyByteStringFile vkeyPath $ textEnvelopeToJSON Nothing vk + AGenesisDelegateKey vk -> writeLazyByteStringFile vkeyPath $ textEnvelopeToJSON Nothing vk + AGenesisUTxOKey vk -> writeLazyByteStringFile vkeyPath $ textEnvelopeToJSON Nothing vk data SomeGenesisKey f = AGenesisKey (f GenesisKey) diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Governance.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Governance.hs index beb79fb7847..7951de93159 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Governance.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Governance.hs @@ -92,7 +92,7 @@ runGovernanceMIRCertificatePayStakeAddrs mirPot sAddrs rwdAmts (OutputFile oFp) firstExceptT ShelleyGovernanceCmdTextEnvWriteError . newExceptT - $ writeFileTextEnvelope oFp (Just mirCertDesc) mirCert + $ writeLazyByteStringFile oFp $ textEnvelopeToJSON (Just mirCertDesc) mirCert where mirCertDesc :: TextEnvelopeDescr mirCertDesc = "Move Instantaneous Rewards Certificate" @@ -111,7 +111,8 @@ runGovernanceMIRCertificateTransfer ll (OutputFile oFp) direction = do firstExceptT ShelleyGovernanceCmdTextEnvWriteError . newExceptT - $ writeFileTextEnvelope oFp (Just $ mirCertDesc direction) mirCert + $ writeLazyByteStringFile oFp + $ textEnvelopeToJSON (Just $ mirCertDesc direction) mirCert where mirCertDesc :: TransferDirection -> TextEnvelopeDescr mirCertDesc TransferToTreasury = "MIR Certificate Send To Treasury" @@ -139,7 +140,8 @@ runGovernanceGenesisKeyDelegationCertificate genVkOrHashOrFp $ readVerificationKeyOrHashOrFile AsVrfKey vrfVkOrHashOrFp firstExceptT ShelleyGovernanceCmdTextEnvWriteError . newExceptT - $ writeFileTextEnvelope oFp (Just genKeyDelegCertDesc) + $ writeLazyByteStringFile oFp + $ textEnvelopeToJSON (Just genKeyDelegCertDesc) $ makeGenesisKeyDelegationCertificate genesisVkHash genesisDelVkHash vrfVkHash where genKeyDelegCertDesc :: TextEnvelopeDescr @@ -175,5 +177,6 @@ runGovernanceUpdateProposal (OutputFile upFile) eNo genVerKeyFiles upPprams mCos let genKeyHashes = fmap verificationKeyHash genVKeys upProp = makeShelleyUpdateProposal finalUpPprams genKeyHashes eNo - firstExceptT ShelleyGovernanceCmdTextEnvWriteError . newExceptT $ writeFileTextEnvelope upFile Nothing upProp + firstExceptT ShelleyGovernanceCmdTextEnvWriteError . newExceptT + $ writeLazyByteStringFile upFile $ textEnvelopeToJSON Nothing upProp diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Key.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Key.hs index a053bd6ae51..7fd333ef7f1 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Key.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Key.hs @@ -120,7 +120,7 @@ runGetVerificationKey skf (VerificationKeyFile vkf) = do withSomeSigningKey ssk $ \sk -> let vk = getVerificationKey sk in firstExceptT ShelleyKeyCmdWriteFileError . newExceptT $ - writeFileTextEnvelope vkf Nothing vk + writeLazyByteStringFile vkf $ textEnvelopeToJSON Nothing vk data SomeSigningKey @@ -244,8 +244,9 @@ runConvertToNonExtendedKey evkf (VerificationKeyFile vkf) = writeToDisk :: Key keyrole => FilePath -> VerificationKey keyrole -> ExceptT ShelleyKeyCmdError IO () - writeToDisk vkf' vk = firstExceptT ShelleyKeyCmdWriteFileError . newExceptT - $ writeFileTextEnvelope vkf' Nothing vk + writeToDisk vkf' vk = + firstExceptT ShelleyKeyCmdWriteFileError . newExceptT + $ writeLazyByteStringFile vkf' $ textEnvelopeToJSON Nothing vk readExtendedVerificationKeyFile @@ -364,7 +365,7 @@ convertByronSigningKey mPwd byronFormat convert sk' = convert unprotectedSk firstExceptT ShelleyKeyCmdWriteFileError . newExceptT $ - writeFileTextEnvelope skeyPathNew Nothing sk' + writeLazyByteStringFile skeyPathNew $ textEnvelopeToJSON Nothing sk' convertByronVerificationKey :: forall keyrole. @@ -384,7 +385,7 @@ convertByronVerificationKey convert vk' = convert vk firstExceptT ShelleyKeyCmdWriteFileError . newExceptT $ - writeFileTextEnvelope vkeyPathNew Nothing vk' + writeLazyByteStringFile vkeyPathNew $ textEnvelopeToJSON Nothing vk' runConvertByronGenesisVerificationKey @@ -404,7 +405,7 @@ runConvertByronGenesisVerificationKey (VerificationKeyBase64 b64ByronVKey) vk' = convert vk firstExceptT ShelleyKeyCmdWriteFileError . newExceptT $ - writeFileTextEnvelope vkeyPathNew Nothing vk' + writeLazyByteStringFile vkeyPathNew $ textEnvelopeToJSON Nothing vk' where convert :: Byron.VerificationKey -> VerificationKey GenesisKey convert (Byron.VerificationKey xvk) = @@ -426,7 +427,7 @@ runConvertITNStakeKey (AVerificationKeyFile (VerificationKeyFile vk)) (OutputFil . first ShelleyKeyCmdItnKeyConvError $ convertITNVerificationKey bech32publicKey firstExceptT ShelleyKeyCmdWriteFileError . newExceptT $ - writeFileTextEnvelope outFile Nothing vkey + writeLazyByteStringFile outFile $ textEnvelopeToJSON Nothing vkey runConvertITNStakeKey (ASigningKeyFile (SigningKeyFile sk)) (OutputFile outFile) = do bech32privateKey <- firstExceptT ShelleyKeyCmdItnKeyConvError . newExceptT $ @@ -434,8 +435,9 @@ runConvertITNStakeKey (ASigningKeyFile (SigningKeyFile sk)) (OutputFile outFile) skey <- hoistEither . first ShelleyKeyCmdItnKeyConvError $ convertITNSigningKey bech32privateKey - firstExceptT ShelleyKeyCmdWriteFileError . newExceptT $ - writeFileTextEnvelope outFile Nothing skey + firstExceptT ShelleyKeyCmdWriteFileError . newExceptT + $ writeLazyByteStringFile outFile + $ textEnvelopeToJSON Nothing skey runConvertITNExtendedToStakeKey :: SomeKeyFile -> OutputFile -> ExceptT ShelleyKeyCmdError IO () runConvertITNExtendedToStakeKey (AVerificationKeyFile _) _ = left ShelleyKeyCmdWrongKeyTypeError @@ -444,7 +446,8 @@ runConvertITNExtendedToStakeKey (ASigningKeyFile (SigningKeyFile sk)) (OutputFil skey <- hoistEither . first ShelleyKeyCmdItnKeyConvError $ convertITNExtendedSigningKey bech32privateKey firstExceptT ShelleyKeyCmdWriteFileError . newExceptT - $ writeFileTextEnvelope outFile Nothing skey + $ writeLazyByteStringFile outFile + $ textEnvelopeToJSON Nothing skey runConvertITNBip32ToStakeKey :: SomeKeyFile -> OutputFile -> ExceptT ShelleyKeyCmdError IO () runConvertITNBip32ToStakeKey (AVerificationKeyFile _) _ = left ShelleyKeyCmdWrongKeyTypeError @@ -453,7 +456,8 @@ runConvertITNBip32ToStakeKey (ASigningKeyFile (SigningKeyFile sk)) (OutputFile o skey <- hoistEither . first ShelleyKeyCmdItnKeyConvError $ convertITNBIP32SigningKey bech32privateKey firstExceptT ShelleyKeyCmdWriteFileError . newExceptT - $ writeFileTextEnvelope outFile Nothing skey + $ writeLazyByteStringFile outFile + $ textEnvelopeToJSON Nothing skey -- | An error that can occur while converting an Incentivized Testnet (ITN) -- key. @@ -649,8 +653,8 @@ writeSomeCardanoAddressSigningKeyFile writeSomeCardanoAddressSigningKeyFile outFile skey = case skey of ACardanoAddrShelleyPaymentSigningKey sk -> - writeFileTextEnvelope outFile Nothing sk + writeLazyByteStringFile outFile $ textEnvelopeToJSON Nothing sk ACardanoAddrShelleyStakeSigningKey sk -> - writeFileTextEnvelope outFile Nothing sk + writeLazyByteStringFile outFile $ textEnvelopeToJSON Nothing sk ACardanoAddrByronSigningKey sk -> - writeFileTextEnvelope outFile Nothing sk + writeLazyByteStringFile outFile $ textEnvelopeToJSON Nothing sk diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Node.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Node.hs index 3319f0dd61c..6f6dd53cc80 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Node.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Node.hs @@ -81,13 +81,16 @@ runNodeKeyGenCold (VerificationKeyFile vkeyPath) (SigningKeyFile skeyPath) let vkey = getVerificationKey skey firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope skeyPath (Just skeyDesc) skey + $ writeLazyByteStringFile skeyPath + $ textEnvelopeToJSON (Just skeyDesc) skey firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + $ writeLazyByteStringFile vkeyPath + $ textEnvelopeToJSON (Just vkeyDesc) vkey firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope ocertCtrPath (Just ocertCtrDesc) + $ writeLazyByteStringFile ocertCtrPath + $ textEnvelopeToJSON (Just ocertCtrDesc) $ OperationalCertificateIssueCounter initialCounter vkey where skeyDesc, vkeyDesc, ocertCtrDesc :: TextEnvelopeDescr @@ -108,10 +111,12 @@ runNodeKeyGenKES (VerificationKeyFile vkeyPath) (SigningKeyFile skeyPath) = do let vkey = getVerificationKey skey firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope skeyPath (Just skeyDesc) skey + $ writeLazyByteStringFile skeyPath + $ textEnvelopeToJSON (Just skeyDesc) skey firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + $ writeLazyByteStringFile vkeyPath + $ textEnvelopeToJSON (Just vkeyDesc) vkey where skeyDesc, vkeyDesc :: TextEnvelopeDescr skeyDesc = "KES Signing Key" @@ -124,10 +129,12 @@ runNodeKeyGenVRF (VerificationKeyFile vkeyPath) (SigningKeyFile skeyPath) = do let vkey = getVerificationKey skey firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelopeWithOwnerPermissions skeyPath (Just skeyDesc) skey + $ writeLazyByteStringFileWithOwnerPermissions skeyPath + $ textEnvelopeToJSON (Just skeyDesc) skey firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope vkeyPath (Just vkeyDesc) vkey + $ writeLazyByteStringFile vkeyPath + $ textEnvelopeToJSON (Just vkeyDesc) vkey where skeyDesc, vkeyDesc :: TextEnvelopeDescr skeyDesc = "VRF Signing Key" @@ -161,8 +168,9 @@ runNodeNewCounter coldVerKeyOrFile counter let ocertIssueCounter = OperationalCertificateIssueCounter (fromIntegral counter) vkey - firstExceptT ShelleyNodeCmdWriteFileError . newExceptT $ - writeFileTextEnvelope ocertCtrPath Nothing ocertIssueCounter + firstExceptT ShelleyNodeCmdWriteFileError . newExceptT + $ writeLazyByteStringFile ocertCtrPath + $ textEnvelopeToJSON Nothing ocertIssueCounter runNodeIssueOpCert :: VerificationKeyOrFile KesKey @@ -210,14 +218,13 @@ runNodeIssueOpCert kesVerKeyOrFile -- a new cert but without updating the counter. firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope - ocertCtrPath - (Just $ ocertCtrDesc $ getCounter nextOcertCtr) - nextOcertCtr + $ writeLazyByteStringFile ocertCtrPath + $ textEnvelopeToJSON (Just $ ocertCtrDesc $ getCounter nextOcertCtr) nextOcertCtr firstExceptT ShelleyNodeCmdWriteFileError . newExceptT - $ writeFileTextEnvelope certFile Nothing ocert + $ writeLazyByteStringFile certFile + $ textEnvelopeToJSON Nothing ocert where getCounter :: OperationalCertificateIssueCounter -> Word64 getCounter (OperationalCertificateIssueCounter n _) = n diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Pool.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Pool.hs index 04793003a25..19530df820a 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Pool.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Pool.hs @@ -135,7 +135,8 @@ runStakePoolRegistrationCert firstExceptT ShelleyPoolCmdWriteFileError . newExceptT - $ writeFileTextEnvelope outfp (Just registrationCertDesc) registrationCert + $ writeLazyByteStringFile outfp + $ textEnvelopeToJSON (Just registrationCertDesc) registrationCert where registrationCertDesc :: TextEnvelopeDescr registrationCertDesc = "Stake Pool Registration Certificate" @@ -156,7 +157,8 @@ runStakePoolRetirementCert stakePoolVerKeyOrFile retireEpoch (OutputFile outfp) firstExceptT ShelleyPoolCmdWriteFileError . newExceptT - $ writeFileTextEnvelope outfp (Just retireCertDesc) retireCert + $ writeLazyByteStringFile outfp + $ textEnvelopeToJSON (Just retireCertDesc) retireCert where retireCertDesc :: TextEnvelopeDescr retireCertDesc = "Stake Pool Retirement Certificate" diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/StakeAddress.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/StakeAddress.hs index 9529c40285a..8254871371a 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/StakeAddress.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/StakeAddress.hs @@ -68,8 +68,8 @@ runStakeAddressKeyGenToFile (VerificationKeyFile vkFp) (SigningKeyFile skFp) = d let vkey = getVerificationKey skey firstExceptT ShelleyStakeAddressCmdWriteFileError $ do - newExceptT $ writeFileTextEnvelope skFp (Just skeyDesc) skey - newExceptT $ writeFileTextEnvelope vkFp (Just vkeyDesc) vkey + newExceptT $ writeLazyByteStringFile skFp $ textEnvelopeToJSON (Just skeyDesc) skey + newExceptT $ writeLazyByteStringFile vkFp $ textEnvelopeToJSON (Just vkeyDesc) vkey runStakeAddressKeyHash :: VerificationKeyOrFile StakeKey @@ -116,7 +116,8 @@ runStakeCredentialRegistrationCert stakeIdentifier (OutputFile oFp) = do let deRegCert = makeStakeAddressRegistrationCertificate sCred firstExceptT ShelleyStakeAddressCmdWriteFileError . newExceptT - $ writeFileTextEnvelope oFp (Just regCertDesc) deRegCert + $ writeLazyByteStringFile oFp + $ textEnvelopeToJSON (Just regCertDesc) deRegCert regCertDesc :: TextEnvelopeDescr regCertDesc = "Stake Address Registration Certificate" @@ -147,7 +148,8 @@ runStakeCredentialDelegationCert stakeVerifier poolVKeyOrHashOrFile (OutputFile let delegCert = makeStakeAddressDelegationCertificate sCred poolStakeVKeyHash firstExceptT ShelleyStakeAddressCmdWriteFileError . newExceptT - $ writeFileTextEnvelope outFp (Just delegCertDesc) delegCert + $ writeLazyByteStringFile outFp + $ textEnvelopeToJSON (Just delegCertDesc) delegCert delegCertDesc :: TextEnvelopeDescr delegCertDesc = "Stake Address Delegation Certificate" @@ -169,7 +171,8 @@ runStakeCredentialDeRegistrationCert stakeVerifier (OutputFile oFp) = do let deRegCert = makeStakeAddressDeregistrationCertificate sCred firstExceptT ShelleyStakeAddressCmdWriteFileError . newExceptT - $ writeFileTextEnvelope oFp (Just deregCertDesc) deRegCert + $ writeLazyByteStringFile oFp + $ textEnvelopeToJSON (Just deregCertDesc) deRegCert deregCertDesc :: TextEnvelopeDescr deregCertDesc = "Stake Address Deregistration Certificate" diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs index ac5f3ecf220..9f823ed00b1 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Transaction.hs @@ -1102,8 +1102,9 @@ runTxSign txOrTxBody witSigningData mnw (TxFile outTxFile) = do let shelleyKeyWitnesses = map (makeShelleyKeyWitness txbody) sksShelley tx = makeSignedTransaction (byronWitnesses ++ shelleyKeyWitnesses) txbody - firstExceptT ShelleyTxCmdWriteFileError . newExceptT $ - writeFileTextEnvelope outTxFile Nothing tx + firstExceptT ShelleyTxCmdWriteFileError . newExceptT + $ writeLazyByteStringFile outTxFile + $ textEnvelopeToJSON Nothing tx -- ---------------------------------------------------------------------------- -- Transaction submission @@ -1392,7 +1393,8 @@ runTxCreateWitness (TxBodyFile txbodyFilePath) witSignData mbNw (OutputFile oFil pure $ makeShelleyKeyWitness txbody skShelley firstExceptT ShelleyTxCmdWriteFileError . newExceptT - $ writeFileTextEnvelope oFile Nothing witness + $ writeLazyByteStringFile oFile + $ textEnvelopeToJSON Nothing witness runTxSignWitness :: TxBodyFile @@ -1421,7 +1423,8 @@ runTxSignWitness (TxBodyFile txbodyFilePath) witnessFiles (OutputFile oFp) = do let tx = makeSignedTransaction witnesses txbody firstExceptT ShelleyTxCmdWriteFileError . newExceptT - $ writeFileTextEnvelope oFp Nothing tx + $ writeLazyByteStringFile oFp + $ textEnvelopeToJSON Nothing tx IncompleteCddlFormattedTx (InAnyCardanoEra era anyTx) -> do let txbody = getTxBody anyTx diff --git a/cardano-node/test/Test/Cardano/Node/FilePermissions.hs b/cardano-node/test/Test/Cardano/Node/FilePermissions.hs index b0970712047..e3a282604ef 100644 --- a/cardano-node/test/Test/Cardano/Node/FilePermissions.hs +++ b/cardano-node/test/Test/Cardano/Node/FilePermissions.hs @@ -18,21 +18,21 @@ import System.Directory (removeFile) import Cardano.Api import Cardano.Node.Run (checkVRFFilePermissions) import Control.Exception (bracket) -import Control.Monad (Monad(..)) -import Control.Monad.Except(MonadIO(liftIO), runExceptT ) +import Control.Monad (Monad (..)) +import Control.Monad.Except (MonadIO (liftIO), runExceptT) import Data.Bool (Bool, not) -import Data.Either (Either(..)) +import Data.Either (Either (..)) import Data.Eq ((==)) import Data.Foldable (foldl', length) -import Data.Function (($), (.), const) -import Data.Maybe (Maybe(..)) -import Data.Semigroup (Semigroup(..)) +import Data.Function (const, ($), (.)) import qualified Data.List as L +import Data.Maybe (Maybe (..)) +import Data.Semigroup (Semigroup (..)) import Hedgehog (Property, PropertyT, property, success) import qualified Hedgehog import Hedgehog.Internal.Property (Group (..), failWith) import System.IO (FilePath, IO) -import Text.Show (Show(..)) +import Text.Show (Show (..)) #ifdef UNIX import Cardano.Node.Types (VRFPrivateKeyFilePermissionError (..)) @@ -63,7 +63,7 @@ prop_createVRFFileWithOwnerPermissions = createFileWithOwnerPermissions :: HasTextEnvelope a => FilePath -> a -> PropertyT IO () createFileWithOwnerPermissions targetfp value = do - result <- liftIO $ writeFileTextEnvelopeWithOwnerPermissions targetfp Nothing value + result <- liftIO $ writeLazyByteStringFileWithOwnerPermissions targetfp $ textEnvelopeToJSON Nothing value case result of Left err -> failWith Nothing $ displayError err Right () -> return ()