Skip to content

Commit 0e360e2

Browse files
committed
Extract also LMDB backend
1 parent 572f16b commit 0e360e2

File tree

27 files changed

+480
-645
lines changed

27 files changed

+480
-645
lines changed

cabal.project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ index-state:
2020

2121
packages:
2222
ouroboros-consensus
23+
ouroboros-consensus-lmdb
2324
ouroboros-consensus-lsm
2425
ouroboros-consensus-cardano
2526
ouroboros-consensus-protocol

ouroboros-consensus-cardano/ouroboros-consensus-cardano.cabal

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,6 @@ library
160160
contra-tracer,
161161
crypton,
162162
deepseq,
163-
directory,
164-
filepath,
165163
formatting >=6.3 && <7.3,
166164
fs-api,
167165
measures,
@@ -700,6 +698,9 @@ executable immdb-server
700698
executable snapshot-converter
701699
import: common-exe
702700
hs-source-dirs: app
701+
other-modules:
702+
Ouroboros.Consensus.Cardano.StreamingLedgerTables
703+
703704
main-is: snapshot-converter.hs
704705
build-depends:
705706
ansi-terminal,
@@ -711,6 +712,8 @@ executable snapshot-converter
711712
mtl,
712713
optparse-applicative,
713714
ouroboros-consensus,
715+
ouroboros-consensus-lsm,
716+
ouroboros-consensus-lmdb,
714717
ouroboros-consensus-cardano,
715718
ouroboros-consensus-cardano:unstable-cardano-tools,
716719
resource-registry,

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

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ module Ouroboros.Consensus.Node
5353
, pattern DoDiskSnapshotChecksum
5454
, pattern NoDoDiskSnapshotChecksum
5555
, ChainSyncIdleTimeout (..)
56-
, LedgerDbBackendArgs (..)
5756

5857
-- * Internal helpers
5958
, mkNodeKernelArgs
@@ -127,8 +126,6 @@ import qualified Ouroboros.Consensus.Storage.ChainDB as ChainDB
127126
import qualified Ouroboros.Consensus.Storage.ChainDB.Impl.Args as ChainDB
128127
import Ouroboros.Consensus.Storage.LedgerDB.Args
129128
import Ouroboros.Consensus.Storage.LedgerDB.Snapshots
130-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.Args as V2
131-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.LSM as LSM
132129
import Ouroboros.Consensus.Util.Args
133130
import Ouroboros.Consensus.Util.IOLike
134131
import Ouroboros.Consensus.Util.Orphans ()
@@ -320,7 +317,7 @@ data LowLevelRunNodeArgs m addrNTN addrNTC blk
320317
, llrnMaxClockSkew :: InFutureCheck.ClockSkew
321318
-- ^ Maximum clock skew
322319
, llrnPublicPeerSelectionStateVar :: StrictSTM.StrictTVar m (PublicPeerSelectionState addrNTN)
323-
, llrnLdbFlavorArgs :: Complete LedgerDbFlavorArgs m
320+
, llrnLdbFlavorArgs :: LedgerDbBackendArgs m blk
324321
-- ^ The flavor arguments
325322
}
326323

@@ -378,7 +375,7 @@ data
378375
, -- Ad hoc values to replace default ChainDB configurations
379376
srnSnapshotPolicyArgs :: SnapshotPolicyArgs
380377
, srnQueryBatchSize :: QueryBatchSize
381-
, srnLedgerDbBackendArgs :: LedgerDbBackendArgs m
378+
, srnLedgerDbBackendArgs :: LedgerDbBackendArgs m blk
382379
}
383380

