Skip to content

Commit e4f9915

Browse files
iohk-bors[bot]Jimbo4350deepfire
authored
Merge #4234
4234: Update create-staked with the ability to specify relays for all created stake pools r=deepfire a=Jimbo4350 Resolves: #4123 Co-authored-by: Jordan Millar <[email protected]> Co-authored-by: Kosyrev Serge <[email protected]>
2 parents dd3a063 + 6c5b9ae commit e4f9915

File tree

5 files changed

+108
-37
lines changed

5 files changed

+108
-37
lines changed

Diff for: cardano-api/src/Cardano/Api/Shelley.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ import Cardano.Api.Address
235235
import Cardano.Api.Block
236236
import Cardano.Api.Certificate
237237
import Cardano.Api.Eras
238-
import Cardano.Api.IPC
239238
import Cardano.Api.InMode
239+
import Cardano.Api.IPC
240240
import Cardano.Api.KeysByron
241241
import Cardano.Api.KeysPraos
242242
import Cardano.Api.KeysShelley

Diff for: cardano-cli/src/Cardano/CLI/Shelley/Commands.hs

+14-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,20 @@ renderTextViewCmd (TextViewInfo _ _) = "text-view decode-cbor"
429429
data GenesisCmd
430430
= GenesisCreate GenesisDir Word Word (Maybe SystemStart) (Maybe Lovelace) NetworkId
431431
| GenesisCreateCardano GenesisDir Word Word (Maybe SystemStart) (Maybe Lovelace) BlockCount Word Rational NetworkId FilePath FilePath FilePath (Maybe FilePath)
432-
| GenesisCreateStaked GenesisDir Word Word Word Word (Maybe SystemStart) (Maybe Lovelace) Lovelace NetworkId Word Word Word
432+
| GenesisCreateStaked
433+
GenesisDir
434+
Word
435+
Word
436+
Word
437+
Word
438+
(Maybe SystemStart)
439+
(Maybe Lovelace)
440+
Lovelace
441+
NetworkId
442+
Word
443+
Word
444+
Word
445+
(Maybe FilePath) -- ^ Relay specification filepath
433446
| GenesisKeyGenGenesis VerificationKeyFile SigningKeyFile
434447
| GenesisKeyGenDelegate VerificationKeyFile SigningKeyFile OpCertCounterFile
435448
| GenesisKeyGenUTxO VerificationKeyFile SigningKeyFile

Diff for: cardano-cli/src/Cardano/CLI/Shelley/Parsers.hs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,7 @@ pGenesisCmd =
12321232
<*> pBulkPoolCredFiles
12331233
<*> pBulkPoolsPerFile
12341234
<*> pStuffedUtxoCount
1235+
<*> Opt.optional pRelayJsonFp
12351236

12361237
pGenesisHash :: Parser GenesisCmd
12371238
pGenesisHash =
@@ -1304,6 +1305,15 @@ pGenesisCmd =
13041305
<> Opt.value 0
13051306
)
13061307

1308+
pRelayJsonFp :: Parser FilePath
1309+
pRelayJsonFp =
1310+
Opt.strOption
1311+
( Opt.long "relay-specification-file"
1312+
<> Opt.metavar "FILE"
1313+
<> Opt.help "JSON file specified the relays of each stake pool."
1314+
<> Opt.completer (Opt.bashCompleter "file")
1315+
)
1316+
13071317
convertTime :: String -> UTCTime
13081318
convertTime =
13091319
parseTimeOrError False defaultTimeLocale (iso8601DateFormat $ Just "%H:%M:%SZ")
@@ -2779,7 +2789,7 @@ eDNSName :: String -> Either String ByteString
27792789
eDNSName str =
27802790
-- We're using 'Shelley.textToDns' to validate the string.
27812791
case Shelley.textToDns (toS str) of
2782-
Nothing -> Left "DNS name is more than 64 bytes"
2792+
Nothing -> Left $ "DNS name is more than 64 bytes: " <> str
27832793
Just dnsName -> Right . Text.encodeUtf8 . Shelley.dnsToText $ dnsName
27842794

27852795
pSingleHostAddress :: Parser StakePoolRelay

