haskoin-core-0.10.0: src/Network/Haskoin/Test/Network.hs
{-|
Module : Network.Haskoin.Test.Network
Copyright : No rights reserved
License : UNLICENSE
Maintainer : xenog@protonmail.com
Stability : experimental
Portability : POSIX
-}
module Network.Haskoin.Test.Network where
import qualified Data.ByteString as BS (empty, pack)
import qualified Data.ByteString.Char8 as C8
import Data.Word (Word16, Word32)
import Network.Haskoin.Network
import Network.Haskoin.Test.Crypto
import Network.Haskoin.Test.Util
import Network.Socket (SockAddr (..))
import Test.QuickCheck
-- | Arbitrary 'VarInt'.
arbitraryVarInt :: Gen VarInt
arbitraryVarInt = VarInt <$> arbitrary
-- | Arbitrary 'VarString'.
arbitraryVarString :: Gen VarString
arbitraryVarString = VarString <$> arbitraryBS
-- | Arbitrary 'NetworkAddress'.
arbitraryNetworkAddress :: Gen NetworkAddress
arbitraryNetworkAddress = do
s <- arbitrary
a <- arbitrary
p <- arbitrary
d <- oneof
[ do
b <- arbitrary
c <- arbitrary
d <- arbitrary
return $ SockAddrInet6 (fromIntegral p) 0 (a,b,c,d) 0
, return $ SockAddrInet (fromIntegral (p :: Word16)) a
]
let n = sockToHostAddress d
return $ NetworkAddress s n
-- | Arbitrary 'NetworkAddressTime'.
arbitraryNetworkAddressTime :: Gen (Word32, NetworkAddress)
arbitraryNetworkAddressTime = (,) <$> arbitrary <*> arbitraryNetworkAddress
-- | Arbitrary 'InvType'.
arbitraryInvType :: Gen InvType
arbitraryInvType = elements [InvError, InvTx, InvBlock, InvMerkleBlock]
-- | Arbitrary 'InvVector'.
arbitraryInvVector :: Gen InvVector
arbitraryInvVector = InvVector <$> arbitraryInvType <*> arbitraryHash256
-- | Arbitrary non-empty 'Inv'.
arbitraryInv1 :: Gen Inv
arbitraryInv1 = Inv <$> listOf1 arbitraryInvVector
-- | Arbitrary 'Version'.
arbitraryVersion :: Gen Version
arbitraryVersion =
Version <$> arbitrary
<*> arbitrary
<*> arbitrary
<*> arbitraryNetworkAddress
<*> arbitraryNetworkAddress
<*> arbitrary
<*> arbitraryVarString
<*> arbitrary
<*> arbitrary
-- | Arbitrary non-empty 'Addr'.
arbitraryAddr1 :: Gen Addr
arbitraryAddr1 = Addr <$> listOf1 arbitraryNetworkAddressTime
-- | Arbitrary 'Alert' with random payload and signature. Signature is not
-- valid.
arbitraryAlert :: Gen Alert
arbitraryAlert = Alert <$> arbitraryVarString <*> arbitraryVarString
-- | Arbitrary 'Reject'.
arbitraryReject :: Gen Reject
arbitraryReject = do
m <- arbitraryMessageCommand
c <- arbitraryRejectCode
s <- arbitraryVarString
d <- oneof [ return BS.empty
, BS.pack <$> vectorOf 32 arbitrary
]
return $ Reject m c s d
-- | Arbitrary 'RejectCode'.
arbitraryRejectCode :: Gen RejectCode
arbitraryRejectCode =
elements
[ RejectMalformed
, RejectInvalid
, RejectInvalid
, RejectDuplicate
, RejectNonStandard
, RejectDust
, RejectInsufficientFee
, RejectCheckpoint
]
-- | Arbitrary non-empty 'GetData'.
arbitraryGetData :: Gen GetData
arbitraryGetData = GetData <$> listOf1 arbitraryInvVector
-- | Arbitrary 'NotFound'.
arbitraryNotFound :: Gen NotFound
arbitraryNotFound = NotFound <$> listOf1 arbitraryInvVector
-- | Arbitrary 'Ping'.
arbitraryPing :: Gen Ping
arbitraryPing = Ping <$> arbitrary
-- | Arbitrary 'Pong'.
arbitraryPong :: Gen Pong
arbitraryPong = Pong <$> arbitrary
-- | Arbitrary bloom filter flags.
arbitraryBloomFlags :: Gen BloomFlags
arbitraryBloomFlags =
elements
[ BloomUpdateNone
, BloomUpdateAll
, BloomUpdateP2PubKeyOnly
]
-- | Arbitrary bloom filter with its corresponding number of elements
-- and false positive rate.
arbitraryBloomFilter :: Gen (Int, Double, BloomFilter)
arbitraryBloomFilter = do
n <- choose (0,100000)
fp <- choose (1e-8,1)
tweak <- arbitrary
fl <- arbitraryBloomFlags
return (n, fp, bloomCreate n fp tweak fl)
-- | Arbitrary 'FilterLoad'.
arbitraryFilterLoad :: Gen FilterLoad
arbitraryFilterLoad = do
(_, _, bf) <- arbitraryBloomFilter
return $ FilterLoad bf
-- | Arbitrary 'FilterAdd'.
arbitraryFilterAdd :: Gen FilterAdd
arbitraryFilterAdd = FilterAdd <$> arbitraryBS
-- | Arbitrary 'MessageCommand'.
arbitraryMessageCommand :: Gen MessageCommand
arbitraryMessageCommand = do
ASCIIString str <- arbitrary
elements
[ MCVersion
, MCVerAck
, MCAddr
, MCInv
, MCGetData
, MCNotFound
, MCGetBlocks
, MCGetHeaders
, MCTx
, MCBlock
, MCMerkleBlock
, MCHeaders
, MCGetAddr
, MCFilterLoad
, MCFilterAdd
, MCFilterClear
, MCPing
, MCPong
, MCAlert
, MCOther (C8.take 12 (C8.pack (filter (/= '\NUL') str)))
]