@@ -19,7 +19,7 @@ import Prelude hiding (seq)
19
19
import NoThunks.Class
20
20
21
21
import Control.Concurrent.Class.MonadMVar (MonadMVar )
22
- import Control.Concurrent.Class.MonadSTM
22
+ import Control.Concurrent.Class.MonadSTM.Strict
23
23
import Control.Monad.Class.MonadAsync
24
24
import Control.Monad.Class.MonadFork
25
25
import Control.Monad.Class.MonadSay
@@ -34,7 +34,7 @@ import Control.Tracer (Tracer (..), contramap)
34
34
import Data.ByteString.Lazy (ByteString )
35
35
import Data.ByteString.Lazy qualified as BSL
36
36
import Data.Function (on )
37
- import Data.List (intercalate , nubBy )
37
+ import Data.List (nubBy )
38
38
import Data.Map.Strict (Map )
39
39
import Data.Map.Strict qualified as Map
40
40
import Data.Maybe (fromMaybe )
@@ -59,7 +59,6 @@ import Test.Tasty (TestTree, testGroup)
59
59
import Test.Tasty.QuickCheck (testProperty )
60
60
61
61
import Control.Concurrent.Class.MonadMVar.Strict qualified as Strict
62
- import Control.Concurrent.Class.MonadSTM.Strict (StrictTVar )
63
62
import Control.Concurrent.Class.MonadSTM.Strict qualified as Strict
64
63
import Control.Monad (forM )
65
64
import Data.Foldable (traverse_ )
@@ -287,49 +286,58 @@ txSubmissionV2Simulation (TxSubmissionV2State state txDecisionPolicy) = do
287
286
--
288
287
prop_txSubmission :: TxSubmissionV2State -> Property
289
288
prop_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
333
341
334
342
-- | This test checks that all txs are downloaded from all available peers if
335
343
-- available.
@@ -371,15 +379,26 @@ prop_txSubmission_inflight st@(TxSubmissionV2State state _) =
371
379
inmp
372
380
in resultRepeatedValidTxs === maxRepeatedValidTxs
373
381
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
+
383
402
384
403
-- | Split a list into sub list of at most `n` elements.
385
404
--
0 commit comments