@@ -19,7 +19,7 @@ import Prelude hiding (seq)
1919import NoThunks.Class
2020
2121import Control.Concurrent.Class.MonadMVar (MonadMVar )
22- import Control.Concurrent.Class.MonadSTM
22+ import Control.Concurrent.Class.MonadSTM.Strict
2323import Control.Monad.Class.MonadAsync
2424import Control.Monad.Class.MonadFork
2525import Control.Monad.Class.MonadSay
@@ -34,7 +34,7 @@ import Control.Tracer (Tracer (..), contramap)
3434import Data.ByteString.Lazy (ByteString )
3535import Data.ByteString.Lazy qualified as BSL
3636import Data.Function (on )
37- import Data.List (intercalate , nubBy )
37+ import Data.List (nubBy )
3838import Data.Map.Strict (Map )
3939import Data.Map.Strict qualified as Map
4040import Data.Maybe (fromMaybe )
@@ -59,7 +59,6 @@ import Test.Tasty (TestTree, testGroup)
5959import Test.Tasty.QuickCheck (testProperty )
6060
6161import Control.Concurrent.Class.MonadMVar.Strict qualified as Strict
62- import Control.Concurrent.Class.MonadSTM.Strict (StrictTVar )
6362import Control.Concurrent.Class.MonadSTM.Strict qualified as Strict
6463import Control.Monad (forM )
6564import Data.Foldable (traverse_ )
@@ -287,49 +286,58 @@ txSubmissionV2Simulation (TxSubmissionV2State state txDecisionPolicy) = do
287286--
288287prop_txSubmission :: TxSubmissionV2State -> Property
289288prop_txSubmission st =
290- ioProperty $ do
291- tr' <- evaluateTrace (runSimTrace (txSubmissionV2Simulation st))
292- case tr' of
293- SimException e trace -> do
294- return $ counterexample (intercalate " \n " $ show e : trace) False
295- SimDeadLock trace -> do
296- return $ counterexample (intercalate " \n " $ " Deadlock" : trace) False
297- SimReturn (inmp, outmps) _trace -> do
298- r <- mapM (\ outmp -> do
299- let outUniqueTxIds = nubBy (on (==) getTxId) outmp
300- outValidTxs = filter getTxValid outmp
301- case ( length outUniqueTxIds == length outmp
302- , length outValidTxs == length outmp
303- ) of
304- (True , True ) ->
305- -- If we are presented with a stream of unique txids for valid
306- -- transactions the inbound transactions should match the outbound
307- -- transactions exactly.
308- return $ counterexample (" (True, True) " ++ show outmp)
309- $ checkMempools inmp (take (length inmp) outValidTxs)
310-
311- (True , False ) ->
312- -- If we are presented with a stream of unique txids then we should have
313- -- fetched all valid transactions.
314- return $ counterexample (" (True, False) " ++ show outmp)
315- $ checkMempools inmp (take (length inmp) outValidTxs)
316-
317- (False , True ) ->
318- -- If we are presented with a stream of valid txids then we should have
319- -- fetched some version of those transactions.
320- return $ counterexample (" (False, True) " ++ show outmp)
321- $ checkMempools (map getTxId inmp)
322- (take (length inmp)
323- (map getTxId $ filter getTxValid outUniqueTxIds))
324-
325- (False , False ) ->
326- -- If we are presented with a stream of valid and invalid Txs with
327- -- duplicate txids we're content with completing the protocol
328- -- without error.
329- return $ property True )
330- outmps
331- return $ counterexample (intercalate " \n " _trace)
332- $ conjoin r
289+ let tr = runSimTrace (txSubmissionV2Simulation st) in
290+ case traceResult True tr of
291+ Left e ->
292+ counterexample (show e)
293+ . counterexample (ppTrace tr)
294+ $ False
295+ Right (inmp, outmps) ->
296+ counterexample (ppTrace tr)
297+ $ conjoin (validate inmp `map` outmps)
298+ where
299+ validate :: [Tx Int ] -- the inbound mempool
300+ -> [Tx Int ] -- one of the outbound mempools
301+ -> Property
302+ validate inmp outmp =
303+ let outUniqueTxIds = nubBy (on (==) getTxId) outmp
304+ outValidTxs = filter getTxValid outmp
305+ in
306+ case ( length outUniqueTxIds == length outmp
307+ , length outValidTxs == length outmp
308+ ) of
309+ x@ (True , True ) ->
310+ -- If we are presented with a stream of unique txids for valid
311+ -- transactions the inbound transactions should match the outbound
312+ -- transactions exactly.
313+ counterexample (show x)
314+ . counterexample (show inmp)
315+ . counterexample (show outmp)
316+ $ checkMempools inmp (take (length inmp) outValidTxs)
317+
318+ x@ (True , False ) ->
319+ -- If we are presented with a stream of unique txids then we should have
320+ -- fetched all valid transactions.
321+ counterexample (show x)
322+ . counterexample (show inmp)
323+ . counterexample (show outmp)
324+ $ checkMempools inmp (take (length inmp) outValidTxs)
325+
326+ x@ (False , True ) ->
327+ -- If we are presented with a stream of valid txids then we should have
328+ -- fetched some version of those transactions.
329+ counterexample (show x)
330+ . counterexample (show inmp)
331+ . counterexample (show outmp)
332+ $ checkMempools (map getTxId inmp)
333+ (take (length inmp)
334+ (map getTxId $ filter getTxValid outUniqueTxIds))
335+
336+ (False , False ) ->
337+ -- If we are presented with a stream of valid and invalid Txs with
338+ -- duplicate txids we're content with completing the protocol
339+ -- without error.
340+ property True
333341
334342-- | This test checks that all txs are downloaded from all available peers if
335343-- available.
@@ -371,15 +379,26 @@ prop_txSubmission_inflight st@(TxSubmissionV2State state _) =
371379 inmp
372380 in resultRepeatedValidTxs === maxRepeatedValidTxs
373381
374- checkMempools :: (Eq a , Show a ) => [a ] -> [a ] -> Property
375- checkMempools [] [] = property True
376- checkMempools _ [] = property True
377- checkMempools [] _ = property False
378- checkMempools inp@ (i : is) outp@ (o : os) =
379- if o == i then counterexample (show inp ++ " " ++ show outp)
380- $ checkMempools is os
381- else counterexample (show inp ++ " " ++ show outp)
382- $ checkMempools is outp
382+
383+ -- | Check that the inbound mempool contains all outbound `tx`s as a proper
384+ -- subsequence. It might contain more `tx`s from other peers.
385+ --
386+ checkMempools :: Eq tx
387+ => [tx ] -- inbound mempool
388+ -> [tx ] -- outbound mempool
389+ -> Bool
390+ checkMempools _ [] = True -- all outbound `tx` were found in the inbound
391+ -- mempool
392+ checkMempools [] (_: _) = False -- outbound mempool contains `tx`s which were
393+ -- not transferred to the inbound mempool
394+ checkMempools (i : is') os@ (o : os')
395+ | i == o
396+ = checkMempools is' os'
397+
398+ | otherwise
399+ -- `_i` is not present in the outbound mempool, we can skip it.
400+ = checkMempools is' os
401+
383402
384403-- | Split a list into sub list of at most `n` elements.
385404--
0 commit comments