Skip to content

Commit

Permalink
Merge branch 'KtorZ/plutus-cbor-part-2'
Browse files Browse the repository at this point in the history
  • Loading branch information
KtorZ committed Jan 7, 2022
2 parents c109558 + 132890c commit 23719b1
Show file tree
Hide file tree
Showing 17 changed files with 1,235 additions and 136 deletions.
5 changes: 5 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ packages:
hydra-tui
merkle-patricia-tree
plutus-cbor
plutus-merkle-tree

tests: False
package local-cluster
Expand All @@ -30,6 +31,10 @@ package merkle-patricia-tree
package plutus-cbor
tests: True

package plutus-merkle-tree
tests: True


-- Always show detailed output for tests
test-show-details: direct

Expand Down
16 changes: 16 additions & 0 deletions hydra-test-utils/hydra-test-utils.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,21 @@ library
exposed-modules:
Test.Hydra.Prelude
Test.Network.Ports
Test.Plutus.Validator

build-depends:
, array
, base
, bytestring
, cardano-binary
, cardano-ledger-alonzo
, cardano-ledger-alonzo-test
, cardano-ledger-core
, cardano-ledger-shelley
, cardano-ledger-shelley-ma
, cardano-slotting
, containers
, data-default
, directory
, hspec
, hspec-core
Expand All @@ -29,10 +41,14 @@ library
, hydra-prelude
, io-classes
, network
, plutus-ledger
, plutus-tx
, process
, QuickCheck
, random-shuffle
, relude
, serialise
, strict-containers
, temporary
, warp

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}

