@@ -136,6 +136,9 @@ import qualified Cardano.Ledger.Plutus.Language as Plutus
136
136
import qualified Cardano.Ledger.Shelley.API as Ledger
137
137
import Cardano.Slotting.Slot (EpochNo (.. ))
138
138
import 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
139
142
140
143
import Control.Monad
141
144
import Data.Aeson (FromJSON (.. ), ToJSON (.. ), object , withObject , (.!=) , (.:) , (.:?) ,
@@ -1051,6 +1054,40 @@ toAlonzoCostModel (CostModel m) l = first (PpceInvalidCostModel (CostModel m)) $
1051
1054
fromAlonzoCostModel :: Alonzo. CostModel -> CostModel
1052
1055
fromAlonzoCostModel m = CostModel $ Alonzo. getCostModelParams m
1053
1056
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
+
1054
1091
-- ----------------------------------------------------------------------------
1055
1092
-- Proposals embedded in transactions to update protocol parameters
1056
1093
--
@@ -1853,6 +1890,11 @@ data ProtocolParametersConversionError
1853
1890
| PpceMissingParameter ! ProtocolParameterName
1854
1891
deriving (Eq , Show , Data )
1855
1892
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
+
1856
1898
type ProtocolParameterName = String
1857
1899
1858
1900
type ProtocolParameterVersion = Natural
@@ -1867,3 +1909,12 @@ instance Error ProtocolParametersConversionError where
1867
1909
" Invalid cost model: " <> pretty @ Text (display err) <> " Cost model: " <> pshow cm
1868
1910
PpceMissingParameter name ->
1869
1911
" 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