384381
{-------------------------------------------------------------------------------
@@ -819,7 +816,7 @@ openChainDB ::
819816
(ChainDB.RelativeMountPoint -> SomeHasFS m) ->
820817
-- | Volatile FS, see 'NodeDatabasePaths'
821818
(ChainDB.RelativeMountPoint -> SomeHasFS m) ->
822-
Complete LedgerDbFlavorArgs m ->
819+
LedgerDbBackendArgs m blk ->
823820
-- | A set of default arguments (possibly modified from 'defaultArgs')
824821
Incomplete ChainDbArgs m blk ->
825822
-- | Customise the 'ChainDbArgs'
@@ -1007,7 +1004,7 @@ stdLowLevelRunNodeArgsIO
10071004
}
10081005
$(SafeWildCards.fields 'StdRunNodeArgs) = do
10091006
llrnBfcSalt <- stdBfcSaltIO
1010-
(lsmSalt, llrnRng) <- genWord64 <$> newStdGen
1007+
llrnRng <- newStdGen
10111008
pure
10121009
LowLevelRunNodeArgs
10131010
{ llrnBfcSalt
@@ -1052,21 +1049,21 @@ stdLowLevelRunNodeArgsIO
10521049
InFutureCheck.defaultClockSkew
10531050
, llrnPublicPeerSelectionStateVar =
10541051
Diffusion.dcPublicPeerSelectionVar srnDiffusionConfiguration
1055-
, llrnLdbFlavorArgs =
1056-
case srnLedgerDbBackendArgs of
1057-
V1LMDB args -> LedgerDbFlavorArgsV1 args
1058-
V2InMemory -> LedgerDbFlavorArgsV2 (V2.V2Args V2.InMemoryHandleArgs)
1059-
V2LSM path ->
1060-
LedgerDbFlavorArgsV2
1061-
( V2.V2Args
1062-
( V2.LSMHandleArgs
1063-
( V2.LSMArgs
1064-
(mkFsPath $ splitDirectories path)
1065-
lsmSalt
1066-
(LSM.stdMkBlockIOFS (nonImmutableDbPath srnDatabasePath))
1067-
)
1068-
)
1069-
)
1052+
, llrnLdbFlavorArgs = srnLedgerDbBackendArgs
1053+
-- case srnLedgerDbBackendArgs of
1054+
-- V1LMDB args -> LedgerDbFlavorArgsV1 args
1055+
-- V2InMemory -> LedgerDbFlavorArgsV2 (V2.V2Args V2.InMemoryHandleArgs)
1056+
-- V2LSM path ->
1057+
-- LedgerDbFlavorArgsV2
1058+
-- ( V2.V2Args
1059+
-- ( V2.LSMHandleArgs
1060+
-- ( V2.LSMArgs
1061+
-- (mkFsPath $ splitDirectories path)
1062+
-- lsmSalt
1063+
-- (LSM.stdMkBlockIOFS (nonImmutableDbPath srnDatabasePath))
1064+
-- )
1065+
-- )
1066+
-- )
10701067
}
10711068
where
10721069
networkMagic :: NetworkMagic
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
cabal-version: 3.0
2+
name: ouroboros-consensus-lmdb
3+
version: 0.1.0.0
4+
synopsis: LMDB LedgerDB V1 backend for ouroboros-consensus
5+
description: LMDB LedgerDB V1 backend for ouroboros-consensus.
6+
license: Apache-2.0
7+
license-files:
8+
LICENSE
9+
NOTICE
10+
11+
copyright:
12+
2019-2023 Input Output Global Inc (IOG), INTERSECT 2023-2024.
13+
14+
author: IOG Engineering Team
15+
maintainer: operations@iohk.io
16+
category: Network
17+
build-type: Simple
18+
extra-doc-files:
19+
CHANGELOG.md
20+
21+
source-repository head
22+
type: git
23+
location: https://github.com/IntersectMBO/ouroboros-consensus
24+
25+
flag asserts
26+
description: Enable assertions
27+
manual: False
28+
default: False
29+
30+
common common-lib
31+
default-language: Haskell2010
32+
ghc-options:
33+
-Wall
34+
-Wcompat
35+
-Wincomplete-uni-patterns
36+
-Wincomplete-record-updates
37+
-Wpartial-fields
38+
-Widentities
39+
-Wredundant-constraints
40+
-Wmissing-export-lists
41+
-Wunused-packages
42+
-Wno-unticked-promoted-constructors
43+
44+
if flag(asserts)
45+
ghc-options: -fno-ignore-asserts
46+
cpp-options: -DENABLE_ASSERTIONS
47+
48+
common common-test
49+
import: common-lib
50+
ghc-options:
51+
-threaded
52+
-rtsopts
53+
54+
common common-bench
55+
import: common-test
56+
ghc-options:
57+
-threaded
58+
-rtsopts
59+
60+
-- We use this option to avoid skewed results due to changes in cache-line
61+
-- alignment. See
62+
-- https://github.com/Bodigrim/tasty-bench#comparison-against-baseline
63+
ghc-options: -fproc-alignment=64
64+
65+
library
66+
import: common-lib
67+
hs-source-dirs: src
68+
exposed-modules:
69+
Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB
70+
Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB.Bridge
71+
Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB.Status
72+
73+
build-depends:
74+
base >=4.14 && <4.22,
75+
bytestring >=0.10 && <0.13,
76+
cardano-lmdb >=0.4,
77+
cardano-lmdb-simple ^>=0.8,
78+
cardano-slotting,
79+
containers >=0.5 && <0.8,
80+
contra-tracer,
81+
fs-api ^>=0.4,
82+
io-classes ^>=1.8.0.1,
83+
mempack,
84+
sop-core,
85+
nothunks ^>=0.2,
86+
ouroboros-consensus,
87+
rawlock ^>=0.1.1,
88+
serialise ^>=0.2,
89+
mtl,
90+
streaming,
91+
text,
92+
93+
build-depends: text >=1.2.5.0 && <2.2
Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33
{-# LANGUAGE DeriveGeneric #-}
44
{-# LANGUAGE DerivingVia #-}
55
{-# LANGUAGE FlexibleContexts #-}
6+
{-# LANGUAGE FlexibleInstances #-}
67
{-# LANGUAGE GADTs #-}
78
{-# LANGUAGE LambdaCase #-}
9+
{-# LANGUAGE MultiParamTypeClasses #-}
810
{-# LANGUAGE NamedFieldPuns #-}
911
{-# LANGUAGE OverloadedStrings #-}
1012
{-# LANGUAGE PatternSynonyms #-}
1113
{-# LANGUAGE ScopedTypeVariables #-}
14+
{-# LANGUAGE TupleSections #-}
1215
{-# LANGUAGE TypeApplications #-}
16+
{-# LANGUAGE TypeFamilies #-}
1317
{-# LANGUAGE TypeOperators #-}
18+
{-# LANGUAGE UndecidableInstances #-}
1419

1520
-- | A 'BackingStore' implementation based on [LMDB](http://www.lmdb.tech/doc/).
1621
module Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB
@@ -29,12 +34,13 @@ module Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB
2934
, withDbSeqNoRWMaybeNull
3035
) where
3136

32-
import Cardano.Slotting.Slot (SlotNo, WithOrigin (At))
37+
import Cardano.Slotting.Slot (WithOrigin (At))
3338
import qualified Codec.Serialise as S (Serialise (..))
3439
import qualified Control.Concurrent.Class.MonadSTM.TVar as IOLike
3540
import Control.Monad (forM_, unless, void, when)
3641
import qualified Control.Monad.Class.MonadSTM as IOLike
3742
import Control.Monad.IO.Class (MonadIO (liftIO))
43+
import Control.Monad.Trans (lift)
3844
import qualified Control.Tracer as Trace
3945
import Data.Bifunctor (first)
4046
import Data.Functor (($>), (<&>))
@@ -43,6 +49,7 @@ import Data.Map (Map)
4349
import qualified Data.Map.Strict as Map
4450
import Data.MemPack
4551
import Data.Proxy
52+
import qualified Data.SOP.Dict as Dict
4653
import qualified Data.Set as Set
4754
import qualified Data.Text as Strict
4855
import qualified Database.LMDB.Simple as LMDB
@@ -52,11 +59,14 @@ import qualified Database.LMDB.Simple.Internal as LMDB.Internal
5259
import qualified Database.LMDB.Simple.TransactionHandle as TrH
5360
import GHC.Generics (Generic)
5461
import GHC.Stack (HasCallStack)
55-
import Ouroboros.Consensus.Ledger.Tables
62+
import Ouroboros.Consensus.Block
63+
import Ouroboros.Consensus.Ledger.Basics
5664
import qualified Ouroboros.Consensus.Ledger.Tables.Diff as Diff
65+
import Ouroboros.Consensus.Storage.LedgerDB.API
5766
import Ouroboros.Consensus.Storage.LedgerDB.Snapshots
5867
( SnapshotBackend (..)
5968
)
69+
import Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore
6070
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.API as API
6171
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB.Bridge as Bridge
6272
import Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB.Status
@@ -70,10 +80,14 @@ import Ouroboros.Consensus.Util.IOLike
7080
, IOLike
7181
, MonadCatch (..)
7282
, MonadThrow (..)
83+
, PrimState
7384
, bracket
7485
)
7586
import Ouroboros.Consensus.Util.IndexedMemPack
87+
import qualified Streaming as S
88+
import qualified Streaming.Prelude as S
7689
import qualified System.FS.API as FS
90+
import System.FS.IO
7791

7892
{-------------------------------------------------------------------------------
7993
Database definition
@@ -793,3 +807,104 @@ prettyPrintLMDBErr = \case
793807
LMDBErrNotADir path ->
794808
"The path " <> show path <> " should be a directory but it is a file instead."
795809
LMDBErrClosed -> "The database has been closed."
810+
811+
{-------------------------------------------------------------------------------
812+
Backend
813+
-------------------------------------------------------------------------------}
814+
815+
data LMDB
816+
817+
instance
818+
( HasLedgerTables l
819+
, MonadIO m
820+
, IOLike m
821+
, MemPackIdx l EmptyMK ~ l EmptyMK
822+
) =>
823+
Backend m LMDB l
824+
where
825+
data Args m LMDB
826+
= LMDBBackingStoreArgs FilePath LMDBLimits (Dict.Dict MonadIOPrim m)
827+
data Trace m LMDB
828+
= OnDiskBackingStoreInitialise LMDB.Limits
829+
| OnDiskBackingStoreTrace BackingStoreTrace
830+
deriving (Eq, Show)
831+
832+
isRightBackendForSnapshot _ _ UTxOHDLMDBSnapshot = True
833+
isRightBackendForSnapshot _ _ _ = False
834+
835+
newBackingStoreInitialiser trcr (LMDBBackingStoreArgs fs limits Dict.Dict) =
836+
newLMDBBackingStore
837+
(SomeBackendTrace . OnDiskBackingStoreTrace >$< trcr)
838+
limits
839+
(LiveLMDBFS $ FS.SomeHasFS $ ioHasFS $ FS.MountPoint fs)
840+
841+
{-------------------------------------------------------------------------------
842+
Streaming
843+
-------------------------------------------------------------------------------}
844+
845+
instance (Ord (TxIn l), GetTip l, Monad m) => StreamingBackend m LMDB l where
846+
data SinkArgs m LMDB l
847+
= SinkLMDB
848+
-- \| Chunk size
849+
Int
850+
-- \| bsWrite
851+
( SlotNo ->
852+
(l EmptyMK, l EmptyMK) ->
853+
LedgerTables l DiffMK ->
854+
m ()
855+
)
856+
(l EmptyMK -> m ())
857+
858+
data YieldArgs m LMDB l
859+
= YieldLMDB
860+
Int
861+
(LedgerBackingStoreValueHandle m l)
862+
863+
yield _ (YieldLMDB chunkSize valueHandle) = yieldLmdbS chunkSize valueHandle
864+
sink _ (SinkLMDB chunkSize write copy) = sinkLmdbS chunkSize write copy
865+
866+
sinkLmdbS ::
867+
forall m l.
868+
(Ord (TxIn l), GetTip l, Monad m) =>
869+
Int ->
870+
(SlotNo -> (l EmptyMK, l EmptyMK) -> LedgerTables l DiffMK -> m ()) ->
871+
(l EmptyMK -> m ()) ->
872+
Sink m l
873+
sinkLmdbS writeChunkSize bs copyTo hint s = do
874+
r <- go writeChunkSize mempty s
875+
lift $ copyTo hint
876+
pure (fmap (,Nothing) r)
877+
where
878+
sl = withOrigin (error "unreachable") id $ pointSlot $ getTip hint
879+
880+
go 0 m s' = do
881+
lift $ bs sl (hint, hint) (LedgerTables $ DiffMK $ Diff.fromMapInserts m)
882+
go writeChunkSize mempty s'
883+
go n m s' = do
884+
mbs <- S.uncons s'
885+
case mbs of
886+
Nothing -> do
887+
lift $ bs sl (hint, hint) (LedgerTables $ DiffMK $ Diff.fromMapInserts m)
888+
S.effects s'
889+
Just ((k, v), s'') ->
890+
go (n - 1) (Map.insert k v m) s''
891+
892+
yieldLmdbS ::
893+
Monad m =>
894+
Int ->
895+
LedgerBackingStoreValueHandle m l ->
896+
Yield m l
897+
yieldLmdbS readChunkSize bsvh hint k = do
898+
r <- k (go (RangeQuery Nothing readChunkSize))
899+
lift $ S.effects r
900+
where
901+
go p = do
902+
(LedgerTables (ValuesMK values), mx) <- lift $ S.lift $ bsvhRangeRead bsvh hint p
903+
case mx of
904+
Nothing -> pure $ pure Nothing
905+
Just x -> do
906+
S.each $ Map.toList values
907+
go (RangeQuery (Just . LedgerTables . KeysMK $ Set.singleton x) readChunkSize)
908+
909+
class (MonadIO m, PrimState m ~ PrimState IO) => MonadIOPrim m
910+
instance (MonadIO m, PrimState m ~ PrimState IO) => MonadIOPrim m

0 commit comments

Comments
 (0)