Skip to content
This repository was archived by the owner on Mar 1, 2022. It is now read-only.

Commit 3ff3cb8

Browse files
authored
Add script size and budget calculation (#25)
* Move around * add ScriptSize, and remove duplicate code * run in bench
1 parent 46f33ba commit 3ff3cb8

File tree

16 files changed

+91
-446
lines changed

16 files changed

+91
-446
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Pluton is intended to:
1515
- Enrich [Plutarch](https://github.com/Plutonomicon/plutarch) to enable a more ergonomic DSL for writing smart contracts. It is a staging ground for these features to eventually be upstreamed to Plutarch.
1616
- Benchmark (script size, cpu/mem cost) functions and smart contracts written in Haskell, Plutarch and [Pluto](https://github.com/Plutonomicon/pluto), and use that as a guide for enrichment.
1717

18+
See [Project board](https://github.com/orgs/Plutonomicon/projects/2/views/1) for planned tasks.
19+
1820
## Developing
1921

2022
`nix develop` should get a dev environment with Haskell Language Server support and ghcid.

bench/Bench.hs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module Main (main) where
22

33
import Criterion.Main
44
import Criterion.Types
5+
import Example.Contract.Gift.Validator.Haskell qualified as Gift
6+
import Example.Contract.Gift.Validator.Plutarch qualified as Gift
7+
import Example.Contract.Gift.Validator.Pluto qualified as Gift
8+
import Pluton.Run qualified as Run
59

610
-- TODO: placeholder only for https://github.com/Plutonomicon/pluton/issues/9
711
--
@@ -17,7 +21,8 @@ fib m
1721
go n = go (n -1) + go (n -2)
1822

1923
main :: IO ()
20-
main =
24+
main = do
25+
exampleContractGift
2126
defaultMainWith
2227
cfg
2328
[ bgroup
@@ -36,3 +41,10 @@ main =
3641
jsonFile = Just "bench.json",
3742
csvFile = Just "bench.csv"
3843
}
44+
45+
exampleContractGift :: IO ()
46+
exampleContractGift = do
47+
putStrLn "\n== Sample contract - Gift: sizes (haskell; pluto; plutarch) == "
48+
print $ Run.validatorSize Gift.haskellValidator
49+
print $ Run.validatorSize Gift.plutoValidator
50+
print $ Run.validatorSize Gift.plutarchValidator

examples/Example/Contract/Gift/Validator/Pluto.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import PlutusCore.Assembler.Types.AST qualified as Pluto
1010
-- FIXME: This is known to trigger a HLS bug with symbol resolution
1111
-- See https://github.com/haskell/haskell-language-server/issues/1737#issuecomment-825516365
1212
plutoValidatorProg :: Pluto.Program ()
13-
plutoValidatorProg = $(PlutoFFI.load "src/Pluton/Sample/Validator/validator.pluto")
13+
plutoValidatorProg = $(PlutoFFI.load "examples/Example/Contract/Gift/Validator/validator.pluto")
1414

1515
plutoValidator :: Validator
1616
plutoValidator =

exe/Main.hs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,23 @@
22

33
module Main (main) where
44

5-
import Pluton qualified as Pluton
6-
import Example.Contract.Gift.Test qualified as SampleTest
7-
import Example.Contract.Gift.Validator.Plutarch qualified as Sample
5+
import Example.Contract.Gift.Test qualified as GiftTest
6+
import Example.Contract.Gift.Validator.Haskell qualified as Gift
7+
import Example.Contract.Gift.Validator.Plutarch qualified as Gift
8+
import Example.Contract.Gift.Validator.Pluto qualified as Gift
9+
import Pluton qualified
10+
import Pluton.Run qualified as Run
811
import Plutus.Trace.Emulator qualified as Em
912

1013
main :: IO ()
1114
main = do
1215
Pluton.smoke
13-
Em.runEmulatorTraceIO $ SampleTest.smokeTrace Sample.plutarchValidator
14-
SampleTest.tests
16+
-- Gift contract example
17+
putStrLn "\n== Sample contract - Gift: sizes (haskell; pluto; plutarch) == "
18+
print $ Run.validatorSize Gift.haskellValidator
19+
print $ Run.validatorSize Gift.plutoValidator
20+
print $ Run.validatorSize Gift.plutarchValidator
21+
putStrLn "\n== Sample contract - Gift: emulator == "
22+
Em.runEmulatorTraceIO $ GiftTest.smokeTrace Gift.plutarchValidator
23+
putStrLn "\n== Sample contract - Gift: tests == "
24+
GiftTest.tests

pluton.cabal

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ library
3535
hs-source-dirs: src
3636
exposed-modules:
3737
Pluton
38-
Pluton.Evaluate
38+
Pluton.Run
39+
Pluton.Run.Evaluate
40+
Pluton.Run.ScriptSize
3941
Pluton.Types.Builtin
4042
Pluton.Types.Builtin.Data
4143
Pluton.Types.Builtin.Fun
@@ -47,14 +49,16 @@ library
4749
build-depends:
4850
, base
4951
, bytestring
52+
, cardano-api
53+
, cardano-ledger-alonzo
5054
, containers
5155
, fin
5256
, freer-extras
5357
, hashable
5458
, hedgehog
5559
, lens
5660
, mtl
57-
, plutarch >=1.0
61+
, plutarch >=1.0
5862
, pluto
5963
, plutus-contract
6064
, plutus-core
@@ -63,6 +67,7 @@ library
6367
, plutus-tx
6468
, plutus-tx-plugin
6569
, QuickCheck
70+
, serialise
6671
, shower
6772
, tasty
6873
, tasty-hedgehog
@@ -150,5 +155,6 @@ benchmark perf
150155
, base
151156
, criterion
152157
, pluton
158+
, pluton-examples
153159
, plutus-contract
154160
, plutus-core

src/Pluton.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import Plutarch qualified
66
import Plutarch qualified as PLC
77
import Plutarch.Bool as X
88
import Plutarch.Integer as X
9-
import Pluton.Evaluate qualified as Smoke
9+
import Pluton.Run qualified as Run
10+
import Pluton.Run.Evaluate qualified as Smoke
1011
import Pluton.Types.Builtin as X
1112
import Pluton.Types.Builtin.Data ()
1213
import Pluton.Types.Builtin.List qualified as BL
@@ -32,7 +33,9 @@ fibs = phoistAcyclic $
3233
smoke :: IO ()
3334
smoke = do
3435
let eval :: ClosedTerm a -> IO ()
35-
eval p = print $ Smoke.evalPlutarch p
36+
eval p = do
37+
print $ Smoke.evalPlutarch p
38+
print $ Run.scriptSize $ Run.compile p
3639
fourtyTwo = 42 :: Term s PInteger
3740
intNil =
3841
Plutarch.punsafeConstant $

src/Pluton/Run.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Pluton.Run (module X) where
2+
3+
import Pluton.Run.Evaluate as X
4+
import Pluton.Run.ScriptSize as X

src/Pluton/Evaluate.hs renamed to src/Pluton/Run/Evaluate.hs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
module Pluton.Evaluate
2-
( -- * General evaluation of UPLC
3-
eval,
4-
evalWithArgs,
5-
6-
-- * Evaluation of Plutarch eDSL
1+
module Pluton.Run.Evaluate
2+
( -- * Evaluation of Plutarch eDSL
73
evalPlutarch,
4+
Plutarch.compile,
85
)
96
where
107

@@ -41,8 +38,8 @@ evalPlutarch p =
4138
eval :: Script -> Either Error (ExBudget, [Text], Term Name DefaultUni DefaultFun ())
4239
eval = evaluateScript @(Either Error)
4340

44-
evalWithArgs :: [PLC.Data] -> Script -> Either Error (ExBudget, [Text], Term Name DefaultUni DefaultFun ())
45-
evalWithArgs args =
41+
_evalWithArgs :: [PLC.Data] -> Script -> Either Error (ExBudget, [Text], Term Name DefaultUni DefaultFun ())
42+
_evalWithArgs args =
4643
evaluateScript @(Either Error)
4744
. flip Scripts.applyArguments args
4845

src/Pluton/Run/ScriptSize.hs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module Pluton.Run.ScriptSize
2+
( scriptSize,
3+
validatorSize,
4+
)
5+
where
6+
7+
import Codec.Serialise (serialise)
8+
import Control.Arrow ((&&&))
9+
import Data.ByteString.Lazy qualified as LB
10+
import Data.ByteString.Short qualified as SBS
11+
import Data.Maybe (fromJust)
12+
import GHC.Stack (HasCallStack)
13+
import Ledger.Scripts (Script, Validator)
14+
import Plutus.V1.Ledger.Api qualified as Plutus
15+
16+
-- (ExBudget {exBudgetCPU = ExCPU 327603, exBudgetMemory = ExMemory 1200},336)
17+
18+
-- | Return the script size in bytes along with execution budget.
19+
validatorSize :: Validator -> (Plutus.ExBudget, Int)
20+
validatorSize = (evalScriptCounting &&& SBS.length) . serialiseValidator
21+
22+
scriptSize :: Script -> (Plutus.ExBudget, Int)
23+
scriptSize = (evalScriptCounting &&& SBS.length) . serialiseScript
24+
25+
serialiseScript :: Script -> SBS.ShortByteString
26+
serialiseScript = SBS.toShort . LB.toStrict . serialise
27+
28+
serialiseValidator :: Validator -> SBS.ShortByteString
29+
serialiseValidator = SBS.toShort . LB.toStrict . serialise
30+
31+
evalScriptCounting :: HasCallStack => Plutus.SerializedScript -> Plutus.ExBudget
32+
evalScriptCounting script = do
33+
let costModel = fromJust Plutus.defaultCostModelParams
34+
(_logout, e) = Plutus.evaluateScriptCounting Plutus.Verbose costModel script []
35+
in case e of
36+
Left evalErr -> error ("Eval Error: " <> show evalErr)
37+
Right exbudget -> exbudget

src/Pluton/Sample/Offchain.hs

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)