Skip to content

Commit

Permalink
[Errors] Test that evaluation of a well-typed term doesn't fail with …
Browse files Browse the repository at this point in the history
…a structural error (#6443)

Test that evaluation of a well-typed term doesn't fail with a structural error

In theory, this is supposed to conclude the investigation on the "runtime type system" for UPLC. In practice unfortunately, PIR generators aren't very helpful here as per the recent Slack discussion (I'll reflect that in some GitHub issue later), plus the compiler being too slow doesn't help either. So this PR is more of a proof of concept than an actually helpful test, but better than nothing I suppose.

Resolves #6150.
  • Loading branch information
effectfully authored Sep 21, 2024
1 parent e94d73c commit 3d42b87
Show file tree
Hide file tree
Showing 22 changed files with 110 additions and 63 deletions.
2 changes: 1 addition & 1 deletion plutus-benchmark/nofib/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ evaluateWithCek
:: UPLC.Term UPLC.NamedDeBruijn DefaultUni DefaultFun ()
-> UPLC.EvaluationResult (UPLC.Term UPLC.NamedDeBruijn DefaultUni DefaultFun ())
evaluateWithCek =
UPLC.unsafeToEvaluationResult
UPLC.unsafeSplitStructuralOperational
. (\(fstT,_,_) -> fstT)
. UPLC.runCekDeBruijn PLC.defaultCekParametersForTesting UPLC.restrictingEnormous UPLC.noEmitter

Expand Down
2 changes: 1 addition & 1 deletion plutus-core/executables/plutus/AnyProgram/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import UntypedPlutusCore.Check.Uniques qualified as UPLC

import Control.Lens hiding ((%~))
import Control.Monad.Error.Lens
import Control.Monad.Except
import Control.Monad.Except (MonadError)
import Control.Monad.Reader
import Control.Monad.State (StateT (runStateT))
import Data.Singletons.Decide
Expand Down
4 changes: 2 additions & 2 deletions plutus-core/plutus-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ library
UntypedPlutusCore.Parser
UntypedPlutusCore.Purity
UntypedPlutusCore.Rename
UntypedPlutusCore.Size
UntypedPlutusCore.Transform.CaseOfCase

other-modules:
Expand Down Expand Up @@ -265,7 +266,6 @@ library
UntypedPlutusCore.Rename.Internal
UntypedPlutusCore.Simplify
UntypedPlutusCore.Simplify.Opts
UntypedPlutusCore.Size
UntypedPlutusCore.Subst
UntypedPlutusCore.Transform.CaseReduce
UntypedPlutusCore.Transform.Cse
Expand Down Expand Up @@ -476,6 +476,7 @@ library plutus-ir
PlutusIR.Analysis.Builtins
PlutusIR.Analysis.Dependencies
PlutusIR.Analysis.RetainedSize
PlutusIR.Analysis.Size
PlutusIR.Analysis.VarInfo
PlutusIR.Check.Uniques
PlutusIR.Compiler
Expand Down Expand Up @@ -528,7 +529,6 @@ library plutus-ir

