Skip to content

Commit 0ab3170

Browse files
committed
LedgerDB: abstract out immutability criterion
The only remaining use of the `SecurityParam` is for the snapshot policy 🙃
1 parent 6c7098f commit 0ab3170

File tree

8 files changed

+78
-25
lines changed
  • ouroboros-consensus-cardano/src/unstable-cardano-tools/Cardano/Tools/DBAnalyser
  • ouroboros-consensus

8 files changed

+78
-25
lines changed

ouroboros-consensus-cardano/src/unstable-cardano-tools/Cardano/Tools/DBAnalyser/Run.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ openLedgerDB [email protected]{LedgerDB.lgrFlavorArgs = LedgerDB.L
7171
lgrDbArgs
7272
bss
7373
(\_ -> error "no replay")
74+
(LedgerDB.praosGetVolatileSuffix $ LedgerDB.ledgerDbCfgSecParam $ LedgerDB.lgrConfig lgrDbArgs)
7475
)
7576
emptyStream
7677
genesisPoint
@@ -83,6 +84,7 @@ openLedgerDB [email protected]{LedgerDB.lgrFlavorArgs = LedgerDB.L
8384
lgrDbArgs
8485
args
8586
(\_ -> error "no replay")
87+
(LedgerDB.praosGetVolatileSuffix $ LedgerDB.ledgerDbCfgSecParam $ LedgerDB.lgrConfig lgrDbArgs)
8688
)
8789
emptyStream
8890
genesisPoint

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/ChainDB/Impl.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,14 @@ openDBInternal args launchBgTasks = runWithTempRegistry $ do
160160
(chainDB, testing, env) <- lift $ do
161161
traceWith tracer $ TraceOpenEvent (OpenedVolatileDB maxSlot)
162162
traceWith tracer $ TraceOpenEvent StartedOpeningLgrDB
163+
let secParam = configSecurityParam $ Args.cdbsTopLevelConfig cdbSpecificArgs
163164
(lgrDB, replayed) <-
164165
LedgerDB.openDB
165166
argsLgrDb
166167
(ImmutableDB.streamAPI immutableDB)
167168
immutableDbTipPoint
168169
(Query.getAnyKnownBlock immutableDB volatileDB)
170+
(LedgerDB.praosGetVolatileSuffix secParam)
169171
traceWith tracer $ TraceOpenEvent OpenedLgrDB
170172

