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

{-# 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 (AnyMessage (..), AnyMessageAndAgency (..),
           Codec (..), PeerHasAgency (..), prop_codecM, prop_codec_splitsM)
import Network.TypedProtocol.Proofs (TerminalStates (..), connect)
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 (ClientHasAgency (..),
           Message (..), NobodyHasAgency (..), PeerSharing,
           PeerSharingAmount (..), ServerHasAgency (..))
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
-> (AnyMessageAndAgency (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec"            AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec
        , TestName
-> (AnyMessageAndAgency (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec cbor"       AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_cbor
        , TestName
-> (AnyMessageAndAgency (PeerSharing Int) -> Property) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec valid cbor" AnyMessageAndAgency (PeerSharing Int) -> Property
prop_codec_valid_cbor
        , TestName
-> (AnyMessageAndAgency (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec 2-splits"   AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_splits2
        , TestName -> Property -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"codec 3-splits"   (Int -> (AnyMessageAndAgency (PeerSharing Int) -> Bool) -> Property
forall prop. Testable prop => Int -> prop -> Property
withMaxSuccess Int
33 AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_splits3)
        , TestName
-> (AnyMessageAndAgency (PeerSharing Int) -> Bool) -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"byteLimits"       AnyMessageAndAgency (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 'StIdle (IOSim s) [Int]
-> Peer
     (PeerSharing Int) (FlipAgency 'AsClient) 'StIdle (IOSim s) ()
-> IOSim s ([Int], (), TerminalStates (PeerSharing Int))
forall ps (pr :: PeerRole) (st :: ps) (m :: * -> *) a b.
(Monad m, Protocol ps) =>
Peer ps pr st m a
-> Peer ps (FlipAgency pr) st m b -> m (a, b, TerminalStates ps)
connect
            (PeerSharingClient Int (IOSim s) [Int]
-> Peer (PeerSharing Int) 'AsClient 'StIdle (IOSim s) [Int]
forall (m :: * -> *) peerAddress a.
Monad m =>
PeerSharingClient peerAddress m a
-> Peer (PeerSharing peerAddress) 'AsClient '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)
-> Peer (PeerSharing Int) 'AsServer 'StIdle (IOSim s) ()
forall (m :: * -> *) peerAddress.
Monad m =>
PeerSharingServer peerAddress m
-> Peer (PeerSharing peerAddress) 'AsServer '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 NobodyHasAgency st
R:NobodyHasAgencyPeerSharingst (*) Int st
TokDone NobodyHasAgency st
R:NobodyHasAgencyPeerSharingst (*) Int 'StDone
TokDone) ->
       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
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
        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 :: ( MonadST    m
                , MonadAsync m
                , MonadCatch m
                )
             => Fun Word8 Int
             -> [PeerSharingAmount]
             -> m Property
prop_channel :: forall (m :: * -> *).
(MonadST m, MonadAsync m, MonadCatch 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 'StIdle m [Int]
-> Peer (PeerSharing Int) (FlipAgency 'AsClient) 'StIdle m ()
-> m ([Int], ())
forall (m :: * -> *) failure ps bytes (pr :: PeerRole) (st :: ps) a
       b.
(MonadAsync m, MonadCatch m, Show failure,
 forall (st' :: ps). Show (ClientHasAgency st'),
 forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) =>
m (Channel m bytes, Channel m bytes)
-> Tracer m (Role, TraceSendRecv ps)
-> Codec ps failure m bytes
-> Peer ps pr st m a
-> Peer ps (FlipAgency pr) 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 'StIdle m [Int]
client Peer (PeerSharing Int) (FlipAgency 'AsClient) 'StIdle m ()
Peer (PeerSharing Int) 'AsServer '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 'StIdle m [Int]
client = PeerSharingClient Int m [Int]
-> Peer (PeerSharing Int) 'AsClient 'StIdle m [Int]
forall (m :: * -> *) peerAddress a.
Monad m =>
PeerSharingClient peerAddress m a
-> Peer (PeerSharing peerAddress) 'AsClient 'StIdle m a
peerSharingClientPeer ([PeerSharingAmount] -> PeerSharingClient Int m [Int]
forall peer (m :: * -> *).
Monad m =>
[PeerSharingAmount] -> PeerSharingClient peer m [peer]
peerSharingClientCollect [PeerSharingAmount]
l)
    server :: Peer (PeerSharing Int) 'AsServer 'StIdle m ()
server = PeerSharingServer Int m
-> Peer (PeerSharing Int) 'AsServer 'StIdle m ()
forall (m :: * -> *) peerAddress.
Monad m =>
PeerSharingServer peerAddress m
-> Peer (PeerSharing peerAddress) 'AsServer '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 :: * -> *).
(MonadST m, MonadAsync m, MonadCatch 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 :: * -> *).
(MonadST m, MonadAsync m, MonadCatch m) =>
Fun Word8 Int -> [PeerSharingAmount] -> m Property
prop_channel Fun Word8 Int
f [PeerSharingAmount]
l)

--
-- Codec tests
--

instance Arbitrary peer => Arbitrary (AnyMessageAndAgency (PeerSharing peer)) where
  arbitrary :: Gen (AnyMessageAndAgency (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 $ AnyMessageAndAgency (ClientAgency TokIdle) (MsgShareRequest amount)
      , pure $ AnyMessageAndAgency (ServerAgency TokBusy) (MsgSharePeers resp)
      , pure $ AnyMessageAndAgency (ClientAgency TokIdle) 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 :: AnyMessageAndAgency (PeerSharing Int)
           -> Bool
prop_codec :: AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec AnyMessageAndAgency (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
-> AnyMessageAndAgency (PeerSharing Int) -> ST s Bool
forall ps failure (m :: * -> *) bytes.
(Monad m, Eq (AnyMessage ps)) =>
Codec ps failure m bytes -> AnyMessageAndAgency 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) AnyMessageAndAgency (PeerSharing Int)
msg)

prop_codec_cbor
  :: AnyMessageAndAgency (PeerSharing Int)
  -> Bool
prop_codec_cbor :: AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_cbor AnyMessageAndAgency (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
-> AnyMessageAndAgency (PeerSharing Int) -> ST s Bool
forall ps (m :: * -> *).
(Monad m, Eq (AnyMessage ps)) =>
Codec ps DeserialiseFailure m ByteString
-> AnyMessageAndAgency 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) AnyMessageAndAgency (PeerSharing Int)
msg)

prop_codec_valid_cbor :: AnyMessageAndAgency (PeerSharing Int) -> Property
prop_codec_valid_cbor :: AnyMessageAndAgency (PeerSharing Int) -> Property
prop_codec_valid_cbor = Codec (PeerSharing Int) DeserialiseFailure IO ByteString
-> AnyMessageAndAgency (PeerSharing Int) -> Property
forall ps.
Codec ps DeserialiseFailure IO ByteString
-> AnyMessageAndAgency 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 :: AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_splits2 :: AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_splits2 AnyMessageAndAgency (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
-> AnyMessageAndAgency (PeerSharing Int)
-> ST s Bool
forall ps failure (m :: * -> *) bytes.
(Monad m, Eq (AnyMessage ps)) =>
(bytes -> [[bytes]])
-> Codec ps failure m bytes -> AnyMessageAndAgency 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) AnyMessageAndAgency (PeerSharing Int)
msg)

-- | Check for data chunk boundary problems in the codec using 3 chunks.
--
prop_codec_splits3 :: AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_splits3 :: AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_codec_splits3 AnyMessageAndAgency (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
-> AnyMessageAndAgency (PeerSharing Int)
-> ST s Bool
forall ps failure (m :: * -> *) bytes.
(Monad m, Eq (AnyMessage ps)) =>
(bytes -> [[bytes]])
-> Codec ps failure m bytes -> AnyMessageAndAgency 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) AnyMessageAndAgency (PeerSharing Int)
msg)

prop_byteLimits :: AnyMessageAndAgency (PeerSharing Int)
                -> Bool
prop_byteLimits :: AnyMessageAndAgency (PeerSharing Int) -> Bool
prop_byteLimits (AnyMessageAndAgency PeerHasAgency pr st
agency Message (PeerSharing Int) st st'
msg) =
        ByteString -> Word
dataSize (PeerHasAgency pr st
-> Message (PeerSharing Int) st st' -> ByteString
forall (pr :: PeerRole) (st :: PeerSharing Int)
       (st' :: PeerSharing Int).
PeerHasAgency pr st
-> Message (PeerSharing Int) st st' -> ByteString
encode PeerHasAgency pr st
agency Message (PeerSharing Int) st st'
msg)
     Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
<= PeerHasAgency pr st -> Word
forall {k} {peerAddress :: k} (pr :: PeerRole)
       (st :: PeerSharing peerAddress).
PeerHasAgency pr st -> Word
sizeLimitForState PeerHasAgency pr st
agency
  where
    Codec { forall (pr :: PeerRole) (st :: PeerSharing Int)
       (st' :: PeerSharing Int).
PeerHasAgency pr st
-> Message (PeerSharing Int) st st' -> ByteString
encode :: forall (pr :: PeerRole) (st :: PeerSharing Int)
       (st' :: PeerSharing Int).
PeerHasAgency pr st
-> Message (PeerSharing Int) st st' -> ByteString
encode :: forall ps failure (m :: * -> *) bytes.
Codec ps failure m bytes
-> forall (pr :: PeerRole) (st :: ps) (st' :: ps).
   PeerHasAgency pr 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 (pr :: PeerRole) (st :: PeerSharing peerAddress).
PeerHasAgency pr st -> Word
sizeLimitForState :: forall (pr :: PeerRole) (st :: PeerSharing peerAddress).
PeerHasAgency pr st -> Word
sizeLimitForState :: forall ps bytes.
ProtocolSizeLimits ps bytes
-> forall (pr :: PeerRole) (st :: ps). PeerHasAgency pr 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} bytes (peerAddress :: k).
(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)