1515 , PackageImports
1616 , ScopedTypeVariables
1717 , TypeApplications
18+ , RecordWildCards
19+ , ApplicativeDo
1820#-}
1921
2022module Chainweb.Pact.Backend.Compaction
@@ -23,8 +25,8 @@ module Chainweb.Pact.Backend.Compaction
2325 main
2426
2527 -- * Exported for testing
26- , compactPactState
27- , compactRocksDb
28+ , doCompactPactState
29+ , doCompactRocksDb
2830 , Retainment (.. )
2931 , defaultRetainment
3032
@@ -147,23 +149,24 @@ data Config = Config
147149 , toDir :: FilePath
148150 , concurrent :: ConcurrentChains
149151 , logDir :: FilePath
150- , noRocksDb :: Bool
151- -- ^ Don't produce a new RocksDB at all.
152- , noPactState :: Bool
153- -- ^ Don't produce a new Pact State at all.
154- , keepFullTransactionIndex :: Bool
155- -- ^ Whether or not to keep the entire TransactionIndex table. Some APIs rely on this table.
152+ , compactRocksDb :: Bool
153+ -- ^ Compact the RocksDB at all?
154+ , compactPactState :: Bool
155+ -- ^ Compact the Pact State at all?
156+ , compactTransactionIndex :: Bool
157+ -- ^ Compact the TransactionIndex table in the Pact state?
158+ -- Some APIs (e.g. /poll) rely on this table, so the default is False.
156159 }
157160
158161data Retainment = Retainment
159- { keepFullTransactionIndex :: Bool
162+ { compactTransactionIndex :: Bool
160163 , compactThese :: CompactThese
161164 }
162165
163166defaultRetainment :: Retainment
164167defaultRetainment = Retainment
165- { keepFullTransactionIndex = False
166- , compactThese = CompactBoth
168+ { compactTransactionIndex = False
169+ , compactThese = CompactOnlyPactState
167170 }
168171
169172data CompactThese = CompactOnlyRocksDb | CompactOnlyPactState | CompactBoth | CompactNeither
@@ -180,16 +183,26 @@ getConfig = do
180183 (O. fullDesc <> O. progDesc " Pact DB Compaction Tool - create a compacted copy of the source database directory Pact DB into the target directory." )
181184
182185 parser :: O. Parser Config
183- parser = Config
184- <$> (parseVersion <$> O. strOption (O. long " chainweb-version" <> O. value " mainnet01" ))
185- <*> O. strOption (O. long " from" <> O. help " Directory containing SQLite Pact state and RocksDB block data to compact (expected to be in $DIR/0/{sqlite,rocksDb}" )
186- <*> O. strOption (O. long " to" <> O. help " Directory where to place the compacted Pact state and block data. It will place them in $DIR/0/{sqlite,rocksDb}, respectively." )
187- <*> O. flag SingleChain ManyChainsAtOnce (O. long " parallel" <> O. help " Turn on multi-threaded compaction. The threads are per-chain." )
188- <*> O. strOption (O. long " log-dir" <> O. help " Directory where compaction logs will be placed." )
186+ parser = do
187+ chainwebVersion <- (parseVersion <$> O. strOption (O. long " chainweb-version" <> O. value " mainnet01" ))
188+ fromDir <- O. strOption (O. long " from" <> O. help " Directory containing SQLite Pact state and RocksDB block data to compact (expected to be in $DIR/0/{sqlite,rocksDb}" )
189+ toDir <- O. strOption (O. long " to" <> O. help " Directory where to place the compacted Pact state and block data. It will place them in $DIR/0/{sqlite,rocksDb}, respectively." )
190+ concurrent <- O. flag SingleChain ManyChainsAtOnce (O. long " parallel" <> O. help " Turn on multi-threaded compaction. The threads are per-chain." )
191+ logDir <- O. strOption (O. long " log-dir" <> O. help " Directory where compaction logs will be placed." )
189192 -- Hidden options
190- <*> O. switch (O. long " keep-full-rocksdb" <> O. hidden)
191- <*> O. switch (O. long " no-rocksdb" <> O. hidden)
192- <*> O. switch (O. long " no-pact" <> O. hidden)
193+ compactRocksDb <- O. switch
194+ (O. long " compact-rocksdb"
195+ <> O. help " Compact rocksDB block data. Some interfaces require this data for historical blocks, like the /poll Pact endpoint or the /header Chainweb endpoint, so it is not compacted by default."
196+ )
197+ compactPactState <- not <$> O. switch
198+ (O. long " no-compact-pact"
199+ <> O. help " Do not compact Pact state. Pact state is not used by any public interface, so it is compacted by default, and the space savings are usually large on mainnet."
200+ )
201+ compactTransactionIndex <- O. switch
202+ (O. long " compact-transaction-index"
203+ <> O. help " Compact the TransactionIndex table in the Pact state. For historical blocks, the /poll Pact endpoint relies on this table, so it is not compacted by default."
204+ )
205+ return Config {.. }
193206
194207 parseVersion :: Text -> ChainwebVersion
195208 parseVersion =
@@ -201,8 +214,8 @@ main :: IO ()
201214main = do
202215 compact =<< getConfig
203216
204- compactPactState :: (Logger logger ) => logger -> Retainment -> BlockHeight -> SQLiteEnv -> SQLiteEnv -> IO ()
205- compactPactState logger rt targetBlockHeight srcDb targetDb = do
217+ doCompactPactState :: (Logger logger ) => logger -> Retainment -> BlockHeight -> SQLiteEnv -> SQLiteEnv -> IO ()
218+ doCompactPactState logger rt targetBlockHeight srcDb targetDb = do
206219 let log = logFunctionText logger
207220
208221 -- These pragmas are tuned for fast insertion on systems with a wide range
@@ -262,8 +275,7 @@ compactPactState logger rt targetBlockHeight srcDb targetDb = do
262275
263276 -- Copy over TransactionIndex.
264277 --
265- -- If the user specifies that they want to keep the entire table, then we do so, otherwise,
266- -- we compact this based on the RocksDB 'blockHeightKeepDepth'.
278+ -- If the user specifies that they want to compact the table, then we do so based on the RocksDB 'blockHeightKeepDepth'.
267279 --
268280 -- /poll and SPV rely on having this table synchronised with RocksDB.
269281 -- We need to document APIs which need TransactionIndex.
@@ -272,7 +284,7 @@ compactPactState logger rt targetBlockHeight srcDb targetDb = do
272284 -- https://tableplus.com/blog/2018/07/sqlite-how-to-copy-table-to-another-database.html
273285 do
274286 (qry, args) <-
275- if rt. keepFullTransactionIndex
287+ if not rt. compactTransactionIndex
276288 then do
277289 log LL. Info " Copying over entire TransactionIndex table. This could take a while"
278290 let wholeTableQuery = " SELECT txhash, blockheight FROM TransactionIndex ORDER BY blockheight"
@@ -338,11 +350,11 @@ compact :: Config -> IO ()
338350compact cfg = do
339351 let cids = allChains cfg. chainwebVersion
340352
341- let _compactThese = case (cfg. noRocksDb , cfg. noPactState ) of
342- (True , True ) -> CompactNeither
343- (True , False ) -> CompactOnlyPactState
344- (False , True ) -> CompactOnlyRocksDb
345- (False , False ) -> CompactBoth
353+ let _compactThese = case (cfg. compactRocksDb , cfg. compactPactState ) of
354+ (False , False ) -> CompactNeither
355+ (False , True ) -> CompactOnlyPactState
356+ (True , False ) -> CompactOnlyRocksDb
357+ (True , True ) -> CompactBoth
346358
347359 -- Get the target blockheight.
348360 targetBlockHeight <- withDefaultLogger LL. Debug $ \ logger -> do
@@ -378,23 +390,23 @@ compact cfg = do
378390 pure targetBlockHeight
379391
380392 -- Compact RocksDB.
381- when ( not cfg. noRocksDb) $ do
393+ when cfg. compactRocksDb $ do
382394 withRocksDbFileLogger cfg. logDir LL. Debug $ \ logger -> do
383395 withReadOnlyRocksDb (rocksDir cfg. fromDir) modernDefaultOptions $ \ srcRocksDb -> do
384396 withRocksDb (rocksDir cfg. toDir) (modernDefaultOptions { compression = NoCompression }) $ \ targetRocksDb -> do
385- compactRocksDb (set setLoggerLevel (l2l LL. Info ) logger) cfg. chainwebVersion cids (targetBlockHeight - blockHeightKeepDepth) srcRocksDb targetRocksDb
397+ doCompactRocksDb (set setLoggerLevel (l2l LL. Info ) logger) cfg. chainwebVersion cids (targetBlockHeight - blockHeightKeepDepth) srcRocksDb targetRocksDb
386398
387399 -- Compact the pact state.
388400 let retainment = Retainment
389- { keepFullTransactionIndex = cfg. keepFullTransactionIndex
401+ { compactTransactionIndex = cfg. compactTransactionIndex
390402 , compactThese = _compactThese
391403 }
392- when ( not cfg. noPactState) $ do
404+ when cfg. compactPactState $ do
393405 forChains_ cfg. concurrent cids $ \ cid -> do
394406 withPerChainFileLogger cfg. logDir cid LL. Debug $ \ logger -> do
395407 withChainDb cid logger (pactDir cfg. fromDir) $ \ _ srcDb -> do
396408 withChainDb cid logger (pactDir cfg. toDir) $ \ _ targetDb -> do
397- compactPactState logger retainment targetBlockHeight srcDb targetDb
409+ doCompactPactState logger retainment targetBlockHeight srcDb targetDb
398410
399411compactTable :: (Logger logger )
400412 => logger -- ^ logger
@@ -701,15 +713,15 @@ rocksDir :: FilePath -> FilePath
701713rocksDir db = db </> " 0/rocksDb"
702714
703715-- | Copy over all CutHashes, all BlockHeaders, and only some Payloads.
704- compactRocksDb :: (Logger logger )
716+ doCompactRocksDb :: (Logger logger )
705717 => logger
706718 -> ChainwebVersion -- ^ cw version
707719 -> [ChainId ] -- ^ ChainIds
708720 -> BlockHeight -- ^ minBlockHeight for payload copying
709721 -> RocksDb -- ^ source db, should be opened read-only
710722 -> RocksDb -- ^ target db
711723 -> IO ()
712- compactRocksDb logger cwVersion cids minBlockHeight srcDb targetDb = do
724+ doCompactRocksDb logger cwVersion cids minBlockHeight srcDb targetDb = do
713725 let log = logFunctionText logger
714726
715727 -- Copy over entirety of CutHashes table
@@ -768,7 +780,7 @@ compactRocksDb logger cwVersion cids minBlockHeight srcDb targetDb = do
768780 -- them does not.
769781 Nothing -> do
770782 iterFirst it
771-
783+
772784 Just minBlockHeaderHistory -> do
773785 let runBack =
774786 let x = int minBlockHeight
0 commit comments