Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions cardano-chain-gen/test/Test/Cardano/Db/Mock/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,6 @@ mkSyncNodeParams staticDir mutableDir CommandLineArgs {..} = do
, enpHasCache = claHasCache
, enpForceIndexes = claForceIndexes
, enpHasInOut = True
, enpSnEveryFollowing = 35
, enpSnEveryLagging = 35
, enpMaybeRollback = Nothing
}

Expand Down
2 changes: 0 additions & 2 deletions cardano-db-sync/app/cardano-db-sync.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ pRunDbSyncNode = do
<*> pHasCache
<*> pForceIndexes
<*> pHasInOut
<*> pure 500
<*> pure 10000
<*> optional pRollbackSlotNo

pConfigFile :: Parser ConfigFile
Expand Down
3 changes: 1 addition & 2 deletions cardano-db-sync/src/Cardano/DbSync.hs
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@ extractSyncOptions snp aop snc =
isTxOutConsumedBootstrap'
forceTxIn'
, soptInsertOptions = iopts
, snapshotEveryFollowing = enpSnEveryFollowing snp
, snapshotEveryLagging = enpSnEveryLagging snp
, soptSnapshotInterval = dncSnapshotInterval snc
}
where
maybeKeepMNames =
Expand Down
5 changes: 2 additions & 3 deletions cardano-db-sync/src/Cardano/DbSync/Api/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Ouroboros.Network.Magic (NetworkMagic (..))

import qualified Cardano.Db as DB
import Cardano.DbSync.Cache.Types (CacheStatistics, CacheStatus)
import Cardano.DbSync.Config.Types (SyncNodeConfig)
import Cardano.DbSync.Config.Types (SnapshotIntervalConfig, SyncNodeConfig)
import Cardano.DbSync.Ledger.Types (HasLedgerEnv)
import Cardano.DbSync.LocalStateQuery (NoLedgerEnv)
import Cardano.DbSync.Types (
Expand Down Expand Up @@ -70,8 +70,7 @@ data SyncOptions = SyncOptions
, soptCache :: !Bool
, soptPruneConsumeMigration :: !DB.PruneConsumeMigration
, soptInsertOptions :: !InsertOptions
, snapshotEveryFollowing :: !Word64
, snapshotEveryLagging :: !Word64
, soptSnapshotInterval :: !SnapshotIntervalConfig
}
deriving (Show)

Expand Down
1 change: 1 addition & 0 deletions cardano-db-sync/src/Cardano/DbSync/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ coalesceConfig pcfg ncfg adjustGenesisPath = do
, dncConwayHardFork = ncConwayHardFork ncfg
, dncInsertOptions = extractInsertOptions pcfg
, dncIpfsGateway = endsInSlash <$> pcIpfsGateway pcfg
, dncSnapshotInterval = pcSnapshotInterval pcfg
}

mkAdjustPath :: SyncPreConfig -> (FilePath -> FilePath)
Expand Down
32 changes: 30 additions & 2 deletions cardano-db-sync/src/Cardano/DbSync/Config/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module Cardano.DbSync.Config.Types (
GovernanceConfig (..),
OffchainPoolDataConfig (..),
JsonTypeConfig (..),
SnapshotIntervalConfig (..),
LedgerStateDir (..),
LogFileDir (..),
NetworkName (..),
Expand Down Expand Up @@ -109,8 +110,6 @@ data SyncNodeParams = SyncNodeParams
, enpHasCache :: !Bool
, enpForceIndexes :: !Bool
, enpHasInOut :: !Bool
, enpSnEveryFollowing :: !Word64
, enpSnEveryLagging :: !Word64
, enpMaybeRollback :: !(Maybe SlotNo)
}
deriving (Show)
Expand Down Expand Up @@ -147,6 +146,7 @@ data SyncNodeConfig = SyncNodeConfig
, dncConwayHardFork :: !(CardanoHardForkTrigger (ShelleyBlock (Praos StandardCrypto) ConwayEra))
, dncInsertOptions :: !SyncInsertOptions
, dncIpfsGateway :: [Text]
, dncSnapshotInterval :: !SnapshotIntervalConfig
}

data SyncPreConfig = SyncPreConfig
Expand All @@ -159,6 +159,7 @@ data SyncPreConfig = SyncPreConfig
, pcPrometheusPort :: !Int
, pcInsertConfig :: !SyncInsertConfig
, pcIpfsGateway :: ![Text]
, pcSnapshotInterval :: !SnapshotIntervalConfig
}
deriving (Show)

Expand Down Expand Up @@ -279,6 +280,12 @@ data JsonTypeConfig
| JsonTypeDisable
deriving (Eq, Show)

data SnapshotIntervalConfig = SnapshotIntervalConfig
{ sicNearTipEpoch :: !Word64
, sicLagging :: !Word64
}
deriving (Eq, Show)

newtype GenesisFile = GenesisFile
{ unGenesisFile :: FilePath
}
Expand Down Expand Up @@ -407,6 +414,7 @@ parseGenSyncNodeConfig o =
<*> fmap (fromMaybe 8080) (o .:? "PrometheusPort")
<*> o .:? "insert_options" .!= def
<*> o .:? "ipfs_gateway" .!= ["https://ipfs.io/ipfs"]
<*> o .:? "snapshot_interval" .!= def

