{-# OPTIONS_GHC -Wno-orphans #-}

module Hydra.Cardano.Api.BlockHeader where

import Hydra.Cardano.Api.Prelude

import Data.ByteString qualified as BS
import Test.QuickCheck (vectorOf)

unsafeBlockHeaderHashFromBytes :: HasCallStack => ByteString -> Hash BlockHeader
unsafeBlockHeaderHashFromBytes :: HasCallStack => ByteString -> Hash BlockHeader
unsafeBlockHeaderHashFromBytes ByteString
bytes =
  case AsType (Hash BlockHeader)
-> ByteString -> Either SerialiseAsRawBytesError (Hash BlockHeader)
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Either SerialiseAsRawBytesError a
deserialiseFromRawBytes (Proxy (Hash BlockHeader) -> AsType (Hash BlockHeader)
forall t. HasTypeProxy t => Proxy t -> AsType t
proxyToAsType Proxy (Hash BlockHeader)
forall {k} (t :: k). Proxy t
Proxy) ByteString
bytes of
    Left SerialiseAsRawBytesError
e ->
      [Char] -> Hash BlockHeader
forall a. HasCallStack => [Char] -> a
error ([Char] -> Hash BlockHeader) -> [Char] -> Hash BlockHeader
forall a b. (a -> b) -> a -> b
$
        [Char]
"unsafeBlockHeaderHashFromBytes: failed on bytes "
          [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
bytes
          [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
" with error "
          [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> SerialiseAsRawBytesError -> [Char]
forall a. Show a => a -> [Char]
show SerialiseAsRawBytesError
e
    Right Hash BlockHeader
h -> Hash BlockHeader
h

-- * Arbitrary values

-- | Fully arbitrary block header with completely random hash.
genBlockHeader :: Gen BlockHeader
genBlockHeader :: Gen BlockHeader
genBlockHeader = do
  SlotNo
slotNo <- Word64 -> SlotNo
SlotNo (Word64 -> SlotNo) -> Gen Word64 -> Gen SlotNo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
forall a. Arbitrary a => Gen a
arbitrary
  SlotNo -> Gen BlockHeader
genBlockHeaderAt SlotNo
slotNo

-- | Generate a random block header with completely random hash, but at a
-- certain slot.
genBlockHeaderAt :: SlotNo -> Gen BlockHeader
genBlockHeaderAt :: SlotNo -> Gen BlockHeader
genBlockHeaderAt SlotNo
slotNo = do
  Hash BlockHeader
headerHash <- HasCallStack => ByteString -> Hash BlockHeader
ByteString -> Hash BlockHeader
unsafeBlockHeaderHashFromBytes (ByteString -> Hash BlockHeader)
-> ([Word8] -> ByteString) -> [Word8] -> Hash BlockHeader
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BS.pack ([Word8] -> Hash BlockHeader)
-> Gen [Word8] -> Gen (Hash BlockHeader)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen Word8 -> Gen [Word8]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
32 Gen Word8
forall a. Arbitrary a => Gen a
arbitrary
  BlockNo
blockNo <- Word64 -> BlockNo
BlockNo (Word64 -> BlockNo) -> Gen Word64 -> Gen BlockNo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
forall a. Arbitrary a => Gen a
arbitrary
  BlockHeader -> Gen BlockHeader
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (BlockHeader -> Gen BlockHeader) -> BlockHeader -> Gen BlockHeader
forall a b. (a -> b) -> a -> b
$ SlotNo -> Hash BlockHeader -> BlockNo -> BlockHeader
BlockHeader SlotNo
slotNo Hash BlockHeader
headerHash BlockNo
blockNo

instance Arbitrary BlockHeader where
  arbitrary :: Gen BlockHeader
arbitrary = Gen BlockHeader
genBlockHeader