Skip to content

Commit

Permalink
SCP-2417: Add builtin function: serialiseData
Browse files Browse the repository at this point in the history
  • Loading branch information
bezirg committed Mar 16, 2022
1 parent 6fff790 commit 98215e8
Show file tree
Hide file tree
Showing 27 changed files with 147 additions and 5 deletions.
8 changes: 6 additions & 2 deletions doc/reference/builtin-parameters.csv
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ decodeUtf8,decodeUtf8-memory-arguments-slope,Linear model coefficient for the me
divideInteger,divideInteger-cpu-arguments-constant,Constant CPU cost (argument sizes above diagonal)
divideInteger,divideInteger-cpu-arguments-model-arguments-intercept,Linear model intercept for the CPU calculation (argument sizes on or below diagonal)
divideInteger,divideInteger-cpu-arguments-model-arguments-slope,Linear model coefficient for the CPU calculation (argument sizes on or below diagonal)
divideInteger,divideInteger-memory-arguments-intercept,Linear model intercept for the memory calculation (argument sizes on or below diagonal)
divideInteger,divideInteger-memory-arguments-intercept,Linear model intercept for the memory calculation (argument sizes on or below diagonal)
divideInteger,divideInteger-memory-arguments-minimum,Constant memory cost (argument sizes above diagonal)
divideInteger,divideInteger-memory-arguments-slope,Linear model coefficient for the memory calculation (argument sizes on or below diagonal)
encodeUtf8,encodeUtf8-cpu-arguments-intercept,Linear model intercept for the CPU calculation below diagonal
Expand Down Expand Up @@ -98,7 +98,7 @@ modInteger,modInteger-cpu-arguments-model-arguments-slope,Linear model coefficie
modInteger,modInteger-memory-arguments-intercept,Linear model intercept for the memory calculation
modInteger,modInteger-memory-arguments-minimum,Constant memory cost (argument sizes above diagonal)
modInteger,modInteger-memory-arguments-slope,Linear model coefficient for the memory calculation (argument sizes on or below diagonal)
multiplyInteger,multiplyInteger-cpu-arguments-intercept,Linear model intercept for the CPU calculation
multiplyInteger,multiplyInteger-cpu-arguments-intercept,Linear model intercept for the CPU calculation
multiplyInteger,multiplyInteger-cpu-arguments-slope,Linear model coefficient for the CPU calculation
multiplyInteger,multiplyInteger-memory-arguments-intercept,Linear model intercept for the memory calculation
multiplyInteger,multiplyInteger-memory-arguments-slope,Linear model coefficient for the memory calculation
Expand All @@ -116,6 +116,10 @@ remainderInteger,remainderInteger-cpu-arguments-model-arguments-slope,Linear mod
remainderInteger,remainderInteger-memory-arguments-intercept,Linear model intercept for the memory calculation (argument sizes on or below diagonal)
remainderInteger,remainderInteger-memory-arguments-minimum,Constant memory cost (argument sizes above diagonal)
remainderInteger,remainderInteger-memory-arguments-slope,Linear model coefficient for the memory calculation (argument sizes on or below diagonal)
serialiseData,serialiseData-cpu-arguments-intercept,TODO
serialiseData,serialiseData-cpu-arguments-slope,TODO
serialiseData,serialiseData-memory-arguments-intercept,TODO
serialiseData,serialiseData-memory-arguments-slope,TODO
sha2_256,sha2_256-cpu-arguments-intercept,Linear model intercept for the CPU calculation
sha2_256,sha2_256-cpu-arguments-slope,Linear model coefficient for the CPU calculation
sha2_256,sha2_256-memory-arguments,Constant memory cost
Expand Down
5 changes: 5 additions & 0 deletions plutus-core/cost-model/budgeting-bench/Benchmarks/Data.hs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ benchEqualsData =
where args1 = dataSampleForEq -- 400 elements: should take about 35 minutes to benchmark
args2 = fmap copyData args1

benchSerialiseData :: Benchmark
benchSerialiseData =
createOneTermBuiltinBench SerialiseData [] args
where args = dataSampleForEq -- FIXME: is this a good sample for serialization?

