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

-- | The node's LeiosFetch client and server, and what the node-to-node wiring
-- needs to run them.
module Ouroboros.Consensus.Network.NodeToNode.LeiosFetch
  ( leiosFetchClient
  , leiosFetchMiniProtocol
  , leiosFetchServer
  , catchAndRethrow
  ) where

import Cardano.Network.NodeToNode (addSafetyMargin)
import Cardano.Network.PeerSelection (PeerTrustable)
import Control.Tracer (Tracer, traceWith)
import qualified Data.ByteString as BS
import qualified Data.IntSet as IntSet
import qualified Data.Vector.Strict as V
import Ouroboros.Consensus.Leios.Types
  ( EndorserBlock
  , LeiosPoint (..)
  , LeiosTx (..)
  , mkEndorserBlock
  )
import Ouroboros.Consensus.MiniProtocol.LeiosFetch.Client
  ( LeiosFetchClientPeer
  , leiosFetchClientPeerIdle
  )
import Ouroboros.Consensus.MiniProtocol.LeiosFetch.Server
  ( ExnLeiosInvalidRequest (..)
  , LeiosFetchRequestHandler (..)
  , LeiosFetchServerPeer
  , leiosFetchServerPeer
  )
import Ouroboros.Consensus.MiniProtocol.LeiosFetch.Trace (TraceLeiosFetchServerEvent (..))
import Ouroboros.Consensus.MiniProtocol.LeiosFetch.Type
  ( Message (..)
  , TxBitmaps
  , bitmapOffsets
  )
import Ouroboros.Consensus.Network.LeiosFetch (leiosFetchMiniProtocolNum, maxLeiosFetchIngressBytes)
import Ouroboros.Consensus.Storage.LeiosDB.API (LeiosDbReader (..))
import Ouroboros.Consensus.Util.IOLike
  ( Exception
  , MonadCatch (..)
  , MonadSTM (..)
  , MonadThrow (..)
  )
import Ouroboros.Network.ControlMessage (ControlMessage (..), ControlMessageSTM)
import Ouroboros.Network.Mux
  ( MiniProtocol (..)
  , MiniProtocolLimits (..)
  , MiniProtocolWithExpandedCtx
  , RunMiniProtocolWithExpandedCtx
  , StartOnDemandOrEagerly (..)
  )

-- | The node's LeiosFetch client, which requests nothing yet and ends when the
-- node demotes the peer.
leiosFetchClient ::
  MonadSTM m =>
  ControlMessageSTM m ->
  LeiosFetchClientPeer LeiosPoint EndorserBlock LeiosTx m ()
leiosFetchClient :: forall (m :: * -> *).
MonadSTM m =>
ControlMessageSTM m
-> LeiosFetchClientPeer LeiosPoint EndorserBlock LeiosTx m ()
leiosFetchClient ControlMessageSTM m
controlMessageSTM =
  STM m ()
-> LeiosFetchClientPeer LeiosPoint EndorserBlock LeiosTx m ()
forall (m :: * -> *) a point eb tx.
MonadSTM m =>
STM m a -> LeiosFetchClientPeer point eb tx m a
leiosFetchClientPeerIdle (STM m ()
 -> LeiosFetchClientPeer LeiosPoint EndorserBlock LeiosTx m ())
-> STM m ()
-> LeiosFetchClientPeer LeiosPoint EndorserBlock LeiosTx m ()
forall a b. (a -> b) -> a -> b
$
    ControlMessageSTM m
controlMessageSTM ControlMessageSTM m -> (ControlMessage -> STM m ()) -> STM m ()
forall a b. STM m a -> (a -> STM m b) -> STM m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      ControlMessage
Continue -> STM m ()
forall a. STM m a
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
      ControlMessage
Quiesce -> STM m ()
forall a. STM m a
forall (m :: * -> *) a. MonadSTM m => STM m a
retry
      ControlMessage
Terminate -> () -> STM m ()
forall a. a -> STM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | The node's LeiosFetch server, which serves endorser blocks and their
-- transactions from the LeiosDB, through the connection's own reader.
leiosFetchServer ::
  MonadCatch m =>
  Tracer m TraceLeiosFetchServerEvent ->
  LeiosDbReader m ->
  LeiosFetchServerPeer LeiosPoint EndorserBlock LeiosTx m ()
leiosFetchServer :: forall (m :: * -> *).
MonadCatch m =>
Tracer m TraceLeiosFetchServerEvent
-> LeiosDbReader m
-> LeiosFetchServerPeer LeiosPoint EndorserBlock LeiosTx m ()
leiosFetchServer Tracer m TraceLeiosFetchServerEvent
tracer LeiosDbReader m
reader =
  LeiosFetchRequestHandler LeiosPoint EndorserBlock LeiosTx m
