module Main where
import Data.Serialize (decode, encode)
import Haskoin.Block (blockHeader, headerHash)
import Test.Tasty (TestTree, defaultMain, testGroup)
import Test.Tasty.HUnit (testCase, (@?=))
import Test.Tasty.QuickCheck (elements, forAll, testProperty, (===))
import Bitcoin.CompactFilter (
blockFilterHeader,
encodeFilter,
filterContents,
isMember,
)
import Test.CompactFilter (genBlockFilter)
import qualified Test.Examples.Bip as BIP
import qualified Test.Examples.Mainnet as Mainnet
import Test.Util (Example (..))
main :: IO ()
main = do
bipExamples <- BIP.examples
mainnetExamples <- Mainnet.examples
defaultMain . testGroup "bip158 unit tests" $
[ testGroup "Serialization" [testRoundtrip]
, testGroup
"Filter"
[ testGroup "BIP 158" $ testFilter <$> bipExamples
, testGroup "Mainnet" $ testFilter <$> mainnetExamples
]
]
testRoundtrip :: TestTree
testRoundtrip = testProperty "serialization round trip" . forAll genBlockFilter $ \bf ->
decode (encode bf) === Right bf
testFilter :: Example -> TestTree
testFilter v = testGroup (testLabel v) $ [construction] <> [membership | not (null ss)]
where
construction = testCase "Construction" $ do
ourFilter @?= exampleFilter v
ourHeader @?= exampleHeader v
membership = testProperty "Filter membership" $
forAll (elements ss) $ \s ->
isMember bh [s] ourFilter
ourFilter = encodeFilter (examplePrevOuts v) block
ourHeader = blockFilterHeader (examplePrevHeader v) ourFilter
bh = headerHash $ blockHeader block
ss = filterContents (examplePrevOuts v) block
block = exampleBlock v
testLabel :: Example -> String
testLabel e = "Block " <> show (exampleHeight e)