Diff for: cardano-cli/src/Cardano/CLI/Shelley/Run/Genesis.hs

+65-34
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module Cardano.CLI.Shelley.Run.Genesis
2323
) where
2424

2525
import Cardano.Prelude hiding (unlines)
26-
import Prelude (error, id, unlines, zip3)
26+
import Prelude (String, error, id, unlines, zip3)
2727

2828
import Data.Aeson hiding (Key)
2929
import qualified Data.Aeson as Aeson
@@ -92,12 +92,12 @@ import Cardano.CLI.Shelley.Run.StakeAddress (ShelleyStakeAddressCmdErr
9292
renderShelleyStakeAddressCmdError, runStakeAddressKeyGenToFile)
9393
import Cardano.CLI.Types
9494

95-
import Cardano.CLI.Byron.Delegation
96-
import Cardano.CLI.Byron.Genesis as Byron
97-
import qualified Cardano.CLI.Byron.Key as Byron
9895
import qualified Cardano.Chain.Common as Byron (KeyHash, mkKnownLovelace, rationalToLovelacePortion)
9996
import Cardano.Chain.Genesis (FakeAvvmOptions (..), TestnetBalanceOptions (..),
10097
gdProtocolParameters, gsDlgIssuersSecrets, gsPoorSecrets, gsRichSecrets)
98+
import Cardano.CLI.Byron.Delegation
99+
import Cardano.CLI.Byron.Genesis as Byron
100+
import qualified Cardano.CLI.Byron.Key as Byron
101101
import qualified Cardano.Crypto.Signing as Byron
102102

103103
import Cardano.Api.SerialiseTextEnvelope (textEnvelopeToJSON)
@@ -115,8 +115,8 @@ import Data.ListMap (ListMap (..))
115115

116116
import qualified Cardano.CLI.IO.Lazy as Lazy
117117

118-
import System.Random (StdGen)
119118
import qualified System.Random as Random
119+
import System.Random (StdGen)
120120

121121
data ShelleyGenesisCmdError
122122
= ShelleyGenesisCmdAesonDecodeError !FilePath !Text
@@ -136,6 +136,8 @@ data ShelleyGenesisCmdError
136136
| ShelleyGenesisCmdStakeAddressCmdError !ShelleyStakeAddressCmdError
137137
| ShelleyGenesisCmdCostModelsError !FilePath
138138
| ShelleyGenesisCmdByronError !ByronGenesisError
139+
| ShelleyGenesisStakePoolRelayFileError !FilePath !IOException
140+
| ShelleyGenesisStakePoolRelayJsonDecodeError !FilePath !String
139141
deriving Show
140142

141143
instance Error ShelleyGenesisCmdError where
@@ -176,6 +178,12 @@ instance Error ShelleyGenesisCmdError where
176178
" Error: " <> Text.unpack e
177179
ShelleyGenesisCmdGenesisFileReadError e -> displayError e
178180
ShelleyGenesisCmdByronError e -> show e
181+
ShelleyGenesisStakePoolRelayFileError fp e ->
182+
"Error occurred while reading the stake pool relay specification file: " <> fp <>
183+
" Error: " <> show e
184+
ShelleyGenesisStakePoolRelayJsonDecodeError fp e ->
185+
"Error occurred while decoding the stake pool relay specification file: " <> fp <>
186+
" Error: " <> e
179187

180188
runGenesisCmd :: GenesisCmd -> ExceptT ShelleyGenesisCmdError IO ()
181189
runGenesisCmd (GenesisKeyGenGenesis vk sk) = runGenesisKeyGenGenesis vk sk
@@ -187,7 +195,8 @@ runGenesisCmd (GenesisTxIn vk nw mOutFile) = runGenesisTxIn vk nw mOutFile
187195
runGenesisCmd (GenesisAddr vk nw mOutFile) = runGenesisAddr vk nw mOutFile
188196
runGenesisCmd (GenesisCreate gd gn un ms am nw) = runGenesisCreate gd gn un ms am nw
189197
runGenesisCmd (GenesisCreateCardano gd gn un ms am k slotLength sc nw bg sg ag mNodeCfg) = runGenesisCreateCardano gd gn un ms am k slotLength sc nw bg sg ag mNodeCfg
190-
runGenesisCmd (GenesisCreateStaked gd gn gp gl un ms am ds nw bf bp su) = runGenesisCreateStaked gd gn gp gl un ms am ds nw bf bp su
198+
runGenesisCmd (GenesisCreateStaked gd gn gp gl un ms am ds nw bf bp su relayJsonFp) =
199+
runGenesisCreateStaked gd gn gp gl un ms am ds nw bf bp su relayJsonFp
191200
runGenesisCmd (GenesisHashFile gf) = runGenesisHashFile gf
192201

