@@ -80,7 +80,7 @@ import Cardano.CLI.Shelley.Run.Node (ShelleyNodeCmdError (..), renderS
80
80
runNodeIssueOpCert , runNodeKeyGenCold , runNodeKeyGenKES , runNodeKeyGenVRF )
81
81
import Cardano.CLI.Shelley.Run.Pool (ShelleyPoolCmdError (.. ), renderShelleyPoolCmdError )
82
82
import Cardano.CLI.Shelley.Run.StakeAddress (ShelleyStakeAddressCmdError (.. ),
83
- renderShelleyStakeAddressCmdError , runStakeAddressKeyGenToFile , keyGenStakeAddress )
83
+ renderShelleyStakeAddressCmdError , runStakeAddressKeyGenToFile )
84
84
import Cardano.CLI.Types
85
85
86
86
import Cardano.CLI.Byron.Delegation
@@ -703,23 +703,46 @@ runGenesisCreateStaked (GenesisDir rootdir)
703
703
]
704
704
705
705
-- Distribute M delegates across N pools:
706
- delegations :: [ Delegation ] <- forM distribution $ \ (poolParams, index) -> do
706
+ delegations <- liftIO $ Lazy. forM distribution $ \ (poolParams, index) -> do
707
707
computeDelegation network stdeldir poolParams index
708
708
709
+ liftIO $ LBS. writeFile (stdeldir </> " delegations.jsonl" ) $ B. toLazyByteString $
710
+ mconcat (List. intersperse " \n " (B. lazyByteString . Aeson. encode <$> delegations))
711
+
712
+ -- NOTE The following code which reads from the same file 'delegations.jsonl' multiple times
713
+ -- looks like duplication, but it is not. The file is read lazily, and it is important that
714
+ -- they be read multiple times because the code is streaming and reading the file multiple
715
+ -- times ensures that any data structures that are created as a result of the read is not
716
+ -- retained in memory.
717
+
718
+ ! numDelegations <- fmap length $ liftIO $ LBS. lines <$> LBS. readFile (stdeldir </> " delegations.jsonl" )
719
+
720
+ delegations2 <- do
721
+ delegationLines <- liftIO $ LBS. lines <$> LBS. readFile (stdeldir </> " delegations.jsonl" )
722
+ return $ catMaybes $ Aeson. decode @ Delegation <$> delegationLines
723
+
724
+ delegations3 <- do
725
+ delegationLines <- liftIO $ LBS. lines <$> LBS. readFile (stdeldir </> " delegations.jsonl" )
726
+ return $ catMaybes $ Aeson. decode @ Delegation <$> delegationLines
727
+
728
+ delegations4 <- do
729
+ delegationLines <- liftIO $ LBS. lines <$> LBS. readFile (stdeldir </> " delegations.jsonl" )
730
+ return $ catMaybes $ Aeson. decode @ Delegation <$> delegationLines
731
+
709
732
genDlgs <- readGenDelegsMap gendir deldir
710
733
nonDelegAddrs <- readInitialFundAddresses utxodir network
711
734
start <- maybe (SystemStart <$> getCurrentTimePlus30) pure mStart
712
735
713
736
stuffedUtxoAddrs <- liftIO $ Lazy. replicateM (fromIntegral numStuffedUtxo) genStuffedAddress
714
737
715
- let poolMap :: Map ( Ledger. KeyHash Ledger. Staking StandardCrypto ) ( Ledger. PoolParams StandardCrypto )
716
- poolMap = Map. fromList $ mkDelegationMapEntry <$> delegations
717
- delegAddrs = dInitialUtxoAddr <$> delegations
738
+ let stake = second Ledger. _poolId . mkDelegationMapEntry <$> delegations2
739
+ stakePools = [ ( Ledger. _poolId poolParams, poolParams) | poolParams <- snd . mkDelegationMapEntry <$> delegations3 ]
740
+ delegAddrs = dInitialUtxoAddr <$> delegations4
718
741
! shelleyGenesis =
719
742
updateOutputTemplate
720
743
-- Shelley genesis parameters
721
- start genDlgs mNonDlgAmount nonDelegAddrs poolMap
722
- stDlgAmount delegAddrs stuffedUtxoAddrs (toOutputTemplate template)
744
+ start genDlgs mNonDlgAmount ( length nonDelegAddrs) nonDelegAddrs stakePools stake
745
+ stDlgAmount numDelegations delegAddrs stuffedUtxoAddrs (toOutputTemplate template)
723
746
724
747
-- shelleyGenesis contains lazy loaded data, so using lazyToJson to serialise to avoid
725
748
-- retaining large datastructures in memory.
@@ -735,9 +758,7 @@ runGenesisCreateStaked (GenesisDir rootdir)
735
758
, textShow genNumUTxOKeys, " non-delegating UTxO keys, "
736
759
, textShow genNumPools, " stake pools, "
737
760
, textShow genNumStDelegs, " delegating UTxO keys, "
738
- , textShow (length delegations), " delegation relationships, "
739
- , textShow (Map. size poolMap), " delegation map entries, "
740
- , textShow (length delegAddrs), " delegating addresses"
761
+ , textShow numDelegations, " delegation map entries, "
741
762
] ++
742
763
[ mconcat
743
764
[ " , "
@@ -855,12 +876,24 @@ createPoolCredentials dir index = do
855
876
coldSK = SigningKeyFile $ dir </> " cold" ++ strIndex ++ " .skey"
856
877
opCertCtr = OpCertCounterFile $ dir </> " opcert" ++ strIndex ++ " .counter"
857
878
858
- data Delegation
859
- = Delegation
860
- { dInitialUtxoAddr :: AddressInEra ShelleyEra
861
- , dDelegStaking :: Ledger. KeyHash Ledger. Staking StandardCrypto
862
- , dPoolParams :: Ledger. PoolParams StandardCrypto
863
- }
879
+ data Delegation = Delegation
880
+ { dInitialUtxoAddr :: AddressInEra ShelleyEra
881
+ , dDelegStaking :: Ledger. KeyHash Ledger. Staking StandardCrypto
882
+ , dPoolParams :: Ledger. PoolParams StandardCrypto
883
+ }
884
+
885
+ instance ToJSON Delegation where
886
+ toJSON delegation = Aeson. object
887
+ [ " initialUtxoAddr" .= dInitialUtxoAddr delegation
888
+ , " delegStaking" .= dDelegStaking delegation
889
+ , " poolParams" .= dPoolParams delegation
890
+ ]
891
+
892
+ instance FromJSON Delegation where
893
+ parseJSON = Aeson. withObject " Delegation" $ \ v -> Delegation
894
+ <$> (v .: " initialUtxoAddr" )
895
+ <*> (v .: " delegStaking" )
896
+ <*> (v .: " poolParams" )
864
897
865
898
buildPool :: NetworkId -> FilePath -> Word -> ExceptT ShelleyGenesisCmdError IO (Ledger. PoolParams StandardCrypto )
866
899
buildPool nw dir index = do
@@ -924,34 +957,13 @@ computeDelegation :: ()
924
957
-> FilePath
925
958
-> Ledger. PoolParams StandardCrypto
926
959
-> Word
927
- -> ExceptT ShelleyGenesisCmdError IO Delegation
928
- computeDelegation nw delegDir pool delegIx = do
929
- let strIndex = show delegIx
930
-
931
- let paymentVKF = VerificationKeyFile $ delegDir </> " payment" ++ strIndex ++ " .vkey"
932
-
933
- firstExceptT ShelleyGenesisCmdAddressCmdError $ do
934
- let paymentSKF = SigningKeyFile $ delegDir </> " payment" ++ strIndex ++ " .skey"
935
- runAddressKeyGenToFile AddressKeyShelley paymentVKF paymentSKF
936
-
937
- let stakingVKF = VerificationKeyFile $ delegDir </> " staking" ++ strIndex ++ " .vkey"
938
-
939
- (_, stakeVK) <- firstExceptT ShelleyGenesisCmdStakeAddressCmdError $ do
940
- -- let stakingSK = SigningKeyFile $ delegDir </> "staking" ++ strIndex ++ ".skey"
941
- -- runStakeAddressKeyGenToFile stakingVKF stakingSK
942
- keyGenStakeAddress
960
+ -> IO Delegation
961
+ computeDelegation nw _delegDir pool _delegIx = do
962
+ paymentVK <- fmap getVerificationKey $ generateSigningKey AsPaymentKey
963
+ stakeVK <- fmap getVerificationKey $ generateSigningKey AsStakeKey
943
964
944
- paySVK <- firstExceptT (ShelleyGenesisCmdAddressCmdError
945
- . ShelleyAddressCmdVerificationKeyTextOrFileError ) $
946
- readAddressVerificationKeyTextOrFile
947
- (VktofVerificationKeyFile paymentVKF)
948
-
949
- initialUtxoAddr <- case paySVK of
950
- APaymentVerificationKey payVK -> do
951
- firstExceptT ShelleyGenesisCmdAddressCmdError $ do
952
- let stakeVerifier = StakeVerifierKey . VerificationKeyFilePath $ stakingVKF
953
- makeShelleyAddress nw (PaymentCredentialByKey (verificationKeyHash payVK)) <$> makeStakeAddressRef stakeVerifier
954
- _ -> left $ ShelleyGenesisCmdUnexpectedAddressVerificationKey paymentVKF " APaymentVerificationKey" paySVK
965
+ let stakeAddressReference = StakeAddressByValue . StakeCredentialByKey . verificationKeyHash $ stakeVK
966
+ let initialUtxoAddr = makeShelleyAddress nw (PaymentCredentialByKey (verificationKeyHash paymentVK)) stakeAddressReference
955
967
956
968
pure Delegation
957
969
{ dInitialUtxoAddr = shelleyAddressInEra initialUtxoAddr
@@ -1084,17 +1096,20 @@ updateOutputTemplate
1084
1096
-> Map (Hash GenesisKey ) (Hash GenesisDelegateKey , Hash VrfKey )
1085
1097
-- Non-delegated initial UTxO spec:
1086
1098
-> Maybe Lovelace
1099
+ -> Int
1087
1100
-> [AddressInEra ShelleyEra ]
1088
1101
-- Genesis staking: pools/delegation map & delegated initial UTxO spec:
1089
- -> Map (Ledger. KeyHash 'Ledger.Staking StandardCrypto ) (Ledger. PoolParams StandardCrypto )
1102
+ -> [(Ledger. KeyHash 'Ledger.StakePool StandardCrypto , Ledger. PoolParams StandardCrypto )]
1103
+ -> [(Ledger. KeyHash 'Ledger.Staking StandardCrypto , Ledger. KeyHash 'Ledger.StakePool StandardCrypto )]
1090
1104
-> Lovelace
1091
- -> [AddressInEra ShelleyEra ]
1105
+ -> Int
1106
+ -> [AddressInEra ShelleyEra ] --
1092
1107
-> [AddressInEra ShelleyEra ]
1093
1108
-> OT. OutputShelleyGenesis StandardShelley
1094
1109
-> OT. OutputShelleyGenesis StandardShelley
1095
1110
updateOutputTemplate (SystemStart start)
1096
- genDelegMap mAmountNonDeleg utxoAddrsNonDeleg
1097
- poolSpecs (Lovelace amountDeleg) utxoAddrsDeleg stuffedUtxoAddrs
1111
+ genDelegMap mAmountNonDeleg nUtxoAddrsNonDeleg utxoAddrsNonDeleg
1112
+ pools stake (Lovelace amountDeleg) nUtxoAddrsDeleg utxoAddrsDeleg stuffedUtxoAddrs
1098
1113
template = do
1099
1114
1100
1115
let pparamsFromTemplate = OT. sgProtocolParams template
@@ -1105,15 +1120,16 @@ updateOutputTemplate (SystemStart start)
1105
1120
, OT. sgInitialFunds = ListMap
1106
1121
[ (toShelleyAddr addr, toShelleyLovelace v)
1107
1122
| (addr, v) <-
1108
- distribute (nonDelegCoin - subtractForTreasury) utxoAddrsNonDeleg ++
1109
- distribute (delegCoin - subtractForTreasury) utxoAddrsDeleg ++
1110
- mkStuffedUtxo stuffedUtxoAddrs ]
1123
+ distribute (nonDelegCoin - subtractForTreasury) nUtxoAddrsNonDeleg utxoAddrsNonDeleg
1124
+ ++
1125
+ distribute (delegCoin - subtractForTreasury) nUtxoAddrsDeleg utxoAddrsDeleg
1126
+ ++
1127
+ mkStuffedUtxo stuffedUtxoAddrs
1128
+ ]
1111
1129
, OT. sgStaking =
1112
- ShelleyGenesisStaking
1113
- { sgsPools = Map. fromList
1114
- [ (Ledger. _poolId poolParams, poolParams)
1115
- | poolParams <- Map. elems poolSpecs ]
1116
- , sgsStake = Ledger. _poolId <$> poolSpecs
1130
+ OT. OutputShelleyGenesisStaking
1131
+ { OT. osgsPools = ListMap pools
1132
+ , OT. osgsStake = ListMap stake
1117
1133
}
1118
1134
, OT. sgProtocolParams = pparamsFromTemplate
1119
1135
}
@@ -1128,22 +1144,11 @@ updateOutputTemplate (SystemStart start)
1128
1144
nonDelegCoin = fromIntegral (fromMaybe maximumLovelaceSupply (unLovelace <$> mAmountNonDeleg))
1129
1145
delegCoin = fromIntegral amountDeleg
1130
1146
1131
- distribute :: Integer -> [AddressInEra ShelleyEra ] -> [(AddressInEra ShelleyEra , Lovelace )]
1132
- distribute funds addrs =
1133
- fst $ List. foldl' folder ([] , fromIntegral funds) addrs
1134
- where
1135
- nAddrs , coinPerAddr , splitThreshold :: Integer
1136
- nAddrs = fromIntegral $ length addrs
1137
- coinPerAddr = funds `div` nAddrs
1138
- splitThreshold = coinPerAddr + nAddrs
1139
-
1140
- folder :: ([(AddressInEra ShelleyEra , Lovelace )], Integer )
1141
- -> AddressInEra ShelleyEra
1142
- -> ([(AddressInEra ShelleyEra , Lovelace )], Integer )
1143
- folder (acc, rest) addr
1144
- | rest > splitThreshold =
1145
- ((addr, Lovelace coinPerAddr) : acc, rest - coinPerAddr)
1146
- | otherwise = ((addr, Lovelace rest) : acc, 0 )
1147
+ distribute :: Integer -> Int -> [AddressInEra ShelleyEra ] -> [(AddressInEra ShelleyEra , Lovelace )]
1148
+ distribute funds nAddrs addrs = zipWith (,) addrs (fmap Lovelace (coinPerAddr + rest: repeat coinPerAddr))
1149
+ where coinPerAddr :: Integer
1150
+ coinPerAddr = funds `div` fromIntegral nAddrs
1151
+ rest = coinPerAddr * fromIntegral nAddrs
1147
1152
1148
1153
mkStuffedUtxo :: [AddressInEra ShelleyEra ] -> [(AddressInEra ShelleyEra , Lovelace )]
1149
1154
mkStuffedUtxo xs = (, Lovelace minUtxoVal) <$> xs
0 commit comments