{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Cardano.Ledger.Plutus.ExUnits (
  txscriptfee,
  pointWiseExUnits,
  zipSemiExUnits,
  ExUnits (ExUnits, exUnitsMem, exUnitsSteps, ..),
  ExUnits' (..),
  Prices (..),
)
where

import Cardano.Ledger.BaseTypes (
  BoundedRational (unboundRational),
  NonNegativeInterval,
 )
import Cardano.Ledger.Binary (
  DecCBOR (decCBOR),
  Decoder,
  DecoderError (..),
  EncCBOR (encCBOR),
  cborError,
 )
import Cardano.Ledger.Binary.Coders (
  Decode (D, From, RecD),
  Encode (Rec, To),
  decode,
  encode,
  (!>),
  (<!),
 )
import Cardano.Ledger.Coin (Coin (..))
import Control.Applicative ((<|>))
import Control.DeepSeq (NFData (..))
import Control.Monad (when)
import Data.Aeson (
  FromJSON (..),
  ToJSON (..),
  object,
  withObject,
  (.:),
  (.=),
 )
import Data.DerivingVia (InstantiatedAt (..))
import Data.Int (Int64)
import Data.Measure (BoundedMeasure, Measure)
import Data.Semigroup (All (..))
import Data.Word (Word64)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks (..))
import Numeric.Natural (Natural)