193202
--
@@ -661,11 +670,13 @@ runGenesisCreateStaked
661670
-> Word -- ^ bulk credential files to write
662671
-> Word -- ^ pool credentials per bulk file
663672
-> Word -- ^ num stuffed UTxO entries
673+
-> Maybe FilePath -- ^ Specified stake pool relays
664674
-> ExceptT ShelleyGenesisCmdError IO ()
665675
runGenesisCreateStaked (GenesisDir rootdir)
666676
genNumGenesisKeys genNumUTxOKeys genNumPools genNumStDelegs
667677
mStart mNonDlgAmount stDlgAmount network
668-
bulkPoolCredFiles bulkPoolsPerFile numStuffedUtxo = do
678+
numBulkPoolCredFiles bulkPoolsPerFile numStuffedUtxo
679+
sPoolRelayFp = do
669680
liftIO $ do
670681
createDirectoryIfMissing False rootdir
671682
createDirectoryIfMissing False gendir
@@ -678,31 +689,39 @@ runGenesisCreateStaked (GenesisDir rootdir)
678689
alonzoGenesis <- readAlonzoGenesis (rootdir </> "genesis.alonzo.spec.json")
679690

680691
forM_ [ 1 .. genNumGenesisKeys ] $ \index -> do
681-
createGenesisKeys gendir index
692+
createGenesisKeys gendir index
682693
createDelegateKeys deldir index
683694

684695
forM_ [ 1 .. genNumUTxOKeys ] $ \index ->
685696
createUtxoKeys utxodir index
686697

687-
pools <- forM [ 1 .. genNumPools ] $ \index -> do
698+
mayStakePoolRelays
699+
<- forM sPoolRelayFp $
700+
\fp -> do
701+
relaySpecJsonBs <-
702+
handleIOExceptT (ShelleyGenesisStakePoolRelayFileError fp) (LBS.readFile fp)
703+
firstExceptT (ShelleyGenesisStakePoolRelayJsonDecodeError fp)
704+
. hoistEither $ Aeson.eitherDecode relaySpecJsonBs
705+
706+
poolParams <- forM [ 1 .. genNumPools ] $ \index -> do
688707
createPoolCredentials pooldir index
689-
buildPool network pooldir index
708+
buildPoolParams network pooldir index (fromMaybe mempty mayStakePoolRelays)
690709

691-
when (bulkPoolCredFiles * bulkPoolsPerFile > genNumPools) $
692-
left $ ShelleyGenesisCmdTooFewPoolsForBulkCreds genNumPools bulkPoolCredFiles bulkPoolsPerFile
710+
when (numBulkPoolCredFiles * bulkPoolsPerFile > genNumPools) $
711+
left $ ShelleyGenesisCmdTooFewPoolsForBulkCreds genNumPools numBulkPoolCredFiles bulkPoolsPerFile
693712
-- We generate the bulk files for the last pool indices,
694713
-- so that all the non-bulk pools have stable indices at beginning:
695-
let bulkOffset = fromIntegral $ genNumPools - bulkPoolCredFiles * bulkPoolsPerFile
714+
let bulkOffset = fromIntegral $ genNumPools - numBulkPoolCredFiles * bulkPoolsPerFile
696715
bulkIndices :: [Word] = [ 1 + bulkOffset .. genNumPools ]
697716
bulkSlices :: [[Word]] = List.chunksOf (fromIntegral bulkPoolsPerFile) bulkIndices
698-
forM_ (zip [ 1 .. bulkPoolCredFiles ] bulkSlices) $
717+
forM_ (zip [ 1 .. numBulkPoolCredFiles ] bulkSlices) $
699718
uncurry (writeBulkPoolCredentials pooldir)
700719

