{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE TypeFamilies      #-}

module Ouroboros.Consensus.ByronSpec.Ledger.Block (
    BlockConfig (..)
  , ByronSpecBlock (..)
  , CodecConfig (..)
  , Header (..)
  , StorageConfig (..)
    -- * type alias
  , ByronSpecHeader
  ) where

import           Codec.Serialise
import           GHC.Generics (Generic)
import           NoThunks.Class (NoThunks)

import qualified Byron.Spec.Chain.STS.Block as Spec
import qualified Byron.Spec.Ledger.Core as Spec

import           Ouroboros.Consensus.Block

import           Ouroboros.Consensus.ByronSpec.Ledger.Conversions
import           Ouroboros.Consensus.ByronSpec.Ledger.Orphans ()

{-------------------------------------------------------------------------------
  Block
-------------------------------------------------------------------------------}

-- | Block according to the Byron spec
--
-- Just like we do for 'ByronBlock', we cache the header hash. In addition, we
-- also add the 'BlockNo', as this is entirely absent from the spec but we need
-- it for the 'HasHeader' abstraction, which is ubiquitous in
-- @ouroboros-consensus@ and @-network@.
data ByronSpecBlock = ByronSpecBlock {
      ByronSpecBlock -> Block
byronSpecBlock     :: Spec.Block
    , ByronSpecBlock -> BlockNo
byronSpecBlockNo   :: BlockNo
    , ByronSpecBlock -> Hash
byronSpecBlockHash :: Spec.Hash
    }
  deriving (Int -> ByronSpecBlock -> ShowS
[ByronSpecBlock] -> ShowS
ByronSpecBlock -> String
(Int -> ByronSpecBlock -> ShowS)
-> (ByronSpecBlock -> String)
-> ([ByronSpecBlock] -> ShowS)
-> Show ByronSpecBlock
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ByronSpecBlock] -> ShowS
$cshowList :: [ByronSpecBlock] -> ShowS
show :: ByronSpecBlock -> String
$cshow :: ByronSpecBlock -> String
showsPrec :: Int -> ByronSpecBlock -> ShowS
$cshowsPrec :: Int -> ByronSpecBlock -> ShowS
Show, ByronSpecBlock -> ByronSpecBlock -> Bool
(ByronSpecBlock -> ByronSpecBlock -> Bool)
-> (ByronSpecBlock -> ByronSpecBlock -> Bool) -> Eq ByronSpecBlock
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ByronSpecBlock -> ByronSpecBlock -> Bool
$c/= :: ByronSpecBlock -> ByronSpecBlock -> Bool
== :: ByronSpecBlock -> ByronSpecBlock -> Bool
$c== :: ByronSpecBlock -> ByronSpecBlock -> Bool
Eq, (forall x. ByronSpecBlock -> Rep ByronSpecBlock x)
-> (forall x. Rep ByronSpecBlock x -> ByronSpecBlock)
-> Generic ByronSpecBlock
forall x. Rep ByronSpecBlock x -> ByronSpecBlock
forall x. ByronSpecBlock -> Rep ByronSpecBlock x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ByronSpecBlock x -> ByronSpecBlock
$cfrom :: forall x. ByronSpecBlock -> Rep ByronSpecBlock x
Generic, [ByronSpecBlock] -> Encoding
ByronSpecBlock -> Encoding
(ByronSpecBlock -> Encoding)
-> (forall s. Decoder s ByronSpecBlock)
-> ([ByronSpecBlock] -> Encoding)
-> (forall s. Decoder s [ByronSpecBlock])
-> Serialise ByronSpecBlock
forall s. Decoder s [ByronSpecBlock]
forall s. Decoder s ByronSpecBlock
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
decodeList :: Decoder s [ByronSpecBlock]
$cdecodeList :: forall s. Decoder s [ByronSpecBlock]
encodeList :: [ByronSpecBlock] -> Encoding
$cencodeList :: [ByronSpecBlock] -> Encoding
decode :: Decoder s ByronSpecBlock
$cdecode :: forall s. Decoder s ByronSpecBlock
encode :: ByronSpecBlock -> Encoding
$cencode :: ByronSpecBlock -> Encoding
Serialise)

{-------------------------------------------------------------------------------
  GetHeader
-------------------------------------------------------------------------------}

