{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}

module Ouroboros.Consensus.MiniProtocol.ChainSync.Server
  ( Tip
  , chainSyncBlockServerFollower
  , chainSyncBlocksServer
  , chainSyncHeaderServerFollower
  , chainSyncHeadersServer

    -- * Trace events
  , BlockingType (..)
  , TraceChainSyncServerEvent (..)

    -- * Low-level API
  , chainSyncServerForFollower
  ) where

import Control.ResourceRegistry (ResourceRegistry)
import Control.Tracer
import Ouroboros.Consensus.Block
import Ouroboros.Consensus.Storage.ChainDB.API
  ( ChainDB
  , Follower
  , WithPoint (..)
  , getSerialisedBlockWithPoint
  , getSerialisedHeaderWithPoint
  )
import qualified Ouroboros.Consensus.Storage.ChainDB.API as ChainDB
import Ouroboros.Consensus.Storage.Serialisation
import Ouroboros.Consensus.Util.Enclose
  ( Enclosing
  , Enclosing' (..)
  , pattern FallingEdge
  )
import Ouroboros.Consensus.Util.IOLike
import Ouroboros.Network.Block
  ( ChainUpdate (..)
  , Serialised
  , Tip (..)
  )
import Ouroboros.Network.Protocol.ChainSync.Server

chainSyncHeaderServerFollower ::
  ChainDB m blk ->
  ChainDB.ChainType ->
  ResourceRegistry m ->
  m (Follower m blk (WithPoint blk (SerialisedHeader blk)))
chainSyncHeaderServerFollower :: forall (m :: * -> *) blk.
ChainDB m blk
-> ChainType
-> ResourceRegistry m
-> m (Follower m blk (WithPoint blk (SerialisedHeader blk)))
chainSyncHeaderServerFollower ChainDB m blk
chainDB ChainType
chainType ResourceRegistry m
registry =
  ChainDB m blk
-> forall b.
   ResourceRegistry m
   -> ChainType -> BlockComponent blk b -> m (Follower m blk b)
forall (m :: * -> *) blk.
ChainDB m blk
-> forall b.
   ResourceRegistry m
   -> ChainType -> BlockComponent blk b -> m (Follower m blk b)
ChainDB.newFollower ChainDB m blk
chainDB ResourceRegistry m
registry ChainType
chainType BlockComponent blk (WithPoint blk (SerialisedHeader blk))
forall blk.
BlockComponent blk (WithPoint blk (SerialisedHeader blk))
getSerialisedHeaderWithPoint

chainSyncBlockServerFollower ::
  ChainDB m blk ->
  ResourceRegistry m ->
  m (Follower m blk (WithPoint blk (Serialised blk)))
chainSyncBlockServerFollower :: forall (m :: * -> *) blk.
ChainDB m blk
-> ResourceRegistry m
-> m (Follower m blk (WithPoint blk (Serialised blk)))
chainSyncBlockServerFollower ChainDB m blk
chainDB ResourceRegistry m
registry =
  ChainDB m blk
-> forall b.
   ResourceRegistry m
   -> ChainType -> BlockComponent blk b -> m (Follower m blk b)
forall (m :: * -> *) blk.
ChainDB m blk
-> forall b.
   ResourceRegistry m
   -> ChainType -> BlockComponent blk b -> m (Follower m blk b)
ChainDB.newFollower ChainDB m blk
chainDB ResourceRegistry m
registry ChainType
ChainDB.SelectedChain BlockComponent blk (WithPoint blk (Serialised blk))
forall blk. BlockComponent blk (WithPoint blk (Serialised blk))
getSerialisedBlockWithPoint