701720
let (delegsPerPool, delegsRemaining) = divMod genNumStDelegs genNumPools
702721
delegsForPool poolIx = if delegsRemaining /= 0 && poolIx == genNumPools
703722
then delegsPerPool
704723
else delegsPerPool + delegsRemaining
705-
distribution = [pool | (pool, poolIx) <- zip pools [1 ..], _ <- [1 .. delegsForPool poolIx]]
724+
distribution = [pool | (pool, poolIx) <- zip poolParams [1 ..], _ <- [1 .. delegsForPool poolIx]]
706725

707726
g <- Random.getStdGen
708727

@@ -718,7 +737,7 @@ runGenesisCreateStaked (GenesisDir rootdir)
718737
stuffedUtxoAddrs <- liftIO $ Lazy.replicateM (fromIntegral numStuffedUtxo) genStuffedAddress
719738

720739
let stake = second Ledger._poolId . mkDelegationMapEntry <$> delegations
721-
stakePools = [ (Ledger._poolId poolParams, poolParams) | poolParams <- snd . mkDelegationMapEntry <$> delegations ]
740+
stakePools = [ (Ledger._poolId poolParams', poolParams') | poolParams' <- snd . mkDelegationMapEntry <$> delegations ]
722741
delegAddrs = dInitialUtxoAddr <$> delegations
723742
!shelleyGenesis =
724743
updateCreateStakedOutputTemplate
@@ -741,13 +760,13 @@ runGenesisCreateStaked (GenesisDir rootdir)
741760
] ++
742761
[ mconcat
743762
[ ", "
744-
, textShow bulkPoolCredFiles, " bulk pool credential files, "
763+
, textShow numBulkPoolCredFiles, " bulk pool credential files, "
745764
, textShow bulkPoolsPerFile, " pools per bulk credential file, indices starting from "
746765
, textShow bulkOffset, ", "
747766
, textShow $ length bulkIndices, " total pools in bulk nodes, each bulk node having this many entries: "
748767
, textShow $ length <$> bulkSlices
749768
]
750-
| bulkPoolCredFiles * bulkPoolsPerFile > 0 ]
769+
| numBulkPoolCredFiles * bulkPoolsPerFile > 0 ]
751770

752771
where
753772
adjustTemplate t = t { sgNetworkMagic = unNetworkMagic (toNetworkMagic network) }
@@ -861,19 +880,24 @@ data Delegation = Delegation
861880
}
862881
deriving (Generic, NFData)
863882

