Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create-testnet-data: better UX for supply arguments #581

Merged
merged 5 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cardano-cli/src/Cardano/CLI/EraBased/Commands/Genesis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ data GenesisCreateTestNetDataCmdArgs = GenesisCreateTestNetDataCmdArgs
, numDrepKeys :: !Word -- ^ The number of DRep keys to create. Right now they receive neither delegation nor are registrated. This will come later.
, numStuffedUtxo :: !Word -- ^ The number of UTxO accounts to make. They are "stuffed" because the credentials are not written to disk.
, numUtxoKeys :: !Word -- ^ The number of UTxO credentials to create and write to disk.
, supply :: !(Maybe Lovelace) -- ^ The number of Lovelace to distribute over initial, non-delegating stake holders.
, supplyDelegated :: !(Maybe Lovelace) -- ^ The number of Lovelace to distribute over delegating stake holders.
, totalSupply :: !(Maybe Lovelace) -- ^ The total number of Lovelace
, delegatedSupply :: !(Maybe Lovelace) -- ^ The number of Lovelace being delegated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much more understandable 👍🏻

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does total supply indicate total maximum possible supply?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Humm not sure what you mean. totalSupply indicates the entire amount of currency in the testnet being created IIUC.

, networkId :: !NetworkId -- ^ The network ID to use.
, systemStart :: !(Maybe SystemStart) -- ^ The genesis start time.
, outputDir :: !FilePath -- ^ Directory where to write credentials and files.
Expand Down
19 changes: 12 additions & 7 deletions cardano-cli/src/Cardano/CLI/EraBased/Options/Genesis.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Cardano.CLI.EraBased.Options.Genesis
Expand Down Expand Up @@ -273,18 +274,22 @@ pGenesisCreateTestNetData envCli =
pSupply :: Parser (Maybe Lovelace)
pSupply =
Opt.optional $ fmap Lovelace $ Opt.option Opt.auto $ mconcat
[ Opt.long "supply"
[ Opt.long "total-supply"
, Opt.metavar "LOVELACE"
, Opt.help "The initial coin supply in Lovelace which will be evenly distributed across initial, non-delegating stake holders. Defaults to 1 million Ada (i.e. 10^12 Lovelace)."
, Opt.value 1000000000000
, Opt.help $ mconcat [ "The maximum possible amount of Lovelace, which is evenly distributed across stake holders. Defaults to 1 million Ada (i.e. 10^12 Lovelace)."
, " If --delegated-supply is specified, a part of this amount will be delegated."
]
, Opt.value 1_000_000_000_000
]
pSupplyDelegated :: Parser (Maybe Lovelace)
pSupplyDelegated =
Opt.optional $ fmap Lovelace $ Opt.option Opt.auto $ mconcat
[ Opt.long "supply-delegated"
[ Opt.long "delegated-supply"
, Opt.metavar "LOVELACE"
, Opt.help "The initial coin supply in Lovelace which will be evenly distributed across initial, delegating stake holders. Defaults to 1 million Ada (i.e. 10^12 Lovelace)."
, Opt.value 1000000000000
, Opt.help $ mconcat [ "The amount of the total supply which is evenly delegated. Defaults to 500 000 Ada (i.e. (10^12) / 2 Lovelace)."
, " Cannot be more than the amount specified with --total-supply."
]
, Opt.value 500_000_000_000
]
pOutputDir = Opt.strOption $ mconcat
[ Opt.long "out-dir"
Expand Down Expand Up @@ -401,7 +406,7 @@ pSlotLength =
[ Opt.long "slot-length"
, Opt.metavar "INT"
, Opt.help "slot length (ms) parameter for genesis file [default is 1000]."
, Opt.value 1000
, Opt.value 1_000
]


Expand Down
36 changes: 18 additions & 18 deletions cardano-cli/src/Cardano/CLI/EraBased/Run/CreateTestnetData.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ module Cardano.CLI.EraBased.Run.CreateTestnetData
, runGenesisKeyGenDelegateCmd
, runGenesisCreateTestNetDataCmd
, runGenesisKeyGenDelegateVRF
, updateCreateStakedOutputTemplate
) where

import Cardano.Api
Expand Down Expand Up @@ -192,8 +191,8 @@ runGenesisCreateTestNetDataCmd Cmd.GenesisCreateTestNetDataCmdArgs
, numDrepKeys
, numStuffedUtxo
, numUtxoKeys
, supply
, supplyDelegated
, totalSupply
, delegatedSupply
, systemStart
, outputDir }
= do
Expand Down Expand Up @@ -299,10 +298,9 @@ runGenesisCreateTestNetDataCmd Cmd.GenesisCreateTestNetDataCmdArgs
stakePools = [ (Ledger.ppId poolParams', poolParams') | poolParams' <- snd . mkDelegationMapEntry <$> delegations ]
delegAddrs = dInitialUtxoAddr <$> delegations
!shelleyGenesis' =
updateCreateStakedOutputTemplate
-- Shelley genesis parameters
start genDlgs supply (length nonDelegAddrs) nonDelegAddrs stakePools stake
supplyDelegated (length delegations) delegAddrs stuffedUtxoAddrs shelleyGenesis
updateOutputTemplate
start genDlgs totalSupply nonDelegAddrs stakePools stake
delegatedSupply (length delegations) delegAddrs stuffedUtxoAddrs shelleyGenesis

-- Write genesis.json file to output
liftIO $ LBS.writeFile (outputDir </> "genesis.json") $ Aeson.encode shelleyGenesis'
Expand Down Expand Up @@ -567,11 +565,10 @@ computeInsecureDelegation g0 nw pool = do
pure (g2, delegation)


updateCreateStakedOutputTemplate
updateOutputTemplate
:: SystemStart -- ^ System start time
-> Map (Hash GenesisKey) (Hash GenesisDelegateKey, Hash VrfKey) -- ^ Genesis delegation (not stake-based)
-> Maybe Lovelace -- ^ Amount of lovelace not delegated
-> Int -- ^ Number of UTxO addresses that are delegating
-> Maybe Lovelace -- ^ Total amount of lovelace
-> [AddressInEra ShelleyEra] -- ^ UTxO addresses that are not delegating
-> [(Ledger.KeyHash 'Ledger.StakePool StandardCrypto, Ledger.PoolParams StandardCrypto)] -- ^ Pool map
-> [(Ledger.KeyHash 'Ledger.Staking StandardCrypto, Ledger.KeyHash 'Ledger.StakePool StandardCrypto)] -- ^ Delegaton map
Expand All @@ -581,15 +578,15 @@ updateCreateStakedOutputTemplate
-> [AddressInEra ShelleyEra] -- ^ Stuffed UTxO addresses
-> ShelleyGenesis StandardCrypto -- ^ Template from which to build a genesis
-> ShelleyGenesis StandardCrypto -- ^ Updated genesis
updateCreateStakedOutputTemplate
updateOutputTemplate
(SystemStart sgSystemStart)
genDelegMap mAmountNonDeleg nUtxoAddrsNonDeleg utxoAddrsNonDeleg pools stake
amountDeleg
genDelegMap mTotalSupply utxoAddrsNonDeleg pools stake
mDelegatedSupply
nUtxoAddrsDeleg utxoAddrsDeleg stuffedUtxoAddrs
template@ShelleyGenesis{ sgProtocolParams } =
template
{ sgSystemStart
, sgMaxLovelaceSupply = fromIntegral $ nonDelegCoin + delegCoin
, sgMaxLovelaceSupply = totalSupply
, sgGenDelegs = shelleyDelKeys
, sgInitialFunds = ListMap.fromList
[ (toShelleyAddr addr, toShelleyLovelace v)
Expand All @@ -608,15 +605,18 @@ updateCreateStakedOutputTemplate
, sgProtocolParams
}
where
nUtxoAddrsNonDeleg = length utxoAddrsNonDeleg
maximumLovelaceSupply :: Word64
maximumLovelaceSupply = sgMaxLovelaceSupply template
-- If the initial funds are equal to the maximum funds, rewards cannot be created.
subtractForTreasury :: Integer
subtractForTreasury = nonDelegCoin `quot` 10
nonDelegCoin, delegCoin :: Integer
-- if --supply is not specified, non delegated supply comes from the template passed to this function:
nonDelegCoin = fromIntegral (maybe maximumLovelaceSupply unLovelace mAmountNonDeleg)
delegCoin = maybe 0 fromIntegral amountDeleg
totalSupply :: Word64
-- if --total-supply is not specified, supply comes from the template passed to this function:
totalSupply = maybe maximumLovelaceSupply unLovelace mTotalSupply
delegCoin, nonDelegCoin :: Integer
delegCoin = case mDelegatedSupply of Nothing -> 0; Just amountDeleg -> fromIntegral totalSupply - unLovelace amountDeleg
nonDelegCoin = fromIntegral totalSupply - delegCoin

distribute :: Integer -> Int -> [AddressInEra ShelleyEra] -> [(AddressInEra ShelleyEra, Lovelace)]
distribute funds nAddrs addrs = zip addrs (fmap Lovelace (coinPerAddr + remainder:repeat coinPerAddr))
Expand Down
72 changes: 71 additions & 1 deletion cardano-cli/src/Cardano/CLI/EraBased/Run/Genesis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import Data.Functor (void)
import Data.Functor.Identity (Identity)
import qualified Data.List as List
import qualified Data.List.Split as List
import Data.ListMap (ListMap (..))
import qualified Data.ListMap as ListMap
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
Expand Down Expand Up @@ -624,7 +625,7 @@ runGenesisCreateStakedCmd
stakePools = [ (Ledger.ppId poolParams', poolParams') | poolParams' <- snd . mkDelegationMapEntry <$> delegations ]
delegAddrs = dInitialUtxoAddr <$> delegations
!shelleyGenesis =
TN.updateCreateStakedOutputTemplate
updateOutputTemplate
-- Shelley genesis parameters
start genDlgs mNonDelegatedSupply (length nonDelegAddrs) nonDelegAddrs stakePools stake
(Just delegatedSupply) numDelegations delegAddrs stuffedUtxoAddrs template
Expand Down Expand Up @@ -660,6 +661,75 @@ runGenesisCreateStakedCmd

-- -------------------------------------------------------------------------------------------------

updateOutputTemplate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carbolymer> It's not duplicated: the code you refer to was previously shared was previously used both by create-staked and create-testnet-data. To keep create-staked's existing behavior, I unshared it, by copying the preexisting version to create-staked's file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of similar code, like utilities in where. Especially this funds distribution part:

                                distribute (nonDelegCoin - subtractForTreasury) nUtxoAddrsNonDeleg  utxoAddrsNonDeleg
                                ++
                                distribute (delegCoin - subtractForTreasury)    nUtxoAddrsDeleg     utxoAddrsDeleg
                                ++
                                mkStuffedUtxo stuffedUtxoAddrs

Can you de-duplicate parts of this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't want to change behavior of create-staked and don't plan on improving it, I am more in favor of duplicating, so that we have ours hand more free for changing create-testnet-data in the future; if you don't mind.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm in favour of de-duplicating. I'm un-requesting changes. @Jimbo4350 your call.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's focus on create-testnet-data for now. Benchmarking depends on create-staked. We can revisit in the future and clean it up. I would rename it to something create testnet data specific though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not exported by the module, so I think its name doesn't need to be create-testnet-data specific.

:: SystemStart -- ^ System start time
-> Map (Hash GenesisKey) (Hash GenesisDelegateKey, Hash VrfKey) -- ^ Genesis delegation (not stake-based)
-> Maybe Lovelace -- ^ Amount of lovelace not delegated
-> Int -- ^ Number of UTxO addresses that are delegating
-> [AddressInEra ShelleyEra] -- ^ UTxO addresses that are not delegating
-> [(Ledger.KeyHash 'Ledger.StakePool StandardCrypto, Ledger.PoolParams StandardCrypto)] -- ^ Pool map
-> [(Ledger.KeyHash 'Ledger.Staking StandardCrypto, Ledger.KeyHash 'Ledger.StakePool StandardCrypto)] -- ^ Delegaton map
-> Maybe Lovelace -- ^ Amount of lovelace to delegate
-> Int -- ^ Number of UTxO address for delegation
-> [AddressInEra ShelleyEra] -- ^ UTxO address for delegation
-> [AddressInEra ShelleyEra] -- ^ Stuffed UTxO addresses
-> ShelleyGenesis StandardCrypto -- ^ Template from which to build a genesis
-> ShelleyGenesis StandardCrypto -- ^ Updated genesis
updateOutputTemplate
(SystemStart sgSystemStart)
genDelegMap mAmountNonDeleg nUtxoAddrsNonDeleg utxoAddrsNonDeleg pools stake
amountDeleg
nUtxoAddrsDeleg utxoAddrsDeleg stuffedUtxoAddrs
template@ShelleyGenesis{ sgProtocolParams } =
template
{ sgSystemStart
, sgMaxLovelaceSupply = fromIntegral $ nonDelegCoin + delegCoin
, sgGenDelegs = shelleyDelKeys
, sgInitialFunds = ListMap.fromList
[ (toShelleyAddr addr, toShelleyLovelace v)
| (addr, v) <-
distribute (nonDelegCoin - subtractForTreasury) nUtxoAddrsNonDeleg utxoAddrsNonDeleg
++
distribute (delegCoin - subtractForTreasury) nUtxoAddrsDeleg utxoAddrsDeleg
++
mkStuffedUtxo stuffedUtxoAddrs
]
, sgStaking =
ShelleyGenesisStaking
{ sgsPools = ListMap pools
, sgsStake = ListMap stake
}
, sgProtocolParams
}
where
maximumLovelaceSupply :: Word64
maximumLovelaceSupply = sgMaxLovelaceSupply template
-- If the initial funds are equal to the maximum funds, rewards cannot be created.
subtractForTreasury :: Integer
subtractForTreasury = nonDelegCoin `quot` 10
nonDelegCoin, delegCoin :: Integer
-- if --supply is not specified, non delegated supply comes from the template passed to this function:
nonDelegCoin = fromIntegral (maybe maximumLovelaceSupply unLovelace mAmountNonDeleg)
delegCoin = maybe 0 fromIntegral amountDeleg

distribute :: Integer -> Int -> [AddressInEra ShelleyEra] -> [(AddressInEra ShelleyEra, Lovelace)]
distribute funds nAddrs addrs = zip addrs (fmap Lovelace (coinPerAddr + remainder:repeat coinPerAddr))
where coinPerAddr, remainder :: Integer
(coinPerAddr, remainder) = funds `divMod` fromIntegral nAddrs

mkStuffedUtxo :: [AddressInEra ShelleyEra] -> [(AddressInEra ShelleyEra, Lovelace)]
mkStuffedUtxo xs = (, Lovelace minUtxoVal) <$> xs
where Coin minUtxoVal = sgProtocolParams ^. ppMinUTxOValueL

shelleyDelKeys = Map.fromList
[ (gh, Ledger.GenDelegPair gdh h)
| (GenesisKeyHash gh,
(GenesisDelegateKeyHash gdh, VrfKeyHash h)) <- Map.toList genDelegMap
]

unLovelace :: Integral a => Lovelace -> a
unLovelace (Lovelace coin) = fromIntegral coin

createDelegateKeys :: KeyOutputFormat -> FilePath -> Word -> ExceptT GenesisCmdError IO ()
createDelegateKeys fmt dir index = do
liftIO $ createDirectoryIfMissing False dir
Expand Down
28 changes: 14 additions & 14 deletions cardano-cli/test/cardano-cli-golden/files/golden/help.cli
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ Usage: cardano-cli shelley genesis create-testnet-data [--spec-shelley FILE]
[--drep-keys INT]
[--stuffed-utxo INT]
[--utxo-keys INT]
[--supply LOVELACE]
[--supply-delegated LOVELACE]
[--total-supply LOVELACE]
[--delegated-supply LOVELACE]
( --mainnet
| --testnet-magic NATURAL
)
Expand Down Expand Up @@ -1427,8 +1427,8 @@ Usage: cardano-cli allegra genesis create-testnet-data [--spec-shelley FILE]
[--drep-keys INT]
[--stuffed-utxo INT]
[--utxo-keys INT]
[--supply LOVELACE]
[--supply-delegated LOVELACE]
[--total-supply LOVELACE]
[--delegated-supply LOVELACE]
( --mainnet
| --testnet-magic NATURAL
)
Expand Down Expand Up @@ -2584,8 +2584,8 @@ Usage: cardano-cli mary genesis create-testnet-data [--spec-shelley FILE]
[--drep-keys INT]
[--stuffed-utxo INT]
[--utxo-keys INT]
[--supply LOVELACE]
[--supply-delegated LOVELACE]
[--total-supply LOVELACE]
[--delegated-supply LOVELACE]
( --mainnet
| --testnet-magic NATURAL
)
Expand Down Expand Up @@ -3725,8 +3725,8 @@ Usage: cardano-cli alonzo genesis create-testnet-data [--spec-shelley FILE]
[--drep-keys INT]
[--stuffed-utxo INT]
[--utxo-keys INT]
[--supply LOVELACE]
[--supply-delegated LOVELACE]
[--total-supply LOVELACE]
[--delegated-supply LOVELACE]
( --mainnet
| --testnet-magic NATURAL
)
Expand Down Expand Up @@ -4890,8 +4890,8 @@ Usage: cardano-cli babbage genesis create-testnet-data [--spec-shelley FILE]
[--drep-keys INT]
[--stuffed-utxo INT]
[--utxo-keys INT]
[--supply LOVELACE]
[--supply-delegated LOVELACE]
[--total-supply LOVELACE]
[--delegated-supply LOVELACE]
( --mainnet
| --testnet-magic NATURAL
)
Expand Down Expand Up @@ -6073,8 +6073,8 @@ Usage: cardano-cli conway genesis create-testnet-data [--spec-shelley FILE]
[--drep-keys INT]
[--stuffed-utxo INT]
[--utxo-keys INT]
[--supply LOVELACE]
[--supply-delegated LOVELACE]
[--total-supply LOVELACE]
[--delegated-supply LOVELACE]
( --mainnet
| --testnet-magic NATURAL
)
Expand Down Expand Up @@ -7599,8 +7599,8 @@ Usage: cardano-cli latest genesis create-testnet-data [--spec-shelley FILE]
[--drep-keys INT]
[--stuffed-utxo INT]
[--utxo-keys INT]
[--supply LOVELACE]
[--supply-delegated LOVELACE]
[--total-supply LOVELACE]
[--delegated-supply LOVELACE]
( --mainnet
| --testnet-magic NATURAL
)
Expand Down
Loading
Loading