Skip to content

Commit

Permalink
reorganized and stubbed eras
Browse files Browse the repository at this point in the history
  • Loading branch information
carbolymer committed Jul 12, 2024
1 parent 50b5133 commit 3de04f4
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 128 deletions.
3 changes: 2 additions & 1 deletion cardano-cli/cardano-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ library
Cardano.CLI.EraBased.Run
Cardano.CLI.EraBased.Run.Address
Cardano.CLI.EraBased.Run.Address.Info
Cardano.CLI.EraBased.Run.CreateTestnetData
Cardano.CLI.EraBased.Run.Genesis
Cardano.CLI.EraBased.Run.Genesis.Common
Cardano.CLI.EraBased.Run.Genesis.CreateTestnetData
Cardano.CLI.EraBased.Run.Governance
Cardano.CLI.EraBased.Run.Governance.Actions
Cardano.CLI.EraBased.Run.Governance.Committee
Expand Down
7 changes: 4 additions & 3 deletions cardano-cli/src/Cardano/CLI/EraBased/Commands/Genesis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Data.Text (Text)
data GenesisCmds era
= GenesisCreate !GenesisCreateCmdArgs
| GenesisCreateCardano !GenesisCreateCardanoCmdArgs
| GenesisCreateStaked !GenesisCreateStakedCmdArgs
| GenesisCreateStaked !(GenesisCreateStakedCmdArgs era)
| GenesisCreateTestNetData !(GenesisCreateTestNetDataCmdArgs era)
| GenesisKeyGenGenesis !GenesisKeyGenGenesisCmdArgs
| GenesisKeyGenDelegate !GenesisKeyGenDelegateCmdArgs
Expand Down Expand Up @@ -67,8 +67,9 @@ data GenesisCreateCardanoCmdArgs = GenesisCreateCardanoCmdArgs
, mNodeConfigTemplate :: !(Maybe FilePath)
} deriving Show

