Skip to content

Commit 28b4117

Browse files
committed
Implement opening of an LSM LedgerDB backend
1 parent ac4a7f6 commit 28b4117

File tree

3 files changed

+58
-20
lines changed

3 files changed

+58
-20
lines changed

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

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module Ouroboros.Consensus.Storage.LedgerDB
1717
, openDBInternal
1818
) where
1919

20+
import Control.ResourceRegistry
2021
import Data.Functor.Contravariant ((>$<))
2122
import Data.Word
2223
import Ouroboros.Consensus.Block
@@ -32,6 +33,9 @@ import Ouroboros.Consensus.Storage.LedgerDB.TraceEvent
3233
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1 as V1
3334
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.Snapshots as V1
3435
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2 as V2
36+
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.Args as V2
37+
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.InMemory as InMemory
38+
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.LSM as LSM
3539
import Ouroboros.Consensus.Util.Args
3640
import Ouroboros.Consensus.Util.CallStack
3741
import Ouroboros.Consensus.Util.IOLike
@@ -41,7 +45,6 @@ openDB ::
4145
forall m blk.
4246
( IOLike m
4347
, LedgerSupportsProtocol blk
44-
, LedgerDbSerialiseConstraints blk
4548
, InspectLedger blk
4649
, HasCallStack
4750
, HasHardForkHistory blk
@@ -76,31 +79,51 @@ openDB
7679
snapManager
7780
in doOpenDB args initDb snapManager stream replayGoal
7881
LedgerDbFlavorArgsV2 bss -> do
82+
(snapManager, bss') <- case bss of
83+
V2.V2Args V2.InMemoryHandleArgs -> pure (InMemory.snapshotManager args, V2.InMemoryHandleEnv)
84+
V2.V2Args (V2.LSMHandleArgs (V2.LSMArgs path genSalt mkFS)) -> do
85+
(rk1, V2.SomeHasFSAndBlockIO fs blockio) <- mkFS (lgrRegistry args)
86+
session <-
87+
allocate
88+
(lgrRegistry args)
89+
( \_ -> do
90+
salt <- genSalt
91+
LSM.openSession
92+
(LedgerDBFlavorImplEvent . FlavorImplSpecificTraceV2 . V2.LSMTrace >$< lgrTracer args)
93+
fs
94+
blockio
95+
salt
96+
(mkFsPath [path])
97+
)
98+
LSM.closeSession
99+
pure (LSM.snapshotManager (snd session) args, V2.LSMHandleEnv session rk1)
79100
let initDb =
80101
V2.mkInitDb
81102
args
82-
bss
103+
bss'
83104
getBlock
84-
in doOpenDB args initDb stream replayGoal
105+
snapManager
106+
doOpenDB args initDb snapManager stream replayGoal
85107

86108
{-------------------------------------------------------------------------------
87109
Opening a LedgerDB
88110
-------------------------------------------------------------------------------}
89111

90112
doOpenDB ::
91-
forall m blk db.
113+
forall m n blk db st.
92114
( IOLike m
93115
, LedgerSupportsProtocol blk
94116
, InspectLedger blk
95117
, HasCallStack
96118
) =>
97119
Complete LedgerDbArgs m blk ->
98120
InitDB db m blk ->
121+
SnapshotManager m n blk st ->
99122
StreamAPI m blk blk ->
100123
Point blk ->
101124
m (LedgerDB' m blk, Word64)
102-
doOpenDB args initDb stream replayGoal =
103-
f <$> openDBInternal args initDb stream replayGoal
125+
doOpenDB args initDb snapManager stream replayGoal =
126+
f <$> openDBInternal args initDb snapManager stream replayGoal
104127
where
105128
f (ldb, replayCounter, _) = (ldb, replayCounter)
106129

@@ -113,29 +136,28 @@ openDBInternal ::
113136
) =>
114137
Complete LedgerDbArgs m blk ->
115138
InitDB db m blk ->
116-
SnapshotManager m n blk st ->
139+
SnapshotManagement m n blk st ->
117140
StreamAPI m blk blk ->
118141
Point blk ->
119142
m (LedgerDB' m blk, Word64, TestInternals' m blk)
120-
openDBInternal args@(LedgerDbArgs{lgrHasFS = SomeHasFS fs}) initDb stream replayGoal = do
143+
openDBInternal args@(LedgerDbArgs{lgrHasFS = SomeHasFS fs}) initDb snapManager stream replayGoal = do
121144
createDirectoryIfMissing fs True (mkFsPath [])
122145
(_initLog, db, replayCounter) <-
123146
initialize
124147
replayTracer
125148
snapTracer
126-
lgrHasFS
127149
lgrConfig
128150
stream
129151
replayGoal
130152
initDb
153+
snapManager
131154
lgrStartSnapshot
132155
(ledgerDb, internal) <- mkLedgerDb initDb db
133156
return (ledgerDb, replayCounter, internal)
134157
where
135158
LedgerDbArgs
136159
{ lgrConfig
137160
, lgrTracer
138-
, lgrHasFS
139161
, lgrStartSnapshot
140162
} = args
141163

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,17 +184,20 @@ instance FromJSON SnapshotMetadata where
184184
data SnapshotBackend
185185
= UTxOHDMemSnapshot
186186
| UTxOHDLMDBSnapshot
187+
| UTxOHDLSMSnapshot
187188
deriving (Eq, Show)
188189

189190
instance ToJSON SnapshotBackend where
190191
toJSON = \case
191192
UTxOHDMemSnapshot -> "utxohd-mem"
192193
UTxOHDLMDBSnapshot -> "utxohd-lmdb"
194+
UTxOHDLSMSnapshot -> "utxohd-lsm"
193195

194196
instance FromJSON SnapshotBackend where
195197
parseJSON = Aeson.withText "SnapshotBackend" $ \case
196198
"utxohd-mem" -> pure UTxOHDMemSnapshot
197199
"utxohd-lmdb" -> pure UTxOHDLMDBSnapshot
200+
"utxohd-lsm" -> pure UTxOHDLSMSnapshot
198201
_ -> fail "unknown SnapshotBackend"
199202

200203
data MetadataErr

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

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{-# LANGUAGE DataKinds #-}
33
{-# LANGUAGE DeriveAnyClass #-}
44
{-# LANGUAGE DeriveGeneric #-}
5+
{-# LANGUAGE DerivingVia #-}
56
{-# LANGUAGE FlexibleContexts #-}
67
{-# LANGUAGE LambdaCase #-}
78
{-# LANGUAGE NamedFieldPuns #-}
@@ -33,7 +34,6 @@ import Data.Set (Set)
3334
import qualified Data.Set as Set
3435
import Data.Traversable (for)
3536
import Data.Tuple (Solo (..))
36-
import Data.Void
3737
import Data.Word
3838
import GHC.Generics
3939
import NoThunks.Class
@@ -56,6 +56,8 @@ import Ouroboros.Consensus.Storage.LedgerDB.TraceEvent
5656
import Ouroboros.Consensus.Storage.LedgerDB.V2.Args as V2
5757
import Ouroboros.Consensus.Storage.LedgerDB.V2.Forker
5858
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.InMemory as InMemory
59+
import Ouroboros.Consensus.Storage.LedgerDB.V2.LSM (snapshotToStatePath)
60+
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.LSM as LSM
5961
import Ouroboros.Consensus.Storage.LedgerDB.V2.LedgerSeq
6062
import Ouroboros.Consensus.Util.Args
6163
import Ouroboros.Consensus.Util.CallStack
@@ -66,6 +68,8 @@ import Ouroboros.Network.Protocol.LocalStateQuery.Type
6668
import System.FS.API
6769
import Prelude hiding (read)
6870

71+
type SnapshotManagerV2 m blk = SnapshotManager m m blk (StateRef m (ExtLedgerState blk))
72+
6973
mkInitDb ::
7074
forall m blk.
7175
( LedgerSupportsProtocol blk
@@ -75,10 +79,11 @@ mkInitDb ::
7579
, LedgerSupportsV2LedgerDB (LedgerState blk)
7680
) =>
7781
Complete LedgerDbArgs m blk ->
78-
Complete V2.LedgerDbFlavorArgs m ->
82+
HandleEnv m ->
7983
ResolveBlock m blk ->
84+
SnapshotManagerV2 m blk ->
8085
InitDB (LedgerSeq' m blk) m blk
81-
mkInitDb args flavArgs getBlock =
86+
mkInitDb args bss getBlock snapManager =
8287
InitDB
8388
{ initFromGenesis = emptyF =<< lgrGenesis
8489
, initFromSnapshot =
@@ -112,9 +117,12 @@ mkInitDb args flavArgs getBlock =
112117
, ldbResolveBlock = getBlock
113118
, ldbQueryBatchSize = lgrQueryBatchSize
114119
, ldbOpenHandlesLock = lock
120+
, testLdbResourceKeys = case bss of
121+
InMemoryHandleEnv -> Nothing
122+
LSMHandleEnv (s, _) k -> Just (s, k)
115123
}
116124
h <- LDBHandle <$> newTVarIO (LedgerDBOpen env)
117-
pure $ implMkLedgerDb h bss
125+
pure $ implMkLedgerDb h snapManager
118126
}
119127
where
120128
LedgerDbArgs
@@ -127,8 +135,6 @@ mkInitDb args flavArgs getBlock =
127135
, lgrRegistry
128136
} = args
129137

130-
bss = case flavArgs of V2Args bss0 -> bss0
131-
132138
v2Tracer :: Tracer m V2.FlavorImplSpecificTrace
133139
v2Tracer = LedgerDBFlavorImplEvent . FlavorImplSpecificTraceV2 >$< lgrTracer
134140

@@ -137,17 +143,20 @@ mkInitDb args flavArgs getBlock =
137143
m (LedgerSeq' m blk)
138144
emptyF st =
139145
empty' st $ case bss of
140-
InMemoryHandleArgs -> InMemory.newInMemoryLedgerTablesHandle v2Tracer lgrHasFS
141-
LSMHandleArgs x -> absurd x
146+
InMemoryHandleEnv -> InMemory.newInMemoryLedgerTablesHandle v2Tracer lgrHasFS
147+
LSMHandleEnv (_, session) _ ->
148+
\values -> do
149+
table <- LSM.tableFromValuesMK lgrRegistry session values
150+
LSM.newLSMLedgerTablesHandle v2Tracer lgrRegistry session table
142151

143152
loadSnapshot ::
144153
CodecConfig blk ->
145154
SomeHasFS m ->
146155
DiskSnapshot ->
147156
m (Either (SnapshotFailure blk) (LedgerSeq' m blk, RealPoint blk))
148157
loadSnapshot ccfg fs ds = case bss of
149-
InMemoryHandleArgs -> runExceptT $ InMemory.loadSnapshot v2Tracer lgrRegistry ccfg fs ds
150-
LSMHandleArgs x -> absurd x
158+
InMemoryHandleEnv -> runExceptT $ InMemory.loadSnapshot v2Tracer lgrRegistry ccfg fs ds
159+
LSMHandleEnv (_, session) _ -> runExceptT $ LSM.loadSnapshot v2Tracer lgrRegistry ccfg fs session ds
151160

152161
implMkLedgerDb ::
153162
forall m l blk.
@@ -433,6 +442,10 @@ data LedgerDBEnv m l blk = LedgerDBEnv
433442
--
434443
-- * Modify 'ldbSeq' while holding a write lock, and then close the removed
435444
-- handles without any locking.
445+
, testLdbResourceKeys :: !(Maybe (ResourceKey m, ResourceKey m))
446+
-- ^ Resource keys used in the LSM backend so that the closing function used
447+
-- in tests can release such resources. These are the resource keys for the
448+
-- LSM session and the resource key for the BlockIO interface.
436449
}
437450
deriving Generic
438451

0 commit comments

Comments
 (0)