864-
buildPool :: NetworkId -> FilePath -> Word -> ExceptT ShelleyGenesisCmdError IO (Ledger.PoolParams StandardCrypto)
865-
buildPool nw dir index = do
866-
StakePoolVerificationKey poolColdVK <- firstExceptT (ShelleyGenesisCmdPoolCmdError
867-
. ShelleyPoolCmdReadFileError)
868-
. newExceptT
869-
$ readFileTextEnvelope (AsVerificationKey AsStakePoolKey) poolColdVKF
870-
VrfVerificationKey poolVrfVK <- firstExceptT (ShelleyGenesisCmdNodeCmdError
871-
. ShelleyNodeCmdReadFileError)
872-
. newExceptT
873-
$ readFileTextEnvelope (AsVerificationKey AsVrfKey) poolVrfVKF
874-
rewardsSVK <- firstExceptT ShelleyGenesisCmdTextEnvReadFileError
875-
. newExceptT
876-
$ readFileTextEnvelope (AsVerificationKey AsStakeKey) poolRewardVKF
883+
buildPoolParams
884+
:: NetworkId
885+
-> FilePath -- ^ File directory where the necessary pool credentials were created
886+
-> Word
887+
-> Map Word [Ledger.StakePoolRelay] -- ^ User submitted stake pool relay map
888+
-> ExceptT ShelleyGenesisCmdError IO (Ledger.PoolParams StandardCrypto)
889+
buildPoolParams nw dir index specifiedRelays = do
890+
StakePoolVerificationKey poolColdVK
891+
<- firstExceptT (ShelleyGenesisCmdPoolCmdError . ShelleyPoolCmdReadFileError)
892+
. newExceptT $ readFileTextEnvelope (AsVerificationKey AsStakePoolKey) poolColdVKF
893+
894+
VrfVerificationKey poolVrfVK
895+
<- firstExceptT (ShelleyGenesisCmdNodeCmdError . ShelleyNodeCmdReadFileError)
896+
. newExceptT $ readFileTextEnvelope (AsVerificationKey AsVrfKey) poolVrfVKF
897+
rewardsSVK
898+
<- firstExceptT ShelleyGenesisCmdTextEnvReadFileError
899+
. newExceptT $ readFileTextEnvelope (AsVerificationKey AsStakeKey) poolRewardVKF
900+
877901
pure Ledger.PoolParams
878902
{ Ledger._poolId = Ledger.hashKey poolColdVK
879903
, Ledger._poolVrf = Ledger.hashVerKeyVRF poolVrfVK
@@ -883,10 +907,17 @@ buildPool nw dir index = do
883907
, Ledger._poolRAcnt =
884908
toShelleyStakeAddr $ makeStakeAddress nw $ StakeCredentialByKey (verificationKeyHash rewardsSVK)
885909
, Ledger._poolOwners = mempty
886-
, Ledger._poolRelays = Seq.empty
910+
, Ledger._poolRelays = lookupPoolRelay specifiedRelays
887911
, Ledger._poolMD = Ledger.SNothing
888912
}
889913
where
914+
lookupPoolRelay
915+
:: Map Word [Ledger.StakePoolRelay] -> Seq.StrictSeq Ledger.StakePoolRelay
916+
lookupPoolRelay m =
917+
case Map.lookup index m of
918+
Just spRelays -> Seq.fromList spRelays
919+
Nothing -> mempty
920+
890921
strIndex = show index
891922
poolColdVKF = dir </> "cold" ++ strIndex ++ ".vkey"
892923
poolVrfVKF = dir </> "vrf" ++ strIndex ++ ".vkey"
@@ -903,12 +934,12 @@ writeBulkPoolCredentials dir bulkIx poolIxs = do
903934
readPoolCreds :: Word -> ExceptT ShelleyGenesisCmdError IO
904935
(TextEnvelope, TextEnvelope, TextEnvelope)
905936
readPoolCreds ix = do
906-
(,,) <$> readEnvelope poolCert
937+
(,,) <$> readEnvelope poolOpCert
907938
<*> readEnvelope poolVrfSKF
908939
<*> readEnvelope poolKesSKF
909940
where
910941
strIndex = show ix
911-
poolCert = dir </> "opcert" ++ strIndex ++ ".cert"
942+
poolOpCert = dir </> "opcert" ++ strIndex ++ ".cert"
912943
poolVrfSKF = dir </> "vrf" ++ strIndex ++ ".skey"
913944
poolKesSKF = dir </> "kes" ++ strIndex ++ ".skey"
914945
readEnvelope :: FilePath -> ExceptT ShelleyGenesisCmdError IO TextEnvelope

Diff for: nix/workbench/genesis.sh

+17
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,24 @@ case "$op" in
190190
# }'
191191
# -o "$dir"/cardano-cli-execution-stats.json
192192
# )
193+
194+
jq '
195+
to_entries
196+
| map
197+
({ key: (.value.i | tostring)
198+
, value:
199+
[{ "single host name":
200+
{ dnsName: .key
201+
, port: .port
202+
}
203+
}
204+
]
205+
})
206+
| from_entries
207+
' "$node_specs" > "$dir"/pool-relays.json
208+
193209
params=(--genesis-dir "$dir"
210+
--relay-specification-file "$dir/pool-relays.json"
194211
$(jq '.cli_args.createFinalBulk | join(" ")' "$profile_json" --raw-output)
195212
)
196213
time cardano-cli genesis create-staked "${params[@]}"

0 commit comments

Comments
 (0)