-- | Arbitrary execution unit in which we measure the cost of scripts in terms
-- of space in memory and execution time.
--
-- The ledger itself uses 'ExUnits' Natural' exclusively, but the flexibility here
-- allows the consensus layer to translate the execution units into something
-- equivalent to 'ExUnits (Inf Natural)'. This is needed in order to provide
-- a 'BoundedMeasure' instance, which itself is needed for the alonzo instance of
-- 'TxLimits' (in consensus).
data ExUnits' a = ExUnits'
  { forall a. ExUnits' a -> a
exUnitsMem' :: !a
  , forall a. ExUnits' a -> a
exUnitsSteps' :: !a
  }
  deriving (ExUnits' a -> ExUnits' a -> Bool
forall a. Eq a => ExUnits' a -> ExUnits' a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExUnits' a -> ExUnits' a -> Bool
$c/= :: forall a. Eq a => ExUnits' a -> ExUnits' a -> Bool
== :: ExUnits' a -> ExUnits' a -> Bool
$c== :: forall a. Eq a => ExUnits' a -> ExUnits' a -> Bool
Eq, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (ExUnits' a) x -> ExUnits' a
forall a x. ExUnits' a -> Rep (ExUnits' a) x
$cto :: forall a x. Rep (ExUnits' a) x -> ExUnits' a
$cfrom :: forall a x. ExUnits' a -> Rep (ExUnits' a) x
Generic, Int -> ExUnits' a -> ShowS
forall a. Show a => Int -> ExUnits' a -> ShowS
forall a. Show a => [ExUnits' a] -> ShowS
forall a. Show a => ExUnits' a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExUnits' a] -> ShowS
$cshowList :: forall a. Show a => [ExUnits' a] -> ShowS
show :: ExUnits' a -> String
$cshow :: forall a. Show a => ExUnits' a -> String
showsPrec :: Int -> ExUnits' a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> ExUnits' a -> ShowS
Show, forall a b. a -> ExUnits' b -> ExUnits' a
forall a b. (a -> b) -> ExUnits' a -> ExUnits' b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> ExUnits' b -> ExUnits' a
$c<$ :: forall a b. a -> ExUnits' b -> ExUnits' a
fmap :: forall a b. (a -> b) -> ExUnits' a -> ExUnits' b
$cfmap :: forall a b. (a -> b) -> ExUnits' a -> ExUnits' b
Functor)
  -- It is deliberate that there is no Ord instance, use `pointWiseExUnits` instead.
  deriving
    (ExUnits' a
ExUnits' a -> ExUnits' a -> ExUnits' a
forall a.
Eq a
-> a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> Measure a
forall {a}. Measure a => Eq (ExUnits' a)
forall a. Measure a => ExUnits' a
forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
max :: ExUnits' a -> ExUnits' a -> ExUnits' a
$cmax :: forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
min :: ExUnits' a -> ExUnits' a -> ExUnits' a
$cmin :: forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
plus :: ExUnits' a -> ExUnits' a -> ExUnits' a
$cplus :: forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
zero :: ExUnits' a
$czero :: forall a. Measure a => ExUnits' a
Measure, ExUnits' a
forall a. Measure a -> a -> BoundedMeasure a
forall {a}. BoundedMeasure a => Measure (ExUnits' a)
forall a. BoundedMeasure a => ExUnits' a
maxBound :: ExUnits' a
$cmaxBound :: forall a. BoundedMeasure a => ExUnits' a
BoundedMeasure)
    via (InstantiatedAt Generic (ExUnits' a))
  deriving
    (ExUnits' a
[ExUnits' a] -> ExUnits' a
ExUnits' a -> ExUnits' a -> ExUnits' a
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall {a}. Measure a => Semigroup (ExUnits' a)
forall a. Measure a => ExUnits' a
forall a. Measure a => [ExUnits' a] -> ExUnits' a
forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
mconcat :: [ExUnits' a] -> ExUnits' a
$cmconcat :: forall a. Measure a => [ExUnits' a] -> ExUnits' a
mappend :: ExUnits' a -> ExUnits' a -> ExUnits' a
$cmappend :: forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
mempty :: ExUnits' a
$cmempty :: forall a. Measure a => ExUnits' a
Monoid, NonEmpty (ExUnits' a) -> ExUnits' a
ExUnits' a -> ExUnits' a -> ExUnits' a
forall b. Integral b => b -> ExUnits' a -> ExUnits' a
forall a. Measure a => NonEmpty (ExUnits' a) -> ExUnits' a
forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
forall a b.
(Measure a, Integral b) =>
b -> ExUnits' a -> ExUnits' a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> ExUnits' a -> ExUnits' a
$cstimes :: forall a b.
(Measure a, Integral b) =>
b -> ExUnits' a -> ExUnits' a
sconcat :: NonEmpty (ExUnits' a) -> ExUnits' a
$csconcat :: forall a. Measure a => NonEmpty (ExUnits' a) -> ExUnits' a
<> :: ExUnits' a -> ExUnits' a -> ExUnits' a
$c<> :: forall a. Measure a => ExUnits' a -> ExUnits' a -> ExUnits' a
Semigroup)
    via (InstantiatedAt Measure (ExUnits' a))

instance NoThunks a => NoThunks (ExUnits' a)

instance NFData a => NFData (ExUnits' a)

deriving instance ToJSON a => ToJSON (ExUnits' a)

deriving instance FromJSON a => FromJSON (ExUnits' a)

-- | This newtype wrapper of ExUnits' is used to hide
--  an implementation detail inside the ExUnits pattern.
newtype ExUnits = WrapExUnits {ExUnits -> ExUnits' Natural
unWrapExUnits :: ExUnits' Natural}
  deriving (ExUnits -> ExUnits -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExUnits -> ExUnits -> Bool
$c/= :: ExUnits -> ExUnits -> Bool
== :: ExUnits -> ExUnits -> Bool
$c== :: ExUnits -> ExUnits -> Bool
Eq, forall x. Rep ExUnits x -> ExUnits
forall x. ExUnits -> Rep ExUnits x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ExUnits x -> ExUnits
$cfrom :: forall x. ExUnits -> Rep ExUnits x
Generic, Int -> ExUnits -> ShowS
[ExUnits] -> ShowS
ExUnits -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExUnits] -> ShowS
$cshowList :: [ExUnits] -> ShowS
show :: ExUnits -> String
$cshow :: ExUnits -> String
showsPrec :: Int -> ExUnits -> ShowS
$cshowsPrec :: Int -> ExUnits -> ShowS
Show)
  deriving newtype (Semigroup ExUnits
ExUnits
[ExUnits] -> ExUnits
ExUnits -> ExUnits -> ExUnits
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [ExUnits] -> ExUnits
$cmconcat :: [ExUnits] -> ExUnits
mappend :: ExUnits -> ExUnits -> ExUnits
$cmappend :: ExUnits -> ExUnits -> ExUnits
mempty :: ExUnits
$cmempty :: ExUnits
Monoid, NonEmpty ExUnits -> ExUnits
ExUnits -> ExUnits -> ExUnits
forall b. Integral b => b -> ExUnits -> ExUnits
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> ExUnits -> ExUnits
$cstimes :: forall b. Integral b => b -> ExUnits -> ExUnits
sconcat :: NonEmpty ExUnits -> ExUnits
$csconcat :: NonEmpty ExUnits -> ExUnits
<> :: ExUnits -> ExUnits -> ExUnits
$c<> :: ExUnits -> ExUnits -> ExUnits
Semigroup)

instance NoThunks ExUnits

instance NFData ExUnits

instance ToJSON ExUnits where
  toJSON :: ExUnits -> Value
toJSON exUnits :: ExUnits
exUnits@(ExUnits Natural
_ Natural
_) =
    let ExUnits {Natural
exUnitsMem :: Natural
exUnitsMem :: ExUnits -> Natural
exUnitsMem, Natural
exUnitsSteps :: Natural
exUnitsSteps :: ExUnits -> Natural
exUnitsSteps} = ExUnits
exUnits
     in [Pair] -> Value
object
          [ Key
"memory" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= forall a. ToJSON a => a -> Value
toJSON Natural
exUnitsMem
          , Key
"steps" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= forall a. ToJSON a => a -> Value
toJSON Natural
exUnitsSteps
          ]

instance FromJSON ExUnits where
  parseJSON :: Value -> Parser ExUnits
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"exUnits" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    Natural
exUnitsMem <- forall {a} {f :: * -> *}.
(Ord a, Num a, MonadFail f, Show a) =>
a -> f a
checkWord64Bounds forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"memory" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"exUnitsMem")
    Natural
exUnitsSteps <- forall {a} {f :: * -> *}.
(Ord a, Num a, MonadFail f, Show a) =>
a -> f a
checkWord64Bounds forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"steps" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"exUnitsSteps")
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ ExUnits {Natural
exUnitsMem :: Natural
exUnitsMem :: Natural
exUnitsMem, Natural
exUnitsSteps :: Natural
exUnitsSteps :: Natural
exUnitsSteps}
    where
      checkWord64Bounds :: a -> f a
checkWord64Bounds a
n =
        if a
n forall a. Ord a => a -> a -> Bool
>= forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
minBound @Word64)
          Bool -> Bool -> Bool
&& a
n forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound @Word64)
          then forall (f :: * -> *) a. Applicative f => a -> f a
pure a
n
          else forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Unit out of bounds for Word64: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show a
n)

-- | Arbitrary execution unit in which we measure the cost of scripts in terms
-- of space in memory and execution time.
--
-- This pattern hides the fact that ExUnits' is parametric in the underlying type.
-- The ledger itself uses 'ExUnits' Natural' exclusively.
--
-- We would have preferred to use a type alias for 'ExUnits' Natural',
-- but this is not possible: https://gitlab.haskell.org/ghc/ghc/-/issues/19507.
pattern ExUnits :: Natural -> Natural -> ExUnits
pattern $bExUnits :: Natural -> Natural -> ExUnits
$mExUnits :: forall {r}.
ExUnits -> (Natural -> Natural -> r) -> ((# #) -> r) -> r
ExUnits {ExUnits -> Natural
exUnitsMem, ExUnits -> Natural
exUnitsSteps} <-
  WrapExUnits (ExUnits' exUnitsMem exUnitsSteps)
  where
    ExUnits Natural
m Natural
s = ExUnits' Natural -> ExUnits
WrapExUnits (forall a. a -> a -> ExUnits' a
ExUnits' Natural
m Natural
s)

{-# COMPLETE ExUnits #-}

-- | It is deliberate that there is no `Ord` instance for `ExUnits`. Use this function to
--   compare if one `ExUnit` is pointwise compareable to another. In case when `Ord`
--   instance like comparison is necessary you can use @`zipSemiExUnits` `compare`@
pointWiseExUnits :: (Natural -> Natural -> Bool) -> ExUnits -> ExUnits -> Bool
pointWiseExUnits :: (Natural -> Natural -> Bool) -> ExUnits -> ExUnits -> Bool
pointWiseExUnits Natural -> Natural -> Bool
f ExUnits
ex1 ExUnits
ex2 = All -> Bool
getAll (forall a.
Semigroup a =>
(Natural -> Natural -> a) -> ExUnits -> ExUnits -> a
zipSemiExUnits (\Natural
x Natural
y -> Bool -> All
All (Natural -> Natural -> Bool
f Natural
x Natural
y)) ExUnits
ex1 ExUnits
ex2)

-- | Pointwise combine units into a semigroup and mappened the results.
zipSemiExUnits :: Semigroup a => (Natural -> Natural -> a) -> ExUnits -> ExUnits -> a
zipSemiExUnits :: forall a.
Semigroup a =>
(Natural -> Natural -> a) -> ExUnits -> ExUnits -> a
zipSemiExUnits Natural -> Natural -> a
f (ExUnits Natural
m1 Natural
s1) (ExUnits Natural
m2 Natural
s2) = (Natural
m1 Natural -> Natural -> a
`f` Natural
m2) forall a. Semigroup a => a -> a -> a
<> (Natural
s1 Natural -> Natural -> a
`f` Natural
s2)

-- ==================================

-- | Prices per execution unit
data Prices = Prices
  { Prices -> NonNegativeInterval
prMem :: !NonNegativeInterval
  , Prices -> NonNegativeInterval
prSteps :: !NonNegativeInterval
  }
  deriving (Prices -> Prices -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Prices -> Prices -> Bool
$c/= :: Prices -> Prices -> Bool
== :: Prices -> Prices -> Bool
$c== :: Prices -> Prices -> Bool
Eq, forall x. Rep Prices x -> Prices
forall x. Prices -> Rep Prices x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Prices x -> Prices
$cfrom :: forall x. Prices -> Rep Prices x
Generic, Int -> Prices -> ShowS
[Prices] -> ShowS
Prices -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Prices] -> ShowS
$cshowList :: [Prices] -> ShowS
show :: Prices -> String
$cshow :: Prices -> String
showsPrec :: Int -> Prices -> ShowS
$cshowsPrec :: Int -> Prices -> ShowS
Show, Eq Prices
Prices -> Prices -> Bool
Prices -> Prices -> Ordering
Prices -> Prices -> Prices
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Prices -> Prices -> Prices
$cmin :: Prices -> Prices -> Prices
max :: Prices -> Prices -> Prices
$cmax :: Prices -> Prices -> Prices
>= :: Prices -> Prices -> Bool
$c>= :: Prices -> Prices -> Bool
> :: Prices -> Prices -> Bool
$c> :: Prices -> Prices -> Bool
<= :: Prices -> Prices -> Bool
$c<= :: Prices -> Prices -> Bool
< :: Prices -> Prices -> Bool
$c< :: Prices -> Prices -> Bool
compare :: Prices -> Prices -> Ordering
$ccompare :: Prices -> Prices -> Ordering
Ord)

instance NoThunks Prices

instance NFData Prices

instance ToJSON Prices where
  toJSON :: Prices -> Value
toJSON Prices {NonNegativeInterval
prSteps :: NonNegativeInterval
prSteps :: Prices -> NonNegativeInterval
prSteps, NonNegativeInterval
prMem :: NonNegativeInterval
prMem :: Prices -> NonNegativeInterval
prMem} =
    [Pair] -> Value
object
      [ Key
"priceSteps" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= NonNegativeInterval
prSteps
      , Key
"priceMemory" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= NonNegativeInterval
prMem
      ]

instance FromJSON Prices where
  parseJSON :: Value -> Parser Prices
parseJSON =
    forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"prices" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
      NonNegativeInterval
prSteps <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"priceSteps" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"prSteps"
      NonNegativeInterval
prMem <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"priceMemory" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"prMem"
      forall (m :: * -> *) a. Monad m => a -> m a
return Prices {NonNegativeInterval
prSteps :: NonNegativeInterval
prSteps :: NonNegativeInterval
prSteps, NonNegativeInterval
prMem :: NonNegativeInterval
prMem :: NonNegativeInterval
prMem}

-- | Compute the cost of a script based upon prices and the number of execution
-- units.
txscriptfee :: Prices -> ExUnits -> Coin
txscriptfee :: Prices -> ExUnits -> Coin
txscriptfee Prices {NonNegativeInterval
prMem :: NonNegativeInterval
prMem :: Prices -> NonNegativeInterval
prMem, NonNegativeInterval
prSteps :: NonNegativeInterval
prSteps :: Prices -> NonNegativeInterval
prSteps} ExUnits {exUnitsMem :: ExUnits -> Natural
exUnitsMem = Natural
m, exUnitsSteps :: ExUnits -> Natural
exUnitsSteps = Natural
s} =
  Integer -> Coin
Coin forall a b. (a -> b) -> a -> b
$
    forall a b. (RealFrac a, Integral b) => a -> b
ceiling forall a b. (a -> b) -> a -> b
$
      (forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
m forall a. Num a => a -> a -> a
* forall r. BoundedRational r => r -> Rational
unboundRational NonNegativeInterval
prMem)
        forall a. Num a => a -> a -> a
+ (forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
s forall a. Num a => a -> a -> a
* forall r. BoundedRational r => r -> Rational
unboundRational NonNegativeInterval
prSteps)

instance EncCBOR ExUnits where
  encCBOR :: ExUnits -> Encoding
encCBOR (ExUnits Natural
m Natural
s) = forall (w :: Wrapped) t. Encode w t -> Encoding
encode forall a b. (a -> b) -> a -> b
$ forall t. t -> Encode ('Closed 'Dense) t
Rec Natural -> Natural -> ExUnits
ExUnits forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Natural
m forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Natural
s

instance DecCBOR ExUnits where
  decCBOR :: forall s. Decoder s ExUnits
decCBOR = forall (w :: Wrapped) t s. Decode w t -> Decoder s t
decode forall a b. (a -> b) -> a -> b
$ forall t. t -> Decode ('Closed 'Dense) t
RecD Natural -> Natural -> ExUnits
ExUnits forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t. (forall s. Decoder s t) -> Decode ('Closed 'Dense) t
D forall s. Decoder s Natural
decNat forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t. (forall s. Decoder s t) -> Decode ('Closed 'Dense) t
D forall s. Decoder s Natural
decNat
    where
      decNat :: Decoder s Natural
      decNat :: forall s. Decoder s Natural
decNat = do
        Word64
x <- forall a s. DecCBOR a => Decoder s a
decCBOR
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when
          (Word64
x forall a. Ord a => a -> a -> Bool
> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
Prelude.maxBound :: Int64))
          ( forall (m :: * -> *) e a. (MonadFail m, Buildable e) => e -> m a
cborError forall a b. (a -> b) -> a -> b
$
              Text -> Text -> DecoderError
DecoderErrorCustom Text
"ExUnits field" Text
"values must not exceed maxBound :: Int64"
          )
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Word64 -> Natural
wordToNatural Word64
x
      {-# INLINE decNat #-}
      wordToNatural :: Word64 -> Natural
      wordToNatural :: Word64 -> Natural
wordToNatural = forall a b. (Integral a, Num b) => a -> b
fromIntegral
      {-# INLINE wordToNatural #-}
  {-# INLINE decCBOR #-}

instance EncCBOR Prices where
  encCBOR :: Prices -> Encoding
encCBOR (Prices NonNegativeInterval
m NonNegativeInterval
s) = forall (w :: Wrapped) t. Encode w t -> Encoding
encode forall a b. (a -> b) -> a -> b
$ forall t. t -> Encode ('Closed 'Dense) t
Rec NonNegativeInterval -> NonNegativeInterval -> Prices
Prices forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To NonNegativeInterval
m forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To NonNegativeInterval
s

instance DecCBOR Prices where
  decCBOR :: forall s. Decoder s Prices
decCBOR = forall (w :: Wrapped) t s. Decode w t -> Decoder s t
decode forall a b. (a -> b) -> a -> b
$ forall t. t -> Decode ('Closed 'Dense) t
RecD NonNegativeInterval -> NonNegativeInterval -> Prices
Prices forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
  {-# INLINE decCBOR #-}