Skip to content

Commit b5ecb30

Browse files
authored
Merge pull request #1267 from IntersectMBO/jordan/fix-legacy-genesis-creation
Fix legacy genesis creation
2 parents 8030676 + 78d9e03 commit b5ecb30

14 files changed

Lines changed: 922 additions & 56 deletions

File tree

‎cardano-cli/cardano-cli.cabal‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,11 @@ test-suite cardano-cli-golden
436436
cardano-cli,
437437
cardano-cli:cardano-cli-test-lib,
438438
cardano-crypto-wrapper,
439+
cardano-ledger-alonzo,
440+
cardano-ledger-core,
439441
cardano-strict-containers ^>=0.1,
440442
cborg,
443+
containers,
441444
directory,
442445
exceptions,
443446
extra,
@@ -478,6 +481,7 @@ test-suite cardano-cli-golden
478481
Test.Golden.Help
479482
Test.Golden.Key.NonExtendedKey
480483
Test.Golden.Latest.Transaction.CalculateMinFee
484+
Test.Golden.Legacy.Genesis.Create
481485
Test.Golden.Shelley.Address.Build
482486
Test.Golden.Shelley.Address.Info
483487
Test.Golden.Shelley.Address.KeyGen

‎cardano-cli/src/Cardano/CLI/EraBased/Genesis/Command.hs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ data GenesisCmds era
4545
deriving Show
4646