-- | A helper module mostly wrapping the Alonzo.Tools'
-- 'evaluateTransactionExecutionUnits' with a much simpler API (just a plutus
Expand All @@ -7,8 +10,9 @@
-- This is generally handy to measure the execution of Plutus code outside of any
-- context (e.g. an implementation of a data-structure on-chain or, as here,
-- data encoders).
module Test.Plutus.Codec.CBOR.Encoding.Utils (
evaluateScriptExecutionUnits,
module Test.Plutus.Validator (
module Test.Plutus.Validator,
ExUnits (..),
) where

import Hydra.Prelude hiding (label)
Expand All @@ -19,18 +23,31 @@ import Cardano.Ledger.Alonzo (AlonzoEra)
import Cardano.Ledger.Alonzo.Data (Data (..), hashData)
import Cardano.Ledger.Alonzo.Language (Language (PlutusV1))
import Cardano.Ledger.Alonzo.PParams (PParams' (..))
import Cardano.Ledger.Alonzo.Scripts (ExUnits (..), Script (..), Tag (..))
import Cardano.Ledger.Alonzo.Scripts (
ExUnits (..),
Script (..),
Tag (..),
)
import Cardano.Ledger.Alonzo.Tools (evaluateTransactionExecutionUnits)
import Cardano.Ledger.Alonzo.Tx (IsValid (..), ValidatedTx (..))
import Cardano.Ledger.Alonzo.TxBody (TxBody (..), TxOut (..))
import Cardano.Ledger.Alonzo.Tx (
IsValid (..),
ValidatedTx (..),
)
import Cardano.Ledger.Alonzo.TxBody (
TxBody (..),
TxOut (..),
)
import Cardano.Ledger.Alonzo.TxWitness (
RdmrPtr (..),
Redeemers (..),
TxDats (..),
TxWitness (..),
)
import Cardano.Ledger.BaseTypes (Network (..))
import Cardano.Ledger.Credential (Credential (..), StakeReference (..))
import Cardano.Ledger.Credential (
Credential (..),
StakeReference (..),
)
import Cardano.Ledger.Crypto (StandardCrypto)
import Cardano.Ledger.Era (ValidateScript (hashScript))
import Cardano.Ledger.Hashes (ScriptHash (..))
Expand All @@ -40,7 +57,10 @@ import Cardano.Ledger.ShelleyMA.Timelocks (ValidityInterval (..))
import Cardano.Ledger.TxIn (TxIn (..))
import Cardano.Slotting.EpochInfo (fixedEpochInfo)
import Cardano.Slotting.Slot (EpochSize (EpochSize))
import Cardano.Slotting.Time (SystemStart (SystemStart), mkSlotLength)
import Cardano.Slotting.Time (
SystemStart (SystemStart),
mkSlotLength,
)
import Codec.Serialise (serialise)
import Data.Array (array)
import qualified Data.ByteString as BS
Expand All @@ -54,6 +74,24 @@ import qualified PlutusTx as Plutus
import Test.Cardano.Ledger.Alonzo.PlutusScripts (defaultCostModel)
import qualified Prelude

--
-- Compare scripts to baselines
--

-- | Current (2022-04-01) mainchain parameters.
defaultMaxExecutionUnits :: ExUnits
defaultMaxExecutionUnits =
ExUnits
{ exUnitsMem = 10_000_000
, exUnitsSteps = 10_000_000_000
}

distanceExUnits :: ExUnits -> ExUnits -> ExUnits
distanceExUnits (ExUnits m0 s0) (ExUnits m1 s1) =
ExUnits
(if m0 > m1 then m0 - m1 else m1 - m0)
(if s0 > s1 then s0 - s1 else s1 - s0)

evaluateScriptExecutionUnits ::
Plutus.ToData a =>
Scripts.TypedValidator v ->
Expand Down
18 changes: 2 additions & 16 deletions plutus-cbor/plutus-cbor.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ common project-config
ViewPatterns

ghc-options:
-Wall -Wcompat -Widentities -Wincomplete-record-updates
-Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints
-fprint-potential-instances
-Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
-fno-ignore-interface-pragmas -fno-omit-interface-pragmas -fno-strictness -fprint-potential-instances

if !flag(hydra-development)
ghc-options: -Werror
Expand All @@ -88,38 +87,25 @@ test-suite unit
ghc-options: -threaded -rtsopts
build-tool-depends: hspec-discover:hspec-discover -any
build-depends:
, array
, base
, base16
, binary
, bytestring
, cardano-binary
, cardano-ledger-shelley
, cardano-ledger-shelley-ma
, cardano-ledger-alonzo
, cardano-ledger-alonzo-test
, cardano-ledger-core
, cardano-slotting
, cborg
, containers
, data-default
, hspec
, hydra-prelude
, hydra-test-utils
, memory
, plutus-cbor
, plutus-core
, plutus-ledger
, plutus-ledger-api
, plutus-tx
, plutus-tx-plugin
, scientific
, serialise
, strict-containers
, QuickCheck
other-modules:
Plutus.Codec.CBOR.EncodingSpec
Test.Plutus.Codec.CBOR.Encoding.Utils
Test.Plutus.Codec.CBOR.Encoding.Validators
Spec
main-is: Main.hs
113 changes: 86 additions & 27 deletions plutus-cbor/src/Plutus/Codec/CBOR/Encoding.hs
Original file line number Diff line number Diff line change
@@ -1,74 +1,133 @@
{-# OPTIONS_GHC -fno-specialize #-}

module Plutus.Codec.CBOR.Encoding (
Encoding,
encodingToBuiltinByteString,
encodeInteger,
encodeByteString,
encodeNull,
encodeListLen,
encodeList,
encodeMapLen,
encodeMap,
encodeMaybe,
) where

import PlutusTx.Prelude

import PlutusTx.AssocMap (Map)
import qualified PlutusTx.AssocMap as Map
import PlutusTx.Builtins (subtractInteger)

-- * Encoding

type Encoding = BuiltinByteString
newtype Encoding = Encoding (BuiltinByteString -> BuiltinByteString)

instance Semigroup Encoding where
(Encoding a) <> (Encoding b) = Encoding (a . b)

instance Monoid Encoding where
mempty = Encoding id

encodingToBuiltinByteString :: Encoding -> BuiltinByteString
encodingToBuiltinByteString = id
encodingToBuiltinByteString (Encoding runEncoder) =
runEncoder emptyByteString
{-# INLINEABLE encodingToBuiltinByteString #-}

-- * Basic types

encodeInteger :: Integer -> Encoding
encodeInteger n
| n < 0 =
encodeUnsigned 1 (subtractInteger 0 n - 1)
Encoding (encodeUnsigned 1 (subtractInteger 0 n - 1))
| otherwise =
encodeUnsigned 0 n
Encoding (encodeUnsigned 0 n)
{-# INLINEABLE encodeInteger #-}

encodeByteString :: BuiltinByteString -> Encoding
encodeByteString bytes =
Encoding (encodeUnsigned 2 (lengthOfByteString bytes) . appendByteString bytes)
{-# INLINEABLE encodeByteString #-}

encodeNull :: Encoding
encodeNull =
Encoding (consByteString 246)
{-# INLINEABLE encodeNull #-}

-- * Data-Structure

-- | Declare a list of fixed size. Then, provide each element of the list
-- separately via appending them ('Encoding' is a 'Semigroup').
--
-- This is useful to construct non-uniform arrays where elements may have
-- different types. For uniform list, see 'encodeList'.
encodeListLen :: Integer -> Encoding
encodeListLen = Encoding . encodeUnsigned 4
{-# INLINEABLE encodeListLen #-}

encodeList :: (a -> Encoding) -> [a] -> Encoding
encodeList encodeElem es =
encodeListLen (length es)
<> foldr (\e -> (encodeElem e <>)) mempty es
{-# INLINEABLE encodeList #-}

encodeMaybe :: (a -> Encoding) -> Maybe a -> Encoding
encodeMaybe encode = \case
Nothing -> encodeNull
Just a -> encode a
{-# INLINEABLE encodeMaybe #-}

-- | Declare a map of fixed size. Then, provide each key/value pair of the map
-- separately via appending them ('Encoding' is a 'Semigroup').
--
-- This is useful to construct non-uniform maps where keys and values may have
-- different types. For uniform maps, see 'encodeMap'.
encodeMapLen :: Integer -> Encoding
encodeMapLen = Encoding . encodeUnsigned 5
{-# INLINEABLE encodeMapLen #-}

encodeMap :: (k -> Encoding) -> (v -> Encoding) -> Map k v -> Encoding
encodeMap encodeKey encodeValue m =
encodeMapLen (length m)
<> foldr (\(k, v) -> ((encodeKey k <> encodeValue v) <>)) mempty (Map.toList m)
{-# INLINEABLE encodeMap #-}

-- * Internal

withMajorType :: Integer -> Integer -> Encoding -> Encoding
withMajorType :: Integer -> Integer -> BuiltinByteString -> BuiltinByteString
withMajorType major n =
consByteString (32 * major + n)
{-# INLINEABLE withMajorType #-}

encodeUnsigned :: Integer -> Integer -> Encoding
encodeUnsigned major n
encodeUnsigned :: Integer -> Integer -> BuiltinByteString -> BuiltinByteString
encodeUnsigned major n next
| n < 24 =
withMajorType major n emptyByteString
withMajorType major n next
| n < 256 =
withMajorType major 24 (encodeUnsigned8 n)
withMajorType major 24 (encodeUnsigned8 n next)
| n < 65536 =
withMajorType major 25 (encodeUnsigned16 n)
withMajorType major 25 (encodeUnsigned16 n next)
| n < 4294967296 =
withMajorType major 26 (encodeUnsigned32 n)
withMajorType major 26 (encodeUnsigned32 n next)
| otherwise =
withMajorType major 27 (encodeUnsigned64 n)
withMajorType major 27 (encodeUnsigned64 n next)
{-# INLINEABLE encodeUnsigned #-}

encodeUnsigned8 :: Integer -> Encoding
encodeUnsigned8 n =
consByteString n emptyByteString
encodeUnsigned8 :: Integer -> BuiltinByteString -> BuiltinByteString
encodeUnsigned8 = consByteString
{-# INLINEABLE encodeUnsigned8 #-}

encodeUnsigned16 :: Integer -> Encoding
encodeUnsigned16 :: Integer -> BuiltinByteString -> BuiltinByteString
encodeUnsigned16 n =
appendByteString
(encodeUnsigned8 (quotient n 256))
(encodeUnsigned8 (remainder n 256))
encodeUnsigned8 (quotient n 256) . encodeUnsigned8 (remainder n 256)
{-# INLINEABLE encodeUnsigned16 #-}

encodeUnsigned32 :: Integer -> Encoding
encodeUnsigned32 :: Integer -> BuiltinByteString -> BuiltinByteString
encodeUnsigned32 n =
appendByteString
(encodeUnsigned16 (quotient n 65536))
(encodeUnsigned16 (remainder n 65536))
encodeUnsigned16 (quotient n 65536) . encodeUnsigned16 (remainder n 65536)
{-# INLINEABLE encodeUnsigned32 #-}

encodeUnsigned64 :: Integer -> Encoding
encodeUnsigned64 :: Integer -> BuiltinByteString -> BuiltinByteString
encodeUnsigned64 n =
appendByteString
(encodeUnsigned32 (quotient n 4294967296))
(encodeUnsigned32 (remainder n 4294967296))
encodeUnsigned32 (quotient n 4294967296) . encodeUnsigned32 (remainder n 4294967296)
{-# INLINEABLE encodeUnsigned64 #-}

0 comments on commit 23719b1

Please sign in to comment.