-- | Chain Sync Server for block headers for a given a 'ChainDB'.
--
-- The node-to-node protocol uses the chain sync mini-protocol with chain
-- headers (and fetches blocks separately with the block fetch mini-protocol).
chainSyncHeadersServer ::
  forall m blk.
  ( IOLike m
  , HasHeader (Header blk)
  ) =>
  Tracer m (TraceChainSyncServerEvent blk) ->
  ChainDB m blk ->
  Follower m blk (WithPoint blk (SerialisedHeader blk)) ->
  ChainSyncServer (SerialisedHeader blk) (Point blk) (Tip blk) m ()
chainSyncHeadersServer :: forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk)) =>
Tracer m (TraceChainSyncServerEvent blk)
-> ChainDB m blk
-> Follower m blk (WithPoint blk (SerialisedHeader blk))
-> ChainSyncServer
     (SerialisedHeader blk) (Point blk) (Tip blk) m ()
chainSyncHeadersServer Tracer m (TraceChainSyncServerEvent blk)
tracer ChainDB m blk
chainDB Follower m blk (WithPoint blk (SerialisedHeader blk))
flr =
  Tracer m (TraceChainSyncServerEvent blk)
-> STM m (Tip blk)
-> Follower m blk (WithPoint blk (SerialisedHeader blk))
-> ChainSyncServer
     (SerialisedHeader blk) (Point blk) (Tip blk) m ()
forall (m :: * -> *) blk b.
IOLike m =>
Tracer m (TraceChainSyncServerEvent blk)
-> STM m (Tip blk)
-> Follower m blk (WithPoint blk b)
-> ChainSyncServer b (Point blk) (Tip blk) m ()
chainSyncServerForFollower Tracer m (TraceChainSyncServerEvent blk)
tracer (ChainDB m blk -> STM m (Tip blk)
forall (m :: * -> *) blk.
(Monad (STM m), HasHeader (Header blk)) =>
ChainDB m blk -> STM m (Tip blk)
ChainDB.getCurrentTip ChainDB m blk
chainDB) Follower m blk (WithPoint blk (SerialisedHeader blk))
flr

-- | Chain Sync Server for blocks for a given a 'ChainDB'.
--
-- The local node-to-client protocol uses the chain sync mini-protocol with
-- chains of full blocks (rather than a header \/ body split).
chainSyncBlocksServer ::
  forall m blk.
  (IOLike m, HasHeader (Header blk)) =>
  Tracer m (TraceChainSyncServerEvent blk) ->
  ChainDB m blk ->
  Follower m blk (WithPoint blk (Serialised blk)) ->
  ChainSyncServer (Serialised blk) (Point blk) (Tip blk) m ()
chainSyncBlocksServer :: forall (m :: * -> *) blk.
(IOLike m, HasHeader (Header blk)) =>
Tracer m (TraceChainSyncServerEvent blk)
-> ChainDB m blk
-> Follower m blk (WithPoint blk (Serialised blk))
-> ChainSyncServer (Serialised blk) (Point blk) (Tip blk) m ()
chainSyncBlocksServer Tracer m (TraceChainSyncServerEvent blk)
tracer ChainDB m blk
chainDB Follower m blk (WithPoint blk (Serialised blk))
flr =
  Tracer m (TraceChainSyncServerEvent blk)
-> STM m (Tip blk)
-> Follower m blk (WithPoint blk (Serialised blk))
-> ChainSyncServer (Serialised blk) (Point blk) (Tip blk) m ()
forall (m :: * -> *) blk b.
IOLike m =>
Tracer m (TraceChainSyncServerEvent blk)
-> STM m (Tip blk)
-> Follower m blk (WithPoint blk b)
-> ChainSyncServer b (Point blk) (Tip blk) m ()
chainSyncServerForFollower Tracer m (TraceChainSyncServerEvent blk)
tracer (ChainDB m blk -> STM m (Tip blk)
forall (m :: * -> *) blk.
(Monad (STM m), HasHeader (Header blk)) =>
ChainDB m blk -> STM m (Tip blk)
ChainDB.getCurrentTip ChainDB m blk
chainDB) Follower m blk (WithPoint blk (Serialised blk))
flr

