Skip to content

Commit 4387df4

Browse files
committed
draft: ex-budget for plutip
- return ex budgets for each script for each transaction
1 parent 3732887 commit 4387df4

File tree

7 files changed

+87
-40
lines changed

7 files changed

+87
-40
lines changed

bot-plutus-interface.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ source-repository head
2525
common common-lang
2626
ghc-options:
2727
-Wall -Wcompat -Wincomplete-record-updates
28-
-Wincomplete-uni-patterns -Wredundant-constraints -Werror
28+
-Wincomplete-uni-patterns -Wredundant-constraints
29+
-- -Werror
2930
-fobject-code -fno-ignore-interface-pragmas
3031
-fno-omit-interface-pragmas -fplugin=RecordDotPreprocessor
3132

examples/ex-units/app/Main.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ import Prelude
2929
-}
3030
main :: IO ()
3131
main = do
32-
[sockPath, clusterDir, cliDir] <- getArgs
33-
setEnv "CARDANO_NODE_SOCKET_PATH" sockPath
32+
[clusterDir, cliDir] <- getArgs
33+
let socketPath = clusterDir ++ "/node/node.socket"
34+
setEnv "CARDANO_NODE_SOCKET_PATH" socketPath
3435
getEnv "PATH" >>= \p -> setEnv "PATH" (p ++ ":" ++ cliDir)
35-
let nodeInfo = BPI.NodeInfo Mainnet sockPath
36+
let nodeInfo = BPI.NodeInfo Mainnet socketPath
3637

3738
cEnv <- mkContractEnv nodeInfo clusterDir
38-
res <- BPI.runContract cEnv lockThenSpend
39+
res <- BPI.runContract' cEnv lockThenSpend
3940
putStrLn $ case res of
4041
Right r -> "=== OK ===\n" ++ show r
4142
Left e -> "=== FAILED ===\n" ++ show e

examples/ex-units/ex-units.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ common common-lang
2424
ghc-options:
2525
-Wall -Wcompat -Wincomplete-record-updates
2626
-Wincomplete-uni-patterns -Wredundant-constraints
27-
-Werror
27+
-- -Werror
2828
-fobject-code -fno-ignore-interface-pragmas
2929
-fno-omit-interface-pragmas -Wunused-packages
3030
-fplugin-opt PlutusTx.Plugin:defer-errors

examples/ex-units/src/LockSpend.hs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,50 @@
11
module LockSpend (lockThenSpend) where
22

3+
import Control.Monad (void)
34
import Data.Map qualified as Map
45
import Data.Text (Text)
5-
import Ledger
6-
( Address,
7-
CardanoTx,
8-
CurrencySymbol,
9-
MintingPolicy,
10-
ScriptContext (scriptContextTxInfo),
11-
TxId,
12-
Validator,
13-
getCardanoTxId,
14-
mkMintingPolicyScript,
15-
scriptAddress,
16-
scriptCurrencySymbol,
17-
unitDatum,
18-
unitRedeemer,
19-
validatorHash, TxInfo (txInfoMint), TxOutRef, ChainIndexTxOut, PaymentPubKeyHash (PaymentPubKeyHash), pubKeyHashAddress
20-
)
6+
import Ledger (
7+
Address,
8+
CardanoTx,
9+
ChainIndexTxOut,
10+
CurrencySymbol,
11+
MintingPolicy,
12+
PaymentPubKeyHash (PaymentPubKeyHash),
13+
ScriptContext (scriptContextTxInfo),
14+
TxId,
15+
TxInfo (txInfoMint),
16+
TxOutRef,
17+
Validator,
18+
getCardanoTxId,
19+
mkMintingPolicyScript,
20+
pubKeyHashAddress,
21+
scriptAddress,
22+
scriptCurrencySymbol,
23+
unitDatum,
24+
unitRedeemer,
25+
validatorHash,
26+
)
2127
import Ledger.Constraints qualified as Constraints
2228
import Ledger.Typed.Scripts (wrapMintingPolicy)
2329
import Ledger.Typed.Scripts.Validators qualified as Validators
2430
import Ledger.Value (flattenValue, tokenName)
2531
import Plutus.Contract (Contract, awaitTxConfirmed, submitTx, submitTxConstraintsWith)
2632
import Plutus.Contract qualified as Contract
2733
import Plutus.PAB.Effects.Contract.Builtin (EmptySchema)
34+
import Plutus.V1.Ledger.Ada (adaValueOf)
2835
import Plutus.V1.Ledger.Ada qualified as Value
2936
import Plutus.V1.Ledger.Value qualified as Value
3037
import PlutusTx qualified
3138
import PlutusTx.Prelude qualified as PP
3239
import Prelude
33-
import Control.Monad (void)
34-
import Plutus.V1.Ledger.Ada (adaValueOf)
3540