instance FromJSON SyncProtocol where
parseJSON o =
Expand Down Expand Up @@ -728,6 +736,26 @@ instance FromJSON JsonTypeConfig where
"disable" -> pure JsonTypeDisable
other -> fail $ "unexpected json_type: " <> show other

instance ToJSON SnapshotIntervalConfig where
toJSON cfg =
Aeson.object
[ "near_tip_epoch" .= sicNearTipEpoch cfg
, "lagging" .= sicLagging cfg
]

instance FromJSON SnapshotIntervalConfig where
parseJSON = Aeson.withObject "snapshot_interval" $ \obj ->
SnapshotIntervalConfig
<$> obj .:? "near_tip_epoch" .!= sicNearTipEpoch def
<*> obj .:? "lagging" .!= sicLagging def

instance Default SnapshotIntervalConfig where
def =
SnapshotIntervalConfig
{ sicNearTipEpoch = 580 -- Epoch threshold to consider being near tip
, sicLagging = 100000 -- Every 100,000 blocks when syncing (less frequent)
}

instance Default SyncInsertConfig where
def = SyncInsertConfig Nothing def

Expand Down
17 changes: 10 additions & 7 deletions cardano-db-sync/src/Cardano/DbSync/Ledger/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ mkHasLedgerEnv trce protoInfo dir nw systemStart syncOptions = do
, leNetwork = nw
, leSystemStart = systemStart
, leAbortOnPanic = soptAbortOnInvalid syncOptions
, leSnapshotEveryFollowing = snapshotEveryFollowing syncOptions
, leSnapshotEveryLagging = snapshotEveryLagging syncOptions
, leSnapshotNearTipEpoch = sicNearTipEpoch $ soptSnapshotInterval syncOptions
, leSnapshotEveryLagging = sicLagging $ soptSnapshotInterval syncOptions
, leInterpreter = intervar
, leStateVar = svar
, leStateWriteQueue = swQueue
Expand Down Expand Up @@ -218,7 +218,8 @@ readStateUnsafe env = do
applyBlockAndSnapshot :: HasLedgerEnv -> CardanoBlock -> Bool -> IO (ApplyResult, Bool)
applyBlockAndSnapshot ledgerEnv blk isCons = do
(oldState, appResult) <- applyBlock ledgerEnv blk
tookSnapshot <- storeSnapshotAndCleanupMaybe ledgerEnv oldState appResult (blockNo blk) isCons (isSyncedWithinSeconds (apSlotDetails appResult) 600)
-- 864000 seconds = 10 days; consider synced "near tip" if within 10 days of current time
tookSnapshot <- storeSnapshotAndCleanupMaybe ledgerEnv oldState appResult (blockNo blk) isCons (isSyncedWithinSeconds (apSlotDetails appResult) 864000)
pure (appResult, tookSnapshot)

