{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Ledger.Alonzo.Binary.CostModelsSpec (spec) where

import Cardano.Ledger.Alonzo.Core
import Cardano.Ledger.BaseTypes
import Cardano.Ledger.Binary.Decoding
import Cardano.Ledger.Binary.Encoding
import Cardano.Ledger.Plutus.CostModels
import Cardano.Ledger.Plutus.Language
import qualified Data.Map as Map
import Data.Text (Text)
import Data.Word (Word8)
import Lens.Micro
import Test.Cardano.Ledger.Alonzo.Arbitrary (genEraLanguage)
import Test.Cardano.Ledger.Common

spec :: forall era. (AlonzoEraPParams era, AlonzoEraScript era) => Spec
spec :: forall era. (AlonzoEraPParams era, AlonzoEraScript era) => Spec
spec = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"CBOR deserialization" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    forall era. (AlonzoEraPParams era, AlonzoEraScript era) => Spec
validCostModelProp @era
    forall era. AlonzoEraPParams era => Spec
underspecifiedCostModelProp @era
    forall era. AlonzoEraPParams era => Spec
unknownCostModelProp @era
  String
-> (CostModels
    -> CostModels -> Map Word8 [Int64] -> Map Word8 [Int64] -> IO ())
-> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"applyPPUpdates" ((CostModels
  -> CostModels -> Map Word8 [Int64] -> Map Word8 [Int64] -> IO ())
 -> Spec)
-> (CostModels
    -> CostModels -> Map Word8 [Int64] -> Map Word8 [Int64] -> IO ())
-> Spec
forall a b. (a -> b) -> a -> b
$ \CostModels
valid CostModels
validUpdate Map Word8 [Int64]
unknown Map Word8 [Int64]
unknownUpdate -> do
    CostModels
original <- Map Word8 [Int64] -> IO CostModels
forall (m :: * -> *).
MonadFail m =>
Map Word8 [Int64] -> m CostModels
mkCostModelsLenient (CostModels -> Map Word8 [Int64]
flattenCostModels CostModels
valid Map Word8 [Int64] -> Map Word8 [Int64] -> Map Word8 [Int64]
forall a. Semigroup a => a -> a -> a
<> Map Word8 [Int64]
unknown)
    CostModels
originalUpdate <- Map Word8 [Int64] -> IO CostModels
forall (m :: * -> *).
MonadFail m =>
Map Word8 [Int64] -> m CostModels
mkCostModelsLenient (CostModels -> Map Word8 [Int64]
flattenCostModels CostModels
validUpdate Map Word8 [Int64] -> Map Word8 [Int64] -> Map Word8 [Int64]
forall a. Semigroup a => a -> a -> a
<> Map Word8 [Int64]
unknownUpdate)
    let
      pp :: PParams era
pp = PParams era
forall era. EraPParams era => PParams era
emptyPParams PParams era -> (PParams era -> PParams era) -> PParams era
forall a b. a -> (a -> b) -> b
& (CostModels -> Identity CostModels)
-> PParams era -> Identity (PParams era)
forall era. AlonzoEraPParams era => Lens' (PParams era) CostModels
Lens' (PParams era) CostModels
ppCostModelsL ((CostModels -> Identity CostModels)
 -> PParams era -> Identity (PParams era))
-> CostModels -> PParams era -> PParams era
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CostModels
original
      ppu :: PParamsUpdate era
ppu = PParamsUpdate era
forall era. EraPParams era => PParamsUpdate era
emptyPParamsUpdate PParamsUpdate era
-> (PParamsUpdate era -> PParamsUpdate era) -> PParamsUpdate era
forall a b. a -> (a -> b) -> b
& (StrictMaybe CostModels -> Identity (StrictMaybe CostModels))
-> PParamsUpdate era -> Identity (PParamsUpdate era)
forall era.
AlonzoEraPParams era =>
Lens' (PParamsUpdate era) (StrictMaybe CostModels)
Lens' (PParamsUpdate era) (StrictMaybe CostModels)
ppuCostModelsL ((StrictMaybe CostModels -> Identity (StrictMaybe CostModels))
 -> PParamsUpdate era -> Identity (PParamsUpdate era))
-> StrictMaybe CostModels -> PParamsUpdate era -> PParamsUpdate era
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CostModels -> StrictMaybe CostModels
forall a. a -> StrictMaybe a
SJust CostModels
originalUpdate
      updated :: PParams era
updated = forall era.
EraPParams era =>
PParams era -> PParamsUpdate era -> PParams era
applyPPUpdates @era PParams era
pp PParamsUpdate era
ppu
    -- Starting with Conway we update CostModel on per-language basis, while before
    -- that CostModels where overwritten completely
    if forall era. Era era => Version
eraProtVerLow @era Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @9
      then do
        CostModels
expected <- Map Word8 [Int64] -> IO CostModels
forall (m :: * -> *).
MonadFail m =>
Map Word8 [Int64] -> m CostModels
mkCostModelsLenient (CostModels -> Map Word8 [Int64]
flattenCostModels CostModels
originalUpdate Map Word8 [Int64] -> Map Word8 [Int64] -> Map Word8 [Int64]
forall a. Semigroup a => a -> a -> a
<> CostModels -> Map Word8 [Int64]
flattenCostModels CostModels
original)
        PParams era
updated PParams era -> PParams era -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (PParams era
pp PParams era -> (PParams era -> PParams era) -> PParams era
forall a b. a -> (a -> b) -> b
& (CostModels -> Identity CostModels)
-> PParams era -> Identity (PParams era)
forall era. AlonzoEraPParams era => Lens' (PParams era) CostModels
Lens' (PParams era) CostModels
ppCostModelsL ((CostModels -> Identity CostModels)
 -> PParams era -> Identity (PParams era))
-> CostModels -> PParams era -> PParams era
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CostModels
expected)
      else PParams era
updated PParams era -> PParams era -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (PParams era
pp PParams era -> (PParams era -> PParams era) -> PParams era
forall a b. a -> (a -> b) -> b
& (CostModels -> Identity CostModels)
-> PParams era -> Identity (PParams era)
forall era. AlonzoEraPParams era => Lens' (PParams era) CostModels
Lens' (PParams era) CostModels
ppCostModelsL ((CostModels -> Identity CostModels)
 -> PParams era -> Identity (PParams era))
-> CostModels -> PParams era -> PParams era
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CostModels
originalUpdate)

validCostModelProp ::
  forall era.
  (AlonzoEraPParams era, AlonzoEraScript era) =>
  Spec
validCostModelProp :: forall era. (AlonzoEraPParams era, AlonzoEraScript era) => Spec
validCostModelProp = do
  String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"valid CostModels deserialize correctly, both independently and within PParamsUpdate" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
    Gen Language -> (Language -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll (forall era. AlonzoEraScript era => Gen Language
genEraLanguage @era) ((Language -> Property) -> Property)
-> (Language -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(Language
lang :: Language) -> do
      Gen Encoding
-> (Encoding -> String) -> (Encoding -> IO ()) -> Property
forall prop a.
Testable prop =>
Gen a -> (a -> String) -> (a -> prop) -> Property
forAllShow (Language -> Gen Encoding
genValidCostModelEnc Language
lang) (forall era. Era era => Encoding -> String
showEnc @era) ((Encoding -> IO ()) -> Property)
-> (Encoding -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$
        \Encoding
validCmEnc -> do
          forall era.
AlonzoEraPParams era =>
Encoding
-> (Either DecoderError CostModels
    -> Either DecoderError (PParamsUpdate era) -> IO ())
-> IO ()
encodeAndCheckDecoded @era Encoding
validCmEnc ((Either DecoderError CostModels
  -> Either DecoderError (PParamsUpdate era) -> IO ())
 -> IO ())
-> (Either DecoderError CostModels
    -> Either DecoderError (PParamsUpdate era) -> IO ())
-> IO ()
forall a b. (a -> b) -> a -> b
$
            \Either DecoderError CostModels
cmDecoded Either DecoderError (PParamsUpdate era)
ppuDecoded -> do
              Either DecoderError CostModels -> IO CostModels
forall a b. (HasCallStack, Show a) => Either a b -> IO b
expectRight Either DecoderError CostModels
cmDecoded IO CostModels -> (CostModels -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CostModels -> (CostModels -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` CostModels -> Bool
validCm)
              PParamsUpdate era
ppuRes <- Either DecoderError (PParamsUpdate era) -> IO (PParamsUpdate era)
forall a b. (HasCallStack, Show a) => Either a b -> IO b
expectRight Either DecoderError (PParamsUpdate era)
ppuDecoded
              PParamsUpdate era
ppuRes PParamsUpdate era -> (PParamsUpdate era -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` \PParamsUpdate era
ppu -> (CostModels -> Bool
validCm (CostModels -> Bool) -> StrictMaybe CostModels -> StrictMaybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PParamsUpdate era
ppu PParamsUpdate era
-> Getting
     (StrictMaybe CostModels)
     (PParamsUpdate era)
     (StrictMaybe CostModels)
-> StrictMaybe CostModels
forall s a. s -> Getting a s a -> a
^. Getting
  (StrictMaybe CostModels)
  (PParamsUpdate era)
  (StrictMaybe CostModels)
forall era.
AlonzoEraPParams era =>
Lens' (PParamsUpdate era) (StrictMaybe CostModels)
Lens' (PParamsUpdate era) (StrictMaybe CostModels)
ppuCostModelsL) StrictMaybe Bool -> StrictMaybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> StrictMaybe Bool
forall a. a -> StrictMaybe a
SJust Bool
True
  where
    genValidCostModelEnc :: Language -> Gen Encoding
genValidCostModelEnc Language
lang = Language -> Int -> Gen Encoding
genCostModelEncForLanguage Language
lang (Language -> Int
costModelParamsCount Language
lang)
    validCm :: CostModels -> Bool
validCm CostModels
cms =
      Bool -> Bool
not (Map Language CostModel -> Bool
forall a. Map Language a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CostModels -> Map Language CostModel
costModelsValid CostModels
cms)) Bool -> Bool -> Bool
&& Map Word8 [Int64] -> Bool
forall a. Map Word8 a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CostModels -> Map Word8 [Int64]
costModelsUnknown CostModels
cms)

-- | Underspecified is a CostModel that has less than the normal number of parameters
underspecifiedCostModelProp ::
  forall era.
  AlonzoEraPParams era =>
  Spec
underspecifiedCostModelProp :: forall era. AlonzoEraPParams era => Spec
underspecifiedCostModelProp = do
  String -> (Language -> Property) -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"CostModels with less than expected parameters within PParamsUpdate" ((Language -> Property) -> Spec) -> (Language -> Property) -> Spec
forall a b. (a -> b) -> a -> b
$
    \(Language
lang :: Language) -> do
      Gen Encoding
-> (Encoding -> String) -> (Encoding -> IO ()) -> Property
forall prop a.
Testable prop =>
Gen a -> (a -> String) -> (a -> prop) -> Property
forAllShow (Language -> Gen Encoding
genUnderspecifiedCostModelEnc Language
lang) (forall era. Era era => Encoding -> String
showEnc @era) ((Encoding -> IO ()) -> Property)
-> (Encoding -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$
        \Encoding
shortCmEnc -> do
          forall era.
AlonzoEraPParams era =>
Encoding
-> (Either DecoderError CostModels
    -> Either DecoderError (PParamsUpdate era) -> IO ())
-> IO ()
encodeAndCheckDecoded @era Encoding
shortCmEnc ((Either DecoderError CostModels
  -> Either DecoderError (PParamsUpdate era) -> IO ())
 -> IO ())
-> (Either DecoderError CostModels
    -> Either DecoderError (PParamsUpdate era) -> IO ())
-> IO ()
forall a b. (a -> b) -> a -> b
$
            \Either DecoderError CostModels
cmDecoded Either DecoderError (PParamsUpdate era)
ppuDecoded -> do
              -- pre-Conway we are failing when deserializing underspecified costmodels
              if forall era. Era era => Version
eraProtVerHigh @era Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
< forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @9
                then do
                  Either DecoderError CostModels -> Maybe Text -> IO ()
forall t.
(HasCallStack, Show t) =>
Either DecoderError t -> Maybe Text -> IO ()
expectDeserialiseFailure Either DecoderError CostModels
cmDecoded (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"CostModels")
                  Either DecoderError (PParamsUpdate era) -> Maybe Text -> IO ()
forall t.
(HasCallStack, Show t) =>
Either DecoderError t -> Maybe Text -> IO ()
expectDeserialiseFailure Either DecoderError (PParamsUpdate era)
ppuDecoded Maybe Text
forall a. Maybe a
Nothing
                else do
                  -- post-Conway, we are retaining CostModels that specified less parameters than expected
                  CostModels
cmRes <- Either DecoderError CostModels -> IO CostModels
forall a b. (HasCallStack, Show a) => Either a b -> IO b
expectRight Either DecoderError CostModels
cmDecoded
                  CostModels
cmRes CostModels -> (CostModels -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` Bool -> Bool
not (Bool -> Bool) -> (CostModels -> Bool) -> CostModels -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Language CostModel -> Bool
forall a. Map Language a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Map Language CostModel -> Bool)
-> (CostModels -> Map Language CostModel) -> CostModels -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CostModels -> Map Language CostModel
costModelsValid
  where
    genUnderspecifiedCostModelEnc :: Language -> Gen Encoding
genUnderspecifiedCostModelEnc Language
lang = do
      let validCount :: Int
validCount = Language -> Int
costModelParamsCount Language
lang
      Int
count <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
validCount Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
      Language -> Int -> Gen Encoding
genCostModelEncForLanguage Language
lang Int
count

unknownCostModelProp ::
  forall era.
  AlonzoEraPParams era =>
  Spec
unknownCostModelProp :: forall era. AlonzoEraPParams era => Spec
unknownCostModelProp = do
  String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"unknown CostModels deserialize correctly within PParamsUpdate starting with Conway" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
    Gen Encoding
-> (Encoding -> String) -> (Encoding -> IO ()) -> Property
forall prop a.
Testable prop =>
Gen a -> (a -> String) -> (a -> prop) -> Property
forAllShow Gen Encoding
genUnknownCostModelEnc (forall era. Era era => Encoding -> String
showEnc @era) ((Encoding -> IO ()) -> Property)
-> (Encoding -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$
      \Encoding
unknownCmEnc -> do
        forall era.
AlonzoEraPParams era =>
Encoding
-> (Either DecoderError CostModels
    -> Either DecoderError (PParamsUpdate era) -> IO ())
-> IO ()
encodeAndCheckDecoded @era Encoding
unknownCmEnc ((Either DecoderError CostModels
  -> Either DecoderError (PParamsUpdate era) -> IO ())
 -> IO ())
-> (Either DecoderError CostModels
    -> Either DecoderError (PParamsUpdate era) -> IO ())
-> IO ()
forall a b. (a -> b) -> a -> b
$
          \Either DecoderError CostModels
cmDecoded Either DecoderError (PParamsUpdate era)
ppuDecoded -> do
            -- pre-Conway we are failing when deserializing unknown costmodels
            if forall era. Era era => Version
eraProtVerHigh @era Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
< forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @9
              then do
                Either DecoderError CostModels -> Maybe Text -> IO ()
forall t.
(HasCallStack, Show t) =>
Either DecoderError t -> Maybe Text -> IO ()
expectDeserialiseFailure Either DecoderError CostModels
cmDecoded (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"CostModels")
                Either DecoderError (PParamsUpdate era) -> Maybe Text -> IO ()
forall t.
(HasCallStack, Show t) =>
Either DecoderError t -> Maybe Text -> IO ()
expectDeserialiseFailure Either DecoderError (PParamsUpdate era)
ppuDecoded Maybe Text
forall a. Maybe a
Nothing
              else do
                -- post-Conway, we are collecting unknown CostModels
                CostModels
cmRes <- Either DecoderError CostModels -> IO CostModels
forall a b. (HasCallStack, Show a) => Either a b -> IO b
expectRight Either DecoderError CostModels
cmDecoded
                CostModels
cmRes CostModels -> (CostModels -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` CostModels -> Bool
unknownCm
                PParamsUpdate era
ppuRes <- Either DecoderError (PParamsUpdate era) -> IO (PParamsUpdate era)
forall a b. (HasCallStack, Show a) => Either a b -> IO b
expectRight Either DecoderError (PParamsUpdate era)
ppuDecoded
                PParamsUpdate era
ppuRes PParamsUpdate era -> (PParamsUpdate era -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` \PParamsUpdate era
ppu -> (CostModels -> Bool
unknownCm (CostModels -> Bool) -> StrictMaybe CostModels -> StrictMaybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PParamsUpdate era
ppu PParamsUpdate era
-> Getting
     (StrictMaybe CostModels)
     (PParamsUpdate era)
     (StrictMaybe CostModels)
-> StrictMaybe CostModels
forall s a. s -> Getting a s a -> a
^. Getting
  (StrictMaybe CostModels)
  (PParamsUpdate era)
  (StrictMaybe CostModels)
forall era.
AlonzoEraPParams era =>
Lens' (PParamsUpdate era) (StrictMaybe CostModels)
Lens' (PParamsUpdate era) (StrictMaybe CostModels)
ppuCostModelsL) StrictMaybe Bool -> StrictMaybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> StrictMaybe Bool
forall a. a -> StrictMaybe a
SJust Bool
True
  where
    genUnknownCostModelEnc :: Gen Encoding
genUnknownCostModelEnc = do
      let firstUnknownLang :: Int
firstUnknownLang = Language -> Int
forall a. Enum a => a -> Int
fromEnum (forall a. Bounded a => a
maxBound @Language) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
      Word8
lang <- (Word8, Word8) -> Gen Word8
forall a. Random a => (a, a) -> Gen a
choose (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
firstUnknownLang, forall a. Bounded a => a
maxBound @Word8)
      NonNegative Int
count <- Gen (NonNegative Int)
forall a. Arbitrary a => Gen a
arbitrary
      Word8 -> Int -> Gen Encoding
genCostModelsEnc Word8
lang Int
count
    unknownCm :: CostModels -> Bool
unknownCm CostModels
cms =
      Map Language CostModel -> Bool
forall a. Map Language a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CostModels -> Map Language CostModel
costModelsValid CostModels
cms) Bool -> Bool -> Bool
&& Bool -> Bool
not (Map Word8 [Int64] -> Bool
forall a. Map Word8 a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CostModels -> Map Word8 [Int64]
costModelsUnknown CostModels
cms))

encodeAndCheckDecoded ::
  forall era.
  AlonzoEraPParams era =>
  Encoding ->
  (Either DecoderError CostModels -> Either DecoderError (PParamsUpdate era) -> IO ()) ->
  IO ()
encodeAndCheckDecoded :: forall era.
AlonzoEraPParams era =>
Encoding
-> (Either DecoderError CostModels
    -> Either DecoderError (PParamsUpdate era) -> IO ())
-> IO ()
encodeAndCheckDecoded Encoding
cmEnc Either DecoderError CostModels
-> Either DecoderError (PParamsUpdate era) -> IO ()
check = do
  let ver :: Version
ver = forall era. Era era => Version
eraProtVerHigh @era
      ppuEnc :: Encoding
ppuEnc = Map Int Encoding -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR (Int -> Encoding -> Map Int Encoding
forall k a. k -> a -> Map k a
Map.singleton (Int
18 :: Int) Encoding
cmEnc)
      cmBytes :: ByteString
cmBytes = Version -> Encoding -> ByteString
forall a. EncCBOR a => Version -> a -> ByteString
serialize Version
ver Encoding
cmEnc
      ppuBytes :: ByteString
ppuBytes = Version -> Encoding -> ByteString
forall a. EncCBOR a => Version -> a -> ByteString
serialize Version
ver Encoding
ppuEnc
  Either DecoderError CostModels
-> Either DecoderError (PParamsUpdate era) -> IO ()
check
    (forall a.
DecCBOR a =>
Version -> ByteString -> Either DecoderError a
decodeFull @CostModels Version
ver ByteString
cmBytes)
    (forall a.
DecCBOR a =>
Version -> ByteString -> Either DecoderError a
decodeFull @(PParamsUpdate era) Version
ver ByteString
ppuBytes)

genCostModelsEnc :: Word8 -> Int -> Gen Encoding
genCostModelsEnc :: Word8 -> Int -> Gen Encoding
genCostModelsEnc Word8
lang Int
count = do
  [Int]
values <- Int -> Gen Int -> Gen [Int]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
count (Gen Int
forall a. Arbitrary a => Gen a
arbitrary :: Gen Int)
  Encoding -> Gen Encoding
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> Gen Encoding) -> Encoding -> Gen Encoding
forall a b. (a -> b) -> a -> b
$ Map Word8 [Int] -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR (Map Word8 [Int] -> Encoding) -> Map Word8 [Int] -> Encoding
forall a b. (a -> b) -> a -> b
$ Word8 -> [Int] -> Map Word8 [Int]
forall k a. k -> a -> Map k a
Map.singleton Word8
lang [Int]
values

genCostModelEncForLanguage :: Language -> Int -> Gen Encoding
genCostModelEncForLanguage :: Language -> Int -> Gen Encoding
genCostModelEncForLanguage = Word8 -> Int -> Gen Encoding
genCostModelsEnc (Word8 -> Int -> Gen Encoding)
-> (Language -> Word8) -> Language -> Int -> Gen Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> (Language -> Int) -> Language -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Language -> Int
forall a. Enum a => a -> Int
fromEnum

expectDeserialiseFailure :: (HasCallStack, Show t) => Either DecoderError t -> Maybe Text -> IO ()
expectDeserialiseFailure :: forall t.
(HasCallStack, Show t) =>
Either DecoderError t -> Maybe Text -> IO ()
expectDeserialiseFailure Either DecoderError t
e Maybe Text
expectedTxt = do
  DecoderError
res <- Either DecoderError t -> IO DecoderError
forall b a. (HasCallStack, Show b) => Either a b -> IO a
expectLeft Either DecoderError t
e
  DecoderError
res DecoderError -> (DecoderError -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` \case
    DecoderErrorDeserialiseFailure Text
txt DeserialiseFailure
_ -> Bool -> (Text -> Bool) -> Maybe Text -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
txt) Maybe Text
expectedTxt
    DecoderError
_ -> Bool
False

showEnc :: forall era. Era era => Encoding -> String
showEnc :: forall era. Era era => Encoding -> String
showEnc Encoding
enc = Encoding -> String
forall a. Show a => a -> String
show (Encoding -> String) -> Encoding -> String
forall a b. (a -> b) -> a -> b
$ Version -> Encoding -> Encoding
toPlainEncoding (forall era. Era era => Version
eraProtVerHigh @era) Encoding
enc