data instance Header ByronSpecBlock = ByronSpecHeader {
      Header ByronSpecBlock -> BlockHeader
byronSpecHeader     :: Spec.BlockHeader
    , Header ByronSpecBlock -> BlockNo
byronSpecHeaderNo   :: BlockNo
    , Header ByronSpecBlock -> Hash
byronSpecHeaderHash :: Spec.Hash
    }
  deriving (Int -> Header ByronSpecBlock -> ShowS
[Header ByronSpecBlock] -> ShowS
Header ByronSpecBlock -> String
(Int -> Header ByronSpecBlock -> ShowS)
-> (Header ByronSpecBlock -> String)
-> ([Header ByronSpecBlock] -> ShowS)
-> Show (Header ByronSpecBlock)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Header ByronSpecBlock] -> ShowS
$cshowList :: [Header ByronSpecBlock] -> ShowS
show :: Header ByronSpecBlock -> String
$cshow :: Header ByronSpecBlock -> String
showsPrec :: Int -> Header ByronSpecBlock -> ShowS
$cshowsPrec :: Int -> Header ByronSpecBlock -> ShowS
Show, Header ByronSpecBlock -> Header ByronSpecBlock -> Bool
(Header ByronSpecBlock -> Header ByronSpecBlock -> Bool)
-> (Header ByronSpecBlock -> Header ByronSpecBlock -> Bool)
-> Eq (Header ByronSpecBlock)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Header ByronSpecBlock -> Header ByronSpecBlock -> Bool
$c/= :: Header ByronSpecBlock -> Header ByronSpecBlock -> Bool
== :: Header ByronSpecBlock -> Header ByronSpecBlock -> Bool
$c== :: Header ByronSpecBlock -> Header ByronSpecBlock -> Bool
Eq, (forall x. Header ByronSpecBlock -> Rep (Header ByronSpecBlock) x)
-> (forall x.
    Rep (Header ByronSpecBlock) x -> Header ByronSpecBlock)
-> Generic (Header ByronSpecBlock)
forall x. Rep (Header ByronSpecBlock) x -> Header ByronSpecBlock
forall x. Header ByronSpecBlock -> Rep (Header ByronSpecBlock) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep (Header ByronSpecBlock) x -> Header ByronSpecBlock
$cfrom :: forall x. Header ByronSpecBlock -> Rep (Header ByronSpecBlock) x
Generic, [Header ByronSpecBlock] -> Encoding
Header ByronSpecBlock -> Encoding
(Header ByronSpecBlock -> Encoding)
-> (forall s. Decoder s (Header ByronSpecBlock))
-> ([Header ByronSpecBlock] -> Encoding)
-> (forall s. Decoder s [Header ByronSpecBlock])
-> Serialise (Header ByronSpecBlock)
forall s. Decoder s [Header ByronSpecBlock]
forall s. Decoder s (Header ByronSpecBlock)
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
decodeList :: Decoder s [Header ByronSpecBlock]
$cdecodeList :: forall s. Decoder s [Header ByronSpecBlock]
encodeList :: [Header ByronSpecBlock] -> Encoding
$cencodeList :: [Header ByronSpecBlock] -> Encoding
decode :: Decoder s (Header ByronSpecBlock)
$cdecode :: forall s. Decoder s (Header ByronSpecBlock)
encode :: Header ByronSpecBlock -> Encoding
$cencode :: Header ByronSpecBlock -> Encoding
Serialise)

instance GetHeader ByronSpecBlock where
  getHeader :: ByronSpecBlock -> Header ByronSpecBlock
getHeader ByronSpecBlock{BlockNo
Hash
Block
byronSpecBlockHash :: Hash
byronSpecBlockNo :: BlockNo
byronSpecBlock :: Block
byronSpecBlockHash :: ByronSpecBlock -> Hash
byronSpecBlockNo :: ByronSpecBlock -> BlockNo
byronSpecBlock :: ByronSpecBlock -> Block
..} = ByronSpecHeader :: BlockHeader -> BlockNo -> Hash -> Header ByronSpecBlock
ByronSpecHeader {
        byronSpecHeader :: BlockHeader
byronSpecHeader     = Block -> BlockHeader
Spec._bHeader Block
byronSpecBlock
      , byronSpecHeaderNo :: BlockNo
byronSpecHeaderNo   = BlockNo
byronSpecBlockNo
      , byronSpecHeaderHash :: Hash
byronSpecHeaderHash = Hash
byronSpecBlockHash
      }

  -- We don't care about integrity checks, so we don't bother checking whether
  -- the hashes of the body are correct
  blockMatchesHeader :: Header ByronSpecBlock -> ByronSpecBlock -> Bool