-- | A chain sync server.
--
-- This is a version of
-- 'Ouroboros.Network.Protocol.ChainSync.Examples.chainSyncServerExample' that
-- uses an action to get the current 'Tip' and a 'Follower' instead of
-- 'Ourboros.Network.ChainProducerState.ChainProducerState'.
--
-- All the hard work is done by the 'Follower's provided by the 'ChainDB'.
chainSyncServerForFollower ::
  forall m blk b.
  IOLike m =>
  Tracer m (TraceChainSyncServerEvent blk) ->
  STM m (Tip blk) ->
  Follower m blk (WithPoint blk b) ->
  ChainSyncServer b (Point blk) (Tip blk) m ()
chainSyncServerForFollower :: forall (m :: * -> *) blk b.
IOLike m =>
Tracer m (TraceChainSyncServerEvent blk)
-> STM m (Tip blk)
-> Follower m blk (WithPoint blk b)
-> ChainSyncServer b (Point blk) (Tip blk) m ()
chainSyncServerForFollower Tracer m (TraceChainSyncServerEvent blk)
tracer STM m (Tip blk)
getCurrentTip Follower m blk (WithPoint blk b)
flr =
  ChainSyncServer b (Point blk) (Tip blk) m ()
idle'
 where
  idle :: ServerStIdle b (Point blk) (Tip blk) m ()
  idle :: ServerStIdle b (Point blk) (Tip blk) m ()
idle =
    ServerStIdle
      { recvMsgRequestNext :: m (Either
     (ServerStNext b (Point blk) (Tip blk) m ())
     (m (ServerStNext b (Point blk) (Tip blk) m ())))
recvMsgRequestNext = m (Either
     (ServerStNext b (Point blk) (Tip blk) m ())
     (m (ServerStNext b (Point blk) (Tip blk) m ())))
handleRequestNext
      , recvMsgFindIntersect :: [Point blk] -> m (ServerStIntersect b (Point blk) (Tip blk) m ())
recvMsgFindIntersect = [Point blk] -> m (ServerStIntersect b (Point blk) (Tip blk) m ())
handleFindIntersect
      , recvMsgDoneClient :: m ()
recvMsgDoneClient = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      }

  idle' :: ChainSyncServer b (Point blk) (Tip blk) m ()
  idle' :: ChainSyncServer b (Point blk) (Tip blk) m ()
idle' = m (ServerStIdle b (Point blk) (Tip blk) m ())
-> ChainSyncServer b (Point blk) (Tip blk) m ()
forall header point tip (m :: * -> *) a.
m (ServerStIdle header point tip m a)
-> ChainSyncServer header point tip m a
ChainSyncServer (m (ServerStIdle b (Point blk) (Tip blk) m ())
 -> ChainSyncServer b (Point blk) (Tip blk) m ())
-> m (ServerStIdle b (Point blk) (Tip blk) m ())
-> ChainSyncServer b (Point blk) (Tip blk) m ()
forall a b. (a -> b) -> a -> b
$ ServerStIdle b (Point blk) (Tip blk) m ()
-> m (ServerStIdle b (Point blk) (Tip blk) m ())
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ServerStIdle b (Point blk) (Tip blk) m ()
idle

  handleRequestNext ::
    m
      ( Either
          (ServerStNext b (Point blk) (Tip blk) m ())
          (m (ServerStNext b (Point blk) (Tip blk) m ()))
      )
  handleRequestNext :: m (Either
     (ServerStNext b (Point blk) (Tip blk) m ())
     (m (ServerStNext b (Point blk) (Tip blk) m ())))
handleRequestNext =
    Follower m blk (WithPoint blk b)
