Skip to content

Commit 5449f22

Browse files
committed
WIP
1 parent 9016f5c commit 5449f22

File tree

4 files changed

+58
-248
lines changed

4 files changed

+58
-248
lines changed

ouroboros-consensus-cardano/app/snapshot-converter.hs

Lines changed: 35 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
{-# LANGUAGE FlexibleContexts #-}
44
{-# LANGUAGE OverloadedStrings #-}
55
{-# LANGUAGE ScopedTypeVariables #-}
6-
{-# LANGUAGE TupleSections #-}
76
{-# LANGUAGE TypeApplications #-}
87
{-# LANGUAGE ViewPatterns #-}
98

@@ -12,17 +11,9 @@ module Main (main) where
1211
import Cardano.Crypto.Init (cryptoInit)
1312
import Cardano.Tools.DBAnalyser.HasAnalysis (Args, mkProtocolInfo)
1413
import Codec.Serialise
15-
import qualified Control.Monad as Monad
1614
import Control.Monad.Except
17-
import qualified Control.Monad.Trans as Trans (lift)
18-
import Control.ResourceRegistry (ResourceRegistry)
19-
import qualified Control.ResourceRegistry as RR
20-
import Control.Tracer (nullTracer)
2115
import DBAnalyser.Parsers
2216
import Data.Bifunctor
23-
import qualified Data.ByteString.Builder as BS
24-
import qualified Data.SOP.Dict as Dict
25-
import qualified Debug.Trace as Debug
2617
import Main.Utf8
2718
import Options.Applicative
2819
import Ouroboros.Consensus.Block
@@ -31,34 +22,17 @@ import Ouroboros.Consensus.Cardano.StreamingLedgerTables
3122
import Ouroboros.Consensus.Config
3223
import Ouroboros.Consensus.Ledger.Basics
3324
import Ouroboros.Consensus.Ledger.Extended
34-
import Ouroboros.Consensus.Ledger.SupportsProtocol
35-
import Ouroboros.Consensus.Ledger.Tables.Utils
3625
import Ouroboros.Consensus.Node.ProtocolInfo
37-
import Ouroboros.Consensus.Storage.LedgerDB
3826
import Ouroboros.Consensus.Storage.LedgerDB.Snapshots
39-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.Args as V1
40-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore as V1
4127
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.BackingStore.Impl.LMDB as V1
42-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.DbChangelog as V1
43-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.Lock as V1
44-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V1.Snapshots as V1
45-
import Ouroboros.Consensus.Storage.LedgerDB.V2.Args
46-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.InMemory as InMemory
47-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.InMemory as V2
48-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.LSM as LSM
49-
import qualified Ouroboros.Consensus.Storage.LedgerDB.V2.LedgerSeq as V2
50-
import Ouroboros.Consensus.Util.CRC
5128
import Ouroboros.Consensus.Util.IOLike
5229
import Ouroboros.Consensus.Util.StreamingLedgerTables
53-
import qualified System.Directory as Directory
30+
import qualified System.Directory as D
5431
import System.FS.API
55-
import System.FS.API.Lazy
5632
import System.FS.CRC
5733
import System.FS.IO
58-
import System.FilePath (splitFileName)
59-
import System.IO (hFlush, stdout)
60-
import System.IO.Temp
61-
import System.Random
34+
import System.FilePath (splitDirectories)
35+
import qualified System.FilePath as F
6236

6337
data Format
6438
= Mem FilePath
@@ -127,10 +101,18 @@ parsePath optName strHelp =
127101

128102
-- Helpers
129103

130-
pathToDiskSnapshot :: FilePath -> Maybe (SomeHasFS IO, FsPath, DiskSnapshot)
131-
pathToDiskSnapshot path = (SomeHasFS $ ioHasFS $ MountPoint dir,mkFsPath [file],) <$> snapshotFromPath file
132-
where
133-
(dir, file) = splitFileName path
104+
-- | Given a filepath pointing to a snapshot (with or without a trailing slash), produce:
105+
--
106+
-- * A HasFS at the snapshot directory
107+
pathToHasFS :: FilePath -> SomeHasFS IO
108+
pathToHasFS (maybeRemoveTrailingSlash -> path) =
109+
SomeHasFS $ ioHasFS $ MountPoint path
110+
111+
maybeRemoveTrailingSlash :: String -> String
112+
maybeRemoveTrailingSlash s = case last s of
113+
'/' -> init s
114+
'\\' -> init s
115+
_ -> s
134116

135117
defaultLMDBLimits :: V1.LMDBLimits
136118
defaultLMDBLimits =
@@ -142,166 +124,15 @@ defaultLMDBLimits =
142124

143125
data Error blk
144126
= SnapshotError (SnapshotFailure blk)
145-
| TablesCantDeserializeError DeserialiseFailure
146-
| TablesTrailingBytes
147-
| SnapshotFormatMismatch Format String
148127
| ReadSnapshotCRCError FsPath CRCError
149128
deriving Exception
150129

151130
instance StandardHash blk => Show (Error blk) where
152131
show (SnapshotError err) =
153132
"Couldn't deserialize the snapshot. Are you running the same node version that created the snapshot? "
154133
<> show err
155-
show (TablesCantDeserializeError err) = "Couldn't deserialize the tables: " <> show err
156-
show TablesTrailingBytes = "Malformed tables, there are trailing bytes!"
157-
show (SnapshotFormatMismatch expected err) =
158-
"The input snapshot does not seem to correspond to the input format:\n\t"
159-
<> show expected
160-
<> "\n\tThe provided path "
161-
<> err
162134
show (ReadSnapshotCRCError fp err) = "An error occurred while reading the snapshot checksum at " <> show fp <> ": \n\t" <> show err
163135

164-
-- load ::
165-
-- forall blk.
166-
-- ( CanStowLedgerTables (LedgerState blk)
167-
-- , LedgerSupportsProtocol blk
168-
-- , LedgerSupportsLedgerDB blk
169-
-- ) =>
170-
-- Config ->
171-
-- ResourceRegistry IO ->
172-
-- CodecConfig blk ->
173-
-- FilePath ->
174-
-- ExceptT (Error blk) IO (ExtLedgerState blk EmptyMK, LedgerTables (ExtLedgerState blk) ValuesMK)
175-
-- load config rr ccfg tempFP =
176-
-- case from config of
177-
-- -- Legacy (pathToDiskSnapshot -> Just (fs@(SomeHasFS hasFS), path, _)) -> do
178-
-- -- (st, checksumAsRead) <-
179-
-- -- first unstowLedgerTables
180-
-- -- <$> withExceptT
181-
-- -- (SnapshotError . InitFailureRead . ReadSnapshotFailed)
182-
-- -- (readExtLedgerState fs (decodeDiskExtLedgerState ccfg) decode path)
183-
-- -- let crcPath = path <.> "checksum"
184-
-- -- crcFileExists <- Trans.lift $ doesFileExist hasFS crcPath
185-
-- -- Monad.when crcFileExists $ do
186-
-- -- snapshotCRC <-
187-
-- -- withExceptT (ReadSnapshotCRCError crcPath) $
188-
-- -- readCRC hasFS crcPath
189-
-- -- Monad.when (checksumAsRead /= snapshotCRC) $
190-
-- -- throwError $
191-
-- -- SnapshotError $
192-
-- -- InitFailureRead ReadSnapshotDataCorruption
193-
-- -- pure (forgetLedgerTables st, projectLedgerTables st)
194-
-- Mem (pathToDiskSnapshot -> Just (fs, path, ds)) -> do
195-
-- (ls, _) <- withExceptT SnapshotError $ V2.loadSnapshot nullTracer rr ccfg fs ds
196-
-- let h = V2.currentHandle ls
197-
-- (V2.state h,) <$> Trans.lift (V2.readAll (V2.tables h) (V2.state h))
198-
-- LMDB (pathToDiskSnapshot -> Just (fs, _, ds)) -> do
199-
-- ((dbch, k, bstore), _) <-
200-
-- withExceptT SnapshotError $
201-
-- V1.loadSnapshot
202-
-- nullTracer
203-
-- (V1.LMDBBackingStoreArgs tempFP defaultLMDBLimits Dict.Dict)
204-
-- ccfg
205-
-- (V1.SnapshotsFS fs)
206-
-- rr
207-
-- ds
208-
-- values <- Trans.lift (V1.bsReadAll bstore (V1.changelogLastFlushedState dbch))
209-
-- _ <- Trans.lift $ RR.release k
210-
-- pure (V1.current dbch, values)
211-
-- LSM _ _ -> error "unimplemented"
212-
-- _ -> error "Malformed input path!"
213-
214-
-- store ::
215-
-- ( CanStowLedgerTables (LedgerState blk)
216-
-- , LedgerSupportsProtocol blk
217-
-- , LedgerSupportsLedgerDB blk
218-
-- ) =>
219-
-- Config ->
220-
-- CodecConfig blk ->
221-
-- (ExtLedgerState blk EmptyMK, LedgerTables (ExtLedgerState blk) ValuesMK) ->
222-
-- SomeHasFS IO ->
223-
-- IO ()
224-
-- store config ccfg (state, tbs) tempFS =
225-
-- case to config of
226-
-- -- Legacy (p@(pathToDiskSnapshot -> Just (fs@(SomeHasFS hasFS), path, _))) -> do
227-
-- -- crc <-
228-
-- -- writeExtLedgerState
229-
-- -- fs
230-
-- -- (encodeDiskExtLedgerState ccfg)
231-
-- -- path
232-
-- -- (stowLedgerTables $ state `withLedgerTables` tbs)
233-
-- -- withFile hasFS (path <.> "checksum") (WriteMode MustBeNew) $ \h ->
234-
-- -- Monad.void $ hPutAll hasFS h . BS.toLazyByteString . BS.word32HexFixed $ getCRC crc
235-
-- -- putStrLn "DONE"
236-
-- -- putStrLn $
237-
-- -- unlines $
238-
-- -- [ "You can now copy the file "
239-
-- -- ++ p
240-
-- -- ++ " to your `ledger` directory in your ChainDB storage."
241-
-- -- , "Note this snapshot can only be used by cardano-node <10.4."
242-
-- -- ]
243-
-- Mem (p@(pathToDiskSnapshot -> Just (fs, _, DiskSnapshot _ suffix))) -> do
244-
-- lseq <- V2.empty state tbs $ V2.newInMemoryLedgerTablesHandle nullTracer fs
245-
-- let h = V2.currentHandle lseq
246-
-- Monad.void $ InMemory.implTakeSnapshot ccfg nullTracer fs suffix h
247-
-- putStrLn "DONE"
248-
-- putStrLn $
249-
-- unlines $
250-
-- [ "You can now copy the directory "
251-
-- ++ p
252-
-- ++ " to your `ledger` directory in your ChainDB storage."
253-
-- , "Note this snapshot can only be used by cardano-node >=10.4 configured to use the InMemory backend (set the \"LedgerDB\".\"Backend\" key in your config file to \"V2InMemory\" or leave it undefined)."
254-
-- ]
255-
-- LMDB (p@(pathToDiskSnapshot -> Just (fs, _, DiskSnapshot _ suffix))) -> do
256-
-- chlog <- newTVarIO (V1.empty state)
257-
-- lock <- V1.mkLedgerDBLock
258-
-- bs <-
259-
-- V1.newLMDBBackingStore
260-
-- nullTracer
261-
-- defaultLMDBLimits
262-
-- (V1.LiveLMDBFS tempFS)
263-
-- (V1.SnapshotsFS fs)
264-
-- (V1.InitFromValues (pointSlot $ getTip state) state tbs)
265-
-- Monad.void $ V1.withReadLock lock $ do
266-
-- V1.implTakeSnapshot chlog ccfg nullTracer (V1.SnapshotsFS fs) bs suffix
267-
-- putStrLn "DONE"
268-
-- putStrLn $
269-
-- unlines $
270-
-- [ "You can now copy the directory "
271-
-- ++ p
272-
-- ++ " to your `ledger` directory in your ChainDB storage."
273-
-- , "Note this snapshot can only be used by cardano-node >=10.4 configured to use the LMDB backend (set the \"LedgerDB\".\"Backend\" key in your config file to \"V1LMDB\")."
274-
-- ]
275-
-- LSM (p@(pathToDiskSnapshot -> Just (fs, _, DiskSnapshot _ suffix))) dbPath -> do
276-
-- exists <- Directory.doesDirectoryExist dbPath
277-
-- Monad.when (not exists) $ Directory.createDirectory dbPath
278-
-- RR.withRegistry $ \reg -> do
279-
-- (_, SomeHasFSAndBlockIO hasFS blockIO) <- LSM.stdMkBlockIOFS dbPath reg
280-
-- salt <- fst . genWord64 <$> newStdGen
281-
-- LSM.withNewSession nullTracer hasFS blockIO salt (mkFsPath [""]) $ \session -> do
282-
-- lsmTable <- LSM.tableFromValuesMK reg session state tbs
283-
-- lsmHandle <- LSM.newLSMLedgerTablesHandle nullTracer reg lsmTable
284-
-- Monad.void $
285-
-- LSM.implTakeSnapshot
286-
-- ccfg
287-
-- nullTracer
288-
-- fs
289-
-- suffix
290-
-- (V2.StateRef state lsmHandle)
291-
-- putStrLn "DONE"
292-
-- putStrLn $
293-
-- unlines $
294-
-- [ "You can now:"
295-
-- , "- copy the directory "
296-
-- ++ p
297-
-- ++ " to your `ledger` directory in your ChainDB storage."
298-
-- , "- copy the directory "
299-
-- ++ dbPath
300-
-- ++ " to your fast storage device and point to it in your config file."
301-
-- , "Note this snapshot can only be used by cardano-node >=10.7 configured to use the LSM backend (set the \"LedgerDB\".\"Backend\" key in your config file to \"V2LSM\")."
302-
-- ]
303-
-- _ -> error "Malformed output path!"
304-
305136
main :: IO ()
306137
main = withStdTerminalHandles $ do
307138
cryptoInit
@@ -318,32 +149,24 @@ main = withStdTerminalHandles $ do
318149
(pure . first ledgerState)
319150
=<< runExceptT (readExtLedgerState fs (decodeDiskExtLedgerState ccfg) decode path)
320151

321-
(st, f) <- case from conf of
322-
Mem fp@(pathToDiskSnapshot -> Just (fs, path, _)) -> do
323-
(st, _) <- getState fs path
324-
pure (st, fromInMemory fp)
325-
LMDB fp@(pathToDiskSnapshot -> Just (fs, path, _)) -> do
326-
(st, _) <- getState (Debug.trace (show fp) fs) (Debug.traceShowId path </> mkFsPath ["state"])
327-
pure (st, fromLMDB (fp <> "/tables"))
328-
LSM fp@(pathToDiskSnapshot -> Just (fs, path, ds)) fp2 -> do
329-
(st, _) <- getState fs (Debug.traceShowId path </> mkFsPath ["state"])
330-
pure (st, fromLSM fp2 (dsSuffix ds))
331-
let t = case to conf of
332-
Mem fp@(pathToDiskSnapshot -> Just (fs, path, _)) ->
333-
toInMemory fp
334-
LMDB fp@(pathToDiskSnapshot -> Just (fs, path, _)) ->
335-
toLMDB fp
336-
LSM fp@(pathToDiskSnapshot -> Just (fs, path, _)) fp2 ->
337-
toLSM fp
338-
either throwIO pure =<< runExceptT (stream st f t)
152+
(st, fpInDir, f) <- case from conf of
153+
Mem fp@(pathToHasFS -> fs) -> do
154+
(st, _) <- getState fs (mkFsPath ["state"])
155+
pure (st, fp, fromInMemory (fp F.</> "tables" F.</> "tvar"))
156+
LMDB fp@(pathToHasFS -> fs) -> do
157+
(st, _) <- getState fs (mkFsPath ["state"])
158+
pure (st, fp, fromLMDB (fp F.</> "tables") defaultLMDBLimits)
159+
LSM fp@(pathToHasFS -> fs) lsmDbPath -> do
160+
(st, _) <- getState fs (mkFsPath ["state"])
161+
pure (st, fp, fromLSM lsmDbPath (last $ splitDirectories fp))
339162

340-
-- withSystemTempDirectory "lmdb" $ \dir -> do
341-
-- let tempFS = SomeHasFS $ ioHasFS $ MountPoint dir
342-
-- RR.withRegistry $ \rr -> do
343-
-- putStr "Loading snapshot..."
344-
-- hFlush stdout
345-
-- state <- either throwIO pure =<< runExceptT (load conf rr ccfg dir)
346-
-- putStrLn "DONE"
347-
-- putStr "Writing snapshot..."
348-
-- hFlush stdout
349-
-- store conf ccfg state tempFS
163+
let (fpOutDir, t) = case to conf of
164+
Mem fp -> (fp, toInMemory fp)
165+
LMDB fp -> (fp, toLMDB fp defaultLMDBLimits)
166+
LSM fp lsmDbPath -> (fp, toLSM lsmDbPath (last $ splitDirectories fp))
167+
168+
D.createDirectoryIfMissing True fpOutDir
169+
170+
D.copyFile (fpInDir F.</> "state") (fpOutDir F.</> "state")
171+
172+
either throwIO pure =<< runExceptT (stream st f t)

0 commit comments

Comments
 (0)