-> LeiosFetchServerPeer LeiosPoint EndorserBlock LeiosTx m ()
forall point eb tx (m :: * -> *).
Functor m =>
LeiosFetchRequestHandler point eb tx m
-> LeiosFetchServerPeer point eb tx m ()
leiosFetchServerPeer (LeiosFetchRequestHandler LeiosPoint EndorserBlock LeiosTx m
 -> LeiosFetchServerPeer LeiosPoint EndorserBlock LeiosTx m ())
-> LeiosFetchRequestHandler LeiosPoint EndorserBlock LeiosTx m
-> LeiosFetchServerPeer LeiosPoint EndorserBlock LeiosTx m ()
forall a b. (a -> b) -> a -> b
$ (forall (st :: LeiosFetchBusy LeiosPoint EndorserBlock LeiosTx).
 Message
   (LeiosFetch LeiosPoint EndorserBlock LeiosTx) 'StIdle ('StBusy st)
 -> m (Message
         (LeiosFetch LeiosPoint EndorserBlock LeiosTx)
         ('StBusy st)
         'StIdle))
-> LeiosFetchRequestHandler LeiosPoint EndorserBlock LeiosTx m
forall point eb tx (m :: * -> *).
(forall (st :: LeiosFetchBusy point eb tx).
 Message (LeiosFetch point eb tx) 'StIdle ('StBusy st)
 -> m (Message (LeiosFetch point eb tx) ('StBusy st) 'StIdle))
-> LeiosFetchRequestHandler point eb tx m
MkLeiosFetchRequestHandler ((forall (st :: LeiosFetchBusy LeiosPoint EndorserBlock LeiosTx).
  Message
    (LeiosFetch LeiosPoint EndorserBlock LeiosTx) 'StIdle ('StBusy st)
  -> m (Message
          (LeiosFetch LeiosPoint EndorserBlock LeiosTx)
          ('StBusy st)
          'StIdle))
 -> LeiosFetchRequestHandler LeiosPoint EndorserBlock LeiosTx m)
-> (forall (st :: LeiosFetchBusy LeiosPoint EndorserBlock LeiosTx).
    Message
      (LeiosFetch LeiosPoint EndorserBlock LeiosTx) 'StIdle ('StBusy st)
    -> m (Message
            (LeiosFetch LeiosPoint EndorserBlock LeiosTx)
            ('StBusy st)
            'StIdle))
-> LeiosFetchRequestHandler LeiosPoint EndorserBlock LeiosTx m
forall a b. (a -> b) -> a -> b
$ \case
    MsgLeiosBlockRequest LeiosPoint
point ->
      (EndorserBlock
 -> Message
      (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle)
-> m EndorserBlock
-> m (Message
        (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap EndorserBlock
-> Message
     (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle
EndorserBlock
-> Message
     (LeiosFetch LeiosPoint EndorserBlock LeiosTx)
     ('StBusy 'StBlock)
     'StIdle
forall eb point tx.
eb -> Message (LeiosFetch point eb tx) ('StBusy 'StBlock) 'StIdle
MsgLeiosBlock (m EndorserBlock
 -> m (Message
         (LeiosFetch LeiosPoint EndorserBlock LeiosTx)
         ('StBusy st)
         'StIdle))
-> m EndorserBlock
-> m (Message
        (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle)
forall a b. (a -> b) -> a -> b
$
        Tracer m TraceLeiosFetchServerEvent
-> (ExnLeiosInvalidRequest -> TraceLeiosFetchServerEvent)
-> m EndorserBlock
-> m EndorserBlock
forall (m :: * -> *) e ev a.
(MonadCatch m, Exception e) =>
Tracer m ev -> (e -> ev) -> m a -> m a
catchAndRethrow Tracer m TraceLeiosFetchServerEvent
tracer ExnLeiosInvalidRequest -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerInvalidRequest (m EndorserBlock -> m EndorserBlock)
-> m EndorserBlock -> m EndorserBlock
forall a b. (a -> b) -> a -> b
$
          Tracer m TraceLeiosFetchServerEvent
-> (LeiosDbException -> TraceLeiosFetchServerEvent)
-> m EndorserBlock
-> m EndorserBlock
forall (m :: * -> *) e ev a.
(MonadCatch m, Exception e) =>
Tracer m ev -> (e -> ev) -> m a -> m a
catchAndRethrow Tracer m TraceLeiosFetchServerEvent
tracer (LeiosPoint -> LeiosDbException -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerBlockDbFailure LeiosPoint
point) (m EndorserBlock -> m EndorserBlock)
-> m EndorserBlock -> m EndorserBlock
forall a b. (a -> b) -> a -> b
$
            Tracer m TraceLeiosFetchServerEvent
-> LeiosDbReader m -> LeiosPoint -> m EndorserBlock
forall (m :: * -> *).
MonadThrow m =>
Tracer m TraceLeiosFetchServerEvent
-> LeiosDbReader m -> LeiosPoint -> m EndorserBlock
serveEb Tracer m TraceLeiosFetchServerEvent
tracer LeiosDbReader m
reader LeiosPoint
point
    MsgLeiosBlockTxsRequest LeiosPoint
point TxBitmaps
bitmaps ->
      (Vector LeiosTx
 -> Message
      (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle)
-> m (Vector LeiosTx)
-> m (Message
        (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector LeiosTx
-> Message
     (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle
Vector LeiosTx
-> Message
     (LeiosFetch LeiosPoint EndorserBlock LeiosTx)
     ('StBusy 'StBlockTxs)
     'StIdle
forall tx point eb.
Vector tx
-> Message (LeiosFetch point eb tx) ('StBusy 'StBlockTxs) 'StIdle
MsgLeiosBlockTxs (m (Vector LeiosTx)
 -> m (Message
         (LeiosFetch LeiosPoint EndorserBlock LeiosTx)
         ('StBusy st)
         'StIdle))
-> m (Vector LeiosTx)
-> m (Message
        (LeiosFetch LeiosPoint EndorserBlock LeiosTx) ('StBusy st) 'StIdle)
forall a b. (a -> b) -> a -> b
$
        Tracer m TraceLeiosFetchServerEvent
-> (ExnLeiosInvalidRequest -> TraceLeiosFetchServerEvent)
-> m (Vector LeiosTx)
-> m (Vector LeiosTx)
forall (m :: * -> *) e ev a.
(MonadCatch m, Exception e) =>
Tracer m ev -> (e -> ev) -> m a -> m a
catchAndRethrow Tracer m TraceLeiosFetchServerEvent
tracer ExnLeiosInvalidRequest -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerInvalidRequest (m (Vector LeiosTx) -> m (Vector LeiosTx))
-> m (Vector LeiosTx) -> m (Vector LeiosTx)
forall a b. (a -> b) -> a -> b
$
          Tracer m TraceLeiosFetchServerEvent
-> (LeiosDbException -> TraceLeiosFetchServerEvent)
-> m (Vector LeiosTx)
-> m (Vector LeiosTx)
forall (m :: * -> *) e ev a.
(MonadCatch m, Exception e) =>
Tracer m ev -> (e -> ev) -> m a -> m a
catchAndRethrow Tracer m TraceLeiosFetchServerEvent
tracer (LeiosPoint
-> TxBitmaps -> LeiosDbException -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerTxsDbFailure LeiosPoint
point TxBitmaps
bitmaps) (m (Vector LeiosTx) -> m (Vector LeiosTx))
-> m (Vector LeiosTx) -> m (Vector LeiosTx)
forall a b. (a -> b) -> a -> b
$
            Tracer m TraceLeiosFetchServerEvent
-> LeiosDbReader m -> LeiosPoint -> TxBitmaps -> m (Vector LeiosTx)
forall (m :: * -> *).
MonadThrow m =>
Tracer m TraceLeiosFetchServerEvent
-> LeiosDbReader m -> LeiosPoint -> TxBitmaps -> m (Vector LeiosTx)
serveTxs Tracer m TraceLeiosFetchServerEvent
tracer LeiosDbReader m
reader LeiosPoint
point TxBitmaps
bitmaps

serveEb ::
  MonadThrow m =>
  Tracer m TraceLeiosFetchServerEvent ->
  LeiosDbReader m ->
  LeiosPoint ->
  m EndorserBlock
serveEb :: forall (m :: * -> *).
MonadThrow m =>
Tracer m TraceLeiosFetchServerEvent
-> LeiosDbReader m -> LeiosPoint -> m EndorserBlock
serveEb Tracer m TraceLeiosFetchServerEvent
tracer LeiosDbReader m
reader LeiosPoint
point = do
  -- TODO Disconnect a client that requests what the node never offered it.
  Tracer m TraceLeiosFetchServerEvent
-> TraceLeiosFetchServerEvent -> m ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer m TraceLeiosFetchServerEvent
tracer (TraceLeiosFetchServerEvent -> m ())
-> TraceLeiosFetchServerEvent -> m ()
forall a b. (a -> b) -> a -> b
$ LeiosPoint -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerBlockRequested LeiosPoint
point
  -- The one body's tx references, in order. A stored body is never empty, so
  -- no references means the node does not hold the body.
  LeiosDbReader m
-> HasCallStack => EndorserBlockHash -> m [(TxHash, BytesSize)]
forall (m :: * -> *).
LeiosDbReader m
-> HasCallStack => EndorserBlockHash -> m [(TxHash, BytesSize)]
lookupEbBody LeiosDbReader m
reader (LeiosPoint -> EndorserBlockHash
pointEbHash LeiosPoint
point) m [(TxHash, BytesSize)]
-> ([(TxHash, BytesSize)] -> m EndorserBlock) -> m EndorserBlock
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    [] -> ExnLeiosInvalidRequest -> m EndorserBlock
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ExnLeiosInvalidRequest -> m EndorserBlock)
-> ExnLeiosInvalidRequest -> m EndorserBlock
forall a b. (a -> b) -> a -> b
$ LeiosPoint -> ExnLeiosInvalidRequest
ExnLeiosUnknownBlockRequested LeiosPoint
point
    [(TxHash, BytesSize)]
refs -> do
      let n :: Int
n = [(TxHash, BytesSize)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(TxHash, BytesSize)]
refs
      Tracer m TraceLeiosFetchServerEvent
-> TraceLeiosFetchServerEvent -> m ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer m TraceLeiosFetchServerEvent
tracer (TraceLeiosFetchServerEvent -> m ())
-> TraceLeiosFetchServerEvent -> m ()
forall a b. (a -> b) -> a -> b
$ LeiosPoint -> Int -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerBlockServed LeiosPoint
point Int
n
      EndorserBlock -> m EndorserBlock
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (EndorserBlock -> m EndorserBlock)
-> EndorserBlock -> m EndorserBlock
forall a b. (a -> b) -> a -> b
$ [(TxHash, BytesSize)] -> EndorserBlock
mkEndorserBlock [(TxHash, BytesSize)]
refs

serveTxs ::
  MonadThrow m =>
  Tracer m TraceLeiosFetchServerEvent ->
  LeiosDbReader m ->
  LeiosPoint ->
  TxBitmaps ->
  m (V.Vector LeiosTx)
serveTxs :: forall (m :: * -> *).
MonadThrow m =>
Tracer m TraceLeiosFetchServerEvent
-> LeiosDbReader m -> LeiosPoint -> TxBitmaps -> m (Vector LeiosTx)
serveTxs Tracer m TraceLeiosFetchServerEvent
tracer LeiosDbReader m
reader LeiosPoint
point TxBitmaps
bitmaps = do
  -- TODO Disconnect a client that requests what the node never offered it.
  Tracer m TraceLeiosFetchServerEvent
-> TraceLeiosFetchServerEvent -> m ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer m TraceLeiosFetchServerEvent
tracer (TraceLeiosFetchServerEvent -> m ())
-> TraceLeiosFetchServerEvent -> m ()
forall a b. (a -> b) -> a -> b
$ LeiosPoint -> Int -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerTxsRequested LeiosPoint
point ([Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
offsets)
  -- One row for each requested offset that the endorser block has, with its
  -- bytes if the node holds them.
  rows <- LeiosDbReader m
-> HasCallStack =>
   EndorserBlockHash -> [Int] -> m [(Int, TxHash, Maybe ByteString)]
forall (m :: * -> *).
LeiosDbReader m
-> HasCallStack =>
   EndorserBlockHash -> [Int] -> m [(Int, TxHash, Maybe ByteString)]
batchRetrieveTxs LeiosDbReader m
reader (LeiosPoint -> EndorserBlockHash
pointEbHash LeiosPoint
point) [Int]
offsets
  case traverse (\(Int
_offset, TxHash
_txHash, Maybe ByteString
mbBytes) -> ByteString -> LeiosTx
MkLeiosTx (ByteString -> LeiosTx) -> Maybe ByteString -> Maybe LeiosTx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ByteString
mbBytes) rows of
    Just [LeiosTx]
txs | [LeiosTx] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [LeiosTx]
txs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
offsets -> do
      let n :: Int
n = [LeiosTx] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [LeiosTx]
txs
      Tracer m TraceLeiosFetchServerEvent
-> TraceLeiosFetchServerEvent -> m ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer m TraceLeiosFetchServerEvent
tracer (TraceLeiosFetchServerEvent -> m ())
-> TraceLeiosFetchServerEvent -> m ()
forall a b. (a -> b) -> a -> b
$
        LeiosPoint -> Int -> Int -> TraceLeiosFetchServerEvent
TraceLeiosFetchServerTxsServed LeiosPoint
point Int
n ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [ByteString -> Int
BS.length (LeiosTx -> ByteString
leiosTxBytes LeiosTx
tx) | LeiosTx
tx <- [LeiosTx]
txs])
      Vector LeiosTx -> m (Vector LeiosTx)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Vector LeiosTx -> m (Vector LeiosTx))
-> Vector LeiosTx -> m (Vector LeiosTx)
forall a b. (a -> b) -> a -> b
$ Int -> [LeiosTx] -> Vector LeiosTx
forall a. Int -> [a] -> Vector a
V.fromListN Int
n [LeiosTx]
txs
    Maybe [LeiosTx]
_ -> do
      let held :: IntSet
held = [Int] -> IntSet
IntSet.fromList [Int
offset | (Int
offset, TxHash
_txHash, Just ByteString
_bytes) <- [(Int, TxHash, Maybe ByteString)]
rows]
      ExnLeiosInvalidRequest -> m (Vector LeiosTx)
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ExnLeiosInvalidRequest -> m (Vector LeiosTx))
-> ExnLeiosInvalidRequest -> m (Vector LeiosTx)
forall a b. (a -> b) -> a -> b
$ LeiosPoint -> [Int] -> ExnLeiosInvalidRequest
ExnLeiosUnknownTxsRequested LeiosPoint
point ((Int -> Bool) -> [Int] -> [Int]
forall a. (a -> Bool) -> [a] -> [a]
filter (Int -> IntSet -> Bool
`IntSet.notMember` IntSet
held) [Int]
offsets)
 where
  offsets :: [Int]
offsets = TxBitmaps -> [Int]
bitmapOffsets TxBitmaps
bitmaps

-- | Trace an exception of the event's type that the action throws, then
-- rethrow it.
catchAndRethrow :: (MonadCatch m, Exception e) => Tracer m ev -> (e -> ev) -> m a -> m a
catchAndRethrow :: forall (m :: * -> *) e ev a.
(MonadCatch m, Exception e) =>
Tracer m ev -> (e -> ev) -> m a -> m a
catchAndRethrow Tracer m ev
tracer e -> ev
mkEvent m a
action =
  m a
action m a -> (e -> m a) -> m a
forall e a. Exception e => m a -> (e -> m a) -> m a
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` \e
e -> do
    Tracer m ev -> ev -> m ()
forall (m :: * -> *) a. Monad m => Tracer m a -> a -> m ()
traceWith Tracer m ev
tracer (e -> ev
mkEvent e
e)
    e -> m a
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO e
e

-- | LeiosFetch as a node-to-node mini-protocol.
leiosFetchMiniProtocol ::
  RunMiniProtocolWithExpandedCtx mode addr PeerTrustable b m a c ->
  MiniProtocolWithExpandedCtx mode addr PeerTrustable b m a c
leiosFetchMiniProtocol :: forall (mode :: Mode) addr b (m :: * -> *) a c.
RunMiniProtocolWithExpandedCtx mode addr PeerTrustable b m a c
-> MiniProtocolWithExpandedCtx mode addr PeerTrustable b m a c
leiosFetchMiniProtocol RunMiniProtocolWithExpandedCtx mode addr PeerTrustable b m a c
run =
  MiniProtocol
    { miniProtocolNum :: MiniProtocolNum
miniProtocolNum = MiniProtocolNum
leiosFetchMiniProtocolNum
    , miniProtocolStart :: StartOnDemandOrEagerly
miniProtocolStart = StartOnDemandOrEagerly
StartOnDemand
    , miniProtocolLimits :: MiniProtocolLimits
miniProtocolLimits = MiniProtocolLimits
leiosFetchProtocolLimits
    , miniProtocolRun :: RunMiniProtocolWithExpandedCtx mode addr PeerTrustable b m a c
miniProtocolRun = RunMiniProtocolWithExpandedCtx mode addr PeerTrustable b m a c
run
    }

-- | The ingress queue must hold every reply the client may have requested and
-- not yet consumed, 'maxLeiosFetchIngressBytes' of them; the margin covers the
-- framing around those bytes (see
-- 'Ouroboros.Consensus.MiniProtocol.LeiosFetch.Type.byteLimitsLeiosFetch'). The
-- server's, which only receives requests, needs far less.
leiosFetchProtocolLimits :: MiniProtocolLimits
leiosFetchProtocolLimits :: MiniProtocolLimits
leiosFetchProtocolLimits =
  MiniProtocolLimits
    { maximumIngressQueue :: Int
maximumIngressQueue = Int -> Int
addSafetyMargin Int
maxLeiosFetchIngressBytes
    }