Skip to content

Commit 013f1f2

Browse files
authored
Merge pull request IntersectMBO#3953 from input-output-hk/mpj/return-remaining-budget
SCP-2772: Teach evaluateScriptRestricting to return the used budget
2 parents dd41fd3 + c632199 commit 013f1f2

File tree

4 files changed

+18
-9
lines changed

4 files changed

+18
-9
lines changed

cabal.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ source-repository-package
185185
source-repository-package
186186
type: git
187187
location: https://github.com/input-output-hk/cardano-ledger-specs
188-
tag: 8efcfc755faae4db3a64ad45343235fce3ed5c47
188+
tag: 6b884673ab0bfa120b63a30fb4dc255e3f3a02bc
189189
subdir:
190190
byron/chain/executable-spec
191191
byron/crypto

nix/pkgs/haskell/haskell.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ let
4848
"https://github.com/shmish111/servant-purescript.git"."a76104490499aa72d40c2790d10e9383e0dbde63" = "11nxxmi5bw66va7psvrgrw7b7n85fvqgfp58yva99w3v9q3a50v9";
4949
"https://github.com/input-output-hk/cardano-base"."46502694f6a9f0498f822068008b232b3837a9e9" = "04bvsvghkrjhfjb3phh0s5yfb37fishglrrlcwbvcv48y2in1dcz";
5050
"https://github.com/input-output-hk/cardano-crypto.git"."07397f0e50da97eaa0575d93bee7ac4b2b2576ec" = "06sdx5ndn2g722jhpicmg96vsrys89fl81k8290b3lr6b1b0w4m3";
51-
"https://github.com/input-output-hk/cardano-ledger-specs"."8efcfc755faae4db3a64ad45343235fce3ed5c47" = "13mj8nqk4jglyl96d6zm3dbjmx2qn5gwn06g7cmanxiwfkfm7bi1";
51+
"https://github.com/input-output-hk/cardano-ledger-specs"."6b884673ab0bfa120b63a30fb4dc255e3f3a02bc" = "1lpr35zpp4sqy4lqra24wswwkmaryvgj4rlbkn5n3z79f83jqgz4";
5252
"https://github.com/input-output-hk/cardano-prelude"."fd773f7a58412131512b9f694ab95653ac430852" = "02jddik1yw0222wd6q0vv10f7y8rdgrlqaiy83ph002f9kjx7mh6";
5353
"https://github.com/input-output-hk/goblins"."cde90a2b27f79187ca8310b6549331e59595e7ba" = "17c88rbva3iw82yg9srlxjv2ia5wjb9cyqw44hik565f5v9svnyg";
5454
"https://github.com/input-output-hk/iohk-monitoring-framework"."46f994e216a1f8b36fe4669b47b2a7011b0e153c" = "1il8fx3misp3650ryj368b3x95ksz01zz3x0z9k00807j93d0ka0";

plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExBudget.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ possible to adjust them at runtime.
137137

138138
module PlutusCore.Evaluation.Machine.ExBudget
139139
( ExBudget(..)
140+
, minusExBudget
140141
, ExBudgetBuiltin(..)
141142
, ExRestrictingBudget(..)
142143
, LowerIntialCharacter
@@ -178,6 +179,10 @@ data ExBudget = ExBudget { exBudgetCPU :: ExCPU, exBudgetMemory :: ExMemory }
178179
deriving (FromJSON, ToJSON) via CustomJSON '[FieldLabelModifier LowerIntialCharacter] ExBudget
179180
-- LowerIntialCharacter won't actually do anything here, but let's have it in case we change the field names.
180181

182+
-- | Subract one 'ExBudget' from another. Does not guarantee that the result is positive.
183+
minusExBudget :: ExBudget -> ExBudget -> ExBudget
184+
minusExBudget (ExBudget c1 m1) (ExBudget c2 m2) = ExBudget (c1-c2) (m1-m2)
185+
181186
-- These functions are performance critical, so we can't use GenericSemigroupMonoid, and we insist that they be inlined.
182187
instance Semigroup ExBudget where
183188
{-# INLINE (<>) #-}

plutus-ledger-api/src/Plutus/V1/Ledger/Api.hs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,24 +220,25 @@ mkTermToEvaluate bs args = do
220220
pure t
221221

222222
-- | Evaluates a script, with a cost model and a budget that restricts how many
223-
-- resources it can use according to the cost model. There's a default cost
224-
-- model in 'UPLC.defaultBuiltinCostModel' and a budget called 'enormousBudget' in
225-
-- 'UntypedPlutusCore.Evaluation.Machine.Cek.ExBudgetMode' which should be large
226-
-- enough to evaluate any sensible program.
223+
-- resources it can use according to the cost model. Also returns the budget that
224+
-- was actually used.
225+
--
226+
-- Can be used to calculate budgets for scripts, but even in this case you must give
227+
-- a limit to guard against scripts that run for a long time or loop.
227228
evaluateScriptRestricting
228229
:: VerboseMode -- ^ Whether to produce log output
229230
-> CostModelParams -- ^ The cost model to use
230231
-> ExBudget -- ^ The resource budget which must not be exceeded during evaluation
231232
-> SerializedScript -- ^ The script to evaluate
232233
-> [PLC.Data] -- ^ The arguments to the script
233-
-> (LogOutput, Either EvaluationError ())
234+
-> (LogOutput, Either EvaluationError ExBudget)
234235
evaluateScriptRestricting verbose cmdata budget p args = swap $ runWriter @LogOutput $ runExceptT $ do
235236
appliedTerm <- mkTermToEvaluate p args
236237
model <- case applyCostModelParams PLC.defaultCekCostModel cmdata of
237238
Just model -> pure model
238239
Nothing -> throwError CostModelParameterMismatch
239240

240-
let (res, _, logs) =
241+
let (res, UPLC.RestrictingSt (PLC.ExRestrictingBudget final), logs) =
241242
UPLC.runCek
242243
(toMachineParameters model)
243244
(UPLC.restricting $ PLC.ExRestrictingBudget budget)
@@ -246,9 +247,12 @@ evaluateScriptRestricting verbose cmdata budget p args = swap $ runWriter @LogOu
246247

247248
tell logs
248249
liftEither $ first CekError $ void res
250+
pure (budget `PLC.minusExBudget` final)
249251

250252
-- | Evaluates a script, returning the minimum budget that the script would need
251-
-- to evaluate successfully.
253+
-- to evaluate successfully. This will take as long as the script takes, if you need to
254+
-- limit the execution time of the script also, you can use 'evaluateScriptRestricting', which
255+
-- also returns the used budget.
252256
evaluateScriptCounting
253257
:: VerboseMode -- ^ Whether to produce log output
254258
-> CostModelParams -- ^ The cost model to use

0 commit comments

Comments
 (0)