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/
2 changes: 1 addition & 1 deletion cardano-chain-gen/test/Test/Cardano/Db/Mock/Config.hs
Expand Up @@ -219,7 +219,7 @@ 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
Expand Down
2 changes: 1 addition & 1 deletion cardano-db-sync/app/cardano-db-sync.hs
Expand Up @@ -52,7 +52,7 @@ pRunDbSyncNode =
SyncNodeParams
<$> pConfigFile
<*> pSocketPath
<*> pLedgerStateDir
<*> optional pLedgerStateDir
<*> pMigrationDir
<*> pPGPassSource
<*> pExtended
Expand Down
72 changes: 35 additions & 37 deletions cardano-db-sync/src/Cardano/DbSync/Api.hs
Expand Up @@ -21,7 +21,6 @@ module Cardano.DbSync.Api (
mkSyncEnvFromConfig,
replaceConnection,
verifySnapshotPoint,
getTrace,
getBackend,
hasLedgerState,
getLatestPoints,
Expand Down Expand Up @@ -89,17 +88,17 @@ data SyncEnv = SyncEnv
, envEpochState :: !(StrictTVar IO EpochState)
, envEpochSyncTime :: !(StrictTVar IO UTCTime)
, envNoLedgerEnv :: !NoLedgerStateEnv -- only used when configured without ledger state.
, envLedger :: !LedgerEnv
, envLedger :: !(Maybe LedgerEnv)
}

type RunMigration = DB.MigrationToRun -> IO ()

data ConsistentLevel = Consistent | DBAheadOfLedger | Unchecked
deriving (Show, Eq)

setConsistentLevel :: SyncEnv -> ConsistentLevel -> IO ()
setConsistentLevel env cst = do
logInfo (getTrace env) $ "Setting ConsistencyLevel to " <> textShow cst
setConsistentLevel :: SyncEnv -> LedgerEnv -> ConsistentLevel -> IO ()
setConsistentLevel env ledgerEnv cst = do
logInfo (leTrace ledgerEnv) $ "Setting ConsistencyLevel to " <> textShow cst
atomically $ writeTVar (envConsistentLevel env) cst

getConsistentLevel :: SyncEnv -> IO ConsistentLevel
Expand All @@ -125,15 +124,13 @@ getRanIndexes :: SyncEnv -> IO Bool
getRanIndexes env = do
readTVarIO $ envIndexes env

runIndexMigrations :: SyncEnv -> IO ()
runIndexMigrations env = do
runIndexMigrations :: SyncEnv -> LedgerEnv -> IO ()
runIndexMigrations env ledgerEnv = do
haveRan <- readTVarIO $ envIndexes env
unless haveRan $ do
envRunDelayedMigration env DB.Indexes
logInfo trce "Indexes were created"
logInfo (leTrace ledgerEnv) "Indexes were created"
atomically $ writeTVar (envIndexes env) True
where
trce = getTrace env

data SyncOptions = SyncOptions
{ soptExtended :: !Bool
Expand Down Expand Up @@ -187,9 +184,6 @@ generateNewEpochEvents env details = do
, esEpochNo = Strict.Just currentEpochNo
}

getTrace :: SyncEnv -> Trace IO Text
Cmdv marked this conversation as resolved.
Show resolved Hide resolved
getTrace = leTrace . envLedger

getSlotHash :: SqlBackend -> SlotNo -> IO [(SlotNo, ByteString)]
getSlotHash backend = DB.runDbIohkNoLogging backend . DB.querySlotHash

Expand Down Expand Up @@ -223,13 +217,14 @@ getDbTipBlockNo env =
>>= getDbLatestBlockInfo
<&> maybe Point.Origin (Point.At . bBlockNo)

