@@ -33,19 +33,19 @@ import Cardano.Network.PeerSelection.Bootstrap
3333import Cardano.Network.PeerSelection.PeerTrustable
3434import qualified Cardano.Node.Configuration.Topology as NonP2P
3535import qualified Cardano.Node.Configuration.TopologyP2P as P2P
36+ import Cardano.Node.Protocol.Byron
3637import Ouroboros.Network.NodeToNode (DiffusionMode (.. ))
3738import Ouroboros.Network.PeerSelection.LedgerPeers
3839import Ouroboros.Network.PeerSelection.State.LocalRootPeers
3940
40- import Control.Exception.Safe ( MonadCatch )
41+ import Control.Exception
4142import Control.Monad
4243import Control.Monad.Extra
4344import Data.Aeson
4445import qualified Data.Aeson as Aeson
4546import qualified Data.Aeson.Encode.Pretty as A
4647import Data.Aeson.Key hiding (fromString )
4748import Data.Aeson.KeyMap hiding (map )
48- import Data.Bifunctor (first )
4949import qualified Data.ByteString as BS
5050import qualified Data.ByteString.Lazy as LBS
5151import qualified Data.List as List
@@ -57,25 +57,25 @@ import Data.Word (Word64)
5757import GHC.Stack (HasCallStack )
5858import qualified GHC.Stack as GHC
5959import qualified Network.HTTP.Simple as HTTP
60+ import RIO ( MonadThrow , throwM )
6061import qualified System.Directory as System
6162import System.FilePath.Posix (takeDirectory , (</>) )
6263
64+
6365import Testnet.Blockfrost (blockfrostToGenesis )
6466import qualified Testnet.Defaults as Defaults
6567import Testnet.Filepath
66- import Testnet.Process.Run (execCli_ )
68+ import Testnet.Process.RunIO (execCli_ , liftIOAnnotated )
6769import Testnet.Start.Types
6870
69- import Hedgehog
70- import qualified Hedgehog as H
7171import qualified Hedgehog.Extras.Stock.OS as OS
7272import qualified Hedgehog.Extras.Stock.Time as DTC
73- import qualified Hedgehog.Extras.Test.Base as H
74- import qualified Hedgehog.Extras.Test.File as H
7573
7674-- | Returns JSON encoded hashes of the era, as well as the hard fork configuration toggle.
7775createConfigJson :: ()
78- => (MonadTest m , MonadIO m , HasCallStack )
76+ => HasCallStack
77+ => MonadIO m
78+ => MonadThrow m
7979 => TmpAbsolutePath
8080 -> ShelleyBasedEra era -- ^ The era used for generating the hard fork configuration toggle
8181 -> m (KeyMap Aeson. Value )
@@ -93,7 +93,7 @@ createConfigJson (TmpAbsolutePath tempAbsPath) sbe = GHC.withFrozenCallStack $ d
9393 , Defaults. defaultYamlHardforkViaConfig sbe
9494 ]
9595 where
96- getHash :: ( MonadTest m , MonadIO m ) => CardanoEra a -> Text. Text -> m (KeyMap Value )
96+ getHash :: MonadIO m => CardanoEra a -> Text. Text -> m (KeyMap Value )
9797 getHash e = getShelleyGenesisHash (tempAbsPath </> Defaults. defaultGenesisFilepath e)
9898
9999createConfigJsonNoHash :: ()
@@ -104,22 +104,25 @@ createConfigJsonNoHash = Defaults.defaultYamlHardforkViaConfig
104104-- Generate hashes for genesis.json files
105105
106106getByronGenesisHash
107- :: (H. MonadTest m , MonadIO m )
107+ :: MonadIO m
108+ => MonadThrow m
108109 => FilePath
109110 -> m (KeyMap Aeson. Value )
110111getByronGenesisHash path = do
111112 e <- runExceptT $ readGenesisData path
112- (_, genesisHash) <- H. leftFail e
113- let genesisHash' = unGenesisHash genesisHash
114- pure . singleton " ByronGenesisHash" $ toJSON genesisHash'
113+ case e of
114+ Left err -> throwM $ GenesisReadError path err
115+ Right (_, genesisHash) -> do
116+ let genesisHash' = unGenesisHash genesisHash
117+ pure . singleton " ByronGenesisHash" $ toJSON genesisHash'
115118
116119getShelleyGenesisHash
117- :: ( H. MonadTest m , MonadIO m )
120+ :: MonadIO m
118121 => FilePath
119122 -> Text
120123 -> m (KeyMap Aeson. Value )
121124getShelleyGenesisHash path key = do
122- content <- H. evalIO $ BS. readFile path
125+ content <- liftIOAnnotated $ BS. readFile path
123126 let genesisHash = Crypto. hashWith id content :: Crypto. Hash Crypto. Blake2b_256 BS. ByteString
124127 pure . singleton (fromText key) $ toJSON genesisHash
125128
@@ -130,32 +133,35 @@ startTimeOffsetSeconds = if OS.isWin32 then 90 else 15
130133
131134-- | A start time and 'ShelleyGenesis' value that are fit to pass to 'cardanoTestnet'
132135getDefaultShelleyGenesis :: ()
133- => HasCallStack
134136 => MonadIO m
135- => MonadTest m
136137 => AnyShelleyBasedEra
137138 -> Word64 -- ^ The max supply
138139 -> GenesisOptions
139140 -> m ShelleyGenesis
140141getDefaultShelleyGenesis asbe maxSupply opts = do
141- currentTime <- H. noteShowIO DTC. getCurrentTime
142- startTime <- H. noteShow $ DTC. addUTCTime startTimeOffsetSeconds currentTime
142+ currentTime <- liftIOAnnotated DTC. getCurrentTime
143+ let startTime = DTC. addUTCTime startTimeOffsetSeconds currentTime
143144 return $ Defaults. defaultShelleyGenesis asbe startTime maxSupply opts
144145
145146-- | An 'AlonzoGenesis' value that is fit to pass to 'cardanoTestnet'
146147getDefaultAlonzoGenesis :: ()
147148 => HasCallStack
148- => MonadTest m
149+ => MonadThrow m
149150 => ShelleyBasedEra era
150151 -> m AlonzoGenesis
151152getDefaultAlonzoGenesis sbe =
152- H. evalEither $ first prettyError (Defaults. defaultAlonzoGenesis sbe)
153+ case Defaults. defaultAlonzoGenesis sbe of
154+ Right genesis -> return genesis
155+ Left err -> throwM err
156+
153157
154158numSeededUTxOKeys :: Int
155159numSeededUTxOKeys = 3
156160
157161createSPOGenesisAndFiles
158- :: (MonadTest m , MonadCatch m , MonadIO m , HasCallStack )
162+ :: MonadIO m
163+ => HasCallStack
164+ => MonadThrow m
159165 => CardanoTestnetOptions -- ^ The options to use
160166 -> GenesisOptions
161167 -> TestnetOnChainParams
@@ -164,11 +170,12 @@ createSPOGenesisAndFiles
164170createSPOGenesisAndFiles
165171 testnetOptions genesisOptions@ GenesisOptions {genesisTestnetMagic}
166172 onChainParams
167- (TmpAbsolutePath tempAbsPath) = GHC. withFrozenCallStack $ do
173+ (TmpAbsolutePath tempAbsPath) = do
168174 AnyShelleyBasedEra sbe <- pure cardanoNodeEra
169175
170176 let genesisShelleyDirAbs = takeDirectory inputGenesisShelleyFp
171- genesisShelleyDir <- H. createDirectoryIfMissing genesisShelleyDirAbs
177+
178+ genesisShelleyDir <- liftIOAnnotated $ System. createDirectoryIfMissing True genesisShelleyDirAbs >> pure genesisShelleyDirAbs
172179 let -- At least there should be a delegator per DRep
173180 -- otherwise some won't be representing anybody
174181 numStakeDelegators = max 3 (fromIntegral cardanoNumDReps) :: Int
@@ -184,23 +191,20 @@ createSPOGenesisAndFiles
184191 alonzoGenesis' <- getDefaultAlonzoGenesis sbe
185192 let conwayGenesis' = Defaults. defaultConwayGenesis
186193
187- (alonzoGenesis, conwayGenesis, shelleyGenesis) <- resolveOnChainParams onChainParams
188- (alonzoGenesis', conwayGenesis', shelleyGenesis')
194+ (alonzoGenesis, conwayGenesis, shelleyGenesis)
195+ <- resolveOnChainParams onChainParams
196+ (alonzoGenesis', conwayGenesis', shelleyGenesis')
189197
190198 -- Write Genesis files to disk, so they can be picked up by create-testnet-data
191- H. evalIO $ do
199+ liftIOAnnotated $ do
192200 LBS. writeFile inputGenesisAlonzoFp $ A. encodePretty alonzoGenesis
193201 LBS. writeFile inputGenesisConwayFp $ A. encodePretty conwayGenesis
194202 LBS. writeFile inputGenesisShelleyFp $ A. encodePretty shelleyGenesis
195203
196- H. note_ $ " Number of pools: " <> show nPoolNodes
197- H. note_ $ " Number of stake delegators: " <> show numStakeDelegators
198- H. note_ $ " Number of seeded UTxO keys: " <> show numSeededUTxOKeys
199-
200204 let era = toCardanoEra sbe
201205
202- currentTime <- H. noteShowIO DTC. getCurrentTime
203- startTime <- H. noteShow $ DTC. addUTCTime startTimeOffsetSeconds currentTime
206+ currentTime <- liftIOAnnotated DTC. getCurrentTime
207+ let startTime = DTC. addUTCTime startTimeOffsetSeconds currentTime
204208
205209 execCli_ $
206210 [ eraToString sbe, " genesis" , " create-testnet-data" ]
@@ -225,9 +229,6 @@ createSPOGenesisAndFiles
225229 ]
226230 (\ fp -> liftIO $ whenM (System. doesFileExist fp) (System. removeFile fp))
227231
228- files <- H. listDirectory tempAbsPath
229- forM_ files H. note
230-
231232 return genesisShelleyDir
232233 where
233234 inputGenesisShelleyFp = genesisInputFilepath ShelleyEra
@@ -287,23 +288,37 @@ mkTopologyConfig numNodes allPorts port True = A.encodePretty topologyP2P
287288 DontUseBootstrapPeers
288289 Nothing
289290
291+
292+ data BlockfrostParamsError = BlockfrostParamsDecodeError FilePath String
293+ deriving Show
294+
295+ instance Exception BlockfrostParamsError where
296+ displayException (BlockfrostParamsDecodeError fp err) =
297+ " Failed to decode Blockfrost on-chain parameters from file "
298+ <> fp
299+ <> " : "
300+ <> err
301+
290302-- | Resolves different kinds of user-provided on-chain parameters
291303-- into a unified, consistent set of Genesis files
292304resolveOnChainParams :: ()
293- => (MonadTest m , MonadIO m )
294305 => HasCallStack
306+ => MonadIO m
307+ => MonadThrow m
295308 => TestnetOnChainParams
296309 -> (AlonzoGenesis , ConwayGenesis , ShelleyGenesis )
297310 -> m (AlonzoGenesis , ConwayGenesis , ShelleyGenesis )
298311resolveOnChainParams onChainParams geneses = case onChainParams of
299312
300- DefaultParams -> pure geneses
313+ DefaultParams -> do
314+ pure geneses
301315
302316 OnChainParamsFile file -> do
303- eParams <- H. readJsonFile file
304- params <- H. leftFail eParams
305- pure $ blockfrostToGenesis geneses params
317+ eParams <- eitherDecode <$> liftIOAnnotated (LBS. readFile file)
318+ case eParams of
319+ Right params -> pure $ blockfrostToGenesis geneses params
320+ Left err -> throwM $ BlockfrostParamsDecodeError file err
306321
307322 OnChainParamsMainnet -> do
308- mainnetParams <- H. evalIO $ HTTP. getResponseBody <$> HTTP. httpJSON mainnetParamsRequest
323+ mainnetParams <- liftIOAnnotated $ HTTP. getResponseBody <$> HTTP. httpJSON mainnetParamsRequest
309324 pure $ blockfrostToGenesis geneses mainnetParams
0 commit comments