makeBenchmarks :: StdGen -> [Benchmark]
makeBenchmarks gen =
Expand All @@ -141,4 +145,5 @@ makeBenchmarks gen =
, benchUnIData
, benchUnBData
, benchEqualsData
, benchSerialiseData
]
10 changes: 10 additions & 0 deletions plutus-core/cost-model/create-cost-model/CostModelCreation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ builtinCostModelNames = BuiltinCostModelBase
, paramMkPairData = "mkPairDataModel"
, paramMkNilData = "mkNilDataModel"
, paramMkNilPairData = "mkNilPairDataModel"
, paramSerialiseData = "serialiseDataModel"
}


Expand Down Expand Up @@ -175,6 +176,7 @@ createBuiltinCostModel =
paramUnIData <- getParams unIData paramUnIData
paramUnBData <- getParams unBData paramUnBData
paramEqualsData <- getParams equalsData paramEqualsData
paramSerialiseData <- getParams serialiseData paramSerialiseData
-- Misc constructors
paramMkPairData <- getParams mkPairData paramMkPairData
paramMkNilData <- getParams mkNilData paramMkNilData
Expand Down Expand Up @@ -676,6 +678,14 @@ equalsData cpuModelR = do
worst case it may have to examine almost all of the smaller argument before
realising that the two arguments are different. -}

serialiseData :: MonadR m => (SomeSEXP (Region m)) -> m (CostingFun ModelOneArgument)
serialiseData cpuModelR = do
-- FIXME: add cpumodel for serialisedata
cpuModel <- ModelOneArgumentLinearCost <$> readModelLinearInX cpuModelR
-- FIXME: add memmodel for serialisedata
let memModel = ModelOneArgumentLinearCost $ ModelLinearSize 0 0
pure $ CostingFun cpuModel memModel

---------------- Misc constructors ----------------

