{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE GADTs               #-}
{-# LANGUAGE KindSignatures      #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}

-- | A view of the transaction submission protocol from the point of view of
-- the server.
--
-- This provides a view that uses less complex types and should be easier to
-- use than the underlying typed protocol itself.
--
-- For execution, a conversion into the typed protocol is provided.
--
module Ouroboros.Network.Protocol.TxSubmission2.Server
  ( -- * Protocol type for the server
    -- | The protocol states from the point of view of the server.
    TxSubmissionServerPipelined (..)
  , ServerStIdle (..)
  , Collect (..)
    -- * Execution as a typed protocol
  , txSubmissionServerPeerPipelined
  ) where

import Data.List.NonEmpty (NonEmpty)

import Network.TypedProtocol.Core
import Network.TypedProtocol.Peer.Server

import Ouroboros.Network.Protocol.TxSubmission2.Type


data TxSubmissionServerPipelined txid tx m a where
  TxSubmissionServerPipelined
    :: m (ServerStIdle              Z txid tx m a)
    ->    TxSubmissionServerPipelined txid tx m a


-- | This is the type of the pipelined results, collected by 'CollectPipelined'.
-- This protocol can pipeline requests for transaction ids and transactions,
-- so we use a sum of either for collecting the responses.
--
data Collect txid tx =
       -- | The result of 'SendMsgRequestTxIdsPipelined'. It also carries
       -- the number of txids originally requested.
       CollectTxIds NumTxIdsToReq [(txid, SizeInBytes)]

       -- | The result of 'SendMsgRequestTxsPipelined'. The actual reply only
       -- contains the transactions sent, but this pairs them up with the
       -- transactions requested. This is because the peer can determine that
       -- some transactions are no longer needed.
     | CollectTxs [txid] [tx]


data ServerStIdle (n :: N) txid tx m a where

  -- |
  --
  SendMsgRequestTxIdsBlocking
    :: NumTxIdsToAck                        -- ^ number of txids to acknowledge
    -> NumTxIdsToReq                        -- ^ number of txids to request
    -> m a                                  -- ^ Result if done
    -> (NonEmpty (txid, SizeInBytes)
        -> m (ServerStIdle Z txid tx m a))
    -> ServerStIdle        Z txid tx m a

  -- |
  --
  SendMsgRequestTxIdsPipelined
    :: NumTxIdsToAck
    -> NumTxIdsToReq
    -> m (ServerStIdle (S n) txid tx m a)
    -> ServerStIdle       n  txid tx m a

  -- |
  --
  SendMsgRequestTxsPipelined
    :: [txid]
    -> m (ServerStIdle (S n) txid tx m a)
    -> ServerStIdle       n  txid tx m a

  -- | Collect a pipelined result.
  --
  CollectPipelined
    :: Maybe                 (ServerStIdle (S n) txid tx m a)
    -> (Collect txid tx -> m (ServerStIdle    n  txid tx m a))
    ->                        ServerStIdle (S n) txid tx m a


-- | Transform a 'TxSubmissionServerPipelined' into a 'PeerPipelined'.
--
txSubmissionServerPeerPipelined
    :: forall txid tx m a.
       Functor m
    => TxSubmissionServerPipelined txid tx m a
    -> ServerPipelined (TxSubmission2 txid tx) StInit m a
txSubmissionServerPeerPipelined :: forall txid tx (m :: * -> *) a.
Functor m =>
TxSubmissionServerPipelined txid tx m a
-> ServerPipelined (TxSubmission2 txid tx) 'StInit m a
txSubmissionServerPeerPipelined (TxSubmissionServerPipelined m (ServerStIdle 'Z txid tx m a)
server) =
    Server
  (TxSubmission2 txid tx)
  ('Pipelined 'Z (Collect txid tx))
  'StInit
  m
  a
-> ServerPipelined (TxSubmission2 txid tx) 'StInit m a
forall ps (st :: ps) (m :: * -> *) a c.
Server ps ('Pipelined 'Z c) st m a -> ServerPipelined ps st m a
ServerPipelined (Server
   (TxSubmission2 txid tx)
   ('Pipelined 'Z (Collect txid tx))
   'StInit
   m
   a
 -> ServerPipelined (TxSubmission2 txid tx) 'StInit m a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined 'Z (Collect txid tx))
     'StInit
     m
     a
-> ServerPipelined (TxSubmission2 txid tx) 'StInit m a
forall a b. (a -> b) -> a -> b
$
      -- We need to assist GHC to infer the existentially quantified `c` as
      -- `Collect txid tx`
      forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Server ps pl st' m a)
-> Server ps pl st m a
Await @_ @(Pipelined Z (Collect txid tx))
            (\Message (TxSubmission2 txid tx) 'StInit st'
R:MessageTxSubmission2fromto (*) (*) txid tx 'StInit st'
MsgInit -> m (Server
     (TxSubmission2 txid tx) ('Pipelined 'Z (Collect txid tx)) st' m a)
-> Server
     (TxSubmission2 txid tx) ('Pipelined 'Z (Collect txid tx)) st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Server ps pl st m a) -> Server ps pl st m a
Effect (ServerStIdle 'Z txid tx m a
-> Server
     (TxSubmission2 txid tx) ('Pipelined 'Z (Collect txid tx)) st' m a
ServerStIdle 'Z txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined 'Z (Collect txid tx))
     'StIdle
     m
     a
forall (n :: N).
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
go (ServerStIdle 'Z txid tx m a
 -> Server
      (TxSubmission2 txid tx) ('Pipelined 'Z (Collect txid tx)) st' m a)
-> m (ServerStIdle 'Z txid tx m a)
-> m (Server
        (TxSubmission2 txid tx) ('Pipelined 'Z (Collect txid tx)) st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ServerStIdle 'Z txid tx m a)
server))
  where
    go :: forall (n :: N).
          ServerStIdle n txid tx m a
       -> Server (TxSubmission2 txid tx) (Pipelined n (Collect txid tx)) StIdle m a

    go :: forall (n :: N).
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
go (SendMsgRequestTxIdsBlocking NumTxIdsToAck
ackNo NumTxIdsToReq
reqNo m a
kDone NonEmpty (txid, SizeInBytes) -> m (ServerStIdle 'Z txid tx m a)
k) =
      Message (TxSubmission2 txid tx) 'StIdle ('StTxIds 'StBlocking)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     ('StTxIds 'StBlocking)
     m
     a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ServerAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Server ps pl st' m a -> Server ps pl st m a
Yield
        (SingBlockingStyle 'StBlocking
-> NumTxIdsToAck
-> NumTxIdsToReq
-> Message (TxSubmission2 txid tx) 'StIdle ('StTxIds 'StBlocking)
forall {k} {k1} (blocking :: StBlockingStyle) (txid :: k)
       (tx :: k1).
SingBlockingStyle blocking
-> NumTxIdsToAck
-> NumTxIdsToReq
-> Message (TxSubmission2 txid tx) 'StIdle ('StTxIds blocking)
MsgRequestTxIds SingBlockingStyle 'StBlocking
SingBlocking NumTxIdsToAck
ackNo NumTxIdsToReq
reqNo) (Server
   (TxSubmission2 txid tx)
   ('Pipelined n (Collect txid tx))
   ('StTxIds 'StBlocking)
   m
   a
 -> Server
      (TxSubmission2 txid tx)
      ('Pipelined n (Collect txid tx))
      'StIdle
      m
      a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     ('StTxIds 'StBlocking)
     m
     a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall a b. (a -> b) -> a -> b
$
      (forall (st' :: TxSubmission2 txid tx).
 Message (TxSubmission2 txid tx) ('StTxIds 'StBlocking) st'
 -> Server
      (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     ('StTxIds 'StBlocking)
     m
     a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Server ps pl st' m a)
-> Server ps pl st m a
Await ((forall (st' :: TxSubmission2 txid tx).
  Message (TxSubmission2 txid tx) ('StTxIds 'StBlocking) st'
  -> Server
       (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
 -> Server
      (TxSubmission2 txid tx)
      ('Pipelined n (Collect txid tx))
      ('StTxIds 'StBlocking)
      m
      a)
-> (forall (st' :: TxSubmission2 txid tx).
    Message (TxSubmission2 txid tx) ('StTxIds 'StBlocking) st'
    -> Server
         (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     ('StTxIds 'StBlocking)
     m
     a
forall a b. (a -> b) -> a -> b
$ \Message (TxSubmission2 txid tx) ('StTxIds 'StBlocking) st'
msg ->
        case Message (TxSubmission2 txid tx) ('StTxIds 'StBlocking) st'
msg of
          Message (TxSubmission2 txid tx) ('StTxIds 'StBlocking) st'
R:MessageTxSubmission2fromto
  (*) (*) txid tx ('StTxIds 'StBlocking) st'
MsgDone ->
            m (Server
     (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
-> Server
     (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Server ps pl st m a) -> Server ps pl st m a
Effect (a
-> Server
     (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'NobodyAgency,
 Outstanding pl ~ 'Z) =>
a -> Server ps pl st m a
Done (a
 -> Server
      (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
-> m a
-> m (Server
        (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
kDone)

          MsgReplyTxIds (BlockingReply NonEmpty (txid1, SizeInBytes)
txids) ->
            m (Server
     (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
-> Server
     (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Server ps pl st m a) -> Server ps pl st m a
Effect (ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall (n :: N).
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
go (ServerStIdle n txid tx m a
 -> Server
      (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
-> m (ServerStIdle n txid tx m a)
-> m (Server
        (TxSubmission2 txid tx) ('Pipelined n (Collect txid tx)) st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (txid, SizeInBytes) -> m (ServerStIdle 'Z txid tx m a)
k NonEmpty (txid, SizeInBytes)
NonEmpty (txid1, SizeInBytes)
txids)

    go (SendMsgRequestTxIdsPipelined NumTxIdsToAck
ackNo NumTxIdsToReq
reqNo m (ServerStIdle ('S n) txid tx m a)
k) =
      Message (TxSubmission2 txid tx) 'StIdle ('StTxIds 'StNonBlocking)
-> Receiver
     (TxSubmission2 txid tx)
     ('StTxIds 'StNonBlocking)
     'StIdle
     m
     (Collect txid tx)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall ps (st :: ps) (n :: N) c (m :: * -> *) a (st' :: ps)
       (st'' :: ps).
(StateTokenI st, StateTokenI st',
 StateAgency st ~ 'ServerAgency) =>
Message ps st st'
-> Receiver ps st' st'' m c
-> Server ps ('Pipelined ('S n) c) st'' m a
-> Server ps ('Pipelined n c) st m a
YieldPipelined
        (SingBlockingStyle 'StNonBlocking
-> NumTxIdsToAck
-> NumTxIdsToReq
-> Message
     (TxSubmission2 txid tx) 'StIdle ('StTxIds 'StNonBlocking)
forall {k} {k1} (blocking :: StBlockingStyle) (txid :: k)
       (tx :: k1).
SingBlockingStyle blocking
-> NumTxIdsToAck
-> NumTxIdsToReq
-> Message (TxSubmission2 txid tx) 'StIdle ('StTxIds blocking)
MsgRequestTxIds SingBlockingStyle 'StNonBlocking
SingNonBlocking NumTxIdsToAck
ackNo NumTxIdsToReq
reqNo)
        ((forall (st' :: TxSubmission2 txid tx).
 Message (TxSubmission2 txid tx) ('StTxIds 'StNonBlocking) st'
 -> Receiver
      (TxSubmission2 txid tx) st' 'StIdle m (Collect txid tx))
-> Receiver
     (TxSubmission2 txid tx)
     ('StTxIds 'StNonBlocking)
     'StIdle
     m
     (Collect txid tx)
forall ps (st :: ps) (stdone :: ps) (m :: * -> *) c.
(StateTokenI st, ActiveState st, StateAgency st ~ 'ClientAgency) =>
(forall (st' :: ps).
 Message ps st st' -> Receiver ps st' stdone m c)
-> Receiver ps st stdone m c
ReceiverAwait ((forall (st' :: TxSubmission2 txid tx).
  Message (TxSubmission2 txid tx) ('StTxIds 'StNonBlocking) st'
  -> Receiver
       (TxSubmission2 txid tx) st' 'StIdle m (Collect txid tx))
 -> Receiver
      (TxSubmission2 txid tx)
      ('StTxIds 'StNonBlocking)
      'StIdle
      m
      (Collect txid tx))
-> (forall (st' :: TxSubmission2 txid tx).
    Message (TxSubmission2 txid tx) ('StTxIds 'StNonBlocking) st'
    -> Receiver
         (TxSubmission2 txid tx) st' 'StIdle m (Collect txid tx))
-> Receiver
     (TxSubmission2 txid tx)
     ('StTxIds 'StNonBlocking)
     'StIdle
     m
     (Collect txid tx)
forall a b. (a -> b) -> a -> b
$ \Message (TxSubmission2 txid tx) ('StTxIds 'StNonBlocking) st'
msg ->
           case Message (TxSubmission2 txid tx) ('StTxIds 'StNonBlocking) st'
msg of
             MsgReplyTxIds (NonBlockingReply [(txid1, SizeInBytes)]
txids) ->
               Collect txid tx
-> Receiver (TxSubmission2 txid tx) st' st' m (Collect txid tx)
forall ps (stdone :: ps) (m :: * -> *) c.
c -> Receiver ps stdone stdone m c
ReceiverDone (NumTxIdsToReq -> [(txid, SizeInBytes)] -> Collect txid tx
forall txid tx.
NumTxIdsToReq -> [(txid, SizeInBytes)] -> Collect txid tx
CollectTxIds NumTxIdsToReq
reqNo [(txid, SizeInBytes)]
[(txid1, SizeInBytes)]
txids))
        (m (Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Server ps pl st m a) -> Server ps pl st m a
Effect (ServerStIdle ('S n) txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
forall (n :: N).
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
go (ServerStIdle ('S n) txid tx m a
 -> Server
      (TxSubmission2 txid tx)
      ('Pipelined ('S n) (Collect txid tx))
      'StIdle
      m
      a)
-> m (ServerStIdle ('S n) txid tx m a)
-> m (Server
        (TxSubmission2 txid tx)
        ('Pipelined ('S n) (Collect txid tx))
        'StIdle
        m
        a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ServerStIdle ('S n) txid tx m a)
k))

    go (SendMsgRequestTxsPipelined [txid]
txids m (ServerStIdle ('S n) txid tx m a)
k) =
      Message (TxSubmission2 txid tx) 'StIdle 'StTxs
-> Receiver
     (TxSubmission2 txid tx) 'StTxs 'StIdle m (Collect txid tx)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall ps (st :: ps) (n :: N) c (m :: * -> *) a (st' :: ps)
       (st'' :: ps).
(StateTokenI st, StateTokenI st',
 StateAgency st ~ 'ServerAgency) =>
Message ps st st'
-> Receiver ps st' st'' m c
-> Server ps ('Pipelined ('S n) c) st'' m a
-> Server ps ('Pipelined n c) st m a
YieldPipelined
        ([txid] -> Message (TxSubmission2 txid tx) 'StIdle 'StTxs
forall {k1} txid1 (tx :: k1).
[txid1] -> Message (TxSubmission2 txid1 tx) 'StIdle 'StTxs
MsgRequestTxs [txid]
txids)
        ((forall (st' :: TxSubmission2 txid tx).
 Message (TxSubmission2 txid tx) 'StTxs st'
 -> Receiver
      (TxSubmission2 txid tx) st' 'StIdle m (Collect txid tx))
-> Receiver
     (TxSubmission2 txid tx) 'StTxs 'StIdle m (Collect txid tx)
forall ps (st :: ps) (stdone :: ps) (m :: * -> *) c.
(StateTokenI st, ActiveState st, StateAgency st ~ 'ClientAgency) =>
(forall (st' :: ps).
 Message ps st st' -> Receiver ps st' stdone m c)
-> Receiver ps st stdone m c
ReceiverAwait ((forall (st' :: TxSubmission2 txid tx).
  Message (TxSubmission2 txid tx) 'StTxs st'
  -> Receiver
       (TxSubmission2 txid tx) st' 'StIdle m (Collect txid tx))
 -> Receiver
      (TxSubmission2 txid tx) 'StTxs 'StIdle m (Collect txid tx))
-> (forall (st' :: TxSubmission2 txid tx).
    Message (TxSubmission2 txid tx) 'StTxs st'
    -> Receiver
         (TxSubmission2 txid tx) st' 'StIdle m (Collect txid tx))
-> Receiver
     (TxSubmission2 txid tx) 'StTxs 'StIdle m (Collect txid tx)
forall a b. (a -> b) -> a -> b
$ \Message (TxSubmission2 txid tx) 'StTxs st'
msg ->
           case Message (TxSubmission2 txid tx) 'StTxs st'
msg of
             MsgReplyTxs [tx1]
txs -> Collect txid tx
-> Receiver (TxSubmission2 txid tx) st' st' m (Collect txid tx)
forall ps (stdone :: ps) (m :: * -> *) c.
c -> Receiver ps stdone stdone m c
ReceiverDone ([txid] -> [tx] -> Collect txid tx
forall txid tx. [txid] -> [tx] -> Collect txid tx
CollectTxs [txid]
txids [tx]
[tx1]
txs))
        (m (Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Server ps pl st m a) -> Server ps pl st m a
Effect (ServerStIdle ('S n) txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
forall (n :: N).
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
go (ServerStIdle ('S n) txid tx m a
 -> Server
      (TxSubmission2 txid tx)
      ('Pipelined ('S n) (Collect txid tx))
      'StIdle
      m
      a)
-> m (ServerStIdle ('S n) txid tx m a)
-> m (Server
        (TxSubmission2 txid tx)
        ('Pipelined ('S n) (Collect txid tx))
        'StIdle
        m
        a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ServerStIdle ('S n) txid tx m a)
k))

    go (CollectPipelined Maybe (ServerStIdle ('S n) txid tx m a)
mNone Collect txid tx -> m (ServerStIdle n txid tx m a)
collect) =
      Maybe
  (Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a)
-> (Collect txid tx
    -> Server
         (TxSubmission2 txid tx)
         ('Pipelined n (Collect txid tx))
         'StIdle
         m
         a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
forall ps (st :: ps) (n :: N) c (m :: * -> *) a.
(StateTokenI st, ActiveState st) =>
Maybe (Server ps ('Pipelined ('S n) c) st m a)
-> (c -> Server ps ('Pipelined n c) st m a)
-> Server ps ('Pipelined ('S n) c) st m a
Collect ((ServerStIdle ('S n) txid tx m a
 -> Server
      (TxSubmission2 txid tx)
      ('Pipelined ('S n) (Collect txid tx))
      'StIdle
      m
      a)
-> Maybe (ServerStIdle ('S n) txid tx m a)
-> Maybe
     (Server
        (TxSubmission2 txid tx)
        ('Pipelined ('S n) (Collect txid tx))
        'StIdle
        m
        a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ServerStIdle ('S n) txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined ('S n) (Collect txid tx))
     'StIdle
     m
     a
forall (n :: N).
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
go Maybe (ServerStIdle ('S n) txid tx m a)
mNone)
              (m (Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a)
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Server ps pl st m a) -> Server ps pl st m a
Effect (m (Server
      (TxSubmission2 txid tx)
      ('Pipelined n (Collect txid tx))
      'StIdle
      m
      a)
 -> Server
      (TxSubmission2 txid tx)
      ('Pipelined n (Collect txid tx))
      'StIdle
      m
      a)
-> (Collect txid tx
    -> m (Server
            (TxSubmission2 txid tx)
            ('Pipelined n (Collect txid tx))
            'StIdle
            m
            a))
-> Collect txid tx
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ServerStIdle n txid tx m a
 -> Server
      (TxSubmission2 txid tx)
      ('Pipelined n (Collect txid tx))
      'StIdle
      m
      a)
-> m (ServerStIdle n txid tx m a)
-> m (Server
        (TxSubmission2 txid tx)
        ('Pipelined n (Collect txid tx))
        'StIdle
        m
        a)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
forall (n :: N).
ServerStIdle n txid tx m a
-> Server
     (TxSubmission2 txid tx)
     ('Pipelined n (Collect txid tx))
     'StIdle
     m
     a
go (m (ServerStIdle n txid tx m a)
 -> m (Server
         (TxSubmission2 txid tx)
         ('Pipelined n (Collect txid tx))
         'StIdle
         m
         a))
-> (Collect txid tx -> m (ServerStIdle n txid tx m a))
-> Collect txid tx
-> m (Server
        (TxSubmission2 txid tx)
        ('Pipelined n (Collect txid tx))
        'StIdle
        m
        a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Collect txid tx -> m (ServerStIdle n txid tx m a)
collect)