-- The function 'tickThenReapply' does zero validation, so add minimal validation ('blockPrevHash'
Expand Down Expand Up @@ -330,7 +331,8 @@ storeSnapshotAndCleanupMaybe env oldState appResult blkNo isCons syncState =
Just newEpoch
| newEpochNo <- unEpochNo (Generic.neEpoch newEpoch)
, newEpochNo > 0
, isCons || (newEpochNo `mod` 10 == 0) || newEpochNo >= 530 ->
, -- Snapshot every epoch when near tip, every 10 epochs when lagging, or always for epoch >= threshold
(isCons && syncState == SyncFollowing) || (newEpochNo `mod` 10 == 0) || newEpochNo >= leSnapshotNearTipEpoch env ->
do
-- TODO: Instead of newEpochNo - 1, is there any way to get the epochNo from 'lssOldState'?
liftIO $ saveCleanupState env oldState (Just $ EpochNo $ newEpochNo - 1)
Expand All @@ -345,8 +347,8 @@ storeSnapshotAndCleanupMaybe env oldState appResult blkNo isCons syncState =
timeToSnapshot :: SyncState -> BlockNo -> Bool
timeToSnapshot syncSt bNo =
case (syncSt, unBlockNo bNo) of
(SyncFollowing, bno) -> bno `mod` leSnapshotEveryFollowing env == 0
(SyncLagging, _) -> False
(SyncFollowing, _) -> False -- No block-based snapshots when following
(SyncLagging, bno) -> bno `mod` leSnapshotEveryLagging env == 0

saveCurrentLedgerState :: HasLedgerEnv -> CardanoLedgerState -> Maybe EpochNo -> IO ()
saveCurrentLedgerState env lState mEpochNo = do
Expand Down Expand Up @@ -403,7 +405,8 @@ ledgerStateWriteLoop tracer swQueue codecConfig =

mkLedgerStateFilename :: LedgerStateDir -> ExtLedgerState CardanoBlock -> Maybe EpochNo -> WithOrigin FilePath
mkLedgerStateFilename dir ledger mEpochNo =
lsfFilePath . dbPointToFileName dir mEpochNo
lsfFilePath
. dbPointToFileName dir mEpochNo
<$> getPoint (ledgerTipPoint @CardanoBlock (ledgerState ledger))

saveCleanupState :: HasLedgerEnv -> CardanoLedgerState -> Maybe EpochNo -> IO ()
Expand Down
2 changes: 1 addition & 1 deletion cardano-db-sync/src/Cardano/DbSync/Ledger/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ data HasLedgerEnv = HasLedgerEnv
, leNetwork :: !Ledger.Network
, leSystemStart :: !SystemStart
, leAbortOnPanic :: !Bool
, leSnapshotEveryFollowing :: !Word64
, leSnapshotNearTipEpoch :: !Word64
, leSnapshotEveryLagging :: !Word64
, leInterpreter :: !(StrictTVar IO (Strict.Maybe CardanoInterpreter))
, leStateVar :: !(StrictTVar IO (Strict.Maybe LedgerDB))
Expand Down
10 changes: 8 additions & 2 deletions cardano-db-sync/test/Cardano/DbSync/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ syncPreConfig =
<*> Gen.int (Range.linear 0 10000)
<*> syncInsertConfig
<*> Gen.list (Range.linear 0 10) (Gen.text (Range.linear 0 100) Gen.unicode)
<*> snapshotIntervalConfig

snapshotIntervalConfig :: Gen SnapshotIntervalConfig
snapshotIntervalConfig =
SnapshotIntervalConfig
<$> Gen.word64 (Range.linear 100 1000)
<*> Gen.word64 (Range.linear 10000 100000)

syncNodeParams :: MonadGen m => m SyncNodeParams
syncNodeParams =
Expand All @@ -71,8 +78,6 @@ syncNodeParams =
<*> Gen.bool
<*> Gen.bool
<*> Gen.bool
<*> Gen.word64 (Range.linear 0 1000)
<*> Gen.word64 (Range.linear 0 1000)
<*> pure Nothing

syncNodeConfig :: Logging.Configuration -> Gen SyncNodeConfig
Expand Down Expand Up @@ -104,6 +109,7 @@ syncNodeConfig loggingCfg =
<*> triggerHardFork
<*> syncInsertOptions
<*> pure []
<*> snapshotIntervalConfig

syncInsertConfig :: Gen SyncInsertConfig
syncInsertConfig =
Expand Down
54 changes: 54 additions & 0 deletions doc/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Below is a sample `insert_options` section that shows all the defaults:
| [pool\_stat](#pool-stat) | `enum` | Optional |
| [remove\_jsonb_from_schema](#remove-jsonb-from-schema) | `enum` | Optional |
| [stop\_at\_block](#stop-at-block) | `integer` | Optional |
| [snapshot\_interval](#snapshot-interval) | `object` | Optional |

## Preset

Expand Down Expand Up @@ -602,3 +603,56 @@ Stops db-sync after processing the specified block number. Useful for testing an
}
```

## Snapshot Interval

`snapshot_interval`

* Type: `object`
* Optional: When not specified, uses default values

Controls how frequently ledger state snapshots are taken during sync. Taking snapshots less frequently during initial sync can significantly improve sync performance by reducing IOPS and disk throughput consumption.

Snapshot Interval Properties:

| Property | Type | Required | Default |
| :------------------------------- | :-------- | :------- | :------ |
| [near\_tip\_epoch](#near-tip-epoch) | `integer` | Optional | 580 |
| [lagging](#lagging) | `integer` | Optional | 100000 |

### Near Tip Epoch

`snapshot_interval.near_tip_epoch`

* Type: `integer`
* Default: `580`

Epoch threshold used to determine snapshot behavior. When syncing reaches this epoch or later, db-sync is considered to be approaching or at the current tip of the chain. Combined with time-based detection (within 10 days of current time), this ensures snapshots are taken every epoch when near the tip for fast rollback recovery. During earlier epochs or when syncing behind, snapshots are taken every 10 epochs or according to the `lagging` block interval.

### Lagging

`snapshot_interval.lagging`

* Type: `integer`
* Default: `100000`

Number of blocks between snapshots when db-sync is syncing and significantly behind the tip of the chain (more than 10 days behind current time). Less frequent snapshots during initial sync improves performance by reducing expensive disk operations.

### Example

```json
{
"snapshot_interval": {
"near_tip_epoch": 580,
"lagging": 100000
}
}
```

### Performance Considerations

- **Lower `near_tip_epoch` value**: Start taking frequent epoch-based snapshots earlier in the chain history
- **Higher `near_tip_epoch` value**: Delay frequent snapshots until later in the chain, improving sync speed for longer
- **Larger `lagging` value**: Faster initial sync with reduced IOPS, but slower recovery if rollback is needed during sync
- **Recommended for initial sync**: Use a large `lagging` value (100000+) and appropriate `near_tip_epoch` to maximize sync speed
- **Near tip detection**: Automatically switches to epoch-based snapshots when within 10 days of current time, regardless of epoch number

Loading