@@ -33,19 +33,18 @@ 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 )
4141import Control.Monad
4242import Control.Monad.Extra
4343import Data.Aeson
4444import qualified Data.Aeson as Aeson
4545import qualified Data.Aeson.Encode.Pretty as A
4646import Data.Aeson.Key hiding (fromString )
4747import Data.Aeson.KeyMap hiding (map )
48- import Data.Bifunctor (first )
4948import qualified Data.ByteString as BS
5049import qualified Data.ByteString.Lazy as LBS
5150import qualified Data.List as List
@@ -57,25 +56,26 @@ import Data.Word (Word64)
5756import GHC.Stack (HasCallStack )
5857import qualified GHC.Stack as GHC
5958import qualified Network.HTTP.Simple as HTTP
59+ import RIO (Exception (.. ), MonadThrow , throwM )
6060import qualified System.Directory as System
6161import System.FilePath.Posix (takeDirectory , (</>) )
6262
63+
6364import Testnet.Blockfrost (blockfrostToGenesis )
6465import qualified Testnet.Defaults as Defaults
6566import Testnet.Filepath
66- import Testnet.Process.Run (execCli_ )
67+ import Testnet.Process.NewRun (execCli_ )
6768import Testnet.Start.Types
6869
69- import Hedgehog
70- import qualified Hedgehog as H
7170import qualified Hedgehog.Extras.Stock.OS as OS
7271import 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
72+
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 <- liftIO $ 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,44 @@ 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 <- liftIO 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
161+ -- TODO: So that we don't lose
162+ -- logging power. We should catch the exception
163+ -- and use the MonadTest instance of the Integration
164+ -- monad to log the exception and also log additional
165+ -- information from the function.
166+ -- Once we lift to Integration monad we can
167+ -- use the various hedgehog-extra functions
168+ -- for logging purposes. No reason for the annotations
169+ -- to be littered within the functions
157170createSPOGenesisAndFiles
158- :: (MonadTest m , MonadCatch m , MonadIO m , HasCallStack )
171+ :: MonadIO m
172+ => HasCallStack
173+ => MonadThrow m
159174 => CardanoTestnetOptions -- ^ The options to use
160175 -> GenesisOptions
161176 -> TestnetOnChainParams
@@ -168,7 +183,8 @@ createSPOGenesisAndFiles
168183 AnyShelleyBasedEra sbe <- pure cardanoNodeEra
169184
170185 let genesisShelleyDirAbs = takeDirectory inputGenesisShelleyFp
171- genesisShelleyDir <- H. createDirectoryIfMissing genesisShelleyDirAbs
186+
187+ genesisShelleyDir <- liftIO $ System. createDirectoryIfMissing True genesisShelleyDirAbs >> pure genesisShelleyDirAbs
172188 let -- At least there should be a delegator per DRep
173189 -- otherwise some won't be representing anybody
174190 numStakeDelegators = max 3 (fromIntegral cardanoNumDReps) :: Int
@@ -184,23 +200,25 @@ createSPOGenesisAndFiles
184200 alonzoGenesis' <- getDefaultAlonzoGenesis sbe
185201 let conwayGenesis' = Defaults. defaultConwayGenesis
186202
187- (alonzoGenesis, conwayGenesis, shelleyGenesis) <- resolveOnChainParams onChainParams
188- (alonzoGenesis', conwayGenesis', shelleyGenesis')
203+ (alonzoGenesis, conwayGenesis, shelleyGenesis)
204+ <- resolveOnChainParams onChainParams
205+ (alonzoGenesis', conwayGenesis', shelleyGenesis')
189206
190207 -- Write Genesis files to disk, so they can be picked up by create-testnet-data
191- H. evalIO $ do
208+ -- H.evalIO $ do
209+ liftIO $ do
192210 LBS. writeFile inputGenesisAlonzoFp $ A. encodePretty alonzoGenesis
193211 LBS. writeFile inputGenesisConwayFp $ A. encodePretty conwayGenesis
194212 LBS. writeFile inputGenesisShelleyFp $ A. encodePretty shelleyGenesis
195213
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
214+ -- TODO: H.note_ $ "Number of pools: " <> show nPoolNodes
215+ -- TODO: H.note_ $ "Number of stake delegators: " <> show numStakeDelegators
216+ -- TODO: H.note_ $ "Number of seeded UTxO keys: " <> show numSeededUTxOKeys
199217
200218 let era = toCardanoEra sbe
201219
202- currentTime <- H. noteShowIO DTC. getCurrentTime
203- startTime <- H. noteShow $ DTC. addUTCTime startTimeOffsetSeconds currentTime
220+ currentTime <- liftIO DTC. getCurrentTime
221+ let startTime = DTC. addUTCTime startTimeOffsetSeconds currentTime
204222
205223 execCli_ $
206224 [ eraToString sbe, " genesis" , " create-testnet-data" ]
@@ -225,8 +243,8 @@ createSPOGenesisAndFiles
225243 ]
226244 (\ fp -> liftIO $ whenM (System. doesFileExist fp) (System. removeFile fp))
227245
228- files <- H . listDirectory tempAbsPath
229- forM_ files H. note
246+ _files <- liftIO $ System . listDirectory tempAbsPath
247+ -- forM_ files H.note
230248
231249 return genesisShelleyDir
232250 where
@@ -287,11 +305,23 @@ mkTopologyConfig numNodes allPorts port True = A.encodePretty topologyP2P
287305 DontUseBootstrapPeers
288306 Nothing
289307
308+
309+ data BlockfrostParamsError = BlockfrostParamsDecodeError FilePath String
310+ deriving Show
311+
312+ instance Exception BlockfrostParamsError where
313+ displayException (BlockfrostParamsDecodeError fp err) =
314+ " Failed to decode Blockfrost on-chain parameters from file "
315+ <> fp
316+ <> " : "
317+ <> err
318+
290319-- | Resolves different kinds of user-provided on-chain parameters
291320-- into a unified, consistent set of Genesis files
292321resolveOnChainParams :: ()
293- => (MonadTest m , MonadIO m )
294322 => HasCallStack
323+ => MonadIO m
324+ => MonadThrow m
295325 => TestnetOnChainParams
296326 -> (AlonzoGenesis , ConwayGenesis , ShelleyGenesis )
297327 -> m (AlonzoGenesis , ConwayGenesis , ShelleyGenesis )
@@ -300,10 +330,11 @@ resolveOnChainParams onChainParams geneses = case onChainParams of
300330 DefaultParams -> pure geneses
301331
302332 OnChainParamsFile file -> do
303- eParams <- H. readJsonFile file
304- params <- H. leftFail eParams
305- pure $ blockfrostToGenesis geneses params
333+ eParams <- eitherDecode <$> liftIO (LBS. readFile file)
334+ case eParams of
335+ Right params -> pure $ blockfrostToGenesis geneses params
336+ Left err -> throwM $ BlockfrostParamsDecodeError file err
306337
307338 OnChainParamsMainnet -> do
308- mainnetParams <- H. evalIO $ HTTP. getResponseBody <$> HTTP. httpJSON mainnetParamsRequest
339+ mainnetParams <- liftIO $ HTTP. getResponseBody <$> HTTP. httpJSON mainnetParamsRequest
309340 pure $ blockfrostToGenesis geneses mainnetParams
0 commit comments