{-# LANGUAGE UndecidableInstances #-}

module Hydra.Network.Message where

import Hydra.Prelude

import Cardano.Binary (serialize')
import Cardano.Crypto.Util (SignableRepresentation, getSignableRepresentation)
import Hydra.Network (Connectivity)
import Hydra.Tx (
  IsTx (TxIdType),
  Party,
  Snapshot,
  SnapshotNumber,
  SnapshotVersion,
  UTxOType,
 )
import Hydra.Tx.Crypto (Signature)

data NetworkEvent msg
  = ConnectivityEvent Connectivity
  | ReceivedMessage {forall msg. NetworkEvent msg -> Party
sender :: Party, forall msg. NetworkEvent msg -> msg
msg :: msg}
  deriving stock (NetworkEvent msg -> NetworkEvent msg -> Bool
(NetworkEvent msg -> NetworkEvent msg -> Bool)
-> (NetworkEvent msg -> NetworkEvent msg -> Bool)
-> Eq (NetworkEvent msg)
forall msg. Eq msg => NetworkEvent msg -> NetworkEvent msg -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall msg. Eq msg => NetworkEvent msg -> NetworkEvent msg -> Bool
== :: NetworkEvent msg -> NetworkEvent msg -> Bool
$c/= :: forall msg. Eq msg => NetworkEvent msg -> NetworkEvent msg -> Bool
/= :: NetworkEvent msg -> NetworkEvent msg -> Bool
Eq, Int -> NetworkEvent msg -> ShowS
[NetworkEvent msg] -> ShowS
NetworkEvent msg -> String
(Int -> NetworkEvent msg -> ShowS)
-> (NetworkEvent msg -> String)
-> ([NetworkEvent msg] -> ShowS)
-> Show (NetworkEvent msg)
forall msg. Show msg => Int -> NetworkEvent msg -> ShowS
forall msg. Show msg => [NetworkEvent msg] -> ShowS
forall msg. Show msg => NetworkEvent msg -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall msg. Show msg => Int -> NetworkEvent msg -> ShowS
showsPrec :: Int -> NetworkEvent msg -> ShowS
$cshow :: forall msg. Show msg => NetworkEvent msg -> String
show :: NetworkEvent msg -> String
$cshowList :: forall msg. Show msg => [NetworkEvent msg] -> ShowS
showList :: [NetworkEvent msg] -> ShowS
Show, (forall x. NetworkEvent msg -> Rep (NetworkEvent msg) x)
-> (forall x. Rep (NetworkEvent msg) x -> NetworkEvent msg)
-> Generic (NetworkEvent msg)
forall x. Rep (NetworkEvent msg) x -> NetworkEvent msg
forall x. NetworkEvent msg -> Rep (NetworkEvent msg) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall msg x. Rep (NetworkEvent msg) x -> NetworkEvent msg
forall msg x. NetworkEvent msg -> Rep (NetworkEvent msg) x
$cfrom :: forall msg x. NetworkEvent msg -> Rep (NetworkEvent msg) x
from :: forall x. NetworkEvent msg -> Rep (NetworkEvent msg) x
$cto :: forall msg x. Rep (NetworkEvent msg) x -> NetworkEvent msg
to :: forall x. Rep (NetworkEvent msg) x -> NetworkEvent msg
Generic)
  deriving anyclass ([NetworkEvent msg] -> Value
[NetworkEvent msg] -> Encoding
NetworkEvent msg -> Bool
NetworkEvent msg -> Value
NetworkEvent msg -> Encoding
(NetworkEvent msg -> Value)
-> (NetworkEvent msg -> Encoding)
-> ([NetworkEvent msg] -> Value)
-> ([NetworkEvent msg] -> Encoding)
-> (NetworkEvent msg -> Bool)
-> ToJSON (NetworkEvent msg)
forall msg. ToJSON msg => [NetworkEvent msg] -> Value
forall msg. ToJSON msg => [NetworkEvent msg] -> Encoding
forall msg. ToJSON msg => NetworkEvent msg -> Bool
forall msg. ToJSON msg => NetworkEvent msg -> Value
forall msg. ToJSON msg => NetworkEvent msg -> Encoding
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: forall msg. ToJSON msg => NetworkEvent msg -> Value
toJSON :: NetworkEvent msg -> Value
$ctoEncoding :: forall msg. ToJSON msg => NetworkEvent msg -> Encoding
toEncoding :: NetworkEvent msg -> Encoding
$ctoJSONList :: forall msg. ToJSON msg => [NetworkEvent msg] -> Value
toJSONList :: [NetworkEvent msg] -> Value
$ctoEncodingList :: forall msg. ToJSON msg => [NetworkEvent msg] -> Encoding
toEncodingList :: [NetworkEvent msg] -> Encoding
$comitField :: forall msg. ToJSON msg => NetworkEvent msg -> Bool
omitField :: NetworkEvent msg -> Bool
ToJSON, Maybe (NetworkEvent msg)
Value -> Parser [NetworkEvent msg]
Value -> Parser (NetworkEvent msg)
(Value -> Parser (NetworkEvent msg))
-> (Value -> Parser [NetworkEvent msg])
-> Maybe (NetworkEvent msg)
-> FromJSON (NetworkEvent msg)
forall msg. FromJSON msg => Maybe (NetworkEvent msg)
forall msg. FromJSON msg => Value -> Parser [NetworkEvent msg]
forall msg. FromJSON msg => Value -> Parser (NetworkEvent msg)
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: forall msg. FromJSON msg => Value -> Parser (NetworkEvent msg)
parseJSON :: Value -> Parser (NetworkEvent msg)
$cparseJSONList :: forall msg. FromJSON msg => Value -> Parser [NetworkEvent msg]
parseJSONList :: Value -> Parser [NetworkEvent msg]
$comittedField :: forall msg. FromJSON msg => Maybe (NetworkEvent msg)
omittedField :: Maybe (NetworkEvent msg)
FromJSON)

data Message tx
  = ReqTx {forall tx. Message tx -> tx
transaction :: tx}
  | ReqSn
      { forall tx. Message tx -> SnapshotVersion
snapshotVersion :: SnapshotVersion
      , forall tx. Message tx -> SnapshotNumber
snapshotNumber :: SnapshotNumber
      , forall tx. Message tx -> [TxIdType tx]
transactionIds :: [TxIdType tx]
      , forall tx. Message tx -> Maybe tx
decommitTx :: Maybe tx
      , forall tx. Message tx -> Maybe (TxIdType tx)
depositTxId :: Maybe (TxIdType tx)
      }
  | AckSn
      { forall tx. Message tx -> Signature (Snapshot tx)
signed :: Signature (Snapshot tx)
      , snapshotNumber :: SnapshotNumber
      }
  | ReqDec {transaction :: tx}
  deriving stock ((forall x. Message tx -> Rep (Message tx) x)
-> (forall x. Rep (Message tx) x -> Message tx)
-> Generic (Message tx)
forall x. Rep (Message tx) x -> Message tx
forall x. Message tx -> Rep (Message tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (Message tx) x -> Message tx
forall tx x. Message tx -> Rep (Message tx) x
$cfrom :: forall tx x. Message tx -> Rep (Message tx) x
from :: forall x. Message tx -> Rep (Message tx) x
$cto :: forall tx x. Rep (Message tx) x -> Message tx
to :: forall x. Rep (Message tx) x -> Message tx
Generic)

deriving stock instance IsTx tx => Eq (Message tx)
deriving stock instance IsTx tx => Show (Message tx)
deriving anyclass instance IsTx tx => ToJSON (Message tx)
deriving anyclass instance IsTx tx => FromJSON (Message tx)

instance (ToCBOR tx, ToCBOR (UTxOType tx), ToCBOR (TxIdType tx)) => ToCBOR (Message tx) where
  toCBOR :: Message tx -> Encoding
toCBOR = Message tx -> Encoding
forall a. (Generic a, GToCBOR (Rep a)) => a -> Encoding
genericToCBOR

instance (FromCBOR tx, FromCBOR (UTxOType tx), FromCBOR (TxIdType tx)) => FromCBOR (Message tx) where
  fromCBOR :: forall s. Decoder s (Message tx)
fromCBOR = Decoder s (Message tx)
forall a s. (Generic a, GFromCBOR (Rep a)) => Decoder s a
genericFromCBOR

instance IsTx tx => SignableRepresentation (Message tx) where
  getSignableRepresentation :: Message tx -> ByteString
getSignableRepresentation = Message tx -> ByteString
forall a. ToCBOR a => a -> ByteString
serialize'