data GenesisCreateStakedCmdArgs = GenesisCreateStakedCmdArgs
{ keyOutputFormat :: !KeyOutputFormat
data GenesisCreateStakedCmdArgs era = GenesisCreateStakedCmdArgs
{ eon :: !(CardanoEra era)
, keyOutputFormat :: !KeyOutputFormat
, genesisDir :: !GenesisDir
, numGenesisKeys :: !Word
, numUTxOKeys :: !Word
Expand Down
8 changes: 4 additions & 4 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/Genesis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pGenesisCmds era envCli =
]
, Just
$ subParser "create-staked"
$ Opt.info (pGenesisCreateStaked envCli)
$ Opt.info (pGenesisCreateStaked era envCli)
$ Opt.progDesc
$ mconcat
[ "Create a staked Shelley genesis file from a genesis "
Expand Down Expand Up @@ -180,9 +180,9 @@ pGenesisCreate envCli =
<*> pInitialSupplyNonDelegated
<*> pNetworkId envCli

pGenesisCreateStaked :: EnvCli -> Parser (GenesisCmds era)
pGenesisCreateStaked envCli =
fmap GenesisCreateStaked $ GenesisCreateStakedCmdArgs
pGenesisCreateStaked :: CardanoEra era -> EnvCli -> Parser (GenesisCmds era)
pGenesisCreateStaked era envCli =
fmap GenesisCreateStaked $ GenesisCreateStakedCmdArgs era
<$> pKeyOutputFormat
<*> pGenesisDir
<*> pGenesisNumGenesisKeys
Expand Down
58 changes: 22 additions & 36 deletions cardano-cli/src/Cardano/CLI/EraBased/Run/Genesis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ import Cardano.CLI.Byron.Genesis as Byron
import qualified Cardano.CLI.Byron.Key as Byron
import Cardano.CLI.EraBased.Commands.Genesis as Cmd
import qualified Cardano.CLI.EraBased.Commands.Node as Cmd
import qualified Cardano.CLI.EraBased.Run.CreateTestnetData as TN
import Cardano.CLI.EraBased.Run.Genesis.Common
import qualified Cardano.CLI.EraBased.Run.Genesis.CreateTestnetData as TN
import Cardano.CLI.EraBased.Run.Node (runNodeIssueOpCertCmd, runNodeKeyGenColdCmd,
runNodeKeyGenKesCmd, runNodeKeyGenVrfCmd)
import Cardano.CLI.EraBased.Run.StakeAddress (runStakeAddressKeyGenCmd)
Expand Down Expand Up @@ -250,8 +251,8 @@ runGenesisCreateCmd
createDirectoryIfMissing False utxodir

template <- readShelleyGenesisWithDefault (rootdir </> "genesis.spec.json") adjustTemplate
alonzoGenesis <- readAlonzoGenesis (rootdir </> "genesis.alonzo.spec.json")
conwayGenesis <- readConwayGenesis (rootdir </> "genesis.conway.spec.json")
alonzoGenesis <- decodeAlonzoGenesisFile undefined $ rootdir </> "genesis.alonzo.spec.json" -- FIXME!!!
conwayGenesis <- decodeConwayGenesisFile $ rootdir </> "genesis.conway.spec.json"

forM_ [ 1 .. numGenesisKeys ] $ \index -> do
createGenesisKeys gendir index
Expand All @@ -262,7 +263,7 @@ runGenesisCreateCmd

genDlgs <- readGenDelegsMap gendir deldir
utxoAddrs <- readInitialFundAddresses utxodir network
start <- maybe (SystemStart <$> TN.getCurrentTimePlus30) pure mSystemStart
start <- maybe (SystemStart <$> getCurrentTimePlus30) pure mSystemStart

let shelleyGenesis =
updateTemplate
Expand Down Expand Up @@ -364,7 +365,7 @@ runGenesisCreateCardanoCmd
, Cmd.conwayGenesisTemplate
, Cmd.mNodeConfigTemplate
} = do
start <- maybe (SystemStart <$> TN.getCurrentTimePlus30) pure mSystemStart
start <- maybe (SystemStart <$> getCurrentTimePlus30) pure mSystemStart
(byronGenesis', byronSecrets) <- convertToShelleyError $ Byron.mkGenesis $ byronParams start
let
byronGenesis = byronGenesis'
Expand Down Expand Up @@ -403,9 +404,9 @@ runGenesisCreateCardanoCmd
, sgSystemStart = getSystemStart start
, sgSlotLength = L.secondsToNominalDiffTimeMicro $ MkFixed (fromIntegral slotLength) * 1_000
}
shelleyGenesisTemplate' <- overrideShelleyGenesis <$> TN.readAndDecodeGenesisFile shelleyGenesisTemplate
alonzoGenesis <- readAlonzoGenesis alonzoGenesisTemplate
conwayGenesis <- readConwayGenesis conwayGenesisTemplate
shelleyGenesisTemplate' <- overrideShelleyGenesis <$> decodeShelleyGenesisFile shelleyGenesisTemplate
alonzoGenesis <- decodeAlonzoGenesisFile undefined alonzoGenesisTemplate -- FIXME!!!
conwayGenesis <- decodeConwayGenesisFile conwayGenesisTemplate
(delegateMap, vrfKeys, kesKeys, opCerts) <- liftIO $ generateShelleyNodeSecrets shelleyDelegateKeys shelleyGenesisvkeys
let
shelleyGenesis :: ShelleyGenesis L.StandardCrypto
Expand Down Expand Up @@ -510,11 +511,12 @@ runGenesisCreateCardanoCmd
dlgCertMap byronGenesis = Genesis.unGenesisDelegation $ Genesis.gdHeavyDelegation byronGenesis

runGenesisCreateStakedCmd
:: GenesisCreateStakedCmdArgs
:: GenesisCreateStakedCmdArgs era
-> ExceptT GenesisCmdError IO ()
runGenesisCreateStakedCmd
Cmd.GenesisCreateStakedCmdArgs
{ Cmd.keyOutputFormat
{ eon = era
, Cmd.keyOutputFormat
, Cmd.genesisDir
, Cmd.numGenesisKeys
, Cmd.numUTxOKeys
Expand Down Expand Up @@ -545,8 +547,8 @@ runGenesisCreateStakedCmd
createDirectoryIfMissing False utxodir

template <- readShelleyGenesisWithDefault (rootdir </> "genesis.spec.json") adjustTemplate
alonzoGenesis <- readAlonzoGenesis (rootdir </> "genesis.alonzo.spec.json")
conwayGenesis <- readConwayGenesis (rootdir </> "genesis.conway.spec.json")
alonzoGenesis <- decodeAlonzoGenesisFile (Just era) $ rootdir </> "genesis.alonzo.spec.json"
conwayGenesis <- decodeConwayGenesisFile $ rootdir </> "genesis.conway.spec.json"

forM_ [ 1 .. numGenesisKeys ] $ \index -> do
createGenesisKeys gendir index
Expand All @@ -555,11 +557,11 @@ runGenesisCreateStakedCmd
forM_ [ 1 .. numUTxOKeys ] $ \index ->
createUtxoKeys utxodir index

mayStakePoolRelays <- forM mStakePoolRelaySpecFile TN.readRelays
mStakePoolRelays <- forM mStakePoolRelaySpecFile readRelays

poolParams <- forM [ 1 .. numPools ] $ \index -> do
createPoolCredentials keyOutputFormat pooldir index
buildPoolParams networkId pooldir (Just index) (fromMaybe mempty mayStakePoolRelays)
buildPoolParams networkId pooldir (Just index) (fromMaybe mempty mStakePoolRelays)

when (numBulkPoolCredFiles * numBulkPoolsPerFile > numPools) $
left $ GenesisCmdTooFewPoolsForBulkCreds numPools numBulkPoolCredFiles numBulkPoolsPerFile
Expand Down Expand Up @@ -590,10 +592,10 @@ runGenesisCreateStakedCmd

genDlgs <- readGenDelegsMap gendir deldir
nonDelegAddrs <- readInitialFundAddresses utxodir networkId
start <- maybe (SystemStart <$> TN.getCurrentTimePlus30) pure mSystemStart
start <- maybe (SystemStart <$> getCurrentTimePlus30) pure mSystemStart

let network = toShelleyNetwork networkId
stuffedUtxoAddrs <- liftIO $ Lazy.replicateM (fromIntegral numStuffedUtxo) $ TN.genStuffedAddress network
stuffedUtxoAddrs <- liftIO $ Lazy.replicateM (fromIntegral numStuffedUtxo) $ genStuffedAddress network

let stake = second L.ppId . mkDelegationMapEntry <$> delegations
stakePools = [ (L.ppId poolParams', poolParams') | poolParams' <- snd . mkDelegationMapEntry <$> delegations ]
Expand Down Expand Up @@ -860,7 +862,7 @@ writeBulkPoolCredentials dir bulkIx poolIxs = do
readEnvelope fp = do
content <- handleIOExceptT (GenesisCmdFileError . FileIOError fp) $
BS.readFile fp
firstExceptT (GenesisCmdAesonDecodeError fp . Text.pack) . hoistEither $
firstExceptT (GenesisCmdFileDecodeError fp . Text.pack) . hoistEither $
Aeson.eitherDecodeStrict' content

-- | This function should only be used for testing purposes.
Expand All @@ -875,7 +877,7 @@ computeInsecureDelegation g0 nw pool = do
(stakeVK , g2) <- first getVerificationKey <$> generateInsecureSigningKey g1 AsStakeKey

let stakeAddressReference = StakeAddressByValue . StakeCredentialByKey . verificationKeyHash $ stakeVK
let initialUtxoAddr = makeShelleyAddress nw (PaymentCredentialByKey (verificationKeyHash paymentVK)) stakeAddressReference
initialUtxoAddr = makeShelleyAddress nw (PaymentCredentialByKey (verificationKeyHash paymentVK)) stakeAddressReference

delegation = Delegation
{ dInitialUtxoAddr = shelleyAddressInEra ShelleyBasedEraShelley initialUtxoAddr
Expand All @@ -892,10 +894,10 @@ readShelleyGenesisWithDefault
-> (ShelleyGenesis L.StandardCrypto -> ShelleyGenesis L.StandardCrypto)
-> ExceptT GenesisCmdError IO (ShelleyGenesis L.StandardCrypto)
readShelleyGenesisWithDefault fpath adjustDefaults = do
TN.readAndDecodeGenesisFile fpath
decodeShelleyGenesisFile fpath
`catchError` \err ->
case err of
GenesisCmdGenesisFileReadError (FileIOError _ ioe)
GenesisCmdGenesisFileError (FileIOError _ ioe)
| isDoesNotExistError ioe -> writeDefault
_ -> left err
where
Expand Down Expand Up @@ -1150,22 +1152,6 @@ runGenesisHashFileCmd (GenesisFile fpath) = do
gh = Crypto.hashWith id content
liftIO $ Text.putStrLn (Crypto.hashToTextAsHex gh)

readAlonzoGenesis
:: FilePath
-> ExceptT GenesisCmdError IO L.AlonzoGenesis
readAlonzoGenesis fpath = do
lbs <- handleIOExceptT (GenesisCmdGenesisFileError . FileIOError fpath) $ LBS.readFile fpath
firstExceptT (GenesisCmdAesonDecodeError fpath . Text.pack)
. hoistEither $ Aeson.eitherDecode' lbs

readConwayGenesis
:: FilePath
-> ExceptT GenesisCmdError IO (L.ConwayGenesis L.StandardCrypto)
readConwayGenesis fpath = do
lbs <- handleIOExceptT (GenesisCmdGenesisFileError . FileIOError fpath) $ LBS.readFile fpath
firstExceptT (GenesisCmdAesonDecodeError fpath . Text.pack)
. hoistEither $ Aeson.eitherDecode' lbs

-- Protocol Parameters

--TODO: eliminate this and get only the necessary params, and get them in a more
Expand Down
156 changes: 156 additions & 0 deletions cardano-cli/src/Cardano/CLI/EraBased/Run/Genesis/Common.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}

module Cardano.CLI.EraBased.Run.Genesis.Common
( decodeShelleyGenesisFile
, decodeAlonzoGenesisFile
, decodeConwayGenesisFile
, readAndDecodeGenesisFileWith
, genStuffedAddress
, getCurrentTimePlus30
, readRelays
) where

import Cardano.Api hiding (ConwayEra)
import Cardano.Api.Ledger (StrictMaybe (SNothing), StandardCrypto, AlonzoGenesis, ConwayGenesis)
import qualified Cardano.Api.Ledger as L
import Cardano.Api.Shelley (Address (ShelleyAddress),
Hash (DRepKeyHash, GenesisDelegateKeyHash, GenesisKeyHash, StakeKeyHash, VrfKeyHash),
KESPeriod (KESPeriod),
OperationalCertificateIssueCounter (OperationalCertificateIssueCounter),
ShelleyGenesis (ShelleyGenesis, sgGenDelegs, sgInitialFunds, sgMaxLovelaceSupply, sgNetworkMagic, sgProtocolParams, sgStaking, sgSystemStart),
StakeCredential (StakeCredentialByKey), VerificationKey (VrfVerificationKey),
VrfKey, alonzoGenesisDefaults, conwayGenesisDefaults, decodeAlonzoGenesis,
shelleyGenesisDefaults, toShelleyAddr, toShelleyNetwork, toShelleyStakeAddr)

import Cardano.CLI.EraBased.Commands.Genesis as Cmd
import qualified Cardano.CLI.EraBased.Commands.Governance.DRep as DRep
import qualified Cardano.CLI.EraBased.Commands.Node as Cmd
import Cardano.CLI.EraBased.Run.Address (generateAndWriteKeyFiles)
import qualified Cardano.CLI.EraBased.Run.Governance.DRep as DRep
import qualified Cardano.CLI.EraBased.Run.Key as Key
import Cardano.CLI.EraBased.Run.Node (runNodeIssueOpCertCmd, runNodeKeyGenColdCmd,
runNodeKeyGenKesCmd, runNodeKeyGenVrfCmd)
import Cardano.CLI.EraBased.Run.StakeAddress (runStakeAddressKeyGenCmd)
import qualified Cardano.CLI.IO.Lazy as Lazy
import Cardano.CLI.Types.Common
import Cardano.CLI.Types.Errors.GenesisCmdError
import Cardano.CLI.Types.Errors.NodeCmdError
import Cardano.CLI.Types.Errors.StakePoolCmdError
import Cardano.CLI.Types.Key
import Cardano.Crypto.Hash (HashAlgorithm)
import qualified Cardano.Crypto.Hash as Hash
import qualified Cardano.Crypto.Random as Crypto
import Ouroboros.Consensus.Shelley.Node (ShelleyGenesisStaking (..))

import Control.DeepSeq (NFData, deepseq)
import Control.Monad (forM, forM_, unless, void, when)
import qualified Data.Aeson as Aeson
import Data.Bifunctor (Bifunctor (..))
import qualified Data.Binary.Get as Bin
import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy.Char8 as LBS
import Data.Coerce (coerce)
import Data.Data (Proxy (..))
import Data.ListMap (ListMap (..))
import qualified Data.ListMap as ListMap
import Data.Map.Strict (Map, fromList, toList)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import qualified Data.Sequence.Strict as Seq
import Data.String (fromString)
import qualified Data.Text as Text
import Data.Time (NominalDiffTime, UTCTime, addUTCTime, getCurrentTime)
import Data.Tuple (swap)
import Data.Word (Word64)
import GHC.Generics (Generic)
import GHC.Num (Natural)
import Lens.Micro ((^.))
import System.Directory (createDirectoryIfMissing)
import System.FilePath ((</>))
import qualified System.Random as Random
import System.Random (StdGen)

import Crypto.Random (getRandomBytes)


decodeShelleyGenesisFile
:: MonadIOTransError GenesisCmdError t m
=> FilePath
-> t m (ShelleyGenesis StandardCrypto)
decodeShelleyGenesisFile = readAndDecodeGenesisFile

decodeAlonzoGenesisFile
:: MonadIOTransError GenesisCmdError t m
=> Maybe (CardanoEra era)
-> FilePath
-> t m AlonzoGenesis
decodeAlonzoGenesisFile mEra = readAndDecodeGenesisFileWith (runExcept . decodeAlonzoGenesis mEra)

decodeConwayGenesisFile
:: MonadIOTransError GenesisCmdError t m
=> FilePath
-> t m (ConwayGenesis StandardCrypto)
decodeConwayGenesisFile = readAndDecodeGenesisFile

readAndDecodeGenesisFile
:: MonadIOTransError GenesisCmdError t m
=> FromJSON a => FilePath -> t m a
readAndDecodeGenesisFile = readAndDecodeGenesisFileWith Aeson.eitherDecode

readAndDecodeGenesisFileWith
:: MonadIOTransError GenesisCmdError t m
=> (LBS.ByteString -> Either String a) -> FilePath -> t m a
readAndDecodeGenesisFileWith decode' fpath = do
lbs <- handleIOExceptionsLiftWith (GenesisCmdGenesisFileError . FileIOError fpath) . liftIO $ LBS.readFile fpath
modifyError (GenesisCmdGenesisFileDecodeError fpath . Text.pack)
. hoistEither $ decode' lbs

genStuffedAddress :: L.Network -> IO (AddressInEra ShelleyEra)
genStuffedAddress network = do
paymentCredential <- L.KeyHashObj . mkKeyHash . read64BitInt <$> Crypto.runSecureRandom (getRandomBytes 8)
pure . shelleyAddressInEra ShelleyBasedEraShelley $
ShelleyAddress network paymentCredential L.StakeRefNull
where
read64BitInt :: ByteString -> Int
read64BitInt = (fromIntegral :: Word64 -> Int)
. Bin.runGet Bin.getWord64le . LBS.fromStrict

mkDummyHash :: forall h a. HashAlgorithm h => Proxy h -> Int -> Hash.Hash h a
mkDummyHash _ = coerce . L.hashWithSerialiser @h L.toCBOR

mkKeyHash :: forall c discriminator. L.Crypto c => Int -> L.KeyHash discriminator c
mkKeyHash = L.KeyHash . mkDummyHash (Proxy @(L.ADDRHASH c))


-- | Current UTCTime plus 30 seconds
getCurrentTimePlus30 :: MonadIO m => m UTCTime
getCurrentTimePlus30 =
plus30sec <$> liftIO getCurrentTime
where
plus30sec :: UTCTime -> UTCTime
plus30sec = addUTCTime (30 :: NominalDiffTime)


-- @readRelays fp@ reads the relays specification from a file
readRelays :: ()
=> MonadIO m
=> FilePath -- ^ The file to read from
-> ExceptT GenesisCmdError m (Map Word [L.StakePoolRelay])
readRelays fp = do
relaySpecJsonBs <-
handleIOExceptT (GenesisCmdStakePoolRelayFileError fp) (LBS.readFile fp)
firstExceptT (GenesisCmdStakePoolRelayJsonDecodeError fp)
. hoistEither $ Aeson.eitherDecode relaySpecJsonBs
Loading

0 comments on commit 3de04f4

Please sign in to comment.