11{-# LANGUAGE DataKinds #-}
22{-# LANGUAGE DeriveGeneric #-}
3+ {-# LANGUAGE FlexibleContexts #-}
34{-# LANGUAGE GADTs #-}
45{-# LANGUAGE LambdaCase #-}
56{-# LANGUAGE MultiWayIf #-}
67{-# LANGUAGE NamedFieldPuns #-}
8+ {-# LANGUAGE ScopedTypeVariables #-}
9+ {-# LANGUAGE StandaloneDeriving #-}
10+ {-# LANGUAGE TypeApplications #-}
711{-# LANGUAGE TypeOperators #-}
12+ {-# LANGUAGE UndecidableInstances #-}
813
914-- | Definitions used in ThreadNet tests that involve two eras.
1015module Test.ThreadNet.Infra.TwoEras
11- ( -- * Generators
12- Partition (.. )
16+ ( -- * Common infrastructure used in the ThreadNet tests that perform an era crossing
17+
18+ -- ** A hard-fork block for two eras
19+ DualBlock
20+
21+ -- ** The varying data of the tests crossing between Shelley-based eras
22+ , TestSetup (.. )
23+
24+ -- ** Generators
25+ , Partition (.. )
1326 , genNonce
1427 , genPartition
1528 , genTestConfig
1629
17- -- * Era inspection
30+ -- ** Era inspection
1831 , ReachesEra2 (.. )
1932 , activeSlotCoeff
2033 , isFirstEraBlock
@@ -25,7 +38,7 @@ module Test.ThreadNet.Infra.TwoEras
2538 , secondEraOverlaySlots
2639 , shelleyEpochSize
2740
28- -- * Properties
41+ -- ** Properties
2942 , label_ReachesEra2
3043 , label_hadActiveNonOverlaySlots
3144 , prop_ReachesEra2
@@ -37,42 +50,138 @@ module Test.ThreadNet.Infra.TwoEras
3750import qualified Cardano.Chain.Common as CC.Common
3851import Cardano.Chain.ProtocolConstants (kEpochSlots )
3952import Cardano.Chain.Slotting (unEpochSlots )
40- import Cardano.Ledger.BaseTypes (unNonZero )
53+ import Cardano.Ledger.BaseTypes (nonZero , unNonZero )
4154import qualified Cardano.Ledger.BaseTypes as SL
4255import qualified Cardano.Protocol.TPraos.Rules.Overlay as SL
4356import Cardano.Slotting.EpochInfo
44- import Cardano.Slotting.Slot
45- ( EpochNo (.. )
46- , EpochSize (.. )
47- , SlotNo (.. )
48- )
57+ import Cardano.Slotting.Slot (EpochNo (.. ), EpochSize (.. ), SlotNo (.. ))
4958import Control.Exception (assert )
5059import Data.Functor ((<&>) )
5160import qualified Data.Map.Strict as Map
5261import Data.Maybe (isJust )
62+ import Data.Proxy (Proxy (.. ))
5363import Data.SOP.Strict (NS (.. ))
5464import Data.Set (Set )
5565import qualified Data.Set as Set
5666import Data.Word (Word64 )
5767import GHC.Generics (Generic )
68+ import Ouroboros.Consensus.BlockchainTime
69+ import Ouroboros.Consensus.Cardano.Condense ()
5870import Ouroboros.Consensus.Config.SecurityParam
5971import Ouroboros.Consensus.HardFork.Combinator
6072 ( HardForkBlock (.. )
6173 , OneEraBlock (.. )
6274 )
75+ import Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common
76+ ( isHardForkNodeToNodeEnabled
77+ )
6378import qualified Ouroboros.Consensus.HardFork.History.Util as Util
79+ import Ouroboros.Consensus.Node.NetworkProtocolVersion
6480import Ouroboros.Consensus.Node.ProtocolInfo
6581import Ouroboros.Consensus.NodeId
82+ import Ouroboros.Consensus.Shelley.Ledger.SupportsProtocol ()
83+ import Test.Consensus.Shelley.MockCrypto (MockCrypto )
6684import Test.QuickCheck
6785import Test.ThreadNet.General
6886import qualified Test.ThreadNet.Infra.Shelley as Shelley
87+ import Test.ThreadNet.Infra.ShelleyBasedHardFork
6988import Test.ThreadNet.Network (CalcMessageDelay (.. ), NodeOutput (.. ))
89+ import Test.ThreadNet.TxGen.Allegra ()
7090import Test.ThreadNet.Util.Expectations (NumBlocks (.. ))
91+ import Test.ThreadNet.Util.NodeToNodeVersion (genVersionFiltered )
7192import qualified Test.ThreadNet.Util.NodeTopology as Topo
7293import qualified Test.Util.BoolProps as BoolProps
7394import Test.Util.Orphans.Arbitrary ()
7495import Test.Util.Slots (NumSlots (.. ))
7596
97+ {- ------------------------------------------------------------------------------
98+ Block Type
99+ -------------------------------------------------------------------------------}
100+
101+ -- | A hard-fork block for two Shelley-based eras
102+ type DualBlock proto era1 era2 =
103+ ShelleyBasedHardForkBlock (proto MockCrypto ) era1 (proto MockCrypto ) era2
104+
105+ {- ------------------------------------------------------------------------------
106+ Test Setup
107+ -------------------------------------------------------------------------------}
108+
109+ -- | The varying data of the tests crossing between Shelley-based eras
110+ --
111+ -- Note: The Shelley nodes in this test all join, propose an update, and endorse
112+ -- it literally as soon as possible. Therefore, if the test reaches the end of
113+ -- the first epoch, the proposal will be adopted.
114+ data TestSetup proto era1 era2 = TestSetup
115+ { setupD :: Shelley. DecentralizationParam
116+ , setupHardFork :: Bool
117+ -- ^ whether the proposal should trigger a hard fork or not
118+ , setupInitialNonce :: SL. Nonce
119+ -- ^ the initial Shelley 'SL.ticknStateEpochNonce'
120+ --
121+ -- We vary it to ensure we explore different leader schedules.
122+ , setupK :: SecurityParam
123+ , setupPartition :: Partition
124+ , setupSlotLength :: SlotLength
125+ , setupTestConfig :: TestConfig
126+ , setupVersion :: (NodeToNodeVersion , BlockNodeToNodeVersion (DualBlock proto era1 era2 ))
127+ }
128+
129+ deriving instance Show (TestSetup proto era1 era2 )
130+
131+ instance
132+ SupportedNetworkProtocolVersion (DualBlock proto era1 era2 ) =>
133+ Arbitrary (TestSetup proto era1 era2 )
134+ where
135+ arbitrary = do
136+ setupD <-
137+ arbitrary
138+ -- The decentralization parameter cannot be 0 in the first
139+ -- Shelley epoch, since stake pools can only be created and
140+ -- delegated to via Shelley transactions.
141+ `suchThat` ((/= 0 ) . Shelley. decentralizationParamToRational)
142+ setupK <- SecurityParam <$> choose (8 , 10 ) `suchThatMap` nonZero
143+ -- If k < 8, common prefix violations become too likely in
144+ -- Praos mode for thin overlay schedules (ie low d), even for
145+ -- f=0.2.
146+
147+ setupInitialNonce <- genNonce
148+
149+ setupSlotLength <- arbitrary
150+
151+ let epochSize = EpochSize $ shelleyEpochSize setupK
152+ setupTestConfig <-
153+ genTestConfig
154+ setupK
155+ (epochSize, epochSize)
156+ let TestConfig {numCoreNodes, numSlots} = setupTestConfig
157+
158+ setupHardFork <- frequency [(49 , pure True ), (1 , pure False )]
159+
160+ -- TODO How reliable is the Byron-based partition duration logic when
161+ -- reused for Shelley?
162+ setupPartition <- genPartition numCoreNodes numSlots setupK
163+
164+ setupVersion <-
165+ genVersionFiltered
166+ isHardForkNodeToNodeEnabled
167+ (Proxy @ (DualBlock proto era1 era2 ))
168+
169+ pure
170+ TestSetup
171+ { setupD
172+ , setupHardFork
173+ , setupInitialNonce
174+ , setupK
175+ , setupPartition
176+ , setupSlotLength
177+ , setupTestConfig
178+ , setupVersion
179+ }
180+
181+ {- ------------------------------------------------------------------------------
182+ Network Partitions
183+ -------------------------------------------------------------------------------}
184+
76185-- | When and for how long the nodes are partitioned
77186--
78187-- The nodes are divided via message delays into two sub-networks by the parity
0 commit comments