-> m (Maybe (ChainUpdate blk (WithPoint blk b)))
forall (m :: * -> *) blk a.
Follower m blk a -> m (Maybe (ChainUpdate blk a))
ChainDB.followerInstruction Follower m blk (WithPoint blk b)
flr m (Maybe (ChainUpdate blk (WithPoint blk b)))
-> (Maybe (ChainUpdate blk (WithPoint blk b))
    -> m (Either
            (ServerStNext b (Point blk) (Tip blk) m ())
            (m (ServerStNext b (Point blk) (Tip blk) m ()))))
-> m (Either
        (ServerStNext b (Point blk) (Tip blk) m ())
        (m (ServerStNext b (Point blk) (Tip blk) m ())))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Just ChainUpdate blk (WithPoint blk b)
update -> do
        tip <- STM m (Tip blk) -> m (Tip blk)
forall a. HasCallStack => STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically STM m (Tip blk)
getCurrentTip
        let mkTraceEvent =
              Tip blk
-> ChainUpdate blk (Point blk)
-> BlockingType
-> Enclosing
-> TraceChainSyncServerEvent blk
forall blk.
Tip blk
-> ChainUpdate blk (Point blk)
-> BlockingType
-> Enclosing
-> TraceChainSyncServerEvent blk
TraceChainSyncServerUpdate Tip blk
tip (WithPoint blk b -> Point blk
forall blk b. WithPoint blk b -> Point blk
point (WithPoint blk b -> Point blk)
-> ChainUpdate blk (WithPoint blk b) -> ChainUpdate blk (Point blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ChainUpdate blk (WithPoint blk b)
update) BlockingType
NonBlocking
        traceWith tracer $ mkTraceEvent RisingEdge
        return $ Left $ sendNext mkTraceEvent tip update
      Maybe (ChainUpdate blk (WithPoint blk b))
Nothing -> Either
  (ServerStNext b (Point blk) (Tip blk) m ())
  (m (ServerStNext b (Point blk) (Tip blk) m ()))
-> m (Either
        (ServerStNext b (Point blk) (Tip blk) m ())
        (m (ServerStNext b (Point blk) (Tip blk) m ())))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (ServerStNext b (Point blk) (Tip blk) m ())
   (m (ServerStNext b (Point blk) (Tip blk) m ()))
 -> m (Either
         (ServerStNext b (Point blk) (Tip blk) m ())
         (m (ServerStNext b (Point blk) (Tip blk) m ()))))
-> Either
     (ServerStNext b (Point blk) (Tip blk) m ())
     (m (ServerStNext b (Point blk) (Tip blk) m ()))
-> m (Either
        (ServerStNext b (Point blk) (Tip blk) m ())
        (m (ServerStNext b (Point blk) (Tip blk) m ())))
forall a b. (a -> b) -> a -> b
$ m (ServerStNext b (Point blk) (Tip blk) m ())
-> Either
     (ServerStNext b (Point blk) (Tip blk) m ())
     (m (ServerStNext b (Point blk) (Tip blk) m ()))
forall a b. b -> Either a b
Right (m (ServerStNext b (Point blk) (Tip blk) m ())
 -> Either
      (ServerStNext b (Point blk) (Tip blk) m ())
      (m (ServerStNext b (Point blk) (Tip blk) m ())))
-> m (ServerStNext b (Point blk) (Tip blk) m ())
-> Either
     (ServerStNext b (Point blk) (Tip blk) m ())
     (m (ServerStNext b (Point blk) (Tip blk) m ()))
forall a b. (a -> b) -> a -> b
$ do
        -- Follower is at the head, we have to block and wait for the chain to
        -- change.
        update <- Follower m blk (WithPoint blk b)
-> m (ChainUpdate blk (WithPoint blk b))
forall (m :: * -> *) blk a.
Follower m blk a -> m (ChainUpdate blk a)
ChainDB.followerInstructionBlocking Follower m blk (WithPoint blk b)
flr
        tip <- atomically getCurrentTip
        let mkTraceEvent =
              Tip blk
