Skip to content

Commit

Permalink
Update mkfiles.sh to allow immediate hard forking to Alonzo
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimbo4350 committed May 18, 2021
1 parent 8873b9c commit 45bbb5b
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 50 deletions.
50 changes: 32 additions & 18 deletions cardano-cli/src/Cardano/CLI/Shelley/Run/Genesis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,15 @@ import qualified Cardano.Ledger.Alonzo.Language as Alonzo
import qualified Cardano.Ledger.Alonzo.Scripts as Alonzo
import qualified Cardano.Ledger.Alonzo.Translation as Alonzo
import Cardano.Ledger.Coin (Coin (..))
import qualified Plutus.V1.Ledger.Api as Plutus
import qualified PlutusCore.Evaluation.Machine.ExBudgeting as Plutus
import qualified Shelley.Spec.Ledger.API as Ledger
import qualified Shelley.Spec.Ledger.BaseTypes as Ledger
import qualified Shelley.Spec.Ledger.Keys as Ledger
import qualified Shelley.Spec.Ledger.PParams as Shelley

-- TODO: Remove me, cli should not depend directly on plutus repo.
import qualified PlutusCore.Evaluation.Machine.ExBudgeting as Plutus
import qualified PlutusCore.Evaluation.Machine.ExBudgetingDefaults as Plutus

import Cardano.Ledger.Era ()

