<commit_before>{-# LANGUAGE ScopedTypeVariables #-}

-- | Specification of 'Pos.Block.Logic.Creation' module.

module Test.Pos.Block.Logic.CreationSpec
       ( spec
       ) where

import           Universum

import           Data.Default               (def)
import           Serokell.Data.Memory.Units (Byte, Gigabyte, convertUnit, fromBytes)
import           Test.Hspec                 (Spec, describe, runIO)
import           Test.Hspec.QuickCheck      (prop)
import           Test.QuickCheck            (Gen, Property, Testable, arbitrary, choose,
                                             counterexample, elements, forAll, generate,
                                             listOf, listOf1, oneof, property)

import           Pos.Arbitrary.Block        ()
import           Pos.Arbitrary.Delegation   (genDlgPayload)
import           Pos.Arbitrary.Txp          (SmallGoodTx (..), goodTxToTxAux)
import           Pos.Binary.Class           (biSize)
import           Pos.Block.Core             (BlockHeader, MainBlock)
import           Pos.Block.Logic            (RawPayload (..), createMainBlockPure)
import qualified Pos.Communication          ()
import           Pos.Constants              (blkSecurityParam, genesisMaxBlockSize)
import           Pos.Core                   (SlotId (..), unsafeMkLocalSlotIndex)
import           Pos.Crypto                 (SecretKey)
import           Pos.Delegation             (DlgPayload, ProxySKBlockInfo)
import           Pos.Ssc.Class              (Ssc (..), sscDefaultPayload)
import           Pos.Ssc.GodTossing         (GtPayload (..), SscGodTossing,
                                             commitmentMapEpochGen, mkVssCertificatesMap,
                                             vssCertificateEpochGen)
import           Pos.Txp.Core               (TxAux)
import           Pos.Update.Core            (UpdatePayload (..))
import           Pos.Util.Arbitrary         (makeSmall)

spec :: Spec
spec = describe "Block.Logic.Creation" $ do

    -- Sampling the minimum empty block size
    (sk0,prevHeader0) <- runIO $ generate arbitrary

    -- We multiply by 1.5 because there are different possible
    -- combinations of empty constructors and there's no out-of-box
    -- way to get maximum of them. Some settings produce 390b empty
    -- block, some -- 431b.
    let emptyBSize0 :: Byte
        emptyBSize0 = biSize (noSscBlock infLimit prevHeader0 [] def def sk0) -- in bytes
        emptyBSize :: Integral n => n
        emptyBSize = round $ (1.5 * fromIntegral emptyBSize0 :: Double)

    describe "createMainBlockPure" $ do
        prop "empty block size is sane" $ emptyBlk $ \blk0 -> leftToCounter blk0 $ \blk ->
            let s = biSize blk
            in counterexample ("Real block size: " <> show s) $ do
               -- 500 + 16 of serialization overhead. Note how being CBOR a var-len encoding,
               -- so 32 is an upper bound here.
               s <= 516 && s <= genesisMaxBlockSize
        prop "doesn't create blocks bigger than the limit" $
            forAll (choose (emptyBSize, emptyBSize * 10)) $ \(fromBytes -> limit) ->
            forAll arbitrary $ \(prevHeader, sk, updatePayload) ->
            forAll validGtPayloadGen $ \(gtPayload, slotId) ->
            forAll (genDlgPayload (siEpoch slotId)) $ \dlgPayload ->
            forAll (makeSmall $ listOf1 genTxAux) $ \txs ->
            let blk = producePureBlock limit prevHeader txs Nothing slotId
                                       dlgPayload gtPayload updatePayload sk<commit_msg>[CSL-1296] Raise empty block limit a bit & run more tests<commit_after>{-# LANGUAGE ScopedTypeVariables #-}

-- | Specification of 'Pos.Block.Logic.Creation' module.

module Test.Pos.Block.Logic.CreationSpec
       ( spec
       ) where

import           Universum

import           Data.Default               (def)
import           Serokell.Data.Memory.Units (Byte, Gigabyte, convertUnit, fromBytes)
import           Test.Hspec                 (Spec, describe, runIO)
import           Test.Hspec.QuickCheck      (modifyMaxSuccess, prop)
import           Test.QuickCheck            (Gen, Property, Testable, arbitrary, choose,
                                             counterexample, elements, forAll, generate,
                                             listOf, listOf1, oneof, property)

import           Pos.Arbitrary.Block        ()
import           Pos.Arbitrary.Delegation   (genDlgPayload)
import           Pos.Arbitrary.Txp          (SmallGoodTx (..), goodTxToTxAux)
import           Pos.Binary.Class           (biSize)
import           Pos.Block.Core             (BlockHeader, MainBlock)
import           Pos.Block.Logic            (RawPayload (..), createMainBlockPure)
import qualified Pos.Communication          ()
import           Pos.Constants              (blkSecurityParam, genesisMaxBlockSize)
import           Pos.Core                   (SlotId (..), unsafeMkLocalSlotIndex)
import           Pos.Crypto                 (SecretKey)
import           Pos.Delegation             (DlgPayload, ProxySKBlockInfo)
import           Pos.Ssc.Class              (Ssc (..), sscDefaultPayload)
import           Pos.Ssc.GodTossing         (GtPayload (..), SscGodTossing,
                                             commitmentMapEpochGen, mkVssCertificatesMap,
                                             vssCertificateEpochGen)
import           Pos.Txp.Core               (TxAux)
import           Pos.Update.Core            (UpdatePayload (..))
import           Pos.Util.Arbitrary         (makeSmall)

spec :: Spec
spec = describe "Block.Logic.Creation" $ do

    -- Sampling the minimum empty block size
    (sk0,prevHeader0) <- runIO $ generate arbitrary

    -- We multiply by 1.5 because there are different possible
    -- combinations of empty constructors and there's no out-of-box
    -- way to get maximum of them. Some settings produce 390b empty
    -- block, some -- 431b.
    let emptyBSize0 :: Byte
        emptyBSize0 = biSize (noSscBlock infLimit prevHeader0 [] def def sk0) -- in bytes
        emptyBSize :: Integral n => n
        emptyBSize = round $ (1.5 * fromIntegral emptyBSize0 :: Double)

    describe "createMainBlockPure" $ modifyMaxSuccess (const 1000) $ do
        prop "empty block size is sane" $ emptyBlk $ \blk0 -> leftToCounter blk0 $ \blk ->
            let s = biSize blk
            in counterexample ("Real block size: " <> show s <>
                               "\n\nBlock: " <> show blk) $
                 -- Various hashes and signatures in the block take 416
                 -- bytes; this is *completely* independent of encoding used.
                 -- Empirically, empty blocks don't get bigger than 550
                 -- bytes.
                 s <= 550 && s <= genesisMaxBlockSize
        prop "doesn't create blocks bigger than the limit" $
            forAll (choose (emptyBSize, emptyBSize * 10)) $ \(fromBytes -> limit) ->
            forAll arbitrary $ \(prevHeader, sk, updatePayload) ->
            forAll validGtPayloadGen $ \(gtPayload, slotId) ->
            forAll (genDlgPayload (siEpoch slotId)) $ \dlgPayload ->
            forAll (makeSmall $ listOf1 genTxAux) $ \txs ->
            let blk = producePureBlock limit prevHeader txs Nothing slotId
                                       dlgPayload gtPayload updatePayload sk
{'fraction_non_alphanumeric': 0.08319716775599129, 'fraction_numerical': 0.009940087145969499, 'mean_word_length': 1.6747997086671522, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2222638', 'n_tokens_mistral': 1960, 'n_tokens_neox': 1894, 'n_words': 557}