logDbState :: SyncEnv -> IO ()
logDbState env = do
logDbState :: SyncEnv -> LedgerEnv -> IO ()
logDbState env ledgerEnv= do
let tracer = leTrace ledgerEnv
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 +251,25 @@ mkSyncEnv ::
Ledger.Network ->
NetworkMagic ->
SystemStart ->
LedgerStateDir ->
Maybe LedgerStateDir ->
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 ranAll forcedIndexes runMigration = do
maybeLedgerEnv <-
case maybeLedgerDir of
Nothing -> pure Nothing
Just dir -> do
Just <$> mkLedgerEnv
trce
protoInfo
dir
nw
systemStart
(soptAbortOnInvalid syncOptions)
(snapshotEveryFollowing syncOptions)
(snapshotEveryLagging syncOptions)
cache <- if soptCache syncOptions then newEmptyCache 250000 else pure uninitiatedCache
backendVar <- newTVarIO Strict.Nothing
consistentLevelVar <- newTVarIO Unchecked
Expand Down Expand Up @@ -300,20 +298,20 @@ mkSyncEnv trce connSring syncOptions protoInfo nw nwMagic systemStart dir ranAll
, envEpochState = epochVar
, envEpochSyncTime = epochSyncTime
, envNoLedgerEnv = noLegdState
, envLedger = ledgerEnv
, envLedger = maybeLedgerEnv
}

