Skip to content

Commit 405bfc9

Browse files
Merge pull request #119 from mlabs-haskell/sam/expose-budget-multiplier
Sam/expose budget multiplier
2 parents 4ad6321 + 0042df9 commit 405bfc9

File tree

6 files changed

+60
-6
lines changed

6 files changed

+60
-6
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ Top-level configuration file fields:
126126
collectStats: `true` or `false`
127127
Save some stats during contract run (only transactions execution
128128
budgets supported atm) (default: false)
129+
budgetMultiplier: rational multiplier in form `1` or `1 % 2`
130+
(default: 1)
129131
```
130132

131133
To run the fake PAB, you need to prepare a few more things:

src/BotPlutusInterface/Config.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import Data.String.ToString (toString)
3333
import Data.Text (Text)
3434
import Data.Text qualified as Text
3535
import PlutusConfig.Base (
36+
customRationalSpec,
3637
enumToAtom,
3738
filepathSpec,
3839
maybeSpec,
@@ -95,6 +96,7 @@ instance ToValue PABConfig where
9596
pcPort
9697
pcEnableTxEndpoint
9798
pcCollectStats
99+
pcBudgetMultiplier
98100
) =
99101
Sections
100102
()
@@ -116,6 +118,7 @@ instance ToValue PABConfig where
116118
, Section () "port" $ toValue pcPort
117119
, Section () "enableTxEndpoint" $ toValue pcEnableTxEndpoint
118120
, Section () "collectStats" $ toValue pcCollectStats
121+
, Section () "budgetMultiplier" $ toValue pcBudgetMultiplier
119122
]
120123
{- ORMOLU_ENABLE -}
121124

@@ -206,6 +209,13 @@ pabConfigSpec = sectionsSpec "PABConfig" $ do
206209
trueOrFalseSpec
207210
"Save some stats during contract run (only transactions execution budgets supported atm)"
208211

212+
pcBudgetMultiplier <-
213+
sectionWithDefault'
214+
(pcBudgetMultiplier def)
215+
"budgetMultiplier"
216+
customRationalSpec
217+
"Multiplier on the budgets automatically calculated"
218+
209219
pure PABConfig {..}
210220

211221
docPABConfig :: String

src/BotPlutusInterface/ExBudget.hs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ import BotPlutusInterface.Types (
1414
TxFile (..),
1515
)
1616
import Cardano.Api qualified as CAPI
17+
import Cardano.Api.Shelley (ProtocolParameters (protocolParamMaxTxExUnits))
18+
import Cardano.Prelude (maybeToEither)
1719
import Control.Arrow (left)
20+
import Data.Either (rights)
1821
import Data.List (sort)
1922
import Data.Map (Map)
2023
import Data.Map qualified as Map
2124
import Data.Text qualified as Text
25+
import GHC.Natural (Natural)
2226
import Ledger (ExBudget (ExBudget), ExCPU (ExCPU), ExMemory (ExMemory), MintingPolicyHash, TxOutRef)
2327
import Ledger.Tx.CardanoAPI (fromCardanoPolicyId, fromCardanoTxIn)
2428
import System.Directory.Internal.Prelude (getEnv)
@@ -43,13 +47,47 @@ estimateBudget pabConf txFile = do
4347
(getExUnits debugNodeInf)
4448
txBody
4549

46-
let txBudget = do
47-
body <- txBody
48-
budget <- budgetRes
49-
(spendingBudgets, policyBudgets) <- mkBudgetMaps budget body
50-
Right $ TxBudget spendingBudgets policyBudgets
50+
return $
51+
do
52+
body <- txBody
53+
budget <- budgetRes
54+
maxUnits <- maybeToEither (BudgetEstimationError "Missing max units in parameters") $ protocolParamMaxTxExUnits pabConf.pcProtocolParams
55+
56+
scaledBudget <- getScaledBudget maxUnits pabConf.pcBudgetMultiplier budget
57+
58+
(spendingBudgets, policyBudgets) <- mkBudgetMaps scaledBudget body
59+
60+
Right $ TxBudget spendingBudgets policyBudgets
61+
62+
-- | Scale the budget clamping the total to the parameter limits
63+
getScaledBudget :: CAPI.ExecutionUnits -> Rational -> ExUnitsMap -> Either BudgetEstimationError ExUnitsMap
64+
getScaledBudget maxUnits scaler budget =
65+
if fst scalers >= 1 && snd scalers >= 1
66+
then Right $ fmap (fmap $ scaleBudget scalers) budget
67+
else
68+
Left $
69+
BudgetEstimationError $
70+
Text.pack $
71+
"Exceeded global transaction budget\nCalculated: " ++ show budgetSum ++ "\nLimit: " ++ show maxUnits
72+
where
73+
budgetSum = foldr addBudgets (CAPI.ExecutionUnits 0 0) $ rights $ Map.elems budget
74+
scalers =
75+
( clampedScaler (CAPI.executionSteps budgetSum) (CAPI.executionSteps maxUnits) scaler
76+
, clampedScaler (CAPI.executionMemory budgetSum) (CAPI.executionMemory maxUnits) scaler
77+
)
78+
79+
clampedScaler :: Natural -> Natural -> Rational -> Rational
80+
clampedScaler 0 _ scaler = scaler
81+
clampedScaler val maxVal scaler = min scaler (toRational maxVal / toRational val)
82+
83+
-- | Scale the budget by the multipliers in config
84+
scaleBudget :: (Rational, Rational) -> CAPI.ExecutionUnits -> CAPI.ExecutionUnits
85+
scaleBudget (stepsScaler, memScaler) (CAPI.ExecutionUnits steps mem) = CAPI.ExecutionUnits (scale steps stepsScaler) (scale mem memScaler)
86+
where
87+
scale x scaler = round $ toRational x * scaler
5188

52-
return txBudget
89+
addBudgets :: CAPI.ExecutionUnits -> CAPI.ExecutionUnits -> CAPI.ExecutionUnits
90+
addBudgets (CAPI.ExecutionUnits steps mem) (CAPI.ExecutionUnits steps' mem') = CAPI.ExecutionUnits (steps + steps') (mem + mem')
5391

5492
-- | Deserialize transaction body from ".signed" file
5593
deserialiseSigned :: FilePath -> IO (Either BudgetEstimationError (CAPI.Tx CAPI.AlonzoEra))

src/BotPlutusInterface/QueryNode.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
-- | Several query functions to query local node
44
module BotPlutusInterface.QueryNode (
55
NodeInfo (..),
6+
NodeQueryError (..),
67
queryProtocolParams,
78
querySystemStart,
89
queryEraHistory,

src/BotPlutusInterface/Types.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ data PABConfig = PABConfig
8383
, pcPort :: !Port
8484
, pcEnableTxEndpoint :: !Bool
8585
, pcCollectStats :: !Bool
86+
, pcBudgetMultiplier :: !Rational
8687
}
8788
deriving stock (Show, Eq)
8889

@@ -221,6 +222,7 @@ instance Default PABConfig where
221222
, pcPort = 9080
222223
, pcEnableTxEndpoint = False
223224
, pcCollectStats = False
225+
, pcBudgetMultiplier = 1
224226
}
225227

226228
data RawTx = RawTx

test/Spec/BotPlutusInterface/Config.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,5 @@ pabConfigExample =
113113
, pcPort = 1021
114114
, pcEnableTxEndpoint = True
115115
, pcCollectStats = False
116+
, pcBudgetMultiplier = 1
116117
}

0 commit comments

Comments
 (0)