From eb9640d4f5249d92bc266d37e461e4549bfcf978 Mon Sep 17 00:00:00 2001 From: kwxm Date: Fri, 18 Jul 2025 06:12:43 +0100 Subject: [PATCH 01/11] Enable all builtins and v1.1.0 in all LLs at PV11 --- .../src/PlutusLedgerApi/Common.hs | 1 + .../src/PlutusLedgerApi/Common/Eval.hs | 2 + .../Common/ProtocolVersions.hs | 53 ++-- .../src/PlutusLedgerApi/Common/Versions.hs | 292 ++++++++++------- .../src/PlutusLedgerApi/MachineParameters.hs | 3 +- .../PlutusLedgerApi/V1/EvaluationContext.hs | 3 +- .../src/PlutusLedgerApi/V1/ParamName.hs | 132 ++++++++ .../PlutusLedgerApi/V2/EvaluationContext.hs | 3 +- .../src/PlutusLedgerApi/V2/ParamName.hs | 114 +++++++ .../PlutusLedgerApi/V3/EvaluationContext.hs | 3 +- .../src/PlutusLedgerApi/V3/ParamName.hs | 31 +- .../test/Spec/CostModelParams.hs | 32 +- .../test/Spec/Data/CostModelParams.hs | 22 +- plutus-ledger-api/test/Spec/Data/Eval.hs | 3 +- plutus-ledger-api/test/Spec/Data/Versions.hs | 294 +++++++++++++----- plutus-ledger-api/test/Spec/Eval.hs | 3 +- plutus-ledger-api/test/Spec/Versions.hs | 294 +++++++++++++----- .../Test/V3/Data/EvaluationContext.hs | 17 +- .../Test/V3/EvaluationContext.hs | 22 +- 19 files changed, 953 insertions(+), 371 deletions(-) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common.hs index 3831896ee30..f96075b534f 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common.hs @@ -43,6 +43,7 @@ module PlutusLedgerApi.Common ( Protocol.valentinePV, Protocol.changPV, Protocol.plominPV, + Protocol.anonPV, Protocol.knownPVs, -- * Costing-related types diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/Eval.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/Eval.hs index 615789e39d8..bb88c178967 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/Eval.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/Eval.hs @@ -155,6 +155,8 @@ data EvaluationContext = EvaluationContext -- doesn't depend on the 'PlutusLedgerLanguage' or the AST version: deserialisation of a 1.0.0 -- AST fails upon encountering a 'Case' node anyway, so we can safely assume here that 'case' -- is available. + -- FIXME: do we need to test that it fails for older PVs? We can't submit + -- transactions in old PVs, so maybe it doesn't matter. , _evalCtxToSemVar :: MajorProtocolVersion -> BuiltinSemanticsVariant DefaultFun -- ^ Specifies how to get a semantics variant for this ledger language given a -- 'MajorProtocolVersion'. diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs index 066f2960862..dfeb3ba718e 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs @@ -10,22 +10,24 @@ module PlutusLedgerApi.Common.ProtocolVersions , valentinePV , changPV , plominPV + , anonPV + , newestPV , knownPVs , futurePV ) where import Codec.Serialise (Serialise) -import Data.Set qualified as Set import GHC.Generics (Generic) import Prettyprinter {- Note [Adding new builtins: protocol versions] *** ATTENTION! *** - New built-in functions must initially be added under `futurePV` and should - only be moved to an earlier MajorProtocolVersion once they have been fully - implemented and costed and their release under the relevant protocol version - has been officially approved. + New built-in functions must initially be added under + `futurePV` and should only be moved to an earlier MajorProtocolVersion once + they have been fully implemented and costed and their release under the + relevant protocol version has been officially approved. Remember to update + the tests in `Spec.Versions` and `Spec.Data.Versions` when this happens. -} -- | This represents the major component of the Cardano protocol version. @@ -33,7 +35,7 @@ import Prettyprinter -- component, and Plutus should only need to care about the major component anyway. -- This relies on careful understanding between us and the ledger as to what this means. newtype MajorProtocolVersion = MajorProtocolVersion { getMajorProtocolVersion :: Int } - deriving newtype (Eq, Ord, Show, Serialise) + deriving newtype (Eq, Ord, Show, Serialise, Enum) deriving stock (Generic) instance Pretty MajorProtocolVersion where @@ -55,6 +57,8 @@ maryPV = MajorProtocolVersion 4 alonzoPV :: MajorProtocolVersion alonzoPV = MajorProtocolVersion 5 +-- According to https://cardano.org/hardforks/, PV 6 was called "Lobster". + -- | The Vasil HF introduced the Babbage era and Plutus V2 vasilPV :: MajorProtocolVersion vasilPV = MajorProtocolVersion 7 @@ -68,16 +72,19 @@ valentinePV = MajorProtocolVersion 8 changPV :: MajorProtocolVersion changPV = MajorProtocolVersion 9 --- | The Plomin HF will be an intra-era HF where some new builtin functions --- are introduced in Plutus V2 and V3. +-- | The Plomin HF was an intra-era HF where some new builtin functions were +-- introduced in Plutus V2 and V3. plominPV :: MajorProtocolVersion plominPV = MajorProtocolVersion 10 +-- | Not sure what this is going to be called yet +anonPV :: MajorProtocolVersion +anonPV = MajorProtocolVersion 11 + -- | The set of protocol versions that are "known", i.e. that have been released -- and have actual differences associated with them. -knownPVs :: Set.Set MajorProtocolVersion +knownPVs :: [MajorProtocolVersion] knownPVs = - Set.fromList [ shelleyPV , allegraPV , maryPV @@ -86,16 +93,26 @@ knownPVs = , valentinePV , changPV , plominPV + , anonPV ] --- | This is a placeholder for when we don't yet know what protocol version will --- be used for something. It's a very high protocol version that should never --- appear in reality. New builtins should always be given this protocol version --- until they've been finalised. --- --- We should not assign names to future protocol versions until it's --- confirmed that they are correct, otherwise we could accidentally --- associate something with the wrong protocol version. +-- We're sometimes in an intermediate state where we've added new builtins but +-- not yet released them (but intend to). This is used by some of the tests to +-- decide what PVs the test should include. UPDATE THIS when we're expecting to +-- release new builtins in a forthcoming PV. +newestPV :: MajorProtocolVersion +newestPV = anonPV + +{-| This is a placeholder for when we don't yet know what protocol version will + be used for something. It's a very high protocol version that should never + appear in reality. New builtins should always be given this protocol version + until they've been finalised (at which point they should be moved to + the PV named in `newestPV`). + +We should not assign names to future protocol versions until it's + confirmed that they are correct, otherwise we could accidentally + associate something with the wrong protocol version. +-} futurePV :: MajorProtocolVersion futurePV = MajorProtocolVersion maxBound diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs index aa988877502..7e06ae57caa 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs @@ -22,6 +22,13 @@ module PlutusLedgerApi.Common.Versions , plcVersionsAvailableIn , builtinsIntroducedIn , builtinsAvailableIn + , batch1 + , batch2 + , batch3 + , batch4a + , batch4b + , batch5 + , batch6 ) where import PlutusCore @@ -36,26 +43,34 @@ import PlutusCore.Version (plcVersion100, plcVersion110) import Prettyprinter {- Note [New builtins/language versions and protocol versions] + +Abbreviations: LL = ledger language, PV = (major) protocol version. + When we add a new builtin to the Plutus language, that is a *backwards-compatible* change. Old scripts will still work (since they don't use the new builtins), we just make some more scripts possible. The same is true for new Plutus Core language versions: adding these is also backwards-compatible. -It would be nice, therefore, to get away with just having one definition of the set of builtin -functions/language features. Then the new features will just "work". However, this neglects the fact that -support for the new feature will be added in the *software update* that -brings a new Plutus ledger language, but they should only be usable after the corresponding -*hard fork*. So there is a period of time in which the feature must be present in the software but not +It would be nice, therefore, to get away with just having one definition of the +set of builtin functions/language features. Then the new features will just +"work". However, this neglects the fact that support for the new feature will be +added in the *software update* that brings a new Plutus ledger language, but +they should only be usable after the corresponding *hard fork*. So there is a +period of time in which the feature must be present in the software but not usable, so we need to decide this conditionally based on the protocol version. To do this we need to: - Know which protocol version a feature was introduced in. - Given the protocol version, check a program for features that should not be usable yet. -To simplify our lives, we pervasively make the assumption that after a -feature is introduced in a ledger-language/protocol-version combo, it is present in all -later ledger-languages/protocol-versions. +To simplify our lives, we pervasively make the assumption that after a feature +is introduced in a particular ledger language and protocol version, it remains +present in the same ledger language in all later protocol versions (but not +necessarily in other ledger languages; there was previously an assumption that +if a feature was available in a given LL then it would also be available in all +later LLs, but this led to complications when we retrospectively introduced +certain features in earlier LLs). Note that this doesn't currently handle removals, although it fairly straighforwardly could do, just by tracking when they were removed. @@ -72,79 +87,15 @@ and the __ordering of constructors__ is essential for deriving Enum,Ord,Bounded. IMPORTANT: this is different from the Plutus Core language version, `PlutusCore.Version` -} data PlutusLedgerLanguage = - PlutusV1 -- ^ introduced in shelley era - | PlutusV2 -- ^ introduced in vasil era - | PlutusV3 -- ^ not yet enabled + PlutusV1 -- ^ introduced in Alonzo HF + | PlutusV2 -- ^ introduced in Vasil HF + | PlutusV3 -- ^ introduced in Chang HF deriving stock (Eq, Ord, Show, Generic, Enum, Bounded) deriving anyclass (NFData, NoThunks, Serialise) instance Pretty PlutusLedgerLanguage where pretty = viaShow -{-| A map indicating which builtin functions were introduced in which 'MajorProtocolVersion'. - -This __must__ be updated when new builtins are added. -See Note [New builtins/language versions and protocol versions] --} -builtinsIntroducedIn :: Map.Map (PlutusLedgerLanguage, MajorProtocolVersion) (Set.Set DefaultFun) -builtinsIntroducedIn = Map.fromList [ - ((PlutusV1, alonzoPV), Set.fromList [ - AddInteger, SubtractInteger, MultiplyInteger, DivideInteger, QuotientInteger, RemainderInteger, ModInteger, EqualsInteger, LessThanInteger, LessThanEqualsInteger, - AppendByteString, ConsByteString, SliceByteString, LengthOfByteString, IndexByteString, EqualsByteString, LessThanByteString, LessThanEqualsByteString, - Sha2_256, Sha3_256, Blake2b_256, VerifyEd25519Signature, - AppendString, EqualsString, EncodeUtf8, DecodeUtf8, - IfThenElse, - ChooseUnit, - Trace, - FstPair, SndPair, - ChooseList, MkCons, HeadList, TailList, NullList, - ChooseData, ConstrData, MapData, ListData, IData, BData, UnConstrData, UnMapData, UnListData, UnIData, UnBData, EqualsData, - MkPairData, MkNilData, MkNilPairData - ]), - ((PlutusV2, vasilPV), Set.fromList [ - SerialiseData - ]), - ((PlutusV2, valentinePV), Set.fromList [ - VerifyEcdsaSecp256k1Signature, VerifySchnorrSecp256k1Signature - ]), - ((PlutusV2, plominPV), Set.fromList [ - IntegerToByteString, ByteStringToInteger - ]), - ((PlutusV3, changPV), Set.fromList [ - Bls12_381_G1_add, Bls12_381_G1_neg, Bls12_381_G1_scalarMul, - Bls12_381_G1_equal, Bls12_381_G1_hashToGroup, - Bls12_381_G1_compress, Bls12_381_G1_uncompress, - Bls12_381_G2_add, Bls12_381_G2_neg, Bls12_381_G2_scalarMul, - Bls12_381_G2_equal, Bls12_381_G2_hashToGroup, - Bls12_381_G2_compress, Bls12_381_G2_uncompress, - Bls12_381_millerLoop, Bls12_381_mulMlResult, Bls12_381_finalVerify, - Keccak_256, Blake2b_224, IntegerToByteString, ByteStringToInteger - ]), - ((PlutusV3, plominPV), Set.fromList [ - AndByteString, OrByteString, XorByteString, ComplementByteString, - ReadBit, WriteBits, ReplicateByte, - ShiftByteString, RotateByteString, CountSetBits, FindFirstSetBit, - Ripemd_160 - ]), - ((PlutusV3, futurePV), Set.fromList [ - ExpModInteger, - DropList, - ListToArray, IndexArray, LengthOfArray - ]) - ] - -{-| A map indicating which Plutus Core versions were introduced in which -'MajorProtocolVersion' and 'PlutusLedgerLanguage'. Each version should appear at most once. - -This __must__ be updated when new versions are added. -See Note [New builtins/language versions and protocol versions] --} -plcVersionsIntroducedIn :: Map.Map (PlutusLedgerLanguage, MajorProtocolVersion) (Set.Set Version) -plcVersionsIntroducedIn = Map.fromList [ - ((PlutusV1, alonzoPV), Set.fromList [ plcVersion100 ]), - ((PlutusV3, changPV), Set.fromList [ plcVersion110 ]) - ] - {-| Query the protocol version that a specific Plutus ledger language was first introduced in. -} ledgerLanguageIntroducedIn :: PlutusLedgerLanguage -> MajorProtocolVersion @@ -153,44 +104,173 @@ ledgerLanguageIntroducedIn = \case PlutusV2 -> vasilPV PlutusV3 -> changPV -{-| Which Plutus language versions are available in the given 'MajorProtocolVersion'? - -See Note [New builtins/language versions and protocol versions] +{-| Which Plutus language versions are available in the given +'MajorProtocolVersion'? See Note [New builtins/language versions and protocol +versions]. This function (and others in this module) assumes that once a LL is +available it remains available in all later PVs and that if m <= n, PlutusVm is +introduced no later than PlutusVn. -} ledgerLanguagesAvailableIn :: MajorProtocolVersion -> Set.Set PlutusLedgerLanguage ledgerLanguagesAvailableIn searchPv = - foldMap ledgerVersionToSet enumerate - where - -- OPTIMIZE: could be done faster using takeWhile - ledgerVersionToSet :: PlutusLedgerLanguage -> Set.Set PlutusLedgerLanguage - ledgerVersionToSet ll - | ledgerLanguageIntroducedIn ll <= searchPv = Set.singleton ll - | otherwise = mempty + Set.fromList $ takeWhile (\ll -> ledgerLanguageIntroducedIn ll <= searchPv) enumerate -{-| Which Plutus Core language versions are available in the given 'PlutusLedgerLanguage' -and 'MajorProtocolVersion'? +-- | Given a map from PVs to a type `a`, return a `Set a` containing all of the +-- entries with PV <= thisPv +collectUpTo + :: Ord a + => Map.Map MajorProtocolVersion (Set.Set a) + -> MajorProtocolVersion + -> Set.Set a +collectUpTo m thisPv = + fold $ -- ie, iterated `union` + Map.elems $ Map.takeWhileAntitone (<= thisPv) m -See Note [New builtins/language versions and protocol versions] +{- Batches of builtins which were introduced in the same hard fork (but perhaps + not for all LLs): see the Plutus Core specification and + `builtinsIntroducedIn` below. -} -plcVersionsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set.Set Version -plcVersionsAvailableIn thisLv thisPv = fold $ Map.elems $ - Map.takeWhileAntitone plcVersionAvailableIn plcVersionsIntroducedIn - where - plcVersionAvailableIn :: (PlutusLedgerLanguage, MajorProtocolVersion) -> Bool - plcVersionAvailableIn (introducedInLv,introducedInPv) = - -- both should be satisfied - introducedInLv <= thisLv && introducedInPv <= thisPv -{-| Which builtin functions are available in the given given 'PlutusLedgerLanguage' -and 'MajorProtocolVersion'? +{- If any new builtins are introduced after a batch has been deployed on the chain + then a new `batch` object MUST be added to contain them and the + `builtinsIntroducedIn` function must be updated. Also, remember to UPDATE THE + TESTS in `Spec.Versions` and `Spec.Data.Versions` when a new batch is added. +-} -See Note [New builtins/language versions and protocol versions] +{- It's tempting to try something like `fmap toEnum [0..50]` here, but that's + dangerous because the order of the constructors in DefaultFun doesn't + precisely match the order that the builtins were introduced in. A safer + alternative would be to use the flat tags, but they're not directly + accessible at the moment. +-} +batch1 :: [DefaultFun] +batch1 = + [ AddInteger, SubtractInteger, MultiplyInteger, DivideInteger, QuotientInteger + , RemainderInteger, ModInteger, EqualsInteger, LessThanInteger, LessThanEqualsInteger + , AppendByteString, ConsByteString, SliceByteString, LengthOfByteString + , IndexByteString, EqualsByteString, LessThanByteString, LessThanEqualsByteString + , Sha2_256, Sha3_256, Blake2b_256, VerifyEd25519Signature, AppendString, EqualsString + , EncodeUtf8, DecodeUtf8, IfThenElse, ChooseUnit, Trace, FstPair, SndPair, ChooseList + , MkCons, HeadList, TailList, NullList, ChooseData, ConstrData, MapData, ListData + , IData, BData, UnConstrData, UnMapData, UnListData, UnIData, UnBData, EqualsData + , MkPairData, MkNilData, MkNilPairData + ] + +batch2 :: [DefaultFun] +batch2 = + [ SerialiseData ] + +batch3 :: [DefaultFun] +batch3 = + [ VerifyEcdsaSecp256k1Signature, VerifySchnorrSecp256k1Signature ] + +-- `cekCase` and `cekConstr` costs come between Batch 3 and Batch 4 in the +-- PlutusV3 cost model parameters, although that's irrelevant here. + +-- batch4, excluding IntegerToByteString and ByteStringToInteger. +batch4a :: [DefaultFun] +batch4a = + [ Bls12_381_G1_add, Bls12_381_G1_neg, Bls12_381_G1_scalarMul + , Bls12_381_G1_equal, Bls12_381_G1_hashToGroup + , Bls12_381_G1_compress, Bls12_381_G1_uncompress + , Bls12_381_G2_add, Bls12_381_G2_neg, Bls12_381_G2_scalarMul + , Bls12_381_G2_equal, Bls12_381_G2_hashToGroup + , Bls12_381_G2_compress, Bls12_381_G2_uncompress + , Bls12_381_millerLoop, Bls12_381_mulMlResult, Bls12_381_finalVerify + , Keccak_256, Blake2b_224 + ] + +{- batch4b: IntegerToByteString and ByteStringToInteger. These were enabled in + PlutusV3 at PV9, along with batch4a, They were enabled in PlutusV2 at PV10 in + #6056 and #6065. They are available on the chain, but they're prohibitively + expensive because the proposal to update the relevant protocol parameters has + not (yet) been enacted. This has left a "gap" in the cost model paramters: for + PlutusV3, the parameters for Batch 3 are followed those for 4a, then 4b, but + for PlutusV2 those for Batch3 are followed by those for Batch 4a, and those for + 4b aren't in use yet. Since you can't actually use the 4b builtins in PlutusV2 + at the moment, it's tempting to insert the 4a parameter before the 4b + parameters and enable them all at PV11 and with a suitable parameter update. + However, if we do do this there's a theoretical risk of turning a phase 2 + failure into a phase 1 failure: would that be problematic? +-} +batch4b :: [DefaultFun] +batch4b = + [ IntegerToByteString, ByteStringToInteger ] + +batch4 :: [DefaultFun] +batch4 = batch4a ++ batch4b + +batch5 :: [DefaultFun] +batch5 = + [ AndByteString, OrByteString, XorByteString, ComplementByteString + , ReadBit, WriteBits, ReplicateByte + , ShiftByteString, RotateByteString, CountSetBits, FindFirstSetBit + , Ripemd_160 + ] + +batch6 :: [DefaultFun] +batch6 = + [ ExpModInteger, DropList + , LengthOfArray, ListToArray, IndexArray + ] + +{-| Given a ledger language, return a map indicating which builtin functions were + introduced in which 'MajorProtocolVersion'. This __must__ be updated when new + builtins are added. It is not necessary to add entries for protocol versions + where no new builtins are added. See Note [New builtins/language versions and + protocol versions] -} +builtinsIntroducedIn :: PlutusLedgerLanguage -> Map.Map MajorProtocolVersion (Set.Set DefaultFun) +builtinsIntroducedIn = + \case + PlutusV1 -> + Map.fromList + [ (alonzoPV, Set.fromList batch1) + , (anonPV, Set.fromList (batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6)) + ] + PlutusV2 -> + Map.fromList + [ (vasilPV, Set.fromList (batch1 ++ batch2)) + , (valentinePV, Set.fromList batch3) + , (plominPV, Set.fromList batch4b) + , (anonPV , Set.fromList (batch4a ++ batch5 ++ batch6)) + ] + PlutusV3 -> + Map.fromList + [ (changPV, Set.fromList (batch1 ++ batch2 ++ batch3 ++ batch4)) + , (plominPV, Set.fromList batch5) + , (anonPV, Set.fromList batch6) + ] + +{- | Return a set containing the builtins which are available in a given LL in a +given PV. All builtins are available in all LLs from `anonPV` onwards. -} builtinsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set.Set DefaultFun -builtinsAvailableIn thisLv thisPv = fold $ - Map.filterWithKey (const . alreadyIntroduced) builtinsIntroducedIn - where - alreadyIntroduced :: (PlutusLedgerLanguage, MajorProtocolVersion) -> Bool - alreadyIntroduced (introducedInLv,introducedInPv) = - -- both should be satisfied - introducedInLv <= thisLv && introducedInPv <= thisPv +builtinsAvailableIn = collectUpTo . builtinsIntroducedIn + + +{-| A map indicating which Plutus Core versions were introduced in which +'MajorProtocolVersion' and 'PlutusLedgerLanguage'. Each version should appear at most once. +This __must__ be updated when new versions are added. +See Note [New builtins/language versions and protocol versions] +-} +plcVersionsIntroducedIn :: PlutusLedgerLanguage -> Map.Map MajorProtocolVersion (Set.Set Version) +plcVersionsIntroducedIn = + \case + PlutusV1 -> + Map.fromList + [ (alonzoPV, Set.fromList [ plcVersion100 ]) + , (anonPV, Set.fromList [ plcVersion110 ]) + ] + PlutusV2 -> + Map.fromList + [ (alonzoPV, Set.fromList [ plcVersion100 ]) + , (anonPV, Set.fromList [ plcVersion110 ]) + ] + PlutusV3 -> + Map.fromList + [(changPV, Set.fromList [ plcVersion110 ]) + ] + +{-| Which Plutus Core language versions are available in the given 'PlutusLedgerLanguage' +and 'MajorProtocolVersion'? -} +plcVersionsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set.Set Version +plcVersionsAvailableIn = collectUpTo . plcVersionsIntroducedIn diff --git a/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs b/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs index 306288df644..d5313dbbd40 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs @@ -1,7 +1,6 @@ module PlutusLedgerApi.MachineParameters where import PlutusLedgerApi.Common -import PlutusLedgerApi.Common.ProtocolVersions (futurePV) import PlutusCore.Builtin (CaserBuiltin (..), caseBuiltin, unavailableCaserBuiltin) import PlutusCore.Default (BuiltinSemanticsVariant (..)) @@ -16,7 +15,7 @@ machineParametersFor -> DefaultMachineParameters machineParametersFor ledgerLang majorPV = MachineParameters - (if majorPV < futurePV + (if majorPV < anonPV then unavailableCaserBuiltin $ getMajorProtocolVersion majorPV else CaserBuiltin caseBuiltin) (mkMachineVariantParameters builtinSemVar $ cekCostModelForVariant builtinSemVar) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs b/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs index 66faf322296..622afb36d90 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs @@ -11,7 +11,6 @@ module PlutusLedgerApi.V1.EvaluationContext ( ) where import PlutusLedgerApi.Common -import PlutusLedgerApi.Common.ProtocolVersions (futurePV) import PlutusLedgerApi.V1.ParamName as V1 import PlutusCore.Builtin (CaserBuiltin (..), caseBuiltin, unavailableCaserBuiltin) @@ -43,7 +42,7 @@ mkEvaluationContext = >=> mkDynEvaluationContext PlutusV1 (\pv -> - if pv < futurePV + if pv < anonPV then unavailableCaserBuiltin $ getMajorProtocolVersion pv else CaserBuiltin caseBuiltin) [DefaultFunSemanticsVariantA, DefaultFunSemanticsVariantB] diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V1/ParamName.hs b/plutus-ledger-api/src/PlutusLedgerApi/V1/ParamName.hs index c4007c855f5..6a7f4a25f7d 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V1/ParamName.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V1/ParamName.hs @@ -181,6 +181,138 @@ data ParamName = | VerifyEd25519Signature'cpu'arguments'intercept | VerifyEd25519Signature'cpu'arguments'slope | VerifyEd25519Signature'memory'arguments + -- End of original cost model parameters + -- Remaining parameters to be deployed in PV11 + | SerialiseData'cpu'arguments'intercept + | SerialiseData'cpu'arguments'slope + | SerialiseData'memory'arguments'intercept + | SerialiseData'memory'arguments'slope + | VerifyEcdsaSecp256k1Signature'cpu'arguments + | VerifyEcdsaSecp256k1Signature'memory'arguments + | VerifySchnorrSecp256k1Signature'cpu'arguments'intercept + | VerifySchnorrSecp256k1Signature'cpu'arguments'slope + | VerifySchnorrSecp256k1Signature'memory'arguments + | CekConstrCost'exBudgetCPU + | CekConstrCost'exBudgetMemory + | CekCaseCost'exBudgetCPU + | CekCaseCost'exBudgetMemory + | Bls12_381_G1_add'cpu'arguments + | Bls12_381_G1_add'memory'arguments + | Bls12_381_G1_compress'cpu'arguments + | Bls12_381_G1_compress'memory'arguments + | Bls12_381_G1_equal'cpu'arguments + | Bls12_381_G1_equal'memory'arguments + | Bls12_381_G1_hashToGroup'cpu'arguments'intercept + | Bls12_381_G1_hashToGroup'cpu'arguments'slope + | Bls12_381_G1_hashToGroup'memory'arguments + | Bls12_381_G1_neg'cpu'arguments + | Bls12_381_G1_neg'memory'arguments + | Bls12_381_G1_scalarMul'cpu'arguments'intercept + | Bls12_381_G1_scalarMul'cpu'arguments'slope + | Bls12_381_G1_scalarMul'memory'arguments + | Bls12_381_G1_uncompress'cpu'arguments + | Bls12_381_G1_uncompress'memory'arguments + | Bls12_381_G2_add'cpu'arguments + | Bls12_381_G2_add'memory'arguments + | Bls12_381_G2_compress'cpu'arguments + | Bls12_381_G2_compress'memory'arguments + | Bls12_381_G2_equal'cpu'arguments + | Bls12_381_G2_equal'memory'arguments + | Bls12_381_G2_hashToGroup'cpu'arguments'intercept + | Bls12_381_G2_hashToGroup'cpu'arguments'slope + | Bls12_381_G2_hashToGroup'memory'arguments + | Bls12_381_G2_neg'cpu'arguments + | Bls12_381_G2_neg'memory'arguments + | Bls12_381_G2_scalarMul'cpu'arguments'intercept + | Bls12_381_G2_scalarMul'cpu'arguments'slope + | Bls12_381_G2_scalarMul'memory'arguments + | Bls12_381_G2_uncompress'cpu'arguments + | Bls12_381_G2_uncompress'memory'arguments + | Bls12_381_finalVerify'cpu'arguments + | Bls12_381_finalVerify'memory'arguments + | Bls12_381_millerLoop'cpu'arguments + | Bls12_381_millerLoop'memory'arguments + | Bls12_381_mulMlResult'cpu'arguments + | Bls12_381_mulMlResult'memory'arguments + | Keccak_256'cpu'arguments'intercept + | Keccak_256'cpu'arguments'slope + | Keccak_256'memory'arguments + | Blake2b_224'cpu'arguments'intercept + | Blake2b_224'cpu'arguments'slope + | Blake2b_224'memory'arguments + | IntegerToByteString'cpu'arguments'c0 + | IntegerToByteString'cpu'arguments'c1 + | IntegerToByteString'cpu'arguments'c2 + | IntegerToByteString'memory'arguments'intercept + | IntegerToByteString'memory'arguments'slope + | ByteStringToInteger'cpu'arguments'c0 + | ByteStringToInteger'cpu'arguments'c1 + | ByteStringToInteger'cpu'arguments'c2 + | ByteStringToInteger'memory'arguments'intercept + | ByteStringToInteger'memory'arguments'slope + | AndByteString'cpu'arguments'intercept + | AndByteString'cpu'arguments'slope1 + | AndByteString'cpu'arguments'slope2 + | AndByteString'memory'arguments'intercept + | AndByteString'memory'arguments'slope + | OrByteString'cpu'arguments'intercept + | OrByteString'cpu'arguments'slope1 + | OrByteString'cpu'arguments'slope2 + | OrByteString'memory'arguments'intercept + | OrByteString'memory'arguments'slope + | XorByteString'cpu'arguments'intercept + | XorByteString'cpu'arguments'slope1 + | XorByteString'cpu'arguments'slope2 + | XorByteString'memory'arguments'intercept + | XorByteString'memory'arguments'slope + | ComplementByteString'cpu'arguments'intercept + | ComplementByteString'cpu'arguments'slope + | ComplementByteString'memory'arguments'intercept + | ComplementByteString'memory'arguments'slope + | ReadBit'cpu'arguments + | ReadBit'memory'arguments + | WriteBits'cpu'arguments'intercept + | WriteBits'cpu'arguments'slope + | WriteBits'memory'arguments'intercept + | WriteBits'memory'arguments'slope + | ReplicateByte'cpu'arguments'intercept + | ReplicateByte'cpu'arguments'slope + | ReplicateByte'memory'arguments'intercept + | ReplicateByte'memory'arguments'slope + | ShiftByteString'cpu'arguments'intercept + | ShiftByteString'cpu'arguments'slope + | ShiftByteString'memory'arguments'intercept + | ShiftByteString'memory'arguments'slope + | RotateByteString'cpu'arguments'intercept + | RotateByteString'cpu'arguments'slope + | RotateByteString'memory'arguments'intercept + | RotateByteString'memory'arguments'slope + | CountSetBits'cpu'arguments'intercept + | CountSetBits'cpu'arguments'slope + | CountSetBits'memory'arguments + | FindFirstSetBit'cpu'arguments'intercept + | FindFirstSetBit'cpu'arguments'slope + | FindFirstSetBit'memory'arguments + | Ripemd_160'cpu'arguments'intercept + | Ripemd_160'cpu'arguments'slope + | Ripemd_160'memory'arguments + | ExpModInteger'cpu'arguments'coefficient00 + | ExpModInteger'cpu'arguments'coefficient11 + | ExpModInteger'cpu'arguments'coefficient12 + | ExpModInteger'memory'arguments'intercept + | ExpModInteger'memory'arguments'slope + | DropList'cpu'arguments'intercept + | DropList'cpu'arguments'slope + | DropList'memory'arguments + | LengthOfArray'cpu'arguments + | LengthOfArray'memory'arguments + | ListToArray'cpu'arguments'intercept + | ListToArray'cpu'arguments'slope + | ListToArray'memory'arguments'intercept + | ListToArray'memory'arguments'slope + | IndexArray'cpu'arguments + | IndexArray'memory'arguments + deriving stock (Eq, Ord, Enum, Ix, Bounded, Generic) deriving IsParamName via (GenericParamName ParamName) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs b/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs index 8f6703e2546..d0b76cc6860 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs @@ -10,7 +10,6 @@ module PlutusLedgerApi.V2.EvaluationContext ) where import PlutusLedgerApi.Common -import PlutusLedgerApi.Common.ProtocolVersions (futurePV) import PlutusLedgerApi.V2.ParamName as V2 import PlutusCore.Builtin (CaserBuiltin (..), caseBuiltin, unavailableCaserBuiltin) @@ -42,7 +41,7 @@ mkEvaluationContext = >=> mkDynEvaluationContext PlutusV2 (\pv -> - if pv < futurePV + if pv < anonPV then unavailableCaserBuiltin $ getMajorProtocolVersion pv else CaserBuiltin caseBuiltin) [DefaultFunSemanticsVariantA, DefaultFunSemanticsVariantB] diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs b/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs index 1f6ef6f5610..4bb12385389 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs @@ -190,6 +190,8 @@ data ParamName = | VerifySchnorrSecp256k1Signature'cpu'arguments'intercept | VerifySchnorrSecp256k1Signature'cpu'arguments'slope | VerifySchnorrSecp256k1Signature'memory'arguments + -- End of original cost model parameters + -- `integerToByteString` and `byteStringToInteger` enabled in V2 at Plomin | IntegerToByteString'cpu'arguments'c0 | IntegerToByteString'cpu'arguments'c1 | IntegerToByteString'cpu'arguments'c2 @@ -200,5 +202,117 @@ data ParamName = | ByteStringToInteger'cpu'arguments'c2 | ByteStringToInteger'memory'arguments'intercept | ByteStringToInteger'memory'arguments'slope + -- Remaining parameters to be deployed in PV11 + | CekConstrCost'exBudgetCPU + | CekConstrCost'exBudgetMemory + | CekCaseCost'exBudgetCPU + | CekCaseCost'exBudgetMemory + | Bls12_381_G1_add'cpu'arguments + | Bls12_381_G1_add'memory'arguments + | Bls12_381_G1_compress'cpu'arguments + | Bls12_381_G1_compress'memory'arguments + | Bls12_381_G1_equal'cpu'arguments + | Bls12_381_G1_equal'memory'arguments + | Bls12_381_G1_hashToGroup'cpu'arguments'intercept + | Bls12_381_G1_hashToGroup'cpu'arguments'slope + | Bls12_381_G1_hashToGroup'memory'arguments + | Bls12_381_G1_neg'cpu'arguments + | Bls12_381_G1_neg'memory'arguments + | Bls12_381_G1_scalarMul'cpu'arguments'intercept + | Bls12_381_G1_scalarMul'cpu'arguments'slope + | Bls12_381_G1_scalarMul'memory'arguments + | Bls12_381_G1_uncompress'cpu'arguments + | Bls12_381_G1_uncompress'memory'arguments + | Bls12_381_G2_add'cpu'arguments + | Bls12_381_G2_add'memory'arguments + | Bls12_381_G2_compress'cpu'arguments + | Bls12_381_G2_compress'memory'arguments + | Bls12_381_G2_equal'cpu'arguments + | Bls12_381_G2_equal'memory'arguments + | Bls12_381_G2_hashToGroup'cpu'arguments'intercept + | Bls12_381_G2_hashToGroup'cpu'arguments'slope + | Bls12_381_G2_hashToGroup'memory'arguments + | Bls12_381_G2_neg'cpu'arguments + | Bls12_381_G2_neg'memory'arguments + | Bls12_381_G2_scalarMul'cpu'arguments'intercept + | Bls12_381_G2_scalarMul'cpu'arguments'slope + | Bls12_381_G2_scalarMul'memory'arguments + | Bls12_381_G2_uncompress'cpu'arguments + | Bls12_381_G2_uncompress'memory'arguments + | Bls12_381_finalVerify'cpu'arguments + | Bls12_381_finalVerify'memory'arguments + | Bls12_381_millerLoop'cpu'arguments + | Bls12_381_millerLoop'memory'arguments + | Bls12_381_mulMlResult'cpu'arguments + | Bls12_381_mulMlResult'memory'arguments + | Keccak_256'cpu'arguments'intercept + | Keccak_256'cpu'arguments'slope + | Keccak_256'memory'arguments + | Blake2b_224'cpu'arguments'intercept + | Blake2b_224'cpu'arguments'slope + | Blake2b_224'memory'arguments + | AndByteString'cpu'arguments'intercept + | AndByteString'cpu'arguments'slope1 + | AndByteString'cpu'arguments'slope2 + | AndByteString'memory'arguments'intercept + | AndByteString'memory'arguments'slope + | OrByteString'cpu'arguments'intercept + | OrByteString'cpu'arguments'slope1 + | OrByteString'cpu'arguments'slope2 + | OrByteString'memory'arguments'intercept + | OrByteString'memory'arguments'slope + | XorByteString'cpu'arguments'intercept + | XorByteString'cpu'arguments'slope1 + | XorByteString'cpu'arguments'slope2 + | XorByteString'memory'arguments'intercept + | XorByteString'memory'arguments'slope + | ComplementByteString'cpu'arguments'intercept + | ComplementByteString'cpu'arguments'slope + | ComplementByteString'memory'arguments'intercept + | ComplementByteString'memory'arguments'slope + | ReadBit'cpu'arguments + | ReadBit'memory'arguments + | WriteBits'cpu'arguments'intercept + | WriteBits'cpu'arguments'slope + | WriteBits'memory'arguments'intercept + | WriteBits'memory'arguments'slope + | ReplicateByte'cpu'arguments'intercept + | ReplicateByte'cpu'arguments'slope + | ReplicateByte'memory'arguments'intercept + | ReplicateByte'memory'arguments'slope + | ShiftByteString'cpu'arguments'intercept + | ShiftByteString'cpu'arguments'slope + | ShiftByteString'memory'arguments'intercept + | ShiftByteString'memory'arguments'slope + | RotateByteString'cpu'arguments'intercept + | RotateByteString'cpu'arguments'slope + | RotateByteString'memory'arguments'intercept + | RotateByteString'memory'arguments'slope + | CountSetBits'cpu'arguments'intercept + | CountSetBits'cpu'arguments'slope + | CountSetBits'memory'arguments + | FindFirstSetBit'cpu'arguments'intercept + | FindFirstSetBit'cpu'arguments'slope + | FindFirstSetBit'memory'arguments + | Ripemd_160'cpu'arguments'intercept + | Ripemd_160'cpu'arguments'slope + | Ripemd_160'memory'arguments + -- Not yet deployed + | ExpModInteger'cpu'arguments'coefficient00 + | ExpModInteger'cpu'arguments'coefficient11 + | ExpModInteger'cpu'arguments'coefficient12 + | ExpModInteger'memory'arguments'intercept + | ExpModInteger'memory'arguments'slope + | DropList'cpu'arguments'intercept + | DropList'cpu'arguments'slope + | DropList'memory'arguments + | LengthOfArray'cpu'arguments + | LengthOfArray'memory'arguments + | ListToArray'cpu'arguments'intercept + | ListToArray'cpu'arguments'slope + | ListToArray'memory'arguments'intercept + | ListToArray'memory'arguments'slope + | IndexArray'cpu'arguments + | IndexArray'memory'arguments deriving stock (Eq, Ord, Enum, Ix, Bounded, Generic) deriving IsParamName via (GenericParamName ParamName) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs b/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs index a1cb8b107d3..baabd1589c9 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs @@ -9,7 +9,6 @@ module PlutusLedgerApi.V3.EvaluationContext ) where import PlutusLedgerApi.Common -import PlutusLedgerApi.Common.ProtocolVersions (futurePV) import PlutusLedgerApi.V3.ParamName as V3 import PlutusCore.Builtin (CaserBuiltin (..), caseBuiltin, unavailableCaserBuiltin) @@ -41,7 +40,7 @@ mkEvaluationContext = >=> mkDynEvaluationContext PlutusV3 (\pv -> - if pv < futurePV + if pv < anonPV then unavailableCaserBuiltin $ getMajorProtocolVersion pv else CaserBuiltin caseBuiltin) [DefaultFunSemanticsVariantC] diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs index c4af4f460c1..c2e3c812d41 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs @@ -313,19 +313,22 @@ data ParamName = | Ripemd_160'cpu'arguments'intercept | Ripemd_160'cpu'arguments'slope | Ripemd_160'memory'arguments --- not enabled yet: --- | ExpModInteger'cpu'arguments --- | ExpModInteger'memory'arguments --- | DropList'cpu'arguments'intercept --- | DropList'cpu'arguments'slope --- | DropList'memory'arguments'intercept --- | DropList'memory'arguments'slope --- | LengthOfArray'cpu'arguments --- | LengthOfArray'memory'arguments --- | ListToArray'cpu'arguments --- | ListToArray'memory'arguments --- | IndexArray'cpu'arguments --- | IndexArray'memory'arguments - + -- Not yet deployed + | ExpModInteger'cpu'arguments'coefficient00 + | ExpModInteger'cpu'arguments'coefficient11 + | ExpModInteger'cpu'arguments'coefficient12 + | ExpModInteger'memory'arguments'intercept + | ExpModInteger'memory'arguments'slope + | DropList'cpu'arguments'intercept + | DropList'cpu'arguments'slope + | DropList'memory'arguments + | LengthOfArray'cpu'arguments + | LengthOfArray'memory'arguments + | ListToArray'cpu'arguments'intercept + | ListToArray'cpu'arguments'slope + | ListToArray'memory'arguments'intercept + | ListToArray'memory'arguments'slope + | IndexArray'cpu'arguments + | IndexArray'memory'arguments deriving stock (Eq, Ord, Enum, Ix, Bounded, Generic) deriving IsParamName via (GenericParamName ParamName) diff --git a/plutus-ledger-api/test/Spec/CostModelParams.hs b/plutus-ledger-api/test/Spec/CostModelParams.hs index 39fd79c7ad1..dbb4e66715a 100644 --- a/plutus-ledger-api/test/Spec/CostModelParams.hs +++ b/plutus-ledger-api/test/Spec/CostModelParams.hs @@ -10,13 +10,14 @@ import PlutusLedgerApi.Test.V3.EvaluationContext qualified as V3 import PlutusLedgerApi.V1 qualified as V1 import PlutusLedgerApi.V2 qualified as V2 import PlutusLedgerApi.V3 qualified as V3 +-- import PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCostModelParamsForTesting) import Control.Monad.Except (runExcept) import Control.Monad.Writer.Strict (WriterT (runWriterT)) import Data.Either (isRight) import Data.Foldable (for_) import Data.List.Extra (enumerate) -import Data.Set (isProperSubsetOf, isSubsetOf) +import Data.Set (isSubsetOf) import Data.Set qualified as Set import Data.Text qualified as Text import Test.Tasty.Extras (TestNested, embed, nestedGoldenVsTextPredM, testNestedNamed) @@ -28,9 +29,9 @@ tests = "CostModelParams" "costModelParams" [ embed $ testCase "length" do - 166 @=? length v1_ParamNames - 185 @=? length v2_ParamNames - 297 @=? length v3_ParamNames + 295 @=? length v1_ParamNames + 295 @=? length v2_ParamNames + 313 @=? length v3_ParamNames , embed $ testCase "tripping paramname" do for_ v1_ParamNames \p -> assertBool "tripping v1 cm params failed" $ @@ -41,15 +42,14 @@ tests = for_ v3_ParamNames \p -> assertBool "tripping v3 cm params failed" $ Just p == readParamName (showParamName p) - , -- \*** FIXME (https://github.com/IntersectMBO/plutus-private/issues/1612) !!! *** : -- The introduction of the new bitwise builtins has -- messed this up because defaultCostModelParamsForTesting is the cost -- model parameters for model C, -- which now includes the new bitwise builtins. - -- , testCase "default values costmodelparamsfortesting" do - -- defaultCostModelParamsForTesting - -- @=? Just (toCostModelParams V3.costModelParamsForTesting) - embed $ testCase "context length" do + -- , embed $ testCase "default values costmodelparamsfortesting" do + -- defaultCostModelParamsForTesting + -- @=? Just (toCostModelParams V3.costModelParamsForTesting) + , embed $ testCase "context length" do let costValuesForTesting = fmap snd V3.costModelParamsForTesting -- the `costModelParamsForTesting` reflects only the latest -- version (V3), so this should succeed because the lengths match @@ -71,10 +71,10 @@ tests = $ V3.mkEvaluationContext $ costValuesForTesting ++ [1] -- dummy param value appended , embed $ testCase "cost model parameters" do - -- v1 is missing some cost model parameters - -- because new builtins are added in v2 - assertBool "v1 params is not a proper subset of v2 params" $ - v1_ParamNames `paramProperSubset` v2_ParamNames + -- From PV11, the v1 and v2 parameter names are identical; before PV11 + -- the v1 parameter names were a subset of the v2 ones. + assertBool "v1 params is not equal to v2 params" $ + v1_ParamNames `paramEqual` v2_ParamNames -- v1/v2 and v3 cost models are not comparable because we added -- new builtins in v3 but also removed some superseded cost model -- parameters. @@ -100,14 +100,12 @@ tests = | testExpected == cmExpected && testActual == cmActual = True hasWarnMoreParams _ _ _ = False - paramProperSubset pA pB = - Set.fromList (showParamName <$> pA) - `isProperSubsetOf` Set.fromList (showParamName <$> pB) - paramSubset pA pB = Set.fromList (showParamName <$> pA) `isSubsetOf` Set.fromList (showParamName <$> pB) + paramEqual pA pB = paramSubset pA pB && paramSubset pB pA + v1_ParamNames = enumerate @V1.ParamName v2_ParamNames = enumerate @V2.ParamName v3_ParamNames = enumerate @V3.ParamName diff --git a/plutus-ledger-api/test/Spec/Data/CostModelParams.hs b/plutus-ledger-api/test/Spec/Data/CostModelParams.hs index d9c9bc06b36..3dfe9c1d3fc 100644 --- a/plutus-ledger-api/test/Spec/Data/CostModelParams.hs +++ b/plutus-ledger-api/test/Spec/Data/CostModelParams.hs @@ -16,7 +16,7 @@ import Control.Monad.Writer.Strict (WriterT (runWriterT)) import Data.Either (isRight) import Data.Foldable (for_) import Data.List.Extra (enumerate) -import Data.Set (isProperSubsetOf, isSubsetOf) +import Data.Set (isSubsetOf) import Data.Set qualified as Set import Data.Text qualified as Text import Test.Tasty.Extras (TestNested, embed, nestedGoldenVsTextPredM, testNestedNamed) @@ -28,9 +28,9 @@ tests = "CostModelParams" "costModelParams" [ embed $ testCase "length" do - 166 @=? length v1_ParamNames - 185 @=? length v2_ParamNames - 297 @=? length v3_ParamNames + 295 @=? length v1_ParamNames + 295 @=? length v2_ParamNames + 313 @=? length v3_ParamNames , embed $ testCase "tripping paramname" do for_ v1_ParamNames \p -> assertBool "tripping v1 cm params failed" $ @@ -71,10 +71,10 @@ tests = $ V3.mkEvaluationContext $ costValuesForTesting ++ [1] -- dummy param value appended , embed $ testCase "cost model parameters" do - -- v1 is missing some cost model parameters - -- because new builtins are added in v2 - assertBool "v1 params is not a proper subset of v2 params" $ - v1_ParamNames `paramProperSubset` v2_ParamNames + -- From PV11, the v1 and v2 parameter names are identical; before PV11 + -- the v1 parameter names were a subset of the v2 ones. + assertBool "v1 params is not equal to v2 params" $ + v1_ParamNames `paramEqual` v2_ParamNames -- v1/v2 and v3 cost models are not comparable because we added -- new builtins in v3 but also removed some superseded cost model -- parameters. @@ -100,14 +100,12 @@ tests = | testExpected == cmExpected && testActual == cmActual = True hasWarnMoreParams _ _ _ = False - paramProperSubset pA pB = - Set.fromList (showParamName <$> pA) - `isProperSubsetOf` Set.fromList (showParamName <$> pB) - paramSubset pA pB = Set.fromList (showParamName <$> pA) `isSubsetOf` Set.fromList (showParamName <$> pB) + paramEqual pA pB = paramSubset pA pB && paramSubset pB pA + v1_ParamNames = enumerate @V1.ParamName v2_ParamNames = enumerate @V2.ParamName v3_ParamNames = enumerate @V3.ParamName diff --git a/plutus-ledger-api/test/Spec/Data/Eval.hs b/plutus-ledger-api/test/Spec/Data/Eval.hs index eb04fbd3e8f..f807c78bd87 100644 --- a/plutus-ledger-api/test/Spec/Data/Eval.hs +++ b/plutus-ledger-api/test/Spec/Data/Eval.hs @@ -29,7 +29,6 @@ import Control.Monad.Writer import Data.Int (Int64) import Data.Map qualified as Map import Data.Maybe (fromJust) -import Data.Set qualified as Set import NoThunks.Class import Test.Tasty import Test.Tasty.Extras (ignoreTestWhenHpcEnabled) @@ -112,7 +111,7 @@ evaluationContextCacheIsComplete = testGroup "EvaluationContext has machine parameters for all protocol versions" $ enumerate <&> \ll -> testCase (show ll) $ do evalCtx <- mkEvaluationContextV ll - for_ (Set.insert futurePV knownPVs) $ \pv -> + for_ (futurePV:knownPVs) $ \pv -> evaluate $ toMachineParameters pv evalCtx failIfThunk :: Show a => Maybe a -> IO () diff --git a/plutus-ledger-api/test/Spec/Data/Versions.hs b/plutus-ledger-api/test/Spec/Data/Versions.hs index ef2e2584f73..24dc00d348e 100644 --- a/plutus-ledger-api/test/Spec/Data/Versions.hs +++ b/plutus-ledger-api/test/Spec/Data/Versions.hs @@ -1,27 +1,25 @@ -- editorconfig-checker-disable-file {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -Wno-orphans #-} + module Spec.Data.Versions (tests) where import PlutusCore as PLC -import PlutusCore.Data as PLC import PlutusCore.MkPlc as PLC import PlutusCore.Version as PLC import PlutusLedgerApi.Common -import PlutusLedgerApi.Common.Versions import PlutusPrelude import UntypedPlutusCore as UPLC +import PlutusLedgerApi.Common.Versions + import PlutusLedgerApi.Data.V1 qualified as V1 import PlutusLedgerApi.Data.V2 qualified as V2 import PlutusLedgerApi.Data.V3 qualified as V3 -import PlutusLedgerApi.Test.Scripts -import Data.ByteString qualified as BS import Data.ByteString.Short qualified as BSS import Data.Either -import Data.Map qualified as Map +import Data.List ((\\)) import Data.Set qualified as Set import Test.Tasty import Test.Tasty.HUnit @@ -30,22 +28,78 @@ import Test.Tasty.QuickCheck tests :: TestTree tests = testGroup "versions" [ testLedgerLanguages - , testBuiltinVersions , testLanguageVersions + , testPermittedBuiltins , testRmdr ] +allPVs :: [MajorProtocolVersion] +allPVs = [ shelleyPV .. newestPV ] + +showPV :: MajorProtocolVersion -> String +showPV (MajorProtocolVersion pv) = + case pv of + 2 -> "Shelley (PV2)" + 3 -> "Allegra (PV3)" + 4 -> "Mary (PV4)" + 5 -> "Alonzo (PV5)" + 6 -> "(Lobster) (PV6)" + 7 -> "Vasil (PV7)" + 8 -> "Valentine (PV8)" + 9 -> "Chang (PV9)" + 10 -> "Plomin (PV10)" + 11 -> "Anon (PV11)" + _ -> " (PV" ++ show pv ++ ")" + +-- Some scripts for use in the version tests. +errorScript :: SerialisedScript +errorScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ UPLC.Error () + +v110script :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () +v110script = UPLC.Program () PLC.plcVersion110 $ UPLC.Constr () 0 mempty + +badConstrScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () +badConstrScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Constr () 0 mempty + +badCaseScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () +badCaseScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Case () (UPLC.Error ()) mempty + +{- Given a UPLC term, serialise it then deserialise it for use in a particular + LL/PV combination, checking whether or not it deserialises successfully. See + Note [Checking the Plutus Core language version] for why this has to use + `mkTermToEvaluate`. Both `deserialiseScript` and `mkTermToEvaluate` can + produce script decoding errors (for different reasons) and we intercept these + and return them as `Left` values. Any other errors will cause `error` to be + invoked. +-} +mkTestTerm + :: PlutusLedgerLanguage + -> MajorProtocolVersion + -> UPLC.Program DeBruijn DefaultUni DefaultFun () + -> Either ScriptDecodeError (UPLC.Term NamedDeBruijn DefaultUni DefaultFun ()) +mkTestTerm ll pv prog = + case deserialiseScript ll pv $ serialiseUPLC prog + of Right s -> + case mkTermToEvaluate ll pv s [] + of Right t -> Right t + Left (CodecError e) -> Left e + Left e -> Prelude.error $ show e + Left e -> Left e + +-- Test that the different Plutus Core ledger languages are available in the +-- expected protocol versions and not in others. testLedgerLanguages :: TestTree testLedgerLanguages = testGroup "ledger languages" - [ testProperty "v1 not before but after" $ prop_notBeforeButAfter V1.deserialiseScript alonzoPV - , testProperty "v2 not before but after" $ prop_notBeforeButAfter V2.deserialiseScript vasilPV - , testProperty "v3 not before but after" $ prop_notBeforeButAfter V3.deserialiseScript changPV + [ testProperty "PlutusV1 not before but after" $ prop_notBeforeButAfter V1.deserialiseScript alonzoPV + , testProperty "PlutusV2 not before but after" $ prop_notBeforeButAfter V2.deserialiseScript vasilPV + , testProperty "PlutusV3 not before but after" $ prop_notBeforeButAfter V3.deserialiseScript changPV , testProperty "protocol-versions can add but not remove ledger languages" $ \pvA pvB -> pvA < pvB ==> ledgerLanguagesAvailableIn pvA `Set.isSubsetOf` ledgerLanguagesAvailableIn pvB ] where - prop_notBeforeButAfter :: (MajorProtocolVersion -> SerialisedScript -> Either ScriptDecodeError b) - -> MajorProtocolVersion -> MajorProtocolVersion -> Bool + prop_notBeforeButAfter + :: (MajorProtocolVersion -> SerialisedScript -> Either ScriptDecodeError b) + -> MajorProtocolVersion -> MajorProtocolVersion -> Bool prop_notBeforeButAfter phase1Func expectedPv genPv = -- run phase 1 on an example script let resPhase1 = phase1Func genPv errorScript @@ -58,35 +112,153 @@ testLedgerLanguages = testGroup "ledger languages" -- generated an eq or gt the expected protocol version else isRight resPhase1 -deriving newtype instance Arbitrary MajorProtocolVersion +-- Test that the different Plutus Core language versions are available in the +-- expected LL/PV combinations. +testLanguageVersions :: TestTree +testLanguageVersions = + testGroup "Plutus Core language versions" $ + let expectGood prog ll pv = + testCase ("Ok in " ++ showPV pv) $ + assertBool ("v110" ++ " not allowed in " ++ show ll ++" @" ++ showPV pv) $ + isRight $ mkTestTerm ll pv prog + expectBad prog ll pv = + testCase ("Not in " ++ showPV pv) $ + assertBool ("v110" ++ " should not be allowed in " ++ show ll ++" @" ++ showPV pv) $ + isLeft $ mkTestTerm ll pv prog + testOkFrom ll firstGood prog = + let expectedGood = [ firstGood .. newestPV ] + in testGroup (show ll) $ + fmap (expectBad prog ll) (allPVs \\ expectedGood) ++ + fmap (expectGood prog ll) expectedGood + in [ testGroup "v1.1.0 availability" + [ testOkFrom PlutusV1 newestPV v110script + , testOkFrom PlutusV2 newestPV v110script + , testOkFrom PlutusV3 changPV v110script + ] + -- Check that case and constr are not allowed in 1.1.0 in any LL/PV combination + , testCase "case is not available in v1.0.0 ever" $ + sequence_ [ assertBool ("case unexpectedly allowed in " ++ show ll ++ " @PV" ++ show pv) $ + isLeft $ mkTestTerm ll pv badCaseScript + | ll <- enumerate, pv <- allPVs ] + + , testCase "constr is not available in v1.0.0 ever" $ + sequence_ [ assertBool ("constr unexpectedly allowed in " ++ show ll ++ " @PV" ++ show pv) $ + isLeft $ mkTestTerm ll pv badConstrScript + | ll <- enumerate, pv <- allPVs ] + ] + +-- Testing deserialisation checks for builtins + +{- | Make small scripts containing each builtin and check that the expected + builtins are successfully deserialised in each PV/LL combination (and + unexpected builtins cause an error during deserialisation. These MUST BE + EXTENDED when new builtins are deployed. +-} +-- Should we test plcVersion110 as well? +mkScriptForBuiltin :: DefaultFun -> (String, SerialisedScript) +mkScriptForBuiltin fun = + (show fun, serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ builtin () fun) + +mkScriptsForBuiltins :: [DefaultFun] -> [(String, SerialisedScript)] +mkScriptsForBuiltins = fmap mkScriptForBuiltin + +builtins1 :: [(String, SerialisedScript)] +builtins1 = mkScriptsForBuiltins batch1 -testBuiltinVersions :: TestTree -testBuiltinVersions = testGroup "builtins" - [ testCase "all builtins are available some time" $ - let allPvBuiltins = fold $ Map.elems builtinsIntroducedIn - allBuiltins = enumerate @DefaultFun - in for_ allBuiltins $ \f -> assertBool (show f) (f `Set.member` allPvBuiltins) - , testCase "builtins aren't available before Alonzo" $ - assertBool "empty" (Set.null $ builtinsAvailableIn PlutusV1 maryPV) - , testCase "serializeData is only available in l2,Vasil and after" $ do - assertBool "in l1,Alonzo" $ isLeft $ V1.deserialiseScript alonzoPV serialiseDataExScript - assertBool "in l1,Vasil" $ isLeft $ V1.deserialiseScript vasilPV serialiseDataExScript - assertBool "in l2,Alonzo" $ isLeft $ V2.deserialiseScript alonzoPV serialiseDataExScript - assertBool "in l3,Alonzo" $ isLeft $ V3.deserialiseScript alonzoPV serialiseDataExScript - assertBool "not in l2,Vasil" $ isRight $ V2.deserialiseScript vasilPV serialiseDataExScript - assertBool "not in l3,future" $ isRight $ V3.deserialiseScript futurePV serialiseDataExScript - , testCase "bls,keccak256,blake2b224 only available in l3,Future and after" $ - for_ [blsExScript, keccak256ExScript, blake2b224ExScript] $ \script -> do - assertBool "in l1,Alonzo" $ isLeft $ V1.deserialiseScript alonzoPV script - assertBool "in l1,Vasil" $ isLeft $ V1.deserialiseScript vasilPV script - assertBool "in l2,Alonzo" $ isLeft $ V2.deserialiseScript alonzoPV script - assertBool "in l3,Alonzo" $ isLeft $ V3.deserialiseScript alonzoPV script - assertBool "in l2,Valentine" $ isLeft $ V2.deserialiseScript valentinePV script - assertBool "not in l3,future" $ isRight $ V3.deserialiseScript futurePV script +builtins2 :: [(String, SerialisedScript)] +builtins2 = mkScriptsForBuiltins batch2 + +builtins3 :: [(String, SerialisedScript)] +builtins3 = mkScriptsForBuiltins batch3 + +builtins4a :: [(String, SerialisedScript)] +builtins4a = mkScriptsForBuiltins batch4a + +builtins4b :: [(String, SerialisedScript)] +builtins4b = mkScriptsForBuiltins batch4b + +builtins5 :: [(String, SerialisedScript)] +builtins5 = mkScriptsForBuiltins batch5 + +builtins6 :: [(String, SerialisedScript)] +builtins6 = mkScriptsForBuiltins batch6 + +allBuiltins :: [(String, SerialisedScript)] +allBuiltins = builtins1 ++ builtins2 + ++ builtins3 ++ builtins4a + ++ builtins4b ++ builtins5 + ++ builtins6 + +{-| Test that the builtins that we expect to be allowed in each LL/PV + combination can be successfully deserialised and that the rest cannot. This + is mostly testing that `builtinsAvailableIn` does what it's supposed to. + This should be updated when new builtins, ledger languages, or protocol + versions are added, but we expect that after Anon all builtins will be + allowed in all ledger languages. +-} +{- FIXME: Ideally we'd test that for PV11 scripts, all of the newer builtins + have the same cost in each Plutus ledger language. That would involve having + appropriate sets of cost model parameters to feed into the parameter update + process though. +-} +testPermittedBuiltins :: TestTree +testPermittedBuiltins = + let testBuiltins ll deserialise pv expectedGood = + let expectGood scripts = + for_ scripts $ \(name, script) -> + assertBool (name ++ " not allowed in " ++ show ll ++" @" ++ showPV pv) $ + isRight $ deserialise pv script + expectBad scripts = + for_ scripts $ \(name, script) -> + assertBool (name ++ " should be allowed in " ++ show ll ++" @" ++ showPV pv) $ + isLeft $ deserialise pv script + in testCase (showPV pv) $ do + expectGood expectedGood + expectBad (allBuiltins \\ expectedGood) + in testGroup "Builtins allowed" + [ let mkTest = testBuiltins PlutusV1 V1.deserialiseScript + in testGroup "PlutusV1" + [ mkTest shelleyPV [] + , mkTest allegraPV [] + , mkTest maryPV [] + , mkTest alonzoPV builtins1 + , mkTest vasilPV builtins1 + , mkTest valentinePV builtins1 + , mkTest changPV builtins1 + , mkTest plominPV builtins1 + , mkTest newestPV allBuiltins + ] + , let mkTest = testBuiltins PlutusV2 V2.deserialiseScript + in testGroup "PlutusV2" + [ mkTest shelleyPV [] + , mkTest allegraPV [] + , mkTest maryPV [] + , mkTest alonzoPV [] + , mkTest vasilPV $ builtins1 ++ builtins2 + , mkTest valentinePV $ builtins1 ++ builtins2 ++ builtins3 + , mkTest changPV $ builtins1 ++ builtins2 ++ builtins3 + , mkTest plominPV $ builtins1 ++ builtins2 ++ builtins3 ++ builtins4b + , mkTest newestPV allBuiltins + ] + , let mkTest = testBuiltins PlutusV3 V3.deserialiseScript + in testGroup "PlutusV3" + [ mkTest shelleyPV [] + , mkTest allegraPV [] + , mkTest maryPV [] + , mkTest alonzoPV [] + , mkTest vasilPV [] + , mkTest valentinePV [] + , mkTest changPV $ builtins1 ++ builtins2 ++ builtins3 ++ builtins4a ++ builtins4b + , mkTest plominPV $ builtins1 ++ builtins2 ++ builtins3 ++ builtins4a ++ builtins4b ++ builtins5 + , mkTest newestPV allBuiltins + ] ] +-- Test that the checks for extra bytes after ends of scripts behave properly. +deriving newtype instance Arbitrary MajorProtocolVersion + testRmdr :: TestTree -testRmdr = testGroup "rmdr" +testRmdr = testGroup "extra bytes after end of script" [ testCase "remdr" $ do assertBool "remdr1" $ isRight $ V1.deserialiseScript valentinePV $ errorScript <> "remdr1" assertBool "remdr2" $ isRight $ V2.deserialiseScript valentinePV $ errorScript <> "remdr2" @@ -100,51 +272,3 @@ testRmdr = testGroup "rmdr" -- we cannot make the same property as above for remdr3gen because it may generate valid bytestring append extensions to the original script -- a more sophisticated one could work though ] - --- See Note [Checking the Plutus Core language version] for why these have to use mkTermToEvaluate -testLanguageVersions :: TestTree -testLanguageVersions = testGroup "Plutus Core language versions" - [ testCase "v1.1.0 is available in l3,future and not before" $ do - -- `LedgerLanguageNotAvailableError` is checked in `deserialiseScript` - assertBool "in l3,Vasil" $ isLeft $ uplcToScriptForEvaluation PlutusV3 vasilPV v110script - -- `PlutusCoreLanguageNotAvailableError` is checked in `mkTermToEvaluate` - assertBool "in l2,future" $ isLeft $ mkTermToEvaluate PlutusV2 changPV (either (Prelude.error . show) id (V2.deserialiseScript changPV $ serialiseUPLC v110script)) [] - -- Both `deserialiseScript` and `mkTermToEvaluate` should succeed - assertBool "not in l3,future" $ isRight $ mkTermToEvaluate PlutusV3 changPV (either (Prelude.error . show) id (V3.deserialiseScript changPV $ serialiseUPLC v110script)) [] - -- The availability of `case` and `constr` is checked in `deserialise` - , testCase "constr is not available with v1.0.0 ever" $ assertBool "in l3,future" $ isLeft $ uplcToScriptForEvaluation PlutusV3 changPV badConstrScript - , testCase "case is not available with v1.0.0 ever" $ assertBool "in l3,future" $ isLeft $ uplcToScriptForEvaluation PlutusV3 changPV badCaseScript - ] - --- * UPLC written examples to test - -serialiseDataExScript :: SerialisedScript -serialiseDataExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - UPLC.Apply () (UPLC.Builtin () PLC.SerialiseData) (PLC.mkConstant () $ I 1) - -errorScript :: SerialisedScript -errorScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ UPLC.Error () - -v110script :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () -v110script = UPLC.Program () PLC.plcVersion110 $ UPLC.Constr () 0 mempty - -badConstrScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () -badConstrScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Constr () 0 mempty - -badCaseScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () -badCaseScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Case () (UPLC.Error ()) mempty - --- Note that bls can work also with plcversion==1.0.0 -blsExScript :: SerialisedScript -blsExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - builtin () Bls12_381_G1_uncompress @@ [mkConstant () $ BS.pack (0xc0 : replicate 47 0x00)] - --- Note that keccak can work also with plcversion==1.0.0 -keccak256ExScript :: SerialisedScript -keccak256ExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - builtin () Keccak_256 @@ [mkConstant @BS.ByteString () "hashme"] - --- Note that blake2b224 can work also with plcversion==1.0.0 -blake2b224ExScript :: SerialisedScript -blake2b224ExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - builtin () Blake2b_224 @@ [mkConstant @BS.ByteString () "hashme"] diff --git a/plutus-ledger-api/test/Spec/Eval.hs b/plutus-ledger-api/test/Spec/Eval.hs index ec20c0e45f1..e8b61b03ac1 100644 --- a/plutus-ledger-api/test/Spec/Eval.hs +++ b/plutus-ledger-api/test/Spec/Eval.hs @@ -29,7 +29,6 @@ import Control.Monad.Writer import Data.Int (Int64) import Data.Map qualified as Map import Data.Maybe (fromJust) -import Data.Set qualified as Set import NoThunks.Class import Test.Tasty import Test.Tasty.Extras (ignoreTestWhenHpcEnabled) @@ -112,7 +111,7 @@ evaluationContextCacheIsComplete = testGroup "EvaluationContext has machine parameters for all protocol versions" $ enumerate <&> \ll -> testCase (show ll) $ do evalCtx <- mkEvaluationContextV ll - for_ (Set.insert futurePV knownPVs) $ \pv -> + for_ (futurePV:knownPVs) $ \pv -> evaluate $ toMachineParameters pv evalCtx failIfThunk :: Show a => Maybe a -> IO () diff --git a/plutus-ledger-api/test/Spec/Versions.hs b/plutus-ledger-api/test/Spec/Versions.hs index 093247a4e69..aa276acec12 100644 --- a/plutus-ledger-api/test/Spec/Versions.hs +++ b/plutus-ledger-api/test/Spec/Versions.hs @@ -1,27 +1,25 @@ -- editorconfig-checker-disable-file {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -Wno-orphans #-} + module Spec.Versions (tests) where import PlutusCore as PLC -import PlutusCore.Data as PLC import PlutusCore.MkPlc as PLC import PlutusCore.Version as PLC import PlutusLedgerApi.Common -import PlutusLedgerApi.Common.Versions import PlutusPrelude import UntypedPlutusCore as UPLC -import PlutusLedgerApi.Test.Scripts +import PlutusLedgerApi.Common.Versions + import PlutusLedgerApi.V1 qualified as V1 import PlutusLedgerApi.V2 qualified as V2 import PlutusLedgerApi.V3 qualified as V3 -import Data.ByteString qualified as BS import Data.ByteString.Short qualified as BSS import Data.Either -import Data.Map qualified as Map +import Data.List ((\\)) import Data.Set qualified as Set import Test.Tasty import Test.Tasty.HUnit @@ -30,22 +28,78 @@ import Test.Tasty.QuickCheck tests :: TestTree tests = testGroup "versions" [ testLedgerLanguages - , testBuiltinVersions , testLanguageVersions + , testPermittedBuiltins , testRmdr ] +allPVs :: [MajorProtocolVersion] +allPVs = [ shelleyPV .. newestPV ] + +showPV :: MajorProtocolVersion -> String +showPV (MajorProtocolVersion pv) = + case pv of + 2 -> "Shelley (PV2)" + 3 -> "Allegra (PV3)" + 4 -> "Mary (PV4)" + 5 -> "Alonzo (PV5)" + 6 -> "(Lobster) (PV6)" + 7 -> "Vasil (PV7)" + 8 -> "Valentine (PV8)" + 9 -> "Chang (PV9)" + 10 -> "Plomin (PV10)" + 11 -> "Anon (PV11)" + _ -> " (PV" ++ show pv ++ ")" + +-- Some scripts for use in the version tests. +errorScript :: SerialisedScript +errorScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ UPLC.Error () + +v110script :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () +v110script = UPLC.Program () PLC.plcVersion110 $ UPLC.Constr () 0 mempty + +badConstrScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () +badConstrScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Constr () 0 mempty + +badCaseScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () +badCaseScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Case () (UPLC.Error ()) mempty + +{- Given a UPLC term, serialise it then deserialise it for use in a particular + LL/PV combination, checking whether or not it deserialises successfully. See + Note [Checking the Plutus Core language version] for why this has to use + `mkTermToEvaluate`. Both `deserialiseScript` and `mkTermToEvaluate` can + produce script decoding errors (for different reasons) and we intercept these + and return them as `Left` values. Any other errors will cause `error` to be + invoked. +-} +mkTestTerm + :: PlutusLedgerLanguage + -> MajorProtocolVersion + -> UPLC.Program DeBruijn DefaultUni DefaultFun () + -> Either ScriptDecodeError (UPLC.Term NamedDeBruijn DefaultUni DefaultFun ()) +mkTestTerm ll pv prog = + case deserialiseScript ll pv $ serialiseUPLC prog + of Right s -> + case mkTermToEvaluate ll pv s [] + of Right t -> Right t + Left (CodecError e) -> Left e + Left e -> Prelude.error $ show e + Left e -> Left e + +-- Test that the different Plutus Core ledger languages are available in the +-- expected protocol versions and not in others. testLedgerLanguages :: TestTree testLedgerLanguages = testGroup "ledger languages" - [ testProperty "v1 not before but after" $ prop_notBeforeButAfter V1.deserialiseScript alonzoPV - , testProperty "v2 not before but after" $ prop_notBeforeButAfter V2.deserialiseScript vasilPV - , testProperty "v3 not before but after" $ prop_notBeforeButAfter V3.deserialiseScript changPV + [ testProperty "PlutusV1 not before but after" $ prop_notBeforeButAfter V1.deserialiseScript alonzoPV + , testProperty "PlutusV2 not before but after" $ prop_notBeforeButAfter V2.deserialiseScript vasilPV + , testProperty "PlutusV3 not before but after" $ prop_notBeforeButAfter V3.deserialiseScript changPV , testProperty "protocol-versions can add but not remove ledger languages" $ \pvA pvB -> pvA < pvB ==> ledgerLanguagesAvailableIn pvA `Set.isSubsetOf` ledgerLanguagesAvailableIn pvB ] where - prop_notBeforeButAfter :: (MajorProtocolVersion -> SerialisedScript -> Either ScriptDecodeError b) - -> MajorProtocolVersion -> MajorProtocolVersion -> Bool + prop_notBeforeButAfter + :: (MajorProtocolVersion -> SerialisedScript -> Either ScriptDecodeError b) + -> MajorProtocolVersion -> MajorProtocolVersion -> Bool prop_notBeforeButAfter phase1Func expectedPv genPv = -- run phase 1 on an example script let resPhase1 = phase1Func genPv errorScript @@ -58,35 +112,153 @@ testLedgerLanguages = testGroup "ledger languages" -- generated an eq or gt the expected protocol version else isRight resPhase1 -deriving newtype instance Arbitrary MajorProtocolVersion +-- Test that the different Plutus Core language versions are available in the +-- expected LL/PV combinations. +testLanguageVersions :: TestTree +testLanguageVersions = + testGroup "Plutus Core language versions" $ + let expectGood prog ll pv = + testCase ("Ok in " ++ showPV pv) $ + assertBool ("v110" ++ " not allowed in " ++ show ll ++" @" ++ showPV pv) $ + isRight $ mkTestTerm ll pv prog + expectBad prog ll pv = + testCase ("Not in " ++ showPV pv) $ + assertBool ("v110" ++ " should not be allowed in " ++ show ll ++" @" ++ showPV pv) $ + isLeft $ mkTestTerm ll pv prog + testOkFrom ll firstGood prog = + let expectedGood = [ firstGood .. newestPV ] + in testGroup (show ll) $ + fmap (expectBad prog ll) (allPVs \\ expectedGood) ++ + fmap (expectGood prog ll) expectedGood + in [ testGroup "v1.1.0 availability" + [ testOkFrom PlutusV1 newestPV v110script + , testOkFrom PlutusV2 newestPV v110script + , testOkFrom PlutusV3 changPV v110script + ] + -- Check that case and constr are not allowed in 1.1.0 in any LL/PV combination + , testCase "case is not available in v1.0.0 ever" $ + sequence_ [ assertBool ("case unexpectedly allowed in " ++ show ll ++ " @PV" ++ show pv) $ + isLeft $ mkTestTerm ll pv badCaseScript + | ll <- enumerate, pv <- allPVs ] + + , testCase "constr is not available in v1.0.0 ever" $ + sequence_ [ assertBool ("constr unexpectedly allowed in " ++ show ll ++ " @PV" ++ show pv) $ + isLeft $ mkTestTerm ll pv badConstrScript + | ll <- enumerate, pv <- allPVs ] + ] + +-- Testing deserialisation checks for builtins + +{- | Make small scripts containing each builtin and check that the expected + builtins are successfully deserialised in each PV/LL combination (and + unexpected builtins cause an error during deserialisation. These MUST BE + EXTENDED when new builtins are deployed. +-} +-- Should we test plcVersion110 as well? +mkScriptForBuiltin :: DefaultFun -> (String, SerialisedScript) +mkScriptForBuiltin fun = + (show fun, serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ builtin () fun) + +mkScriptsForBuiltins :: [DefaultFun] -> [(String, SerialisedScript)] +mkScriptsForBuiltins = fmap mkScriptForBuiltin + +builtins1 :: [(String, SerialisedScript)] +builtins1 = mkScriptsForBuiltins batch1 -testBuiltinVersions :: TestTree -testBuiltinVersions = testGroup "builtins" - [ testCase "all builtins are available some time" $ - let allPvBuiltins = fold $ Map.elems builtinsIntroducedIn - allBuiltins = enumerate @DefaultFun - in for_ allBuiltins $ \f -> assertBool (show f) (f `Set.member` allPvBuiltins) - , testCase "builtins aren't available before Alonzo" $ - assertBool "empty" (Set.null $ builtinsAvailableIn PlutusV1 maryPV) - , testCase "serializeData is only available in l2,Vasil and after" $ do - assertBool "in l1,Alonzo" $ isLeft $ V1.deserialiseScript alonzoPV serialiseDataExScript - assertBool "in l1,Vasil" $ isLeft $ V1.deserialiseScript vasilPV serialiseDataExScript - assertBool "in l2,Alonzo" $ isLeft $ V2.deserialiseScript alonzoPV serialiseDataExScript - assertBool "in l3,Alonzo" $ isLeft $ V3.deserialiseScript alonzoPV serialiseDataExScript - assertBool "not in l2,Vasil" $ isRight $ V2.deserialiseScript vasilPV serialiseDataExScript - assertBool "not in l3,future" $ isRight $ V3.deserialiseScript futurePV serialiseDataExScript - , testCase "bls,keccak256,blake2b224 only available in l3,Future and after" $ - for_ [blsExScript, keccak256ExScript, blake2b224ExScript] $ \script -> do - assertBool "in l1,Alonzo" $ isLeft $ V1.deserialiseScript alonzoPV script - assertBool "in l1,Vasil" $ isLeft $ V1.deserialiseScript vasilPV script - assertBool "in l2,Alonzo" $ isLeft $ V2.deserialiseScript alonzoPV script - assertBool "in l3,Alonzo" $ isLeft $ V3.deserialiseScript alonzoPV script - assertBool "in l2,Valentine" $ isLeft $ V2.deserialiseScript valentinePV script - assertBool "not in l3,future" $ isRight $ V3.deserialiseScript futurePV script +builtins2 :: [(String, SerialisedScript)] +builtins2 = mkScriptsForBuiltins batch2 + +builtins3 :: [(String, SerialisedScript)] +builtins3 = mkScriptsForBuiltins batch3 + +builtins4a :: [(String, SerialisedScript)] +builtins4a = mkScriptsForBuiltins batch4a + +builtins4b :: [(String, SerialisedScript)] +builtins4b = mkScriptsForBuiltins batch4b + +builtins5 :: [(String, SerialisedScript)] +builtins5 = mkScriptsForBuiltins batch5 + +builtins6 :: [(String, SerialisedScript)] +builtins6 = mkScriptsForBuiltins batch6 + +allBuiltins :: [(String, SerialisedScript)] +allBuiltins = builtins1 ++ builtins2 + ++ builtins3 ++ builtins4a + ++ builtins4b ++ builtins5 + ++ builtins6 + +{-| Test that the builtins that we expect to be allowed in each LL/PV + combination can be successfully deserialised and that the rest cannot. This + is mostly testing that `builtinsAvailableIn` does what it's supposed to. + This should be updated when new builtins, ledger languages, or protocol + versions are added, but we expect that after Anon all builtins will be + allowed in all ledger languages. +-} +{- FIXME: Ideally we'd test that for PV11 scripts, all of the newer builtins + have the same cost in each Plutus ledger language. That would involve having + appropriate sets of cost model parameters to feed into the parameter update + process though. +-} +testPermittedBuiltins :: TestTree +testPermittedBuiltins = + let testBuiltins ll deserialise pv expectedGood = + let expectGood scripts = + for_ scripts $ \(name, script) -> + assertBool (name ++ " not allowed in " ++ show ll ++" @" ++ showPV pv) $ + isRight $ deserialise pv script + expectBad scripts = + for_ scripts $ \(name, script) -> + assertBool (name ++ " should be allowed in " ++ show ll ++" @" ++ showPV pv) $ + isLeft $ deserialise pv script + in testCase (showPV pv) $ do + expectGood expectedGood + expectBad (allBuiltins \\ expectedGood) + in testGroup "Builtins allowed" + [ let mkTest = testBuiltins PlutusV1 V1.deserialiseScript + in testGroup "PlutusV1" + [ mkTest shelleyPV [] + , mkTest allegraPV [] + , mkTest maryPV [] + , mkTest alonzoPV builtins1 + , mkTest vasilPV builtins1 + , mkTest valentinePV builtins1 + , mkTest changPV builtins1 + , mkTest plominPV builtins1 + , mkTest newestPV allBuiltins + ] + , let mkTest = testBuiltins PlutusV2 V2.deserialiseScript + in testGroup "PlutusV2" + [ mkTest shelleyPV [] + , mkTest allegraPV [] + , mkTest maryPV [] + , mkTest alonzoPV [] + , mkTest vasilPV $ builtins1 ++ builtins2 + , mkTest valentinePV $ builtins1 ++ builtins2 ++ builtins3 + , mkTest changPV $ builtins1 ++ builtins2 ++ builtins3 + , mkTest plominPV $ builtins1 ++ builtins2 ++ builtins3 ++ builtins4b + , mkTest newestPV allBuiltins + ] + , let mkTest = testBuiltins PlutusV3 V3.deserialiseScript + in testGroup "PlutusV3" + [ mkTest shelleyPV [] + , mkTest allegraPV [] + , mkTest maryPV [] + , mkTest alonzoPV [] + , mkTest vasilPV [] + , mkTest valentinePV [] + , mkTest changPV $ builtins1 ++ builtins2 ++ builtins3 ++ builtins4a ++ builtins4b + , mkTest plominPV $ builtins1 ++ builtins2 ++ builtins3 ++ builtins4a ++ builtins4b ++ builtins5 + , mkTest newestPV allBuiltins + ] ] +-- Test that the checks for extra bytes after ends of scripts behave properly. +deriving newtype instance Arbitrary MajorProtocolVersion + testRmdr :: TestTree -testRmdr = testGroup "rmdr" +testRmdr = testGroup "extra bytes after end of script" [ testCase "remdr" $ do assertBool "remdr1" $ isRight $ V1.deserialiseScript valentinePV $ errorScript <> "remdr1" assertBool "remdr2" $ isRight $ V2.deserialiseScript valentinePV $ errorScript <> "remdr2" @@ -100,51 +272,3 @@ testRmdr = testGroup "rmdr" -- we cannot make the same property as above for remdr3gen because it may generate valid bytestring append extensions to the original script -- a more sophisticated one could work though ] - --- See Note [Checking the Plutus Core language version] for why these have to use mkTermToEvaluate -testLanguageVersions :: TestTree -testLanguageVersions = testGroup "Plutus Core language versions" - [ testCase "v1.1.0 is available in l3,future and not before" $ do - -- `LedgerLanguageNotAvailableError` is checked in `deserialiseScript` - assertBool "in l3,Vasil" $ isLeft $ uplcToScriptForEvaluation PlutusV3 vasilPV v110script - -- `PlutusCoreLanguageNotAvailableError` is checked in `mkTermToEvaluate` - assertBool "in l2,future" $ isLeft $ mkTermToEvaluate PlutusV2 changPV (either (Prelude.error . show) id (V2.deserialiseScript changPV $ serialiseUPLC v110script)) [] - -- Both `deserialiseScript` and `mkTermToEvaluate` should succeed - assertBool "not in l3,future" $ isRight $ mkTermToEvaluate PlutusV3 changPV (either (Prelude.error . show) id (V3.deserialiseScript changPV $ serialiseUPLC v110script)) [] - -- The availability of `case` and `constr` is checked in `deserialise` - , testCase "constr is not available with v1.0.0 ever" $ assertBool "in l3,future" $ isLeft $ uplcToScriptForEvaluation PlutusV3 changPV badConstrScript - , testCase "case is not available with v1.0.0 ever" $ assertBool "in l3,future" $ isLeft $ uplcToScriptForEvaluation PlutusV3 changPV badCaseScript - ] - --- * UPLC written examples to test - -serialiseDataExScript :: SerialisedScript -serialiseDataExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - UPLC.Apply () (UPLC.Builtin () PLC.SerialiseData) (PLC.mkConstant () $ I 1) - -errorScript :: SerialisedScript -errorScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ UPLC.Error () - -v110script :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () -v110script = UPLC.Program () PLC.plcVersion110 $ UPLC.Constr () 0 mempty - -badConstrScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () -badConstrScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Constr () 0 mempty - -badCaseScript :: UPLC.Program UPLC.DeBruijn UPLC.DefaultUni UPLC.DefaultFun () -badCaseScript = UPLC.Program () PLC.plcVersion100 $ UPLC.Case () (UPLC.Error ()) mempty - --- Note that bls can work also with plcversion==1.0.0 -blsExScript :: SerialisedScript -blsExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - builtin () Bls12_381_G1_uncompress @@ [mkConstant () $ BS.pack (0xc0 : replicate 47 0x00)] - --- Note that keccak can work also with plcversion==1.0.0 -keccak256ExScript :: SerialisedScript -keccak256ExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - builtin () Keccak_256 @@ [mkConstant @BS.ByteString () "hashme"] - --- Note that blake2b224 can work also with plcversion==1.0.0 -blake2b224ExScript :: SerialisedScript -blake2b224ExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ - builtin () Blake2b_224 @@ [mkConstant @BS.ByteString () "hashme"] diff --git a/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/Data/EvaluationContext.hs b/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/Data/EvaluationContext.hs index 06bfd5ffb47..f13e332ad88 100644 --- a/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/Data/EvaluationContext.hs +++ b/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/Data/EvaluationContext.hs @@ -70,8 +70,8 @@ clearBuiltinCostModel r = r , paramBls12_381_finalVerify = mempty , paramKeccak_256 = mempty , paramBlake2b_224 = mempty - -- , paramIntegerToByteString = mempty -- Required for V2 - -- , paramByteStringToInteger = mempty -- Required for V2 + , paramIntegerToByteString = mempty + , paramByteStringToInteger = mempty , paramAndByteString = mempty , paramOrByteString = mempty , paramXorByteString = mempty @@ -93,13 +93,8 @@ clearBuiltinCostModel r = r -- *** FIXME(https://github.com/IntersectMBO/plutus-private/issues/1610)!!! *** -- This is temporary to get the tests to pass -clearBuiltinCostModel' :: (m ~ MBuiltinCostModel) => m -> m +-- [Later: now we can get away without this because we're planning to deploy all builtins in all versions]. +clearBuiltinCostModel' :: + -- (m ~ MBuiltinCostModel) => + m -> m clearBuiltinCostModel' r = r - { -- , paramIntegerToByteString = mempty -- Required for V2 - -- , paramByteStringToInteger = mempty -- Required for V2 - paramExpModInteger = mempty - , paramDropList = mempty - , paramLengthOfArray = mempty - , paramListToArray = mempty - , paramIndexArray = mempty - } diff --git a/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs b/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs index 2e61c30513c..0cc0649467f 100644 --- a/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs +++ b/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs @@ -21,6 +21,11 @@ import Data.Map qualified as Map import Data.Maybe import GHC.Stack (HasCallStack) + +-- ** FIXME **. These tests no longer make much sense because now we're assuming +-- that all builtins will be available in all PlutusVN, so the cost models will +-- be very similar (but not yet identical). + -- | Example values of costs for @PlutusV3@, in expected ledger order. -- Suitable to be used in testing. costModelParamsForTesting :: HasCallStack => [(V3.ParamName, Int64)] @@ -71,8 +76,8 @@ clearBuiltinCostModel r = r , paramBls12_381_finalVerify = mempty , paramKeccak_256 = mempty , paramBlake2b_224 = mempty - -- , paramIntegerToByteString = mempty -- Required for V2 - -- , paramByteStringToInteger = mempty -- Required for V2 + , paramIntegerToByteString = mempty + , paramByteStringToInteger = mempty , paramAndByteString = mempty , paramOrByteString = mempty , paramXorByteString = mempty @@ -95,13 +100,8 @@ clearBuiltinCostModel r = r -- *** FIXME(https://github.com/IntersectMBO/plutus-private/issues/1610)!!! *** -- This is temporary to get the tests to pass -clearBuiltinCostModel' :: (m ~ MBuiltinCostModel) => m -> m +-- [Later: now we can get away without this because we're planning to deploy all builtins in all versions]. +clearBuiltinCostModel' :: + -- (m ~ MBuiltinCostModel) => + m -> m clearBuiltinCostModel' r = r - { -- , paramIntegerToByteString = mempty -- Required for V2 - -- , paramByteStringToInteger = mempty -- Required for V2 - paramExpModInteger = mempty - , paramDropList = mempty - , paramLengthOfArray = mempty - , paramListToArray = mempty - , paramIndexArray = mempty - } From 850af4b606d6656445ef82ea1002415cdec072d1 Mon Sep 17 00:00:00 2001 From: kwxm Date: Fri, 18 Jul 2025 06:54:36 +0100 Subject: [PATCH 02/11] Comment --- .../src/PlutusLedgerApi/Common/ProtocolVersions.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs index dfeb3ba718e..2e52e798c81 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs @@ -82,7 +82,8 @@ anonPV :: MajorProtocolVersion anonPV = MajorProtocolVersion 11 -- | The set of protocol versions that are "known", i.e. that have been released --- and have actual differences associated with them. +-- and have actual differences associated with them. This is currently only +-- used for testing, so efficiency is not parmount and a list is fine. knownPVs :: [MajorProtocolVersion] knownPVs = [ shelleyPV From 38936222241e72c974f4be72273091e844e8bab7 Mon Sep 17 00:00:00 2001 From: kwxm Date: Fri, 18 Jul 2025 07:23:48 +0100 Subject: [PATCH 03/11] Add changelog entry --- ...50718_072102_kenneth.mackenzie_enable_all_builtins_2.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md diff --git a/plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md b/plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md new file mode 100644 index 00000000000..448c55fc14e --- /dev/null +++ b/plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md @@ -0,0 +1,7 @@ + From 8593065e8a032b00e8601c928d301f10b3366000 Mon Sep 17 00:00:00 2001 From: kwxm Date: Mon, 21 Jul 2025 06:49:27 +0100 Subject: [PATCH 04/11] Uncomment changelog entry --- .../20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md b/plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md index 448c55fc14e..3805b5284e2 100644 --- a/plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md +++ b/plutus-ledger-api/changelog.d/20250718_072102_kenneth.mackenzie_enable_all_builtins_2.md @@ -1,7 +1,4 @@ - From 214f4c2919df4980d81ba4e816f1ec33969f571e Mon Sep 17 00:00:00 2001 From: kwxm Date: Wed, 23 Jul 2025 03:01:28 +0100 Subject: [PATCH 05/11] Add extra compatibility check for builtinsAvailableIn --- plutus-ledger-api/test/Spec/Data/Versions.hs | 75 +++++++++++++++++++ plutus-ledger-api/test/Spec/Versions.hs | 76 ++++++++++++++++++++ 2 files changed, 151 insertions(+) diff --git a/plutus-ledger-api/test/Spec/Data/Versions.hs b/plutus-ledger-api/test/Spec/Data/Versions.hs index 24dc00d348e..a1f5e2866c4 100644 --- a/plutus-ledger-api/test/Spec/Data/Versions.hs +++ b/plutus-ledger-api/test/Spec/Data/Versions.hs @@ -20,6 +20,7 @@ import PlutusLedgerApi.Data.V3 qualified as V3 import Data.ByteString.Short qualified as BSS import Data.Either import Data.List ((\\)) +import Data.Map qualified as Map import Data.Set qualified as Set import Test.Tasty import Test.Tasty.HUnit @@ -30,6 +31,7 @@ tests = testGroup "versions" [ testLedgerLanguages , testLanguageVersions , testPermittedBuiltins + , testBuiltinAvailabilityCompatibility , testRmdr ] @@ -254,6 +256,79 @@ testPermittedBuiltins = ] ] +{- It's important that the results returned by `builtinsAvailableIn` don't change. + The implementation changed when we enabled all builtins in all ledger + languages in PV11, so this test compares the results returned by the old and + new versions to make sure that they're the same (the old version's been + transplanted from PlutusLedgerApi.Common.Versions into the test below). A + little care is required because the old version can return a nonempty result + for an (LL,PV) combination where LL didn't actually exist in PV and the new + version returns the empty set: to avoid this we only test pairs where LL was + available in PV. +-} +testBuiltinAvailabilityCompatibility :: TestTree +testBuiltinAvailabilityCompatibility = + testCase "Old and new versions of builtinsAvailableIn are compatible" $ + let builtinsIntroducedIn_old + :: Map.Map (PlutusLedgerLanguage, MajorProtocolVersion) (Set.Set DefaultFun) + builtinsIntroducedIn_old = + Map.fromList + [ ((PlutusV1, alonzoPV), Set.fromList + [ AddInteger, SubtractInteger, MultiplyInteger, DivideInteger + , QuotientInteger, RemainderInteger, ModInteger, EqualsInteger + , LessThanInteger, LessThanEqualsInteger, AppendByteString + , ConsByteString, SliceByteString, LengthOfByteString + , IndexByteString, EqualsByteString, LessThanByteString + , LessThanEqualsByteString, Sha2_256, Sha3_256, Blake2b_256 + , VerifyEd25519Signature, AppendString, EqualsString, EncodeUtf8 + , DecodeUtf8, IfThenElse, ChooseUnit, Trace, FstPair, SndPair + , ChooseList, MkCons, HeadList, TailList, NullList, ChooseData + , ConstrData, MapData, ListData, IData, BData, UnConstrData + , UnMapData, UnListData, UnIData, UnBData, EqualsData, MkPairData + , MkNilData, MkNilPairData ]) + , ((PlutusV2, vasilPV), Set.fromList + [ SerialiseData ]) + , ((PlutusV2, valentinePV), Set.fromList + [ VerifyEcdsaSecp256k1Signature, VerifySchnorrSecp256k1Signature ]) + , ((PlutusV2, plominPV), Set.fromList + [ IntegerToByteString, ByteStringToInteger ]) + , ((PlutusV3, changPV), Set.fromList + [ Bls12_381_G1_add, Bls12_381_G1_neg, Bls12_381_G1_scalarMul + , Bls12_381_G1_equal, Bls12_381_G1_hashToGroup + , Bls12_381_G1_compress, Bls12_381_G1_uncompress + , Bls12_381_G2_add, Bls12_381_G2_neg, Bls12_381_G2_scalarMul + , Bls12_381_G2_equal, Bls12_381_G2_hashToGroup + , Bls12_381_G2_compress, Bls12_381_G2_uncompress + , Bls12_381_millerLoop, Bls12_381_mulMlResult + , Bls12_381_finalVerify, Keccak_256, Blake2b_224 + , IntegerToByteString, ByteStringToInteger ]) + , ((PlutusV3, plominPV), Set.fromList + [ AndByteString, OrByteString, XorByteString + , ComplementByteString , ReadBit, WriteBits + , ReplicateByte , ShiftByteString, RotateByteString + , CountSetBits, FindFirstSetBit, Ripemd_160 ]) + , ((PlutusV3, futurePV), Set.fromList + [ ExpModInteger, DropList + , ListToArray, IndexArray, LengthOfArray ]) + ] + builtinsAvailableIn_old + :: PlutusLedgerLanguage + -> MajorProtocolVersion + -> Set.Set DefaultFun + builtinsAvailableIn_old thisLv thisPv = + fold $ + Map.filterWithKey (const . alreadyIntroduced) builtinsIntroducedIn_old + where + alreadyIntroduced :: (PlutusLedgerLanguage, MajorProtocolVersion) -> Bool + alreadyIntroduced (introducedInLv,introducedInPv) = + -- both should be satisfied + introducedInLv <= thisLv && introducedInPv <= thisPv + in sequence_ [ assertBool ("Old and new versions of builtinsAvailableIn differ for " + ++ show ll ++ " @PV" ++ show pv) + $ builtinsAvailableIn ll pv == builtinsAvailableIn_old ll pv + | pv <- [alonzoPV .. plominPV] + , ll <- Set.toList (ledgerLanguagesAvailableIn pv) ] + -- Test that the checks for extra bytes after ends of scripts behave properly. deriving newtype instance Arbitrary MajorProtocolVersion diff --git a/plutus-ledger-api/test/Spec/Versions.hs b/plutus-ledger-api/test/Spec/Versions.hs index aa276acec12..6ded4efa26e 100644 --- a/plutus-ledger-api/test/Spec/Versions.hs +++ b/plutus-ledger-api/test/Spec/Versions.hs @@ -20,6 +20,7 @@ import PlutusLedgerApi.V3 qualified as V3 import Data.ByteString.Short qualified as BSS import Data.Either import Data.List ((\\)) +import Data.Map qualified as Map import Data.Set qualified as Set import Test.Tasty import Test.Tasty.HUnit @@ -30,6 +31,7 @@ tests = testGroup "versions" [ testLedgerLanguages , testLanguageVersions , testPermittedBuiltins + , testBuiltinAvailabilityCompatibility , testRmdr ] @@ -254,6 +256,80 @@ testPermittedBuiltins = ] ] + +{- It's important that the results returned by `builtinsAvailableIn` don't change. + The implementation changed when we enabled all builtins in all ledger + languages in PV11, so this test compares the results returned by the old and + new versions to make sure that they're the same (the old version's been + transplanted from PlutusLedgerApi.Common.Versions into the test below). A + little care is required because the old version can return a nonempty result + for an (LL,PV) combination where LL didn't actually exist in PV and the new + version returns the empty set: to avoid this we only test pairs where LL was + available in PV. +-} +testBuiltinAvailabilityCompatibility :: TestTree +testBuiltinAvailabilityCompatibility = + testCase "Old and new versions of builtinsAvailableIn are compatible" $ + let builtinsIntroducedIn_old + :: Map.Map (PlutusLedgerLanguage, MajorProtocolVersion) (Set.Set DefaultFun) + builtinsIntroducedIn_old = + Map.fromList + [ ((PlutusV1, alonzoPV), Set.fromList + [ AddInteger, SubtractInteger, MultiplyInteger, DivideInteger + , QuotientInteger, RemainderInteger, ModInteger, EqualsInteger + , LessThanInteger, LessThanEqualsInteger, AppendByteString + , ConsByteString, SliceByteString, LengthOfByteString + , IndexByteString, EqualsByteString, LessThanByteString + , LessThanEqualsByteString, Sha2_256, Sha3_256, Blake2b_256 + , VerifyEd25519Signature, AppendString, EqualsString, EncodeUtf8 + , DecodeUtf8, IfThenElse, ChooseUnit, Trace, FstPair, SndPair + , ChooseList, MkCons, HeadList, TailList, NullList, ChooseData + , ConstrData, MapData, ListData, IData, BData, UnConstrData + , UnMapData, UnListData, UnIData, UnBData, EqualsData, MkPairData + , MkNilData, MkNilPairData ]) + , ((PlutusV2, vasilPV), Set.fromList + [ SerialiseData ]) + , ((PlutusV2, valentinePV), Set.fromList + [ VerifyEcdsaSecp256k1Signature, VerifySchnorrSecp256k1Signature ]) + , ((PlutusV2, plominPV), Set.fromList + [ IntegerToByteString, ByteStringToInteger ]) + , ((PlutusV3, changPV), Set.fromList + [ Bls12_381_G1_add, Bls12_381_G1_neg, Bls12_381_G1_scalarMul + , Bls12_381_G1_equal, Bls12_381_G1_hashToGroup + , Bls12_381_G1_compress, Bls12_381_G1_uncompress + , Bls12_381_G2_add, Bls12_381_G2_neg, Bls12_381_G2_scalarMul + , Bls12_381_G2_equal, Bls12_381_G2_hashToGroup + , Bls12_381_G2_compress, Bls12_381_G2_uncompress + , Bls12_381_millerLoop, Bls12_381_mulMlResult + , Bls12_381_finalVerify, Keccak_256, Blake2b_224 + , IntegerToByteString, ByteStringToInteger ]) + , ((PlutusV3, plominPV), Set.fromList + [ AndByteString, OrByteString, XorByteString + , ComplementByteString , ReadBit, WriteBits + , ReplicateByte , ShiftByteString, RotateByteString + , CountSetBits, FindFirstSetBit, Ripemd_160 ]) + , ((PlutusV3, futurePV), Set.fromList + [ ExpModInteger, DropList + , ListToArray, IndexArray, LengthOfArray ]) + ] + builtinsAvailableIn_old + :: PlutusLedgerLanguage + -> MajorProtocolVersion + -> Set.Set DefaultFun + builtinsAvailableIn_old thisLv thisPv = + fold $ + Map.filterWithKey (const . alreadyIntroduced) builtinsIntroducedIn_old + where + alreadyIntroduced :: (PlutusLedgerLanguage, MajorProtocolVersion) -> Bool + alreadyIntroduced (introducedInLv,introducedInPv) = + -- both should be satisfied + introducedInLv <= thisLv && introducedInPv <= thisPv + in sequence_ [ assertBool ("Old and new versions of builtinsAvailableIn differ for " + ++ show ll ++ " @PV" ++ show pv) + $ builtinsAvailableIn ll pv == builtinsAvailableIn_old ll pv + | pv <- [alonzoPV .. plominPV] + , ll <- Set.toList (ledgerLanguagesAvailableIn pv) ] + -- Test that the checks for extra bytes after ends of scripts behave properly. deriving newtype instance Arbitrary MajorProtocolVersion From e3bb71eae642f6907dffb06f9b9bcf66e6f4dacf Mon Sep 17 00:00:00 2001 From: kwxm Date: Wed, 23 Jul 2025 03:04:49 +0100 Subject: [PATCH 06/11] Add extra compatibility check for builtinsAvailableIn --- plutus-ledger-api/test/Spec/Data/Versions.hs | 14 +++++++------- plutus-ledger-api/test/Spec/Versions.hs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plutus-ledger-api/test/Spec/Data/Versions.hs b/plutus-ledger-api/test/Spec/Data/Versions.hs index a1f5e2866c4..49cd7bfd4e7 100644 --- a/plutus-ledger-api/test/Spec/Data/Versions.hs +++ b/plutus-ledger-api/test/Spec/Data/Versions.hs @@ -259,12 +259,12 @@ testPermittedBuiltins = {- It's important that the results returned by `builtinsAvailableIn` don't change. The implementation changed when we enabled all builtins in all ledger languages in PV11, so this test compares the results returned by the old and - new versions to make sure that they're the same (the old version's been - transplanted from PlutusLedgerApi.Common.Versions into the test below). A - little care is required because the old version can return a nonempty result - for an (LL,PV) combination where LL didn't actually exist in PV and the new - version returns the empty set: to avoid this we only test pairs where LL was - available in PV. + new versions to make sure that they're the same up to PV10 (the old version's + been transplanted from PlutusLedgerApi.Common.Versions into the test below). + A little care is required because the old version can return a nonempty + result for an (LL,PV) combination where LL didn't actually exist in PV and + the new version returns the empty set: to avoid this we only test pairs where + LL was available in PV. -} testBuiltinAvailabilityCompatibility :: TestTree testBuiltinAvailabilityCompatibility = @@ -326,7 +326,7 @@ testBuiltinAvailabilityCompatibility = in sequence_ [ assertBool ("Old and new versions of builtinsAvailableIn differ for " ++ show ll ++ " @PV" ++ show pv) $ builtinsAvailableIn ll pv == builtinsAvailableIn_old ll pv - | pv <- [alonzoPV .. plominPV] + | pv <- [shelleyPV .. plominPV] , ll <- Set.toList (ledgerLanguagesAvailableIn pv) ] -- Test that the checks for extra bytes after ends of scripts behave properly. diff --git a/plutus-ledger-api/test/Spec/Versions.hs b/plutus-ledger-api/test/Spec/Versions.hs index 6ded4efa26e..cac8985b36f 100644 --- a/plutus-ledger-api/test/Spec/Versions.hs +++ b/plutus-ledger-api/test/Spec/Versions.hs @@ -260,12 +260,12 @@ testPermittedBuiltins = {- It's important that the results returned by `builtinsAvailableIn` don't change. The implementation changed when we enabled all builtins in all ledger languages in PV11, so this test compares the results returned by the old and - new versions to make sure that they're the same (the old version's been - transplanted from PlutusLedgerApi.Common.Versions into the test below). A - little care is required because the old version can return a nonempty result - for an (LL,PV) combination where LL didn't actually exist in PV and the new - version returns the empty set: to avoid this we only test pairs where LL was - available in PV. + new versions to make sure that they're the same up to PV10 (the old version's + been transplanted from PlutusLedgerApi.Common.Versions into the test below). + A little care is required because the old version can return a nonempty + result for an (LL,PV) combination where LL didn't actually exist in PV and + the new version returns the empty set: to avoid this we only test pairs where + LL was available in PV. -} testBuiltinAvailabilityCompatibility :: TestTree testBuiltinAvailabilityCompatibility = @@ -327,7 +327,7 @@ testBuiltinAvailabilityCompatibility = in sequence_ [ assertBool ("Old and new versions of builtinsAvailableIn differ for " ++ show ll ++ " @PV" ++ show pv) $ builtinsAvailableIn ll pv == builtinsAvailableIn_old ll pv - | pv <- [alonzoPV .. plominPV] + | pv <- [shelleyPV .. plominPV] , ll <- Set.toList (ledgerLanguagesAvailableIn pv) ] -- Test that the checks for extra bytes after ends of scripts behave properly. From 50b283aa868edb3539f754c8b084ed6528f07afa Mon Sep 17 00:00:00 2001 From: kwxm Date: Wed, 23 Jul 2025 03:13:42 +0100 Subject: [PATCH 07/11] Add extra compatibility check for builtinsAvailableIn --- plutus-ledger-api/test/Spec/Data/Versions.hs | 6 +++--- plutus-ledger-api/test/Spec/Versions.hs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plutus-ledger-api/test/Spec/Data/Versions.hs b/plutus-ledger-api/test/Spec/Data/Versions.hs index 49cd7bfd4e7..5a857387f8e 100644 --- a/plutus-ledger-api/test/Spec/Data/Versions.hs +++ b/plutus-ledger-api/test/Spec/Data/Versions.hs @@ -262,9 +262,9 @@ testPermittedBuiltins = new versions to make sure that they're the same up to PV10 (the old version's been transplanted from PlutusLedgerApi.Common.Versions into the test below). A little care is required because the old version can return a nonempty - result for an (LL,PV) combination where LL didn't actually exist in PV and - the new version returns the empty set: to avoid this we only test pairs where - LL was available in PV. + result for an (LL,PV) combination where LL didn't actually exist in PV but + the new version returns the empty set in this case: to avoid this we only + test pairs where LL was available in PV. -} testBuiltinAvailabilityCompatibility :: TestTree testBuiltinAvailabilityCompatibility = diff --git a/plutus-ledger-api/test/Spec/Versions.hs b/plutus-ledger-api/test/Spec/Versions.hs index cac8985b36f..cb07f69b1ca 100644 --- a/plutus-ledger-api/test/Spec/Versions.hs +++ b/plutus-ledger-api/test/Spec/Versions.hs @@ -263,9 +263,9 @@ testPermittedBuiltins = new versions to make sure that they're the same up to PV10 (the old version's been transplanted from PlutusLedgerApi.Common.Versions into the test below). A little care is required because the old version can return a nonempty - result for an (LL,PV) combination where LL didn't actually exist in PV and - the new version returns the empty set: to avoid this we only test pairs where - LL was available in PV. + result for an (LL,PV) combination where LL didn't actually exist in PV but + the new version returns the empty set in this case: to avoid this we only + test pairs where LL was available in PV. -} testBuiltinAvailabilityCompatibility :: TestTree testBuiltinAvailabilityCompatibility = From d52b947154848d9f07b4d5b5c88181b5c15ba1eb Mon Sep 17 00:00:00 2001 From: kwxm Date: Wed, 23 Jul 2025 03:19:21 +0100 Subject: [PATCH 08/11] Add warnings not to change already-deployed batches of builtins --- .../src/PlutusLedgerApi/Common/Versions.hs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs index 7e06ae57caa..835c57f0045 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs @@ -132,7 +132,8 @@ collectUpTo m thisPv = {- If any new builtins are introduced after a batch has been deployed on the chain then a new `batch` object MUST be added to contain them and the - `builtinsIntroducedIn` function must be updated. Also, remember to UPDATE THE + `builtinsIntroducedIn` function must be updated; the contents of batches which + have already been deployed must NOT be altered. Also, remember to UPDATE THE TESTS in `Spec.Versions` and `Spec.Data.Versions` when a new batch is added. -} @@ -142,6 +143,7 @@ collectUpTo m thisPv = alternative would be to use the flat tags, but they're not directly accessible at the moment. -} +-- DO NOT CHANGE THIS. batch1 :: [DefaultFun] batch1 = [ AddInteger, SubtractInteger, MultiplyInteger, DivideInteger, QuotientInteger @@ -155,10 +157,12 @@ batch1 = , MkPairData, MkNilData, MkNilPairData ] +-- DO NOT CHANGE THIS. batch2 :: [DefaultFun] batch2 = [ SerialiseData ] +-- DO NOT CHANGE THIS. batch3 :: [DefaultFun] batch3 = [ VerifyEcdsaSecp256k1Signature, VerifySchnorrSecp256k1Signature ] @@ -167,6 +171,7 @@ batch3 = -- PlutusV3 cost model parameters, although that's irrelevant here. -- batch4, excluding IntegerToByteString and ByteStringToInteger. +-- DO NOT CHANGE THIS. batch4a :: [DefaultFun] batch4a = [ Bls12_381_G1_add, Bls12_381_G1_neg, Bls12_381_G1_scalarMul @@ -192,13 +197,16 @@ batch4a = However, if we do do this there's a theoretical risk of turning a phase 2 failure into a phase 1 failure: would that be problematic? -} +-- DO NOT CHANGE THIS. batch4b :: [DefaultFun] batch4b = [ IntegerToByteString, ByteStringToInteger ] +-- DO NOT CHANGE THIS. batch4 :: [DefaultFun] batch4 = batch4a ++ batch4b +-- DO NOT CHANGE THIS. batch5 :: [DefaultFun] batch5 = [ AndByteString, OrByteString, XorByteString, ComplementByteString From da88110911659055347a053dd4f19859ebad44e4 Mon Sep 17 00:00:00 2001 From: kwxm Date: Wed, 23 Jul 2025 03:52:43 +0100 Subject: [PATCH 09/11] Update comments --- plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs | 2 +- plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs b/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs index 4bb12385389..071add490be 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V2/ParamName.hs @@ -297,7 +297,7 @@ data ParamName = | Ripemd_160'cpu'arguments'intercept | Ripemd_160'cpu'arguments'slope | Ripemd_160'memory'arguments - -- Not yet deployed + -- To be deployed in PV11 | ExpModInteger'cpu'arguments'coefficient00 | ExpModInteger'cpu'arguments'coefficient11 | ExpModInteger'cpu'arguments'coefficient12 diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs index c2e3c812d41..58153c7235e 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs @@ -313,7 +313,7 @@ data ParamName = | Ripemd_160'cpu'arguments'intercept | Ripemd_160'cpu'arguments'slope | Ripemd_160'memory'arguments - -- Not yet deployed + -- To be deployed in PV11 | ExpModInteger'cpu'arguments'coefficient00 | ExpModInteger'cpu'arguments'coefficient11 | ExpModInteger'cpu'arguments'coefficient12 From 1e30a513f19f0453ef908dc2d84223f3719ef789 Mon Sep 17 00:00:00 2001 From: kwxm Date: Wed, 23 Jul 2025 04:24:19 +0100 Subject: [PATCH 10/11] anonPV -> pv11PV --- plutus-ledger-api/src/PlutusLedgerApi/Common.hs | 2 +- .../src/PlutusLedgerApi/Common/ProtocolVersions.hs | 10 +++++----- .../src/PlutusLedgerApi/Common/Versions.hs | 12 ++++++------ .../src/PlutusLedgerApi/MachineParameters.hs | 2 +- .../src/PlutusLedgerApi/V1/EvaluationContext.hs | 2 +- .../src/PlutusLedgerApi/V2/EvaluationContext.hs | 2 +- .../src/PlutusLedgerApi/V3/EvaluationContext.hs | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common.hs index f96075b534f..513621a2cc3 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common.hs @@ -43,7 +43,7 @@ module PlutusLedgerApi.Common ( Protocol.valentinePV, Protocol.changPV, Protocol.plominPV, - Protocol.anonPV, + Protocol.pv11PV, Protocol.knownPVs, -- * Costing-related types diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs index 2e52e798c81..8bba53b2117 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs @@ -10,7 +10,7 @@ module PlutusLedgerApi.Common.ProtocolVersions , valentinePV , changPV , plominPV - , anonPV + , pv11PV , newestPV , knownPVs , futurePV @@ -78,8 +78,8 @@ plominPV :: MajorProtocolVersion plominPV = MajorProtocolVersion 10 -- | Not sure what this is going to be called yet -anonPV :: MajorProtocolVersion -anonPV = MajorProtocolVersion 11 +pv11PV :: MajorProtocolVersion +pv11PV = MajorProtocolVersion 11 -- | The set of protocol versions that are "known", i.e. that have been released -- and have actual differences associated with them. This is currently only @@ -94,7 +94,7 @@ knownPVs = , valentinePV , changPV , plominPV - , anonPV + , pv11PV ] -- We're sometimes in an intermediate state where we've added new builtins but @@ -102,7 +102,7 @@ knownPVs = -- decide what PVs the test should include. UPDATE THIS when we're expecting to -- release new builtins in a forthcoming PV. newestPV :: MajorProtocolVersion -newestPV = anonPV +newestPV = pv11PV {-| This is a placeholder for when we don't yet know what protocol version will be used for something. It's a very high protocol version that should never diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs index 835c57f0045..e87b3aad69f 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs @@ -233,24 +233,24 @@ builtinsIntroducedIn = PlutusV1 -> Map.fromList [ (alonzoPV, Set.fromList batch1) - , (anonPV, Set.fromList (batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6)) + , (pv11PV, Set.fromList (batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6)) ] PlutusV2 -> Map.fromList [ (vasilPV, Set.fromList (batch1 ++ batch2)) , (valentinePV, Set.fromList batch3) , (plominPV, Set.fromList batch4b) - , (anonPV , Set.fromList (batch4a ++ batch5 ++ batch6)) + , (pv11PV , Set.fromList (batch4a ++ batch5 ++ batch6)) ] PlutusV3 -> Map.fromList [ (changPV, Set.fromList (batch1 ++ batch2 ++ batch3 ++ batch4)) , (plominPV, Set.fromList batch5) - , (anonPV, Set.fromList batch6) + , (pv11PV, Set.fromList batch6) ] {- | Return a set containing the builtins which are available in a given LL in a -given PV. All builtins are available in all LLs from `anonPV` onwards. -} +given PV. All builtins are available in all LLs from `pv11PV` onwards. -} builtinsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set.Set DefaultFun builtinsAvailableIn = collectUpTo . builtinsIntroducedIn @@ -266,12 +266,12 @@ plcVersionsIntroducedIn = PlutusV1 -> Map.fromList [ (alonzoPV, Set.fromList [ plcVersion100 ]) - , (anonPV, Set.fromList [ plcVersion110 ]) + , (pv11PV, Set.fromList [ plcVersion110 ]) ] PlutusV2 -> Map.fromList [ (alonzoPV, Set.fromList [ plcVersion100 ]) - , (anonPV, Set.fromList [ plcVersion110 ]) + , (pv11PV, Set.fromList [ plcVersion110 ]) ] PlutusV3 -> Map.fromList diff --git a/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs b/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs index d5313dbbd40..32f0a8dd2a5 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/MachineParameters.hs @@ -15,7 +15,7 @@ machineParametersFor -> DefaultMachineParameters machineParametersFor ledgerLang majorPV = MachineParameters - (if majorPV < anonPV + (if majorPV < pv11PV then unavailableCaserBuiltin $ getMajorProtocolVersion majorPV else CaserBuiltin caseBuiltin) (mkMachineVariantParameters builtinSemVar $ cekCostModelForVariant builtinSemVar) diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs b/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs index 622afb36d90..0c1fcd6ec1b 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V1/EvaluationContext.hs @@ -42,7 +42,7 @@ mkEvaluationContext = >=> mkDynEvaluationContext PlutusV1 (\pv -> - if pv < anonPV + if pv < pv11PV then unavailableCaserBuiltin $ getMajorProtocolVersion pv else CaserBuiltin caseBuiltin) [DefaultFunSemanticsVariantA, DefaultFunSemanticsVariantB] diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs b/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs index d0b76cc6860..80bf7ea4373 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V2/EvaluationContext.hs @@ -41,7 +41,7 @@ mkEvaluationContext = >=> mkDynEvaluationContext PlutusV2 (\pv -> - if pv < anonPV + if pv < pv11PV then unavailableCaserBuiltin $ getMajorProtocolVersion pv else CaserBuiltin caseBuiltin) [DefaultFunSemanticsVariantA, DefaultFunSemanticsVariantB] diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs b/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs index baabd1589c9..29c0001941f 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V3/EvaluationContext.hs @@ -40,7 +40,7 @@ mkEvaluationContext = >=> mkDynEvaluationContext PlutusV3 (\pv -> - if pv < anonPV + if pv < pv11PV then unavailableCaserBuiltin $ getMajorProtocolVersion pv else CaserBuiltin caseBuiltin) [DefaultFunSemanticsVariantC] From aad23bea7b7800fc2b8e389bebcd6cc848af7b4c Mon Sep 17 00:00:00 2001 From: kwxm Date: Wed, 23 Jul 2025 22:16:16 +0100 Subject: [PATCH 11/11] Remove commented-out import --- plutus-ledger-api/test/Spec/CostModelParams.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/plutus-ledger-api/test/Spec/CostModelParams.hs b/plutus-ledger-api/test/Spec/CostModelParams.hs index dbb4e66715a..6a27e4f002c 100644 --- a/plutus-ledger-api/test/Spec/CostModelParams.hs +++ b/plutus-ledger-api/test/Spec/CostModelParams.hs @@ -10,7 +10,6 @@ import PlutusLedgerApi.Test.V3.EvaluationContext qualified as V3 import PlutusLedgerApi.V1 qualified as V1 import PlutusLedgerApi.V2 qualified as V2 import PlutusLedgerApi.V3 qualified as V3 --- import PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCostModelParamsForTesting) import Control.Monad.Except (runExcept) import Control.Monad.Writer.Strict (WriterT (runWriterT))