@@ -136,6 +136,9 @@ import qualified Cardano.Ledger.Plutus.Language as Plutus
136136import qualified Cardano.Ledger.Shelley.API as Ledger
137137import Cardano.Slotting.Slot (EpochNo (.. ))
138138import PlutusLedgerApi.Common (CostModelApplyError )
139+ import qualified PlutusLedgerApi.V1.ParamName as PlutusV1
140+ import qualified PlutusLedgerApi.V2.ParamName as PlutusV2
141+ import qualified PlutusLedgerApi.V3.ParamName as PlutusV3
139142
140143import Control.Monad
141144import Data.Aeson (FromJSON (.. ), ToJSON (.. ), object , withObject , (.!=) , (.:) , (.:?) ,
@@ -1051,6 +1054,40 @@ toAlonzoCostModel (CostModel m) l = first (PpceInvalidCostModel (CostModel m)) $
10511054fromAlonzoCostModel :: Alonzo. CostModel -> CostModel
10521055fromAlonzoCostModel m = CostModel $ Alonzo. getCostModelParams m
10531056
1057+ validateCostModelSize
1058+ :: Maybe (ShelleyBasedEra era )
1059+ -> Plutus. Language
1060+ -> [Int64 ]
1061+ -> Either CostModelNotEnoughParametersError CostModel
1062+ validateCostModelSize mSbe lang model
1063+ | actual < expected = Left $ CostModelNotEnoughParametersError lang expected actual
1064+ | actual == expected = Right $ CostModel model
1065+ | otherwise =
1066+ -- Since the number of parameters can increase in future versions of the Plutus language,
1067+ -- we are fine having too many parameters. This allows for easier testing.
1068+ Right $ CostModel model
1069+ where
1070+ actual = length model
1071+ expected = languageToMinimumParameterCount lang
1072+ allValues :: forall a . (Bounded a , Enum a ) => [a ]
1073+ allValues = [minBound :: a .. maxBound ]
1074+ languageToMinimumParameterCount :: Plutus. Language -> Int
1075+ languageToMinimumParameterCount = \ case
1076+ Plutus. PlutusV1 -> length $ allValues @ PlutusV1. ParamName -- 166
1077+ Plutus. PlutusV2 ->
1078+ let nParamNames = length $ allValues @ PlutusV2. ParamName -- 185
1079+ in case mSbe of
1080+ Nothing ->
1081+ -- We don't know the era, so we can't know the exact number of parameters that is expected,
1082+ -- so we need to be lenient
1083+ nParamNames - 10
1084+ Just sbe ->
1085+ caseShelleyToBabbageOrConwayEraOnwards
1086+ (const $ nParamNames - 10 ) -- Ten parameters were added to V2 in Conway, need to remove them here
1087+ (const nParamNames)
1088+ sbe
1089+ Plutus. PlutusV3 -> length $ allValues @ PlutusV3. ParamName -- 297
1090+
10541091-- ----------------------------------------------------------------------------
10551092-- Proposals embedded in transactions to update protocol parameters
10561093--
@@ -1853,6 +1890,11 @@ data ProtocolParametersConversionError
18531890 | PpceMissingParameter ! ProtocolParameterName
18541891 deriving (Eq , Show , Data )
18551892
1893+ -- | @CostModelNotEnoughParametersError lang minimum actual@ is returned when the observed number of
1894+ -- protocol parameters for @lang@ is @actual@ and that number is below the @minimum@ expected number of parameters.
1895+ data CostModelNotEnoughParametersError
1896+ = CostModelNotEnoughParametersError Plutus. Language Int Int
1897+
18561898type ProtocolParameterName = String
18571899
18581900type ProtocolParameterVersion = Natural
@@ -1867,3 +1909,12 @@ instance Error ProtocolParametersConversionError where
18671909 " Invalid cost model: " <> pretty @ Text (display err) <> " Cost model: " <> pshow cm
18681910 PpceMissingParameter name ->
18691911 " Missing parameter: " <> pretty name
1912+
1913+ instance Error CostModelNotEnoughParametersError where
1914+ prettyError (CostModelNotEnoughParametersError lang minimum' actual) =
1915+ " Not enough parameters for language "
1916+ <> pretty (Plutus. languageToText lang)
1917+ <> " . Expected at least "
1918+ <> pretty minimum'
1919+ <> " parameters but got "
1920+ <> pretty actual
0 commit comments