-> ChainUpdate blk (Point blk)
-> BlockingType
-> Enclosing
-> TraceChainSyncServerEvent blk
forall blk.
Tip blk
-> ChainUpdate blk (Point blk)
-> BlockingType
-> Enclosing
-> TraceChainSyncServerEvent blk
TraceChainSyncServerUpdate Tip blk
tip (WithPoint blk b -> Point blk
forall blk b. WithPoint blk b -> Point blk
point (WithPoint blk b -> Point blk)
-> ChainUpdate blk (WithPoint blk b) -> ChainUpdate blk (Point blk)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ChainUpdate blk (WithPoint blk b)
update) BlockingType
Blocking
        traceWith tracer $ mkTraceEvent RisingEdge
        return $ sendNext mkTraceEvent tip update

  sendNext ::
    (Enclosing -> TraceChainSyncServerEvent blk) ->
    Tip blk ->
    ChainUpdate blk (WithPoint blk b) ->
    ServerStNext b (Point blk) (Tip blk) m ()
  sendNext :: (Enclosing -> TraceChainSyncServerEvent blk)
-> Tip blk
-> ChainUpdate blk (WithPoint blk b)
-> ServerStNext b (Point blk) (Tip blk) m ()
sendNext Enclosing -> TraceChainSyncServerEvent blk
mkTraceEvent Tip blk
tip = \case
    AddBlock WithPoint blk b
hdr -> b
-> Tip blk
-> ChainSyncServer b (Point blk) (Tip blk) m ()
-> ServerStNext b (Point blk) (Tip blk) m ()
forall header tip point (m :: * -> *) a.
header
-> tip
-> ChainSyncServer header point tip m a
-> ServerStNext header point tip m a
SendMsgRollForward (WithPoint blk b -> b
forall blk b. WithPoint blk b -> b
withoutPoint WithPoint blk b
hdr) Tip blk
tip ChainSyncServer b (Point blk) (Tip blk) m ()
traceThenIdle
    RollBack Point blk
pt -> Point blk
-> Tip blk
-> ChainSyncServer b (Point blk) (Tip blk) m ()
-> ServerStNext b (Point blk) (Tip blk) m ()
forall point tip header (m :: * -> *) a.
point
-> tip
-> ChainSyncServer header point tip m a
-> ServerStNext header point tip m a
SendMsgRollBackward Point blk
pt Tip blk
tip ChainSyncServer b (Point blk) (Tip blk) m ()
traceThenIdle
   where
    traceThenIdle :: ChainSyncServer b (Point blk) (Tip blk) m ()
traceThenIdle = m (ServerStIdle b (Point blk) (Tip blk) m ())
-> ChainSyncServer b (Point blk) (Tip blk) m ()
forall header point tip (m :: * -> *) a.
m (ServerStIdle header point tip m a)
-> ChainSyncServer header point tip m a
ChainSyncServer (m (ServerStIdle b (Point blk) (Tip blk) m ())
 -> ChainSyncServer b (Point blk) (Tip blk) m ())
-> m (ServerStIdle b (Point blk) (Tip blk) m ())
-> ChainSyncServer b (Point blk) (Tip blk) m ()
forall a b. (a -> b) -> a -> b
$ do
      Tracer m (TraceChainSyncServerEvent blk)
-> TraceChainSyncServerEvent blk -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (TraceChainSyncServerEvent blk)
tracer (TraceChainSyncServerEvent blk -> m ())
-> TraceChainSyncServerEvent blk -> m ()
forall a b. (a -> b) -> a -> b
$ Enclosing -> TraceChainSyncServerEvent blk
mkTraceEvent Enclosing
FallingEdge
      ServerStIdle b (Point blk) (Tip blk) m ()
-> m (ServerStIdle b (Point blk) (Tip blk) m ())
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ServerStIdle b (Point blk) (Tip blk) m ()
idle

  handleFindIntersect ::
    [Point blk] ->
    m (ServerStIntersect b (Point blk) (Tip blk) m ())
  handleFindIntersect :: [Point blk] -> m (ServerStIntersect b (Point blk) (Tip blk) m ())
