Skip to content

Commit 2a0c419

Browse files
committed
tx-generator: fix choice of correct cost model
1 parent e50799c commit 2a0c419

File tree

1 file changed

+42
-34
lines changed
  • bench/tx-generator/src/Cardano/TxGenerator/Setup

1 file changed

+42
-34
lines changed

bench/tx-generator/src/Cardano/TxGenerator/Setup/Plutus.hs

+42-34
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
{-# LANGUAGE GADTs #-}
2+
{-# LANGUAGE NamedFieldPuns #-}
23
{-# LANGUAGE RankNTypes #-}
34
{-# LANGUAGE ScopedTypeVariables #-}
45

56
-- | This module provides convenience functions when dealing with Plutus scripts.
6-
-- It currently only supports PlutusV1 script & cost model.
77
module Cardano.TxGenerator.Setup.Plutus
88
( readPlutusScript
99
, preExecutePlutusScript
1010
)
1111
where
12-
import Control.Monad.Writer (runWriter)
1312

14-
import Data.Map.Strict (Map)
15-
import qualified Data.Map.Strict as Map
16-
import Data.Text (Text)
13+
import Data.Bifunctor (bimap)
14+
import Data.Map.Strict as Map (lookup, toAscList)
1715

1816
import Control.Monad.Trans.Except
1917
import Control.Monad.Trans.Except.Extra
18+
import Control.Monad.Writer (runWriter)
2019

2120
import Cardano.CLI.Shelley.Run.Read (readFileScriptInAnyLang)
2221

@@ -31,6 +30,9 @@ import qualified PlutusLedgerApi.V2 as PlutusV2
3130
import Cardano.TxGenerator.Types
3231

3332

33+
type ProtocolVersion = (Int, Int)
34+
35+
3436
readPlutusScript :: FilePath -> IO (Either TxGenError ScriptInAnyLang)
3537
readPlutusScript fp
3638
= runExceptT $ do
@@ -46,37 +48,46 @@ preExecutePlutusScript ::
4648
-> ScriptData
4749
-> ScriptRedeemer
4850
-> Either TxGenError ExecutionUnits
49-
preExecutePlutusScript protocolParameters script@(ScriptInAnyLang scriptLang _) datum redeemer
51+
preExecutePlutusScript
52+
ProtocolParameters{protocolParamCostModels, protocolParamProtocolVersion}
53+
script@(ScriptInAnyLang scriptLang _)
54+
datum
55+
redeemer
5056
= runExcept $ do
57+
costModel <- hoistMaybe (TxGenError $ "preExecutePlutusScript: cost model unavailable for: " ++ show scriptLang) $
58+
case script of
59+
ScriptInAnyLang _ (PlutusScript lang _) ->
60+
AnyPlutusScriptVersion lang `Map.lookup` protocolParamCostModels
61+
_ ->
62+
Nothing
63+
5164
case script of
5265
ScriptInAnyLang (PlutusScriptLanguage PlutusScriptV1) script' ->
53-
hoistEither $ preExecutePlutusV1 protocolParameters script' datum redeemer
66+
hoistEither $ preExecutePlutusV1 protocolVersion script' datum redeemer costModel
5467
ScriptInAnyLang (PlutusScriptLanguage PlutusScriptV2) script' ->
55-
hoistEither $ preExecutePlutusV2 protocolParameters script' datum redeemer
68+
hoistEither $ preExecutePlutusV2 protocolVersion script' datum redeemer costModel
5669
_ ->
5770
throwE $ TxGenError $ "preExecutePlutusScript: script not supported: " ++ show scriptLang
71+
where
72+
protocolVersion :: ProtocolVersion
73+
protocolVersion = bimap fromIntegral fromIntegral protocolParamProtocolVersion
5874

5975
preExecutePlutusV1 ::
60-
ProtocolParameters
76+
ProtocolVersion
6177
-> Script PlutusScriptV1
6278
-> ScriptData
6379
-> ScriptRedeemer
80+
-> CostModel
6481
-> Either TxGenError ExecutionUnits
65-
preExecutePlutusV1 protocolParameters (PlutusScript _ (PlutusScriptSerialised script)) datum redeemer
66-
= fst $ -- for now, we discard warnings (:: PlutusCore.Evaluation.Machine.CostModelInterface.CostModelApplyWarn)
67-
runWriter $ runExceptT go
82+
preExecutePlutusV1 protocolVersion_ (PlutusScript _ (PlutusScriptSerialised script)) datum redeemer costModel
83+
= fst $ runWriter $ runExceptT go -- for now, we discard warnings (:: PlutusCore.Evaluation.Machine.CostModelInterface.CostModelApplyWarn)
6884
where
85+
protocolVersion = uncurry PlutusV1.ProtocolVersion protocolVersion_
6986
go
7087
= do
71-
CostModel costModel <- hoistMaybe (TxGenError "preExecutePlutusScript: costModel unavailable") $
72-
AnyPlutusScriptVersion PlutusScriptV1 `Map.lookup` protocolParamCostModels protocolParameters
7388
evaluationContext <- firstExceptT PlutusError $
7489
PlutusV1.mkEvaluationContext (flattenCostModel costModel)
7590

76-
let
77-
(majVer, minVer) = protocolParamProtocolVersion protocolParameters
78-
protocolVersion = PlutusV1.ProtocolVersion (fromIntegral majVer) (fromIntegral minVer)
79-
8091
exBudget <- firstExceptT PlutusError $
8192
hoistEither $
8293
snd $ PlutusV1.evaluateScriptCounting protocolVersion PlutusV1.Verbose evaluationContext script
@@ -85,7 +96,7 @@ preExecutePlutusV1 protocolParameters (PlutusScript _ (PlutusScriptSerialised sc
8596
, PlutusV1.toData dummyContext
8697
]
8798

88-
x <- hoistMaybe (TxGenError "preExecutePlutusScript: could not convert to execution units") $
99+
x <- hoistMaybe (TxGenError "preExecutePlutusV1: could not convert to execution units") $
89100
exBudgetToExUnits exBudget
90101
return $ fromAlonzoExUnits x
91102

@@ -110,26 +121,21 @@ preExecutePlutusV1 protocolParameters (PlutusScript _ (PlutusScriptSerialised sc
110121
}
111122

112123
preExecutePlutusV2 ::
113-
ProtocolParameters
124+
ProtocolVersion
114125
-> Script PlutusScriptV2
115126
-> ScriptData
116127
-> ScriptRedeemer
128+
-> CostModel
117129
-> Either TxGenError ExecutionUnits
118-
preExecutePlutusV2 protocolParameters (PlutusScript _ (PlutusScriptSerialised script)) datum redeemer
119-
= fst $ -- for now, we discard warnings (:: PlutusCore.Evaluation.Machine.CostModelInterface.CostModelApplyWarn)
120-
runWriter $ runExceptT go
130+
preExecutePlutusV2 protocolVersion_ (PlutusScript _ (PlutusScriptSerialised script)) datum redeemer costModel
131+
= fst $ runWriter $ runExceptT go -- for now, we discard warnings (:: PlutusCore.Evaluation.Machine.CostModelInterface.CostModelApplyWarn)
121132
where
133+
protocolVersion = uncurry PlutusV2.ProtocolVersion protocolVersion_
122134
go
123135
= do
124-
CostModel costModel <- hoistMaybe (TxGenError "preExecutePlutusScript: costModel unavailable") $
125-
AnyPlutusScriptVersion PlutusScriptV1 `Map.lookup` protocolParamCostModels protocolParameters
126136
evaluationContext <- firstExceptT PlutusError $
127137
PlutusV2.mkEvaluationContext (flattenCostModel costModel)
128138

129-
let
130-
(majVer, minVer) = protocolParamProtocolVersion protocolParameters
131-
protocolVersion = PlutusV2.ProtocolVersion (fromIntegral majVer) (fromIntegral minVer)
132-
133139
exBudget <- firstExceptT PlutusError $
134140
hoistEither $
135141
snd $ PlutusV2.evaluateScriptCounting protocolVersion PlutusV2.Verbose evaluationContext script
@@ -138,7 +144,7 @@ preExecutePlutusV2 protocolParameters (PlutusScript _ (PlutusScriptSerialised sc
138144
, PlutusV2.toData dummyContext
139145
]
140146

141-
x <- hoistMaybe (TxGenError "preExecutePlutusScript: could not convert to execution units") $
147+
x <- hoistMaybe (TxGenError "preExecutePlutusV2: could not convert to execution units") $
142148
exBudgetToExUnits exBudget
143149
return $ fromAlonzoExUnits x
144150

@@ -164,9 +170,11 @@ preExecutePlutusV2 protocolParameters (PlutusScript _ (PlutusScriptSerialised sc
164170
, PlutusV2.txInfoRedeemers = PlutusV2.fromList []
165171
}
166172

167-
-- This is an incredibly bad idea. The order of the output list is inportant, but:
173+
-- The order of the output list is important, but:
168174
-- * This way of flattening it is not guaranteed to always be correct.
169175
-- * There is no way to ensure that the list remains in the correct order.
170-
-- IMO, the `[Integer]` should *NEVER* have been exposed from `ledger`.
171-
flattenCostModel :: Map Text Integer -> [Integer]
172-
flattenCostModel = map snd . Map.toAscList
176+
-- However, we're bound to the type `Cardano.Api.ProtocolParameters.CostModel` which
177+
-- might be changed from a key-value map to something providing stronger guarantees.
178+
flattenCostModel :: CostModel -> [Integer]
179+
flattenCostModel (CostModel cm)
180+
= snd <$> Map.toAscList cm

0 commit comments

Comments
 (0)