Skip to content

Commit 31b1fa5

Browse files
facundominguezneilmayhew
authored andcommitted
Limit the rate at which GDD is evaluated
1 parent adbc26b commit 31b1fa5

File tree

5 files changed

+50
-17
lines changed
  • ouroboros-consensus-diffusion
  • ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Genesis

5 files changed

+50
-17
lines changed

ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node/Genesis.hs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module Ouroboros.Consensus.Node.Genesis (
1818
, mkGenesisConfig
1919
-- * NodeKernel helpers
2020
, GenesisNodeKernelArgs (..)
21+
, LoEAndGDDNodeKernelArgs (..)
2122
, mkGenesisNodeKernelArgs
2223
, setGetLoEFragment
2324
) where
@@ -59,7 +60,7 @@ data GenesisConfig = GenesisConfig
5960
{ gcBlockFetchConfig :: !GenesisBlockFetchConfiguration
6061
, gcChainSyncLoPBucketConfig :: !ChainSyncLoPBucketConfig
6162
, gcCSJConfig :: !CSJConfig
62-
, gcLoEAndGDDConfig :: !(LoEAndGDDConfig ())
63+
, gcLoEAndGDDConfig :: !(LoEAndGDDConfig LoEAndGDDParams)
6364
, gcHistoricityCutoff :: !(Maybe HistoricityCutoff)
6465
} deriving stock (Eq, Generic, Show)
6566

@@ -72,6 +73,7 @@ data GenesisConfigFlags = GenesisConfigFlags
7273
, gcfBucketCapacity :: Maybe Integer
7374
, gcfBucketRate :: Maybe Integer
7475
, gcfCSJJumpSize :: Maybe Integer
76+
, gcfGDDRateLimit :: Maybe DiffTime
7577
} deriving stock (Eq, Generic, Show)
7678

7779
defaultGenesisConfigFlags :: GenesisConfigFlags
@@ -83,6 +85,7 @@ defaultGenesisConfigFlags = GenesisConfigFlags
8385
, gcfBucketCapacity = Nothing
8486
, gcfBucketRate = Nothing
8587
, gcfCSJJumpSize = Nothing
88+
, gcfGDDRateLimit = Nothing
8689
}
8790

8891
enableGenesisConfigDefault :: GenesisConfig
@@ -120,7 +123,7 @@ mkGenesisConfig (Just GenesisConfigFlags{..}) =
120123
}
121124
else CSJDisabled
122125
, gcLoEAndGDDConfig = if gcfEnableLoEAndGDD
123-
then LoEAndGDDEnabled ()
126+
then LoEAndGDDEnabled LoEAndGDDParams{lgpGDDRateLimit}
124127
else LoEAndGDDDisabled
125128
, -- Duration in seconds of one Cardano mainnet Shelley stability window
126129
-- (3k/f slots times one second per slot) plus one extra hour as a
@@ -147,20 +150,35 @@ mkGenesisConfig (Just GenesisConfigFlags{..}) =
147150
-- eras.
148151
defaultCSJJumpSize = 2 * 2160 -- Byron forecast range
149152

153+
-- Limiting the performance impact of the GDD.
154+
defaultGDDRateLimit = 1.0 -- seconds
155+
150156
gbfcBulkSyncGracePeriod = fromInteger $ fromMaybe defaultBulkSyncGracePeriod gcfBulkSyncGracePeriod
151157
csbcCapacity = fromInteger $ fromMaybe defaultCapacity gcfBucketCapacity
152158
csbcRate = fromInteger $ fromMaybe defaultRate gcfBucketRate
153159
csjcJumpSize = fromInteger $ fromMaybe defaultCSJJumpSize gcfCSJJumpSize
160+
lgpGDDRateLimit = fromMaybe defaultGDDRateLimit gcfGDDRateLimit
161+
162+
newtype LoEAndGDDParams = LoEAndGDDParams
163+
{ -- | How often to evaluate GDD. 0 means as soon as possible.
164+
-- Otherwise, no faster than once every T seconds, where T is the
165+
-- value of the field.
166+
lgpGDDRateLimit :: DiffTime
167+
} deriving stock (Eq, Generic, Show)
154168

