Skip to content

Commit b7fa122

Browse files
facundominguezamesgen
authored andcommitted
Limit the rate at which GDD is evaluated
1 parent 028883a commit b7fa122

File tree

5 files changed

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

5 files changed

+47
-17
lines changed

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

Lines changed: 30 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
@@ -54,7 +55,7 @@ data GenesisConfig = GenesisConfig
5455
{ gcBlockFetchConfig :: !GenesisBlockFetchConfiguration
5556
, gcChainSyncLoPBucketConfig :: !ChainSyncLoPBucketConfig
5657
, gcCSJConfig :: !CSJConfig
57-
, gcLoEAndGDDConfig :: !(LoEAndGDDConfig ())
58+
, gcLoEAndGDDConfig :: !(LoEAndGDDConfig LoEAndGDDParams)
5859
} deriving stock (Eq, Generic, Show)
5960

6061
-- | Genesis configuration flags and low-level args, as parsed from config file or CLI
@@ -66,6 +67,7 @@ data GenesisConfigFlags = GenesisConfigFlags
6667
, gcfBucketCapacity :: Maybe Integer
6768
, gcfBucketRate :: Maybe Integer
6869
, gcfCSJJumpSize :: Maybe Integer
70+
, gcfGDDRateLimit :: Maybe DiffTime
6971
} deriving stock (Eq, Generic, Show)
7072

7173
defaultGenesisConfigFlags :: GenesisConfigFlags
@@ -77,6 +79,7 @@ defaultGenesisConfigFlags = GenesisConfigFlags
7779
, gcfBucketCapacity = Nothing
7880
, gcfBucketRate = Nothing
7981
, gcfCSJJumpSize = Nothing
82+
, gcfGDDRateLimit = Nothing
8083
}
8184

8285
enableGenesisConfigDefault :: GenesisConfig
@@ -113,7 +116,7 @@ mkGenesisConfig (Just GenesisConfigFlags{..}) =
113116
}
114117
else CSJDisabled
115118
, gcLoEAndGDDConfig = if gcfEnableLoEAndGDD
116-
then LoEAndGDDEnabled ()
119+
then LoEAndGDDEnabled LoEAndGDDParams{lgpGDDRateLimit}
117120
else LoEAndGDDDisabled
118121
}
119122
where
@@ -124,21 +127,34 @@ mkGenesisConfig (Just GenesisConfigFlags{..}) =
124127
-- 3 * 2160 * 20 works in more recent ranges of slots, but causes syncing to
125128
-- block in byron.
126129
defaultCSJJumpSize = 2 * 2160
130+
defaultGDDRateLimit = 1.0 -- seconds
127131

128132
gbfcBulkSyncGracePeriod = fromInteger $ fromMaybe defaultBulkSyncGracePeriod gcfBulkSyncGracePeriod
129133
csbcCapacity = fromInteger $ fromMaybe defaultCapacity gcfBucketCapacity
130134
csbcRate = fromInteger $ fromMaybe defaultRate gcfBucketRate
131135
csjcJumpSize = fromInteger $ fromMaybe defaultCSJJumpSize gcfCSJJumpSize
136+
lgpGDDRateLimit = fromMaybe defaultGDDRateLimit gcfGDDRateLimit
137+
138+
newtype LoEAndGDDParams = LoEAndGDDParams
139+
{ -- | How often to evaluate GDD. 0 means as soon as possible.
140+
-- Otherwise, no faster than once every T seconds, where T is the
141+
-- value of the field.
142+
lgpGDDRateLimit :: DiffTime
143+
} deriving stock (Eq, Generic, Show)
132144

133145
-- | Genesis-related arguments needed by the NodeKernel initialization logic.
134146
data GenesisNodeKernelArgs m blk = GenesisNodeKernelArgs {
147+
gnkaLoEAndGDDArgs :: !(LoEAndGDDConfig (LoEAndGDDNodeKernelArgs m blk))
148+
}
149+
150+
data LoEAndGDDNodeKernelArgs m blk = LoEAndGDDNodeKernelArgs {
135151
-- | A TVar containing an action that returns the 'ChainDB.GetLoEFragment'
136152
-- action. We use this extra indirection to update this action after we
137153
-- opened the ChainDB (which happens before we initialize the NodeKernel).
138154
-- After that, this TVar will not be modified again.
139-
gnkaGetLoEFragment :: !(LoEAndGDDConfig (StrictTVar m (ChainDB.GetLoEFragment m blk)))
155+
lgnkaLoEFragmentTVar :: !(StrictTVar m (ChainDB.GetLoEFragment m blk))
156+
, lgnkaGDDRateLimit :: DiffTime
140157
}
141-
142158
-- | Create the initial 'GenesisNodeKernelArgs" (with a temporary
143159
-- 'ChainDB.GetLoEFragment' that will be replaced via 'setGetLoEFragment') and a
144160
-- function to update the 'ChainDbArgs' accordingly.
@@ -149,20 +165,24 @@ mkGenesisNodeKernelArgs ::
149165
, Complete ChainDbArgs m blk -> Complete ChainDbArgs m blk
150166
)
151167
mkGenesisNodeKernelArgs gcfg = do
152-
gnkaGetLoEFragment <- for (gcLoEAndGDDConfig gcfg) $ \() ->
153-
newTVarIO $ pure $
168+
gnkaLoEAndGDDArgs <- for (gcLoEAndGDDConfig gcfg) $ \p -> do
169+
loeFragmentTVar <- newTVarIO $ pure $
154170
-- Use the most conservative LoE fragment until 'setGetLoEFragment'
155171
-- is called.
156172
ChainDB.LoEEnabled $ AF.Empty AF.AnchorGenesis
157-
let updateChainDbArgs = case gnkaGetLoEFragment of
173+
pure LoEAndGDDNodeKernelArgs
174+
{ lgnkaLoEFragmentTVar = loeFragmentTVar
175+
, lgnkaGDDRateLimit = lgpGDDRateLimit p
176+
}
177+
let updateChainDbArgs = case gnkaLoEAndGDDArgs of
158178
LoEAndGDDDisabled -> id
159-
LoEAndGDDEnabled varGetLoEFragment -> \cfg ->
179+
LoEAndGDDEnabled lgnkArgs -> \cfg ->
160180
cfg { ChainDB.cdbsArgs =
161181
(ChainDB.cdbsArgs cfg) { ChainDB.cdbsLoE = getLoEFragment }
162182
}
163183
where
164-
getLoEFragment = join $ readTVarIO varGetLoEFragment
165-
pure (GenesisNodeKernelArgs {gnkaGetLoEFragment}, updateChainDbArgs)
184+
getLoEFragment = join $ readTVarIO $ lgnkaLoEFragmentTVar lgnkArgs
185+
pure (GenesisNodeKernelArgs{gnkaLoEAndGDDArgs}, updateChainDbArgs)
166186

