1+ {-# LANGUAGE DeriveGeneric #-}
12{-# LANGUAGE DeriveTraversable #-}
23{-# LANGUAGE DerivingStrategies #-}
34{-# LANGUAGE LambdaCase #-}
45{-# LANGUAGE NamedFieldPuns #-}
56{-# LANGUAGE NumericUnderscores #-}
7+ {-# LANGUAGE RecordWildCards #-}
68{-# LANGUAGE ScopedTypeVariables #-}
79
810module Ouroboros.Consensus.Node.Genesis (
911 -- * 'GenesisConfig'
1012 GenesisConfig (.. )
13+ , GenesisConfigFlags (.. )
1114 , LoEAndGDDConfig (.. )
15+ , defaultGenesisConfigFlags
1216 , disableGenesisConfig
1317 , enableGenesisConfigDefault
18+ , mkGenesisConfig
1419 -- * NodeKernel helpers
1520 , GenesisNodeKernelArgs (.. )
1621 , mkGenesisNodeKernelArgs
1722 , setGetLoEFragment
1823 ) where
1924
2025import Control.Monad (join )
26+ import Data.Maybe (fromMaybe )
2127import Data.Traversable (for )
28+ import GHC.Generics (Generic )
2229import Ouroboros.Consensus.Block
2330import Ouroboros.Consensus.MiniProtocol.ChainSync.Client
2431 (CSJConfig (.. ), CSJEnabledConfig (.. ),
@@ -34,47 +41,111 @@ import Ouroboros.Consensus.Util.Args
3441import Ouroboros.Consensus.Util.IOLike
3542import Ouroboros.Network.AnchoredFragment (AnchoredFragment )
3643import qualified Ouroboros.Network.AnchoredFragment as AF
44+ import Ouroboros.Network.BlockFetch
45+ (GenesisBlockFetchConfiguration (.. ))
3746
3847-- | Whether to en-/disable the Limit on Eagerness and the Genesis Density
3948-- Disconnector.
4049data LoEAndGDDConfig a =
4150 LoEAndGDDEnabled ! a
4251 | LoEAndGDDDisabled
43- deriving stock (Show , Functor , Foldable , Traversable )
52+ deriving stock (Eq , Generic , Show , Functor , Foldable , Traversable )
4453
4554-- | Aggregating the various configs for Genesis-related subcomponents.
46- data GenesisConfig = GenesisConfig {
47- gcChainSyncLoPBucketConfig :: ! ChainSyncLoPBucketConfig
55+ --
56+ -- Usually, 'enableGenesisConfigDefault' or 'disableGenesisConfig' can be used.
57+ -- See the haddocks of the types of the individual fields for details.
58+ data GenesisConfig = GenesisConfig
59+ { gcBlockFetchConfig :: ! GenesisBlockFetchConfiguration
60+ , gcChainSyncLoPBucketConfig :: ! ChainSyncLoPBucketConfig
4861 , gcCSJConfig :: ! CSJConfig
4962 , gcLoEAndGDDConfig :: ! (LoEAndGDDConfig () )
5063 , gcHistoricityCutoff :: ! (Maybe HistoricityCutoff )
64+ } deriving stock (Eq , Generic , Show )
65+
66+ -- | Genesis configuration flags and low-level args, as parsed from config file or CLI
67+ data GenesisConfigFlags = GenesisConfigFlags
68+ { gcfEnableCSJ :: Bool
69+ , gcfEnableLoEAndGDD :: Bool
70+ , gcfEnableLoP :: Bool
71+ , gcfBulkSyncGracePeriod :: Maybe Integer
72+ , gcfBucketCapacity :: Maybe Integer
73+ , gcfBucketRate :: Maybe Integer
74+ , gcfCSJJumpSize :: Maybe Integer
75+ } deriving stock (Eq , Generic , Show )
76+
77+ defaultGenesisConfigFlags :: GenesisConfigFlags
78+ defaultGenesisConfigFlags = GenesisConfigFlags
79+ { gcfEnableCSJ = True
80+ , gcfEnableLoEAndGDD = True
81+ , gcfEnableLoP = True
82+ , gcfBulkSyncGracePeriod = Nothing
83+ , gcfBucketCapacity = Nothing
84+ , gcfBucketRate = Nothing
85+ , gcfCSJJumpSize = Nothing
5186 }
5287
53- -- TODO justification/derivation from other parameters
5488enableGenesisConfigDefault :: GenesisConfig
55- enableGenesisConfigDefault = GenesisConfig {
56- gcChainSyncLoPBucketConfig = ChainSyncLoPBucketEnabled ChainSyncLoPBucketEnabledConfig {
57- csbcCapacity = 100_000 -- number of tokens
58- , csbcRate = 500 -- tokens per second leaking, 1/2ms
59- }
60- , gcCSJConfig = CSJEnabled CSJEnabledConfig {
61- csjcJumpSize = 3 * 2160 * 20 -- mainnet forecast range
62- }
63- , gcLoEAndGDDConfig = LoEAndGDDEnabled ()
64- -- Duration in seconds of one Cardano mainnet Shelley stability window
65- -- (3k/f slots times one second per slot) plus one extra hour as a
66- -- safety margin.
67- , gcHistoricityCutoff = Just $ HistoricityCutoff $ 3 * 2160 * 20 + 3600
68- }
89+ enableGenesisConfigDefault = mkGenesisConfig $ Just defaultGenesisConfigFlags
6990
7091-- | Disable all Genesis components, yielding Praos behavior.
7192disableGenesisConfig :: GenesisConfig
72- disableGenesisConfig = GenesisConfig {
73- gcChainSyncLoPBucketConfig = ChainSyncLoPBucketDisabled
93+ disableGenesisConfig = mkGenesisConfig Nothing
94+
95+ mkGenesisConfig :: Maybe GenesisConfigFlags -> GenesisConfig
96+ mkGenesisConfig Nothing = -- disable Genesis
97+ GenesisConfig
98+ { gcBlockFetchConfig = GenesisBlockFetchConfiguration
99+ { gbfcBulkSyncGracePeriod = 0 -- no grace period when Genesis is disabled
100+ }
101+ , gcChainSyncLoPBucketConfig = ChainSyncLoPBucketDisabled
74102 , gcCSJConfig = CSJDisabled
75103 , gcLoEAndGDDConfig = LoEAndGDDDisabled
76104 , gcHistoricityCutoff = Nothing
77105 }
106+ mkGenesisConfig (Just GenesisConfigFlags {.. }) =
107+ GenesisConfig
108+ { gcBlockFetchConfig = GenesisBlockFetchConfiguration
109+ { gbfcBulkSyncGracePeriod
110+ }
111+ , gcChainSyncLoPBucketConfig = if gcfEnableLoP
112+ then ChainSyncLoPBucketEnabled ChainSyncLoPBucketEnabledConfig
113+ { csbcCapacity
114+ , csbcRate
115+ }
116+ else ChainSyncLoPBucketDisabled
117+ , gcCSJConfig = if gcfEnableCSJ
118+ then CSJEnabled CSJEnabledConfig
119+ { csjcJumpSize
120+ }
121+ else CSJDisabled
122+ , gcLoEAndGDDConfig = if gcfEnableLoEAndGDD
123+ then LoEAndGDDEnabled ()
124+ else LoEAndGDDDisabled
125+ , -- Duration in seconds of one Cardano mainnet Shelley stability window
126+ -- (3k/f slots times one second per slot) plus one extra hour as a
127+ -- safety margin.
128+ gcHistoricityCutoff = Just $ HistoricityCutoff $ 3 * 2160 * 20 + 3600
129+ }
130+ where
131+ -- The minimum amount of time during which the Genesis BlockFetch logic will
132+ -- download blocks from a specific peer (even if it is not performing well
133+ -- during that period).
134+ defaultBulkSyncGracePeriod = 10 -- seconds
135+
136+ -- LoP parameters. Empirically, it takes less than 1ms to validate a header,
137+ -- so leaking one token per 2ms is conservative. The capacity of 100_000
138+ -- tokens corresponds to 200s, which is definitely enough to handle long GC
139+ -- pauses; we could even make this more conservative.
140+ defaultCapacity = 100_000 -- number of tokens
141+ defaultRate = 500 -- tokens per second leaking, 1/2ms
142+
143+ defaultCSJJumpSize = 3 * 2160 * 20 -- mainnet forecast range
144+
145+ gbfcBulkSyncGracePeriod = fromInteger $ fromMaybe defaultBulkSyncGracePeriod gcfBulkSyncGracePeriod
146+ csbcCapacity = fromInteger $ fromMaybe defaultCapacity gcfBucketCapacity
147+ csbcRate = fromInteger $ fromMaybe defaultRate gcfBucketRate
148+ csjcJumpSize = fromInteger $ fromMaybe defaultCSJJumpSize gcfCSJJumpSize
78149
79150-- | Genesis-related arguments needed by the NodeKernel initialization logic.
80151data GenesisNodeKernelArgs m blk = GenesisNodeKernelArgs {
@@ -124,9 +195,10 @@ setGetLoEFragment readGsmState readLoEFragment varGetLoEFragment =
124195 where
125196 getLoEFragment :: ChainDB. GetLoEFragment m blk
126197 getLoEFragment = atomically $ readGsmState >>= \ case
127- -- When the Honest Availability Assumption cannot currently be guaranteed, we should not select
128- -- any blocks that would cause our immutable tip to advance, so we
129- -- return the most conservative LoE fragment.
198+ -- When the Honest Availability Assumption cannot currently be
199+ -- guaranteed, we should not select any blocks that would cause our
200+ -- immutable tip to advance, so we return the most conservative LoE
201+ -- fragment.
130202 GSM. PreSyncing ->
131203 pure $ ChainDB. LoEEnabled $ AF. Empty AF. AnchorGenesis
132204 -- When we are syncing, return the current LoE fragment.
0 commit comments