{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Test.Consensus.Genesis.Tests.LongRangeAttack (tests) where
import Data.Functor (($>))
import Test.Consensus.Genesis.Setup
import Test.Consensus.Genesis.Setup.Classifiers
( allAdversariesForecastable
, allAdversariesSelectable
, classifiers
)
import Test.Consensus.PeerSimulator.Run (defaultSchedulerConfig)
import Test.Consensus.PointSchedule
import Test.Consensus.PointSchedule.Shrinking (shrinkPeerSchedules)
import Test.Tasty
import Test.Tasty.QuickCheck
import Test.Util.Orphans.IOLike ()
import Test.Util.TestBlock (TestBlock)
import Test.Util.TestEnv (adjustQuickCheckTests)
tests :: TestTree
tests :: TestTree
tests =
TestName -> [TestTree] -> TestTree
testGroup
TestName
"long range attack"
[
(Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
TestName -> Property -> TestTree
forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"one adversary" Property
prop_longRangeAttack
]
prop_longRangeAttack :: Property
prop_longRangeAttack :: Property
prop_longRangeAttack =
Property -> Property
forall prop. Testable prop => prop -> Property
noShrinking (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
forall blk prop.
(Testable prop, Condense (StateView blk),
CondenseList (NodeState blk), ShowProxy blk,
ShowProxy (Header blk), ConfigSupportsNode blk,
LedgerSupportsProtocol blk, SerialiseDiskConstraints blk,
BlockSupportsDiffusionPipelining blk, InspectLedger blk,
HasHardForkHistory blk, ConvertRawHash blk,
CanUpgradeLedgerTables (LedgerState blk),
HasPointScheduleTestParams blk, Eq (Header blk), Eq blk, Terse blk,
Condense (NodeState blk)) =>
Gen (GenesisTestFull blk)
-> SchedulerConfig
-> (GenesisTestFull blk -> StateView blk -> [GenesisTestFull blk])
-> (GenesisTestFull blk -> StateView blk -> prop)
-> Property
forAllGenesisTest @TestBlock
( do
gt@GenesisTest{gtBlockTree} <- Gen Word -> Gen (GenesisTest TestBlock ())
forall blk.
(HasHeader blk, IssueTestBlock blk) =>
Gen Word -> Gen (GenesisTest blk ())
genChains (Word -> Gen Word
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word
1)
ps <- stToGen (longRangeAttack gtBlockTree)
let cls = GenesisTest TestBlock () -> Classifiers
forall blk schedule.
HasHeader blk =>
GenesisTest blk schedule -> Classifiers
classifiers GenesisTest TestBlock ()
gt
if allAdversariesSelectable cls && allAdversariesForecastable cls
then pure $ gt $> ps
else discard
)
SchedulerConfig
defaultSchedulerConfig
GenesisTestFull TestBlock
-> StateView TestBlock -> [GenesisTestFull TestBlock]
forall blk.
(HasHeader blk, Ord blk) =>
GenesisTestFull blk -> StateView blk -> [GenesisTestFull blk]
shrinkPeerSchedules
(\GenesisTestFull TestBlock
genesisTest -> Bool -> Bool
not (Bool -> Bool)
-> (StateView TestBlock -> Bool) -> StateView TestBlock -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenesisTestFull TestBlock -> StateView TestBlock -> Bool
forall blk.
GetHeader blk =>
GenesisTestFull blk -> StateView blk -> Bool
selectedHonestChain GenesisTestFull TestBlock
genesisTest)