{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE GADTs               #-}
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE ScopedTypeVariables #-}


-- | A view of the transaction monitor protocol from the point of view of
-- the client.
--
-- This provides simple access to the local mempool snapshots, to allow building
-- more monitoring logic from the client side after submitting transactions.
--
-- For execution, 'localTxMonitorClientPeer' is provided for conversion
-- into the typed protocol.
--
module Ouroboros.Network.Protocol.LocalTxMonitor.Client
  ( -- * Protocol type for the client
    -- | The protocol states from the point of view of the client.
    LocalTxMonitorClient (..)
  , ClientStIdle (..)
  , ClientStAcquired (..)
    -- * Execution as a typed protocol
  , localTxMonitorClientPeer
  ) where

import Network.TypedProtocol.Core
import Network.TypedProtocol.Peer.Client

import Ouroboros.Network.Protocol.LocalTxMonitor.Type

-- | A tx monitor client, on top of some effect 'm'.
--
newtype LocalTxMonitorClient txid tx slot m a = LocalTxMonitorClient {
      forall txid tx slot (m :: * -> *) a.
LocalTxMonitorClient txid tx slot m a
-> m (ClientStIdle txid tx slot m a)
runLocalTxMonitorClient :: m (ClientStIdle txid tx slot m a)
    }

-- | In the 'StIdle' protocol state, the client has agency and can proceed to
-- acquire a mempool snapshot, or end the protocol.
--
data ClientStIdle txid tx slot m a where

  -- | Send the 'MsgAcquire', with handlers for the replies.
  --
  -- This request cannot timeout and cannot fail, it'll acquire the latest
  -- mempool snapshot available on the server and hang on to it. This allows to
  -- run any subsequent queries against the same view of the mempool.
  --
  -- The snapshot is acquired for a particular slot number which materializes
  -- the 'virtual block' under construction.
  --
  SendMsgAcquire
    :: (slot -> m (ClientStAcquired txid tx slot m a))
    -> ClientStIdle txid tx slot m a

  -- | The client decided to end the protocol
  --
  SendMsgDone
    :: a
    -> ClientStIdle txid tx slot m a

-- | In the 'StAcquired' protocol state, the client has agency and can query the
-- server against the acquired snapshot. Alternatively, it can also (re)acquire
-- a more recent snapshot.
--
data ClientStAcquired txid tx slot m a where
  -- | The mempool is modeled as an ordered list of transactions and thus, can
  -- be traversed linearly. 'MsgNextTx' requests the next transaction from the
  -- current list. This must be a transaction that was not previously sent to
  -- the client for this particular snapshot.
  --
  SendMsgNextTx
    :: (Maybe tx -> m (ClientStAcquired txid tx slot m a))
    -> ClientStAcquired txid tx slot m a

  -- | For some cases where clients do not wish to traverse the entire mempool
  -- but look for a specific transaction, they can assess the presence of such
  -- transaction directly. Note that, the absence of a transaction does not
  -- imply anything about how the transaction was processed: it may have been
  -- dropped, or inserted in a block. 'False' simply means that it is no longer
  -- in the mempool.
  --
  SendMsgHasTx
    :: txid
    -> (Bool -> m (ClientStAcquired txid tx slot m a))
    -> ClientStAcquired txid tx slot m a

  -- | Ask the server about the current mempool's capacity and sizes. This is
  -- fixed in a given snapshot.
  SendMsgGetSizes
    :: (MempoolSizeAndCapacity -> m (ClientStAcquired txid tx slot m a))
    -> ClientStAcquired txid tx slot m a

  -- | Await for a new snapshot and acquire it.
  --
  SendMsgAwaitAcquire
    :: (slot ->  m (ClientStAcquired txid tx slot m a))
    -> ClientStAcquired txid tx slot m a

  -- | Release the acquired snapshot, in order to loop back to the idle state.
  --
  SendMsgRelease
    :: m (ClientStIdle txid tx slot m a)
    -> ClientStAcquired txid tx slot m a

-- | Interpret a 'LocalTxMonitorClient' action sequence as a 'Peer' on the
-- client-side of the 'LocalTxMonitor' protocol.
--
localTxMonitorClientPeer ::
     forall txid tx slot m a.
     ( Monad m
     )
  => LocalTxMonitorClient txid tx slot m a
  -> Client (LocalTxMonitor txid tx slot) NonPipelined StIdle m a
localTxMonitorClientPeer :: forall txid tx slot (m :: * -> *) a.
Monad m =>
LocalTxMonitorClient txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
localTxMonitorClientPeer (LocalTxMonitorClient m (ClientStIdle txid tx slot m a)
mClient) =
    m (Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> m (Client
        (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
forall a b. (a -> b) -> a -> b
$ ClientStIdle txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
handleStIdle (ClientStIdle txid tx slot m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> m (ClientStIdle txid tx slot m a)
-> m (Client
        (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ClientStIdle txid tx slot m a)
mClient
  where
    handleStIdle ::
         ClientStIdle txid tx slot m a
      -> Client (LocalTxMonitor txid tx slot) NonPipelined StIdle m a
    handleStIdle :: ClientStIdle txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
handleStIdle = \case
      SendMsgAcquire slot -> m (ClientStAcquired txid tx slot m a)
stAcquired ->
        Message (LocalTxMonitor txid tx slot) 'StIdle 'StAcquiring
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message (LocalTxMonitor txid tx slot) 'StIdle 'StAcquiring
forall {k} {k1} {k2} (txid :: k) (tx :: k1) (slot :: k2).
Message (LocalTxMonitor txid tx slot) 'StIdle 'StAcquiring
MsgAcquire (Client
   (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
forall a b. (a -> b) -> a -> b
$
          (forall (st' :: LocalTxMonitor txid tx slot).
 Message (LocalTxMonitor txid tx slot) 'StAcquiring st'
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ServerAgency,
 Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Client ps pl st' m a)
-> Client ps pl st m a
Await ((forall (st' :: LocalTxMonitor txid tx slot).
  Message (LocalTxMonitor txid tx slot) 'StAcquiring st'
  -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a)
-> (forall (st' :: LocalTxMonitor txid tx slot).
    Message (LocalTxMonitor txid tx slot) 'StAcquiring st'
    -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
forall a b. (a -> b) -> a -> b
$ \case
            MsgAcquired slot1
slot -> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall a b. (a -> b) -> a -> b
$ ClientStAcquired txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
ClientStAcquired txid tx slot m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
handleStAcquired (ClientStAcquired txid tx slot m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (ClientStAcquired txid tx slot m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> slot -> m (ClientStAcquired txid tx slot m a)
stAcquired slot
slot1
slot
      SendMsgDone a
a ->
        Message (LocalTxMonitor txid tx slot) 'StIdle 'StDone
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StDone m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message (LocalTxMonitor txid tx slot) 'StIdle 'StDone
forall {k} {k1} {k2} (txid :: k) (tx :: k1) (slot :: k2).
Message (LocalTxMonitor txid tx slot) 'StIdle 'StDone
MsgDone (a -> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StDone m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'NobodyAgency,
 Outstanding pl ~ 'Z) =>
a -> Client ps pl st m a
Done a
a)

    handleStAcquired ::
         ClientStAcquired txid tx slot m a
      -> Client (LocalTxMonitor txid tx slot) NonPipelined StAcquired m a
    handleStAcquired :: ClientStAcquired txid tx slot m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
handleStAcquired = \case
      SendMsgNextTx Maybe tx -> m (ClientStAcquired txid tx slot m a)
stAcquired ->
        Message (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'NextTx)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'NextTx) m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'NextTx)
forall {k} {k1} {k2} (txid :: k) (tx :: k1) (slot :: k2).
Message (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'NextTx)
MsgNextTx (Client
   (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'NextTx) m a
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'NextTx) m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall a b. (a -> b) -> a -> b
$
          (forall (st' :: LocalTxMonitor txid tx slot).
 Message (LocalTxMonitor txid tx slot) ('StBusy 'NextTx) st'
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'NextTx) m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ServerAgency,
 Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Client ps pl st' m a)
-> Client ps pl st m a
Await ((forall (st' :: LocalTxMonitor txid tx slot).
  Message (LocalTxMonitor txid tx slot) ('StBusy 'NextTx) st'
  -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'NextTx) m a)
-> (forall (st' :: LocalTxMonitor txid tx slot).
    Message (LocalTxMonitor txid tx slot) ('StBusy 'NextTx) st'
    -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'NextTx) m a
forall a b. (a -> b) -> a -> b
$ \case
            MsgReplyNextTx Maybe tx1
tx ->
              m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall a b. (a -> b) -> a -> b
$ ClientStAcquired txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
ClientStAcquired txid tx slot m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
handleStAcquired (ClientStAcquired txid tx slot m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (ClientStAcquired txid tx slot m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe tx -> m (ClientStAcquired txid tx slot m a)
stAcquired Maybe tx
Maybe tx1
tx
      SendMsgHasTx txid
txid Bool -> m (ClientStAcquired txid tx slot m a)
stAcquired ->
        Message (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'HasTx)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'HasTx) m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield (txid
-> Message
     (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'HasTx)
forall {k1} {k2} txid1 (tx :: k1) (slot :: k2).
txid1
-> Message
     (LocalTxMonitor txid1 tx slot) 'StAcquired ('StBusy 'HasTx)
MsgHasTx txid
txid) (Client
   (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'HasTx) m a
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'HasTx) m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall a b. (a -> b) -> a -> b
$
          (forall (st' :: LocalTxMonitor txid tx slot).
 Message (LocalTxMonitor txid tx slot) ('StBusy 'HasTx) st'
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'HasTx) m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ServerAgency,
 Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Client ps pl st' m a)
-> Client ps pl st m a
Await ((forall (st' :: LocalTxMonitor txid tx slot).
  Message (LocalTxMonitor txid tx slot) ('StBusy 'HasTx) st'
  -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'HasTx) m a)
-> (forall (st' :: LocalTxMonitor txid tx slot).
    Message (LocalTxMonitor txid tx slot) ('StBusy 'HasTx) st'
    -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'HasTx) m a
forall a b. (a -> b) -> a -> b
$ \case
            MsgReplyHasTx Bool
res ->
              m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall a b. (a -> b) -> a -> b
$ ClientStAcquired txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
ClientStAcquired txid tx slot m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
handleStAcquired (ClientStAcquired txid tx slot m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (ClientStAcquired txid tx slot m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> m (ClientStAcquired txid tx slot m a)
stAcquired Bool
res
      SendMsgGetSizes MempoolSizeAndCapacity -> m (ClientStAcquired txid tx slot m a)
stAcquired ->
        Message
  (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'GetSizes)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'GetSizes) m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message
  (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'GetSizes)
forall {k} {k1} {k2} (txid :: k) (tx :: k1) (slot :: k2).
Message
  (LocalTxMonitor txid tx slot) 'StAcquired ('StBusy 'GetSizes)
MsgGetSizes (Client
   (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'GetSizes) m a
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'GetSizes) m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall a b. (a -> b) -> a -> b
$
          (forall (st' :: LocalTxMonitor txid tx slot).
 Message (LocalTxMonitor txid tx slot) ('StBusy 'GetSizes) st'
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'GetSizes) m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ServerAgency,
 Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Client ps pl st' m a)
-> Client ps pl st m a
Await ((forall (st' :: LocalTxMonitor txid tx slot).
  Message (LocalTxMonitor txid tx slot) ('StBusy 'GetSizes) st'
  -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client
      (LocalTxMonitor txid tx slot)
      'NonPipelined
      ('StBusy 'GetSizes)
      m
      a)
-> (forall (st' :: LocalTxMonitor txid tx slot).
    Message (LocalTxMonitor txid tx slot) ('StBusy 'GetSizes) st'
    -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined ('StBusy 'GetSizes) m a
forall a b. (a -> b) -> a -> b
$ \case
            MsgReplyGetSizes MempoolSizeAndCapacity
sizes ->
              m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall a b. (a -> b) -> a -> b
$ ClientStAcquired txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
ClientStAcquired txid tx slot m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
handleStAcquired (ClientStAcquired txid tx slot m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (ClientStAcquired txid tx slot m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MempoolSizeAndCapacity -> m (ClientStAcquired txid tx slot m a)
stAcquired MempoolSizeAndCapacity
sizes
      SendMsgAwaitAcquire slot -> m (ClientStAcquired txid tx slot m a)
stAcquired ->
        Message (LocalTxMonitor txid tx slot) 'StAcquired 'StAcquiring
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message (LocalTxMonitor txid tx slot) 'StAcquired 'StAcquiring
forall {k} {k1} {k2} (txid :: k) (tx :: k1) (slot :: k2).
Message (LocalTxMonitor txid tx slot) 'StAcquired 'StAcquiring
MsgAwaitAcquire (Client
   (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall a b. (a -> b) -> a -> b
$
          (forall (st' :: LocalTxMonitor txid tx slot).
 Message (LocalTxMonitor txid tx slot) 'StAcquiring st'
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
(StateTokenI st, StateAgency st ~ 'ServerAgency,
 Outstanding pl ~ 'Z) =>
(forall (st' :: ps). Message ps st st' -> Client ps pl st' m a)
-> Client ps pl st m a
Await ((forall (st' :: LocalTxMonitor txid tx slot).
  Message (LocalTxMonitor txid tx slot) 'StAcquiring st'
  -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a)
-> (forall (st' :: LocalTxMonitor txid tx slot).
    Message (LocalTxMonitor txid tx slot) 'StAcquiring st'
    -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquiring m a
forall a b. (a -> b) -> a -> b
$ \case
            MsgAcquired slot1
slot ->
              m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
forall a b. (a -> b) -> a -> b
$ ClientStAcquired txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a
ClientStAcquired txid tx slot m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
handleStAcquired (ClientStAcquired txid tx slot m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
-> m (ClientStAcquired txid tx slot m a)
-> m (Client (LocalTxMonitor txid tx slot) 'NonPipelined st' m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> slot -> m (ClientStAcquired txid tx slot m a)
stAcquired slot
slot1
slot
      SendMsgRelease m (ClientStIdle txid tx slot m a)
stIdle ->
        Message (LocalTxMonitor txid tx slot) 'StAcquired 'StIdle
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a
       (st' :: ps).
(StateTokenI st, StateTokenI st', StateAgency st ~ 'ClientAgency,
 Outstanding pl ~ 'Z) =>
Message ps st st' -> Client ps pl st' m a -> Client ps pl st m a
Yield Message (LocalTxMonitor txid tx slot) 'StAcquired 'StIdle
forall {k} {k1} {k2} (txid :: k) (tx :: k1) (slot :: k2).
Message (LocalTxMonitor txid tx slot) 'StAcquired 'StIdle
MsgRelease (Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
 -> Client
      (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
-> Client
     (LocalTxMonitor txid tx slot) 'NonPipelined 'StAcquired m a
forall a b. (a -> b) -> a -> b
$
          m (Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
forall ps (pl :: IsPipelined) (st :: ps) (m :: * -> *) a.
m (Client ps pl st m a) -> Client ps pl st m a
Effect (m (Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> m (Client
        (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
forall a b. (a -> b) -> a -> b
$ ClientStIdle txid tx slot m a
-> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a
handleStIdle (ClientStIdle txid tx slot m a
 -> Client (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
-> m (ClientStIdle txid tx slot m a)
-> m (Client
        (LocalTxMonitor txid tx slot) 'NonPipelined 'StIdle m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ClientStIdle txid tx slot m a)
stIdle