{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE GADTs               #-}
{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE ScopedTypeVariables #-}

{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE PolyKinds           #-}
{-# LANGUAGE TypeApplications    #-}

module Ouroboros.Network.Protocol.PeerSharing.Test where

import Codec.CBOR.Decoding qualified as CBOR
import Codec.CBOR.Encoding qualified as CBOR
import Control.Monad.Class.MonadAsync (MonadAsync)
import Control.Monad.Class.MonadST (MonadST)
import Control.Monad.Class.MonadThrow (MonadCatch)
import Control.Monad.IOSim (runSimOrThrow)
import Control.Monad.ST (runST)
import Control.Tracer (nullTracer)
import Data.ByteString.Lazy qualified as BL
import Data.Foldable as Foldable (foldl')
import Data.Word (Word8)

import Network.TypedProtocol.Codec
import Network.TypedProtocol.Proofs

import Ouroboros.Network.Channel (createConnectedChannels)
import Ouroboros.Network.Driver.Limits (ProtocolSizeLimits (..))
import Ouroboros.Network.Driver.Simple (runConnectedPeers)
import Ouroboros.Network.Protocol.PeerSharing.Client (peerSharingClientPeer)
import Ouroboros.Network.Protocol.PeerSharing.Codec (byteLimitsPeerSharing,
           codecPeerSharing)
import Ouroboros.Network.Protocol.PeerSharing.Direct (direct)
import Ouroboros.Network.Protocol.PeerSharing.Examples
           (peerSharingClientCollect, peerSharingServerReplicate)
import Ouroboros.Network.Protocol.PeerSharing.Server (peerSharingServerPeer)
import Ouroboros.Network.Protocol.PeerSharing.Type
import Test.Ouroboros.Network.Testing.Utils (prop_codec_cborM,
           prop_codec_valid_cbor_encoding, splits2, splits3)
import Test.QuickCheck.Function (Fun, applyFun)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.QuickCheck (Arbitrary (..), Property, ioProperty, oneof,
           testProperty, withMaxSuccess, (===))

tests :: TestTree
tests :: TestTree
tests =
  TestName -> [TestTree] -> TestTree
testGroup TestName
"Ouroboros.Network.Protocol"
    [ TestName -> [TestTree] -> TestTree
testGroup TestName
"PeerSharing"
        [ TestName
-> (Fun Word8 Int -> [PeerSharingAmount] -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"direct"           Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_direct
        , TestName
-> (Fun Word8 Int -> [PeerSharingAmount] -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"connect"          Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_connect
        , TestName
-> (Fun Word8 Int -> [PeerSharingAmount] -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"channel ST"       Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_channel_ST
        , TestName
-> (Fun Word8 Int -> [PeerSharingAmount] -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"channel IO"       Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_channel_IO
        , TestName -> (AnyMessage (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec"            AnyMessage (PeerSharing Int) -> Bool
prop_codec_PeerSharing
        , TestName -> (AnyMessage (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec cbor"       AnyMessage (PeerSharing Int) -> Bool
prop_codec_cbor
        , TestName -> (AnyMessage (PeerSharing Int) -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec valid cbor" AnyMessage (PeerSharing Int) -> Property
prop_codec_valid_cbor
        , TestName -> (AnyMessage (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec 2-splits"   AnyMessage (PeerSharing Int) -> Bool
prop_codec_splits2
        , TestName -> Property -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec 3-splits"   (Int -> (AnyMessage (PeerSharing Int) -> Bool) -> Property
forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess Int
33 AnyMessage (PeerSharing Int) -> Bool
prop_codec_splits3)
        , TestName -> (AnyMessage (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"byteLimits"       AnyMessage (PeerSharing Int) -> Bool
prop_byteLimits
        ]
    ]

instance Arbitrary PeerSharingAmount where
  arbitrary :: Gen PeerSharingAmount
arbitrary = Word8 -> PeerSharingAmount
PeerSharingAmount (Word8 -> PeerSharingAmount) -> Gen Word8 -> Gen PeerSharingAmount
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word8
forall a. Arbitrary a => Gen a
arbitrary
  shrink :: PeerSharingAmount -> [PeerSharingAmount]
shrink (PeerSharingAmount Word8
amount) = Word8 -> PeerSharingAmount
PeerSharingAmount (Word8 -> PeerSharingAmount) -> [Word8] -> [PeerSharingAmount]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word8 -> [Word8]
forall a. Arbitrary a => a -> [a]
shrink Word8
amount

--
-- Properties going directly, not via Peer.
--

prop_direct :: Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_direct :: Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_direct Fun Word8 Int
f [PeerSharingAmount]
l =
  (forall s. IOSim s [Int]) -> [Int]
forall a. (forall s. IOSim s a) -> a
runSimOrThrow
    (PeerSharingServer Int (IOSim s)
-> PeerSharingClient Int (IOSim s) [Int] -> IOSim s [Int]
forall (m :: * -> *) peer b.
Monad m =>
PeerSharingServer peer m -> PeerSharingClient peer m b -> m b
direct (Fun Word8 Int -> PeerSharingServer Int (IOSim s)
forall (m :: * -> *).
Monad m =>
Fun Word8 Int -> PeerSharingServer Int m
peerSharingServerReplicate Fun Word8 Int
f)
            ([PeerSharingAmount] -> PeerSharingClient Int (IOSim s) [Int]
forall peer (m :: * -> *).
Monad m =>
[PeerSharingAmount] -> PeerSharingClient peer m [peer]
peerSharingClientCollect [PeerSharingAmount]
l))
  [Int] -> [Int] -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== ((Int, [Int]) -> [Int]
forall a b. (a, b) -> b
snd ((Int, [Int]) -> [Int]) -> (Int, [Int]) -> [Int]
forall a b. (a -> b) -> a -> b
$ ((Int, [Int]) -> PeerSharingAmount -> (Int, [Int]))
-> (Int, [Int]) -> [PeerSharingAmount] -> (Int, [Int])
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Foldable.foldl' (\(Int
n, [Int]
r) (PeerSharingAmount Word8
amount)
                      -> (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (Fun Word8 Int -> Word8 -> Int
forall a b. Fun a b -> a -> b
applyFun Fun Word8 Int
f Word8
amount) Int
n [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int]
r))
             (Int
0, [])
             [PeerSharingAmount]
l)

--
-- Properties using connect
--

prop_connect :: Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_connect :: Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_connect Fun Word8 Int
f [PeerSharingAmount]
l =
   case (forall s. IOSim s ([Int], (), TerminalStates (PeerSharing Int)))
-> ([Int], (), TerminalStates (PeerSharing Int))
forall a. (forall s. IOSim s a) -> a
runSimOrThrow
          (Peer
  (PeerSharing Int) 'AsClient 'NonPipelined 'StIdle (IOSim s) [Int]
-> Peer
     (PeerSharing Int)
     (FlipAgency 'AsClient)
     'NonPipelined
     'StIdle
     (IOSim s)
     ()
-> IOSim s ([Int], (), TerminalStates (PeerSharing Int))
forall ps (pr :: PeerRole) (initSt :: ps) (m :: * -> *) a b.
(Monad m, SingI pr) =>
Peer ps pr 'NonPipelined initSt m a
-> Peer ps (FlipAgency pr) 'NonPipelined initSt m b
-> m (a, b, TerminalStates ps)
connect
            (PeerSharingClient Int (IOSim s) [Int]
-> Peer
     (PeerSharing Int) 'AsClient 'NonPipelined 'StIdle (IOSim s) [Int]
forall (m :: * -> *) peerAddress a.
Monad m =>
PeerSharingClient peerAddress m a
-> Client (PeerSharing peerAddress) 'NonPipelined 'StIdle m a
peerSharingClientPeer ([PeerSharingAmount] -> PeerSharingClient Int (IOSim s) [Int]
forall peer (m :: * -> *).
Monad m =>
[PeerSharingAmount] -> PeerSharingClient peer m [peer]
peerSharingClientCollect [PeerSharingAmount]
l))
            (PeerSharingServer Int (IOSim s)
-> Server (PeerSharing Int) 'NonPipelined 'StIdle (IOSim s) ()
forall (m :: * -> *) peerAddress.
Monad m =>
PeerSharingServer peerAddress m
-> Server (PeerSharing peerAddress) 'NonPipelined 'StIdle m ()
peerSharingServerPeer (Fun Word8 Int -> PeerSharingServer Int (IOSim s)
forall (m :: * -> *).
Monad m =>
Fun Word8 Int -> PeerSharingServer Int m
peerSharingServerReplicate Fun Word8 Int
f))) of
     ([Int]
ns, ()
_, TerminalStates SingPeerSharing st
StateToken st
SingDone SingPeerSharing 'StDone
StateToken st
SingDone) ->
       let compute :: (Int, [Int])
compute = ((Int, [Int]) -> PeerSharingAmount -> (Int, [Int]))
-> (Int, [Int]) -> [PeerSharingAmount] -> (Int, [Int])
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\(Int
x, [Int]
r) (PeerSharingAmount Word8
amount)
                              -> (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (Fun Word8 Int -> Word8 -> Int
forall a b. Fun a b -> a -> b
applyFun Fun Word8 Int
f Word8
amount) Int
x [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int]
r))
                            (Int
0, [])
                            [PeerSharingAmount]
l
        in [Int]
ns [Int] -> [Int] -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (Int, [Int]) -> [Int]
forall a b. (a, b) -> b
snd (Int, [Int])
compute


--
-- Properties using channels, codecs and drivers.
--

prop_channel :: ( MonadAsync m
                , MonadCatch m
                , MonadST    m
                )
             => Fun Word8 Int
             -> [PeerSharingAmount]
             -> m Property
prop_channel :: forall (m :: * -> *).
(MonadAsync m, MonadCatch m, MonadST m) =>
Fun Word8 Int -> [PeerSharingAmount] -> m Property
prop_channel Fun Word8 Int
f [PeerSharingAmount]
l = do
    (s, _) <- m (Channel m ByteString, Channel m ByteString)
-> Tracer m (Role, TraceSendRecv (PeerSharing Int))
-> Codec (PeerSharing Int) DeserialiseFailure m ByteString
-> Peer (PeerSharing Int) 'AsClient 'NonPipelined 'StIdle m [Int]
-> Peer
     (PeerSharing Int) (FlipAgency 'AsClient) 'NonPipelined 'StIdle m ()
-> m ([Int], ())
forall ps (pr :: PeerRole) (st :: ps) failure bytes (m :: * -> *) a
       b.
(MonadAsync m, MonadThrow m, ShowProxy ps,
 forall (st' :: ps) stok. (stok ~ StateToken st') => Show stok,
 Show failure) =>
m (Channel m bytes, Channel m bytes)
-> Tracer m (Role, TraceSendRecv ps)
-> Codec ps failure m bytes
-> Peer ps pr 'NonPipelined st m a
-> Peer ps (FlipAgency pr) 'NonPipelined st m b
-> m (a, b)
runConnectedPeers m (Channel m ByteString, Channel m ByteString)
forall (m :: * -> *) a. MonadSTM m => m (Channel m a, Channel m a)
createConnectedChannels
                                Tracer m (Role, TraceSendRecv (PeerSharing Int))
forall (m :: * -> *) a. Applicative m => Tracer m a
nullTracer
                                ((Int -> Encoding)
-> (forall s. Decoder s Int)
-> Codec (PeerSharing Int) DeserialiseFailure m ByteString
forall (m :: * -> *) peerAddress.
MonadST m =>
(peerAddress -> Encoding)
-> (forall s. Decoder s peerAddress)
-> Codec (PeerSharing peerAddress) DeserialiseFailure m ByteString
codecPeerSharing Int -> Encoding
CBOR.encodeInt Decoder s Int
forall s. Decoder s Int
CBOR.decodeInt)
                                Peer (PeerSharing Int) 'AsClient 'NonPipelined 'StIdle m [Int]
client Peer
  (PeerSharing Int) (FlipAgency 'AsClient) 'NonPipelined 'StIdle m ()
Server (PeerSharing Int) 'NonPipelined 'StIdle m ()
server
    let compute = ((Int, [Int]) -> PeerSharingAmount -> (Int, [Int]))
-> (Int, [Int]) -> [PeerSharingAmount] -> (Int, [Int])
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Foldable.foldl' (\(Int
x, [Int]
r) (PeerSharingAmount Word8
amount)
                           -> (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (Fun Word8 Int -> Word8 -> Int
forall a b. Fun a b -> a -> b
applyFun Fun Word8 Int
f Word8
amount) Int
x [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int]
r))
                         (Int
0, [])
                         [PeerSharingAmount]
l
    return (s === snd compute)
  where
    client :: Peer (PeerSharing Int) 'AsClient 'NonPipelined 'StIdle m [Int]
client = PeerSharingClient Int m [Int]
-> Peer (PeerSharing Int) 'AsClient 'NonPipelined 'StIdle m [Int]
forall (m :: * -> *) peerAddress a.
Monad m =>
PeerSharingClient peerAddress m a
-> Client (PeerSharing peerAddress) 'NonPipelined 'StIdle m a
peerSharingClientPeer ([PeerSharingAmount] -> PeerSharingClient Int m [Int]
forall peer (m :: * -> *).
Monad m =>
[PeerSharingAmount] -> PeerSharingClient peer m [peer]
peerSharingClientCollect [PeerSharingAmount]
l)
    server :: Server (PeerSharing Int) 'NonPipelined 'StIdle m ()
server = PeerSharingServer Int m
-> Server (PeerSharing Int) 'NonPipelined 'StIdle m ()
forall (m :: * -> *) peerAddress.
Monad m =>
PeerSharingServer peerAddress m
-> Server (PeerSharing peerAddress) 'NonPipelined 'StIdle m ()
peerSharingServerPeer (Fun Word8 Int -> PeerSharingServer Int m
forall (m :: * -> *).
Monad m =>
Fun Word8 Int -> PeerSharingServer Int m
peerSharingServerReplicate Fun Word8 Int
f)

prop_channel_ST :: Fun Word8 Int
                -> [PeerSharingAmount]
                -> Property
prop_channel_ST :: Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_channel_ST Fun Word8 Int
f [PeerSharingAmount]
l =
  (forall s. IOSim s Property) -> Property
forall a. (forall s. IOSim s a) -> a
runSimOrThrow (Fun Word8 Int -> [PeerSharingAmount] -> IOSim s Property
forall (m :: * -> *).
(MonadAsync m, MonadCatch m, MonadST m) =>
Fun Word8 Int -> [PeerSharingAmount] -> m Property
prop_channel Fun Word8 Int
f [PeerSharingAmount]
l)

prop_channel_IO :: Fun Word8 Int
                -> [PeerSharingAmount]
                -> Property
prop_channel_IO :: Fun Word8 Int -> [PeerSharingAmount] -> Property
prop_channel_IO Fun Word8 Int
f [PeerSharingAmount]
l =
  IO Property -> Property
forall prop. Testable prop => IO prop -> Property
ioProperty (Fun Word8 Int -> [PeerSharingAmount] -> IO Property
forall (m :: * -> *).
(MonadAsync m, MonadCatch m, MonadST m) =>
Fun Word8 Int -> [PeerSharingAmount] -> m Property
prop_channel Fun Word8 Int
f [PeerSharingAmount]
l)

--
-- Codec tests
--

instance Arbitrary peer => Arbitrary (AnyMessage (PeerSharing peer)) where
  -- TODO: refactor, add shrinker
  arbitrary :: Gen (AnyMessage (PeerSharing peer))
arbitrary = do
    amount <- Word8 -> PeerSharingAmount
PeerSharingAmount (Word8 -> PeerSharingAmount) -> Gen Word8 -> Gen PeerSharingAmount
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word8
forall a. Arbitrary a => Gen a
arbitrary
    resp <- arbitrary
    oneof
      [ pure $ AnyMessage (MsgShareRequest amount)
      , pure $ AnyMessage (MsgSharePeers resp)
      , pure $ AnyMessage MsgDone
      ]

instance Eq peer => Eq (AnyMessage (PeerSharing peer)) where
    AnyMessage (MsgShareRequest PeerSharingAmount
amountA) == :: AnyMessage (PeerSharing peer)
-> AnyMessage (PeerSharing peer) -> Bool
== AnyMessage (MsgShareRequest PeerSharingAmount
amountB) = PeerSharingAmount
amountA PeerSharingAmount -> PeerSharingAmount -> Bool
forall a. Eq a => a -> a -> Bool
== PeerSharingAmount
amountB
    AnyMessage (MsgSharePeers [peerAddress1]
respA)     == AnyMessage (MsgSharePeers [peerAddress1]
respB)     = [peerAddress1]
respA   [peerAddress1] -> [peerAddress1] -> Bool
forall a. Eq a => a -> a -> Bool
== [peerAddress1]
[peerAddress1]
respB
    AnyMessage Message (PeerSharing peer) st st'
R:MessagePeerSharingfromto (*) peer st st'
MsgDone                   == AnyMessage Message (PeerSharing peer) st st'
R:MessagePeerSharingfromto (*) peer st st'
MsgDone                   = Bool
True
    AnyMessage (PeerSharing peer)
_ == AnyMessage (PeerSharing peer)
_                                                                       = Bool
False

prop_codec_PeerSharing :: AnyMessage (PeerSharing Int)
               -> Bool
prop_codec_PeerSharing :: AnyMessage (PeerSharing Int) -> Bool
prop_codec_PeerSharing AnyMessage (PeerSharing Int)
msg =
  (forall s. ST s Bool) -> Bool
forall a. (forall s. ST s a) -> a
runST (Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
-> AnyMessage (PeerSharing Int) -> ST s Bool
forall ps failure (m :: * -> *) bytes.
(Monad m, Eq (AnyMessage ps)) =>
Codec ps failure m bytes -> AnyMessage ps -> m Bool
prop_codecM ((Int -> Encoding)
-> (forall s. Decoder s Int)
-> Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
forall (m :: * -> *) peerAddress.
MonadST m =>
(peerAddress -> Encoding)
-> (forall s. Decoder s peerAddress)
-> Codec (PeerSharing peerAddress) DeserialiseFailure m ByteString
codecPeerSharing Int -> Encoding
CBOR.encodeInt Decoder s Int
forall s. Decoder s Int
CBOR.decodeInt) AnyMessage (PeerSharing Int)
msg)

-- TODO: this test is not needed; `prop_codec_valid_cbor` and
-- `prop_codec_PeerSharing` subsume it.
prop_codec_cbor
  :: AnyMessage (PeerSharing Int)
  -> Bool
prop_codec_cbor :: AnyMessage (PeerSharing Int) -> Bool
prop_codec_cbor AnyMessage (PeerSharing Int)
msg =
  (forall s. ST s Bool) -> Bool
forall a. (forall s. ST s a) -> a
runST (Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
-> AnyMessage (PeerSharing Int) -> ST s Bool
forall ps (m :: * -> *).
Monad m =>
Codec ps DeserialiseFailure m ByteString -> AnyMessage ps -> m Bool
prop_codec_cborM ((Int -> Encoding)
-> (forall s. Decoder s Int)
-> Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
forall (m :: * -> *) peerAddress.
MonadST m =>
(peerAddress -> Encoding)
-> (forall s. Decoder s peerAddress)
-> Codec (PeerSharing peerAddress) DeserialiseFailure m ByteString
codecPeerSharing Int -> Encoding
CBOR.encodeInt Decoder s Int
forall s. Decoder s Int
CBOR.decodeInt) AnyMessage (PeerSharing Int)
msg)

prop_codec_valid_cbor :: AnyMessage (PeerSharing Int) -> Property
prop_codec_valid_cbor :: AnyMessage (PeerSharing Int) -> Property
prop_codec_valid_cbor = Codec (PeerSharing Int) DeserialiseFailure IO ByteString
-> AnyMessage (PeerSharing Int) -> Property
forall ps.
Codec ps DeserialiseFailure IO ByteString
-> AnyMessage ps -> Property
prop_codec_valid_cbor_encoding ((Int -> Encoding)
-> (forall s. Decoder s Int)
-> Codec (PeerSharing Int) DeserialiseFailure IO ByteString
forall (m :: * -> *) peerAddress.
MonadST m =>
(peerAddress -> Encoding)
-> (forall s. Decoder s peerAddress)
-> Codec (PeerSharing peerAddress) DeserialiseFailure m ByteString
codecPeerSharing Int -> Encoding
CBOR.encodeInt Decoder s Int
forall s. Decoder s Int
CBOR.decodeInt)

-- | Check for data chunk boundary problems in the codec using 2 chunks.
--
prop_codec_splits2 :: AnyMessage (PeerSharing Int) -> Bool
prop_codec_splits2 :: AnyMessage (PeerSharing Int) -> Bool
prop_codec_splits2 AnyMessage (PeerSharing Int)
msg =
  (forall s. ST s Bool) -> Bool
forall a. (forall s. ST s a) -> a
runST ((ByteString -> [[ByteString]])
-> Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
-> AnyMessage (PeerSharing Int)
-> ST s Bool
forall ps failure (m :: * -> *) bytes.
(Monad m, Eq (AnyMessage ps)) =>
(bytes -> [[bytes]])
-> Codec ps failure m bytes -> AnyMessage ps -> m Bool
prop_codec_splitsM ByteString -> [[ByteString]]
splits2 ((Int -> Encoding)
-> (forall s. Decoder s Int)
-> Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
forall (m :: * -> *) peerAddress.
MonadST m =>
(peerAddress -> Encoding)
-> (forall s. Decoder s peerAddress)
-> Codec (PeerSharing peerAddress) DeserialiseFailure m ByteString
codecPeerSharing Int -> Encoding
CBOR.encodeInt Decoder s Int
forall s. Decoder s Int
CBOR.decodeInt) AnyMessage (PeerSharing Int)
msg)

-- | Check for data chunk boundary problems in the codec using 3 chunks.
--
prop_codec_splits3 :: AnyMessage (PeerSharing Int) -> Bool
prop_codec_splits3 :: AnyMessage (PeerSharing Int) -> Bool
prop_codec_splits3 AnyMessage (PeerSharing Int)
msg =
  (forall s. ST s Bool) -> Bool
forall a. (forall s. ST s a) -> a
runST ((ByteString -> [[ByteString]])
-> Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
-> AnyMessage (PeerSharing Int)
-> ST s Bool
forall ps failure (m :: * -> *) bytes.
(Monad m, Eq (AnyMessage ps)) =>
(bytes -> [[bytes]])
-> Codec ps failure m bytes -> AnyMessage ps -> m Bool
prop_codec_splitsM ByteString -> [[ByteString]]
splits3 ((Int -> Encoding)
-> (forall s. Decoder s Int)
-> Codec (PeerSharing Int) DeserialiseFailure (ST s) ByteString
forall (m :: * -> *) peerAddress.
MonadST m =>
(peerAddress -> Encoding)
-> (forall s. Decoder s peerAddress)
-> Codec (PeerSharing peerAddress) DeserialiseFailure m ByteString
codecPeerSharing Int -> Encoding
CBOR.encodeInt Decoder s Int
forall s. Decoder s Int
CBOR.decodeInt) AnyMessage (PeerSharing Int)
msg)

prop_byteLimits :: AnyMessage (PeerSharing Int)
                -> Bool
prop_byteLimits :: AnyMessage (PeerSharing Int) -> Bool
prop_byteLimits (AnyMessage (Message (PeerSharing Int) st st'
msg :: Message (PeerSharing Int) st st')) =
        ByteString -> Word
dataSize (Message (PeerSharing Int) st st' -> ByteString
forall (st :: PeerSharing Int) (st' :: PeerSharing Int).
(StateTokenI st, IsActiveState st (StateAgency st)) =>
Message (PeerSharing Int) st st' -> ByteString
encode Message (PeerSharing Int) st st'
msg)
     Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
<= SingPeerSharing st -> Word
forall {k} {peerAddress :: k} (st :: PeerSharing peerAddress).
IsActiveState st (StateAgency st) =>
SingPeerSharing st -> Word
sizeLimitForState (StateToken st
forall {ps} (st :: ps). StateTokenI st => StateToken st
stateToken :: StateToken st)
  where
    Codec { forall (st :: PeerSharing Int) (st' :: PeerSharing Int).
(StateTokenI st, IsActiveState st (StateAgency st)) =>
Message (PeerSharing Int) st st' -> ByteString
encode :: forall (st :: PeerSharing Int) (st' :: PeerSharing Int).
(StateTokenI st, IsActiveState st (StateAgency st)) =>
Message (PeerSharing Int) st st' -> ByteString
encode :: forall ps failure (m :: * -> *) bytes.
Codec ps failure m bytes
-> forall (st :: ps) (st' :: ps).
   (StateTokenI st, ActiveState st) =>
   Message ps st st' -> bytes
encode } = forall (m :: * -> *) peerAddress.
MonadST m =>
(peerAddress -> Encoding)
-> (forall s. Decoder s peerAddress)
-> Codec (PeerSharing peerAddress) DeserialiseFailure m ByteString
codecPeerSharing @IO Int -> Encoding
CBOR.encodeInt Decoder s Int
forall s. Decoder s Int
CBOR.decodeInt
    ProtocolSizeLimits { forall (st :: PeerSharing peerAddress).
IsActiveState st (StateAgency st) =>
StateToken st -> Word
sizeLimitForState :: forall (st :: PeerSharing peerAddress).
IsActiveState st (StateAgency st) =>
StateToken st -> Word
sizeLimitForState :: forall ps bytes.
ProtocolSizeLimits ps bytes
-> forall (st :: ps). ActiveState st => StateToken st -> Word
sizeLimitForState, ByteString -> Word
dataSize :: ByteString -> Word
dataSize :: forall ps bytes. ProtocolSizeLimits ps bytes -> bytes -> Word
dataSize } =
      (ByteString -> Word)
-> ProtocolSizeLimits (PeerSharing peerAddress) ByteString
forall {k} (peerAddress :: k) bytes.
(bytes -> Word)
-> ProtocolSizeLimits (PeerSharing peerAddress) bytes
byteLimitsPeerSharing (Int64 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Word) -> (ByteString -> Int64) -> ByteString -> Word
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Int64
BL.length)