Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!--
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uncomment the changelog

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Done.

### Changed
- All built-in functions will be enabled in PlutusV1 and PlutusV2 in Protocol Version 11.
- Plutus Core version 1.1.0, and hence sums of products (the `case` and `constr` AST nodes), will be enabled in PlutusV1 and PlutusV2 in Protocol Version 11.
-->
1 change: 1 addition & 0 deletions plutus-ledger-api/src/PlutusLedgerApi/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module PlutusLedgerApi.Common (
Protocol.valentinePV,
Protocol.changPV,
Protocol.plominPV,
Protocol.anonPV,
Protocol.knownPVs,

-- * Costing-related types
Expand Down
2 changes: 2 additions & 0 deletions plutus-ledger-api/src/PlutusLedgerApi/Common/Eval.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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'.
Expand Down
56 changes: 37 additions & 19 deletions plutus-ledger-api/src/PlutusLedgerApi/Common/ProtocolVersions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,32 @@ 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.
-- The ledger can only supply the major component of the protocol version, not the minor
-- 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
Expand All @@ -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
Expand All @@ -68,16 +72,20 @@ 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm not quite sure what it means for a PV to be "released". It's probably more accurate to say: these are the PVs in which some Plutus primitives are enabled.

-- and have actual differences associated with them.
knownPVs :: Set.Set MajorProtocolVersion
-- 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 =
Set.fromList
[ shelleyPV
, allegraPV
, maryPV
Expand All @@ -86,16 +94,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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than saying "UPDATE THIS" in a comment here - which is extremely easy to overlook - it would be nice to have a checklist somewhere, that documents everything we need to do when we are ready to release new builtins.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I have an issue to do that: thanks for reminding me. I'll put the issue in the current sprint so I can do it while the process is still fresh in my mind. I had in mind to write some kind of textual document, but maybe an issue template would be a better way to do it.

-- release new builtins in a forthcoming PV.
newestPV :: MajorProtocolVersion
newestPV = anonPV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If new builtins are assigned to futurePV first, then changed to the appropriate PV when ready, then I don't see why we need this.

Copy link
Contributor Author

@kwxm kwxm Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If new builtins are assigned to futurePV first, then changed to the appropriate PV when ready, then I don't see why we need this.

The preceding comment attempts to explain that. Some of the tests (here for instance) iterate over all of the deployed (or just-about-to-be-deployed) PVs and use newestPV to say where to stop. We can't use futurePV for that because it's maxBound. I added newestPV so that we wouldn't have to go through the tests and replace the actual most recent PV everywhere when we update it.


{-| 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

Expand Down
Loading