Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ledger state dir optional to handle disable ledger option #1378

Merged
merged 9 commits into from Mar 23, 2023
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -8,6 +8,7 @@ launch_*
cabal.project.local
gen/
/.vscode
.DS_Store

cardano-chain-gen/test/testfiles/temp/
/secp256k1/
4 changes: 2 additions & 2 deletions cardano-chain-gen/test/Test/Cardano/Db/Mock/Config.hs
Expand Up @@ -219,12 +219,12 @@ mkSyncNodeParams staticDir mutableDir = do
SyncNodeParams
{ enpConfigFile = ConfigFile $ staticDir </> "test-db-sync-config.json"
, enpSocketPath = SocketPath $ mutableDir </> ".socket"
, enpLedgerStateDir = LedgerStateDir $ mutableDir </> "ledger-states"
, enpMaybeLedgerStateDir = Just $ LedgerStateDir $ mutableDir </> "ledger-states"
, enpMigrationDir = MigrationDir "../schema"
, enpPGPassSource = Db.PGPassCached pgconfig
, enpExtended = True
, enpHasCache = True
, enpHasLedger = True
, enpShouldUseLedger = True
, enpSkipFix = True
, enpOnlyFix = False
, enpForceIndexes = False
Expand Down
35 changes: 27 additions & 8 deletions cardano-db-sync/app/cardano-db-sync.hs
Expand Up @@ -15,21 +15,40 @@ import Options.Applicative (Parser, ParserInfo)
import qualified Options.Applicative as Opt
import Paths_cardano_db_sync (version)
import System.Info (arch, compilerName, compilerVersion, os)
import GHC.Base (error)

main :: IO ()
main = do
cmd <- Opt.execParser opts
case cmd of
CmdVersion -> runVersionCommand
CmdRun params -> do
prometheusPort <- dncPrometheusPort <$> readSyncNodeConfig (enpConfigFile params)

withMetricSetters prometheusPort $ \metricsSetters ->
runDbSyncNode metricsSetters knownMigrationsPlain params
let maybeLedgerStateDir = enpMaybeLedgerStateDir params
case (maybeLedgerStateDir, enpShouldUseLedger params) of
(Just _, True ) -> run params
(Nothing, False ) -> run params
(Just _, False ) -> error disableLedgerErrorMsg
(Nothing, True) -> error stateDirErrorMsg
where
knownMigrationsPlain :: [(Text, Text)]
knownMigrationsPlain = (\x -> (hash x, filepath x)) <$> knownMigrations

disableLedgerErrorMsg :: [Char]
disableLedgerErrorMsg =
"Error: Using `--disable-ledger` doesn't require having a --state-dir. "
<> "For more details view https://github.com/input-output-hk/cardano-db-sync/blob/master/doc/configuration.md#--disable-ledger"

stateDirErrorMsg :: [Char]
stateDirErrorMsg =
"Error: If not using --state-dir then make sure to have --disable-ledger. "
<> "For more details view https://github.com/input-output-hk/cardano-db-sync/blob/master/doc/syncing-and-rollbacks.md#ledger-state"

run :: SyncNodeParams -> IO ()
run prms = do
prometheusPort <- dncPrometheusPort <$> readSyncNodeConfig (enpConfigFile prms)
withMetricSetters prometheusPort $ \metricsSetters ->
runDbSyncNode metricsSetters knownMigrationsPlain prms

-- -------------------------------------------------------------------------------------------------

opts :: ParserInfo SyncCommand
Expand All @@ -52,12 +71,12 @@ pRunDbSyncNode =
SyncNodeParams
<$> pConfigFile
<*> pSocketPath
<*> pLedgerStateDir
<*> optional pLedgerStateDir
<*> pMigrationDir
<*> pPGPassSource
<*> pExtended
<*> pHasCache
<*> pHasLedger
<*> pUseLedger
<*> pSkipFix
<*> pOnlyFix
<*> pForceIndexes
Expand Down Expand Up @@ -148,8 +167,8 @@ pHasCache =
<> Opt.help "Disables the db-sync caches. Reduces memory usage but it takes longer to sync."
)

