Skip to content

Commit c041632

Browse files
authored
Merge pull request #5379 from IntersectMBO/ldan/alonzogen-cm-injection
Add ability to inject any cost models via `AlonzoGenesis` Resolves #5342
2 parents 52083c8 + 3e1ff5f commit c041632

File tree

14 files changed

+205
-103
lines changed

14 files changed

+205
-103
lines changed

eras/alonzo/impl/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## 1.15.0.0
44

5+
* Renamed `uappCostModels` to `uappPlutusV1CostModel`
6+
and changed its type from `CostModels` to `CostModel`
7+
* Renamed `agCostModels` to `agPlutusV1CostModel`
8+
and changed its type from `CostModels` to `CostModel`
9+
* Updated `AlonzoGenesis` with `extraConfig` field
10+
* Added `AlonzoExtraConfig` and its instances
511
* Remove deprecated functions `nullRedeemers`, `lookupRedeemers`, `nullDats`
612
* Remove deprecated type `AlonzoTxWits'` and its accessor functions:
713
- `txwitsVKey'`
@@ -38,6 +44,7 @@
3844

3945
### `testlib`
4046

47+
* Added `Arbitrary` instance for `AlonzoExtraConfig`
4148
* Add CDDL definitions for Plutus V1 types: `big_int`, `big_uint`, `big_nint`, `bounded_bytes`
4249
* Rename `plutus_script` -> `plutus_v1_script` in CDDL
4350
* Add `plutus_v1_script` to CDDL exports

eras/alonzo/impl/src/Cardano/Ledger/Alonzo/Genesis.hs

Lines changed: 122 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,101 +3,156 @@
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

1615
module 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

3234
import 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+
)
3551
import Cardano.Ledger.BaseTypes (KeyValuePairs (..), ToKeyValuePairs (..))
3652
import 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
5061
import Cardano.Ledger.Core
5162
import Cardano.Ledger.Genesis (EraGenesis (..))
63+
import Cardano.Ledger.Plutus (Language (PlutusV1))
5264
import Cardano.Ledger.Plutus.CostModels (parseCostModels)
5365
import Control.DeepSeq (NFData)
54-
import Data.Aeson (FromJSON (..), ToJSON (..), (.:), (.=))
66+
import Data.Aeson (FromJSON (..), ToJSON (..), (.:), (.:?), (.=))
5567
import qualified Data.Aeson as Aeson
5668
import Data.Functor.Identity (Identity)
69+
import qualified Data.List as List
70+
import qualified Data.Map.Strict as Map
5771
import GHC.Generics (Generic)
5872
import NoThunks.Class (NoThunks)
5973
import 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+
69120
pattern AlonzoGenesis ::
70121
CoinPerWord ->
71-
CostModels ->
122+
CostModel ->
72123
Prices ->
73124
ExUnits ->
74125
ExUnits ->
75126
Natural ->
76127
Natural ->
77128
Natural ->
129+
Maybe AlonzoExtraConfig ->
78130
AlonzoGenesis
79131
pattern 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

147206
instance 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

171221
instance 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

183243
instance 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]]

eras/alonzo/impl/src/Cardano/Ledger/Alonzo/PParams.hs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
{-# LANGUAGE GADTs #-}
99
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1010
{-# LANGUAGE InstanceSigs #-}
11+
{-# LANGUAGE LambdaCase #-}
1112
{-# LANGUAGE MultiParamTypeClasses #-}
1213
{-# LANGUAGE NamedFieldPuns #-}
1314
{-# LANGUAGE OverloadedStrings #-}
@@ -96,6 +97,7 @@ import Cardano.Ledger.Plutus.CostModels (
9697
emptyCostModels,
9798
getCostModelLanguage,
9899
getCostModelParams,
100+
mkCostModels,
99101
)
100102
import Cardano.Ledger.Plutus.ExUnits (
101103
ExUnits (..),
@@ -106,10 +108,7 @@ import Cardano.Ledger.Plutus.Language (Language (..))
106108
import Cardano.Ledger.Plutus.ToPlutusData (ToPlutusData (..))
107109
import Cardano.Ledger.Shelley.PParams
108110
import Control.DeepSeq (NFData)
109-
import Data.Aeson as Aeson (
110-
FromJSON,
111-
ToJSON (..),
112-
)
111+
import Data.Aeson (FromJSON (..), ToJSON (..))
113112
import Data.ByteString (ByteString)
114113
import qualified Data.ByteString as BS
115114
import Data.Coerce (coerce)
@@ -410,7 +409,7 @@ instance Ord OrdExUnits where
410409
-- | Parameters that were added in Alonzo
411410
data UpgradeAlonzoPParams f = UpgradeAlonzoPParams
412411
{ uappCoinsPerUTxOWord :: !(HKD f CoinPerWord)
413-
, uappCostModels :: !(HKD f CostModels)
412+
, uappPlutusV1CostModel :: !(HKD f CostModel)
414413
, uappPrices :: !(HKD f Prices)
415414
, uappMaxTxExUnits :: !(HKD f ExUnits)
416415
, uappMaxBlockExUnits :: !(HKD f ExUnits)
@@ -422,7 +421,15 @@ data UpgradeAlonzoPParams f = UpgradeAlonzoPParams
422421

423422
emptyAlonzoUpgradePParamsUpdate :: UpgradeAlonzoPParams StrictMaybe
424423
emptyAlonzoUpgradePParamsUpdate =
425-
UpgradeAlonzoPParams SNothing SNothing SNothing SNothing SNothing SNothing SNothing SNothing
424+
UpgradeAlonzoPParams
425+
SNothing
426+
SNothing
427+
SNothing
428+
SNothing
429+
SNothing
430+
SNothing
431+
SNothing
432+
SNothing
426433

427434
deriving instance Eq (UpgradeAlonzoPParams Identity)
428435

@@ -436,7 +443,7 @@ instance Default (UpgradeAlonzoPParams StrictMaybe) where
436443
def =
437444
UpgradeAlonzoPParams
438445
{ uappCoinsPerUTxOWord = SNothing
439-
, uappCostModels = SNothing
446+
, uappPlutusV1CostModel = SNothing
440447
, uappPrices = SNothing
441448
, uappMaxTxExUnits = SNothing
442449
, uappMaxBlockExUnits = SNothing
@@ -605,7 +612,7 @@ upgradeAlonzoPParams UpgradeAlonzoPParams {..} ShelleyPParams {..} =
605612
, appMinPoolCost = sppMinPoolCost
606613
, -- new in alonzo
607614
appCoinsPerUTxOWord = uappCoinsPerUTxOWord
608-
, appCostModels = uappCostModels
615+
, appCostModels = hkdMap (Proxy @f) (mkCostModels . Map.singleton PlutusV1) uappPlutusV1CostModel
609616
, appPrices = uappPrices
610617
, appMaxTxExUnits = hkdMap (Proxy @f) OrdExUnits uappMaxTxExUnits
611618
, appMaxBlockExUnits = hkdMap (Proxy @f) OrdExUnits uappMaxBlockExUnits

0 commit comments

Comments
 (0)