3641
lockThenSpend :: Contract () EmptySchema Text [(TxOutRef, ChainIndexTxOut)]
3742
lockThenSpend = do
3843
_ <- lockAtScript
3944
wait 1
4045
_ <- spendFromScript
4146
wait 1
42-
pkh <- Contract.ownPaymentPubKeyHash
47+
pkh <- Contract.ownPaymentPubKeyHash
4348
Map.toList <$> Contract.utxosAt (pubKeyHashAddress pkh Nothing)
4449
where
4550
wait = void . Contract.waitNSlots
@@ -79,10 +84,11 @@ spendFromScript = do
7984
<> Constraints.otherScript validator
8085
<> Constraints.mintingPolicy mintingPolicy
8186

82-
let txc2 = Constraints.mustSpendScriptOutput oref2 unitRedeemer
83-
<> Constraints.mustPayToPubKey
84-
(PaymentPubKeyHash "72cae61f85ed97fb0e7703d9fec382e4973bf47ea2ac9335cab1e3fe")
85-
(adaValueOf 200)
87+
let txc2 =
88+
Constraints.mustSpendScriptOutput oref2 unitRedeemer
89+
<> Constraints.mustPayToPubKey
90+
(PaymentPubKeyHash "72cae61f85ed97fb0e7703d9fec382e4973bf47ea2ac9335cab1e3fe")
91+
(adaValueOf 200)
8692
lookups2 =
8793
Constraints.unspentOutputs (Map.fromList utxos2)
8894
<> Constraints.otherScript (validator2 2)
@@ -130,7 +136,6 @@ mkValidator2 i _ _ _ =
130136
someWork = PP.sort $ PP.reverse [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] :: [Integer]
131137
check = PP.length someWork PP.== 10
132138

133-
134139
data TestLockSpend2
135140