import Cardano.CLI.Helpers (textShow)
Expand Down Expand Up @@ -963,34 +965,46 @@ readAlonzoGenesis fpath = do
createAlonzoGenesis
:: AlonzoGenWrapper
-> ExceptT ShelleyGenesisCmdError IO Alonzo.AlonzoGenesis
createAlonzoGenesis (AlonzoGenWrapper costModelFp' alonzoGenesis) = do
costModel <- readAndDecode
case Plutus.extractModelParams costModel of
-- TODO: We should not be using functions directly from the plutus repo
-- These should be exposed via the ledger
Just m -> if Plutus.validateCostModelParams m
then left $ ShelleyGenesisCmdCostModelsError costModelFp'
else return $ alonzoGenesis { Alonzo.costmdls = Map.singleton Alonzo.PlutusV1 $ Alonzo.CostModel m }

Nothing -> panic ""
createAlonzoGenesis (AlonzoGenWrapper costModelFp' alonzoGenesis) =
case costModelFp' of
Just fp -> do
costModel <- readAndDecode fp
case Plutus.extractModelParams costModel of
-- TODO: We should not be using functions directly from the plutus repo
-- These should be exposed via the ledger
Just m -> -- if Plutus.validateCostModelParams m
-- then left $ ShelleyGenesisCmdCostModelsError costModelFp'
-- else
--TODO: Plutus repo needs to expose a cost model validation function
return $ alonzoGenesis { Alonzo.costmdls = Map.singleton Alonzo.PlutusV1 $ Alonzo.CostModel m }

Nothing -> panic "createAlonzoGenesis: not implemented yet"
Nothing ->
case Plutus.extractModelParams Plutus.defaultCostModel of
Just m ->
if Alonzo.validateCostModelParams m
then return $ alonzoGenesis { Alonzo.costmdls = Map.singleton Alonzo.PlutusV1 $ Alonzo.CostModel m }
else panic "createAlonzoGenesis: Plutus.defaultCostModel is invalid"

Nothing -> panic "createAlonzoGenesis: Could not extract cost model params from Plutus.defaultCostModel"
where
readAndDecode :: ExceptT ShelleyGenesisCmdError IO Plutus.CostModel
readAndDecode = do
lbs <- handleIOExceptT (ShelleyGenesisCmdGenesisFileError . FileIOError costModelFp') $ LBS.readFile costModelFp'
firstExceptT (ShelleyGenesisCmdAesonDecodeError costModelFp' . Text.pack)
readAndDecode :: FilePath -> ExceptT ShelleyGenesisCmdError IO Plutus.CostModel
readAndDecode fp = do
lbs <- handleIOExceptT (ShelleyGenesisCmdGenesisFileError . FileIOError fp) $ LBS.readFile fp
firstExceptT (ShelleyGenesisCmdAesonDecodeError fp . Text.pack)
. hoistEither $ Aeson.eitherDecode' lbs


data AlonzoGenWrapper =
AlonzoGenWrapper { costModelFp :: FilePath
AlonzoGenWrapper { costModelFp :: Maybe FilePath
, genesis :: Alonzo.AlonzoGenesis
}

instance FromJSON AlonzoGenWrapper where
parseJSON = withObject "Alonzo Genesis Wrapper" $ \o -> do
-- NB: This has an empty map for the cost model
alonzoGenensis <- parseJSON (Aeson.Object o) :: Aeson.Parser Alonzo.AlonzoGenesis
cModelFp <- o .: "alonzoCostModel"
cModelFp <- o .:? "costModel"
return $ AlonzoGenWrapper
{ costModelFp = cModelFp
, genesis = alonzoGenensis
Expand Down
65 changes: 48 additions & 17 deletions cardano-node/src/Cardano/Node/Protocol/Alonzo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

module Cardano.Node.Protocol.Alonzo
( AlonzoProtocolInstantiationError(..)
, renderAlonzoProtocolInstantiationError
-- * Reusable parts
, readAlonzoGenesis
) where
Expand All @@ -13,7 +14,7 @@ import Cardano.Prelude
import Cardano.Api

import Control.Monad.Trans.Except.Extra (firstExceptT, handleIOExceptT, hoistEither, left)
import Data.Aeson (FromJSON (..), withObject, (.:))
import Data.Aeson (FromJSON (..), withObject, (.:?))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson
import qualified Data.ByteString.Lazy as LBS
Expand All @@ -24,8 +25,10 @@ import System.IO.Error (isDoesNotExistError)
import qualified Cardano.Ledger.Alonzo.Language as Alonzo
import qualified Cardano.Ledger.Alonzo.Scripts as Alonzo
import qualified Cardano.Ledger.Alonzo.Translation as Alonzo
import qualified Plutus.V1.Ledger.Api as Plutus

-- TODO: Remove me, cli should not depend directly on plutus repo.
import qualified PlutusCore.Evaluation.Machine.ExBudgeting as Plutus
import qualified PlutusCore.Evaluation.Machine.ExBudgetingDefaults as Plutus


import Cardano.Node.Orphans ()
Expand Down Expand Up @@ -66,45 +69,73 @@ readAlonzoGenesis fpath = do
createAlonzoGenesis
:: AlonzoGenWrapper
-> ExceptT AlonzoProtocolInstantiationError IO Alonzo.AlonzoGenesis
createAlonzoGenesis (AlonzoGenWrapper costModelFp' alonzoGenesis) = do
costModel <- readAndDecode
case Plutus.extractModelParams costModel of
Just m -> if Plutus.validateCostModelParams m
then left $ InvalidCostModelError costModelFp'
else return $ alonzoGenesis { Alonzo.costmdls = Map.singleton Alonzo.PlutusV1 $ Alonzo.CostModel m }

Nothing -> left CostModelExtractionError -- TODO: costModel
createAlonzoGenesis (AlonzoGenWrapper costModelFp' alonzoGenesis) =
case costModelFp' of
Just fp -> do
costModel <- readAndDecode fp
case Plutus.extractModelParams costModel of
-- TODO: We should not be using functions directly from the plutus repo
-- These should be exposed via the ledger
Just m -> -- if Plutus.validateCostModelParams m
-- then left $ ShelleyGenesisCmdCostModelsError costModelFp'
-- else
--TODO: Plutus repo needs to expose a cost model validation function
return $ alonzoGenesis { Alonzo.costmdls = Map.singleton Alonzo.PlutusV1 $ Alonzo.CostModel m }

Nothing -> panic "createAlonzoGenesis: not implemented yet"
Nothing ->
case Plutus.extractModelParams Plutus.defaultCostModel of
Just m ->
if Alonzo.validateCostModelParams m
then return $ alonzoGenesis { Alonzo.costmdls = Map.singleton Alonzo.PlutusV1 $ Alonzo.CostModel m }
else panic "createAlonzoGenesis: Plutus.defaultCostModel is invalid"
Nothing -> panic "createAlonzoGenesis: Could not extract cost model params from Plutus.defaultCostModel"
where
readAndDecode :: ExceptT AlonzoProtocolInstantiationError IO Plutus.CostModel
readAndDecode = do
lbs <- handleIOExceptT (AlonzoCostModelFileError . FileIOError costModelFp') $ LBS.readFile costModelFp'
firstExceptT (AlonzoCostModelDecodeError costModelFp' . Text.pack)
readAndDecode :: FilePath -> ExceptT AlonzoProtocolInstantiationError IO Plutus.CostModel
readAndDecode fp = do
lbs <- handleIOExceptT (AlonzoCostModelFileError . FileIOError fp) $ LBS.readFile fp
firstExceptT (AlonzoCostModelDecodeError fp . Text.pack)
. hoistEither $ Aeson.eitherDecode' lbs


data AlonzoGenWrapper =
AlonzoGenWrapper { costModelFp :: FilePath
AlonzoGenWrapper { costModelFp :: Maybe FilePath
, genesis :: Alonzo.AlonzoGenesis
}

instance FromJSON AlonzoGenWrapper where
parseJSON = withObject "Alonzo Genesis Wrapper" $ \o -> do
-- NB: This has an empty map for the cost model
alonzoGenensis <- parseJSON (Aeson.Object o) :: Aeson.Parser Alonzo.AlonzoGenesis
cModelFp <- o .: "alonzoCostModel"
cModelFp <- o .:? "costModel"
return $ AlonzoGenWrapper
{ costModelFp = cModelFp
, genesis = alonzoGenensis
}

data AlonzoProtocolInstantiationError
= InvalidCostModelError !FilePath
| CostModelExtractionError
| CostModelExtractionError !FilePath
| AlonzoCostModelFileError !(FileError ())
| AlonzoCostModelDecodeError !FilePath !Text
| AlonzoGenesisFileError !(FileError ())
| AlonzoGenesisDecodeError !FilePath !Text
| GenesisFileNotFound !FilePath
deriving Show

renderAlonzoProtocolInstantiationError :: AlonzoProtocolInstantiationError -> Text
renderAlonzoProtocolInstantiationError (InvalidCostModelError fp) =
"Invalid cost model: " <> Text.pack (show fp)
renderAlonzoProtocolInstantiationError (CostModelExtractionError fp) =
"Error extracting the cost model at: " <> Text.pack (show fp)
renderAlonzoProtocolInstantiationError (AlonzoCostModelFileError err) =
Text.pack $ displayError err
renderAlonzoProtocolInstantiationError (AlonzoCostModelDecodeError fp err) =
"Error decoding cost model at: " <> Text.pack (show fp) <> " Error: " <> err
renderAlonzoProtocolInstantiationError (AlonzoGenesisFileError err) =
Text.pack $ displayError err
renderAlonzoProtocolInstantiationError (AlonzoGenesisDecodeError fp err) =
"Error decoding genesis at: " <> Text.pack fp <> " Error: " <> err
renderAlonzoProtocolInstantiationError (GenesisFileNotFound fp) =
"Genesis file not found at: " <> Text.pack fp

7 changes: 4 additions & 3 deletions cardano-node/src/Cardano/Node/Protocol/Cardano.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ import Cardano.Node.Types
import Cardano.Tracing.OrphanInstances.Byron ()
import Cardano.Tracing.OrphanInstances.Shelley ()

import Cardano.Node.Protocol.Alonzo (AlonzoProtocolInstantiationError, readAlonzoGenesis)
import Cardano.Node.Protocol.Alonzo (AlonzoProtocolInstantiationError, readAlonzoGenesis,
renderAlonzoProtocolInstantiationError)
import qualified Cardano.Node.Protocol.Byron as Byron
import qualified Cardano.Node.Protocol.Shelley as Shelley

Expand Down Expand Up @@ -268,5 +269,5 @@ renderCardanoProtocolInstantiationError
Shelley.renderShelleyProtocolInstantiationError err

renderCardanoProtocolInstantiationError
(CardanoProtocolInstantiationErrorAlonzo _) =
error "TODO: renderCardanoProtocolInstantiationError CardanoProtocolInstantiationErrorAlonzo"
(CardanoProtocolInstantiationErrorAlonzo err) =
renderAlonzoProtocolInstantiationError err
2 changes: 1 addition & 1 deletion configuration/cardano/shelley_qa-shelley-genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"executionPrices": 42,
"maxTxExUnits": 42,
"maxBlockExUnits": 42,
"maxMultiAssetSize": 42,
"maxValueSize": 42,
"costModel": "configuration/cardano/alonzo/shelley_qa_cost-model.json"

}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#!/usr/bin/env bash

set -e
#set -x
# Unoffiical bash strict mode.
# See: http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -u
set -o pipefail


# This script sets up a cluster that starts out in Byron, and can transition to Mary.
#
Expand Down Expand Up @@ -97,7 +101,7 @@ pushd ${ROOT}
# create the node directories
for NODE in ${ALL_NODES}; do

mkdir ${NODE} ${NODE}/byron ${NODE}/shelley
mkdir "${NODE}" "${NODE}/byron" "${NODE}/shelley"

done

Expand Down Expand Up @@ -186,7 +190,7 @@ EOF

cardano-cli byron genesis genesis \
--protocol-magic ${NETWORK_MAGIC} \
--start-time ${START_TIME} \
--start-time "${START_TIME}" \
--k ${SECURITY_PARAM} \
--n-poor-addresses 0 \
--n-delegate-addresses ${NUM_BFT_NODES} \
Expand All @@ -202,8 +206,8 @@ mv byron.genesis.spec.json byron/genesis.spec.json
# Symlink the BFT operator keys from the genesis delegates, for uniformity
for N in ${BFT_NODES_N}; do

ln -s ../../byron/delegate-keys.00$((${N} - 1)).key node-bft${N}/byron/delegate.key
ln -s ../../byron/delegation-cert.00$((${N} - 1)).json node-bft${N}/byron/delegate.cert
ln -s ../../byron/delegate-keys.00$((${N} - 1)).key "node-bft${N}/byron/delegate.key"
ln -s ../../byron/delegation-cert.00$((${N} - 1)).json "node-bft${N}/byron/delegate.cert"

done

Expand All @@ -227,7 +231,7 @@ for N in ${BFT_NODES_N}; do
--testnet-magic 42 \
--tx tx$((${N} - 1)).tx \
--wallet-key byron/delegate-keys.00$((${N} - 1)).key \
--rich-addr-from $(head -n 1 byron/genesis-address-00$((${N} - 1))) \
--rich-addr-from "$(head -n 1 byron/genesis-address-00$((${N} - 1)))" \
--txout "(\"$(head -n 1 byron/address-00$((${N} - 1)))\", $FUNDS_PER_BYRON_ADDRESS)"

done
Expand Down Expand Up @@ -502,21 +506,21 @@ echo
echo "In order to do the protocol updates, proceed as follows:"
echo
echo " 0. wait for the nodes to start producing blocks"
echo " 1. invoke ./scripts/byron-to-mary/update-1.sh"
echo " 1. invoke ./scripts/byron-to-alonzo/update-1.sh"
echo " wait for the next epoch for the update to take effect"
echo
echo " 2. invoke ./scripts/byron-to-mary/update-2.sh"
echo " 2. invoke ./scripts/byron-to-alonzo/update-2.sh"
echo " 3. restart the nodes"
echo " wait for the next epoch for the update to take effect"
echo
echo " 4. invoke ./scripts/byron-to-mary/update-3.sh <N>"
echo " 4. invoke ./scripts/byron-to-alonzo/update-3.sh <N>"
echo " Here, <N> the current epoch (2 if you're quick)."
echo " If you provide the wrong epoch, you will see an error"
echo " that will tell you the current epoch, and can run"
echo " the script again."
echo " 5. restart the nodes"
echo " wait for the next epoch for the update to take effect"
echo " 6. invoke ./scripts/byron-to-mary/update-4.sh <N>"
echo " 6. invoke ./scripts/byron-to-alonzo/update-4.sh <N>"
echo " 7. restart the nodes"
echo
echo "You can observe the status of the updates by grepping the logs, via"
Expand Down Expand Up @@ -545,7 +549,27 @@ popd
# For an automatic transition at epoch 0, specifying mary, allegra or shelley
# will start the node in the appropriate era.
echo ""
if [ "$1" = "mary" ]; then
if [ "$1" = "alonzo" ]; then
echo "TestShelleyHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml
echo "TestAllegraHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml
echo "TestMaryHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml
echo "TestAlonzoHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml
echo "TestEnableDevelopmentHardForkEras: True" >> ${ROOT}/configuration.yaml
echo "TestEnableDevelopmentNetworkProtocols: True" >> ${ROOT}/configuration.yaml

sed -i ${ROOT}/configuration.yaml \
-e 's/LastKnownBlockVersion-Major: 1/LastKnownBlockVersion-Major: 5/'

# Update shelley genesis with required Alonzo fields.
alonzogenesisparams='.+ {adaPerUTxOWord: 0, executionPrices: {prMem: 1, prSteps: 1}, maxTxExUnits: {exUnitsMem: 1, exUnitsSteps: 1}, maxBlockExUnits: {exUnitsMem: 1, exUnitsSteps: 1}, maxValueSize: 1000, costModel: "example/shelley/alonzo/costmodel.json", collateralPercentage: 100, maxCollateralInputs: 1}'
alonzogenesis=$(jq "${alonzogenesisparams}" < ${ROOT}/shelley/genesis.json)
echo "${alonzogenesis}" > ${ROOT}/shelley/genesis.json
# Copy the cost model
mkdir ${ROOT}/shelley/alonzo
cp configuration/cardano/alonzo/shelley_qa_cost-model.json ${ROOT}/shelley/alonzo/costmodel.json
echo "Nodes will start in Alonzo era from epoch 0"

elif [ "$1" = "mary" ]; then
echo "TestShelleyHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml
echo "TestAllegraHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml
echo "TestMaryHardForkAtEpoch: 0" >> ${ROOT}/configuration.yaml
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 45bbb5b

Please sign in to comment.