|
| 1 | +{-# LANGUAGE DataKinds #-} |
| 2 | +{-# LANGUAGE NoImplicitPrelude #-} |
| 3 | +{-# LANGUAGE TemplateHaskell #-} |
| 4 | + |
| 5 | +{-# OPTIONS_GHC -fno-warn-orphans #-} |
| 6 | + |
| 7 | +module Cardano.Benchmarking.PlutusScripts.CustomCallV3 (script) where |
| 8 | + |
| 9 | +import Cardano.Api (PlutusScript (..), PlutusScriptV3, |
| 10 | + PlutusScriptVersion (..),Script (..), toScriptInAnyLang) |
| 11 | +import Cardano.Benchmarking.PlutusScripts.CustomCallTypes |
| 12 | +import Cardano.Benchmarking.ScriptAPI |
| 13 | +import qualified Data.ByteString.Short as SBS |
| 14 | +import Language.Haskell.TH.Syntax (Exp (LitE), Lit (StringL), Loc (loc_module), qLocation) |
| 15 | +import qualified PlutusLedgerApi.V3 as PlutusV3 |
| 16 | +import qualified PlutusTx (compile) |
| 17 | +import qualified PlutusTx.Builtins.Internal as BI (BuiltinList, head, snd, tail, unitval, |
| 18 | + unsafeDataAsConstr) |
| 19 | +import PlutusTx.Foldable (sum) |
| 20 | +import PlutusTx.List (all, length) |
| 21 | +import PlutusTx.Prelude as Plutus hiding (Semigroup (..), (.), (<$>)) |
| 22 | +import Prelude as Haskell (String, (.), (<$>)) |
| 23 | + |
| 24 | + |
| 25 | +script :: PlutusBenchScript |
| 26 | +script = mkPlutusBenchScript scriptName (toScriptInAnyLang (PlutusScript PlutusScriptV3 scriptSerialized)) |
| 27 | + |
| 28 | +scriptName :: Haskell.String |
| 29 | +scriptName |
| 30 | + = prepareScriptName $(LitE . StringL . loc_module <$> qLocation) |
| 31 | + |
| 32 | + |
| 33 | +instance Plutus.Eq CustomCallData where |
| 34 | + CCNone == CCNone = True |
| 35 | + CCInteger i == CCInteger i' = i == i' |
| 36 | + CCSum i is == CCSum i' is' = i == i' && is == is' |
| 37 | + CCByteString s == CCByteString s' = s == s' |
| 38 | + CCConcat s ss == CCConcat s' ss' = s == s' && ss == ss' |
| 39 | + _ == _ = False |
| 40 | + |
| 41 | +{-# INLINABLE mkValidator #-} |
| 42 | +mkValidator :: BuiltinData -> BuiltinUnit |
| 43 | +mkValidator arg = |
| 44 | + let |
| 45 | + result = case cmd of |
| 46 | + EvalSpine -> length redeemerArg == length datumArg |
| 47 | + EvalValues -> redeemerArg == datumArg |
| 48 | + EvalAndValidate -> all validateValue redeemerArg && redeemerArg == datumArg |
| 49 | + in if result then BI.unitval else error () |
| 50 | + where |
| 51 | + -- lazily decode script context up to datum and redeemer |
| 52 | + constrArgs :: BuiltinData -> BI.BuiltinList BuiltinData |
| 53 | + constrArgs = BI.snd . BI.unsafeDataAsConstr |
| 54 | + |
| 55 | + ctxFields :: BI.BuiltinList BuiltinData |
| 56 | + ctxFields = constrArgs arg |
| 57 | + |
| 58 | + datum :: BuiltinData |
| 59 | + datum = BI.head ctxFields |
| 60 | + |
| 61 | + redeemerFollowedByScriptInfo :: BI.BuiltinList BuiltinData |
| 62 | + redeemerFollowedByScriptInfo = BI.tail ctxFields |
| 63 | + |
| 64 | + redeemer :: BuiltinData |
| 65 | + redeemer = BI.head redeemerFollowedByScriptInfo |
| 66 | + |
| 67 | + datumArg = snd (unwrap datum) |
| 68 | + (cmd, redeemerArg) = unwrap redeemer |
| 69 | + |
| 70 | + validateValue :: CustomCallData -> Bool |
| 71 | + validateValue (CCSum i is) = i == sum is |
| 72 | + validateValue (CCConcat s ss) = s == mconcat ss |
| 73 | + validateValue _ = True |
| 74 | + |
| 75 | +{-# INLINABLE unwrap #-} |
| 76 | +unwrap :: BuiltinData -> CustomCallArg |
| 77 | +unwrap = PlutusV3.unsafeFromBuiltinData |
| 78 | + |
| 79 | +customCallScriptShortBs :: SBS.ShortByteString |
| 80 | +customCallScriptShortBs = PlutusV3.serialiseCompiledCode $$(PlutusTx.compile [|| mkValidator ||]) |
| 81 | + |
| 82 | +scriptSerialized :: PlutusScript PlutusScriptV3 |
| 83 | +scriptSerialized = PlutusScriptSerialised customCallScriptShortBs |
0 commit comments