{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE GADTs               #-}
{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE PolyKinds           #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies        #-}

module Ouroboros.Network.Protocol.BlockFetch.Codec
  ( codecBlockFetch
  , codecBlockFetchId
  , byteLimitsBlockFetch
  , timeLimitsBlockFetch
  ) where

import           Control.Monad.Class.MonadST
import           Control.Monad.Class.MonadTime

import qualified Data.ByteString.Lazy as LBS

import qualified Codec.CBOR.Decoding as CBOR
import qualified Codec.CBOR.Encoding as CBOR
import qualified Codec.CBOR.Read as CBOR
import           Text.Printf

import           Network.TypedProtocol.Codec.CBOR

import           Ouroboros.Network.Driver.Limits
import           Ouroboros.Network.Protocol.BlockFetch.Type
import           Ouroboros.Network.Protocol.Limits

-- | Byte Limit.
byteLimitsBlockFetch :: forall bytes block point.
                        (bytes -> Word)
                     -> ProtocolSizeLimits (BlockFetch block point) bytes
byteLimitsBlockFetch :: (bytes -> Word)
-> ProtocolSizeLimits (BlockFetch block point) bytes
byteLimitsBlockFetch = (forall (pr :: PeerRole) (st :: BlockFetch block point).
 PeerHasAgency pr st -> Word)
-> (bytes -> Word)
-> ProtocolSizeLimits (BlockFetch block point) bytes
forall ps bytes.
(forall (pr :: PeerRole) (st :: ps). PeerHasAgency pr st -> Word)
-> (bytes -> Word) -> ProtocolSizeLimits ps bytes
ProtocolSizeLimits forall (pr :: PeerRole) (st :: BlockFetch block point).
PeerHasAgency pr st -> Word
stateToLimit
  where
    stateToLimit :: forall (pr :: PeerRole) (st :: BlockFetch block point).
                    PeerHasAgency pr st -> Word
    stateToLimit :: PeerHasAgency pr st -> Word
stateToLimit (ClientAgency ClientHasAgency st
TokIdle)      = Word
smallByteLimit
    stateToLimit (ServerAgency ServerHasAgency st
TokBusy)      = Word
smallByteLimit
    stateToLimit (ServerAgency ServerHasAgency st
TokStreaming) = Word
largeByteLimit

-- | Time Limits
--
-- `TokIdle' No timeout
-- `TokBusy` `longWait` timeout
-- `TokStreaming` `longWait` timeout
timeLimitsBlockFetch :: forall block point.
                        ProtocolTimeLimits (BlockFetch block point)
timeLimitsBlockFetch :: ProtocolTimeLimits (BlockFetch block point)
timeLimitsBlockFetch = (forall (pr :: PeerRole) (st :: BlockFetch block point).
 PeerHasAgency pr st -> Maybe DiffTime)
-> ProtocolTimeLimits (BlockFetch block point)
forall ps.
(forall (pr :: PeerRole) (st :: ps).
 PeerHasAgency pr st -> Maybe DiffTime)
-> ProtocolTimeLimits ps
ProtocolTimeLimits forall (pr :: PeerRole) (st :: BlockFetch block point).
PeerHasAgency pr st -> Maybe DiffTime
stateToLimit
  where
    stateToLimit :: forall (pr :: PeerRole) (st :: BlockFetch block point).
                    PeerHasAgency pr st -> Maybe DiffTime
    stateToLimit :: PeerHasAgency pr st -> Maybe DiffTime
stateToLimit (ClientAgency ClientHasAgency st
TokIdle)      = Maybe DiffTime
waitForever
    stateToLimit (ServerAgency ServerHasAgency st
TokBusy)      = Maybe DiffTime
longWait
    stateToLimit (ServerAgency ServerHasAgency st
TokStreaming) = Maybe DiffTime
longWait

-- | Codec for chain sync that encodes/decodes blocks
--
-- NOTE: See 'wrapCBORinCBOR' and 'unwrapCBORinCBOR' if you want to use this
-- with a block type that has annotations.
codecBlockFetch
  :: forall block point m.
     MonadST m
  => (block            -> CBOR.Encoding)
  -> (forall s. CBOR.Decoder s block)
  -> (point -> CBOR.Encoding)
  -> (forall s. CBOR.Decoder s point)
  -> Codec (BlockFetch block point) CBOR.DeserialiseFailure m LBS.ByteString
codecBlockFetch :: (block -> Encoding)
-> (forall s. Decoder s block)
-> (point -> Encoding)
-> (forall s. Decoder s point)
-> Codec (BlockFetch block point) DeserialiseFailure m ByteString
codecBlockFetch block -> Encoding
encodeBlock forall s. Decoder s block
decodeBlock
                point -> Encoding
encodePoint forall s. Decoder s point
decodePoint =
    (forall (pr :: PeerRole) (st :: BlockFetch block point)
        (st' :: BlockFetch block point).
 PeerHasAgency pr st
 -> Message (BlockFetch block point) st st' -> Encoding)
-> (forall (pr :: PeerRole) (st :: BlockFetch block point) s.
    PeerHasAgency pr st -> Decoder s (SomeMessage st))
-> Codec (BlockFetch block point) DeserialiseFailure m ByteString
forall ps (m :: * -> *).
MonadST m =>
(forall (pr :: PeerRole) (st :: ps) (st' :: ps).
 PeerHasAgency pr st -> Message ps st st' -> Encoding)
-> (forall (pr :: PeerRole) (st :: ps) s.
    PeerHasAgency pr st -> Decoder s (SomeMessage st))
-> Codec ps DeserialiseFailure m ByteString
mkCodecCborLazyBS forall (pr :: PeerRole) (st :: BlockFetch block point)
       (st' :: BlockFetch block point).
PeerHasAgency pr st
-> Message (BlockFetch block point) st st' -> Encoding
encode forall (pr :: PeerRole) s (st :: BlockFetch block point).
PeerHasAgency pr st -> Decoder s (SomeMessage st)
forall (pr :: PeerRole) (st :: BlockFetch block point) s.
PeerHasAgency pr st -> Decoder s (SomeMessage st)
decode
 where
  encode :: forall (pr :: PeerRole) st st'.
            PeerHasAgency pr st
         -> Message (BlockFetch block point) st st'
         -> CBOR.Encoding
  encode :: PeerHasAgency pr st
-> Message (BlockFetch block point) st st' -> Encoding
encode (ClientAgency ClientHasAgency st
TokIdle) (MsgRequestRange (ChainRange from to)) =
    Word -> Encoding
CBOR.encodeListLen Word
3 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word -> Encoding
CBOR.encodeWord Word
0 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> point -> Encoding
encodePoint point
point
from
                                              Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> point -> Encoding
encodePoint point
point
to
  encode (ClientAgency ClientHasAgency st
TokIdle) Message (BlockFetch block point) st st'
MsgClientDone =
    Word -> Encoding
CBOR.encodeListLen Word
1 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word -> Encoding
CBOR.encodeWord Word
1
  encode (ServerAgency ServerHasAgency st
TokBusy) Message (BlockFetch block point) st st'
MsgStartBatch =
    Word -> Encoding
CBOR.encodeListLen Word
1 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word -> Encoding
CBOR.encodeWord Word
2
  encode (ServerAgency ServerHasAgency st
TokBusy) Message (BlockFetch block point) st st'
MsgNoBlocks =
    Word -> Encoding
CBOR.encodeListLen Word
1 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word -> Encoding
CBOR.encodeWord Word
3
  encode (ServerAgency ServerHasAgency st
TokStreaming) (MsgBlock block) =
    Word -> Encoding
CBOR.encodeListLen Word
2 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word -> Encoding
CBOR.encodeWord Word
4 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> block -> Encoding
encodeBlock block
block
block
  encode (ServerAgency ServerHasAgency st
TokStreaming) Message (BlockFetch block point) st st'
MsgBatchDone =
    Word -> Encoding
CBOR.encodeListLen Word
1 Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Word -> Encoding
CBOR.encodeWord Word
5

  decode :: forall (pr :: PeerRole) s (st :: BlockFetch block point).
            PeerHasAgency pr st
         -> CBOR.Decoder s (SomeMessage st)
  decode :: PeerHasAgency pr st -> Decoder s (SomeMessage st)
decode PeerHasAgency pr st
stok = do
    Int
len <- Decoder s Int
forall s. Decoder s Int
CBOR.decodeListLen
    Word
key <- Decoder s Word
forall s. Decoder s Word
CBOR.decodeWord
    case (PeerHasAgency pr st
stok, Word
key, Int
len) of
      (ClientAgency ClientHasAgency st
TokIdle, Word
0, Int
3) -> do
        point
from <- Decoder s point
forall s. Decoder s point
decodePoint
        point
to   <- Decoder s point
forall s. Decoder s point
decodePoint
        SomeMessage 'BFIdle -> Decoder s (SomeMessage 'BFIdle)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage 'BFIdle -> Decoder s (SomeMessage 'BFIdle))
-> SomeMessage 'BFIdle -> Decoder s (SomeMessage 'BFIdle)
forall a b. (a -> b) -> a -> b
$ Message (BlockFetch block point) 'BFIdle 'BFBusy
-> SomeMessage 'BFIdle
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage (Message (BlockFetch block point) 'BFIdle 'BFBusy
 -> SomeMessage 'BFIdle)
-> Message (BlockFetch block point) 'BFIdle 'BFBusy
-> SomeMessage 'BFIdle
forall a b. (a -> b) -> a -> b
$ ChainRange point
-> Message (BlockFetch block point) 'BFIdle 'BFBusy
forall k point (block :: k).
ChainRange point
-> Message (BlockFetch block point) 'BFIdle 'BFBusy
MsgRequestRange (point -> point -> ChainRange point
forall point. point -> point -> ChainRange point
ChainRange point
from point
to)
      (ClientAgency ClientHasAgency st
TokIdle, Word
1, Int
1) -> SomeMessage 'BFIdle -> Decoder s (SomeMessage 'BFIdle)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage 'BFIdle -> Decoder s (SomeMessage 'BFIdle))
-> SomeMessage 'BFIdle -> Decoder s (SomeMessage 'BFIdle)
forall a b. (a -> b) -> a -> b
$ Message (BlockFetch block point) 'BFIdle 'BFDone
-> SomeMessage 'BFIdle
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) 'BFIdle 'BFDone
forall k k (block :: k) (point :: k).
Message (BlockFetch block point) 'BFIdle 'BFDone
MsgClientDone
      (ServerAgency ServerHasAgency st
TokBusy, Word
2, Int
1) -> SomeMessage 'BFBusy -> Decoder s (SomeMessage 'BFBusy)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage 'BFBusy -> Decoder s (SomeMessage 'BFBusy))
-> SomeMessage 'BFBusy -> Decoder s (SomeMessage 'BFBusy)
forall a b. (a -> b) -> a -> b
$ Message (BlockFetch block point) 'BFBusy 'BFStreaming
-> SomeMessage 'BFBusy
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) 'BFBusy 'BFStreaming
forall k k (block :: k) (point :: k).
Message (BlockFetch block point) 'BFBusy 'BFStreaming
MsgStartBatch
      (ServerAgency ServerHasAgency st
TokBusy, Word
3, Int
1) -> SomeMessage 'BFBusy -> Decoder s (SomeMessage 'BFBusy)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage 'BFBusy -> Decoder s (SomeMessage 'BFBusy))
-> SomeMessage 'BFBusy -> Decoder s (SomeMessage 'BFBusy)
forall a b. (a -> b) -> a -> b
$ Message (BlockFetch block point) 'BFBusy 'BFIdle
-> SomeMessage 'BFBusy
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) 'BFBusy 'BFIdle
forall k k (block :: k) (point :: k).
Message (BlockFetch block point) 'BFBusy 'BFIdle
MsgNoBlocks
      (ServerAgency ServerHasAgency st
TokStreaming, Word
4, Int
2) -> Message (BlockFetch block point) 'BFStreaming 'BFStreaming
-> SomeMessage 'BFStreaming
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage (Message (BlockFetch block point) 'BFStreaming 'BFStreaming
 -> SomeMessage 'BFStreaming)
-> (block
    -> Message (BlockFetch block point) 'BFStreaming 'BFStreaming)
-> block
-> SomeMessage 'BFStreaming
forall b c a. (b -> c) -> (a -> b) -> a -> c
. block -> Message (BlockFetch block point) 'BFStreaming 'BFStreaming
forall k block (point :: k).
block -> Message (BlockFetch block point) 'BFStreaming 'BFStreaming
MsgBlock
                                          (block -> SomeMessage 'BFStreaming)
-> Decoder s block -> Decoder s (SomeMessage 'BFStreaming)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s block
forall s. Decoder s block
decodeBlock
      (ServerAgency ServerHasAgency st
TokStreaming, Word
5, Int
1) -> SomeMessage 'BFStreaming -> Decoder s (SomeMessage 'BFStreaming)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage 'BFStreaming -> Decoder s (SomeMessage 'BFStreaming))
-> SomeMessage 'BFStreaming -> Decoder s (SomeMessage 'BFStreaming)
forall a b. (a -> b) -> a -> b
$ Message (BlockFetch block point) 'BFStreaming 'BFIdle
-> SomeMessage 'BFStreaming
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) 'BFStreaming 'BFIdle
forall k k (block :: k) (point :: k).
Message (BlockFetch block point) 'BFStreaming 'BFIdle
MsgBatchDone

      --
      -- failures per protocol state
      --

      (ClientAgency ClientHasAgency st
TokIdle, Word
_, Int
_) ->
        String -> Decoder s (SomeMessage st)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> String -> Word -> Int -> String
forall r. PrintfType r => String -> r
printf String
"codecBlockFetch (%s) unexpected key (%d, %d)" (PeerHasAgency pr st -> String
forall a. Show a => a -> String
show PeerHasAgency pr st
stok) Word
key Int
len)
      (ServerAgency ServerHasAgency st
TokStreaming, Word
_ , Int
_) ->
        String -> Decoder s (SomeMessage st)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> String -> Word -> Int -> String
forall r. PrintfType r => String -> r
printf String
"codecBlockFetch (%s) unexpected key (%d, %d)" (PeerHasAgency pr st -> String
forall a. Show a => a -> String
show PeerHasAgency pr st
stok) Word
key Int
len)
      (ServerAgency ServerHasAgency st
TokBusy, Word
_, Int
_) ->
        String -> Decoder s (SomeMessage st)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> String -> Word -> Int -> String
forall r. PrintfType r => String -> r
printf String
"codecBlockFetch (%s) unexpected key (%d, %d)" (PeerHasAgency pr st -> String
forall a. Show a => a -> String
show PeerHasAgency pr st
stok) Word
key Int
len)


codecBlockFetchId
  :: forall block point m.
     Monad m
  => Codec (BlockFetch block point) CodecFailure m
           (AnyMessage (BlockFetch block point))
codecBlockFetchId :: Codec
  (BlockFetch block point)
  CodecFailure
  m
  (AnyMessage (BlockFetch block point))
codecBlockFetchId = (forall (pr :: PeerRole) (st :: BlockFetch block point)
        (st' :: BlockFetch block point).
 PeerHasAgency pr st
 -> Message (BlockFetch block point) st st'
 -> AnyMessage (BlockFetch block point))
-> (forall (pr :: PeerRole) (st :: BlockFetch block point).
    PeerHasAgency pr st
    -> m (DecodeStep
            (AnyMessage (BlockFetch block point))
            CodecFailure
            m
            (SomeMessage st)))
-> Codec
     (BlockFetch block point)
     CodecFailure
     m
     (AnyMessage (BlockFetch block point))
forall ps failure (m :: * -> *) bytes.
(forall (pr :: PeerRole) (st :: ps) (st' :: ps).
 PeerHasAgency pr st -> Message ps st st' -> bytes)
-> (forall (pr :: PeerRole) (st :: ps).
    PeerHasAgency pr st
    -> m (DecodeStep bytes failure m (SomeMessage st)))
-> Codec ps failure m bytes
Codec forall (pr :: PeerRole) (st :: BlockFetch block point)
       (st' :: BlockFetch block point).
PeerHasAgency pr st
-> Message (BlockFetch block point) st st'
-> AnyMessage (BlockFetch block point)
encode forall (pr :: PeerRole) (st :: BlockFetch block point).
PeerHasAgency pr st
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
decode
 where
  encode :: forall (pr :: PeerRole) st st'.
            PeerHasAgency pr st
         -> Message (BlockFetch block point) st st'
         -> AnyMessage (BlockFetch block point)
  encode :: PeerHasAgency pr st
-> Message (BlockFetch block point) st st'
-> AnyMessage (BlockFetch block point)
encode PeerHasAgency pr st
_ = Message (BlockFetch block point) st st'
-> AnyMessage (BlockFetch block point)
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> AnyMessage ps
AnyMessage

  decode :: forall (pr :: PeerRole) (st :: BlockFetch block point).
            PeerHasAgency pr st
         -> m (DecodeStep (AnyMessage (BlockFetch block point))
                          CodecFailure m (SomeMessage st))
  decode :: PeerHasAgency pr st
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
decode PeerHasAgency pr st
stok = DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (DecodeStep
   (AnyMessage (BlockFetch block point))
   CodecFailure
   m
   (SomeMessage st)
 -> m (DecodeStep
         (AnyMessage (BlockFetch block point))
         CodecFailure
         m
         (SomeMessage st)))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall a b. (a -> b) -> a -> b
$ (Maybe (AnyMessage (BlockFetch block point))
 -> m (DecodeStep
         (AnyMessage (BlockFetch block point))
         CodecFailure
         m
         (SomeMessage st)))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
(Maybe bytes -> m (DecodeStep bytes failure m a))
-> DecodeStep bytes failure m a
DecodePartial ((Maybe (AnyMessage (BlockFetch block point))
  -> m (DecodeStep
          (AnyMessage (BlockFetch block point))
          CodecFailure
          m
          (SomeMessage st)))
 -> DecodeStep
      (AnyMessage (BlockFetch block point))
      CodecFailure
      m
      (SomeMessage st))
-> (Maybe (AnyMessage (BlockFetch block point))
    -> m (DecodeStep
            (AnyMessage (BlockFetch block point))
            CodecFailure
            m
            (SomeMessage st)))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall a b. (a -> b) -> a -> b
$ \Maybe (AnyMessage (BlockFetch block point))
bytes -> case (PeerHasAgency pr st
stok, Maybe (AnyMessage (BlockFetch block point))
bytes) of
    (PeerHasAgency pr st
_, Maybe (AnyMessage (BlockFetch block point))
Nothing) -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (DecodeStep
   (AnyMessage (BlockFetch block point))
   CodecFailure
   m
   (SomeMessage st)
 -> m (DecodeStep
         (AnyMessage (BlockFetch block point))
         CodecFailure
         m
         (SomeMessage st)))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall a b. (a -> b) -> a -> b
$ CodecFailure
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
failure -> DecodeStep bytes failure m a
DecodeFail CodecFailure
CodecFailureOutOfInput
    (ClientAgency ClientHasAgency st
TokIdle,      Just (AnyMessage msg@(MsgRequestRange {}))) -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage st
-> Maybe (AnyMessage (BlockFetch block point))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
a -> Maybe bytes -> DecodeStep bytes failure m a
DecodeDone (Message (BlockFetch block point) st st' -> SomeMessage st
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) st st'
msg) Maybe (AnyMessage (BlockFetch block point))
forall a. Maybe a
Nothing)
    (ClientAgency ClientHasAgency st
TokIdle,      Just (AnyMessage msg@(MsgClientDone {})))   -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage st
-> Maybe (AnyMessage (BlockFetch block point))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
a -> Maybe bytes -> DecodeStep bytes failure m a
DecodeDone (Message (BlockFetch block point) st st' -> SomeMessage st
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) st st'
msg) Maybe (AnyMessage (BlockFetch block point))
forall a. Maybe a
Nothing)
    (ServerAgency ServerHasAgency st
TokBusy,      Just (AnyMessage msg@(MsgStartBatch {})))   -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage st
-> Maybe (AnyMessage (BlockFetch block point))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
a -> Maybe bytes -> DecodeStep bytes failure m a
DecodeDone (Message (BlockFetch block point) st st' -> SomeMessage st
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) st st'
msg) Maybe (AnyMessage (BlockFetch block point))
forall a. Maybe a
Nothing)
    (ServerAgency ServerHasAgency st
TokBusy,      Just (AnyMessage msg@(MsgNoBlocks {})))     -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage st
-> Maybe (AnyMessage (BlockFetch block point))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
a -> Maybe bytes -> DecodeStep bytes failure m a
DecodeDone (Message (BlockFetch block point) st st' -> SomeMessage st
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) st st'
msg) Maybe (AnyMessage (BlockFetch block point))
forall a. Maybe a
Nothing)
    (ServerAgency ServerHasAgency st
TokStreaming, Just (AnyMessage msg@(MsgBlock {})))        -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage st
-> Maybe (AnyMessage (BlockFetch block point))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
a -> Maybe bytes -> DecodeStep bytes failure m a
DecodeDone (Message (BlockFetch block point) st st' -> SomeMessage st
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) st st'
msg) Maybe (AnyMessage (BlockFetch block point))
forall a. Maybe a
Nothing)
    (ServerAgency ServerHasAgency st
TokStreaming, Just (AnyMessage msg@(MsgBatchDone {})))    -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeMessage st
-> Maybe (AnyMessage (BlockFetch block point))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
a -> Maybe bytes -> DecodeStep bytes failure m a
DecodeDone (Message (BlockFetch block point) st st' -> SomeMessage st
forall ps (st :: ps) (st' :: ps).
Message ps st st' -> SomeMessage st
SomeMessage Message (BlockFetch block point) st st'
msg) Maybe (AnyMessage (BlockFetch block point))
forall a. Maybe a
Nothing)
    (PeerHasAgency pr st
_, Maybe (AnyMessage (BlockFetch block point))
_) -> DecodeStep
  (AnyMessage (BlockFetch block point))
  CodecFailure
  m
  (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall (m :: * -> *) a. Monad m => a -> m a
return (DecodeStep
   (AnyMessage (BlockFetch block point))
   CodecFailure
   m
   (SomeMessage st)
 -> m (DecodeStep
         (AnyMessage (BlockFetch block point))
         CodecFailure
         m
         (SomeMessage st)))
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
-> m (DecodeStep
        (AnyMessage (BlockFetch block point))
        CodecFailure
        m
        (SomeMessage st))
forall a b. (a -> b) -> a -> b
$ CodecFailure
-> DecodeStep
     (AnyMessage (BlockFetch block point))
     CodecFailure
     m
     (SomeMessage st)
forall bytes failure (m :: * -> *) a.
failure -> DecodeStep bytes failure m a
DecodeFail (String -> CodecFailure
CodecFailure String
"codecBlockFetchId: no matching message")