blockMatchesHeader Header ByronSpecBlock
hdr ByronSpecBlock
blk = Header ByronSpecBlock -> HeaderHash (Header ByronSpecBlock)
forall b. HasHeader b => b -> HeaderHash b
blockHash Header ByronSpecBlock
hdr Hash -> Hash -> Bool
forall a. Eq a => a -> a -> Bool
== ByronSpecBlock -> HeaderHash ByronSpecBlock
forall b. HasHeader b => b -> HeaderHash b
blockHash ByronSpecBlock
blk

  -- No EBBs
  headerIsEBB :: Header ByronSpecBlock -> Maybe EpochNo
headerIsEBB = Maybe EpochNo -> Header ByronSpecBlock -> Maybe EpochNo
forall a b. a -> b -> a
const Maybe EpochNo
forall a. Maybe a
Nothing

type ByronSpecHeader = Header ByronSpecBlock

{-------------------------------------------------------------------------------
  HasHeader
-------------------------------------------------------------------------------}

type instance HeaderHash ByronSpecBlock = Spec.Hash
instance StandardHash ByronSpecBlock

instance HasHeader ByronSpecBlock where
  getHeaderFields :: ByronSpecBlock -> HeaderFields ByronSpecBlock
getHeaderFields = ByronSpecBlock -> HeaderFields ByronSpecBlock
forall blk. GetHeader blk => blk -> HeaderFields blk
getBlockHeaderFields

instance HasHeader ByronSpecHeader where
  getHeaderFields :: Header ByronSpecBlock -> HeaderFields (Header ByronSpecBlock)
getHeaderFields Header ByronSpecBlock
hdr = HeaderFields :: forall b. SlotNo -> BlockNo -> HeaderHash b -> HeaderFields b
HeaderFields {
        headerFieldHash :: HeaderHash (Header ByronSpecBlock)
headerFieldHash    = Header ByronSpecBlock -> Hash
byronSpecHeaderHash Header ByronSpecBlock
hdr
      , headerFieldBlockNo :: BlockNo
headerFieldBlockNo = Header ByronSpecBlock -> BlockNo
byronSpecHeaderNo Header ByronSpecBlock
hdr
      , headerFieldSlot :: SlotNo
headerFieldSlot    = Slot -> SlotNo
fromByronSpecSlotNo (Slot -> SlotNo) -> (BlockHeader -> Slot) -> BlockHeader -> SlotNo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlockHeader -> Slot
Spec._bhSlot (BlockHeader -> SlotNo) -> BlockHeader -> SlotNo
forall a b. (a -> b) -> a -> b
$ Header ByronSpecBlock -> BlockHeader
byronSpecHeader Header ByronSpecBlock
hdr
      }

instance GetPrevHash ByronSpecBlock where
  headerPrevHash :: Header ByronSpecBlock -> ChainHash ByronSpecBlock
headerPrevHash = (Hash -> HeaderHash ByronSpecBlock)
-> Hash -> ChainHash ByronSpecBlock
forall b. (Hash -> HeaderHash b) -> Hash -> ChainHash b
fromByronSpecPrevHash Hash -> HeaderHash ByronSpecBlock
forall a. a -> a
id (Hash -> ChainHash ByronSpecBlock)
-> (Header ByronSpecBlock -> Hash)
-> Header ByronSpecBlock
-> ChainHash ByronSpecBlock
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlockHeader -> Hash
Spec._bhPrevHash (BlockHeader -> Hash)
-> (Header ByronSpecBlock -> BlockHeader)
-> Header ByronSpecBlock
-> Hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header ByronSpecBlock -> BlockHeader
byronSpecHeader

{-------------------------------------------------------------------------------
  Config
-------------------------------------------------------------------------------}