pHasLedger :: Parser Bool
pHasLedger =
pUseLedger :: Parser Bool
pUseLedger =
Opt.flag
True
False
Expand Down
2 changes: 1 addition & 1 deletion cardano-db-sync/src/Cardano/DbSync.hs
Expand Up @@ -141,7 +141,7 @@ startupReport :: Trace IO Text -> Bool -> SyncNodeParams -> IO ()
startupReport trce aop params = do
logInfo trce $ mconcat ["Version number: ", Text.pack (showVersion version)]
logInfo trce $ mconcat ["Git hash: ", Db.gitRev]
logInfo trce $ mconcat ["Option disable-ledger: ", textShow (not $ enpHasLedger params)]
logInfo trce $ mconcat ["Option disable-ledger: ", textShow (not $ enpShouldUseLedger params)]
logInfo trce $ mconcat ["Option disable-cache: ", textShow (not $ enpHasCache params)]
logInfo trce $ mconcat ["Option disable-epoch: ", textShow (not $ enpExtended params)]
logInfo trce $ mconcat ["Option skip-plutus-data-fix: ", textShow (enpSkipFix params)]
Expand Down
154 changes: 95 additions & 59 deletions cardano-db-sync/src/Cardano/DbSync/Api.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
Expand All @@ -21,8 +22,10 @@ module Cardano.DbSync.Api (
mkSyncEnvFromConfig,
replaceConnection,
verifySnapshotPoint,
getTrace,
getBackend,
getTrace,
getTopLevelConfig,
getNetwork,
hasLedgerState,
getLatestPoints,
getSlotHash,
Expand Down Expand Up @@ -67,10 +70,12 @@ import Database.Persist.Postgresql (ConnectionString)
import Database.Persist.Sql (SqlBackend)
import Ouroboros.Consensus.Block.Abstract (HeaderHash, Point (..), fromRawHash)
import Ouroboros.Consensus.BlockchainTime.WallClock.Types (SystemStart (..))
import Ouroboros.Consensus.Config (TopLevelConfig)
import Ouroboros.Consensus.Node.ProtocolInfo (ProtocolInfo)
import Ouroboros.Network.Block (BlockNo (..), Point (..))
import Ouroboros.Network.Magic (NetworkMagic (..))
import qualified Ouroboros.Network.Point as Point
import qualified Ouroboros.Consensus.Node.ProtocolInfo as Consensus

data SyncEnv = SyncEnv
{ envProtocol :: !SyncProtocol
Expand All @@ -88,10 +93,17 @@ data SyncEnv = SyncEnv
, envOfflineResultQueue :: !(StrictTBQueue IO FetchResult)
, envEpochState :: !(StrictTVar IO EpochState)
, envEpochSyncTime :: !(StrictTVar IO UTCTime)
, envNoLedgerEnv :: !NoLedgerStateEnv -- only used when configured without ledger state.
, envLedger :: !LedgerEnv
, envLedgerEnv :: !LedgerEnv
}

-- A representation of if we are using a ledger or not given CLI options
data LedgerEnv where
HasLedger :: HasLedgerEnv -> LedgerEnv
NoLedger :: NoLedgerEnv -> LedgerEnv

-- topLevelConfig :: SyncEnv -> TopLevelConfig CardanoBlock
-- topLevelConfig = Consensus.pInfoConfig . envProtocolInfo
Cmdv marked this conversation as resolved.
Show resolved Hide resolved

type RunMigration = DB.MigrationToRun -> IO ()

data ConsistentLevel = Consistent | DBAheadOfLedger | Unchecked
Expand Down Expand Up @@ -130,16 +142,13 @@ runIndexMigrations env = do
haveRan <- readTVarIO $ envIndexes env
unless haveRan $ do
envRunDelayedMigration env DB.Indexes
logInfo trce "Indexes were created"
logInfo (getTrace env) "Indexes were created"
atomically $ writeTVar (envIndexes env) True
where
trce = getTrace env

data SyncOptions = SyncOptions
{ soptExtended :: !Bool
, soptAbortOnInvalid :: !Bool
, soptCache :: !Bool
, soptLedger :: !Bool
, soptSkipFix :: !Bool
, soptOnlyFix :: !Bool
, snapshotEveryFollowing :: !Word64
Expand Down Expand Up @@ -187,8 +196,23 @@ generateNewEpochEvents env details = do
, esEpochNo = Strict.Just currentEpochNo
}

getTopLevelConfig :: SyncEnv -> TopLevelConfig CardanoBlock
getTopLevelConfig syncEnv =
case envLedgerEnv syncEnv of
HasLedger hasLedgerEnv -> Consensus.pInfoConfig $ leProtocolInfo hasLedgerEnv
NoLedger noLedgerEnv -> Consensus.pInfoConfig $ nleProtocolInfo noLedgerEnv
Cmdv marked this conversation as resolved.
Show resolved Hide resolved

getTrace :: SyncEnv -> Trace IO Text
Cmdv marked this conversation as resolved.
Show resolved Hide resolved
getTrace = leTrace . envLedger
getTrace sEnv =
case envLedgerEnv sEnv of
HasLedger hasLedgerEnv -> leTrace hasLedgerEnv
NoLedger noLedgerEnv -> nleTracer noLedgerEnv

getNetwork :: SyncEnv -> Ledger.Network
getNetwork sEnv =
case envLedgerEnv sEnv of
HasLedger hasLedgerEnv -> leNetwork hasLedgerEnv
NoLedger noLedgerEnv -> nleNetwork noLedgerEnv

getSlotHash :: SqlBackend -> SlotNo -> IO [(SlotNo, ByteString)]
getSlotHash backend = DB.runDbIohkNoLogging backend . DB.querySlotHash
Expand All @@ -201,7 +225,10 @@ getBackend env = do
Strict.Nothing -> panic "sql connection not initiated"

hasLedgerState :: SyncEnv -> Bool
hasLedgerState = soptLedger . envOptions
hasLedgerState syncEnv =
case envLedgerEnv syncEnv of
HasLedger _ -> True
NoLedger _ -> False

getDbLatestBlockInfo :: SqlBackend -> IO (Maybe TipInfo)
getDbLatestBlockInfo backend = do
Expand All @@ -225,11 +252,12 @@ getDbTipBlockNo env =

logDbState :: SyncEnv -> IO ()
logDbState env = do
let tracer = getTrace env
Cmdv marked this conversation as resolved.
Show resolved Hide resolved
backend <- getBackend env
mblk <- getDbLatestBlockInfo backend
case mblk of
Nothing -> logInfo (getTrace env) "Cardano.Db is empty"
Just tip -> logInfo (getTrace env) $ mconcat ["Cardano.Db tip is at ", showTip tip]
Nothing -> logInfo tracer "Cardano.Db is empty"
Just tip -> logInfo tracer $ mconcat ["Cardano.Db tip is at ", showTip tip]
where
showTip :: TipInfo -> Text
showTip tipInfo =
Expand All @@ -256,22 +284,13 @@ mkSyncEnv ::
Ledger.Network ->
NetworkMagic ->
SystemStart ->
LedgerStateDir ->
Maybe LedgerStateDir ->
Bool -> -- shouldUseLedger
Bool ->
Bool ->
RunMigration ->
IO SyncEnv
mkSyncEnv trce connSring syncOptions protoInfo nw nwMagic systemStart dir ranAll forcedIndexes runMigration = do
ledgerEnv <-
mkLedgerEnv
trce
protoInfo
dir
nw
systemStart
(soptAbortOnInvalid syncOptions)
(snapshotEveryFollowing syncOptions)
(snapshotEveryLagging syncOptions)
mkSyncEnv trce connSring syncOptions protoInfo nw nwMagic systemStart maybeLedgerDir shouldUseLedger ranAll forcedIndexes runMigration = do
cache <- if soptCache syncOptions then newEmptyCache 250000 else pure uninitiatedCache
backendVar <- newTVarIO Strict.Nothing
consistentLevelVar <- newTVarIO Unchecked
Expand All @@ -281,7 +300,23 @@ mkSyncEnv trce connSring syncOptions protoInfo nw nwMagic systemStart dir ranAll
orq <- newTBQueueIO 100
epochVar <- newTVarIO initEpochState
epochSyncTime <- newTVarIO =<< getCurrentTime
noLegdState <- mkNoLedgerStateEnv trce systemStart
ledgerEnvType <-
case (maybeLedgerDir, shouldUseLedger) of
(Just dir, True) ->
HasLedger
<$> mkHasLedgerEnv
trce
protoInfo
dir
nw
systemStart
(soptAbortOnInvalid syncOptions)
(snapshotEveryFollowing syncOptions)
(snapshotEveryLagging syncOptions)
(_, False) -> NoLedger <$> mkNoLedgerEnv trce protoInfo nw systemStart
-- This won't ever call because we error out this combination at parse time
(Nothing, True) -> NoLedger <$> mkNoLedgerEnv trce protoInfo nw systemStart

pure $
SyncEnv
{ envProtocol = SyncProtocolCardano
Expand All @@ -299,62 +334,63 @@ mkSyncEnv trce connSring syncOptions protoInfo nw nwMagic systemStart dir ranAll
, envOfflineResultQueue = orq
, envEpochState = epochVar
, envEpochSyncTime = epochSyncTime
, envNoLedgerEnv = noLegdState
, envLedger = ledgerEnv
, envLedgerEnv = ledgerEnvType
}

mkSyncEnvFromConfig ::
Trace IO Text ->
ConnectionString ->
SyncOptions ->
LedgerStateDir ->
Maybe LedgerStateDir ->
Bool -> -- shouldUseLedger
GenesisConfig ->
Bool ->
Bool ->
RunMigration ->
IO (Either SyncNodeError SyncEnv)
mkSyncEnvFromConfig trce connSring syncOptions dir genCfg ranAll forcedIndexes runMigration =
mkSyncEnvFromConfig trce connSring syncOptions maybeLedgerDir shouldUseLedger genCfg ranAll forcedIndexes runMigration =
case genCfg of
GenesisCardano _ bCfg sCfg _
| unProtocolMagicId (Byron.configProtocolMagicId bCfg) /= Shelley.sgNetworkMagic (scConfig sCfg) ->
pure . Left . NECardanoConfig $
mconcat
[ "ProtocolMagicId "
, DB.textShow (unProtocolMagicId $ Byron.configProtocolMagicId bCfg)
, " /= "
, DB.textShow (Shelley.sgNetworkMagic $ scConfig sCfg)
]
pure . Left . NECardanoConfig $
mconcat
[ "ProtocolMagicId "
, DB.textShow (unProtocolMagicId $ Byron.configProtocolMagicId bCfg)
, " /= "
, DB.textShow (Shelley.sgNetworkMagic $ scConfig sCfg)
]
| Byron.gdStartTime (Byron.configGenesisData bCfg) /= Shelley.sgSystemStart (scConfig sCfg) ->
pure . Left . NECardanoConfig $
mconcat
[ "SystemStart "
, DB.textShow (Byron.gdStartTime $ Byron.configGenesisData bCfg)
, " /= "
, DB.textShow (Shelley.sgSystemStart $ scConfig sCfg)
]
pure . Left . NECardanoConfig $
mconcat
[ "SystemStart "
, DB.textShow (Byron.gdStartTime $ Byron.configGenesisData bCfg)
, " /= "
, DB.textShow (Shelley.sgSystemStart $ scConfig sCfg)
]
| otherwise ->
Right
<$> mkSyncEnv
trce
connSring
syncOptions
(mkProtocolInfoCardano genCfg [])
(Shelley.sgNetworkId $ scConfig sCfg)
(NetworkMagic . unProtocolMagicId $ Byron.configProtocolMagicId bCfg)
(SystemStart . Byron.gdStartTime $ Byron.configGenesisData bCfg)
dir
ranAll
forcedIndexes
runMigration
Right
<$> mkSyncEnv
trce
connSring
syncOptions
(mkProtocolInfoCardano genCfg [])
(Shelley.sgNetworkId $ scConfig sCfg)
(NetworkMagic . unProtocolMagicId $ Byron.configProtocolMagicId bCfg)
(SystemStart . Byron.gdStartTime $ Byron.configGenesisData bCfg)
maybeLedgerDir
shouldUseLedger
ranAll
forcedIndexes
runMigration

-- | 'True' is for in memory points and 'False' for on disk
getLatestPoints :: SyncEnv -> IO [(CardanoPoint, Bool)]
getLatestPoints env = do
if hasLedgerState env
then do
snapshotPoints <- listKnownSnapshots $ envLedger env
case envLedgerEnv env of
HasLedger hasLedgerEnv -> do
snapshotPoints <- listKnownSnapshots hasLedgerEnv
verifySnapshotPoint env snapshotPoints
else do
NoLedger _ -> do
-- Brings the 5 latest.
dbBackend <- getBackend env
lastPoints <- DB.runDbIohkNoLogging dbBackend DB.queryLatestPoints
Expand Down
4 changes: 2 additions & 2 deletions cardano-db-sync/src/Cardano/DbSync/Config/Types.hs
Expand Up @@ -56,12 +56,12 @@ data SyncCommand
data SyncNodeParams = SyncNodeParams
{ enpConfigFile :: !ConfigFile
, enpSocketPath :: !SocketPath
, enpLedgerStateDir :: !LedgerStateDir
, enpMaybeLedgerStateDir :: !(Maybe LedgerStateDir)
, enpMigrationDir :: !MigrationDir
, enpPGPassSource :: !PGPassSource
, enpExtended :: !Bool
, enpHasCache :: !Bool
, enpHasLedger :: !Bool
, enpShouldUseLedger :: !Bool
, enpSkipFix :: !Bool
, enpOnlyFix :: !Bool
, enpForceIndexes :: !Bool
Expand Down