136141
instance Validators.ValidatorTypes TestLockSpend2 where
@@ -154,7 +159,7 @@ validatorAddr2 = scriptAddress . validator2
154159
-- minting policy
155160
{-# INLINEABLE mkPolicy #-}
156161
mkPolicy :: () -> ScriptContext -> Bool
157-
mkPolicy _ !ctx =
162+
mkPolicy _ ctx =
158163
PP.traceIfFalse "Let me mint" check
159164
where
160165
info = scriptContextTxInfo ctx

src/BotPlutusInterface/Contract.hs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{-# LANGUAGE AllowAmbiguousTypes #-}
22
{-# LANGUAGE RankNTypes #-}
33

4-
module BotPlutusInterface.Contract (runContract, handleContract) where
4+
module BotPlutusInterface.Contract (runContract, runContract', handleContract) where
55

66
import BotPlutusInterface.Balance qualified as PreBalance
77
import BotPlutusInterface.BodyBuilder qualified as BodyBuilder
@@ -17,11 +17,11 @@ import BotPlutusInterface.Effects (
1717
queryChainIndex,
1818
readFileTextEnvelope,
1919
threadDelay,
20-
uploadDir,
20+
uploadDir, estimateBudget, saveBudget
2121
)
2222
import BotPlutusInterface.Files (DummyPrivKey (FromSKey, FromVKey))
2323
import BotPlutusInterface.Files qualified as Files
24-
import BotPlutusInterface.Types (ContractEnvironment (..), LogLevel (Debug, Warn), Tip (block, slot))
24+
import BotPlutusInterface.Types (ContractEnvironment (..), LogLevel (Debug, Warn), Tip (block, slot), Budgets, TxFile (Signed), TxBudget)
2525
import Cardano.Api (AsType (..), EraInMode (..), Tx (Tx))
2626
import Control.Lens (preview, (^.))
2727
import Control.Monad (join, void, when)
@@ -64,15 +64,29 @@ import Plutus.Contract.Types (Contract (..), ContractEffs)
6464
import PlutusTx.Builtins (fromBuiltin)
6565
import Wallet.Emulator.Error (WalletAPIError (..))
6666
import Prelude
67+
import Control.Concurrent.STM (newTVarIO, TVar, readTVarIO)
68+
import Data.Map (Map)
6769

6870
runContract ::
6971
forall (w :: Type) (s :: Row Type) (e :: Type) (a :: Type).
7072
(ToJSON w, Monoid w) =>
7173
ContractEnvironment w ->
7274
Contract w s e a ->
7375
IO (Either e a)
74-
runContract contractEnv (Contract effs) = do
75-
runM $ handlePABEffect @w contractEnv $ raiseEnd $ handleContract contractEnv effs
76+
runContract contractEnv contract =
77+
fmap fst <$> runContract' contractEnv contract
78+
79+
runContract' ::
80+
forall (w :: Type) (s :: Row Type) (e :: Type) (a :: Type).
81+
(ToJSON w, Monoid w) =>
82+
ContractEnvironment w ->
83+
Contract w s e a ->
84+
IO (Either e (a, Map Text TxBudget))
85+
runContract' contractEnv (Contract effs) = do
86+
emptyBudgets :: Budgets <- newTVarIO mempty
87+
res <- runM $ handlePABEffect @w contractEnv emptyBudgets $ raiseEnd $ handleContract contractEnv effs
88+
budgets <- readTVarIO emptyBudgets
89+
return $ (,budgets) <$> res
7690

7791
handleContract ::
7892
forall (w :: Type) (e :: Type) (a :: Type).
@@ -272,6 +286,12 @@ writeBalancedTx contractEnv (Right tx) = do
272286
-- We need to replace the outfile we created at the previous step, as it currently still has the old (incorrect) id
273287
mvFiles (Files.txFilePath pabConf "raw" (Tx.txId tx)) (Files.txFilePath pabConf "raw" (Ledger.getCardanoTxId $ Left cardanoTx))
274288
when signable $ mvFiles (Files.txFilePath pabConf "signed" (Tx.txId tx)) (Files.txFilePath pabConf "signed" (Ledger.getCardanoTxId $ Left cardanoTx))
289+
290+
let txId = Ledger.getCardanoTxId $ Left cardanoTx
291+
path = Text.unpack $ Files.txFilePath pabConf "signed" txId
292+
b <- firstEitherT (Text.pack . show) $ newEitherT $ estimateBudget @w (Signed path)
293+
294+
_ <- newEitherT (Right <$> saveBudget @w (Text.pack $ show txId) b)
275295

276296
pure cardanoTx
277297
where

src/BotPlutusInterface/Effects.hs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module BotPlutusInterface.Effects (
2020
writeFileTextEnvelope,
2121
callCommand,
2222
estimateBudget,
23-
) where
23+
saveBudget) where
2424

2525
import BotPlutusInterface.ChainIndex (handleChainIndexReq)
2626
import BotPlutusInterface.Estimate qualified as Estimate
@@ -31,7 +31,7 @@ import BotPlutusInterface.Types (
3131
ContractState (ContractState),
3232
LogLevel (..),
3333
TxBudget,
34-
TxFile,
34+
TxFile, Budgets
3535
)
3636
import Cardano.Api (AsType, FileError, HasTextEnvelope, TextEnvelopeDescr, TextEnvelopeError)
3737
import Cardano.Api qualified
@@ -53,6 +53,7 @@ import System.Directory qualified as Directory
5353
import System.Exit (ExitCode (ExitFailure, ExitSuccess))
5454
import System.Process (readProcess, readProcessWithExitCode)
5555
import Prelude hiding (readFile)
56+
import Data.Map qualified as Map
5657

5758
data ShellArgs a = ShellArgs
5859
{ cmdName :: Text
@@ -88,14 +89,16 @@ data PABEffect (w :: Type) (r :: Type) where
8889
UploadDir :: Text -> PABEffect w ()
8990
QueryChainIndex :: ChainIndexQuery -> PABEffect w ChainIndexResponse
9091
EstimateBudget :: TxFile -> PABEffect w (Either BudgetEstimationError TxBudget)
92+
SaveBudget :: Text -> TxBudget -> PABEffect w ()
9193

9294
handlePABEffect ::
9395
forall (w :: Type) (effs :: [Type -> Type]).
9496
LastMember IO effs =>
9597
(Monoid w) =>
9698
ContractEnvironment w ->
99+
Budgets ->
97100
Eff (PABEffect w ': effs) ~> Eff effs
98-
handlePABEffect contractEnv =
101+
handlePABEffect contractEnv budgets =
99102
interpretM
100103
( \case
101104
CallCommand shellArgs ->
@@ -132,8 +135,12 @@ handlePABEffect contractEnv =
132135
handleChainIndexReq contractEnv.cePABConfig query
133136
EstimateBudget txPath ->
134137
Estimate.estimateBudget contractEnv.cePABConfig txPath
138+
SaveBudget txId exBudget -> saveBudgetImpl budgets txId exBudget
135139
)
136140

141+
saveBudgetImpl budgets txId budget =
142+
atomically $ modifyTVar budgets (Map.insert txId budget)
143+
137144
printLog' :: LogLevel -> LogLevel -> String -> IO ()
138145
printLog' logLevelSetting msgLogLvl msg =
139146
when (logLevelSetting >= msgLogLvl) $ putStrLn msg
@@ -267,3 +274,13 @@ queryChainIndex ::
267274
ChainIndexQuery ->
268275
Eff effs ChainIndexResponse
269276
queryChainIndex = send @(PABEffect w) . QueryChainIndex
277+
278+
279+
280+
saveBudget ::
281+
forall (w :: Type) (effs :: [Type -> Type]).
282+
Member (PABEffect w) effs =>
283+
Text ->
284+
TxBudget ->
285+
Eff effs ()
286+
saveBudget txId budget = send @(PABEffect w) $ SaveBudget txId budget

src/BotPlutusInterface/Types.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module BotPlutusInterface.Types (
2121
SpendBudgets,
2222
MintBudgets,
2323
emptyBudget,
24-
) where
24+
Budgets) where
2525

2626
import Cardano.Api (NetworkId (Testnet), NetworkMagic (..), ScriptExecutionError, ScriptWitnessIndex)
2727
import Cardano.Api.ProtocolParameters (ProtocolParameters)
@@ -192,3 +192,6 @@ emptyBudget = TxBudget mempty mempty
192192
type SpendBudgets = Map TxOutRef ExBudget
193193

194194
type MintBudgets = Map MintingPolicyHash ExBudget
195+
196+
197+
type Budgets = TVar (Map Text TxBudget)

0 commit comments

Comments
 (0)