data instance BlockConfig ByronSpecBlock = ByronSpecBlockConfig
  deriving ((forall x.
 BlockConfig ByronSpecBlock -> Rep (BlockConfig ByronSpecBlock) x)
-> (forall x.
    Rep (BlockConfig ByronSpecBlock) x -> BlockConfig ByronSpecBlock)
-> Generic (BlockConfig ByronSpecBlock)
forall x.
Rep (BlockConfig ByronSpecBlock) x -> BlockConfig ByronSpecBlock
forall x.
BlockConfig ByronSpecBlock -> Rep (BlockConfig ByronSpecBlock) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep (BlockConfig ByronSpecBlock) x -> BlockConfig ByronSpecBlock
$cfrom :: forall x.
BlockConfig ByronSpecBlock -> Rep (BlockConfig ByronSpecBlock) x
Generic, Context -> BlockConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
Proxy (BlockConfig ByronSpecBlock) -> String
(Context -> BlockConfig ByronSpecBlock -> IO (Maybe ThunkInfo))
-> (Context -> BlockConfig ByronSpecBlock -> IO (Maybe ThunkInfo))
-> (Proxy (BlockConfig ByronSpecBlock) -> String)
-> NoThunks (BlockConfig ByronSpecBlock)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (BlockConfig ByronSpecBlock) -> String
$cshowTypeOf :: Proxy (BlockConfig ByronSpecBlock) -> String
wNoThunks :: Context -> BlockConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> BlockConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
noThunks :: Context -> BlockConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> BlockConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
NoThunks)

data instance CodecConfig ByronSpecBlock = ByronSpecCodecConfig
  deriving ((forall x.
 CodecConfig ByronSpecBlock -> Rep (CodecConfig ByronSpecBlock) x)
-> (forall x.
    Rep (CodecConfig ByronSpecBlock) x -> CodecConfig ByronSpecBlock)
-> Generic (CodecConfig ByronSpecBlock)
forall x.
Rep (CodecConfig ByronSpecBlock) x -> CodecConfig ByronSpecBlock
forall x.
CodecConfig ByronSpecBlock -> Rep (CodecConfig ByronSpecBlock) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep (CodecConfig ByronSpecBlock) x -> CodecConfig ByronSpecBlock
$cfrom :: forall x.
CodecConfig ByronSpecBlock -> Rep (CodecConfig ByronSpecBlock) x
Generic, Context -> CodecConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
Proxy (CodecConfig ByronSpecBlock) -> String
(Context -> CodecConfig ByronSpecBlock -> IO (Maybe ThunkInfo))
-> (Context -> CodecConfig ByronSpecBlock -> IO (Maybe ThunkInfo))
-> (Proxy (CodecConfig ByronSpecBlock) -> String)
-> NoThunks (CodecConfig ByronSpecBlock)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (CodecConfig ByronSpecBlock) -> String
$cshowTypeOf :: Proxy (CodecConfig ByronSpecBlock) -> String
wNoThunks :: Context -> CodecConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> CodecConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
noThunks :: Context -> CodecConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> CodecConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
NoThunks)

data instance StorageConfig ByronSpecBlock = ByronSpecStorageConfig
  deriving ((forall x.
 StorageConfig ByronSpecBlock
 -> Rep (StorageConfig ByronSpecBlock) x)
-> (forall x.
    Rep (StorageConfig ByronSpecBlock) x
    -> StorageConfig ByronSpecBlock)
-> Generic (StorageConfig ByronSpecBlock)
forall x.
Rep (StorageConfig ByronSpecBlock) x
-> StorageConfig ByronSpecBlock
forall x.
StorageConfig ByronSpecBlock
-> Rep (StorageConfig ByronSpecBlock) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x.
Rep (StorageConfig ByronSpecBlock) x
-> StorageConfig ByronSpecBlock
$cfrom :: forall x.
StorageConfig ByronSpecBlock
-> Rep (StorageConfig ByronSpecBlock) x
Generic, Context -> StorageConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
Proxy (StorageConfig ByronSpecBlock) -> String
(Context -> StorageConfig ByronSpecBlock -> IO (Maybe ThunkInfo))
-> (Context
    -> StorageConfig ByronSpecBlock -> IO (Maybe ThunkInfo))
-> (Proxy (StorageConfig ByronSpecBlock) -> String)
-> NoThunks (StorageConfig ByronSpecBlock)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (StorageConfig ByronSpecBlock) -> String
$cshowTypeOf :: Proxy (StorageConfig ByronSpecBlock) -> String
wNoThunks :: Context -> StorageConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> StorageConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
noThunks :: Context -> StorageConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> StorageConfig ByronSpecBlock -> IO (Maybe ThunkInfo)
NoThunks)