diff --git a/CHANGELOG.md b/CHANGELOG.md index 19fd967c7..2371eee3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Revision history for plutarch +# 1.5.1 - 25-05-2024 + +## Added + +* `evalTermNoEmit` and internal function used by this function. This function have identical functionality as `evalTerm` + but, internally, runs CEK machine with budget and log tracing disabled. + # 1.5.0 - 26-01-2024 ## Changed diff --git a/Plutarch/Evaluate.hs b/Plutarch/Evaluate.hs index c38a3f2de..46ff0153d 100644 --- a/Plutarch/Evaluate.hs +++ b/Plutarch/Evaluate.hs @@ -6,12 +6,13 @@ module Plutarch.Evaluate ( E.evalScript', E.EvalError, evalTerm, + evalTermNoEmit, ) where import Plutarch.Internal.Evaluate qualified as E import Data.Text (Text) -import Plutarch.Internal (ClosedTerm, Config, RawTerm (RCompiled), Term (..), TermResult (TermResult), compile) +import Plutarch.Internal (ClosedTerm, Config (Config), RawTerm (RCompiled), Term (..), TermResult (TermResult), TracingMode (NoTracing), compile) import Plutarch.Script (Script (Script)) import PlutusCore.Evaluation.Machine.ExBudget (ExBudget) import UntypedPlutusCore qualified as UPLC @@ -31,3 +32,16 @@ evalTerm config term = fromScript :: Script -> ClosedTerm a fromScript (Script script) = Term $ const $ pure $ TermResult (RCompiled $ UPLC._progTerm script) [] + +evalTermNoEmit :: + ClosedTerm a -> + Either Text (Either E.NoEmitEvaluateError (ClosedTerm a)) +evalTermNoEmit term = + case compile (Config NoTracing) term of + Right script -> + Right $ fromScript <$> E.evalScriptNoEmit script + Left a -> Left a + where + fromScript :: Script -> ClosedTerm a + fromScript (Script script) = + Term $ const $ pure $ TermResult (RCompiled $ UPLC._progTerm script) [] diff --git a/Plutarch/Internal/Evaluate.hs b/Plutarch/Internal/Evaluate.hs index 01b2e41e4..79215d6e4 100644 --- a/Plutarch/Internal/Evaluate.hs +++ b/Plutarch/Internal/Evaluate.hs @@ -1,6 +1,15 @@ {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -module Plutarch.Internal.Evaluate (uplcVersion, evalScript, evalScriptHuge, evalScript', EvalError) where +module Plutarch.Internal.Evaluate ( + uplcVersion, + evalScript, + evalScriptHuge, + evalScript', + evalTermNoEmit, + evalScriptNoEmit, + EvalError, + NoEmitEvaluateError (..), +) where import Data.Text (Text) import Plutarch.Script (Script (Script)) @@ -12,12 +21,14 @@ import PlutusCore.Evaluation.Machine.ExBudget ( ) import PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCekParameters) import PlutusCore.Evaluation.Machine.ExMemory (ExCPU (ExCPU), ExMemory (ExMemory)) +import PlutusCore.Quote qualified as Quote import UntypedPlutusCore ( Program (Program), Term, Version (Version), ) import UntypedPlutusCore qualified as UPLC +import UntypedPlutusCore.DeBruijn qualified as DeBruijn import UntypedPlutusCore.Evaluation.Machine.Cek qualified as Cek type EvalError = (Cek.CekEvaluationException PLC.NamedDeBruijn PLC.DefaultUni PLC.DefaultFun) @@ -56,3 +67,27 @@ evalTerm :: evalTerm budget t = case Cek.runCekDeBruijn defaultCekParameters (Cek.restricting (ExRestrictingBudget budget)) Cek.logEmitter t of (errOrRes, Cek.RestrictingSt (ExRestrictingBudget final), logs) -> (errOrRes, budget `minusExBudget` final, logs) + +data NoEmitEvaluateError + = NoEmitEvaluateFreeVariableError DeBruijn.FreeVariableError + | NoEmitEvaluateFailure + +-- Evaluates given script using `unsafeEvaluateCekNoEmit`. This will run with unbound budget and without log output +evalTermNoEmit :: + Term PLC.NamedDeBruijn PLC.DefaultUni PLC.DefaultFun () -> + Either NoEmitEvaluateError (Term PLC.NamedDeBruijn PLC.DefaultUni PLC.DefaultFun ()) +evalTermNoEmit t = + case Quote.runQuoteT $ DeBruijn.unDeBruijnTerm t of + Right namedUPLC -> + case Cek.unsafeEvaluateCekNoEmit defaultCekParameters namedUPLC of + Cek.EvaluationSuccess evaluated -> + case DeBruijn.deBruijnTerm evaluated of + Right evaluatedTerm -> Right evaluatedTerm + Left err -> Left $ NoEmitEvaluateFreeVariableError err + Cek.EvaluationFailure -> Left NoEmitEvaluateFailure + Left err -> Left $ NoEmitEvaluateFreeVariableError err + +evalScriptNoEmit :: Script -> Either NoEmitEvaluateError Script +evalScriptNoEmit (Script (Program _ _ script)) = + Script . Program () uplcVersion . UPLC.termMapNames UPLC.unNameDeBruijn + <$> evalTermNoEmit (UPLC.termMapNames UPLC.fakeNameDeBruijn script) diff --git a/plutarch.cabal b/plutarch.cabal index 2baf6b064..30adbaad1 100644 --- a/plutarch.cabal +++ b/plutarch.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: plutarch -version: 1.5.0 +version: 1.5.1 author: Las Safin , Koz Ross , Seungheon Oh