mkSyncEnvFromConfig ::
Trace IO Text ->
ConnectionString ->
SyncOptions ->
LedgerStateDir ->
Maybe LedgerStateDir ->
GenesisConfig ->
Bool ->
Bool ->
RunMigration ->
IO (Either SyncNodeError SyncEnv)
mkSyncEnvFromConfig trce connSring syncOptions dir genCfg ranAll forcedIndexes runMigration =
mkSyncEnvFromConfig trce connSring syncOptions maybeLedgerDir genCfg ranAll forcedIndexes runMigration =
case genCfg of
GenesisCardano _ bCfg sCfg _
| unProtocolMagicId (Byron.configProtocolMagicId bCfg) /= Shelley.sgNetworkMagic (scConfig sCfg) ->
Expand Down Expand Up @@ -342,19 +340,19 @@ mkSyncEnvFromConfig trce connSring syncOptions dir genCfg ranAll forcedIndexes r
(Shelley.sgNetworkId $ scConfig sCfg)
(NetworkMagic . unProtocolMagicId $ Byron.configProtocolMagicId bCfg)
(SystemStart . Byron.gdStartTime $ Byron.configGenesisData bCfg)
dir
maybeLedgerDir
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 envLedger env of
Just ledgerEnv -> do
snapshotPoints <- listKnownSnapshots ledgerEnv
verifySnapshotPoint env snapshotPoints
else do
Nothing -> do
-- Brings the 5 latest.
dbBackend <- getBackend env
lastPoints <- DB.runDbIohkNoLogging dbBackend DB.queryLatestPoints
Expand Down
2 changes: 1 addition & 1 deletion cardano-db-sync/src/Cardano/DbSync/Config/Types.hs
Expand Up @@ -56,7 +56,7 @@ data SyncCommand
data SyncNodeParams = SyncNodeParams
{ enpConfigFile :: !ConfigFile
, enpSocketPath :: !SocketPath
, enpLedgerStateDir :: !LedgerStateDir
, enpMaybeLedgerStateDir :: !(Maybe LedgerStateDir)
, enpMigrationDir :: !MigrationDir
, enpPGPassSource :: !PGPassSource
, enpExtended :: !Bool
Expand Down
49 changes: 24 additions & 25 deletions cardano-db-sync/src/Cardano/DbSync/Database.hs
Expand Up @@ -40,24 +40,25 @@ data NextState

runDbThread ::
SyncEnv ->
LedgerEnv ->
MetricSetters ->
DbActionQueue ->
IO ()
runDbThread env metricsSetters queue = do
runDbThread syncEnv ledgerEnv metricsSetters queue = do
Cmdv marked this conversation as resolved.
Show resolved Hide resolved
logInfo trce "Running DB thread"
logException trce "runDBThread: " loop
logInfo trce "Shutting down DB thread"
where
trce = getTrace env
trce = leTrace ledgerEnv
loop = do
xs <- blockingFlushDbActionQueue queue

when (length xs > 1) $ do
logDebug trce $ "runDbThread: " <> textShow (length xs) <> " blocks"

eNextState <- runExceptT $ runActions env xs
eNextState <- runExceptT $ runActions syncEnv ledgerEnv xs

backend <- getBackend env
backend <- getBackend syncEnv
mBlock <- getDbLatestBlockInfo backend
whenJust mBlock $ \block -> do
setDbBlockHeight metricsSetters $ bBlockNo block
Expand All @@ -72,9 +73,10 @@ runDbThread env metricsSetters queue = do
-- and other operations are applied one-by-one.
runActions ::
SyncEnv ->
LedgerEnv ->
[DbAction] ->
ExceptT SyncNodeError IO NextState
runActions env actions = do
runActions env ledgerEnv actions = do
dbAction Continue actions
where
dbAction :: NextState -> [DbAction] -> ExceptT SyncNodeError IO NextState
Expand All @@ -85,24 +87,21 @@ runActions env actions = do
([], DbFinish : _) -> do
pure Done
([], DbRollBackToPoint chainSyncPoint serverTip resultVar : ys) -> do
deletedAllBlocks <- newExceptT $ prepareRollback env chainSyncPoint serverTip
points <-
if hasLedgerState env
then lift $ rollbackLedger env chainSyncPoint
else pure Nothing
deletedAllBlocks <- newExceptT $ prepareRollback env ledgerEnv chainSyncPoint serverTip
points <- liftIO $ rollbackLedger env ledgerEnv chainSyncPoint
-- Ledger state always rollbacks at least back to the 'point' given by the Node.
-- It needs to rollback even further, if 'points' is not 'Nothing'.
-- The db may not rollback to the Node point.
case (deletedAllBlocks, points) of
(True, Nothing) -> do
liftIO $ setConsistentLevel env Consistent
liftIO $ validateConsistentLevel env chainSyncPoint
liftIO $ setConsistentLevel env ledgerEnv Consistent
liftIO $ validateConsistentLevel env ledgerEnv chainSyncPoint
(False, Nothing) -> do
liftIO $ setConsistentLevel env DBAheadOfLedger
liftIO $ validateConsistentLevel env chainSyncPoint
liftIO $ setConsistentLevel env ledgerEnv DBAheadOfLedger
liftIO $ validateConsistentLevel env ledgerEnv chainSyncPoint
_ ->
-- No need to validate here
liftIO $ setConsistentLevel env DBAheadOfLedger
liftIO $ setConsistentLevel env ledgerEnv DBAheadOfLedger
blockNo <- lift $ getDbTipBlockNo env
lift $ atomically $ putTMVar resultVar (points, blockNo)
dbAction Continue ys
Expand All @@ -112,15 +111,15 @@ runActions env actions = do
then pure Continue
else dbAction Continue zs

rollbackLedger :: SyncEnv -> CardanoPoint -> IO (Maybe [CardanoPoint])
rollbackLedger env point = do
mst <- loadLedgerAtPoint (envLedger env) point
rollbackLedger :: SyncEnv -> LedgerEnv ->CardanoPoint -> IO (Maybe [CardanoPoint])
rollbackLedger syncEnv ledgerEnv point = do
mst <- loadLedgerAtPoint ledgerEnv point
case mst of
Right st -> do
let statePoint = headerStatePoint $ headerState $ clsState st
-- This is an extra validation that should always succeed.
unless (point == statePoint) $
logAndPanic (getTrace env) $
logAndPanic (leTrace ledgerEnv) $
mconcat
[ "Ledger "
, textShow statePoint
Expand All @@ -130,15 +129,15 @@ rollbackLedger env point = do
]
pure Nothing
Left lsfs ->
Just . fmap fst <$> verifySnapshotPoint env (OnDisk <$> lsfs)
Just . fmap fst <$> verifySnapshotPoint syncEnv (OnDisk <$> lsfs)

-- | This not only checks that the ledger and ChainSync points are equal, but also that the
-- 'Consistent' Level is correct based on the db tip.
validateConsistentLevel :: SyncEnv -> CardanoPoint -> IO ()
validateConsistentLevel env stPoint = do
backend <- getBackend env
validateConsistentLevel :: SyncEnv -> LedgerEnv -> CardanoPoint -> IO ()
validateConsistentLevel syncEnv ledgerEnv stPoint = do
backend <- getBackend syncEnv
dbTipInfo <- getDbLatestBlockInfo backend
cLevel <- getConsistentLevel env
cLevel <- getConsistentLevel syncEnv
compareTips stPoint dbTipInfo cLevel
where
compareTips _ dbTip Unchecked =
Expand All @@ -156,7 +155,7 @@ validateConsistentLevel env stPoint = do
logAndPanic tracer $
"Unexpected Consistent Level. " <> showContext dbTip cLevel

tracer = getTrace env
tracer = leTrace ledgerEnv
showContext dbTip cLevel =
mconcat
[ "Ledger state point is "
Expand Down