diff --git a/alonzo/impl/cardano-ledger-alonzo.cabal b/alonzo/impl/cardano-ledger-alonzo.cabal index 519d32bb5e..d6c750cf26 100644 --- a/alonzo/impl/cardano-ledger-alonzo.cabal +++ b/alonzo/impl/cardano-ledger-alonzo.cabal @@ -51,6 +51,7 @@ library Cardano.Ledger.Alonzo.TxSeq Cardano.Ledger.Alonzo.TxWitness Cardano.Ledger.DescribeEras + Fake.Plutus.V2.Ledger.Api build-depends: array, base-deriving-via, diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo.hs index 4dfa32f942..f85e8eaec0 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo.hs @@ -129,7 +129,7 @@ instance (CC.Crypto c) => Shelley.ValidateScript (AlonzoEra c) where then "\x01" else nativeMultiSigTag -- "\x00" validateScript (TimelockScript script) tx = validateTimelock @(AlonzoEra c) script tx - validateScript (PlutusScript _) _tx = True + validateScript (PlutusScript _ _) _tx = True -- To run a PlutusScript use Cardano.Ledger.Alonzo.TxInfo(runPLCScript) -- To run any Alonzo Script use Cardano.Ledger.Alonzo.PlutusScriptApi(evalScripts) diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/Data.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/Data.hs index 219730f027..28dddf36dd 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/Data.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/Data.hs @@ -34,10 +34,8 @@ module Cardano.Ledger.Alonzo.Data where import Cardano.Binary (FromCBOR (..), ToCBOR (..), TokenType (..), peekTokenType, withSlice) -import Cardano.Ledger.Alonzo.Scripts - ( Script (..), - isPlutusScript, - ) +import Cardano.Ledger.Alonzo.Language (Language (..)) +import Cardano.Ledger.Alonzo.Scripts (Script (..)) import Cardano.Ledger.AuxiliaryData (AuxiliaryDataHash (..)) import Cardano.Ledger.BaseTypes (StrictMaybe (..)) import qualified Cardano.Ledger.Core as Core @@ -72,8 +70,7 @@ import qualified Codec.Serialise as Cborg (Serialise (..)) import Data.ByteString.Lazy (toStrict) import Data.ByteString.Short (toShort) import Data.Coders -import qualified Data.Foldable as Foldable -import qualified Data.List as List +import Data.Foldable (foldl') import Data.Map (Map) import Data.Maybe (mapMaybe) import Data.MemoBytes (Mem, MemoBytes (..), memoBytes) @@ -180,19 +177,21 @@ encodeRaw :: encodeRaw metadata allScripts = Tag 259 $ Keyed - (\m tss pss -> AuxiliaryDataRaw m (StrictSeq.fromList $ tss <> pss)) + (\m tss p1ss p2ss -> AuxiliaryDataRaw m (StrictSeq.fromList $ tss <> p1ss <> p2ss)) !> Omit null (Key 0 $ mapEncode metadata) !> Omit null (Key 1 $ E (encodeFoldable . mapMaybe getTimelock) timelocks) - !> Omit null (Key 2 $ E (encodeFoldable . mapMaybe getPlutus) plutusScripts) + !> Omit null (Key 2 $ E (encodeFoldable . mapMaybe getPlutus) plutusV1Scripts) + !> Omit null (Key 3 $ E (encodeFoldable . mapMaybe getPlutus) plutusV2Scripts) where getTimelock (TimelockScript x) = Just x getTimelock _ = Nothing - getPlutus (PlutusScript x) = Just x + getPlutus (PlutusScript _ x) = Just x getPlutus _ = Nothing - (plutusScripts, timelocks) = - List.partition - isPlutusScript - (Foldable.toList allScripts) + sortScripts (ts, v1, v2) s@(TimelockScript _) = (s : ts, v1, v2) + sortScripts (ts, v1, v2) s@(PlutusScript PlutusV1 _) = (ts, s : v1, v2) + sortScripts (ts, v1, v2) s@(PlutusScript PlutusV2 _) = (ts, v1, s : v2) + (timelocks, plutusV1Scripts, plutusV2Scripts) = + foldl' sortScripts (mempty, mempty, mempty) allScripts instance ( Era era, @@ -243,7 +242,11 @@ instance (D (sequence <$> decodeStrictSeq fromCBOR)) auxDataField 2 = fieldA - (\x ad -> ad {scripts' = scripts' ad <> (PlutusScript <$> x)}) + (\x ad -> ad {scripts' = scripts' ad <> (PlutusScript PlutusV1 <$> x)}) + (D (decodeStrictSeq fromCBOR)) + auxDataField 3 = + fieldA + (\x ad -> ad {scripts' = scripts' ad <> (PlutusScript PlutusV2 <$> x)}) (D (decodeStrictSeq fromCBOR)) auxDataField n = field (\_ t -> t) (Invalid n) diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/Language.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/Language.hs index 478b44218f..fc60bfe634 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/Language.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/Language.hs @@ -24,7 +24,9 @@ import NoThunks.Class (NoThunks) -- For now, the only Non-Native Scriting language is Plutus -- We might add new languages in the futures. -data Language = PlutusV1 -- | ADD-NEW-LANGUAGES-HERE +data Language + = PlutusV1 + | PlutusV2 deriving (Eq, Generic, Show, Ord, Enum, Bounded, Ix) instance NoThunks Language @@ -33,20 +35,23 @@ instance NFData Language instance ToCBOR Language where toCBOR PlutusV1 = toCBOR (0 :: Int) + toCBOR PlutusV2 = toCBOR (1 :: Int) instance FromCBOR Language where fromCBOR = do n <- decodeWord64 case n of 0 -> pure PlutusV1 + 1 -> pure PlutusV2 m -> invalidKey (fromIntegral m) nonNativeLanguages :: Set.Set Language -nonNativeLanguages = Set.singleton PlutusV1 +nonNativeLanguages = Set.fromList [PlutusV1, PlutusV2] -- ================================== ppLanguage :: Language -> PDoc ppLanguage PlutusV1 = ppString "PlutusV1" +ppLanguage PlutusV2 = ppString "PlutusV2" instance PrettyA Language where prettyA = ppLanguage diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/PParams.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/PParams.hs index 46d5f870d1..9eb49e575b 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/PParams.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/PParams.hs @@ -41,7 +41,7 @@ import Cardano.Binary serialize', serializeEncoding', ) -import Cardano.Ledger.Alonzo.Language (Language (PlutusV1), ppLanguage) +import Cardano.Ledger.Alonzo.Language (Language (..), ppLanguage) import Cardano.Ledger.Alonzo.Scripts ( CostModel, ExUnits (..), @@ -517,6 +517,10 @@ getLanguageView pp lang@PlutusV1 = LangDepView (serialize' lang) (serializeEncoding' $ maybe encodeNull toCBOR $ Map.lookup lang (_costmdls pp)) +getLanguageView pp lang@PlutusV2 = + LangDepView + (serialize' lang) + (serializeEncoding' $ maybe encodeNull toCBOR $ Map.lookup lang (_costmdls pp)) encodeLangViews :: Set LangDepView -> Encoding encodeLangViews views = diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/PlutusScriptApi.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/PlutusScriptApi.hs index 6bf0b23a95..46252eab59 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/PlutusScriptApi.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/PlutusScriptApi.hs @@ -178,7 +178,7 @@ collectTwoPhaseScriptInputs ei sysS pp tx utxo = -- on 1-phase scripts. knownToNotBe1Phase (_, sh) = case sh `Map.lookup` txscripts' (getField @"wits" tx) of - Just (AlonzoScript.PlutusScript _) -> True + Just (AlonzoScript.PlutusScript _ _) -> True Just (AlonzoScript.TimelockScript _) -> False Nothing -> True redeemer (sp, _) = @@ -211,7 +211,7 @@ merge f (x : xs) (y : ys) zs = merge f xs ys (gg x y zs) gg (Left a) (Left b) (Left cs) = Left (a : b : cs) language :: AlonzoScript.Script era -> Maybe Language -language (AlonzoScript.PlutusScript _) = Just PlutusV1 +language (AlonzoScript.PlutusScript lang _) = Just lang language (AlonzoScript.TimelockScript _) = Nothing -- | evaluate a list of scripts, All scripts in the list must be True. @@ -236,8 +236,8 @@ evalScripts tx ((AlonzoScript.TimelockScript timelock, _, _, _) : rest) = vhks = Set.map witKeyHash (txwitsVKey' (getField @"wits" tx)) lift True = Passes lift False = Fails [OnePhaseFailure . pack . show $ timelock] -evalScripts tx ((AlonzoScript.PlutusScript pscript, ds, units, cost) : rest) = - runPLCScript (Proxy @era) cost pscript units (map getPlutusData ds) +evalScripts tx ((AlonzoScript.PlutusScript lang pscript, ds, units, cost) : rest) = + runPLCScript (Proxy @era) lang cost pscript units (map getPlutusData ds) `andResult` evalScripts tx rest -- Collect information (purpose and hash) about all the scripts in a Tx. diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/Scripts.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/Scripts.hs index 79d64134d6..f7f3a962ee 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/Scripts.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/Scripts.hs @@ -82,10 +82,11 @@ import qualified Data.Set as Set import Data.Text (Text) import Data.Typeable import Data.Word (Word64, Word8) +import Fake.Plutus.V2.Ledger.Api as PV2 hiding (Script) import GHC.Generics (Generic) import NoThunks.Class (InspectHeapNamed (..), NoThunks) import Numeric.Natural (Natural) -import Plutus.V1.Ledger.Api (defaultCostModelParams, validateCostModelParams) +import Plutus.V1.Ledger.Api as PV1 hiding (Script) import qualified Plutus.V1.Ledger.Examples as Plutus ( alwaysFailingNAryFunction, alwaysSucceedingNAryFunction, @@ -112,12 +113,12 @@ instance NoThunks Tag -- | Scripts in the Alonzo Era, Either a Timelock script or a Plutus script. data Script era = TimelockScript (Timelock (Crypto era)) - | PlutusScript ShortByteString -- A Plutus.V1.Ledger.Scripts(Script) that has been 'CBOR' encoded + | PlutusScript Language ShortByteString deriving (Eq, Generic, Ord) instance (ValidateScript era, Core.Script era ~ Script era) => Show (Script era) where show (TimelockScript x) = "TimelockScript " ++ show x - show s@(PlutusScript _) = "PlutusScript " ++ show (hashScript @era s) + show s@(PlutusScript v _) = "PlutusScript " ++ show v ++ " " ++ show (hashScript @era s) deriving via InspectHeapNamed "Script" (Script era) @@ -129,14 +130,14 @@ instance NFData (Script era) -- | Both constructors know their original bytes instance SafeToHash (Script era) where originalBytes (TimelockScript t) = originalBytes t - originalBytes (PlutusScript bs) = fromShort bs + originalBytes (PlutusScript _ bs) = fromShort bs alwaysSucceeds, alwaysFails :: Natural -> Script era -alwaysSucceeds n = PlutusScript (Plutus.alwaysSucceedingNAryFunction n) -alwaysFails n = PlutusScript (Plutus.alwaysFailingNAryFunction n) +alwaysSucceeds n = PlutusScript PlutusV1 (Plutus.alwaysSucceedingNAryFunction n) +alwaysFails n = PlutusScript PlutusV1 (Plutus.alwaysFailingNAryFunction n) isPlutusScript :: Script era -> Bool -isPlutusScript (PlutusScript _) = True +isPlutusScript (PlutusScript _ _) = True isPlutusScript (TimelockScript _) = False -- =========================================== @@ -186,28 +187,36 @@ instance NoThunks CostModel instance NFData CostModel -checkCostModel :: Map Text Integer -> Either String CostModel -checkCostModel cm = - if validateCostModelParams cm +checkCostModel :: Language -> Map Text Integer -> Either String CostModel +checkCostModel PlutusV1 cm = + if PV1.validateCostModelParams cm then Right (CostModel cm) - else Left ("Invalid cost model: " ++ show cm) + else Left ("Invalid PlutusV1 cost model: " ++ show cm) +checkCostModel PlutusV2 cm = + if PV2.validateCostModelParams cm + then Right (CostModel cm) + else Left ("Invalid PlutusV2 cost model: " ++ show cm) -{-# DEPRECATED defaultCostModel "Use 'import Test.Cardano.Ledger.Alonzo.PlutusScripts' instead." #-} -defaultCostModel :: Maybe CostModel -defaultCostModel = CostModel <$> defaultCostModelParams +defaultCostModel :: Language -> Maybe CostModel +defaultCostModel PlutusV1 = CostModel <$> PV1.defaultCostModelParams +defaultCostModel PlutusV2 = CostModel <$> PV2.defaultCostModelParams decodeCostModelMap :: Decoder s (Map Language CostModel) decodeCostModelMap = decodeMapByKey fromCBOR decodeCostModel decodeCostModel :: Language -> Decoder s CostModel -decodeCostModel PlutusV1 = - case defaultCostModelParams of +decodeCostModel lang = + case dcmps of Nothing -> fail "Default Plutus Cost Model is corrupt." Just dcm -> do - checked <- checkCostModel <$> decodeArrayAsMap (Map.keysSet dcm) fromCBOR + checked <- checkCostModel lang <$> decodeArrayAsMap (Map.keysSet dcm) fromCBOR case checked of Left e -> fail e Right cm -> pure cm + where + dcmps = case lang of + PlutusV1 -> PV1.defaultCostModelParams + PlutusV2 -> PV2.defaultCostModelParams decodeArrayAsMap :: Ord a => Set a -> Decoder s b -> Decoder s (Map a b) decodeArrayAsMap keys decodeValue = do @@ -294,7 +303,8 @@ instance forall era. (Typeable (Crypto era), Typeable era) => ToCBOR (Script era encodeScript :: (Typeable (Crypto era)) => Script era -> Encode 'Open (Script era) encodeScript (TimelockScript i) = Sum TimelockScript 0 !> To i -encodeScript (PlutusScript s) = Sum PlutusScript 1 !> To s -- Use the ToCBOR instance of ShortByteString +encodeScript (PlutusScript PlutusV1 s) = Sum (PlutusScript PlutusV1) 1 !> To s -- Use the ToCBOR instance of ShortByteString +encodeScript (PlutusScript PlutusV2 s) = Sum (PlutusScript PlutusV1) 2 !> To s instance (CC.Crypto (Crypto era), Typeable (Crypto era), Typeable era) => @@ -304,7 +314,8 @@ instance where decodeScript :: Word -> Decode 'Open (Annotator (Script era)) decodeScript 0 = Ann (SumD TimelockScript) <*! From - decodeScript 1 = Ann (SumD PlutusScript) <*! Ann From + decodeScript 1 = Ann (SumD $ PlutusScript PlutusV1) <*! Ann From + decodeScript 2 = Ann (SumD $ PlutusScript PlutusV2) <*! Ann From decodeScript n = Invalid n -- ============================================================ @@ -316,7 +327,7 @@ ppTag x = ppString (show x) instance PrettyA Tag where prettyA = ppTag ppScript :: forall era. (ValidateScript era, Core.Script era ~ Script era) => Script era -> PDoc -ppScript s@(PlutusScript _) = ppString "PlutusScript " PP.<+> ppScriptHash (hashScript @era s) +ppScript s@(PlutusScript v _) = ppString ("PlutusScript " <> show v <> " ") PP.<+> ppScriptHash (hashScript @era s) ppScript (TimelockScript x) = ppTimelock x instance (ValidateScript era, Core.Script era ~ Script era) => PrettyA (Script era) where prettyA = ppScript diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/Tools.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/Tools.hs index acadf05f1a..94fe1fa39b 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/Tools.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/Tools.hs @@ -29,7 +29,7 @@ import qualified Cardano.Ledger.Core as Core import qualified Cardano.Ledger.Crypto as CC (Crypto) import Cardano.Slotting.EpochInfo.API (EpochInfo) import Cardano.Slotting.Time (SystemStart) -import Data.Array (Array, (!)) +import Data.Array (Array, bounds, (!)) import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import GHC.Records (HasField (..)) @@ -57,6 +57,8 @@ data ScriptFailure c | -- | The execution budget that was calculated by the Plutus -- evaluator is out of bounds. IncompatibleBudget P.ExBudget + | -- | There was no cost model for given version of Plutus + NoCostModel Language deriving (Show) note :: e -> Maybe a -> Either e a @@ -101,7 +103,7 @@ evaluateTransactionExecutionUnits pp tx utxo ei sysS costModels = do msb <- case Map.lookup sh scripts of Nothing -> pure Nothing Just (TimelockScript _) -> [] - Just (PlutusScript bytes) -> pure $ Just bytes + Just (PlutusScript v bytes) -> pure $ Just (bytes, v) pointer <- case rdptr @(AlonzoEra c) txb sp of SNothing -> [] -- Since scriptsNeeded used the transaction to create script purposes, @@ -109,8 +111,6 @@ evaluateTransactionExecutionUnits pp tx utxo ei sysS costModels = do SJust p -> pure p pure (pointer, (sp, msb)) - (CostModel costModel) = costModels ! PlutusV1 - findAndCount :: P.TxInfo -> RdmrPtr -> @@ -118,7 +118,10 @@ evaluateTransactionExecutionUnits pp tx utxo ei sysS costModels = do Either (ScriptFailure c) ExUnits findAndCount inf pointer (rdmr, _) = do (sp, mscript) <- note (RedeemerNotNeeded pointer) $ Map.lookup pointer ptrToPlutusScript - script <- note (MissingScript pointer) mscript + (script, lang) <- note (MissingScript pointer) mscript + let (l1, l2) = bounds costModels + (CostModel costModel) <- + if l1 <= lang && lang <= l2 then Right (costModels ! lang) else Left (NoCostModel lang) args <- case sp of (Spending txin) -> do txOut <- note (UnknownTxIn txin) $ Map.lookup txin (unUTxO utxo) diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/TxInfo.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/TxInfo.hs index 36063d1340..52548f251b 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/TxInfo.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/TxInfo.hs @@ -71,54 +71,11 @@ import Data.Text.Prettyprint.Doc (Pretty (..)) import Data.Time.Clock (nominalDiffTimeToSeconds) import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds) import Data.Typeable (Proxy (..), Typeable) +import qualified Fake.Plutus.V2.Ledger.Api as PV2 import GHC.Generics (Generic) import GHC.Records (HasField (..)) import NoThunks.Class (NoThunks) -import qualified Plutus.V1.Ledger.Api as P - ( Address (..), - BuiltinByteString, - Credential (..), - CurrencySymbol (..), - DCert (..), - Data (..), - Datum (..), - DatumHash (..), - EvaluationError (..), - ExBudget (..), - ExCPU (..), - ExMemory (..), - Interval (..), - POSIXTime (..), - POSIXTimeRange, - PubKeyHash (..), - ScriptContext (..), - ScriptPurpose (..), - StakingCredential (..), - TokenName (..), - TxId (..), - TxInInfo (..), - TxInfo (..), - TxOut (..), - TxOutRef (..), - ValidatorHash (..), - Value (..), - VerboseMode (..), - adaSymbol, - adaToken, - always, - dataToBuiltinData, - evaluateScriptRestricting, - from, - fromData, - lowerBound, - singleton, - strictUpperBound, - to, - toBuiltin, - toData, - unionWith, - validateScript, - ) +import qualified Plutus.V1.Ledger.Api as PV1 import Plutus.V1.Ledger.Contexts () import qualified Shelley.Spec.Ledger.HardForks as HardForks ( translateTimeForPlutusScripts, @@ -140,48 +97,48 @@ import Shelley.Spec.Ledger.UTxO (UTxO (..)) -- ========================================================= -- Translate Hashes, Credentials, Certificates etc. -transDataHash :: CC.Crypto c => StrictMaybe (DataHash c) -> Maybe P.DatumHash +transDataHash :: CC.Crypto c => StrictMaybe (DataHash c) -> Maybe PV1.DatumHash transDataHash (SJust safe) = Just (transDataHash' safe) transDataHash SNothing = Nothing -transDataHash' :: CC.Crypto c => DataHash c -> P.DatumHash -transDataHash' safe = P.DatumHash (transSafeHash safe) +transDataHash' :: CC.Crypto c => DataHash c -> PV1.DatumHash +transDataHash' safe = PV1.DatumHash (transSafeHash safe) -transKeyHash :: CC.Crypto c => KeyHash d c -> P.PubKeyHash -transKeyHash (KeyHash (UnsafeHash h)) = P.PubKeyHash (P.toBuiltin (fromShort h)) +transKeyHash :: CC.Crypto c => KeyHash d c -> PV1.PubKeyHash +transKeyHash (KeyHash (UnsafeHash h)) = PV1.PubKeyHash (PV1.toBuiltin (fromShort h)) -transScriptHash :: CC.Crypto c => ScriptHash c -> P.ValidatorHash -transScriptHash (ScriptHash (UnsafeHash h)) = P.ValidatorHash (P.toBuiltin (fromShort h)) +transScriptHash :: CC.Crypto c => ScriptHash c -> PV1.ValidatorHash +transScriptHash (ScriptHash (UnsafeHash h)) = PV1.ValidatorHash (PV1.toBuiltin (fromShort h)) -transSafeHash :: CC.Crypto c => SafeHash c i -> P.BuiltinByteString -transSafeHash safe = case extractHash safe of UnsafeHash b -> P.toBuiltin (fromShort b) +transSafeHash :: CC.Crypto c => SafeHash c i -> PV1.BuiltinByteString +transSafeHash safe = case extractHash safe of UnsafeHash b -> PV1.toBuiltin (fromShort b) transHash :: HashAlgorithm h => Hash h a -> BS.ByteString transHash (UnsafeHash h) = fromShort h -txInfoId :: CC.Crypto crypto => TxId crypto -> P.TxId -txInfoId (TxId safe) = P.TxId (transSafeHash safe) +txInfoId :: CC.Crypto crypto => TxId crypto -> PV1.TxId +txInfoId (TxId safe) = PV1.TxId (transSafeHash safe) -transStakeCred :: CC.Crypto crypto => Credential keyrole crypto -> P.Credential +transStakeCred :: CC.Crypto crypto => Credential keyrole crypto -> PV1.Credential transStakeCred (ScriptHashObj (ScriptHash (UnsafeHash kh))) = - P.ScriptCredential (P.ValidatorHash (P.toBuiltin (fromShort kh))) + PV1.ScriptCredential (PV1.ValidatorHash (PV1.toBuiltin (fromShort kh))) transStakeCred (KeyHashObj (KeyHash (UnsafeHash kh))) = - P.PubKeyCredential (P.PubKeyHash (P.toBuiltin (fromShort kh))) + PV1.PubKeyCredential (PV1.PubKeyHash (PV1.toBuiltin (fromShort kh))) -transStakeReference :: CC.Crypto crypto => StakeReference crypto -> Maybe P.StakingCredential -transStakeReference (StakeRefBase cred) = Just (P.StakingHash (transStakeCred cred)) +transStakeReference :: CC.Crypto crypto => StakeReference crypto -> Maybe PV1.StakingCredential +transStakeReference (StakeRefBase cred) = Just (PV1.StakingHash (transStakeCred cred)) transStakeReference (StakeRefPtr (Ptr (SlotNo slot) i1 i2)) = - Just (P.StakingPtr (fromIntegral slot) (fromIntegral i1) (fromIntegral i2)) + Just (PV1.StakingPtr (fromIntegral slot) (fromIntegral i1) (fromIntegral i2)) transStakeReference StakeRefNull = Nothing -transCred :: CC.Crypto crypto => Credential keyrole crypto -> P.Credential +transCred :: CC.Crypto crypto => Credential keyrole crypto -> PV1.Credential transCred (KeyHashObj (KeyHash (UnsafeHash kh))) = - P.PubKeyCredential (P.PubKeyHash (P.toBuiltin (fromShort kh))) + PV1.PubKeyCredential (PV1.PubKeyHash (PV1.toBuiltin (fromShort kh))) transCred (ScriptHashObj (ScriptHash (UnsafeHash kh))) = - P.ScriptCredential (P.ValidatorHash (P.toBuiltin (fromShort kh))) + PV1.ScriptCredential (PV1.ValidatorHash (PV1.toBuiltin (fromShort kh))) -transAddr :: CC.Crypto crypto => Addr crypto -> Maybe P.Address -transAddr (Addr _net object stake) = Just (P.Address (transCred object) (transStakeReference stake)) +transAddr :: CC.Crypto crypto => Addr crypto -> Maybe PV1.Address +transAddr (Addr _net object stake) = Just (PV1.Address (transCred object) (transStakeReference stake)) transAddr (AddrBootstrap _bootaddr) = Nothing slotToPOSIXTime :: @@ -190,9 +147,9 @@ slotToPOSIXTime :: EpochInfo m -> SystemStart -> SlotNo -> - m P.POSIXTime + m PV1.POSIXTime slotToPOSIXTime pp ei sysS s = do - P.POSIXTime . transTime . nominalDiffTimeToSeconds . utcTimeToPOSIXSeconds + PV1.POSIXTime . transTime . nominalDiffTimeToSeconds . utcTimeToPOSIXSeconds <$> epochInfoSlotToUTCTime ei sysS s where transTime = @@ -210,27 +167,27 @@ transVITime :: EpochInfo m -> SystemStart -> ValidityInterval -> - m P.POSIXTimeRange -transVITime _ _ _ (ValidityInterval SNothing SNothing) = pure P.always + m PV1.POSIXTimeRange +transVITime _ _ _ (ValidityInterval SNothing SNothing) = pure PV1.always transVITime pp ei sysS (ValidityInterval (SJust i) SNothing) = do t <- slotToPOSIXTime pp ei sysS i - pure $ P.from t + pure $ PV1.from t transVITime pp ei sysS (ValidityInterval SNothing (SJust i)) = do t <- slotToPOSIXTime pp ei sysS i - pure $ P.to t + pure $ PV1.to t transVITime pp ei sysS (ValidityInterval (SJust i) (SJust j)) = do t1 <- slotToPOSIXTime pp ei sysS i t2 <- slotToPOSIXTime pp ei sysS j pure $ - P.Interval - (P.lowerBound t1) - (P.strictUpperBound t2) + PV1.Interval + (PV1.lowerBound t1) + (PV1.strictUpperBound t2) -- ======================================== -- translate TxIn and TxOut -txInfoIn' :: CC.Crypto c => TxIn c -> P.TxOutRef -txInfoIn' (TxIn txid nat) = P.TxOutRef (txInfoId txid) (fromIntegral nat) +txInfoIn' :: CC.Crypto c => TxIn c -> PV1.TxOutRef +txInfoIn' (TxIn txid nat) = PV1.TxOutRef (txInfoId txid) (fromIntegral nat) -- | Given a TxIn, look it up in the UTxO. If it exists, translate it and return -- (Just translation). If does not exist in the UTxO, return Nothing. @@ -242,19 +199,19 @@ txInfoIn :: ) => UTxO era -> TxIn (Crypto era) -> - Maybe P.TxInInfo + Maybe PV1.TxInInfo txInfoIn (UTxO mp) txin = case Map.lookup txin mp of Nothing -> Nothing Just txout -> case transAddr addr of - Just ad -> Just (P.TxInInfo (txInfoIn' txin) (P.TxOut ad valout dhash)) + Just ad -> Just (PV1.TxInInfo (txInfoIn' txin) (PV1.TxOut ad valout dhash)) Nothing -> Nothing where valout = transValue (getField @"value" txout) addr = getField @"address" txout dhash = case getField @"datahash" txout of SNothing -> Nothing - SJust safehash -> Just (P.DatumHash (transSafeHash safehash)) + SJust safehash -> Just (PV1.DatumHash (transSafeHash safehash)) -- | Given a TxOut, translate it and return (Just transalation). It is -- possible the address part is a Bootstrap Address, in that case return Nothing @@ -265,77 +222,77 @@ txInfoOut :: Value era ~ Mary.Value (Crypto era) ) => Alonzo.TxOut era -> - Maybe P.TxOut + Maybe PV1.TxOut txInfoOut (Alonzo.TxOut addr val datahash) = case transAddr addr of - Just ad -> Just (P.TxOut ad (transValue @(Crypto era) val) (transDataHash datahash)) + Just ad -> Just (PV1.TxOut ad (transValue @(Crypto era) val) (transDataHash datahash)) Nothing -> Nothing -- ================================== -- translate Values -transPolicyID :: CC.Crypto crypto => Mary.PolicyID crypto -> P.CurrencySymbol -transPolicyID (Mary.PolicyID (ScriptHash (UnsafeHash x))) = P.CurrencySymbol (P.toBuiltin (fromShort x)) +transPolicyID :: CC.Crypto crypto => Mary.PolicyID crypto -> PV1.CurrencySymbol +transPolicyID (Mary.PolicyID (ScriptHash (UnsafeHash x))) = PV1.CurrencySymbol (PV1.toBuiltin (fromShort x)) -transAssetName :: Mary.AssetName -> P.TokenName -transAssetName (Mary.AssetName bs) = P.TokenName (P.toBuiltin bs) +transAssetName :: Mary.AssetName -> PV1.TokenName +transAssetName (Mary.AssetName bs) = PV1.TokenName (PV1.toBuiltin bs) -transValue :: forall c. CC.Crypto c => Mary.Value c -> P.Value +transValue :: forall c. CC.Crypto c => Mary.Value c -> PV1.Value transValue (Mary.Value n mp) = Map.foldlWithKey' accum1 justada mp where accum1 ans sym mp2 = Map.foldlWithKey' accum2 ans mp2 where accum2 ans2 tok quantity = - P.unionWith + PV1.unionWith (+) ans2 - (P.singleton (transPolicyID sym) (transAssetName tok) quantity) - justada = P.singleton P.adaSymbol P.adaToken n + (PV1.singleton (transPolicyID sym) (transAssetName tok) quantity) + justada = PV1.singleton PV1.adaSymbol PV1.adaToken n -- ============================================= -- translate fileds like DCert, Wdrl, and similar -transDCert :: CC.Crypto c => DCert c -> P.DCert +transDCert :: CC.Crypto c => DCert c -> PV1.DCert transDCert (DCertDeleg (RegKey stkcred)) = - P.DCertDelegRegKey (P.StakingHash (transStakeCred stkcred)) + PV1.DCertDelegRegKey (PV1.StakingHash (transStakeCred stkcred)) transDCert (DCertDeleg (DeRegKey stkcred)) = - P.DCertDelegDeRegKey (P.StakingHash (transStakeCred stkcred)) + PV1.DCertDelegDeRegKey (PV1.StakingHash (transStakeCred stkcred)) transDCert (DCertDeleg (Delegate (Delegation stkcred keyhash))) = - P.DCertDelegDelegate - (P.StakingHash (transStakeCred stkcred)) + PV1.DCertDelegDelegate + (PV1.StakingHash (transStakeCred stkcred)) (transKeyHash keyhash) transDCert (DCertPool (RegPool pp)) = - P.DCertPoolRegister (transKeyHash (_poolId pp)) (P.PubKeyHash (P.toBuiltin (transHash (_poolVrf pp)))) + PV1.DCertPoolRegister (transKeyHash (_poolId pp)) (PV1.PubKeyHash (PV1.toBuiltin (transHash (_poolVrf pp)))) transDCert (DCertPool (RetirePool keyhash (EpochNo i))) = - P.DCertPoolRetire (transKeyHash keyhash) (fromIntegral i) -transDCert (DCertGenesis _) = P.DCertGenesis -transDCert (DCertMir _) = P.DCertMir + PV1.DCertPoolRetire (transKeyHash keyhash) (fromIntegral i) +transDCert (DCertGenesis _) = PV1.DCertGenesis +transDCert (DCertMir _) = PV1.DCertMir -transWdrl :: CC.Crypto crypto => Wdrl crypto -> Map.Map P.StakingCredential Integer +transWdrl :: CC.Crypto crypto => Wdrl crypto -> Map.Map PV1.StakingCredential Integer transWdrl (Wdrl mp) = Map.foldlWithKey' accum Map.empty mp where accum ans (RewardAcnt _network cred) (Coin n) = - Map.insert (P.StakingHash (transStakeCred cred)) n ans + Map.insert (PV1.StakingHash (transStakeCred cred)) n ans -getWitVKeyHash :: (CC.Crypto crypto, Typeable kr) => WitVKey kr crypto -> P.PubKeyHash +getWitVKeyHash :: (CC.Crypto crypto, Typeable kr) => WitVKey kr crypto -> PV1.PubKeyHash getWitVKeyHash = - P.PubKeyHash - . P.toBuiltin + PV1.PubKeyHash + . PV1.toBuiltin . fromShort . (\(UnsafeHash x) -> x) . (\(KeyHash x) -> x) . hashKey . (\(WitVKey x _) -> x) -transDataPair :: CC.Crypto c => (DataHash c, Data era) -> (P.DatumHash, P.Datum) -transDataPair (x, y) = (transDataHash' x, P.Datum (P.dataToBuiltinData (getPlutusData y))) +transDataPair :: CC.Crypto c => (DataHash c, Data era) -> (PV1.DatumHash, PV1.Datum) +transDataPair (x, y) = (transDataHash' x, PV1.Datum (PV1.dataToBuiltinData (getPlutusData y))) -transExUnits :: ExUnits -> P.ExBudget +transExUnits :: ExUnits -> PV1.ExBudget transExUnits (ExUnits mem steps) = - P.ExBudget (P.ExCPU (fromIntegral steps)) (P.ExMemory (fromIntegral mem)) + PV1.ExBudget (PV1.ExCPU (fromIntegral steps)) (PV1.ExMemory (fromIntegral mem)) -exBudgetToExUnits :: P.ExBudget -> Maybe ExUnits -exBudgetToExUnits (P.ExBudget (P.ExCPU steps) (P.ExMemory memory)) = +exBudgetToExUnits :: PV1.ExBudget -> Maybe ExUnits +exBudgetToExUnits (PV1.ExBudget (PV1.ExCPU steps) (PV1.ExMemory memory)) = ExUnits <$> safeFromInteger (toInteger memory) <*> safeFromInteger (toInteger steps) where @@ -347,17 +304,19 @@ exBudgetToExUnits (P.ExBudget (P.ExCPU steps) (P.ExMemory memory)) = -- =================================== -- translate Script Purpose -transScriptPurpose :: CC.Crypto crypto => ScriptPurpose crypto -> P.ScriptPurpose -transScriptPurpose (Minting policyid) = P.Minting (transPolicyID policyid) -transScriptPurpose (Spending txin) = P.Spending (txInfoIn' txin) +transScriptPurpose :: CC.Crypto crypto => ScriptPurpose crypto -> PV1.ScriptPurpose +transScriptPurpose (Minting policyid) = PV1.Minting (transPolicyID policyid) +transScriptPurpose (Spending txin) = PV1.Spending (txInfoIn' txin) transScriptPurpose (Rewarding (RewardAcnt _network cred)) = - P.Rewarding (P.StakingHash (transStakeCred cred)) -transScriptPurpose (Certifying dcert) = P.Certifying (transDCert dcert) + PV1.Rewarding (PV1.StakingHash (transStakeCred cred)) +transScriptPurpose (Certifying dcert) = PV1.Certifying (transDCert dcert) -- =================================== -- | Compute a Digest of the current transaction to pass to the script -- This is the major component of the valContext function. +-- +-- TODO Make txInfo depend on 'Language'. txInfo :: forall era tx m. ( Era era, @@ -374,21 +333,21 @@ txInfo :: SystemStart -> UTxO era -> tx -> - m P.TxInfo + m PV1.TxInfo txInfo pp ei sysS utxo tx = do timeRange <- transVITime pp ei sysS interval pure $ - P.TxInfo - { P.txInfoInputs = mapMaybe (txInfoIn utxo) (Set.toList (inputs' tbody)), - P.txInfoOutputs = mapMaybe txInfoOut (foldr (:) [] outs), - P.txInfoFee = transValue (inject @(Mary.Value (Crypto era)) fee), - P.txInfoMint = transValue forge, - P.txInfoDCert = foldr (\c ans -> transDCert c : ans) [] (certs' tbody), - P.txInfoWdrl = Map.toList (transWdrl (wdrls' tbody)), - P.txInfoValidRange = timeRange, - P.txInfoSignatories = map transKeyHash (Set.toList (reqSignerHashes' tbody)), - P.txInfoData = map transDataPair datpairs, - P.txInfoId = P.TxId (transSafeHash (hashAnnotated @(Crypto era) tbody)) + PV1.TxInfo + { PV1.txInfoInputs = mapMaybe (txInfoIn utxo) (Set.toList (inputs' tbody)), + PV1.txInfoOutputs = mapMaybe txInfoOut (foldr (:) [] outs), + PV1.txInfoFee = transValue (inject @(Mary.Value (Crypto era)) fee), + PV1.txInfoMint = transValue forge, + PV1.txInfoDCert = foldr (\c ans -> transDCert c : ans) [] (certs' tbody), + PV1.txInfoWdrl = Map.toList (transWdrl (wdrls' tbody)), + PV1.txInfoValidRange = timeRange, + PV1.txInfoSignatories = map transKeyHash (Set.toList (reqSignerHashes' tbody)), + PV1.txInfoData = map transDataPair datpairs, + PV1.txInfoId = PV1.TxId (transSafeHash (hashAnnotated @(Crypto era) tbody)) } where tbody = getField @"body" tx @@ -408,10 +367,10 @@ txInfo pp ei sysS utxo tx = do -- The UTxO and the PtrMap are used to 'resolve' the TxIn and the StakeRefPtr's valContext :: Era era => - P.TxInfo -> + PV1.TxInfo -> ScriptPurpose (Crypto era) -> Data era -valContext txinfo sp = Data (P.toData (P.ScriptContext txinfo (transScriptPurpose sp))) +valContext txinfo sp = Data (PV1.toData (PV1.ScriptContext txinfo (transScriptPurpose sp))) data FailureDescription = OnePhaseFailure Text @@ -456,7 +415,7 @@ data PlutusDebug = PlutusDebug { debugCostModel :: CostModel, debugExUnits :: ExUnits, debugScript :: SBS.ShortByteString, - debugData :: [P.Data], + debugData :: [PV1.Data], debugVersion :: Language } deriving (Show) @@ -489,8 +448,8 @@ debugPlutus db = case decodeFull' bs of Left e -> DebugCannotDecode (show e) Right (PlutusDebug (CostModel cost) units script ds _version) -> - case P.evaluateScriptRestricting - P.Verbose + case PV1.evaluateScriptRestricting + PV1.Verbose cost (transExUnits units) script @@ -500,7 +459,7 @@ debugPlutus db = -- The runPLCScript in the Specification has a slightly different type -- than the one in the implementation below. Made necessary by the the type --- of P.evaluateScriptRestricting which is the interface to Plutus, and in the impementation +-- of PV1.evaluateScriptRestricting which is the interface to Plutus, and in the impementation -- we try to track why a script failed (if it does) by the [String] in the Fails constructor of ScriptResut. -- | Run a Plutus Script, given the script and the bounds on resources it is allocated. @@ -508,20 +467,25 @@ runPLCScript :: forall era. Show (Script era) => Proxy era -> + Language -> CostModel -> SBS.ShortByteString -> ExUnits -> - [P.Data] -> + [PV1.Data] -> ScriptResult -runPLCScript proxy (CostModel cost) scriptbytestring units ds = - case P.evaluateScriptRestricting - P.Quiet +runPLCScript proxy lang (CostModel cost) scriptbytestring units ds = + case plutusInterpreter + lang + PV1.Quiet cost (transExUnits units) scriptbytestring ds of - (_, Left e) -> explainPlutusFailure proxy scriptbytestring e ds (CostModel cost) units + (_, Left e) -> explainPlutusFailure proxy lang scriptbytestring e ds (CostModel cost) units (_, Right ()) -> Passes + where + plutusInterpreter PlutusV1 = PV1.evaluateScriptRestricting + plutusInterpreter PlutusV2 = PV2.evaluateScriptRestricting -- | Explain why a script might fail. Scripts come in two flavors: -- @@ -537,19 +501,20 @@ explainPlutusFailure, forall era. Show (Script era) => Proxy era -> + Language -> SBS.ShortByteString -> - P.EvaluationError -> - [P.Data] -> + PV1.EvaluationError -> + [PV1.Data] -> CostModel -> ExUnits -> ScriptResult -explainPlutusFailure _proxy scriptbytestring e ds@[dat, redeemer, info] cm eu = +explainPlutusFailure _proxy lang scriptbytestring e ds@[dat, redeemer, info] cm eu = -- A three data argument script. let ss :: Script era - ss = PlutusScript scriptbytestring + ss = PlutusScript lang scriptbytestring name :: String name = show ss - in case P.fromData info of + in case PV1.fromData info of Nothing -> Fails [PlutusFailure line db] where line = @@ -564,7 +529,7 @@ explainPlutusFailure _proxy scriptbytestring e ds@[dat, redeemer, info] cm eu = db = B64.encode . serialize' $ PlutusDebug cm eu scriptbytestring ds PlutusV1 Just info2 -> Fails [PlutusFailure line db] where - info3 = show (pretty (info2 :: P.ScriptContext)) + info3 = show (pretty (info2 :: PV1.ScriptContext)) line = pack $ unlines @@ -575,13 +540,13 @@ explainPlutusFailure _proxy scriptbytestring e ds@[dat, redeemer, info] cm eu = "The context is:\n" ++ info3 ] db = B64.encode . serialize' $ PlutusDebug cm eu scriptbytestring ds PlutusV1 -explainPlutusFailure _proxy scriptbytestring e ds@[redeemer, info] cm eu = +explainPlutusFailure _proxy lang scriptbytestring e ds@[redeemer, info] cm eu = -- A two data argument script. let ss :: Script era - ss = PlutusScript scriptbytestring + ss = PlutusScript lang scriptbytestring name :: String name = show ss - in case P.fromData info of + in case PV1.fromData info of Nothing -> Fails [PlutusFailure line db] where line = @@ -595,7 +560,7 @@ explainPlutusFailure _proxy scriptbytestring e ds@[redeemer, info] cm eu = db = B64.encode . serialize' $ PlutusDebug cm eu scriptbytestring ds PlutusV1 Just info2 -> Fails [PlutusFailure line db] where - info3 = show (pretty (info2 :: P.ScriptContext)) + info3 = show (pretty (info2 :: PV1.ScriptContext)) line = pack $ unlines @@ -605,12 +570,12 @@ explainPlutusFailure _proxy scriptbytestring e ds@[redeemer, info] cm eu = "The context is:\n" ++ info3 ] db = B64.encode . serialize' $ PlutusDebug cm eu scriptbytestring ds PlutusV1 -explainPlutusFailure _proxy scriptbytestring e ds cm eu = +explainPlutusFailure _proxy lang scriptbytestring e ds cm eu = -- A script with the wrong number of arguments Fails [PlutusFailure line db] where ss :: Script era - ss = PlutusScript scriptbytestring + ss = PlutusScript lang scriptbytestring name :: String name = show ss line = @@ -626,18 +591,19 @@ explainPlutusFailure _proxy scriptbytestring e ds cm eu = explain_plutus_failure = explainPlutusFailure {-# DEPRECATED explain_plutus_failure "In favor of properly named `explainPlutusFailure`" #-} -validPlutusdata :: P.Data -> Bool -validPlutusdata (P.Constr _n ds) = all validPlutusdata ds -validPlutusdata (P.Map ds) = +validPlutusdata :: PV1.Data -> Bool +validPlutusdata (PV1.Constr _n ds) = all validPlutusdata ds +validPlutusdata (PV1.Map ds) = all (\(x, y) -> validPlutusdata x && validPlutusdata y) ds -validPlutusdata (P.List ds) = all validPlutusdata ds -validPlutusdata (P.I _n) = True -validPlutusdata (P.B bs) = BS.length bs <= 64 +validPlutusdata (PV1.List ds) = all validPlutusdata ds +validPlutusdata (PV1.I _n) = True +validPlutusdata (PV1.B bs) = BS.length bs <= 64 -- | Test that every Alonzo script represents a real Script. -- Run deepseq to see that there are no infinite computations and that --- every Plutus Script unflattens into a real P.Script +-- every Plutus Script unflattens into a real PV1.Script validScript :: Script era -> Bool validScript scrip = case scrip of TimelockScript sc -> deepseq sc True - PlutusScript bytes -> P.validateScript bytes + PlutusScript PlutusV1 bytes -> PV1.validateScript bytes + PlutusScript PlutusV2 bytes -> PV2.validateScript bytes diff --git a/alonzo/impl/src/Cardano/Ledger/Alonzo/TxWitness.hs b/alonzo/impl/src/Cardano/Ledger/Alonzo/TxWitness.hs index 8d5d7ad632..899e60299b 100644 --- a/alonzo/impl/src/Cardano/Ledger/Alonzo/TxWitness.hs +++ b/alonzo/impl/src/Cardano/Ledger/Alonzo/TxWitness.hs @@ -51,6 +51,7 @@ import Cardano.Binary serializeEncoding', ) import Cardano.Ledger.Alonzo.Data (Data, DataHash, hashData, ppData) +import Cardano.Ledger.Alonzo.Language (Language (..)) import Cardano.Ledger.Alonzo.Scripts (ExUnits (..), Script (..), Tag, isPlutusScript, ppExUnits, ppTag) import qualified Cardano.Ledger.Core as Core import Cardano.Ledger.Era (Era (Crypto), ValidateScript, hashScript) @@ -356,7 +357,7 @@ encodeWitnessRaw :: Encode ('Closed 'Sparse) (TxWitnessRaw era) encodeWitnessRaw vkeys boots scripts dats rdmrs = Keyed - (\a b c d e f -> TxWitnessRaw a b (c <> d) e f) + (\a b c d e f g -> TxWitnessRaw a b (c <> d <> e) f g) !> Omit null (Key 0 $ setEncode vkeys) !> Omit null (Key 2 $ setEncode boots) !> Omit @@ -364,14 +365,19 @@ encodeWitnessRaw vkeys boots scripts dats rdmrs = (Key 1 $ E (encodeFoldable . mapMaybe unwrapTS . Map.elems) timelocks) !> Omit null - (Key 3 $ E (encodeFoldable . mapMaybe unwrapPS . Map.elems) plutusScripts) + (Key 3 $ E (encodeFoldable . mapMaybe unwrapPS1 . Map.elems) plutusScripts) + !> Omit + null + (Key 6 $ E (encodeFoldable . mapMaybe unwrapPS2 . Map.elems) plutusScripts) !> Omit nullDats (Key 4 $ E toCBOR dats) !> Omit nullRedeemers (Key 5 $ To rdmrs) where unwrapTS (TimelockScript x) = Just x unwrapTS _ = Nothing - unwrapPS (PlutusScript x) = Just x - unwrapPS _ = Nothing + unwrapPS1 (PlutusScript PlutusV1 x) = Just x + unwrapPS1 _ = Nothing + unwrapPS2 (PlutusScript PlutusV2 x) = Just x + unwrapPS2 _ = Nothing (plutusScripts, timelocks) = Map.partition isPlutusScript scripts instance @@ -434,12 +440,16 @@ instance txWitnessField 3 = fieldA addScripts - (fmap PlutusScript <$> listDecode) + (fmap (PlutusScript PlutusV1) <$> listDecode) txWitnessField 4 = fieldAA (\x wits -> wits {_txdats = x}) From txWitnessField 5 = fieldAA (\x wits -> wits {_txrdmrs = x}) From + txWitnessField 6 = + fieldA + addScripts + (fmap (PlutusScript PlutusV2) <$> listDecode) txWitnessField n = field (\_ t -> t) (Invalid n) addScripts :: [Script era] -> TxWitnessRaw era -> TxWitnessRaw era diff --git a/alonzo/impl/src/Fake/Plutus/V2/Ledger/Api.hs b/alonzo/impl/src/Fake/Plutus/V2/Ledger/Api.hs new file mode 100644 index 0000000000..f8d0df180d --- /dev/null +++ b/alonzo/impl/src/Fake/Plutus/V2/Ledger/Api.hs @@ -0,0 +1,3 @@ +module Fake.Plutus.V2.Ledger.Api (module X) where + +import Plutus.V1.Ledger.Api as X diff --git a/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/AlonzoEraGen.hs b/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/AlonzoEraGen.hs index 9f3c5e199a..dd6a469419 100644 --- a/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/AlonzoEraGen.hs +++ b/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/AlonzoEraGen.hs @@ -16,7 +16,7 @@ import Cardano.Binary (ToCBOR (toCBOR), serializeEncoding') import Cardano.Ledger.Address (Addr (..)) import Cardano.Ledger.Alonzo (AlonzoEra) import Cardano.Ledger.Alonzo.Data as Alonzo (AuxiliaryData (..), Data (..), DataHash) -import Cardano.Ledger.Alonzo.Language (Language (PlutusV1)) +import Cardano.Ledger.Alonzo.Language (Language (..)) import Cardano.Ledger.Alonzo.PParams (PParams' (..)) import qualified Cardano.Ledger.Alonzo.PParams as Alonzo (PParams, extendPP, retractPP) import Cardano.Ledger.Alonzo.PlutusScriptApi (scriptsNeededFromBody) @@ -215,16 +215,16 @@ instance CC.Crypto c => ScriptClass (AlonzoEra c) where -- basescript _ key = TimelockScript (basescript (Proxy @(MaryEra c)) key) -- The old style from Mary basescript proxy key = (someLeaf proxy key) isKey _ (TimelockScript x) = isKey (Proxy @(MaryEra c)) x - isKey _ (PlutusScript _) = Nothing + isKey _ (PlutusScript _ _) = Nothing isOnePhase _ (TimelockScript _) = True - isOnePhase _ (PlutusScript _) = False + isOnePhase _ (PlutusScript _ _) = False quantify _ (TimelockScript x) = fmap TimelockScript (quantify (Proxy @(MaryEra c)) x) quantify _ x = Leaf x unQuantify _ quant = TimelockScript $ unQuantify (Proxy @(MaryEra c)) (fmap unTime quant) unTime :: Alonzo.Script era -> Timelock (Crypto era) unTime (TimelockScript x) = x -unTime (PlutusScript _) = error "Plutus in Timelock" +unTime (PlutusScript _ _) = error "Plutus in Timelock" okAsCollateral :: forall c. Mock c => UTxO (AlonzoEra c) -> TxIn c -> Bool okAsCollateral utxo inputx = diff --git a/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/PlutusScripts.hs b/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/PlutusScripts.hs index 419e5af192..6e54109336 100644 --- a/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/PlutusScripts.hs +++ b/alonzo/test/lib/Test/Cardano/Ledger/Alonzo/PlutusScripts.hs @@ -1,6 +1,7 @@ -- | This file is generated by plutus-preprocessor/src/Main.hs module Test.Cardano.Ledger.Alonzo.PlutusScripts where +import Cardano.Ledger.Alonzo.Language (Language (..)) import Cardano.Ledger.Alonzo.Scripts (CostModel (..), Script (..)) import Data.ByteString.Short (pack) import Plutus.V1.Ledger.Api (defaultCostModelParams) @@ -18,7 +19,7 @@ guessTheNumber'2_0 d1_1 d2_2 = if d1_1 PlutusTx.Eq.== d2_2 guessTheNumber2 :: Script era guessTheNumber2 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 73, 1, 0, 0, 51, 50, 34, 50, 50, 51, 34, 50, 50, 50], [0, 18, 37, 51, 83, 0, 147, 51, 80, 7, 0, 128, 2, 0, 17], [0, 97, 53, 0, 48, 6, 18, 53, 0, 35, 83, 0, 48, 1, 73], @@ -37,7 +38,7 @@ guessTheNumber'3_0 d1_1 d2_2 _d3_3 = if d1_1 PlutusTx.Eq.== d2_2 guessTheNumber3 :: Script era guessTheNumber3 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 74, 1, 0, 0, 51, 50, 34, 50, 50, 51, 34, 50, 50, 50], [0, 18, 34, 83, 53, 48, 10, 51, 53, 0, 128, 9, 0, 48, 2], [16, 7, 19, 80, 4, 0, 113, 35, 80, 2, 53, 48, 3, 0, 20], @@ -58,7 +59,7 @@ evendata'_0 d1_1 _d2_2 _d3_3 = let n_4 = PlutusTx.Builtins.unsafeDataAsI d1_1 evendata3 :: Script era evendata3 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 93, 1, 0, 0, 51, 50, 34, 50, 50, 50, 51, 34, 50, 50], [50, 50, 0, 18, 34, 83, 53, 48, 12, 51, 53, 0, 160, 11, 51], [0, 83, 0, 64, 3, 72, 1, 18, 0, 1, 0, 129, 53, 0, 96], @@ -80,7 +81,7 @@ odddata'_0 d1_1 _d2_2 _d3_3 = let n_4 = PlutusTx.Builtins.unsafeDataAsI d1_1 odddata3 :: Script era odddata3 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 93, 1, 0, 0, 51, 50, 34, 50, 50, 50, 51, 34, 50, 50], [50, 50, 0, 18, 34, 83, 53, 48, 12, 51, 53, 0, 160, 11, 51], [0, 83, 0, 64, 3, 72, 1, 18, 0, 33, 0, 129, 53, 0, 96], @@ -102,7 +103,7 @@ evenRedeemer'_0 _d1_1 d2_2 _d3_3 = let n_4 = PlutusTx.Builtins.unsafeDataAsI d2_ evenRedeemer3 :: Script era evenRedeemer3 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 93, 1, 0, 0, 51, 50, 34, 50, 50, 50, 51, 34, 50, 50], [50, 50, 0, 18, 34, 83, 53, 48, 12, 51, 53, 0, 160, 11, 51], [0, 83, 0, 64, 2, 72, 1, 18, 0, 1, 0, 129, 53, 0, 96], @@ -124,7 +125,7 @@ oddRedeemer'_0 _d1_1 d2_2 _d3_3 = let n_4 = PlutusTx.Builtins.unsafeDataAsI d2_2 oddRedeemer3 :: Script era oddRedeemer3 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 93, 1, 0, 0, 51, 50, 34, 50, 50, 50, 51, 34, 50, 50], [50, 50, 0, 18, 34, 83, 53, 48, 12, 51, 53, 0, 160, 11, 51], [0, 83, 0, 64, 2, 72, 1, 18, 0, 33, 0, 129, 53, 0, 96], @@ -147,7 +148,7 @@ sumsTo10'_0 d1_1 d2_2 _d3_3 = let {n_4 = PlutusTx.Builtins.unsafeDataAsI d1_1; sumsTo103 :: Script era sumsTo103 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 101, 1, 0, 0, 50, 51, 50, 34, 50, 50, 50, 50, 51, 34], [50, 50, 50, 0, 18, 34, 83, 53, 48, 12, 51, 53, 0, 144, 11], [51, 53, 0, 160, 15, 48, 4, 0, 35, 0, 64, 3, 72, 5, 4], @@ -168,7 +169,7 @@ oddRedeemer2'_0 d1_1 _d3_2 = let n_3 = PlutusTx.Builtins.unsafeDataAsI d1_1 oddRedeemer2 :: Script era oddRedeemer2 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 93, 1, 0, 0, 51, 50, 34, 50, 50, 50, 51, 34, 50, 50], [50, 50, 0, 18, 37, 51, 83, 0, 179, 51, 80, 9, 0, 163, 48], [4, 48, 3, 0, 36, 128, 17, 32, 2, 16, 7, 19, 80, 5, 0], @@ -189,7 +190,7 @@ evenRedeemer2'_0 d1_1 _d3_2 = let n_3 = PlutusTx.Builtins.unsafeDataAsI d1_1 evenRedeemer2 :: Script era evenRedeemer2 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 93, 1, 0, 0, 51, 50, 34, 50, 50, 50, 51, 34, 50, 50], [50, 50, 0, 18, 37, 51, 83, 0, 179, 51, 80, 9, 0, 163, 48], [4, 48, 3, 0, 36, 128, 17, 32, 0, 16, 7, 19, 80, 5, 0], @@ -210,7 +211,7 @@ redeemerIs102'_0 d1_1 _d3_2 = let n_3 = PlutusTx.Builtins.unsafeDataAsI d1_1 redeemerIs102 :: Script era redeemerIs102 = - (PlutusScript . pack . concat) + (PlutusScript PlutusV1 . pack . concat) [ [88, 81, 1, 0, 0, 51, 50, 34, 50, 50, 50, 51, 34, 50, 50], [50, 0, 18, 37, 51, 83, 0, 163, 51, 80, 8, 0, 147, 0, 48], [2, 72, 5, 4, 1, 132, 212, 1, 0, 24, 141, 214, 128, 8, 145], diff --git a/alonzo/test/test/Test/Cardano/Ledger/Alonzo/Examples.hs b/alonzo/test/test/Test/Cardano/Ledger/Alonzo/Examples.hs index 9019ad7001..f57bb295fe 100644 --- a/alonzo/test/test/Test/Cardano/Ledger/Alonzo/Examples.hs +++ b/alonzo/test/test/Test/Cardano/Ledger/Alonzo/Examples.hs @@ -8,6 +8,7 @@ module Test.Cardano.Ledger.Alonzo.Examples where import Cardano.Ledger.Alonzo (AlonzoEra) +import Cardano.Ledger.Alonzo.Language (Language (..)) import Cardano.Ledger.Alonzo.Scripts (CostModel (..), ExUnits (..), Script (..)) import Cardano.Ledger.Alonzo.TxInfo (ScriptResult (Fails, Passes), runPLCScript) import Data.ByteString.Short (ShortByteString) @@ -63,43 +64,43 @@ directPlutusTest expectation script ds = -- | Expects 3 args (data, redeemer, context) guessTheNumber3 :: ShortByteString guessTheNumber3 = case Generated.guessTheNumber3 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'guessTheNumber3' is a plutus script") -- | Expects 2 args (data, redeemer) guessTheNumber2 :: ShortByteString guessTheNumber2 = case Generated.guessTheNumber2 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'guessTheNumber2' is a plutus script") even3 :: ShortByteString even3 = case Generated.evendata3 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'evendata3' is a plutus script") odd3 :: ShortByteString odd3 = case Generated.odddata3 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'odddata3' is a plutus script") sum103 :: ShortByteString sum103 = case Generated.sumsTo103 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'sumsTo1033' is a plutus script") evenRed2 :: ShortByteString evenRed2 = case Generated.evenRedeemer2 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'evenredeemer2' is a plutus script") redeemer102 :: ShortByteString redeemer102 = case Generated.redeemerIs102 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'redeemeris102' is a plutus script") oddredeemer2 :: ShortByteString oddredeemer2 = case Generated.oddRedeemer2 of - PlutusScript sbs -> sbs + PlutusScript _ sbs -> sbs _ -> error ("Should not happen 'oddredeemer2' is a plutus script") plutusScriptExamples :: TestTree @@ -185,9 +186,9 @@ alonzo :: Proxy (AlonzoEra StandardCrypto) alonzo = Proxy explainTest :: Script (AlonzoEra StandardCrypto) -> ShouldSucceed -> [P.Data] -> Assertion -explainTest (script@(PlutusScript bytes)) mode ds = +explainTest (script@(PlutusScript _ bytes)) mode ds = let cost = fromMaybe (error "corrupt default cost model") P.defaultCostModelParams - in case (mode, runPLCScript alonzo (CostModel cost) bytes (ExUnits 100000000 10000000) ds) of + in case (mode, runPLCScript alonzo PlutusV1 (CostModel cost) bytes (ExUnits 100000000 10000000) ds) of (ShouldSucceed, Passes) -> assertBool "" True (ShouldSucceed, Fails xs) -> assertBool (show xs) (trace (show (head xs)) False) (ShouldFail, Passes) -> assertBool ("Test that should fail, passes: " ++ show script) False diff --git a/alonzo/test/test/Test/Cardano/Ledger/Alonzo/PropertyTests.hs b/alonzo/test/test/Test/Cardano/Ledger/Alonzo/PropertyTests.hs index c6531493f2..6f183890e1 100644 --- a/alonzo/test/test/Test/Cardano/Ledger/Alonzo/PropertyTests.hs +++ b/alonzo/test/test/Test/Cardano/Ledger/Alonzo/PropertyTests.hs @@ -90,7 +90,7 @@ alonzoSpecificProps SourceSignalTarget {source = chainSt, signal = block} = Left e -> error $ "Plutus script collection error: " <> show e Right c -> c collectedScripts = Set.fromList $ map (\(s, _, _, _) -> s) collected - suppliedPScrpts = Set.fromList [PlutusScript s | PlutusScript s <- Map.elems allScripts] + suppliedPScrpts = Set.fromList [PlutusScript v s | PlutusScript v s <- Map.elems allScripts] expectedPScripts = collectedScripts == suppliedPScrpts allPlutusTrue = case evalScripts tx collected of Fails _ -> False diff --git a/plutus-preprocessor/plutus-preprocessor.cabal b/plutus-preprocessor/plutus-preprocessor.cabal index 444bf82f4d..d9d49d6e16 100644 --- a/plutus-preprocessor/plutus-preprocessor.cabal +++ b/plutus-preprocessor/plutus-preprocessor.cabal @@ -28,6 +28,7 @@ executable plutus-preprocessor build-depends: base, bytestring, + cardano-ledger-alonzo, flat, plutus-core, plutus-tx, diff --git a/plutus-preprocessor/src/Main.hs b/plutus-preprocessor/src/Main.hs index afc7f8590f..c616d364a1 100644 --- a/plutus-preprocessor/src/Main.hs +++ b/plutus-preprocessor/src/Main.hs @@ -12,6 +12,7 @@ -- cd into the plutus-preprocessor directory and type 'cabal run' module Main where +import Cardano.Ledger.Alonzo.Language (Language (..)) import Codec.Serialise (serialise) import Data.ByteString.Lazy (toStrict) import Data.ByteString.Short (ShortByteString, pack, toShort, unpack) @@ -39,11 +40,20 @@ import System.IO -- ============================================= -- how to display a preprocessed script -display :: Handle -> ShortByteString -> Q [Dec] -> String -> IO () -display h bytes code name = do +display :: Handle -> Language -> ShortByteString -> Q [Dec] -> String -> IO () +display h lang bytes code name = do xxx <- runQ code hPutStrLn h $ ("\n\n{- Preproceesed Plutus Script\n" ++ pprint xxx ++ "\n-}") - hPutStr h ("\n" ++ name ++ " :: Script era\n" ++ name ++ " = (PlutusScript . pack . concat) \n [") + hPutStr h $ + concat + [ "\n", + name, + " :: Script era\n", + name, + " = (PlutusScript ", + show lang, + ". pack . concat)\n [" + ] manylines h 15 (unpack bytes) manylines :: Show t => Handle -> Int -> [t] -> IO () @@ -139,21 +149,22 @@ main = do (hPutStrLn outh) [ "-- | This file is generated by plutus-preprocessor/src/Main.hs", "module Test.Cardano.Ledger.Alonzo.PlutusScripts where\n", - "import Data.ByteString.Short (pack)\n", - "import Cardano.Ledger.Alonzo.Scripts(CostModel (..), Script(..))\n", - "import Plutus.V1.Ledger.Api(defaultCostModelParams)\n", - "defaultCostModel :: Maybe CostModel\n", + "import Cardano.Ledger.Alonzo.Language (Language (..))", + "import Cardano.Ledger.Alonzo.Scripts (CostModel (..), Script (..))", + "import Data.ByteString.Short (pack)", + "import Plutus.V1.Ledger.Api (defaultCostModelParams)\n", + "defaultCostModel :: Maybe CostModel", "defaultCostModel = CostModel <$> defaultCostModelParams" ] - display outh guess2args guessDecl2args "guessTheNumber2" - display outh guessTheNumberBytes guessDecl "guessTheNumber3" - display outh evendataBytes evendataDecl "evendata3" - display outh odddataBytes odddataDecl "odddata3" - display outh evenRedeemerBytes evenRedeemerDecl "evenRedeemer3" - display outh oddRedeemerBytes oddRedeemerDecl "oddRedeemer3" - display outh sumsTo10Bytes sumsTo10Decl "sumsTo103" - -- 2 arg plutus scripts - display outh oddRedeemerBytes2Arg oddRedeemerDecl2Args "oddRedeemer2" - display outh evenRedeemerBytes2Args evenRedeemerDecl2Args "evenRedeemer2" - display outh redeemerIs10Bytes2Args redeemerIs10Decl2Args "redeemerIs102" + display outh PlutusV1 guess2args guessDecl2args "guessTheNumber2" + display outh PlutusV1 guessTheNumberBytes guessDecl "guessTheNumber3" + display outh PlutusV1 evendataBytes evendataDecl "evendata3" + display outh PlutusV1 odddataBytes odddataDecl "odddata3" + display outh PlutusV1 evenRedeemerBytes evenRedeemerDecl "evenRedeemer3" + display outh PlutusV1 oddRedeemerBytes oddRedeemerDecl "oddRedeemer3" + display outh PlutusV1 sumsTo10Bytes sumsTo10Decl "sumsTo103" + -- 2 arg plutPlutusV1 us scripts + display outh PlutusV1 oddRedeemerBytes2Arg oddRedeemerDecl2Args "oddRedeemer2" + display outh PlutusV1 evenRedeemerBytes2Args evenRedeemerDecl2Args "evenRedeemer2" + display outh PlutusV1 redeemerIs10Bytes2Args redeemerIs10Decl2Args "redeemerIs102" hClose outh