171173
varInvalid <- newTVarIO (WithFingerprint Map.empty (Fingerprint 0))

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,29 @@ openDB ::
5858
Point blk ->
5959
-- | How to get blocks from the ChainDB
6060
ResolveBlock m blk ->
61+
GetVolatileSuffix m blk ->
6162
m (LedgerDB' m blk, Word64)
6263
openDB
6364
args
6465
stream
6566
replayGoal
66-
getBlock = case lgrFlavorArgs args of
67+
getBlock
68+
getVolatileSuffix = case lgrFlavorArgs args of
6769
LedgerDbFlavorArgsV1 bss ->
6870
let initDb =
6971
V1.mkInitDb
7072
args
7173
bss
7274
getBlock
75+
getVolatileSuffix
7376
in doOpenDB args initDb stream replayGoal
7477
LedgerDbFlavorArgsV2 bss ->
7578
let initDb =
7679
V2.mkInitDb
7780
args
7881
bss
7982
getBlock
83+
getVolatileSuffix
8084
in doOpenDB args initDb stream replayGoal
8185

8286
{-------------------------------------------------------------------------------

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/Args.hs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{-# LANGUAGE DataKinds #-}
33
{-# LANGUAGE DeriveAnyClass #-}
44
{-# LANGUAGE DeriveGeneric #-}
5-
{-# LANGUAGE DerivingStrategies #-}
5+
{-# LANGUAGE DerivingVia #-}
66
{-# LANGUAGE FlexibleContexts #-}
77
{-# LANGUAGE FlexibleInstances #-}
88
{-# LANGUAGE GADTs #-}
@@ -22,14 +22,21 @@ module Ouroboros.Consensus.Storage.LedgerDB.Args
2222
, QueryBatchSize (..)
2323
, defaultArgs
2424
, defaultQueryBatchSize
25+
26+
-- * 'GetVolatileSuffix'
27+
, GetVolatileSuffix (..)
28+
, praosGetVolatileSuffix
2529
) where
2630

31+
import Cardano.Ledger.BaseTypes (unNonZero)
2732
import Control.ResourceRegistry
2833
import Control.Tracer
2934
import Data.Kind
3035
import Data.Word
3136
import GHC.Generics (Generic)
3237
import NoThunks.Class
38+
import Ouroboros.Consensus.Block
39+
import Ouroboros.Consensus.Config.SecurityParam
3340
import Ouroboros.Consensus.Ledger.Abstract
3441
import Ouroboros.Consensus.Ledger.Extended
3542
import Ouroboros.Consensus.Storage.LedgerDB.API
@@ -38,6 +45,9 @@ import Ouroboros.Consensus.Storage.LedgerDB.TraceEvent
3845
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.Args as V1
3946
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.Args as V2
4047
import Ouroboros.Consensus.Util.Args
48+
import Ouroboros.Consensus.Util.IOLike
49+
import Ouroboros.Network.AnchoredSeq (AnchoredSeq)
50+
import qualified Ouroboros.Network.AnchoredSeq as AS
4151
import System.FS.API
4252

4353
{-------------------------------------------------------------------------------
@@ -120,3 +130,28 @@ defaultQueryBatchSize requestedQueryBatchSize = case requestedQueryBatchSize of
120130
-- acceptable performance. We might want to tweak this further, but for now
121131
-- this default seems good enough.
122132
DefaultQueryBatchSize -> 100_000
133+
134+
{-------------------------------------------------------------------------------
135+
GetVolatileSuffix
136+
-------------------------------------------------------------------------------}
137+
138+
-- | Get the volatile suffix of the given 'AnchoredSeq' of states that the
139+
-- LedgerDB maintains.
140+
newtype GetVolatileSuffix m blk = GetVolatileSuffix
141+
{ getVolatileSuffix ::
142+
forall s.
143+
AS.Anchorable (WithOrigin SlotNo) s s =>
144+
STM
145+
m
146+
( AnchoredSeq (WithOrigin SlotNo) s s ->
147+
AnchoredSeq (WithOrigin SlotNo) s s
148+
)
149+
}
150+
deriving NoThunks via OnlyCheckWhnfNamed "GetVolatileSuffix" (GetVolatileSuffix m blk)
151+
152+
-- | Return the the most recent @k@ blocks, which is the rule mandated by Praos.
153+
praosGetVolatileSuffix :: IOLike m => SecurityParam -> GetVolatileSuffix m blk
154+
praosGetVolatileSuffix secParam =
155+
GetVolatileSuffix $ pure $ AS.anchorNewest k
156+
where
157+
k = unNonZero $ maxRollbacks secParam

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/V1.hs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
-- module will be gone.
2020
module Ouroboros.Consensus.Storage.LedgerDB.V1 (mkInitDb) where
2121

22-
import Cardano.Ledger.BaseTypes.NonZero (NonZero (..))
2322
import Control.Arrow ((>>>))
2423
import Control.Monad
2524
import Control.Monad.Except
@@ -69,6 +68,7 @@ import Ouroboros.Consensus.Util
6968
import Ouroboros.Consensus.Util.Args
7069
import Ouroboros.Consensus.Util.CallStack
7170
import Ouroboros.Consensus.Util.IOLike
71+
import Ouroboros.Network.AnchoredSeq (AnchoredSeq)
7272
import qualified Ouroboros.Network.AnchoredSeq as AS
7373
import Ouroboros.Network.Protocol.LocalStateQuery.Type
7474
import System.FS.API
@@ -84,8 +84,9 @@ mkInitDb ::
8484
Complete LedgerDbArgs m blk ->
8585
Complete V1.LedgerDbFlavorArgs m ->
8686
ResolveBlock m blk ->
87+
GetVolatileSuffix m blk ->
8788
InitDB (DbChangelog' blk, ResourceKey m, BackingStore' m blk) m blk
88-
mkInitDb args bss getBlock =
89+
mkInitDb args bss getBlock getVolatileSuffix =
8990
InitDB
9091
{ initFromGenesis = do
9192
st <- lgrGenesis
@@ -143,6 +144,7 @@ mkInitDb args bss getBlock =
143144
, ldbShouldFlush = shouldFlush flushFreq
144145
, ldbQueryBatchSize = lgrQueryBatchSize
145146
, ldbResolveBlock = getBlock
147+
, ldbGetVolatileSuffix = getVolatileSuffix
146148
}
147149
h <- LDBHandle <$> newTVarIO (LedgerDBOpen env)
148150
pure $ implMkLedgerDb h
@@ -204,10 +206,11 @@ implGetImmutableTip ::
204206
(MonadSTM m, GetTip l) =>
205207
LedgerDBEnv m l blk ->
206208
STM m (l EmptyMK)
207-
implGetImmutableTip env =
209+
implGetImmutableTip env = do
210+
volSuffix <- getVolatileSuffix $ ldbGetVolatileSuffix env
208211
-- The DbChangelog might contain more than k states if they have not yet
209212
-- been garbage-collected.
210-
fmap (AS.anchor . AS.anchorNewest (envMaxRollbacks env) . changelogStates)
213+
fmap (AS.anchor . volSuffix . changelogStates)
211214
. readTVar
212215
$ ldbChangelog env
213216

@@ -220,7 +223,8 @@ implGetPastLedgerState ::
220223
, HeaderHash l ~ HeaderHash blk
221224
) =>
222225
LedgerDBEnv m l blk -> Point blk -> STM m (Maybe (l EmptyMK))
223-
implGetPastLedgerState env point =
226+
implGetPastLedgerState env point = do
227+
volSuffix <- getVolatileSuffix $ ldbGetVolatileSuffix env
224228
readTVar (ldbChangelog env) <&> \chlog -> do
225229
-- The DbChangelog might contain more than k states if they have not yet
226230
-- been garbage-collected, so make sure that the point is volatile (or the
@@ -229,7 +233,7 @@ implGetPastLedgerState env point =
229233
AS.withinBounds
230234
(pointSlot point)
231235
((point ==) . castPoint . either getTip getTip)
232-
(AS.anchorNewest (envMaxRollbacks env) (changelogStates chlog))
236+
(volSuffix (changelogStates chlog))
233237
getPastLedgerAt point chlog
234238

235239
implGetHeaderStateHistory ::
@@ -242,6 +246,7 @@ implGetHeaderStateHistory ::
242246
LedgerDBEnv m l blk -> STM m (HeaderStateHistory blk)
243247
implGetHeaderStateHistory env = do
244248
ldb <- readTVar (ldbChangelog env)
249+
volSuffix <- getVolatileSuffix $ ldbGetVolatileSuffix env
245250
let currentLedgerState = ledgerState $ current ldb
246251
-- This summary can convert all tip slots of the ledger states in the
247252
-- @ledgerDb@ as these are not newer than the tip slot of the current
@@ -255,7 +260,7 @@ implGetHeaderStateHistory env = do
255260
. AS.bimap mkHeaderStateWithTime' mkHeaderStateWithTime'
256261
-- The DbChangelog might contain more than k states if they have not yet
257262
-- been garbage-collected, so only take the corresponding suffix.
258-
. AS.anchorNewest (envMaxRollbacks env)
263+
. volSuffix
259264
$ changelogStates ldb
260265

261266
implValidate ::
@@ -571,6 +576,7 @@ data LedgerDBEnv m l blk = LedgerDBEnv
571576
-- frequency that was provided when opening the LedgerDB.
572577
, ldbQueryBatchSize :: !QueryBatchSize
573578
, ldbResolveBlock :: !(ResolveBlock m blk)
579+
, ldbGetVolatileSuffix :: !(GetVolatileSuffix m blk)
574580
}
575581
deriving Generic
576582

@@ -584,10 +590,6 @@ deriving instance
584590
) =>
585591
NoThunks (LedgerDBEnv m l blk)
586592

587-
-- | Return the security parameter @k@. Convenience function.
588-
envMaxRollbacks :: LedgerDBEnv m l blk -> Word64
589-
envMaxRollbacks = unNonZero . maxRollbacks . ledgerDbCfgSecParam . ldbCfg
590-
591593
-- | Check if the LedgerDB is open, if so, executing the given function on the
592594
-- 'LedgerDBEnv', otherwise, throw a 'CloseDBError'.
593595
getEnv ::
@@ -759,10 +761,16 @@ acquireAtTarget ::
759761
ReadLocked m (Either GetForkerError (DbChangelog l))
760762
acquireAtTarget ldbEnv target = readLocked $ runExceptT $ do
761763
dblog <- lift $ readTVarIO (ldbChangelog ldbEnv)
764+
volSuffix <- lift $ atomically $ getVolatileSuffix $ ldbGetVolatileSuffix env
762765
-- The DbChangelog might contain more than k states if they have not yet
763766
-- been garbage-collected.
764-
let immTip :: Point blk
765-
immTip = castPoint $ getTip $ AS.anchor $ AS.anchorNewest k $ changelogStates dblog
767+
let volStates = volSuffix $ changelogStates dblog
768+
769+
immTip :: Point blk
770+
immTip = castPoint $ getTip $ AS.anchor volStates
771+
772+
rollbackMax :: Word64
773+
rollbackMax = fromIntegral $ AS.length volStates
766774

767775
rollbackTo pt
768776
| pointSlot pt < pointSlot immTip = throwError $ PointTooOld Nothing
@@ -775,7 +783,6 @@ acquireAtTarget ldbEnv target = readLocked $ runExceptT $ do
775783
Right ImmutableTip -> rollbackTo immTip
776784
Right (SpecificPoint pt) -> rollbackTo pt
777785
Left n -> do
778-
let rollbackMax = maxRollback dblog `min` k
779786
when (n > rollbackMax) $
780787
throwError $
781788
PointTooOld $
@@ -787,8 +794,6 @@ acquireAtTarget ldbEnv target = readLocked $ runExceptT $ do
787794
case rollbackN n dblog of
788795
Nothing -> error "unreachable"
789796
Just dblog' -> pure dblog'
790-
where
791-
k = envMaxRollbacks ldbEnv
792797

793798
{-------------------------------------------------------------------------------
794799
Make forkers from consistent views

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/V2.hs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
module Ouroboros.Consensus.Storage.LedgerDB.V2 (mkInitDb) where
1818

19-
import Cardano.Ledger.BaseTypes (unNonZero)
2019
import Control.Arrow ((>>>))
2120
import Control.Monad (join)
2221
import qualified Control.Monad as Monad (void, (>=>))
@@ -79,8 +78,9 @@ mkInitDb ::
7978
Complete LedgerDbArgs m blk ->
8079
Complete V2.LedgerDbFlavorArgs m ->
8180
ResolveBlock m blk ->
81+
GetVolatileSuffix m blk ->
8282
InitDB (LedgerSeq' m blk) m blk
83-
mkInitDb args flavArgs getBlock =
83+
mkInitDb args flavArgs getBlock getVolatileSuffix =
8484
InitDB
8585
{ initFromGenesis = emptyF =<< lgrGenesis
8686
, initFromSnapshot =
@@ -110,6 +110,7 @@ mkInitDb args flavArgs getBlock =
110110
, ldbResolveBlock = getBlock
111111
, ldbQueryBatchSize = lgrQueryBatchSize
112112
, ldbOpenHandlesLock = lock
113+
, ldbGetVolatileSuffix = getVolatileSuffix
113114
}
114115
h <- LDBHandle <$> newTVarIO (LedgerDBOpen env)
115116
pure $ implMkLedgerDb h bss
@@ -486,6 +487,7 @@ data LedgerDBEnv m l blk = LedgerDBEnv
486487
--
487488
-- * Modify 'ldbSeq' while holding a write lock, and then close the removed
488489
-- handles without any locking. See e.g. 'implGarbageCollect'.
490+
, ldbGetVolatileSuffix :: !(GetVolatileSuffix m blk)
489491
}
490492
deriving Generic
491493

@@ -579,11 +581,11 @@ getEnvSTM (LDBHandle varState) f =
579581
-- 'LedgerSeq' can contain more than @k@ states if we adopted new blocks, but
580582
-- garbage collection has not yet been run.
581583
getVolatileLedgerSeq ::
582-
(MonadSTM m, GetTip l) => LedgerDBEnv m l blk -> STM m (LedgerSeq m l)
583-
getVolatileLedgerSeq env =
584-
LedgerSeq . AS.anchorNewest k . getLedgerSeq <$> readTVar (ldbSeq env)
585-
where
586-
k = unNonZero $ maxRollbacks $ ledgerDbCfgSecParam $ ldbCfg env
584+
(MonadSTM m, GetTip l) =>
585+
LedgerDBEnv m l blk -> STM m (LedgerSeq m l)
586+
getVolatileLedgerSeq env = do
587+
volSuffix <- getVolatileSuffix (ldbGetVolatileSuffix env)
588+
LedgerSeq . volSuffix . getLedgerSeq <$> readTVar (ldbSeq env)
587589

588590
-- | Get a 'StateRef' from the 'LedgerSeq' (via 'getVolatileLedgerSeq') in the
589591
-- 'LedgerDBEnv', with the 'LedgerTablesHandle' having been duplicated (such

ouroboros-consensus/test/consensus-test/Test/Consensus/MiniProtocol/LocalStateQuery/Server.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ initLedgerDB s c = do
244244
streamAPI
245245
(Chain.headPoint c)
246246
(\rpt -> pure $ fromMaybe (error "impossible") $ Chain.findBlock ((rpt ==) . blockRealPoint) c)
247+
(LedgerDB.praosGetVolatileSuffix s)
247248

248249
result <-
249250
LedgerDB.validateFork

ouroboros-consensus/test/storage-test/Test/Ouroboros/Storage/LedgerDB/StateMachine.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,13 +504,15 @@ openLedgerDB flavArgs env cfg fs = do
504504
args
505505
bss
506506
getBlock
507+
(praosGetVolatileSuffix $ ledgerDbCfgSecParam cfg)
507508
in openDBInternal args initDb stream replayGoal
508509
LedgerDbFlavorArgsV2 bss ->
509510
let initDb =
510511
V2.mkInitDb
511512
args
512513
bss
513514
getBlock
515+
(praosGetVolatileSuffix $ ledgerDbCfgSecParam cfg)
514516
in openDBInternal args initDb stream replayGoal
515517
withRegistry $ \reg -> do
516518
vr <- validateFork ldb reg (const $ pure ()) BlockCache.empty 0 (map getHeader volBlocks)

0 commit comments

Comments
 (0)