{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE DerivingVia                #-}
{-# LANGUAGE EmptyCase                  #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PolyKinds                  #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE StandaloneKindSignatures   #-}
{-# LANGUAGE TypeFamilies               #-}

-- | The type of the transaction submission protocol.
--
-- This is used to relay transactions between nodes.
--
module Ouroboros.Network.Protocol.TxSubmission2.Type
  ( TxSubmission2 (..)
  , Message (..)
  , SingTxSubmission (..)
  , SingBlockingStyle (..)
  , StBlockingStyle (..)
  , BlockingReplyList (..)
  , NumTxIdsToAck (..)
  , NumTxIdsToReq (..)
    -- re-exports
  , SizeInBytes (..)
  ) where

import Control.DeepSeq
import Data.Kind (Type)
import Data.List.NonEmpty (NonEmpty)
import Data.Monoid (Sum (..))
import Data.Singletons
import Data.Word (Word16)
import GHC.Generics
import NoThunks.Class (NoThunks (..))

import Quiet (Quiet (..))

import Network.TypedProtocol.Core

import Ouroboros.Network.SizeInBytes (SizeInBytes (..))
import Ouroboros.Network.Util.ShowProxy

-- | The kind of the transaction-submission protocol, and the types of the
-- states in the protocol state machine.
--
-- We describe this protocol using the label \"client\" for the peer that is
-- submitting transactions, and \"server\" for the one receiving them. The
-- protocol is however pull based, so it is typically the server that has
-- agency in this protocol. This is the opposite of the chain sync and block
-- fetch protocols, but that makes sense because the information flow is also
-- reversed: submitting transactions rather than receiving headers and blocks.
--
-- Because these client\/server labels are somewhat confusing in this case, we
-- sometimes clarify by using the terms inbound and outbound. This refers to
-- whether transactions are flowing towards a peer or away, and thus indicates
-- what role the peer is playing.
--
data TxSubmission2 txid tx where

  -- | Initial protocol message.
  --
  StInit   :: TxSubmission2 txid tx

  -- | The server (inbound side) has agency; it can either terminate, ask for
  -- transaction identifiers or ask for transactions.
  --
  -- There is no timeout in this state.
  --
  StIdle   :: TxSubmission2 txid tx

  -- | The client (outbound side) has agency; it must reply with a
  -- list of transaction identifiers that it wishes to submit.
  --
  -- There are two sub-states for this, for blocking and non-blocking cases.
  --
  StTxIds  :: StBlockingStyle -> TxSubmission2 txid tx

  -- | The client (outbound side) has agency; it must reply with the list of
  -- transactions.
  --
  StTxs    :: TxSubmission2 txid tx

  -- | Nobody has agency; termination state.
  --
  StDone   :: TxSubmission2 txid tx


instance ( ShowProxy txid
         , ShowProxy tx
         ) => ShowProxy (TxSubmission2 txid tx) where
    showProxy :: Proxy (TxSubmission2 txid tx) -> String
showProxy Proxy (TxSubmission2 txid tx)
_ = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
      [ String
"TxSubmission "
      , Proxy txid -> String
forall {k} (p :: k). ShowProxy p => Proxy p -> String
showProxy (Proxy txid
forall {k} (t :: k). Proxy t
Proxy :: Proxy txid)
      , String
" "
      , Proxy tx -> String
forall {k} (p :: k). ShowProxy p => Proxy p -> String
showProxy (Proxy tx
forall {k} (t :: k). Proxy t
Proxy :: Proxy tx)
      ]

instance ShowProxy (StIdle :: TxSubmission2 txid tx) where
    showProxy :: Proxy 'StIdle -> String
showProxy Proxy 'StIdle
_ = String
"StIdle"


type SingTxSubmission :: TxSubmission2 txid tx
                      -> Type
data SingTxSubmission k where
    SingInit  :: SingTxSubmission  StInit
    SingIdle  :: SingTxSubmission  StIdle
    SingTxIds :: SingBlockingStyle stBlocking
              -> SingTxSubmission (StTxIds stBlocking)
    SingTxs   :: SingTxSubmission  StTxs
    SingDone  :: SingTxSubmission  StDone

deriving instance Show (SingTxSubmission k)

instance StateTokenI StInit               where stateToken :: StateToken 'StInit
stateToken = StateToken 'StInit
SingTxSubmission 'StInit
forall {k} {k} {txid :: k} {tx :: k}. SingTxSubmission 'StInit
SingInit
instance StateTokenI StIdle               where stateToken :: StateToken 'StIdle
stateToken = StateToken 'StIdle
SingTxSubmission 'StIdle
forall {k} {k} {txid :: k} {tx :: k}. SingTxSubmission 'StIdle
SingIdle
instance SingI stBlocking
      => StateTokenI (StTxIds stBlocking) where stateToken :: StateToken ('StTxIds stBlocking)
stateToken = SingBlockingStyle stBlocking
-> SingTxSubmission ('StTxIds stBlocking)
forall {k} {k} {txid :: k} {tx :: k}
       (stBlocking :: StBlockingStyle).
SingBlockingStyle stBlocking
-> SingTxSubmission ('StTxIds stBlocking)
SingTxIds Sing stBlocking
SingBlockingStyle stBlocking
forall {k} (a :: k). SingI a => Sing a
sing
instance StateTokenI StTxs                where stateToken :: StateToken 'StTxs
stateToken = StateToken 'StTxs
SingTxSubmission 'StTxs
forall {k} {k} {txid :: k} {tx :: k}. SingTxSubmission 'StTxs
SingTxs
instance StateTokenI StDone               where stateToken :: StateToken 'StDone
stateToken = StateToken 'StDone
SingTxSubmission 'StDone
forall {k} {k} {txid :: k} {tx :: k}. SingTxSubmission 'StDone
SingDone


data StBlockingStyle where

  -- | In this sub-state the reply need not be prompt. There is no timeout.
  --
  StBlocking    :: StBlockingStyle

  -- | In this state the peer must reply. There is a timeout.
  --
  StNonBlocking :: StBlockingStyle


newtype NumTxIdsToAck = NumTxIdsToAck { NumTxIdsToAck -> Word16
getNumTxIdsToAck :: Word16 }
  deriving (NumTxIdsToAck -> NumTxIdsToAck -> Bool
(NumTxIdsToAck -> NumTxIdsToAck -> Bool)
-> (NumTxIdsToAck -> NumTxIdsToAck -> Bool) -> Eq NumTxIdsToAck
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
== :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
$c/= :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
/= :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
Eq, Eq NumTxIdsToAck
Eq NumTxIdsToAck =>
(NumTxIdsToAck -> NumTxIdsToAck -> Ordering)
-> (NumTxIdsToAck -> NumTxIdsToAck -> Bool)
-> (NumTxIdsToAck -> NumTxIdsToAck -> Bool)
-> (NumTxIdsToAck -> NumTxIdsToAck -> Bool)
-> (NumTxIdsToAck -> NumTxIdsToAck -> Bool)
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> Ord NumTxIdsToAck
NumTxIdsToAck -> NumTxIdsToAck -> Bool
NumTxIdsToAck -> NumTxIdsToAck -> Ordering
NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
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
$ccompare :: NumTxIdsToAck -> NumTxIdsToAck -> Ordering
compare :: NumTxIdsToAck -> NumTxIdsToAck -> Ordering
$c< :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
< :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
$c<= :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
<= :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
$c> :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
> :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
$c>= :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
>= :: NumTxIdsToAck -> NumTxIdsToAck -> Bool
$cmax :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
max :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$cmin :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
min :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
Ord, NumTxIdsToAck -> ()
(NumTxIdsToAck -> ()) -> NFData NumTxIdsToAck
forall a. (a -> ()) -> NFData a
$crnf :: NumTxIdsToAck -> ()
rnf :: NumTxIdsToAck -> ()
NFData, (forall x. NumTxIdsToAck -> Rep NumTxIdsToAck x)
-> (forall x. Rep NumTxIdsToAck x -> NumTxIdsToAck)
-> Generic NumTxIdsToAck
forall x. Rep NumTxIdsToAck x -> NumTxIdsToAck
forall x. NumTxIdsToAck -> Rep NumTxIdsToAck x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NumTxIdsToAck -> Rep NumTxIdsToAck x
from :: forall x. NumTxIdsToAck -> Rep NumTxIdsToAck x
$cto :: forall x. Rep NumTxIdsToAck x -> NumTxIdsToAck
to :: forall x. Rep NumTxIdsToAck x -> NumTxIdsToAck
Generic)
  deriving newtype (Integer -> NumTxIdsToAck
NumTxIdsToAck -> NumTxIdsToAck
NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
(NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck)
-> (Integer -> NumTxIdsToAck)
-> Num NumTxIdsToAck
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
+ :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$c- :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
- :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$c* :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
* :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$cnegate :: NumTxIdsToAck -> NumTxIdsToAck
negate :: NumTxIdsToAck -> NumTxIdsToAck
$cabs :: NumTxIdsToAck -> NumTxIdsToAck
abs :: NumTxIdsToAck -> NumTxIdsToAck
$csignum :: NumTxIdsToAck -> NumTxIdsToAck
signum :: NumTxIdsToAck -> NumTxIdsToAck
$cfromInteger :: Integer -> NumTxIdsToAck
fromInteger :: Integer -> NumTxIdsToAck
Num, Int -> NumTxIdsToAck
NumTxIdsToAck -> Int
NumTxIdsToAck -> [NumTxIdsToAck]
NumTxIdsToAck -> NumTxIdsToAck
NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
(NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck)
-> (Int -> NumTxIdsToAck)
-> (NumTxIdsToAck -> Int)
-> (NumTxIdsToAck -> [NumTxIdsToAck])
-> (NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck])
-> (NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck])
-> (NumTxIdsToAck
    -> NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck])
-> Enum NumTxIdsToAck
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: NumTxIdsToAck -> NumTxIdsToAck
succ :: NumTxIdsToAck -> NumTxIdsToAck
$cpred :: NumTxIdsToAck -> NumTxIdsToAck
pred :: NumTxIdsToAck -> NumTxIdsToAck
$ctoEnum :: Int -> NumTxIdsToAck
toEnum :: Int -> NumTxIdsToAck
$cfromEnum :: NumTxIdsToAck -> Int
fromEnum :: NumTxIdsToAck -> Int
$cenumFrom :: NumTxIdsToAck -> [NumTxIdsToAck]
enumFrom :: NumTxIdsToAck -> [NumTxIdsToAck]
$cenumFromThen :: NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
enumFromThen :: NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
$cenumFromTo :: NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
enumFromTo :: NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
$cenumFromThenTo :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
enumFromThenTo :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck -> [NumTxIdsToAck]
Enum, Num NumTxIdsToAck
Ord NumTxIdsToAck
(Num NumTxIdsToAck, Ord NumTxIdsToAck) =>
(NumTxIdsToAck -> Rational) -> Real NumTxIdsToAck
NumTxIdsToAck -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: NumTxIdsToAck -> Rational
toRational :: NumTxIdsToAck -> Rational
Real, Enum NumTxIdsToAck
Real NumTxIdsToAck
(Real NumTxIdsToAck, Enum NumTxIdsToAck) =>
(NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NumTxIdsToAck
    -> NumTxIdsToAck -> (NumTxIdsToAck, NumTxIdsToAck))
-> (NumTxIdsToAck
    -> NumTxIdsToAck -> (NumTxIdsToAck, NumTxIdsToAck))
-> (NumTxIdsToAck -> Integer)
-> Integral NumTxIdsToAck
NumTxIdsToAck -> Integer
NumTxIdsToAck -> NumTxIdsToAck -> (NumTxIdsToAck, NumTxIdsToAck)
NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
quot :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$crem :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
rem :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$cdiv :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
div :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$cmod :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
mod :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$cquotRem :: NumTxIdsToAck -> NumTxIdsToAck -> (NumTxIdsToAck, NumTxIdsToAck)
quotRem :: NumTxIdsToAck -> NumTxIdsToAck -> (NumTxIdsToAck, NumTxIdsToAck)
$cdivMod :: NumTxIdsToAck -> NumTxIdsToAck -> (NumTxIdsToAck, NumTxIdsToAck)
divMod :: NumTxIdsToAck -> NumTxIdsToAck -> (NumTxIdsToAck, NumTxIdsToAck)
$ctoInteger :: NumTxIdsToAck -> Integer
toInteger :: NumTxIdsToAck -> Integer
Integral, NumTxIdsToAck
NumTxIdsToAck -> NumTxIdsToAck -> Bounded NumTxIdsToAck
forall a. a -> a -> Bounded a
$cminBound :: NumTxIdsToAck
minBound :: NumTxIdsToAck
$cmaxBound :: NumTxIdsToAck
maxBound :: NumTxIdsToAck
Bounded, [String] -> NumTxIdsToAck -> IO (Maybe ThunkInfo)
Proxy NumTxIdsToAck -> String
([String] -> NumTxIdsToAck -> IO (Maybe ThunkInfo))
-> ([String] -> NumTxIdsToAck -> IO (Maybe ThunkInfo))
-> (Proxy NumTxIdsToAck -> String)
-> NoThunks NumTxIdsToAck
forall a.
([String] -> a -> IO (Maybe ThunkInfo))
-> ([String] -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: [String] -> NumTxIdsToAck -> IO (Maybe ThunkInfo)
noThunks :: [String] -> NumTxIdsToAck -> IO (Maybe ThunkInfo)
$cwNoThunks :: [String] -> NumTxIdsToAck -> IO (Maybe ThunkInfo)
wNoThunks :: [String] -> NumTxIdsToAck -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy NumTxIdsToAck -> String
showTypeOf :: Proxy NumTxIdsToAck -> String
NoThunks)
  deriving NonEmpty NumTxIdsToAck -> NumTxIdsToAck
NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
(NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> (NonEmpty NumTxIdsToAck -> NumTxIdsToAck)
-> (forall b. Integral b => b -> NumTxIdsToAck -> NumTxIdsToAck)
-> Semigroup NumTxIdsToAck
forall b. Integral b => b -> NumTxIdsToAck -> NumTxIdsToAck
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
<> :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$csconcat :: NonEmpty NumTxIdsToAck -> NumTxIdsToAck
sconcat :: NonEmpty NumTxIdsToAck -> NumTxIdsToAck
$cstimes :: forall b. Integral b => b -> NumTxIdsToAck -> NumTxIdsToAck
stimes :: forall b. Integral b => b -> NumTxIdsToAck -> NumTxIdsToAck
Semigroup via (Sum Word16)
  deriving Semigroup NumTxIdsToAck
NumTxIdsToAck
Semigroup NumTxIdsToAck =>
NumTxIdsToAck
-> (NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck)
-> ([NumTxIdsToAck] -> NumTxIdsToAck)
-> Monoid NumTxIdsToAck
[NumTxIdsToAck] -> NumTxIdsToAck
NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: NumTxIdsToAck
mempty :: NumTxIdsToAck
$cmappend :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
mappend :: NumTxIdsToAck -> NumTxIdsToAck -> NumTxIdsToAck
$cmconcat :: [NumTxIdsToAck] -> NumTxIdsToAck
mconcat :: [NumTxIdsToAck] -> NumTxIdsToAck
Monoid via (Sum Word16)
  deriving Int -> NumTxIdsToAck -> ShowS
[NumTxIdsToAck] -> ShowS
NumTxIdsToAck -> String
(Int -> NumTxIdsToAck -> ShowS)
-> (NumTxIdsToAck -> String)
-> ([NumTxIdsToAck] -> ShowS)
-> Show NumTxIdsToAck
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NumTxIdsToAck -> ShowS
showsPrec :: Int -> NumTxIdsToAck -> ShowS
$cshow :: NumTxIdsToAck -> String
show :: NumTxIdsToAck -> String
$cshowList :: [NumTxIdsToAck] -> ShowS
showList :: [NumTxIdsToAck] -> ShowS
Show via (Quiet NumTxIdsToAck)

newtype NumTxIdsToReq = NumTxIdsToReq { NumTxIdsToReq -> Word16
getNumTxIdsToReq :: Word16 }
  deriving (NumTxIdsToReq -> NumTxIdsToReq -> Bool
(NumTxIdsToReq -> NumTxIdsToReq -> Bool)
-> (NumTxIdsToReq -> NumTxIdsToReq -> Bool) -> Eq NumTxIdsToReq
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
== :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
$c/= :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
/= :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
Eq, Eq NumTxIdsToReq
Eq NumTxIdsToReq =>
(NumTxIdsToReq -> NumTxIdsToReq -> Ordering)
-> (NumTxIdsToReq -> NumTxIdsToReq -> Bool)
-> (NumTxIdsToReq -> NumTxIdsToReq -> Bool)
-> (NumTxIdsToReq -> NumTxIdsToReq -> Bool)
-> (NumTxIdsToReq -> NumTxIdsToReq -> Bool)
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> Ord NumTxIdsToReq
NumTxIdsToReq -> NumTxIdsToReq -> Bool
NumTxIdsToReq -> NumTxIdsToReq -> Ordering
NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
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
$ccompare :: NumTxIdsToReq -> NumTxIdsToReq -> Ordering
compare :: NumTxIdsToReq -> NumTxIdsToReq -> Ordering
$c< :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
< :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
$c<= :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
<= :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
$c> :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
> :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
$c>= :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
>= :: NumTxIdsToReq -> NumTxIdsToReq -> Bool
$cmax :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
max :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$cmin :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
min :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
Ord, NumTxIdsToReq -> ()
(NumTxIdsToReq -> ()) -> NFData NumTxIdsToReq
forall a. (a -> ()) -> NFData a
$crnf :: NumTxIdsToReq -> ()
rnf :: NumTxIdsToReq -> ()
NFData, (forall x. NumTxIdsToReq -> Rep NumTxIdsToReq x)
-> (forall x. Rep NumTxIdsToReq x -> NumTxIdsToReq)
-> Generic NumTxIdsToReq
forall x. Rep NumTxIdsToReq x -> NumTxIdsToReq
forall x. NumTxIdsToReq -> Rep NumTxIdsToReq x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NumTxIdsToReq -> Rep NumTxIdsToReq x
from :: forall x. NumTxIdsToReq -> Rep NumTxIdsToReq x
$cto :: forall x. Rep NumTxIdsToReq x -> NumTxIdsToReq
to :: forall x. Rep NumTxIdsToReq x -> NumTxIdsToReq
Generic)
  deriving newtype (Integer -> NumTxIdsToReq
NumTxIdsToReq -> NumTxIdsToReq
NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
(NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq)
-> (Integer -> NumTxIdsToReq)
-> Num NumTxIdsToReq
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
+ :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$c- :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
- :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$c* :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
* :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$cnegate :: NumTxIdsToReq -> NumTxIdsToReq
negate :: NumTxIdsToReq -> NumTxIdsToReq
$cabs :: NumTxIdsToReq -> NumTxIdsToReq
abs :: NumTxIdsToReq -> NumTxIdsToReq
$csignum :: NumTxIdsToReq -> NumTxIdsToReq
signum :: NumTxIdsToReq -> NumTxIdsToReq
$cfromInteger :: Integer -> NumTxIdsToReq
fromInteger :: Integer -> NumTxIdsToReq
Num, Int -> NumTxIdsToReq
NumTxIdsToReq -> Int
NumTxIdsToReq -> [NumTxIdsToReq]
NumTxIdsToReq -> NumTxIdsToReq
NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
(NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq)
-> (Int -> NumTxIdsToReq)
-> (NumTxIdsToReq -> Int)
-> (NumTxIdsToReq -> [NumTxIdsToReq])
-> (NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq])
-> (NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq])
-> (NumTxIdsToReq
    -> NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq])
-> Enum NumTxIdsToReq
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: NumTxIdsToReq -> NumTxIdsToReq
succ :: NumTxIdsToReq -> NumTxIdsToReq
$cpred :: NumTxIdsToReq -> NumTxIdsToReq
pred :: NumTxIdsToReq -> NumTxIdsToReq
$ctoEnum :: Int -> NumTxIdsToReq
toEnum :: Int -> NumTxIdsToReq
$cfromEnum :: NumTxIdsToReq -> Int
fromEnum :: NumTxIdsToReq -> Int
$cenumFrom :: NumTxIdsToReq -> [NumTxIdsToReq]
enumFrom :: NumTxIdsToReq -> [NumTxIdsToReq]
$cenumFromThen :: NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
enumFromThen :: NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
$cenumFromTo :: NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
enumFromTo :: NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
$cenumFromThenTo :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
enumFromThenTo :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq -> [NumTxIdsToReq]
Enum, Num NumTxIdsToReq
Ord NumTxIdsToReq
(Num NumTxIdsToReq, Ord NumTxIdsToReq) =>
(NumTxIdsToReq -> Rational) -> Real NumTxIdsToReq
NumTxIdsToReq -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: NumTxIdsToReq -> Rational
toRational :: NumTxIdsToReq -> Rational
Real, Enum NumTxIdsToReq
Real NumTxIdsToReq
(Real NumTxIdsToReq, Enum NumTxIdsToReq) =>
(NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NumTxIdsToReq
    -> NumTxIdsToReq -> (NumTxIdsToReq, NumTxIdsToReq))
-> (NumTxIdsToReq
    -> NumTxIdsToReq -> (NumTxIdsToReq, NumTxIdsToReq))
-> (NumTxIdsToReq -> Integer)
-> Integral NumTxIdsToReq
NumTxIdsToReq -> Integer
NumTxIdsToReq -> NumTxIdsToReq -> (NumTxIdsToReq, NumTxIdsToReq)
NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
quot :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$crem :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
rem :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$cdiv :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
div :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$cmod :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
mod :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$cquotRem :: NumTxIdsToReq -> NumTxIdsToReq -> (NumTxIdsToReq, NumTxIdsToReq)
quotRem :: NumTxIdsToReq -> NumTxIdsToReq -> (NumTxIdsToReq, NumTxIdsToReq)
$cdivMod :: NumTxIdsToReq -> NumTxIdsToReq -> (NumTxIdsToReq, NumTxIdsToReq)
divMod :: NumTxIdsToReq -> NumTxIdsToReq -> (NumTxIdsToReq, NumTxIdsToReq)
$ctoInteger :: NumTxIdsToReq -> Integer
toInteger :: NumTxIdsToReq -> Integer
Integral, NumTxIdsToReq
NumTxIdsToReq -> NumTxIdsToReq -> Bounded NumTxIdsToReq
forall a. a -> a -> Bounded a
$cminBound :: NumTxIdsToReq
minBound :: NumTxIdsToReq
$cmaxBound :: NumTxIdsToReq
maxBound :: NumTxIdsToReq
Bounded, [String] -> NumTxIdsToReq -> IO (Maybe ThunkInfo)
Proxy NumTxIdsToReq -> String
([String] -> NumTxIdsToReq -> IO (Maybe ThunkInfo))
-> ([String] -> NumTxIdsToReq -> IO (Maybe ThunkInfo))
-> (Proxy NumTxIdsToReq -> String)
-> NoThunks NumTxIdsToReq
forall a.
([String] -> a -> IO (Maybe ThunkInfo))
-> ([String] -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: [String] -> NumTxIdsToReq -> IO (Maybe ThunkInfo)
noThunks :: [String] -> NumTxIdsToReq -> IO (Maybe ThunkInfo)
$cwNoThunks :: [String] -> NumTxIdsToReq -> IO (Maybe ThunkInfo)
wNoThunks :: [String] -> NumTxIdsToReq -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy NumTxIdsToReq -> String
showTypeOf :: Proxy NumTxIdsToReq -> String
NoThunks)
  deriving NonEmpty NumTxIdsToReq -> NumTxIdsToReq
NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
(NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> (NonEmpty NumTxIdsToReq -> NumTxIdsToReq)
-> (forall b. Integral b => b -> NumTxIdsToReq -> NumTxIdsToReq)
-> Semigroup NumTxIdsToReq
forall b. Integral b => b -> NumTxIdsToReq -> NumTxIdsToReq
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
<> :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$csconcat :: NonEmpty NumTxIdsToReq -> NumTxIdsToReq
sconcat :: NonEmpty NumTxIdsToReq -> NumTxIdsToReq
$cstimes :: forall b. Integral b => b -> NumTxIdsToReq -> NumTxIdsToReq
stimes :: forall b. Integral b => b -> NumTxIdsToReq -> NumTxIdsToReq
Semigroup via (Sum Word16)
  deriving Semigroup NumTxIdsToReq
NumTxIdsToReq
Semigroup NumTxIdsToReq =>
NumTxIdsToReq
-> (NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq)
-> ([NumTxIdsToReq] -> NumTxIdsToReq)
-> Monoid NumTxIdsToReq
[NumTxIdsToReq] -> NumTxIdsToReq
NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: NumTxIdsToReq
mempty :: NumTxIdsToReq
$cmappend :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
mappend :: NumTxIdsToReq -> NumTxIdsToReq -> NumTxIdsToReq
$cmconcat :: [NumTxIdsToReq] -> NumTxIdsToReq
mconcat :: [NumTxIdsToReq] -> NumTxIdsToReq
Monoid via (Sum Word16)
  deriving Int -> NumTxIdsToReq -> ShowS
[NumTxIdsToReq] -> ShowS
NumTxIdsToReq -> String
(Int -> NumTxIdsToReq -> ShowS)
-> (NumTxIdsToReq -> String)
-> ([NumTxIdsToReq] -> ShowS)
-> Show NumTxIdsToReq
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NumTxIdsToReq -> ShowS
showsPrec :: Int -> NumTxIdsToReq -> ShowS
$cshow :: NumTxIdsToReq -> String
show :: NumTxIdsToReq -> String
$cshowList :: [NumTxIdsToReq] -> ShowS
showList :: [NumTxIdsToReq] -> ShowS
Show via (Quiet NumTxIdsToReq)


-- | There are some constraints of the protocol that are not captured in the
-- types of the messages, but are documented with the messages. Violation
-- of these constraints is also a protocol error. The constraints are intended
-- to ensure that implementations are able to work in bounded space.
--
instance Protocol (TxSubmission2 txid tx) where

  -- | The messages in the transaction submission protocol.
  --
  -- In this protocol the consumer (inbound side, server role) always
  -- initiates and the producer (outbound side, client role) replies.
  -- This makes it a pull based protocol where the receiver manages the
  -- control flow.
  --
  -- The protocol involves asking for transaction identifiers, and then
  -- asking for transactions corresponding to the identifiers of interest.
  --
  -- There are two ways to ask for transaction identifiers, blocking and
  -- non-blocking. They otherwise have the same semantics.
  --
  -- The protocol maintains a notional FIFO of \"outstanding\" transaction
  -- identifiers that have been provided but not yet acknowledged. Only
  -- transactions that are outstanding can be requested: they can be
  -- requested in any order, but at most once. Transaction identifiers are
  -- acknowledged in the same FIFO order they were provided in. The
  -- acknowledgement is included in the same messages used to ask for more
  -- transaction identifiers.
  --
  data Message (TxSubmission2 txid tx) from to where

    MsgInit
      :: Message (TxSubmission2 txid tx) StInit StIdle

    -- | Request a non-empty list of transaction identifiers from the client,
    -- and confirm a number of outstanding transaction identifiers.
    --
    -- With 'TokBlocking' this is a a blocking operation: the response will
    -- always have at least one transaction identifier, and it does not expect
    -- a prompt response: there is no timeout. This covers the case when there
    -- is nothing else to do but wait. For example this covers leaf nodes that
    -- rarely, if ever, create and submit a transaction.
    --
    -- With 'TokNonBlocking' this is a non-blocking operation: the response
    -- may be an empty list and this does expect a prompt response. This
    -- covers high throughput use cases where we wish to pipeline, by
    -- interleaving requests for additional transaction identifiers with
    -- requests for transactions, which requires these requests not block.
    --
    -- The request gives the maximum number of transaction identifiers that
    -- can be accepted in the response. This must be greater than zero in the
    -- 'TokBlocking' case. In the 'TokNonBlocking' case either the numbers
    -- acknowledged or the number requested must be non-zero. In either case,
    -- the number requested must not put the total outstanding over the fixed
    -- protocol limit.
    --
    -- The request also gives the number of outstanding transaction
    -- identifiers that can now be acknowledged. The actual transactions
    -- to acknowledge are known to the peer based on the FIFO order in which
    -- they were provided.
    --
    -- There is no choice about when to use the blocking case versus the
    -- non-blocking case, it depends on whether there are any remaining
    -- unacknowledged transactions (after taking into account the ones
    -- acknowledged in this message):
    --
    -- * The blocking case must be used when there are zero remaining
    --   unacknowledged transactions.
    --
    -- * The non-blocking case must be used when there are non-zero remaining
    --   unacknowledged transactions.
    --
    MsgRequestTxIds
      :: forall (blocking :: StBlockingStyle) txid tx.
         SingBlockingStyle blocking
      -> NumTxIdsToAck -- ^ Acknowledge this number of outstanding txids
      -> NumTxIdsToReq -- ^ Request up to this number of txids.
      -> Message (TxSubmission2 txid tx) StIdle (StTxIds blocking)

    -- | Reply with a list of transaction identifiers for available
    -- transactions, along with the size of each transaction.
    --
    -- The list must not be longer than the maximum number requested.
    --
    -- In the 'StTxIds' 'Blocking' state the list must be non-empty while
    -- in the 'StTxIds' 'NonBlocking' state the list may be empty.
    --
    -- These transactions are added to the notional FIFO of outstanding
    -- transaction identifiers for the protocol.
    --
    -- The order in which these transaction identifiers are returned must be
    -- the order in which they are submitted to the mempool, to preserve
    -- dependent transactions.
    --
    MsgReplyTxIds
      :: BlockingReplyList blocking (txid, SizeInBytes)
      -> Message (TxSubmission2 txid tx) (StTxIds blocking) StIdle

    -- | Request one or more transactions corresponding to the given
    -- transaction identifiers.
    --
    -- While it is the responsibility of the replying peer to keep within
    -- pipelining in-flight limits, the sender must also cooperate by keeping
    -- the total requested across all in-flight requests within the limits.
    --
    -- It is an error to ask for transaction identifiers that were not
    -- previously announced (via 'MsgReplyTxIds').
    --
    -- It is an error to ask for transaction identifiers that are not
    -- outstanding or that were already asked for.
    --
    MsgRequestTxs
      :: [txid]
      -> Message (TxSubmission2 txid tx) StIdle StTxs

    -- | Reply with the requested transactions, or implicitly discard.
    --
    -- Transactions can become invalid between the time the transaction
    -- identifier was sent and the transaction being requested. Invalid
    -- (including committed) transactions do not need to be sent.
    --
    -- Any transaction identifiers requested but not provided in this reply
    -- should be considered as if this peer had never announced them. (Note
    -- that this is no guarantee that the transaction is invalid, it may still
    -- be valid and available from another peer).
    --
    MsgReplyTxs
      :: [tx]
      -> Message (TxSubmission2 txid tx) StTxs StIdle

    -- | Termination message, initiated by the client when the server is
    -- making a blocking call for more transaction identifiers.
    --
    MsgDone
      :: Message (TxSubmission2 txid tx) (StTxIds StBlocking) StDone


  type StateAgency  StInit     = ClientAgency
  type StateAgency (StTxIds b) = ClientAgency
  type StateAgency  StTxs      = ClientAgency
  type StateAgency  StIdle     = ServerAgency
  type StateAgency  StDone     = NobodyAgency

  type StateToken = SingTxSubmission


instance ( NFData txid
         , NFData tx
         ) => NFData (Message (TxSubmission2 txid tx) from to) where
  rnf :: Message (TxSubmission2 txid tx) from to -> ()
rnf Message (TxSubmission2 txid tx) from to
R:MessageTxSubmission2fromto (*) (*) txid tx from to
MsgInit                      = ()
  rnf (MsgRequestTxIds SingBlockingStyle blocking
tkbs NumTxIdsToAck
w1 NumTxIdsToReq
w2) = SingBlockingStyle blocking -> ()
forall a. NFData a => a -> ()
rnf SingBlockingStyle blocking
tkbs () -> () -> ()
forall a b. a -> b -> b
`seq` NumTxIdsToAck -> ()
forall a. NFData a => a -> ()
rnf NumTxIdsToAck
w1 () -> () -> ()
forall a b. a -> b -> b
`seq` NumTxIdsToReq -> ()
forall a. NFData a => a -> ()
rnf NumTxIdsToReq
w2
  rnf (MsgReplyTxIds BlockingReplyList blocking (txid, SizeInBytes)
brl)          = BlockingReplyList blocking (txid, SizeInBytes) -> ()
forall a. NFData a => a -> ()
rnf BlockingReplyList blocking (txid, SizeInBytes)
brl
  rnf (MsgRequestTxs [txid]
txids)        = [txid] -> ()
forall a. NFData a => a -> ()
rnf [txid]
txids
  rnf (MsgReplyTxs [tx]
txs)            = [tx] -> ()
forall a. NFData a => a -> ()
rnf [tx]
txs
  rnf Message (TxSubmission2 txid tx) from to
R:MessageTxSubmission2fromto (*) (*) txid tx from to
MsgDone                      = ()

-- | The value level equivalent of 'BlockingStyle'.
--
-- This is also used in 'MsgRequestTxIds' where it is interpreted (and can be
-- encoded) as a 'Bool' with 'True' for blocking, and 'False' for non-blocking.
--
data SingBlockingStyle (k :: StBlockingStyle) where
  SingBlocking    :: SingBlockingStyle StBlocking
  SingNonBlocking :: SingBlockingStyle StNonBlocking

deriving instance Eq   (SingBlockingStyle b)
deriving instance Show (SingBlockingStyle b)
type instance Sing = SingBlockingStyle
instance SingI StBlocking    where sing :: Sing 'StBlocking
sing = Sing 'StBlocking
SingBlockingStyle 'StBlocking
SingBlocking
instance SingI StNonBlocking where sing :: Sing 'StNonBlocking
sing = Sing 'StNonBlocking
SingBlockingStyle 'StNonBlocking
SingNonBlocking

instance NFData (SingBlockingStyle b) where
  rnf :: SingBlockingStyle b -> ()
rnf SingBlockingStyle b
SingBlocking    = ()
  rnf SingBlockingStyle b
SingNonBlocking = ()

-- | We have requests for lists of things. In the blocking case the
-- corresponding reply must be non-empty, whereas in the non-blocking case
-- and empty reply is fine.
--
data BlockingReplyList (blocking :: StBlockingStyle) a where
  BlockingReply    :: NonEmpty a  -> BlockingReplyList StBlocking    a
  NonBlockingReply ::         [a] -> BlockingReplyList StNonBlocking a

deriving instance Eq   a => Eq   (BlockingReplyList blocking a)
deriving instance Show a => Show (BlockingReplyList blocking a)

instance NFData a => NFData (BlockingReplyList blocking a) where
  rnf :: BlockingReplyList blocking a -> ()
rnf (BlockingReply NonEmpty a
as)    = NonEmpty a -> ()
forall a. NFData a => a -> ()
rnf NonEmpty a
as
  rnf (NonBlockingReply [a]
as) = [a] -> ()
forall a. NFData a => a -> ()
rnf [a]
as

deriving instance (Eq txid, Eq tx) =>
                  Eq (Message (TxSubmission2 txid tx) from to)

deriving instance (Show txid, Show tx) =>
                  Show (Message (TxSubmission2 txid tx) from to)