other-modules:
PlutusIR.Analysis.Definitions
PlutusIR.Analysis.Size
PlutusIR.Analysis.Usages
PlutusIR.Compiler.Error
PlutusIR.Compiler.Lower
Expand Down
2 changes: 1 addition & 1 deletion plutus-core/plutus-core/src/PlutusCore/Builtin/Result.hs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ instance AsEvaluationError UnliftingEvaluationError UnliftingError UnliftingErro
{-# INLINE _EvaluationError #-}

-- | An 'UnliftingEvaluationError' /is/ an 'EvaluationError', hence for this instance we only
-- require both @operational@ and @structural@ to have '_UnliftingError' prisms, so that we can
-- require both @structural@ and @operational@ to have '_UnliftingError' prisms, so that we can
-- handle both the cases pointwisely.
instance (AsUnliftingError structural, AsUnliftingError operational) =>
AsUnliftingEvaluationError (EvaluationError structural operational) where
Expand Down
37 changes: 19 additions & 18 deletions plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ nonZeroSecondArg
-- The bang is to communicate to GHC that the function is strict in both the arguments just in case
-- it'd want to allocate a thunk for the first argument otherwise.
nonZeroSecondArg _ !_ 0 =
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
fail "Cannot divide by zero"
nonZeroSecondArg f x y = pure $ f x y
{-# INLINE nonZeroSecondArg #-}
Expand Down Expand Up @@ -1103,10 +1103,11 @@ This was investigated in https://github.com/IntersectMBO/plutus/pull/4337 but we
do it quite yet, even though it worked (the Plutus Tx part wasn't implemented).
-}

{- Note [Operational vs structural errors within builtins]
See the Haddock of 'EvaluationError' to understand why we sometimes use 'fail' (to throw an
"operational" evaluation error) and sometimes use @throwing _StructuralUnliftingError@ (to throw a
"structural" evaluation error). Please respect the distinction when adding new built-in functions.
{- Note [Structural vs operational errors within builtins]
See the Haddock of 'EvaluationError' to understand why we sometimes use use @throwing
_StructuralUnliftingError@ (to throw a "structural" evaluation error) and sometimes use 'fail' (to
throw an "operational" evaluation error). Please respect the distinction when adding new built-in
functions.
-}

instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
Expand Down Expand Up @@ -1273,7 +1274,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
let indexByteStringDenotation :: BS.ByteString -> Int -> BuiltinResult Word8
indexByteStringDenotation xs n = do
unless (n >= 0 && n < BS.length xs) $
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
-- The arguments are going to be printed in the "cause" part of the error
-- message, so we don't need to repeat them here.
fail "Index out of bounds"
Expand Down Expand Up @@ -1449,7 +1450,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
case uniPairAB of
DefaultUniPair uniA _ -> pure . fromValueOf uniA $ fst xy
_ ->
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
throwing _StructuralUnliftingError "Expected a pair but got something else"
{-# INLINE fstPairDenotation #-}
in makeBuiltinMeaning
Expand All @@ -1462,7 +1463,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
case uniPairAB of
DefaultUniPair _ uniB -> pure . fromValueOf uniB $ snd xy
_ ->
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
throwing _StructuralUnliftingError "Expected a pair but got something else"
{-# INLINE sndPairDenotation #-}
in makeBuiltinMeaning
Expand All @@ -1477,7 +1478,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
DefaultUniList _ -> pure $ case xs of
[] -> a
_ : _ -> b
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
_ -> throwing _StructuralUnliftingError "Expected a list but got something else"
{-# INLINE chooseListDenotation #-}
in makeBuiltinMeaning
Expand All @@ -1490,7 +1491,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
mkConsDenotation
(SomeConstant (Some (ValueOf uniA x)))
(SomeConstant (Some (ValueOf uniListA xs))) = do
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
case uniListA of
DefaultUniList uniA' -> case uniA `geq` uniA' of
Just Refl -> pure . fromValueOf uniListA $ x : xs
Expand All @@ -1505,7 +1506,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
toBuiltinMeaning _semvar HeadList =
let headListDenotation :: SomeConstant uni [a] -> BuiltinResult (Opaque val a)
headListDenotation (SomeConstant (Some (ValueOf uniListA xs))) = do
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
case uniListA of
DefaultUniList uniA -> case xs of
[] -> fail "Expected a non-empty list but got an empty one"
Expand All @@ -1519,7 +1520,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
toBuiltinMeaning _semvar TailList =
let tailListDenotation :: SomeConstant uni [a] -> BuiltinResult (Opaque val [a])
tailListDenotation (SomeConstant (Some (ValueOf uniListA xs))) = do
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
case uniListA of
DefaultUniList _ -> case xs of
[] -> fail "Expected a non-empty list but got an empty one"
Expand All @@ -1536,7 +1537,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
case uniListA of
DefaultUniList _ -> pure $ null xs
_ ->
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
throwing _StructuralUnliftingError "Expected a list but got something else"
{-# INLINE nullListDenotation #-}
in makeBuiltinMeaning
Expand Down Expand Up @@ -1602,7 +1603,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
let unConstrDataDenotation :: Data -> BuiltinResult (Integer, [Data])
unConstrDataDenotation = \case
Constr i ds -> pure (i, ds)
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
_ -> fail "Expected the Constr constructor but got a different one"
{-# INLINE unConstrDataDenotation #-}
in makeBuiltinMeaning
Expand All @@ -1613,7 +1614,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
let unMapDataDenotation :: Data -> BuiltinResult [(Data, Data)]
unMapDataDenotation = \case
Map es -> pure es
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
_ -> fail "Expected the Map constructor but got a different one"
{-# INLINE unMapDataDenotation #-}
in makeBuiltinMeaning
Expand All @@ -1624,7 +1625,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
let unListDataDenotation :: Data -> BuiltinResult [Data]
unListDataDenotation = \case
List ds -> pure ds
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
_ -> fail "Expected the List constructor but got a different one"
{-# INLINE unListDataDenotation #-}
in makeBuiltinMeaning
Expand All @@ -1635,7 +1636,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
let unIDataDenotation :: Data -> BuiltinResult Integer
unIDataDenotation = \case
I i -> pure i
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
_ -> fail "Expected the I constructor but got a different one"
{-# INLINE unIDataDenotation #-}
in makeBuiltinMeaning
Expand All @@ -1646,7 +1647,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
let unBDataDenotation :: Data -> BuiltinResult BS.ByteString
unBDataDenotation = \case
B b -> pure b
-- See Note [Operational vs structural errors within builtins].
-- See Note [Structural vs operational errors within builtins].
_ -> fail "Expected the B constructor but got a different one"
{-# INLINE unBDataDenotation #-}
in makeBuiltinMeaning
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ module PlutusCore.Evaluation.Machine.Ck
, CkM
, CkValue
, runCk
, extractEvaluationResult
, unsafeToEvaluationResult
, splitStructuralOperational
, unsafeSplitStructuralOperational
, evaluateCk
, evaluateCkNoEmit
, readKnownCk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ module PlutusCore.Evaluation.Machine.Exception
, throwing
, throwing_
, throwingWithCause
, extractEvaluationResult
, unsafeToEvaluationResult
, splitStructuralOperational
, unsafeSplitStructuralOperational
) where

import PlutusPrelude
Expand Down Expand Up @@ -82,34 +82,36 @@ type EvaluationException structural operational =
ErrorWithCause (EvaluationError structural operational)

{- Note [Ignoring context in OperationalEvaluationError]
The 'OperationalEvaluationError' error has a term argument, but 'extractEvaluationResult' just
The 'OperationalEvaluationError' error has a term argument, but 'splitStructuralOperational' just
discards this and returns 'EvaluationFailure'. This means that, for example, if we use the @plc@
command to execute a program containing a division by zero, @plc@ exits silently without reporting
that anything has gone wrong (but returning a non-zero exit code to the shell via 'exitFailure').
This is because 'OperationalEvaluationError' is used in cases when a PLC program itself goes wrong
(see the Haddocks of 'EvaluationError'). This is used to signal unsuccessful validation and so is
(see the Haddock of 'EvaluationError'). This is used to signal unsuccessful validation and so is
not regarded as a real error; in contrast structural errors are genuine errors and we report their
context if available.
-}

-- See the Haddock of 'EvaluationError' for what structural and operational errors are.
-- See Note [Ignoring context in OperationalEvaluationError].
-- | Preserve the contents of an 'StructuralEvaluationError' as a 'Left' and turn an
-- 'OperationalEvaluationError' into a @Right EvaluationFailure@.
extractEvaluationResult
-- 'OperationalEvaluationError' into a @Right EvaluationFailure@ (thus erasing the content of the
-- error in the latter case).
splitStructuralOperational
:: Either (EvaluationException structural operational term) a
-> Either (ErrorWithCause structural term) (EvaluationResult a)
extractEvaluationResult (Right term) = Right $ EvaluationSuccess term
extractEvaluationResult (Left (ErrorWithCause evalErr cause)) = case evalErr of
StructuralEvaluationError err -> Left $ ErrorWithCause err cause
splitStructuralOperational (Right term) = Right $ EvaluationSuccess term
splitStructuralOperational (Left (ErrorWithCause evalErr cause)) = case evalErr of
StructuralEvaluationError err -> Left $ ErrorWithCause err cause
OperationalEvaluationError _ -> Right EvaluationFailure

-- | Throw on a 'StructuralEvaluationError' and turn an 'OperationalEvaluationError' into an
-- 'EvaluationFailure'.
unsafeToEvaluationResult
-- 'EvaluationFailure' (thus erasing the content of the error in the latter case).
unsafeSplitStructuralOperational
:: (PrettyPlc structural, PrettyPlc term, Typeable structural, Typeable term)
=> Either (EvaluationException structural operational term) a
-> EvaluationResult a
unsafeToEvaluationResult = unsafeFromEither . extractEvaluationResult
unsafeSplitStructuralOperational = unsafeFromEither . splitStructuralOperational

instance (HasPrettyDefaults config ~ 'True, Pretty fun) =>
PrettyBy config (MachineError fun) where
Expand Down
39 changes: 36 additions & 3 deletions plutus-core/plutus-ir/test/PlutusIR/Generators/QuickCheck/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,33 @@

module PlutusIR.Generators.QuickCheck.Tests where

import PlutusPrelude

import PlutusCore.Generators.QuickCheck
import PlutusIR.Generators.QuickCheck

import PlutusCore.Builtin (fromValue)
import PlutusCore.Default
import PlutusCore.Evaluation.Machine.ExBudget
import PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCekParametersForTesting)
import PlutusCore.Name.Unique
import PlutusCore.Quote
import PlutusCore.Rename
import PlutusCore.Test (toUPlc)
import PlutusCore.Version (latestVersion)
import PlutusIR
import PlutusIR.Core.Instance.Pretty.Readable
import PlutusIR.Test ()
import UntypedPlutusCore qualified as UPLC
import UntypedPlutusCore.Evaluation.Machine.Cek (restricting, runCekNoEmit,
unsafeSplitStructuralOperational)

import Control.Exception
import Control.Monad.Reader
import Data.Bifunctor
import Data.Char
import Data.Either
import Data.Function
import Data.Hashable
import Data.HashMap.Strict qualified as HashMap
import Data.List.NonEmpty (NonEmpty (..))
import Data.Map.Strict qualified as Map
import Test.QuickCheck

Expand Down Expand Up @@ -184,3 +193,27 @@ prop_noTermShrinkLoops = withMaxSuccess 10 $
forAllDoc "ty,tm" genTypeAndTerm_
(\(ty', tm') -> filter ((/= tm') . snd) $ shrinkClosedTypedTerm (ty', tm')) $ \(ty, tm) ->
tm `notElem` map snd (shrinkClosedTypedTerm (ty, tm))

-- | Check that evaluation of the given term doesn't fail with a structural error.
noStructuralErrors :: UPLC.Term Name DefaultUni DefaultFun () -> IO ()
noStructuralErrors term =
-- Throw on a structural evaluation error and succeed on both an operational evaluation error and
-- evaluation success.
void . evaluate . unsafeSplitStructuralOperational . fst $ do
let -- The numbers are picked so that evaluation of the arbitrarily generated term always
-- finishes in reasonable time even if evaluation loops (in which case we'll get an
-- out-of-budget failure).
budgeting = restricting . ExRestrictingBudget $ ExBudget 1000000000 1000000000
runCekNoEmit defaultCekParametersForTesting budgeting term

-- | Test that evaluation of well-typed terms doesn't fail with a structural error.
prop_noStructuralErrors :: Property
prop_noStructuralErrors = withMaxSuccess 99 $
forAllDoc "ty,tm" genTypeAndTerm_ shrinkClosedTypedTerm $ \(_, termPir) -> ioProperty $ do
termUPlc <- fmap UPLC._progTerm . modifyError throw . toUPlc $ Program () latestVersion termPir
noStructuralErrors termUPlc

-- | Test that evaluation of an ill-typed terms fails with a structural error.
prop_yesStructuralErrors :: Property
prop_yesStructuralErrors = expectFailure . ioProperty $
noStructuralErrors $ UPLC.Apply () (fromValue True) (fromValue ())
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import PlutusIR.Core qualified as PIR
import PlutusIR.Parser (pTerm)
import UntypedPlutusCore.Core qualified as UPLC
import UntypedPlutusCore.Evaluation.Machine.Cek (CekValue, EvaluationResult (..), evaluateCek,
logEmitter, unsafeToEvaluationResult)
logEmitter, unsafeSplitStructuralOperational)
import UntypedPlutusCore.Evaluation.Machine.Cek.CekMachineCosts (CekMachineCosts)

pirTermFromFile
Expand Down Expand Up @@ -83,7 +83,7 @@ evaluateUplcProgramWithTraces
:: UPLC.Program Name DefaultUni DefaultFun ()
-> (EvaluationResult (UPLC.Term Name DefaultUni DefaultFun ()), [Text])
evaluateUplcProgramWithTraces uplcProg =
first unsafeToEvaluationResult $
first unsafeSplitStructuralOperational $
evaluateCek logEmitter machineParameters (uplcProg ^. UPLC.progTerm)
where
costModel :: CostModel CekMachineCosts BuiltinCostModel =
Expand Down
12 changes: 11 additions & 1 deletion plutus-core/prelude/PlutusPrelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ module PlutusPrelude
, distinct
, unsafeFromRight
, tryError
, modifyError
, lowerInitialChar
) where

Expand All @@ -108,7 +109,7 @@ import Control.DeepSeq (NFData)
import Control.Exception (Exception, throw)
import Control.Lens (Fold, Lens', ala, lens, over, set, view, (%~), (&), (.~), (<&>), (^.))
import Control.Monad
import Control.Monad.Except (MonadError, catchError)
import Control.Monad.Except (ExceptT, MonadError, catchError, runExceptT, throwError)
import Control.Monad.Reader (MonadReader, ask)
import Data.Array (Array, Ix, listArray)
import Data.Bifunctor (first, second)
Expand Down Expand Up @@ -265,6 +266,15 @@ timesA = ala Endo . stimes
tryError :: MonadError e m => m a -> m (Either e a)
tryError a = (Right <$> a) `catchError` (pure . Left)

{- A different 'MonadError' analogue to the 'withExceptT' function.
Modify the value (and possibly the type) of an error in an @ExceptT@-transformed
monad, while stripping the @ExceptT@ layer.
TODO: remove when we switch to mtl>=2.3.1
-}
modifyError :: MonadError e' m => (e -> e') -> ExceptT e m a -> m a
modifyError f m = runExceptT m >>= either (throwError . f) pure

allSame :: Eq a => [a] -> Bool
allSame [] = True
allSame (x:xs) = all (x ==) xs
Expand Down
Loading

1 comment on commit 3d42b87

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Plutus Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 3d42b87 Previous: e94d73c Ratio
validation-auction_1-1 259 μs 200.1 μs 1.29
validation-crowdfunding-success-2 302.6 μs 286.1 μs 1.06
validation-crowdfunding-success-3 300.3 μs 205 μs 1.46
validation-future-settle-early-3 772.6 μs 595.2 μs 1.30
validation-future-settle-early-4 865.6 μs 599.9 μs 1.44
validation-game-sm-success_1-1 557 μs 382.7 μs 1.46
validation-game-sm-success_1-2 271.8 μs 198.1 μs 1.37
validation-ping-pong_2-1 285.6 μs 259.5 μs 1.10
validation-prism-1 240 μs 165.2 μs 1.45
validation-prism-2 585.4 μs 466.6 μs 1.25
validation-uniswap-4 475.1 μs 391.4 μs 1.21
validation-uniswap-5 1640 μs 1217 μs 1.35
validation-decode-auction_1-1 271.6 μs 222.4 μs 1.22
validation-decode-auction_1-2 751.3 μs 532.5 μs 1.41
validation-decode-auction_1-3 750.5 μs 532 μs 1.41
validation-decode-auction_1-4 274.5 μs 194.3 μs 1.41
validation-decode-auction_2-1 272.9 μs 194.2 μs 1.41
validation-decode-auction_2-2 753.4 μs 534 μs 1.41
validation-decode-auction_2-3 752.7 μs 665.6 μs 1.13
validation-decode-multisig-sm-1 815.3 μs 577 μs 1.41
validation-decode-multisig-sm-2 816.7 μs 577.5 μs 1.41
validation-decode-multisig-sm-3 816.5 μs 576.5 μs 1.42
validation-decode-multisig-sm-4 816.2 μs 576.1 μs 1.42
validation-decode-multisig-sm-5 816.3 μs 577 μs 1.41
validation-decode-prism-3 333.4 μs 235.8 μs 1.41
validation-decode-pubkey-1 234 μs 165.3 μs 1.42
validation-decode-stablecoin_1-1 1196 μs 992 μs 1.21
validation-decode-stablecoin_1-3 1195 μs 992.3 μs 1.20
validation-decode-stablecoin_1-4 232.2 μs 177 μs 1.31
validation-decode-stablecoin_2-2 194.1 μs 177.9 μs 1.09
validation-decode-uniswap-2 331.6 μs 315.6 μs 1.05
validation-decode-uniswap-3 1022.9999999999999 μs 730.7 μs 1.40
validation-decode-uniswap-6 195.3 μs 178.8 μs 1.09
nofib-clausify/formula1 4369 μs 3103 μs 1.41
nofib-clausify/formula2 5837 μs 4684 μs 1.25
nofib-clausify/formula5 77330 μs 70410 μs 1.10
nofib-knights/4x4 25120 μs 17770 μs 1.41
nofib-knights/6x6 65069.99999999999 μs 46660 μs 1.39
nofib-knights/8x8 115800 μs 81830 μs 1.42
nofib-primetest/05digits 14440 μs 10230 μs 1.41
nofib-primetest/10digits 24260 μs 20060 μs 1.21
nofib-primetest/30digits 87300 μs 65120.00000000001 μs 1.34
nofib-queens4x4/bjbt1 9248 μs 7098 μs 1.30
nofib-queens5x5/bm 108100 μs 80400 μs 1.34
marlowe-semantics/0000020002010200020101020201000100010001020101020201010000020102 457.2 μs 326.1 μs 1.40
marlowe-semantics/0001000101000000010101000001000001010101010100000001000001010000 628.7 μs 452.5 μs 1.39
marlowe-semantics/0003040402030103010203030303000200000104030002040304020400000102 1473 μs 1177 μs 1.25
marlowe-role-payout/622a7f3bc611b5149253c9189da022a9ff296f60a5b7c172a6dc286faa7284fa 288.6 μs 206.3 μs 1.40
marlowe-role-payout/f1a1e6a487f91feca5606f72bbb1e948c71abf043c6a0ea83bfea9ec6a0f08d8 241.3 μs 226.1 μs 1.07
marlowe-role-payout/f2932e4ca4bbb94b0a9ffbe95fcb7bd5639d9751d75d56d5e14efa5bbed981df 239.2 μs 171.5 μs 1.39
marlowe-role-payout/f53e8cafe26647ccce51e4c31db13608aea1f39034c0f52dee2e5634ef66e747 264.6 μs 188 μs 1.41
marlowe-role-payout/f7275afb60e33a550df13a132102e7e925dd28965a4efbe510a89b077ff9417f 240.5 μs 172.4 μs 1.40
marlowe-role-payout/fc8c5f45ffcdb024c21e0f34b22c23de8045a94d5e1a5bda1555c45ddb059f82 253.8 μs 181.8 μs 1.40
marlowe-role-payout/ff38b1ec89952d0247630f107a90cbbeb92ecbfcd19b284f60255718e4ec7548 292.8 μs 207.8 μs 1.41

This comment was automatically generated by workflow using github-action-benchmark.

CC: @IntersectMBO/plutus-core

Please sign in to comment.