33{-# LANGUAGE FlexibleContexts #-}
44{-# LANGUAGE FlexibleInstances #-}
55{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6- {-# LANGUAGE NamedFieldPuns #-}
6+ {-# LANGUAGE LambdaCase #-}
77{-# LANGUAGE OverloadedStrings #-}
88{-# LANGUAGE PatternSynonyms #-}
99{-# LANGUAGE RecordWildCards #-}
1010{-# LANGUAGE TypeApplications #-}
1111{-# LANGUAGE TypeFamilies #-}
1212{-# LANGUAGE UndecidableInstances #-}
13- {-# LANGUAGE ViewPatterns #-}
1413{-# OPTIONS_GHC -Wno-orphans #-}
1514
1615module Cardano.Ledger.Alonzo.Genesis (
1716 AlonzoGenesis (
1817 AlonzoGenesisWrapper ,
1918 unAlonzoGenesisWrapper ,
19+ extraConfig ,
2020 AlonzoGenesis ,
2121 agCoinsPerUTxOWord ,
22- agCostModels ,
22+ agPlutusV1CostModel ,
2323 agPrices ,
2424 agMaxTxExUnits ,
2525 agMaxBlockExUnits ,
2626 agMaxValSize ,
2727 agCollateralPercentage ,
28- agMaxCollateralInputs
28+ agMaxCollateralInputs ,
29+ agExtraConfig
2930 ),
31+ AlonzoExtraConfig (.. ),
3032) where
3133
3234import Cardano.Ledger.Alonzo.Era (AlonzoEra )
33- import Cardano.Ledger.Alonzo.PParams (CoinPerWord , UpgradeAlonzoPParams (.. ))
34- import Cardano.Ledger.Alonzo.Scripts (CostModels , ExUnits (.. ), Prices (.. ))
35+ import Cardano.Ledger.Alonzo.PParams (
36+ CoinPerWord ,
37+ UpgradeAlonzoPParams (.. ),
38+ )
39+ import Cardano.Ledger.Alonzo.Scripts (
40+ CostModel ,
41+ CostModels ,
42+ ExUnits (.. ),
43+ Prices (.. ),
44+ costModelsValid ,
45+ decodeCostModel ,
46+ decodeCostModelsLenient ,
47+ encodeCostModel ,
48+ flattenCostModels ,
49+ mkCostModels ,
50+ )
3551import Cardano.Ledger.BaseTypes (KeyValuePairs (.. ), ToKeyValuePairs (.. ))
3652import Cardano.Ledger.Binary (
37- DecCBOR ,
38- EncCBOR ,
53+ DecCBOR ( .. ) ,
54+ EncCBOR ( .. ) ,
3955 FromCBOR (.. ),
4056 ToCBOR (.. ),
57+ decodeNullMaybe ,
58+ encodeNullMaybe ,
4159 )
42- import Cardano.Ledger.Binary.Coders (
43- Decode (From , RecD ),
44- Encode (Rec , To ),
45- decode ,
46- encode ,
47- (!>) ,
48- (<!) ,
49- )
60+ import Cardano.Ledger.Binary.Coders
5061import Cardano.Ledger.Core
5162import Cardano.Ledger.Genesis (EraGenesis (.. ))
63+ import Cardano.Ledger.Plutus (Language (PlutusV1 ))
5264import Cardano.Ledger.Plutus.CostModels (parseCostModels )
5365import Control.DeepSeq (NFData )
54- import Data.Aeson (FromJSON (.. ), ToJSON (.. ), (.:) , (.=) )
66+ import Data.Aeson (FromJSON (.. ), ToJSON (.. ), (.:) , (.:?) , (. =) )
5567import qualified Data.Aeson as Aeson
5668import Data.Functor.Identity (Identity )
69+ import qualified Data.List as List
70+ import qualified Data.Map.Strict as Map
5771import GHC.Generics (Generic )
5872import NoThunks.Class (NoThunks )
5973import Numeric.Natural (Natural )
6074
6175-- | All configuration that is necessary to bootstrap AlonzoEra from ShelleyGenesis
62- newtype AlonzoGenesis = AlonzoGenesisWrapper
76+ data AlonzoGenesis = AlonzoGenesisWrapper
6377 { unAlonzoGenesisWrapper :: UpgradeAlonzoPParams Identity
78+ , extraConfig :: Maybe AlonzoExtraConfig
6479 }
65- deriving stock (Eq , Generic )
66- deriving newtype (Show , NoThunks , NFData )
80+ deriving stock (Eq , Show , Generic )
6781 deriving (ToJSON ) via KeyValuePairs AlonzoGenesis
6882
83+ instance NoThunks AlonzoGenesis
84+
85+ instance NFData AlonzoGenesis
86+
87+ newtype AlonzoExtraConfig = AlonzoExtraConfig
88+ { aecCostModels :: Maybe CostModels
89+ }
90+ deriving (Eq )
91+ deriving newtype (NFData , NoThunks , Show )
92+
93+ instance DecCBOR AlonzoExtraConfig
94+
95+ instance EncCBOR AlonzoExtraConfig
96+
97+ instance FromCBOR AlonzoExtraConfig where
98+ fromCBOR =
99+ eraDecoder @ AlonzoEra $
100+ decode $
101+ RecD AlonzoExtraConfig
102+ <! D (decodeNullMaybe decodeCostModelsLenient)
103+
104+ instance ToCBOR AlonzoExtraConfig where
105+ toCBOR x@ (AlonzoExtraConfig _) =
106+ let AlonzoExtraConfig {.. } = x
107+ in toEraCBOR @ AlonzoEra . encode $
108+ Rec AlonzoExtraConfig
109+ !> E (encodeNullMaybe encCBOR) aecCostModels
110+
111+ instance FromJSON AlonzoExtraConfig where
112+ parseJSON = Aeson. withObject " Extra Config" $ \ o ->
113+ o .:? " costModels" >>= \ case
114+ Nothing -> pure $ AlonzoExtraConfig Nothing
115+ Just val -> AlonzoExtraConfig . Just <$> parseCostModels True [] val
116+
117+ instance ToJSON AlonzoExtraConfig where
118+ toJSON (AlonzoExtraConfig cms) = Aeson. object [" costModels" .= cms]
119+
69120pattern AlonzoGenesis ::
70121 CoinPerWord ->
71- CostModels ->
122+ CostModel ->
72123 Prices ->
73124 ExUnits ->
74125 ExUnits ->
75126 Natural ->
76127 Natural ->
77128 Natural ->
129+ Maybe AlonzoExtraConfig ->
78130 AlonzoGenesis
79131pattern AlonzoGenesis
80132 { agCoinsPerUTxOWord
81- , agCostModels
133+ , agPlutusV1CostModel
82134 , agPrices
83135 , agMaxTxExUnits
84136 , agMaxBlockExUnits
85137 , agMaxValSize
86138 , agCollateralPercentage
87139 , agMaxCollateralInputs
140+ , agExtraConfig
88141 } <-
89- ( unAlonzoGenesisWrapper ->
142+ AlonzoGenesisWrapper
143+ { unAlonzoGenesisWrapper =
90144 UpgradeAlonzoPParams
91145 { uappCoinsPerUTxOWord = agCoinsPerUTxOWord
92- , uappCostModels = agCostModels
146+ , uappPlutusV1CostModel = agPlutusV1CostModel
93147 , uappPrices = agPrices
94148 , uappMaxTxExUnits = agMaxTxExUnits
95149 , uappMaxBlockExUnits = agMaxBlockExUnits
96150 , uappMaxValSize = agMaxValSize
97151 , uappCollateralPercentage = agCollateralPercentage
98152 , uappMaxCollateralInputs = agMaxCollateralInputs
99153 }
100- )
154+ , extraConfig = agExtraConfig
155+ }
101156 where
102157 AlonzoGenesis
103158 coinsPerUTxOWord_
@@ -107,18 +162,21 @@ pattern AlonzoGenesis
107162 maxBlockExUnits_
108163 maxValSize_
109164 collateralPercentage_
110- maxCollateralInputs_ =
111- AlonzoGenesisWrapper $
112- UpgradeAlonzoPParams
113- { uappCoinsPerUTxOWord = coinsPerUTxOWord_
114- , uappCostModels = costModels_
115- , uappPrices = prices_
116- , uappMaxTxExUnits = maxTxExUnits_
117- , uappMaxBlockExUnits = maxBlockExUnits_
118- , uappMaxValSize = maxValSize_
119- , uappCollateralPercentage = collateralPercentage_
120- , uappMaxCollateralInputs = maxCollateralInputs_
121- }
165+ maxCollateralInputs_
166+ extraConfig_ =
167+ AlonzoGenesisWrapper
168+ ( UpgradeAlonzoPParams
169+ { uappCoinsPerUTxOWord = coinsPerUTxOWord_
170+ , uappPlutusV1CostModel = costModels_
171+ , uappPrices = prices_
172+ , uappMaxTxExUnits = maxTxExUnits_
173+ , uappMaxBlockExUnits = maxBlockExUnits_
174+ , uappMaxValSize = maxValSize_
175+ , uappCollateralPercentage = collateralPercentage_
176+ , uappMaxCollateralInputs = maxCollateralInputs_
177+ }
178+ )
179+ extraConfig_
122180
123181{-# COMPLETE AlonzoGenesis #-}
124182
@@ -136,6 +194,7 @@ instance FromCBOR AlonzoGenesis where
136194 decode $
137195 RecD AlonzoGenesis
138196 <! From
197+ <! D (decodeCostModel PlutusV1 )
139198 <! From
140199 <! From
141200 <! From
@@ -145,49 +204,51 @@ instance FromCBOR AlonzoGenesis where
145204 <! From
146205
147206instance ToCBOR AlonzoGenesis where
148- toCBOR
149- AlonzoGenesis
150- { agCoinsPerUTxOWord
151- , agCostModels
152- , agPrices
153- , agMaxTxExUnits
154- , agMaxBlockExUnits
155- , agMaxValSize
156- , agCollateralPercentage
157- , agMaxCollateralInputs
158- } =
159- toEraCBOR @ AlonzoEra
160- . encode
161- $ Rec AlonzoGenesis
162- !> To agCoinsPerUTxOWord
163- !> To agCostModels
164- !> To agPrices
165- !> To agMaxTxExUnits
166- !> To agMaxBlockExUnits
167- !> To agMaxValSize
168- !> To agCollateralPercentage
169- !> To agMaxCollateralInputs
207+ toCBOR x@ (AlonzoGenesis _ _ _ _ _ _ _ _ _) =
208+ let AlonzoGenesis {.. } = x
209+ in toEraCBOR @ AlonzoEra . encode $
210+ Rec AlonzoGenesis
211+ !> To agCoinsPerUTxOWord
212+ !> E encodeCostModel agPlutusV1CostModel
213+ !> To agPrices
214+ !> To agMaxTxExUnits
215+ !> To agMaxBlockExUnits
216+ !> To agMaxValSize
217+ !> To agCollateralPercentage
218+ !> To agMaxCollateralInputs
219+ !> To agExtraConfig
170220
171221instance FromJSON AlonzoGenesis where
172222 parseJSON = Aeson. withObject " Alonzo Genesis" $ \ o -> do
173223 agCoinsPerUTxOWord <- o .: " lovelacePerUTxOWord"
174- agCostModels <- parseCostModels False =<< o .: " costModels"
224+ cms <- parseCostModels False [ PlutusV1 ] =<< o .: " costModels"
175225 agPrices <- o .: " executionPrices"
176226 agMaxTxExUnits <- o .: " maxTxExUnits"
177227 agMaxBlockExUnits <- o .: " maxBlockExUnits"
178228 agMaxValSize <- o .: " maxValueSize"
179229 agCollateralPercentage <- o .: " collateralPercentage"
180230 agMaxCollateralInputs <- o .: " maxCollateralInputs"
231+ agExtraConfig <- o .:? " extraConfig"
232+ agPlutusV1CostModel <-
233+ case Map. toList (costModelsValid cms) of
234+ [] -> fail " Expected \" PlutusV1\" cost model to be supplied"
235+ [(PlutusV1 , pv1CostModel)] -> pure pv1CostModel
236+ _ ->
237+ fail $
238+ " Only PlutusV1 CostModel is allowed in the AlonzoGenesis, but "
239+ <> List. intercalate " , " (map show . Map. keys $ flattenCostModels cms)
240+ <> " were supplied. Use \" extraConfig\" if you need to inject other cost models for testing."
181241 return AlonzoGenesis {.. }
182242
183243instance ToKeyValuePairs AlonzoGenesis where
184244 toKeyValuePairs ag =
185245 [ " lovelacePerUTxOWord" .= agCoinsPerUTxOWord ag
186- , " costModels" .= agCostModels ag
246+ , " costModels" .= mkCostModels ( Map. singleton PlutusV1 $ agPlutusV1CostModel ag)
187247 , " executionPrices" .= agPrices ag
188248 , " maxTxExUnits" .= agMaxTxExUnits ag
189249 , " maxBlockExUnits" .= agMaxBlockExUnits ag
190250 , " maxValueSize" .= agMaxValSize ag
191251 , " collateralPercentage" .= agCollateralPercentage ag
192252 , " maxCollateralInputs" .= agMaxCollateralInputs ag
193253 ]
254+ ++ [" extraConfig" .= extraConfig | Just extraConfig <- [agExtraConfig ag]]
0 commit comments