Skip to content

Commit

Permalink
[Errors] Preserve operational unlifting errors (#6181)
Browse files Browse the repository at this point in the history
  • Loading branch information
effectfully committed Jun 12, 2024
1 parent 69eff87 commit 6910d70
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 13 deletions.
7 changes: 0 additions & 7 deletions plutus-core/plutus-core/src/PlutusCore/Builtin/KnownType.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ module PlutusCore.Builtin.KnownType
, BuiltinResult (..)
, ReadKnownM
, MakeKnownIn (..)
, liftReadKnownM
, readKnownConstant
, MakeKnown
, ReadKnownIn (..)
Expand Down Expand Up @@ -262,12 +261,6 @@ typeMismatchError uniExp uniAct =
-- | The monad that 'readKnown' runs in.
type ReadKnownM = Either BuiltinError

-- | Lift a 'ReadKnownM' computation into 'BuiltinResult'.
liftReadKnownM :: ReadKnownM a -> BuiltinResult a
liftReadKnownM (Left err) = BuiltinFailure mempty err
liftReadKnownM (Right x) = BuiltinSuccess x
{-# INLINE liftReadKnownM #-}

-- See Note [Unlifting a term as a value of a built-in type].
-- | Convert a constant embedded into a PLC term to the corresponding Haskell value.
readKnownConstant :: forall val a. KnownBuiltinType val a => val -> ReadKnownM a
Expand Down
5 changes: 2 additions & 3 deletions plutus-core/plutus-core/src/PlutusCore/Builtin/Meaning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import PlutusCore.Evaluation.Machine.ExBudgetStream
import PlutusCore.Evaluation.Machine.ExMemoryUsage
import PlutusCore.Name.Unique

import Control.Monad.Except (throwError)
import Data.Array
import Data.Kind qualified as GHC
import Data.Proxy
Expand Down Expand Up @@ -229,8 +230,6 @@ instance (Typeable res, KnownTypeAst TyName (UniOf val) res, MakeKnown val res)
KnownMonotype val '[] res where
knownMonotype = TypeSchemeResult

-- We need to lift the 'ReadKnownM' action into 'BuiltinResult',
-- hence 'liftReadKnownM'.
toMonoF =
either
-- Unlifting has failed and we don't care about costing at this point, since we're about
Expand All @@ -245,7 +244,7 @@ instance (Typeable res, KnownTypeAst TyName (UniOf val) res, MakeKnown val res)
-- either a budgeting failure or a budgeting success with a cost and a 'BuiltinResult'
-- computation inside, but that would slow things down a bit and the current strategy is
-- reasonable enough.
(BuiltinCostedResult (ExBudgetLast mempty) . BuiltinFailure mempty)
(BuiltinCostedResult (ExBudgetLast mempty) . throwError)
(\(x, cost) -> BuiltinCostedResult cost $ makeKnown x)
{-# INLINE toMonoF #-}

Expand Down
28 changes: 28 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Builtin/Result.hs
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,31 @@ instance Monad BuiltinResult where

(>>) = (*>)
{-# INLINE (>>) #-}

-- | 'throwError' puts every operational unlifting error into the 'BuiltinFailure' logs. This is to
-- compensate for the historical lack of error message content in operational errors (structural
-- ones don't have this problem) in our evaluators (the CK and CEK machines). It would be better to
-- fix the underlying issue and allow operational evaluation errors to carry some form of content,
-- but for now we just fix the symptom in order for the end user to see the error message that they
-- are supposed to see. The fix even makes some sense: what we do here is we emulate logging when
-- the thrown unlifting error is an operational one, i.e. this is similar to what some builtins do
-- manually (like when a crypto builtin fails and puts info about the failure into the logs).
instance MonadError BuiltinError BuiltinResult where
throwError builtinErr = BuiltinFailure operationalLogs builtinErr where
operationalLogs = case builtinErr of
BuiltinUnliftingEvaluationError
(MkUnliftingEvaluationError
(OperationalEvaluationError
(MkUnliftingError operationalErr))) -> pure operationalErr
_ -> mempty

-- Throwing logs out is lame, but embedding them into the error would be weird, since that
-- would change the error. Not that any of that matters, we only implement this because it's a
-- method of 'MonadError' and we can't not implement it.
--
-- We could make it @MonadError (DList Text, BuiltinError)@, but logs are arbitrary and are not
-- necessarily an inherent part of an error, so preserving them is as questionable as not doing
-- so.
BuiltinFailure _ err `catchError` f = f err
res `catchError` _ = res
{-# INLINE catchError #-}
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,11 @@ fails fileName fun typeArgs termArgs = do
concatMap (\_ -> " <...>") termArgs
in testNestedNamedM mempty name $
testNestedNamedM mempty expectedToDisplay $
nestedGoldenVsDoc fileName ".err" . vsep $
map pretty logs ++ [prettyPlcReadableDef err]
nestedGoldenVsDoc fileName ".err" . vsep $ concat
[ [prettyPlcReadableDef err]
, ["Logs were:" | not $ null logs]
, map pretty logs
]

-- | Test all integer related builtins
test_Integer :: TestNested
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
An error has occurred:
The machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.
Caused by: (consByteString 256 #68656c6c6f20776f726c64)
Caused by: (consByteString 256 #68656c6c6f20776f726c64)
Logs were:
256 is not within the bounds of Word8

1 comment on commit 6910d70

@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: 6910d70 Previous: 69eff87 Ratio
nofib-clausify/formula3 11120 μs 10570 μs 1.05
nofib-clausify/formula4 25510 μs 24120 μs 1.06
nofib-knights/4x4 16990 μs 16170.000000000002 μs 1.05
nofib-knights/6x6 45230 μs 42660 μs 1.06
nofib-knights/8x8 79040 μs 75080 μs 1.05
nofib-primetest/10digits 19510 μs 18540 μs 1.05
nofib-primetest/20digits 39460 μs 37150 μs 1.06
nofib-primetest/30digits 60160 μs 57280 μs 1.05
marlowe-role-payout/f7275afb60e33a550df13a132102e7e925dd28965a4efbe510a89b077ff9417f 169.9 μs 161.8 μs 1.05
marlowe-role-payout/f2932e4ca4bbb94b0a9ffbe95fcb7bd5639d9751d75d56d5e14efa5bbed981df 165.5 μs 157 μs 1.05
marlowe-role-payout/f1a1e6a487f91feca5606f72bbb1e948c71abf043c6a0ea83bfea9ec6a0f08d8 168.2 μs 159.2 μs 1.06
marlowe-role-payout/ee3962fbd7373360f46decef3c9bda536a0b1daf6cda3b8a4bcfd6deeb5b4c53 195.2 μs 185.6 μs 1.05
marlowe-role-payout/ec4712ee820eb959a43ebedfab6735f2325fa52994747526ffd2a4f4f84dd58e 193.1 μs 182.8 μs 1.06
marlowe-role-payout/eabeeae18131af89fa57936c0e9eb8d2c7adba534f7e1a517d75410028fa0d6c 170.2 μs 161 μs 1.06
marlowe-role-payout/df487b2fd5c1583fa33644423849bc1ab5f02f37edc0c235f34ef01cb12604f6 176.8 μs 168.2 μs 1.05
marlowe-role-payout/da353bf9219801fa1bf703fc161497570954e9af7e10ffe95c911a9ef97e77bd 175.9 μs 167.2 μs 1.05
marlowe-role-payout/d6bc8ac4155e22300085784148bbc9d9bbfea896e1009dd396610a90e3943032 195.3 μs 185.3 μs 1.05
marlowe-role-payout/d5cda74eb0947e025e02fb8ed365df39d0a43e4b42cd3573ac2d8fcb29115997 187.6 μs 177.4 μs 1.06
marlowe-role-payout/cb2ab8e22d1f64e8d204dece092e90e9bf1fa8b2a6e9cba5012dbe4978065832 168.4 μs 159.7 μs 1.05
marlowe-role-payout/caa409c40e39aed9b0f59214b4baa178c375526dea6026b4552b88d2cc729716 160.1 μs 151.9 μs 1.05
marlowe-role-payout/c78eeba7681d2ab51b4758efa4c812cc041928837c6e7563d8283cce67ce2e02 181.7 μs 172.6 μs 1.05
marlowe-role-payout/c4d4c88c5fe378a25a034025994a0d0b1642f10c8e6e513f872327fa895bfc7e 180.5 μs 171.5 μs 1.05
marlowe-role-payout/c11490431db3a92efdda70933ba411a0423935e73a75c856e326dbcf6672f3bf 168.8 μs 159.9 μs 1.06
marlowe-role-payout/bd79f4a84db23b7c4cd219d498bd581e085cbc3437957e74a8862281a700700b 195.5 μs 185.8 μs 1.05
marlowe-role-payout/5ade103e9530dd0d572fe1b053ea65ad925c6ebbe321e873ace8b804363fa82c 237.2 μs 225.8 μs 1.05
marlowe-role-payout/5a0725d49c733130eda8bc6ed5234f7f6ff8c9dd2d201e8806125e5fbcc081f9 178.1 μs 169 μs 1.05
marlowe-role-payout/47364cfaf2c00f7d633283dce6cf84e4fd4e8228c0a0aa50e7c55f35c3ecaa1c 168 μs 158.7 μs 1.06
marlowe-role-payout/46f8d00030436e4da490a86b331fa6c3251425fb8c19556080e124d75bad7bd6 168.1 μs 160 μs 1.05
marlowe-role-payout/452e17d16222a427707fa83f63ffb79f606cc25c755a18b1e3274c964ed5ec99 206.7 μs 196 μs 1.05
marlowe-role-payout/4299c7fcf093a5dbfe114c188e32ca199b571a7c25cb7f766bf49f12dab308be 185.4 μs 175.3 μs 1.06
marlowe-role-payout/4121d88f14387d33ac5e1329618068e3848445cdd66b29e5ba382be2e02a174a 200.3 μs 189.7 μs 1.06
marlowe-role-payout/3897ef714bba3e6821495b706c75f8d64264c3fdaa58a3826c808b5a768c303d 173.5 μs 163.1 μs 1.06
marlowe-role-payout/371c10d2526fc0f09dbe9ed59e44dcd949270b27dc42035addd7ff9f7e0d05e7 200 μs 189.4 μs 1.06
marlowe-role-payout/36866914aa07cf62ef36cf2cd64c7f240e3371e27bb9fff5464301678e809c40 164.9 μs 156.1 μs 1.06
marlowe-role-payout/3569299fc986f5354d02e627a9eaa48ab46d5af52722307a0af72bae87e256dc 165.2 μs 155.4 μs 1.06
marlowe-role-payout/3565ee025317e065e8555eef288080276716366769aad89e03389f5ec4ce26d7 177.7 μs 166.9 μs 1.06
marlowe-role-payout/332c2b1c11383d1b373e1315201f1128010e0e1518332f273f141b23243f2a07 161.5 μs 151.9 μs 1.06
marlowe-role-payout/224ce46046fab9a17be4197622825f45cc0c59a6bd1604405148e43768c487ef 167.3 μs 158 μs 1.06
marlowe-role-payout/21a1426fb3fb3019d5dc93f210152e90b0a6e740ef509b1cdd423395f010e0ca 187 μs 177 μs 1.06
marlowe-role-payout/211e1b6c10260c4620074d2e372c260d38643a3d605f63772524034f0a4a7632 175.3 μs 164.9 μs 1.06
marlowe-role-payout/1a20b465d48a585ffd622bd8dc26a498a3c12f930ab4feab3a5064cfb3bc536a 184.3 μs 173.7 μs 1.06
marlowe-role-payout/195f522b596360690d04586a2563470f2214163435331a6622311f7323433f1c 163.9 μs 154.4 μs 1.06
marlowe-role-payout/159e5a1bf16fe984b5569be7011b61b5e98f5d2839ca7e1b34c7f2afc7ffb58e 170 μs 160.5 μs 1.06
marlowe-role-payout/121a0a1b12030616111f02121a0e070716090a0e031c071419121f141409031d 165.6 μs 156.7 μs 1.06
marlowe-role-payout/1138a04a83edc0579053f9ffa9394b41df38230121fbecebee8c039776a88c0c 167 μs 158.6 μs 1.05
marlowe-role-payout/0f010d040810040b10020e040f0e030b0a0d100f0c080c0c05000d04100c100f 196.2 μs 184.9 μs 1.06
marlowe-role-payout/0e97c9d9417354d9460f2eb35018d3904b7b035af16ab299258adab93be0911a 183.8 μs 174.7 μs 1.05
marlowe-role-payout/0e72f62b0f922e31a2340baccc768104025400cf7fdd7dae62fbba5fc770936d 189.3 μs 179.5 μs 1.05
marlowe-role-payout/0e00171d0f1e1f14070d0a00091f07101808021d081e1b120219081312081e15 171.1 μs 162 μs 1.06
marlowe-role-payout/0dbb692d2bf22d25eeceac461cfebf616f54003077a8473abc0457f18e025960 202.8 μs 192.8 μs 1.05
marlowe-role-payout/0d0f01050a0a0a0b0b050d0404090e0d0506000d0a041003040e0f100e0a0408 177.6 μs 167.8 μs 1.06
marlowe-role-payout/0c9d3634aeae7038f839a1262d1a8bc724dc77af9426459417a56ec73240f0e0 175.1 μs 165.5 μs 1.06
marlowe-role-payout/0bdca1cb8fa7e38e09062557b82490714052e84e2054e913092cd84ac071b961 198.3 μs 188.4 μs 1.05
marlowe-role-payout/07658a6c898ad6d624c37df1e49e909c2e9349ba7f4c0a6be5f166fe239bfcae 160.5 μs 151 μs 1.06
marlowe-role-payout/06317060a8e488b1219c9dae427f9ce27918a9e09ee8ac424afa33ca923f7954 177.8 μs 167 μs 1.06
marlowe-role-payout/057ebc80922f16a5f4bf13e985bf586b8cff37a2f6fe0f3ce842178c16981027 165 μs 156.2 μs 1.06
marlowe-role-payout/04f592afc6e57c633b9c55246e7c82e87258f04e2fb910c37d8e2417e9db46e5 235 μs 221.2 μs 1.06
marlowe-role-payout/0405010105020401010304080005050800040301010800080207080704020206 198.2 μs 186.9 μs 1.06
marlowe-role-payout/0403020000030204010000030001000202010101000304030001040404030100 179.3 μs 169.7 μs 1.06
marlowe-role-payout/03d730a62332c51c7b70c16c64da72dd1c3ea36c26b41cd1a1e00d39fda3d6cc 196.1 μs 185.7 μs 1.06
marlowe-role-payout/031d56d71454e2c4216ffaa275c4a8b3eb631109559d0e56f44ea8489f57ba97 210 μs 199.1 μs 1.05
marlowe-role-payout/0303020000020001010201060303040208070100050401080304020801030001 167.2 μs 157 μs 1.06
marlowe-role-payout/0202010002010100020102020102020001010101020102010001010101000100 168.5 μs 158.6 μs 1.06
marlowe-role-payout/0201020201020000020000010201020001020200000002010200000101010100 180.8 μs 169.2 μs 1.07
marlowe-role-payout/01dcc372ea619cb9f23c45b17b9a0a8a16b7ca0e04093ef8ecce291667a99a4c 161.8 μs 151.7 μs 1.07
marlowe-role-payout/0101000100000101010000010101000100010101000001000001000000010101 196.6 μs 184.7 μs 1.06
marlowe-role-payout/0004000402010401030101030100040000010104020201030001000204020401 184.1 μs 173.8 μs 1.06

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

CC: @IntersectMBO/plutus-core

Please sign in to comment.