mkPairData :: MonadR m => (SomeSEXP (Region m)) -> m (CostingFun ModelTwoArguments)
Expand Down
16 changes: 16 additions & 0 deletions plutus-core/cost-model/data/builtinCostModel.json
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,22 @@
"type": "constant_cost"
}
},
"serialiseData": {
"memory": {
"arguments": {
"slope": 0,
"intercept": 0
},
"type": "linear_cost"
},
"cpu": {
"arguments": {
"slope": 0,
"intercept": 0
},
"type": "linear_cost"
}
},
"addInteger": {
"memory": {
"arguments": {
Expand Down
10 changes: 9 additions & 1 deletion plutus-core/cost-model/data/models.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ arity <- function(name) {
"AppendString" = 2,
"EqualsString" = 2,
"EncodeUtf8" = 1,
"SerialiseData" = 1,
"DecodeUtf8" = 1,
"IfThenElse" = 3,
"ChooseUnit" = 2,
Expand Down Expand Up @@ -550,6 +551,12 @@ modelFun <- function(path) {
adjustModel(m2,fname)
}

serialiseDataModel <- {
fname <- "SerialiseData"
#FIXME
}


mkPairDataModel <- constantModel ("MkPairData")
mkNilDataModel <- constantModel ("MkNilData")
mkNilPairDataModel <- constantModel ("MkNilPairData")
Expand Down Expand Up @@ -605,6 +612,7 @@ modelFun <- function(path) {
equalsDataModel = equalsDataModel,
mkPairDataModel = mkPairDataModel,
mkNilDataModel = mkNilDataModel,
mkNilPairDataModel = mkNilPairDataModel
mkNilPairDataModel = mkNilPairDataModel,
serialiseDataModel = serialiseDataModel
)
}
1 change: 1 addition & 0 deletions plutus-core/cost-model/test/TestCostModels.hs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ main =
, $(genTest 1 "unIData")
, $(genTest 1 "unBData")
, $(genTest 2 "equalsData") Everywhere
, $(genTest 1 "serialiseData")

-- Misc constructors
, $(genTest 2 "mkPairData") Everywhere
Expand Down
9 changes: 9 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import PlutusCore.Evaluation.Machine.ExMemory
import PlutusCore.Evaluation.Result
import PlutusCore.Pretty

import Codec.Serialise (serialise)
import Crypto (verifySignature)
import Data.ByteString qualified as BS
import Data.ByteString.Hash qualified as Hash
import Data.ByteString.Lazy qualified as BS (toStrict)
import Data.Char
import Data.Ix
import Data.Text (Text)
Expand Down Expand Up @@ -102,6 +104,7 @@ data DefaultFun
| UnIData
| UnBData
| EqualsData
| SerialiseData
-- Misc constructors
-- Constructors that we need for constructing e.g. Data. Polymorphic builtin
-- constructors are often problematic (See note [Representable built-in
Expand Down Expand Up @@ -972,6 +975,10 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
makeBuiltinMeaning
((==) @Data)
(runCostingFunTwoArguments . paramEqualsData)
toBuiltinMeaning SerialiseData =
makeBuiltinMeaning
(BS.toStrict . serialise @Data)
(runCostingFunOneArgument . paramSerialiseData)
-- Misc constructors
toBuiltinMeaning MkPairData =
makeBuiltinMeaning
Expand Down Expand Up @@ -1065,6 +1072,7 @@ instance Flat DefaultFun where
MkPairData -> 48
MkNilData -> 49
MkNilPairData -> 50
SerialiseData -> 51

decode = go =<< decodeBuiltin
where go 0 = pure AddInteger
Expand Down Expand Up @@ -1118,6 +1126,7 @@ instance Flat DefaultFun where
go 48 = pure MkPairData
go 49 = pure MkNilData
go 50 = pure MkNilPairData
go 51 = pure SerialiseData
go t = fail $ "Failed to decode builtin tag, got: " ++ show t

size _ n = n + builtinTagWidth
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ data BuiltinCostModelBase f =
, paramMkPairData :: f ModelTwoArguments
, paramMkNilData :: f ModelOneArgument
, paramMkNilPairData :: f ModelOneArgument
, paramSerialiseData :: f ModelOneArgument
}
deriving stock (Generic)
deriving anyclass (FunctorB, TraversableB, ConstraintsB)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,5 @@ unitCostBuiltinCostModel = BuiltinCostModelBase
, paramMkPairData = unitCostTwoArguments
, paramMkNilData = unitCostOneArgument
, paramMkNilPairData = unitCostOneArgument
, paramSerialiseData = unitCostOneArgument
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ builtinFnList =
, (UnIData,"unIData")
, (UnBData,"unBData")
, (EqualsData,"equalsData")
, (SerialiseData,"serialiseData")
, (MkPairData,"mkPairData")
, (MkNilData,"mkNilData")
, (MkNilPairData,"mkNilPairData")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
"remainderInteger-memory-arguments-intercept": 0,
"remainderInteger-memory-arguments-minimum": 1,
"remainderInteger-memory-arguments-slope": 1,
"serialiseData-cpu-arguments-intercept": 0,
"serialiseData-cpu-arguments-slope": 0,
"serialiseData-memory-arguments-intercept": 0,
"serialiseData-memory-arguments-slope": 0,
"sha2_256-cpu-arguments-intercept": 2477736,
"sha2_256-cpu-arguments-slope": 29175,
"sha2_256-memory-arguments": 4,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(fun (con data) (con bytestring))
2 changes: 1 addition & 1 deletion plutus-core/testlib/PlutusCore/Generators/NEAT/Term.hs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ defaultFunTypes = Map.fromList [(TyFunG (TyBuiltinG TyIntegerG) (TyFunG (TyBuilt
,(TyFunG (TyBuiltinG TyDataG) (TyBuiltinG TyIntegerG)
,[UnIData])
,(TyFunG (TyBuiltinG TyDataG) (TyBuiltinG TyByteStringG)
,[UnBData])
,[UnBData, SerialiseData])
]

instance Ord tyname => Check (TypeG tyname) DefaultFun where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ test_Data = testCase "Data" $ do
evals @[(Data, Data)] [(B "", I 3)] UnMapData [cons $ Map [(B "", I 3)]]
evals @[Data] [] UnListData [cons $ List []]
evals @[Data] [I 3, I 4, B ""] UnListData [cons $ List [I 3, I 4, B ""]]
evals @ByteString "\162\ETX@Ehello8c" SerialiseData [cons $ Map [(I 3, B ""), (B "hello", I $ -100)]]

-- ChooseData
let actualExp = mkIterApp ()
Expand Down Expand Up @@ -539,7 +540,6 @@ test_Crypto = testCase "Crypto" $ do
evals @ByteString "%l\131\178\151\DC1M \ESC0\ETB\159?\SO\240\202\206\151\131b-\165\151C&\180\&6\ETB\138\238\246\DLE"
Blake2b_256 [cons @ByteString "hello world"]


-- Test all remaining builtins of the default universe
test_Other :: TestTree
test_Other = testCase "Other" $ do
Expand Down
3 changes: 3 additions & 0 deletions plutus-ledger-api/src/Plutus/ApiCommon.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ builtinsIntroducedIn = Map.fromList [
ChooseList, MkCons, HeadList, TailList, NullList,
ChooseData, ConstrData, MapData, ListData, IData, BData, UnConstrData, UnMapData, UnListData, UnIData, UnBData, EqualsData,
MkPairData, MkNilData, MkNilPairData
]),
(ProtocolVersion 6 0, Set.fromList [
SerialiseData
])
]

Expand Down
19 changes: 19 additions & 0 deletions plutus-ledger-api/test/Spec/Builtins.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
module Spec.Builtins where

import Plutus.V1.Ledger.Api
import Plutus.V1.Ledger.Scripts as Scripts
import PlutusCore as PLC
import PlutusCore.MkPlc as PLC
import UntypedPlutusCore as UPLC

import Codec.Serialise
import Data.ByteString.Lazy as BSL
import Data.ByteString.Short
import Data.Foldable (fold, for_)
import Data.Map qualified as Map
import Data.Set qualified as Set
import Plutus.ApiCommon
import Test.Tasty
import Test.Tasty.HUnit

serialiseDataExScript :: SerializedScript
serialiseDataExScript = toShort . toStrict $ serialise serialiseDataEx
where
serialiseDataEx :: Script
serialiseDataEx = Scripts.Script $ UPLC.Program () (PLC.defaultVersion ()) $
UPLC.Apply () (UPLC.Builtin () PLC.SerialiseData) (PLC.mkConstant () $ I 1)

tests :: TestTree
tests =
testGroup
Expand All @@ -16,4 +32,7 @@ tests =
allBuiltins = [(toEnum 0)..]
in for_ allBuiltins $ \f -> assertBool (show f) (f `Set.member` allPvBuiltins)
, testCase "builtins aren't available before v5" $ assertBool "empty" (Set.null $ builtinsAvailableIn (ProtocolVersion 4 0))
, testCase "serializeData is only available in v6" $ do
assertBool "in v5 " $ not $ isScriptWellFormed (ProtocolVersion 5 0) serialiseDataExScript
assertBool "not in v6" $ isScriptWellFormed (ProtocolVersion 6 0) serialiseDataExScript
]
1 change: 1 addition & 0 deletions plutus-metatheory/src/Algorithmic.lagda
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ sig unListData = _ ,, ∅ , con Data ,, con (list (con Data))
sig unIData = _ ,, ∅ , con Data ,, con integer
sig unBData = _ ,, ∅ , con Data ,, con bytestring
sig equalsData = _ ,, ∅ , con Data , con Data ,, con bool
sig serialiseData = _ ,, ∅ , con Data ,, con bytestring
sig chooseData =
_
,,
Expand Down
9 changes: 9 additions & 0 deletions plutus-metatheory/src/Algorithmic/CEKV.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ BUILTIN equalsString (app _ (app _ base (V-con (string s))) (V-con (string s')))
BUILTIN unIData (app _ base (V-con (Data (iDATA i)))) = inj₂ (V-con (integer i))
BUILTIN unBData (app _ base (V-con (Data (bDATA b)))) =
inj₂ (V-con (bytestring b))
BUILTIN serialiseData (app _ base (V-con (Data d))) =
inj₂ (V-con (bytestring (serialiseDATA d)))
BUILTIN _ {A} _ = inj₁ A
convBApp : (b : Builtin) → ∀{az}{as}(p p' : az <>> as ∈ arity b)
Expand Down Expand Up @@ -460,6 +462,9 @@ bappTermLem equalsData {as = as} (bubble {as = az} p) q
with <>>-cancel-both' az _ (([] :< Term) :< Term) as p refl
bappTermLem equalsData (bubble (start _)) (app _ base _)
| refl ,, refl ,, refl = _ ,, _ ,, refl
bappTermLem serialiseData {az = az} {as} p q
with <>>-cancel-both az ([] :< Term) as p
bappTermLem serialiseData (start _) base | refl ,, refl = _ ,, _ ,, refl
bappTermLem chooseData (bubble (start _)) (app⋆ _ base refl) =
_ ,, _ ,, refl
bappTermLem chooseData
Expand Down Expand Up @@ -713,6 +718,9 @@ bappTypeLem unBData {az = az} p q
bappTypeLem equalsData (bubble {as = az} p) _
with <>>-cancel-both' az _ (([] :< Term) :< Term) _ p refl
... | refl ,, refl ,, ()
bappTypeLem serialiseData {az = az} p q
with <>>-cancel-both' az _ ([] :< Term) _ p refl
... | refl ,, refl ,, ()
bappTypeLem chooseData (start _) base = _ ,, _ ,, refl
bappTypeLem chooseData (bubble (bubble (bubble (bubble (bubble (bubble {as = az} p)))))) _
with <>>-cancel-both' az _ ([] <>< arity chooseData) _ p refl
Expand Down Expand Up @@ -855,6 +863,7 @@ ival unListData = V-I⇒ unListData (start _) base
ival unIData = V-I⇒ unIData (start _) base
ival unBData = V-I⇒ unBData (start _) base
ival equalsData = V-I⇒ equalsData (start _) base
ival serialiseData = V-I⇒ serialiseData (start _) base
ival chooseData = V-IΠ chooseData (start _) base
ival chooseUnit = V-IΠ chooseUnit (start _) base
ival mkPairData = V-I⇒ mkPairData (start _) base
Expand Down
8 changes: 8 additions & 0 deletions plutus-metatheory/src/Algorithmic/ReductionEC.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ BUILTIN decodeUtf8 (step _ (base refl) (V-con (bytestring b)))
... | just s = con (string s)
BUILTIN unIData (step _ (base refl) (V-con (Data (iDATA i)))) = con (integer i)
BUILTIN unBData (step _ (base refl) (V-con (Data (bDATA b)))) = con (bytestring b)
BUILTIN serialiseData (step _ (base refl) (V-con (Data d))) = con (bytestring (serialiseDATA d))
BUILTIN _ _ = error _
Expand Down Expand Up @@ -584,6 +585,9 @@ bappTermLem equalsData {as = as} _ (bubble {as = az} p) q
with <>>-cancel-both' az _ (([] :< Term) :< Term) as p refl
bappTermLem equalsData _ (bubble (start _)) (step _ (base refl) _)
| refl ,, refl ,, refl = _ ,, _ ,, refl
bappTermLem serialiseData {az = az} {as} M p q
with <>>-cancel-both az ([] :< Term) as p
bappTermLem serialiseData _ (start _) (base refl) | refl ,, refl = _ ,, _ ,, refl
bappTermLem chooseData _ (bubble (start _)) (step⋆ _ (base refl) refl) =
_ ,, _ ,, refl
bappTermLem chooseData
Expand Down Expand Up @@ -782,6 +786,9 @@ bappTypeLem unBData {az = az} _ p q
bappTypeLem equalsData _ (bubble {as = az} p) _
with <>>-cancel-both' az _ (([] :< Term) :< Term) _ p refl
... | refl ,, refl ,, ()
bappTypeLem serialiseData {az = az} _ p q
with <>>-cancel-both' az _ ([] :< Term) _ p refl
... | refl ,, refl ,, ()
bappTypeLem chooseData _ (start _) (base refl) = _ ,, _ ,, refl
bappTypeLem chooseData _ (bubble (bubble (bubble (bubble (bubble (bubble {as = az} p)))))) _
with <>>-cancel-both' az _ ([] <>< arity chooseData) _ p refl
Expand Down Expand Up @@ -913,6 +920,7 @@ ival unListData = V-I _ (start _) (base refl)
ival unIData = V-I _ (start _) (base refl)
ival unBData = V-I _ (start _) (base refl)
ival equalsData = V-I _ (start _) (base refl)
ival serialiseData = V-I _ (start _) (base refl)
ival chooseData = V-I _ (start _) (base refl)
ival chooseUnit = V-I _ (start _) (base refl)
ival mkPairData = V-I _ (start _) (base refl)
Expand Down
3 changes: 3 additions & 0 deletions plutus-metatheory/src/Builtin.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ data Builtin : Set where
unIData : Builtin
unBData : Builtin
equalsData : Builtin
serialiseData : Builtin
-- Misc constructors
mkPairData : Builtin
mkNilData : Builtin
Expand Down Expand Up @@ -127,6 +128,7 @@ data Builtin : Set where
| UnIData
| UnBData
| EqualsData
| SerialiseData
| MkPairData
| MkNilData
| MkNilPairData
Expand Down Expand Up @@ -158,6 +160,7 @@ postulate
equals : ByteString → ByteString → Bool
ENCODEUTF8 : String → ByteString
DECODEUTF8 : ByteString → Maybe String
serialiseDATA : DATA → ByteString
```

# What builtin operations should be compiled to if we compile to Haskell
Expand Down
Loading

0 comments on commit 98215e8

Please sign in to comment.