4747
data GenesisCreateCmdArgs era = GenesisCreateCmdArgs
48-
{ eon :: !(Exp.Era era)
48+
{ eon :: !AnyShelleyBasedEra
4949
, keyOutputFormat :: !(Vary [FormatBech32, FormatTextEnvelope])
5050
, genesisDir :: !GenesisDir
5151
, numGenesisKeys :: !Word

‎cardano-cli/src/Cardano/CLI/EraBased/Genesis/Option.hs‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{-# LANGUAGE FlexibleContexts #-}
33
{-# LANGUAGE GADTs #-}
44
{-# LANGUAGE NumericUnderscores #-}
5+
{-# LANGUAGE RankNTypes #-}
56
{-# LANGUAGE ScopedTypeVariables #-}
67
{-# LANGUAGE TypeApplications #-}
78

@@ -187,17 +188,18 @@ pGenesisCreateCardano envCli =
187188
"JSON file with genesis defaults for conway."
188189
<*> pNodeConfigTemplate
189190

190-
pGenesisCreate :: Exp.IsEra era => EnvCli -> Parser (GenesisCmds era)
191+
pGenesisCreate :: forall era. Exp.IsEra era => EnvCli -> Parser (GenesisCmds era)
191192
pGenesisCreate envCli =
192-
fmap GenesisCreate $
193-
GenesisCreateCmdArgs (convert Exp.useEra)
194-
<$> pKeyOutputFormat
195-
<*> pGenesisDir
196-
<*> pGenesisNumGenesisKeys
197-
<*> pGenesisNumUTxOKeys
198-
<*> pMaybeSystemStart
199-
<*> pInitialSupplyNonDelegated
200-
<*> pNetworkId envCli
193+
let sbe :: ShelleyBasedEra era = convert Exp.useEra
194+
in fmap GenesisCreate $
195+
GenesisCreateCmdArgs (shelleyBasedEraConstraints sbe $ AnyShelleyBasedEra sbe)
196+
<$> pKeyOutputFormat
197+
<*> pGenesisDir
198+
<*> pGenesisNumGenesisKeys
199+
<*> pGenesisNumUTxOKeys
200+
<*> pMaybeSystemStart
201+
<*> pInitialSupplyNonDelegated
202+
<*> pNetworkId envCli
201203

202204
pGenesisCreateStaked :: Exp.IsEra era => EnvCli -> Parser (GenesisCmds era)
203205
pGenesisCreateStaked envCli =

‎cardano-cli/src/Cardano/CLI/EraBased/Genesis/Run.hs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,13 @@ runGenesisCreateCmd
241241
, Cmd.mSupply
242242
, Cmd.network
243243
} = do
244+
AnyShelleyBasedEra sbe <- return eon
244245
let GenesisDir rootdir = genesisDir
245246
gendir = rootdir </> "genesis-keys"
246247
deldir = rootdir </> "delegate-keys"
247248
utxodir = rootdir </> "utxo-keys"
248-
era = toCardanoEra eon
249+
250+
era = toCardanoEra sbe
249251
liftIO $ do
250252
createDirectoryIfMissing False rootdir
251253
createDirectoryIfMissing False gendir

‎cardano-cli/src/Cardano/CLI/EraBased/Query/Run.hs‎

Lines changed: 82 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -133,28 +133,28 @@ runQueryProtocolParametersCmd
133133
, Cmd.outputFormat
134134
, Cmd.mOutFile
135135
} = do
136-
AnyCardanoEra cEra <- fromExceptTCli $ determineEra nodeConnInfo
137-
era <- fromExceptTCli $ supportedEra cEra
136+
anyCEra@(AnyCardanoEra cEra) <- fromExceptTCli $ determineEra nodeConnInfo
137+
case forEraInEonMaybe cEra id of
138+
Nothing -> throwCliError $ QueryCmdEraNotSupported anyCEra
139+
Just sbe -> do
140+
let qInMode = QueryInEra $ QueryInShelleyBasedEra sbe Api.QueryProtocolParameters
138141

139-
let sbe = convert era
140-
qInMode = QueryInEra $ QueryInShelleyBasedEra sbe Api.QueryProtocolParameters
141-
142-
pparams <-
143-
fromExceptTCli $
144-
executeQueryAnyMode nodeConnInfo qInMode
142+
pparams <-
143+
fromExceptTCli $
144+
executeQueryAnyMode nodeConnInfo qInMode
145145

146-
let output =
147-
Exp.obtainCommonConstraints era
148-
$ outputFormat
149-
& ( id
150-
. Vary.on (\FormatJson -> Json.encodeJson)
151-
. Vary.on (\FormatYaml -> Json.encodeYaml)
152-
$ Vary.exhaustiveCase
153-
)
154-
$ pparams
146+
let output =
147+
shelleyBasedEraConstraints sbe
148+
$ outputFormat
149+
& ( id
150+
. Vary.on (\FormatJson -> Json.encodeJson)
151+
. Vary.on (\FormatYaml -> Json.encodeYaml)
152+
$ Vary.exhaustiveCase
153+
)
154+
$ pparams
155155

156-
fromEitherIOCli @(FileError ()) $
157-
writeLazyByteStringOutput mOutFile output
156+
fromEitherIOCli @(FileError ()) $
157+
writeLazyByteStringOutput mOutFile output
158158

159159
-- | Calculate the percentage sync rendered as text: @min 1 (tipTime/nowTime)@
160160
percentage
@@ -316,12 +316,13 @@ runQueryUTxOCmd
316316
) = do
317317
fromEitherIOCli
318318
( executeLocalStateQueryExpr nodeConnInfo target $ runExceptT $ do
319-
AnyCardanoEra cEra <- easyRunQueryCurrentEra
319+
anyCEra@(AnyCardanoEra cEra) <- easyRunQueryCurrentEra
320320

321-
era <- hoist liftIO $ supportedEra cEra
322-
323-
utxo <- easyRunQuery (queryUtxo (convert era) queryFilter)
324-
hoist liftIO $ writeFilteredUTxOs era outputFormat mOutFile utxo
321+
case forEraInEonMaybe cEra id of
322+
Nothing -> throwCliError $ QueryCmdEraNotSupported anyCEra
323+
Just sbe -> do
324+
utxo <- easyRunQuery (queryUtxo sbe queryFilter)
325+
hoist liftIO $ writeFilteredUTxOs sbe outputFormat mOutFile utxo
325326
)
326327
& fromEitherCIOCli
327328

@@ -1199,20 +1200,20 @@ writePoolState outputFormat mOutFile serialisedCurrentEpochState = do
11991200
$ writeLazyByteStringOutput mOutFile output
12001201

12011202
writeFilteredUTxOs
1202-
:: Exp.Era era
1203+
:: ShelleyBasedEra era
12031204
-> Vary [FormatCborBin, FormatCborHex, FormatJson, FormatText, FormatYaml]
12041205
-> Maybe (File () Out)
12051206
-> UTxO era
12061207
-> ExceptT QueryCmdError IO ()
12071208
writeFilteredUTxOs era format mOutFile utxo = do
12081209
let output =
1209-
Exp.obtainCommonConstraints era $
1210+
shelleyBasedEraConstraints era $
12101211
format
12111212
& ( id
1212-
. Vary.on (\FormatCborBin -> CBOR.serialize $ toLedgerUTxO (convert era) utxo)
1213-
. Vary.on (\FormatCborHex -> Base16.encode . CBOR.serialize $ toLedgerUTxO (convert era) utxo)
1213+
. Vary.on (\FormatCborBin -> CBOR.serialize $ toLedgerUTxO era utxo)
1214+
. Vary.on (\FormatCborHex -> Base16.encode . CBOR.serialize $ toLedgerUTxO era utxo)
12141215
. Vary.on (\FormatJson -> Json.encodeJson utxo)
1215-
. Vary.on (\FormatText -> strictTextToLazyBytestring $ filteredUTxOsToText (convert era) utxo)
1216+
. Vary.on (\FormatText -> strictTextToLazyBytestring $ filteredUTxOsToText era utxo)
12161217
. Vary.on (\FormatYaml -> Json.encodeYaml utxo)
12171218
$ Vary.exhaustiveCase
12181219
)
@@ -1221,26 +1222,71 @@ writeFilteredUTxOs era format mOutFile utxo = do
12211222
. newExceptT
12221223
$ writeLazyByteStringOutput mOutFile output
12231224

1224-
filteredUTxOsToText :: Exp.Era era -> UTxO era -> Text
1225-
filteredUTxOsToText era (UTxO utxo) = do
1225+
filteredUTxOsToText :: Api.ShelleyBasedEra era -> UTxO era -> Text
1226+
filteredUTxOsToText sbe (UTxO utxo) = do
12261227
mconcat
12271228
[ Text.unlines [title, Text.replicate (Text.length title + 2) "-"]
1228-
, Text.unlines $ case era of
1229-
Exp.ConwayEra ->
1230-
map (utxoToText era) $ toList utxo
1229+
, Text.unlines $ case sbe of
1230+
ShelleyBasedEraShelley ->
1231+
map (utxoToText sbe) $ toList utxo
1232+
ShelleyBasedEraAllegra ->
1233+
map (utxoToText sbe) $ toList utxo
1234+
ShelleyBasedEraMary ->
1235+
map (utxoToText sbe) $ toList utxo
1236+
ShelleyBasedEraAlonzo ->
1237+
map (utxoToText sbe) $ toList utxo
1238+
ShelleyBasedEraBabbage ->
1239+
map (utxoToText sbe) $ toList utxo
1240+
ShelleyBasedEraConway ->
1241+
map (utxoToText sbe) $ toList utxo
12311242
]
12321243
where
12331244
title :: Text
12341245
title =
12351246
" TxHash TxIx Amount"
12361247

12371248
utxoToText
1238-
:: Exp.Era era
1249+
:: Api.ShelleyBasedEra era
12391250
-> (TxIn, TxOut CtxUTxO era)
12401251
-> Text
12411252
utxoToText sbe txInOutTuple =
12421253
case sbe of
1243-
Exp.ConwayEra ->
1254+
ShelleyBasedEraShelley ->
1255+
let (TxIn (TxId txhash) (TxIx index), TxOut _ value _ _) = txInOutTuple
1256+
in mconcat
1257+
[ Text.decodeLatin1 (hashToBytesAsHex txhash)
1258+
, textShowN 6 index
1259+
, " " <> printableValue value
1260+
]
1261+
ShelleyBasedEraAllegra ->
1262+
let (TxIn (TxId txhash) (TxIx index), TxOut _ value _ _) = txInOutTuple
1263+
in mconcat
1264+
[ Text.decodeLatin1 (hashToBytesAsHex txhash)
1265+
, textShowN 6 index
1266+
, " " <> printableValue value
1267+
]
1268+
ShelleyBasedEraMary ->
1269+
let (TxIn (TxId txhash) (TxIx index), TxOut _ value _ _) = txInOutTuple
1270+
in mconcat
1271+
[ Text.decodeLatin1 (hashToBytesAsHex txhash)
1272+
, textShowN 6 index
1273+
, " " <> printableValue value
1274+
]
1275+
ShelleyBasedEraAlonzo ->
1276+
let (TxIn (TxId txhash) (TxIx index), TxOut _ value mDatum _) = txInOutTuple
1277+
in mconcat
1278+
[ Text.decodeLatin1 (hashToBytesAsHex txhash)
1279+
, textShowN 6 index
1280+
, " " <> printableValue value <> " + " <> Text.pack (show mDatum)
1281+
]
1282+
ShelleyBasedEraBabbage ->
1283+
let (TxIn (TxId txhash) (TxIx index), TxOut _ value mDatum _) = txInOutTuple
1284+
in mconcat
1285+
[ Text.decodeLatin1 (hashToBytesAsHex txhash)
1286+
, textShowN 6 index
1287+
, " " <> printableValue value <> " + " <> Text.pack (show mDatum)
1288+
]
1289+
ShelleyBasedEraConway ->
12441290
let (TxIn (TxId txhash) (TxIx index), TxOut _ value mDatum _) = txInOutTuple
12451291
in mconcat
12461292
[ Text.decodeLatin1 (hashToBytesAsHex txhash)

‎cardano-cli/src/Cardano/CLI/Legacy/Genesis/Command.hs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import Data.Word (Word64)
1919
import Vary (Vary)
2020

2121
data LegacyGenesisCmds
22-
= forall era. GenesisCreate
23-
(Era era)
22+
= GenesisCreate
23+
AnyShelleyBasedEra
2424
(Vary [FormatBech32, FormatTextEnvelope])
2525
GenesisDir
2626
Word

‎cardano-cli/src/Cardano/CLI/Legacy/Genesis/Run.hs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ runLegacyGenesisAddrCmd vkf nid mOf =
130130

131131
runLegacyGenesisCreateCmd
132132
:: ()
133-
=> Era era
133+
=> AnyShelleyBasedEra
134134
-> Vary [FormatBech32, FormatTextEnvelope]
135135
-> GenesisDir
136136
-> Word

‎cardano-cli/src/Cardano/CLI/Legacy/Option.hs‎

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ import Cardano.CLI.Parser
2828
import Cardano.CLI.Type.Common
2929
import Cardano.Ledger.BaseTypes (NonZero, knownNonZeroBounded)
3030

31+
import Data.Char (toLower)
3132
import Data.Foldable
32-
import Data.Maybe (fromMaybe)
33+
import Data.Maybe
3334
import Data.Word (Word64)
3435
import Options.Applicative hiding (help, str)
3536
import Options.Applicative qualified as Opt
@@ -192,7 +193,7 @@ pGenesisCmds envCli =
192193
pGenesisCreate :: Parser LegacyGenesisCmds
193194
pGenesisCreate =
194195
GenesisCreate
195-
<$> pConwayEra envCli
196+
<$> pShelleyBasedEra envCli
196197
<*> pKeyOutputFormat
197198
<*> pGenesisDir
198199
<*> pGenesisNumGenesisKeys
@@ -378,3 +379,25 @@ pGenesisCmds envCli =
378379
, Opt.help "Each bulk pool to contain this many pool credential sets [default is 0]."
379380
, Opt.value 0
380381
]
382+
383+
pShelleyBasedEra :: EnvCli -> Parser AnyShelleyBasedEra
384+
pShelleyBasedEra envCli =
385+
asum $
386+
[ shelleyBasedEraFlag era
387+
| era <- enumFrom minBound
388+
]
389+
++ (pure <$> maybeToList (envCliShelleyBasedEra envCli))
390+
where
391+
shelleyBasedEraFlag :: AnyShelleyBasedEra -> Parser AnyShelleyBasedEra
392+
shelleyBasedEraFlag era@(AnyShelleyBasedEra sbe) =
393+
let eraName = show . pretty $ toCardanoEra sbe
394+
in flag' era $
395+
mconcat
396+
[ long $ map toLower eraName
397+
, Opt.help $ "Specify the " <> eraName <> " era"
398+
]
399+
400+
envCliShelleyBasedEra :: EnvCli -> Maybe AnyShelleyBasedEra
401+
envCliShelleyBasedEra envCli = do
402+
AnyCardanoEra era <- envCliAnyCardanoEra envCli
403+
AnyShelleyBasedEra <$> forEraMaybeEon era
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
3+
module Test.Golden.Legacy.Genesis.Create where
4+
5+
import Cardano.Api qualified as H
6+
import Cardano.Api.Genesis
7+
8+
import Cardano.Ledger.Alonzo.Genesis (AlonzoGenesis (..))
9+
import Cardano.Ledger.Plutus.CostModels (costModelsValid, getCostModelParams)
10+
import Cardano.Ledger.Plutus.Language
11+
12+
import Control.Monad (void)
13+
import Data.ByteString.Char8 qualified as C8
14+
import Data.ByteString.Lazy qualified as LBS
15+
import Data.Map.Strict qualified as Map
16+
import System.FilePath ((</>))
17+
18+
import Test.Cardano.CLI.Util (execCardanoCLI, propertyOnce, watchdogProp)
19+
20+
import Hedgehog (Property)
21+
import Hedgehog qualified as H
22+
import Hedgehog.Extras.Test qualified as H
23+
24+
{- HLINT ignore "Use camelCase" -}
25+
26+
-- | QA needs the ability to generate a V2 cost model with 175 parameters in the Alonzo era
27+
hprop_golden_alonzo_genesis_v2_cost_model_has_175_parameters :: Property
28+
hprop_golden_alonzo_genesis_v2_cost_model_has_175_parameters =
29+
watchdogProp . propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do
30+
alonzoGenesisSpec <-
31+
H.note "test/cardano-cli-golden/files/input/genesis.alonzo.spec.json"
32+
shelleyGenesisSpec <-
33+
H.note "test/cardano-cli-golden/files/input/genesis.spec.json"
34+
35+
conwayGenesisSpec <-
36+
H.note "test/cardano-cli-golden/files/input/genesis.conway.spec.json"
37+
38+
outDir <- H.note $ tempDir </> "genesis-dir"
39+
40+
-- Copy genesis spec files to genesis output directory
41+
alonzoGenSpecBs <- H.readFile alonzoGenesisSpec
42+
shelleyGenSpecBs <- H.readFile shelleyGenesisSpec
43+
conwayGenesisSpecBs <- H.readFile conwayGenesisSpec
44+
45+
H.createDirectoryIfMissing_ outDir
46+
genAlonzoSpec <- H.noteTempFile outDir "genesis.alonzo.spec.json"
47+
genConwaySpec <- H.noteTempFile outDir "genesis.conway.spec.json"
48+
genShelleySpec <- H.noteTempFile outDir "genesis.spec.json"
49+
50+
H.writeFile genAlonzoSpec alonzoGenSpecBs
51+
H.writeFile genConwaySpec conwayGenesisSpecBs
52+
H.writeFile genShelleySpec shelleyGenSpecBs
53+
54+
-- Create genesis files
55+
void $
56+
execCardanoCLI
57+
[ "legacy"
58+
, "genesis"
59+
, "create"
60+
, "--alonzo"
61+
, "--genesis-dir"
62+
, outDir
63+
, "--mainnet"
64+
]
65+
66+
-- Read generated alonzo genesis file
67+
alonzoGenesisFp <- H.note $ outDir </> "genesis.alonzo.json"
68+
alonzoGenesisBs <- C8.pack <$> H.readFile alonzoGenesisFp
69+
70+
alonzoGenesisE <- H.liftIO . H.runExceptT $ decodeGen $ LBS.fromStrict alonzoGenesisBs
71+
AlonzoGenesis _ costModels _ _ _ _ _ _ <- H.evalEither alonzoGenesisE
72+
let v2CostModel = costModelsValid costModels
73+
mV2Params = Map.lookup PlutusV2 v2CostModel
74+
v2Params <- getCostModelParams <$> H.evalMaybe mV2Params
75+
76+
H.note_ $ "Cost model filepath: " <> alonzoGenesisFp
77+
length v2Params H.=== 175
78+
79+
decodeGen :: LBS.ByteString -> H.ExceptT String IO AlonzoGenesis
80+
decodeGen = decodeAlonzoGenesis (Just H.AlonzoEra)

0 commit comments

Comments
 (0)