155169
-- | Genesis-related arguments needed by the NodeKernel initialization logic.
156170
data GenesisNodeKernelArgs m blk = GenesisNodeKernelArgs {
171+
gnkaLoEAndGDDArgs :: !(LoEAndGDDConfig (LoEAndGDDNodeKernelArgs m blk))
172+
}
173+
174+
data LoEAndGDDNodeKernelArgs m blk = LoEAndGDDNodeKernelArgs {
157175
-- | A TVar containing an action that returns the 'ChainDB.GetLoEFragment'
158176
-- action. We use this extra indirection to update this action after we
159177
-- opened the ChainDB (which happens before we initialize the NodeKernel).
160178
-- After that, this TVar will not be modified again.
161-
gnkaGetLoEFragment :: !(LoEAndGDDConfig (StrictTVar m (ChainDB.GetLoEFragment m blk)))
179+
lgnkaLoEFragmentTVar :: !(StrictTVar m (ChainDB.GetLoEFragment m blk))
180+
, lgnkaGDDRateLimit :: DiffTime
162181
}
163-
164182
-- | Create the initial 'GenesisNodeKernelArgs" (with a temporary
165183
-- 'ChainDB.GetLoEFragment' that will be replaced via 'setGetLoEFragment') and a
166184
-- function to update the 'ChainDbArgs' accordingly.
@@ -171,20 +189,24 @@ mkGenesisNodeKernelArgs ::
171189
, Complete ChainDbArgs m blk -> Complete ChainDbArgs m blk
172190
)
173191
mkGenesisNodeKernelArgs gcfg = do
174-
gnkaGetLoEFragment <- for (gcLoEAndGDDConfig gcfg) $ \() ->
175-
newTVarIO $ pure $
192+
gnkaLoEAndGDDArgs <- for (gcLoEAndGDDConfig gcfg) $ \p -> do
193+
loeFragmentTVar <- newTVarIO $ pure $
176194
-- Use the most conservative LoE fragment until 'setGetLoEFragment'
177195
-- is called.
178196
ChainDB.LoEEnabled $ AF.Empty AF.AnchorGenesis
179-
let updateChainDbArgs = case gnkaGetLoEFragment of
197+
pure LoEAndGDDNodeKernelArgs
198+
{ lgnkaLoEFragmentTVar = loeFragmentTVar
199+
, lgnkaGDDRateLimit = lgpGDDRateLimit p
200+
}
201+
let updateChainDbArgs = case gnkaLoEAndGDDArgs of
180202
LoEAndGDDDisabled -> id
181-
LoEAndGDDEnabled varGetLoEFragment -> \cfg ->
203+
LoEAndGDDEnabled lgnkArgs -> \cfg ->
182204
cfg { ChainDB.cdbsArgs =
183205
(ChainDB.cdbsArgs cfg) { ChainDB.cdbsLoE = getLoEFragment }
184206
}
185207
where
186-
getLoEFragment = join $ readTVarIO varGetLoEFragment
187-
pure (GenesisNodeKernelArgs {gnkaGetLoEFragment}, updateChainDbArgs)
208+
getLoEFragment = join $ readTVarIO $ lgnkaLoEFragmentTVar lgnkArgs
209+
pure (GenesisNodeKernelArgs{gnkaLoEAndGDDArgs}, updateChainDbArgs)
188210

189211
-- | Set 'gnkaGetLoEFragment' to the actual logic for determining the current
190212
-- LoE fragment.

ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/NodeKernel.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ import Ouroboros.Consensus.MiniProtocol.ChainSync.Client.HistoricityCh
6969
import Ouroboros.Consensus.MiniProtocol.ChainSync.Client.InFutureCheck
7070
(SomeHeaderInFutureCheck)
7171
import Ouroboros.Consensus.Node.Genesis (GenesisNodeKernelArgs (..),
72-
LoEAndGDDConfig (..), setGetLoEFragment)
72+
LoEAndGDDConfig (..), LoEAndGDDNodeKernelArgs (..),
73+
setGetLoEFragment)
7374
import Ouroboros.Consensus.Node.GSM (GsmNodeKernelArgs (..))
7475
import qualified Ouroboros.Consensus.Node.GSM as GSM
7576
import Ouroboros.Consensus.Node.Run
@@ -283,20 +284,21 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers
283284
ps_POLICY_PEER_SHARE_STICKY_TIME
284285
ps_POLICY_PEER_SHARE_MAX_PEERS
285286