handleFindIntersect [Point blk]
points = do
    -- TODO guard number of points
    changed <- Follower m blk (WithPoint blk b)
-> [Point blk] -> m (Maybe (Point blk))
forall (m :: * -> *) blk a.
Follower m blk a -> [Point blk] -> m (Maybe (Point blk))
ChainDB.followerForward Follower m blk (WithPoint blk b)
flr [Point blk]
points
    tip <- atomically getCurrentTip
    case changed of
      Just Point blk
pt -> ServerStIntersect b (Point blk) (Tip blk) m ()
-> m (ServerStIntersect b (Point blk) (Tip blk) m ())
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ServerStIntersect b (Point blk) (Tip blk) m ()
 -> m (ServerStIntersect b (Point blk) (Tip blk) m ()))
-> ServerStIntersect b (Point blk) (Tip blk) m ()
-> m (ServerStIntersect b (Point blk) (Tip blk) m ())
forall a b. (a -> b) -> a -> b
$ Point blk
-> Tip blk
-> ChainSyncServer b (Point blk) (Tip blk) m ()
-> ServerStIntersect b (Point blk) (Tip blk) m ()
forall point tip header (m :: * -> *) a.
point
-> tip
-> ChainSyncServer header point tip m a
-> ServerStIntersect header point tip m a
SendMsgIntersectFound Point blk
pt Tip blk
tip ChainSyncServer b (Point blk) (Tip blk) m ()
idle'
      Maybe (Point blk)
Nothing -> ServerStIntersect b (Point blk) (Tip blk) m ()
-> m (ServerStIntersect b (Point blk) (Tip blk) m ())
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ServerStIntersect b (Point blk) (Tip blk) m ()
 -> m (ServerStIntersect b (Point blk) (Tip blk) m ()))
-> ServerStIntersect b (Point blk) (Tip blk) m ()
-> m (ServerStIntersect b (Point blk) (Tip blk) m ())
forall a b. (a -> b) -> a -> b
$ Tip blk
-> ChainSyncServer b (Point blk) (Tip blk) m ()
-> ServerStIntersect b (Point blk) (Tip blk) m ()
forall tip header point (m :: * -> *) a.
tip
-> ChainSyncServer header point tip m a
-> ServerStIntersect header point tip m a
SendMsgIntersectNotFound Tip blk
tip ChainSyncServer b (Point blk) (Tip blk) m ()
idle'

{-------------------------------------------------------------------------------
  Trace events
-------------------------------------------------------------------------------}

