Skip to content

Commit

Permalink
Test case for an impure trace message, added note.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unisay committed Apr 17, 2024
1 parent 11dec00 commit 4879e4f
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,19 @@ import PlutusCore.Default.Builtins qualified as Builtin
import PlutusIR.Transform.RewriteRules.Common (pattern A, pattern B, pattern I)
import PlutusIR.Transform.RewriteRules.Internal (RewriteRules (..))

{- Note [Impure trace messages]
Removing of traces could change behavior of those programs that use impure trace messages
e.g. `trace (error ()) foo`.
While it is possible to force evaluation of a trace message when removing a trace call
for the sake of a behavior preservation, this has a downside that pure messages remain
in the program and are not elimitated as a "dead" code.
This downside would defeat the purpose of removing traces, so we decided to not force.
-}

rewriteRuleRemoveTrace :: RewriteRules uni DefaultFun
rewriteRuleRemoveTrace = RewriteRules \_varsInfo -> \case
B Builtin.Trace `I` _ty `A` _msg `A` arg -> pure arg
B Builtin.Trace `I` _argTy `A` _msg `A` arg -> pure arg
term -> pure term
29 changes: 22 additions & 7 deletions plutus-tx-plugin/test/Plugin/NoTrace/Lib.hs
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wno-unused-foralls #-}

module Plugin.NoTrace.Lib where

import Control.Lens (universeOf, (^.))
import Data.Int (Int)
import Data.List (length)
import Prelude hiding (Show, show, (+))

import Control.Lens (universeOf, (&), (^.))
import GHC.Exts (noinline)
import PlutusCore.Builtin.Debug qualified as Builtin
import PlutusTx.Bool (Bool)
import PlutusTx.Builtins (BuiltinString, Integer, appendString)
import PlutusTx.Code (CompiledCode, getPlcNoAnn)
import PlutusCore.Default.Builtins qualified as Builtin
import PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCekParameters)
import PlutusTx.Builtins (BuiltinString, appendString, error)
import PlutusTx.Code (CompiledCode, getPlc, getPlcNoAnn)
import PlutusTx.Numeric ((+))
import PlutusTx.Show.TH (Show (show))
import PlutusTx.Trace (trace, traceError)
import UntypedPlutusCore qualified as UPLC
import UntypedPlutusCore.Evaluation.Machine.Cek (counting, noEmitter)
import UntypedPlutusCore.Evaluation.Machine.Cek.Internal (runCekDeBruijn)

data Arg = MkArg

Expand All @@ -32,6 +35,15 @@ countTraces code =
, subterm@(UPLC.Builtin _ Builtin.Trace) <- universeOf UPLC.termSubterms term
]

evaluatesToError :: CompiledCode a -> Bool
evaluatesToError = not . evaluatesWithoutError

evaluatesWithoutError :: CompiledCode a -> Bool
evaluatesWithoutError code =
runCekDeBruijn defaultCekParameters counting noEmitter (getPlc code ^. UPLC.progTerm) & \case
(Left _exception, _counter, _logs) -> False
(Right _result, _counter, _logs) -> True

----------------------------------------------------------------------------------------------------
-- Functions that contain traces -------------------------------------------------------------------

Expand Down Expand Up @@ -62,3 +74,6 @@ traceRepeatedly =
i2 = trace "Making my second int" (2 :: Integer)
i3 = trace "Adding them up" (i1 + i2)
in i3

traceImpure :: ()
traceImpure = trace ("Message: " `appendString` PlutusTx.Builtins.error ()) ()
15 changes: 12 additions & 3 deletions plutus-tx-plugin/test/Plugin/NoTrace/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ module Plugin.NoTrace.Spec where
import Prelude

import Plugin.NoTrace.Lib (countTraces)
import Plugin.NoTrace.Lib qualified as Lib
import Plugin.NoTrace.WithoutTraces qualified as WithoutTraces
import Plugin.NoTrace.WithTraces qualified as WithTraces
import Test.Tasty (testGroup)
import Test.Tasty.Extras (TestNested)
import Test.Tasty.HUnit (testCase, (@=?))
import Test.Tasty.HUnit (assertBool, testCase, (@=?))

noTrace :: TestNested
noTrace = pure do
testGroup
"remove-trace"
[ testGroup
"Trace calls are present"
"Trace calls are preserved"
[ testCase "trace-argument" $
1 @=? countTraces WithTraces.traceArgument
, testCase "trace-show" $
Expand All @@ -33,9 +34,13 @@ noTrace = pure do
1 @=? countTraces WithTraces.traceNonConstant
, testCase "trace-repeatedly" $
3 @=? countTraces WithTraces.traceRepeatedly
, testCase "trace-impure" $
1 @=? countTraces WithTraces.traceImpure
, testCase "trace-impure with effect" $ -- See note [Impure trace messages]
assertBool "Effect is missing" (Lib.evaluatesToError WithTraces.traceImpure)
]
, testGroup
"Trace calls are absent"
"Trace calls are removed"
[ testCase "trace-argument" $
0 @=? countTraces WithoutTraces.traceArgument
, testCase "trace-show" $
Expand All @@ -48,5 +53,9 @@ noTrace = pure do
0 @=? countTraces WithoutTraces.traceNonConstant
, testCase "trace-repeatedly" $
0 @=? countTraces WithoutTraces.traceRepeatedly
, testCase "trace-impure" $
0 @=? countTraces WithoutTraces.traceImpure
, testCase "trace-impure without effect" $ -- See note [Impure trace messages]
assertBool "Effect wasn't erased" (Lib.evaluatesWithoutError WithoutTraces.traceImpure)
]
]
3 changes: 3 additions & 0 deletions plutus-tx-plugin/test/Plugin/NoTrace/WithTraces.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ traceComplex = plc (Proxy @"traceComplex") Lib.traceComplex

traceRepeatedly :: CompiledCode Integer
traceRepeatedly = plc (Proxy @"traceRepeatedly") Lib.traceRepeatedly

traceImpure :: CompiledCode ()
traceImpure = plc (Proxy @"traceImpure") Lib.traceImpure
3 changes: 3 additions & 0 deletions plutus-tx-plugin/test/Plugin/NoTrace/WithoutTraces.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ traceComplex = plc (Proxy @"traceComplex") Lib.traceComplex

traceRepeatedly :: CompiledCode Integer
traceRepeatedly = plc (Proxy @"traceRepeatedly") Lib.traceRepeatedly

traceImpure :: CompiledCode ()
traceImpure = plc (Proxy @"traceImpure") Lib.traceImpure

0 comments on commit 4879e4f

Please sign in to comment.