167187
-- | Set 'gnkaGetLoEFragment' to the actual logic for determining the current
168188
-- LoE fragment.

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import Ouroboros.Consensus.MiniProtocol.ChainSync.Client
6666
import Ouroboros.Consensus.MiniProtocol.ChainSync.Client.InFutureCheck
6767
(SomeHeaderInFutureCheck)
6868
import Ouroboros.Consensus.Node.Genesis (GenesisNodeKernelArgs (..),
69-
LoEAndGDDConfig (..), setGetLoEFragment)
69+
LoEAndGDDConfig (..), LoEAndGDDNodeKernelArgs (..), setGetLoEFragment)
7070
import Ouroboros.Consensus.Node.GSM (GsmNodeKernelArgs (..))
7171
import qualified Ouroboros.Consensus.Node.GSM as GSM
7272
import Ouroboros.Consensus.Node.Run
@@ -273,20 +273,21 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers
273273
ps_POLICY_PEER_SHARE_STICKY_TIME
274274
ps_POLICY_PEER_SHARE_MAX_PEERS
275275

276-
case gnkaGetLoEFragment genesisArgs of
277-
LoEAndGDDDisabled -> pure ()
278-
LoEAndGDDEnabled varGetLoEFragment -> do
276+
case gnkaLoEAndGDDArgs genesisArgs of
277+
LoEAndGDDDisabled -> pure ()
278+
LoEAndGDDEnabled lgArgs -> do
279279
varLoEFragment <- newTVarIO $ AF.Empty AF.AnchorGenesis
280280
setGetLoEFragment
281281
(readTVar varGsmState)
282282
(readTVar varLoEFragment)
283-
varGetLoEFragment
283+
(lgnkaLoEFragmentTVar lgArgs)
284284

285285
void $ forkLinkedWatcher registry "NodeKernel.GDD" $
286286
gddWatcher
287287
cfg
288288
(gddTracer tracers)
289289
chainDB
290+
(lgnkaGDDRateLimit lgArgs)
290291
(readTVar varGsmState)
291292
-- TODO GDD should only consider (big) ledger peers
292293
(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
@@ -1035,7 +1035,7 @@ runThreadNetwork systemTime ThreadNetworkArgs
10351035
, getUseBootstrapPeers = pure DontUseBootstrapPeers
10361036
, publicPeerSelectionStateVar
10371037
, genesisArgs = GenesisNodeKernelArgs {
1038-
gnkaGetLoEFragment = LoEAndGDDDisabled
1038+
gnkaLoEAndGDDArgs = LoEAndGDDDisabled
10391039
}
10401040
}
10411041

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
@@ -83,6 +83,9 @@ gddWatcher ::
8383
=> TopLevelConfig blk
8484
-> Tracer m (TraceGDDEvent peer blk)
8585
-> ChainDB m blk
86+
-> DiffTime -- ^ How often to evaluate GDD. 0 means as soon as possible.
87+
-- Otherwise, no faster than once every T seconds, where T is
88+
-- the provided value.
8689
-> STM m GsmState
8790
-> STM m (Map peer (ChainSyncClientHandle m blk))
8891
-- ^ The ChainSync handles. We trigger the GDD whenever our 'GsmState'
@@ -95,7 +98,7 @@ gddWatcher ::
9598
-> Watcher m
9699
(GsmState, GDDStateView m blk peer)
97100
(Map peer (StrictMaybe (WithOrigin SlotNo), Bool))
98-
gddWatcher cfg tracer chainDb getGsmState getHandles varLoEFrag =
101+
gddWatcher cfg tracer chainDb rateLimit getGsmState getHandles varLoEFrag =
99102
Watcher {
100103
wInitial = Nothing
101104
, wReader = (,) <$> getGsmState <*> getGDDStateView
@@ -137,12 +140,17 @@ gddWatcher cfg tracer chainDb getGsmState getHandles varLoEFrag =
137140

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

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

0 commit comments

Comments
 (0)