286-
case gnkaGetLoEFragment genesisArgs of
287-
LoEAndGDDDisabled -> pure ()
288-
LoEAndGDDEnabled varGetLoEFragment -> do
287+
case gnkaLoEAndGDDArgs genesisArgs of
288+
LoEAndGDDDisabled -> pure ()
289+
LoEAndGDDEnabled lgArgs -> do
289290
varLoEFragment <- newTVarIO $ AF.Empty AF.AnchorGenesis
290291
setGetLoEFragment
291292
(readTVar varGsmState)
292293
(readTVar varLoEFragment)
293-
varGetLoEFragment
294+
(lgnkaLoEFragmentTVar lgArgs)
294295

295296
void $ forkLinkedWatcher registry "NodeKernel.GDD" $
296297
gddWatcher
297298
cfg
298299
(gddTracer tracers)
299300
chainDB
301+
(lgnkaGDDRateLimit lgArgs)
300302
(readTVar varGsmState)
301303
-- TODO GDD should only consider (big) ledger peers
302304
(cschcMap varChainSyncHandles)

ouroboros-consensus-diffusion/src/unstable-diffusion-testlib/Test/ThreadNet/Network.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ runThreadNetwork systemTime ThreadNetworkArgs
10341034
, getUseBootstrapPeers = pure DontUseBootstrapPeers
10351035
, publicPeerSelectionStateVar
10361036
, genesisArgs = GenesisNodeKernelArgs {
1037-
gnkaGetLoEFragment = LoEAndGDDDisabled
1037+
gnkaLoEAndGDDArgs = LoEAndGDDDisabled
10381038
}
10391039
, getDiffusionPipeliningSupport = DiffusionPipeliningOn
10401040
}

ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/PeerSimulator/Run.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ startNode schedulerConfig genesisTest interval = do
391391
lrConfig
392392
(mkGDDTracerTestBlock lrTracer)
393393
lnChainDb
394+
1.0 -- Default config value in NodeKernel.hs at the time or writing
394395
(pure GSM.Syncing) -- TODO actually run GSM
395396
(cschcMap handles)
396397
var

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Genesis/Governor.hs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ gddWatcher ::
8686
=> TopLevelConfig blk
8787
-> Tracer m (TraceGDDEvent peer blk)
8888
-> ChainDB m blk
89+
-> DiffTime -- ^ How often to evaluate GDD. 0 means as soon as possible.
90+
-- Otherwise, no faster than once every T seconds, where T is
91+
-- the provided value.
8992
-> STM m GsmState
9093
-> STM m (Map peer (ChainSyncClientHandle m blk))
9194
-- ^ The ChainSync handles. We trigger the GDD whenever our 'GsmState'
@@ -98,7 +101,7 @@ gddWatcher ::
98101
-> Watcher m
99102
(GsmState, GDDStateView m blk peer)
100103
(Map peer (StrictMaybe (WithOrigin SlotNo), Bool))
101-
gddWatcher cfg tracer chainDb getGsmState getHandles varLoEFrag =
104+
gddWatcher cfg tracer chainDb rateLimit getGsmState getHandles varLoEFrag =
102105
Watcher {
103106
wInitial = Nothing
104107
, wReader = (,) <$> getGsmState <*> getGDDStateView
@@ -140,12 +143,17 @@ gddWatcher cfg tracer chainDb getGsmState getHandles varLoEFrag =
140143

141144
wNotify :: (GsmState, GDDStateView m blk peer) -> m ()
142145
wNotify (_gsmState, stateView) = do
146+
t0 <- getMonotonicTime
143147
loeFrag <- evaluateGDD cfg tracer stateView
144148
oldLoEFrag <- atomically $ swapTVar varLoEFrag loeFrag
145149
-- The chain selection only depends on the LoE tip, so there
146150
-- is no point in retriggering it if the LoE tip hasn't changed.
147151
when (AF.headHash oldLoEFrag /= AF.headHash loeFrag) $
148152
void $ ChainDB.triggerChainSelectionAsync chainDb
153+
tf <- getMonotonicTime
154+
-- We limit the rate at which GDD is evaluated, otherwise it would
155+
-- be called every time a new header is validated.
156+
threadDelay $ rateLimit - diffTime tf t0
149157

150158
-- | Pure snapshot of the dynamic data the GDD operates on.
151159
data GDDStateView m blk peer = GDDStateView {

0 commit comments

Comments
 (0)