@@ -35,6 +35,7 @@ import Data.Monoid (Sum (..))
35
35
import Data.Sequence.Strict qualified as StrictSeq
36
36
import Data.Set (Set )
37
37
import Data.Set qualified as Set
38
+ import Data.Typeable
38
39
39
40
import NoThunks.Class
40
41
@@ -46,6 +47,7 @@ import Ouroboros.Network.TxSubmission.Inbound.Policy
46
47
import Ouroboros.Network.TxSubmission.Inbound.State (PeerTxState (.. ),
47
48
SharedTxState (.. ))
48
49
import Ouroboros.Network.TxSubmission.Inbound.State qualified as TXS
50
+ import Ouroboros.Network.TxSubmission.Inbound.Types qualified as TXS
49
51
50
52
import Test.Ouroboros.Network.BlockFetch (PeerGSVT (.. ))
51
53
import Test.Ouroboros.Network.TxSubmission.Types
@@ -306,7 +308,7 @@ mkArbPeerTxState mempoolHasTxFun txIdsInflight unacked txMaskMap =
306
308
where
307
309
mempoolHasTx = apply mempoolHasTxFun
308
310
availableTxIds = Map. fromList
309
- [ (txid, getTxSize tx) | (txid, TxAvailable tx _) <- Map. assocs txMaskMap
311
+ [ (txid, getTxAdvSize tx) | (txid, TxAvailable tx _) <- Map. assocs txMaskMap
310
312
, not (mempoolHasTx txid)
311
313
]
312
314
unknownTxs = Set. fromList
@@ -315,7 +317,7 @@ mkArbPeerTxState mempoolHasTxFun txIdsInflight unacked txMaskMap =
315
317
]
316
318
317
319
requestedTxIdsInflight = fromIntegral txIdsInflight
318
- requestedTxsInflightSize = foldMap getTxSize inflightMap
320
+ requestedTxsInflightSize = foldMap getTxAdvSize inflightMap
319
321
requestedTxsInflight = Map. keysSet inflightMap
320
322
321
323
-- exclude `txid`s which are already in the mempool, we never request such
@@ -759,12 +761,20 @@ instance Arbitrary ArbCollectTxs where
759
761
760
762
receivedTx <- sublistOf requestedTxIds'
761
763
>>= traverse (\ txid -> do
764
+ -- real size, which might be different from
765
+ -- the advertised size
766
+ size <- frequency [ (9 , pure (availableTxIds Map. ! txid))
767
+ , (1 , chooseEnum (0 , maxTxSize))
768
+ ]
769
+
762
770
valid <- frequency [(4 , pure True ), (1 , pure False )]
763
- pure $ Tx { getTxId = txid,
764
- getTxSize = availableTxIds Map. ! txid,
765
- getTxValid = valid })
771
+ pure $ Tx { getTxId = txid,
772
+ getTxSize = size,
773
+ -- `availableTxIds` contains advertised sizes
774
+ getTxAdvSize = availableTxIds Map. ! txid,
775
+ getTxValid = valid })
766
776
767
- pure $ assert (foldMap getTxSize receivedTx <= requestedTxsInflightSize)
777
+ pure $ assert (foldMap getTxAdvSize receivedTx <= requestedTxsInflightSize)
768
778
$ ArbCollectTxs mempoolHasTxFun
769
779
(Set. fromList requestedTxIds')
770
780
(Map. fromList [ (getTxId tx, tx) | tx <- receivedTx ])
@@ -856,24 +866,49 @@ prop_collectTxsImpl (ArbCollectTxs _mempoolHasTxFun txidsRequested txsReceived p
856
866
label (" number of txids inflight " ++ labelInt 25 5 (Map. size $ inflightTxs st)) $
857
867
label (" number of txids requested " ++ labelInt 25 5 (Set. size txidsRequested)) $
858
868
label (" number of txids received " ++ labelInt 10 2 (Map. size txsReceived)) $
859
-
860
- -- InboundState invariant
861
- counterexample
862
- ( " InboundState invariant violation:\n " ++ show st' ++ " \n "
863
- ++ show ps'
864
- )
865
- (sharedTxStateInvariant st')
866
-
867
- .&&.
868
- -- `collectTxsImpl` doesn't modify unacknowledged TxId's
869
- counterexample " acknowledged property violation"
870
- ( let unacked = toList $ unacknowledgedTxIds ps
871
- unacked' = toList $ unacknowledgedTxIds ps'
872
- in unacked === unacked'
873
- )
869
+ label (" hasTxSizeError " ++ show hasTxSizeErr) $
870
+
871
+ case TXS. collectTxsImpl getTxSize peeraddr txidsRequested txsReceived st of
872
+ Right st' | not hasTxSizeErr ->
873
+ let ps' = peerTxStates st' Map. ! peeraddr in
874
+ -- InboundState invariant
875
+ counterexample
876
+ ( " InboundState invariant violation:\n " ++ show st' ++ " \n "
877
+ ++ show ps'
878
+ )
879
+ (sharedTxStateInvariant st')
880
+
881
+ .&&.
882
+ -- `collectTxsImpl` doesn't modify unacknowledged TxId's
883
+ counterexample " acknowledged property violation"
884
+ ( let unacked = toList $ unacknowledgedTxIds ps
885
+ unacked' = toList $ unacknowledgedTxIds ps'
886
+ in unacked === unacked'
887
+ )
888
+
889
+ Right _ ->
890
+ counterexample " collectTxsImpl should return Left"
891
+ . counterexample (show txsReceived)
892
+ $ False
893
+ Left _ | not hasTxSizeErr ->
894
+ counterexample " collectTxsImpl should return Right" False
895
+
896
+ Left (TXS. ProtocolErrorTxSizeError as) ->
897
+ counterexample (show as)
898
+ $ Set. fromList ((\ (txid, _, _) -> coerceTxId txid) `map` as)
899
+ ===
900
+ Map. keysSet (Map. filter (\ tx -> getTxSize tx /= getTxAdvSize tx) txsReceived)
901
+ Left e ->
902
+ counterexample (" unexpected error: " ++ show e) False
874
903
where
875
- st' = TXS. collectTxsImpl peeraddr txidsRequested txsReceived st
876
- ps' = peerTxStates st' Map. ! peeraddr
904
+ hasTxSizeErr = any (\ tx -> getTxSize tx /= getTxAdvSize tx) txsReceived
905
+
906
+ -- The `ProtocolErrorTxSizeError` type is an existential type. We know that
907
+ -- the type of `txid` is `TxId`, we just don't have evidence for it.
908
+ coerceTxId :: Typeable txid => txid -> TxId
909
+ coerceTxId txid = case cast txid of
910
+ Just a -> a
911
+ Nothing -> error " impossible happened! Is the test still using `TxId` for `txid`?"
877
912
878
913
879
914
-- | Verify that `SharedTxState` returned by `collectTxsImpl` if evaluated to
@@ -883,11 +918,11 @@ prop_collectTxsImpl_nothunks
883
918
:: ArbCollectTxs
884
919
-> Property
885
920
prop_collectTxsImpl_nothunks (ArbCollectTxs _mempoolHasTxFun txidsRequested txsReceived peeraddr _ st) =
886
- case unsafeNoThunks $! st' of
887
- Nothing -> property True
888
- Just ctx -> counterexample ( show ctx) False
889
- where
890
- st' = TXS. collectTxsImpl peeraddr txidsRequested txsReceived st
921
+ case TXS. collectTxsImpl getTxSize peeraddr txidsRequested txsReceived st of
922
+ Right st' -> case unsafeNoThunks $! st' of
923
+ Nothing -> property True
924
+ Just ctx -> counterexample ( show ctx) False
925
+ Left _ -> property True
891
926
892
927
893
928
newtype ArbTxDecisionPolicy = ArbTxDecisionPolicy TxDecisionPolicy
0 commit comments