7
7
{-# LANGUAGE TupleSections #-}
8
8
{-# LANGUAGE TypeApplications #-}
9
9
10
+ -- REVIEW: required by constraint 'HeaderHash blk ~ HeaderHash (t blk)'
11
+ --
12
+ -- ... to suppress warning 'The use of ‘~’ without TypeOperators will become an error in a future GHC release.'
13
+ {-# LANGUAGE TypeOperators #-}
14
+
10
15
-- | Followers
11
16
module Ouroboros.Consensus.Storage.ChainDB.Impl.Follower (
12
17
closeAllFollowers
@@ -40,6 +45,7 @@ import Ouroboros.Consensus.Util.STM (blockUntilJust)
40
45
import Ouroboros.Network.AnchoredFragment (AnchoredFragment )
41
46
import qualified Ouroboros.Network.AnchoredFragment as AF
42
47
import Ouroboros.Network.Block (ChainUpdate (.. ))
48
+ import Ouroboros.Consensus.HeaderValidation (HeaderWithTime , ProjectHeader (.. ))
43
49
44
50
{- ------------------------------------------------------------------------------
45
51
Accessing the environment
@@ -203,14 +209,15 @@ instructionHelper ::
203
209
, GetHeader blk
204
210
, HasNestedContent Header blk
205
211
, EncodeDiskDep (NestedCtxt Header ) blk
206
- , Traversable f , Applicative f
212
+ , Traversable f
213
+ , Applicative f
207
214
)
208
215
=> ResourceRegistry m
209
216
-> StrictTVar m (FollowerState m blk b )
210
217
-> ChainType
211
218
-> BlockComponent blk b
212
- -> ( STM m (Maybe (ChainUpdate blk (Header blk )))
213
- -> STM m (f (ChainUpdate blk (Header blk ))))
219
+ -> ( STM m (Maybe (ChainUpdate blk (HeaderWithTime blk )))
220
+ -> STM m (f (ChainUpdate blk (HeaderWithTime blk ))))
214
221
-- ^ How to turn a transaction that may or may not result in a new
215
222
-- 'ChainUpdate' in one that returns the right return type: use @fmap
216
223
-- Identity . 'blockUntilJust'@ to block or 'id' to just return the
@@ -271,6 +278,8 @@ instructionHelper registry varFollower chainType blockComponent fromMaybeSTM CDB
271
278
where
272
279
trace = traceWith (contramap TraceFollowerEvent cdbTracer)
273
280
281
+ -- REVIEW: we read from 'cdbChain', so we can't generalize this.
282
+ getCurrentChainByType :: STM m (AnchoredFragment (HeaderWithTime blk ))
274
283
getCurrentChainByType = do
275
284
curChain <- readTVar cdbChain
276
285
case chainType of
@@ -283,16 +292,16 @@ instructionHelper registry varFollower chainType blockComponent fromMaybeSTM CDB
283
292
codecConfig = configCodec cdbTopLevelConfig
284
293
285
294
headerUpdateToBlockComponentUpdate
286
- :: f (ChainUpdate blk (Header blk )) -> m (f (ChainUpdate blk b ))
295
+ :: ProjectHeader t blk => f (ChainUpdate blk (t blk )) -> m (f (ChainUpdate blk b ))
287
296
headerUpdateToBlockComponentUpdate =
288
297
traverse (traverse (`getBlockComponentFromHeader` blockComponent))
289
298
290
299
-- | We only got the header for the in-memory chain fragment, so depending
291
300
-- on the 'BlockComponent' that's requested, we might have to read the
292
301
-- whole block.
293
302
getBlockComponentFromHeader
294
- :: forall b' . Header blk -> BlockComponent blk b' -> m b'
295
- getBlockComponentFromHeader hdr = \ case
303
+ :: forall b' t . ProjectHeader t blk => t blk -> BlockComponent blk b' -> m b'
304
+ getBlockComponentFromHeader t = \ case
296
305
GetVerifiedBlock -> getBlockComponent GetVerifiedBlock
297
306
GetBlock -> getBlockComponent GetBlock
298
307
GetRawBlock -> getBlockComponent GetRawBlock
@@ -313,6 +322,8 @@ instructionHelper registry varFollower chainType blockComponent fromMaybeSTM CDB
313
322
getBlockComponentFromHeader hdr f <*>
314
323
getBlockComponentFromHeader hdr bc
315
324
where
325
+ hdr = projectHeader t
326
+
316
327
-- | Use the 'ImmutableDB' and 'VolatileDB' to read the 'BlockComponent' from
317
328
-- disk (or memory).
318
329
getBlockComponent :: forall c . BlockComponent blk c -> m c
@@ -364,15 +375,16 @@ instructionHelper registry varFollower chainType blockComponent fromMaybeSTM CDB
364
375
EQ | pt == pointAtImmutableDBTip
365
376
-> do
366
377
trace $ FollowerSwitchToMem pt slotNoAtImmutableDBTip
367
- fupdate <- atomically $ fromMaybeSTM $ do
378
+ ( fupdate :: f ( ChainUpdate blk ( HeaderWithTime blk ))) <- atomically $ ( fromMaybeSTM) $ do
368
379
curChain <- getCurrentChainByType
369
380
instructionSTM
370
381
(RollForwardFrom pt)
371
382
curChain
372
383
(writeTVar varFollower . FollowerInMem )
373
384
-- We only got the header, we must first convert it to the right
374
385
-- block component.
375
- headerUpdateToBlockComponentUpdate fupdate
386
+ (headerUpdateToBlockComponentUpdate :: f (ChainUpdate blk (HeaderWithTime blk )) -> m (f (ChainUpdate blk b )))
387
+ fupdate
376
388
377
389
-- Two possibilities:
378
390
--
@@ -391,27 +403,31 @@ instructionHelper registry varFollower chainType blockComponent fromMaybeSTM CDB
391
403
392
404
-- | 'followerInstruction' for when the follower is in the 'FollowerInMem' state.
393
405
instructionSTM ::
394
- forall m blk . (MonadSTM m , HasHeader (Header blk ))
406
+ forall m blk t . (MonadSTM m , HasHeader (t blk ), ProjectHeader t blk
407
+ , HeaderHash blk ~ HeaderHash (t blk )
408
+ , HasHeader (Header blk )
409
+ )
395
410
=> FollowerRollState blk
396
411
-- ^ The current 'FollowerRollState' of the follower
397
- -> AnchoredFragment (Header blk )
412
+ -> AnchoredFragment (t blk )
398
413
-- ^ The current chain fragment
399
414
-> (FollowerRollState blk -> STM m () )
400
415
-- ^ How to save the updated 'FollowerRollState'
401
- -> STM m (Maybe (ChainUpdate blk (Header blk )))
416
+ -> STM m (Maybe (ChainUpdate blk (t blk )))
402
417
instructionSTM rollState curChain saveRollState =
403
418
assert (invariant curChain) $ case rollState of
404
419
RollForwardFrom pt ->
405
420
case AF. successorBlock (castPoint pt) curChain of
406
421
-- There is no successor block because the follower is at the head
407
422
Nothing -> return Nothing
408
423
Just hdr -> do
409
- saveRollState $ RollForwardFrom $ headerPoint hdr
424
+ saveRollState $ RollForwardFrom $ headerPoint $ projectHeader hdr
410
425
return $ Just $ AddBlock hdr
411
426
RollBackTo pt -> do
412
427
saveRollState $ RollForwardFrom pt
413
428
return $ Just $ RollBack pt
414
429
where
430
+ invariant :: AnchoredFragment (t blk ) -> Bool
415
431
invariant =
416
432
AF. withinFragmentBounds (castPoint (followerRollStatePoint rollState))
417
433
@@ -440,8 +456,12 @@ forward registry varFollower blockComponent CDB{..} = \pts -> do
440
456
<*> pure pts
441
457
where
442
458
findFirstPointOnChain ::
443
- HasCallStack
444
- => AnchoredFragment (Header blk )
459
+ forall t .
460
+ ( HasCallStack
461
+ , HeaderHash blk ~ HeaderHash (t blk )
462
+ , HasHeader (t blk )
463
+ )
464
+ => AnchoredFragment (t blk )
445
465
-> FollowerState m blk b
446
466
-> WithOrigin SlotNo
447
467
-> [Point blk ]
0 commit comments