-- | Events traced by the Chain Sync Server.
data TraceChainSyncServerEvent blk
  = -- | Send a 'ChainUpdate' message.
    TraceChainSyncServerUpdate
      -- | Tip of the currently selected chain.
      (Tip blk)
      -- | The whole headers/blocks in the traced 'ChainUpdate' are substituted
      -- with their corresponding 'Point'.
      (ChainUpdate blk (Point blk))
      BlockingType
      Enclosing
  deriving (TraceChainSyncServerEvent blk
-> TraceChainSyncServerEvent blk -> Bool
(TraceChainSyncServerEvent blk
 -> TraceChainSyncServerEvent blk -> Bool)
-> (TraceChainSyncServerEvent blk
    -> TraceChainSyncServerEvent blk -> Bool)
-> Eq (TraceChainSyncServerEvent blk)
forall blk.
StandardHash blk =>
TraceChainSyncServerEvent blk
-> TraceChainSyncServerEvent blk -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall blk.
StandardHash blk =>
TraceChainSyncServerEvent blk
-> TraceChainSyncServerEvent blk -> Bool
== :: TraceChainSyncServerEvent blk
-> TraceChainSyncServerEvent blk -> Bool
$c/= :: forall blk.
StandardHash blk =>
TraceChainSyncServerEvent blk
-> TraceChainSyncServerEvent blk -> Bool
/= :: TraceChainSyncServerEvent blk
-> TraceChainSyncServerEvent blk -> Bool
Eq, Int -> TraceChainSyncServerEvent blk -> ShowS
[TraceChainSyncServerEvent blk] -> ShowS
TraceChainSyncServerEvent blk -> String
(Int -> TraceChainSyncServerEvent blk -> ShowS)
-> (TraceChainSyncServerEvent blk -> String)
-> ([TraceChainSyncServerEvent blk] -> ShowS)
-> Show (TraceChainSyncServerEvent blk)
forall blk.
StandardHash blk =>
Int -> TraceChainSyncServerEvent blk -> ShowS
forall blk.
StandardHash blk =>
[TraceChainSyncServerEvent blk] -> ShowS
forall blk.
StandardHash blk =>
TraceChainSyncServerEvent blk -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall blk.
StandardHash blk =>
Int -> TraceChainSyncServerEvent blk -> ShowS
showsPrec :: Int -> TraceChainSyncServerEvent blk -> ShowS
$cshow :: forall blk.
StandardHash blk =>
TraceChainSyncServerEvent blk -> String
show :: TraceChainSyncServerEvent blk -> String
$cshowList :: forall blk.
StandardHash blk =>
[TraceChainSyncServerEvent blk] -> ShowS
showList :: [TraceChainSyncServerEvent blk] -> ShowS
Show)

-- | Whether reading a ChainSync server update instruction was blocking or
-- non-blocking.
data BlockingType = Blocking | NonBlocking
  deriving (BlockingType -> BlockingType -> Bool
(BlockingType -> BlockingType -> Bool)
-> (BlockingType -> BlockingType -> Bool) -> Eq BlockingType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BlockingType -> BlockingType -> Bool
== :: BlockingType -> BlockingType -> Bool
$c/= :: BlockingType -> BlockingType -> Bool
/= :: BlockingType -> BlockingType -> Bool
Eq, Eq BlockingType
Eq BlockingType =>
(BlockingType -> BlockingType -> Ordering)
-> (BlockingType -> BlockingType -> Bool)
-> (BlockingType -> BlockingType -> Bool)
-> (BlockingType -> BlockingType -> Bool)
-> (BlockingType -> BlockingType -> Bool)
-> (BlockingType -> BlockingType -> BlockingType)
-> (BlockingType -> BlockingType -> BlockingType)
-> Ord BlockingType
BlockingType -> BlockingType -> Bool
BlockingType -> BlockingType -> Ordering
BlockingType -> BlockingType -> BlockingType
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 :: BlockingType -> BlockingType -> Ordering
compare :: BlockingType -> BlockingType -> Ordering
$c< :: BlockingType -> BlockingType -> Bool
< :: BlockingType -> BlockingType -> Bool
$c<= :: BlockingType -> BlockingType -> Bool
<= :: BlockingType -> BlockingType -> Bool
$c> :: BlockingType -> BlockingType -> Bool
> :: BlockingType -> BlockingType -> Bool
$c>= :: BlockingType -> BlockingType -> Bool
>= :: BlockingType -> BlockingType -> Bool
$cmax :: BlockingType -> BlockingType -> BlockingType
max :: BlockingType -> BlockingType -> BlockingType
$cmin :: BlockingType -> BlockingType -> BlockingType
min :: BlockingType -> BlockingType -> BlockingType
Ord, Int -> BlockingType -> ShowS
[BlockingType] -> ShowS
BlockingType -> String
(Int -> BlockingType -> ShowS)
-> (BlockingType -> String)
-> ([BlockingType] -> ShowS)
-> Show BlockingType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BlockingType -> ShowS
showsPrec :: Int -> BlockingType -> ShowS
$cshow :: BlockingType -> String
show :: BlockingType -> String
$cshowList :: [BlockingType] -> ShowS
showList :: [BlockingType] -> ShowS
Show)