Snapshot Plugin
The snapshot plugin enables near-instant node startup by serializing and restoring the full blockchain state as a JSON snapshot file. Instead of replaying millions of blocks from the block log, a node can load a pre-built snapshot and begin syncing from that point via P2P.
Enabling
plugin = snapshotOr on the command line:
vizd --plugin snapshotConfiguration Reference
CLI-only Options
| Option | Type | Description |
|---|---|---|
--snapshot <path> | string | Load state from a snapshot file (DLT mode). Skips import if shared_memory.bin already exists; renames file to .used after successful import. |
--snapshot-auto-latest | bool | Auto-discover the latest snapshot in snapshot-dir by block number in filename. Ignored if --snapshot is set. |
--replay-from-snapshot | bool | Crash recovery: import snapshot then replay dlt_block_log to reach latest available state. Always wipes shared memory; does not rename the snapshot. |
--auto-recover-from-snapshot | bool (default: true) | Automatic runtime recovery when shared memory corruption is detected. Closes database, finds latest snapshot, wipes shared memory, imports and replays — without a restart. |
--create-snapshot <path> | string | Create a snapshot from current database state, then exit. |
--sync-snapshot-from-trusted-peer | bool (default: false) | Download and load snapshot from trusted peers when state is empty. Must be explicitly enabled. |
Config File Options
| Option | Type | Default | Description |
|---|---|---|---|
snapshot-at-block | uint32 | 0 | Create snapshot when this block number is reached |
snapshot-every-n-blocks | uint32 | 0 | Create snapshot every N blocks (0 = disabled) |
snapshot-dir | string | "" | Directory for auto-generated snapshot files |
snapshot-max-age-days | uint32 | 90 | Delete snapshots older than N days (0 = disabled) |
allow-snapshot-serving | bool | false | Enable serving snapshots over TCP to other nodes |
allow-snapshot-serving-only-trusted | bool | false | Restrict serving to trusted peers only |
snapshot-serve-endpoint | string | 0.0.0.0:8092 | TCP endpoint for snapshot serving |
trusted-snapshot-peer | string (multi) | — | Trusted peer for snapshot sync (IP:port). Repeatable. |
dlt-block-log-max-blocks | uint32 | 100000 | Recent blocks to keep in DLT rolling block log (chain plugin) |
Creating Snapshots
Method 1: One-shot (node stops and exits)
vizd --create-snapshot /data/snapshots/viz-snapshot.json --plugin snapshotThe node opens the existing database, replays if needed, creates the snapshot, and exits before P2P activates.
Method 2: At a specific block (no downtime)
plugin = snapshot
snapshot-at-block = 5000000
snapshot-dir = /data/snapshotsWhen block 5,000,000 is applied, the snapshot is written to /data/snapshots/snapshot-block-5000000.json on a background thread — block processing is only briefly paused.
Method 3: Periodic automatic snapshots (recommended)
plugin = snapshot
snapshot-every-n-blocks = 100000
snapshot-dir = /data/snapshotsSnapshots are created every 100,000 blocks (~3.5 days). Snapshots are skipped while syncing — they only trigger on live blocks.
Recommended intervals:
| Interval | Blocks | Approximate time |
|---|---|---|
| Frequent | 10,000 | ~8 hours |
| Daily | 28,800 | ~24 hours |
| Weekly | 100,000 | ~3.5 days |
| Rare | 1,000,000 | ~35 days |
Snapshot Rotation
Old snapshots are automatically deleted after each new snapshot if older than snapshot-max-age-days (default 90). To disable:
snapshot-max-age-days = 0Loading from a Snapshot (DLT Mode)
vizd --snapshot /path/to/snapshot.json --plugin snapshotWhat happens during load:
- Snapshot plugin registers a load callback on the chain plugin.
- Chain plugin checks: if
shared_memory.binalready exists → skips import (restart safety). If snapshot file not found → skips import. - Database is opened via
open_from_snapshot()— shared memory is wiped, chainbase initialized. - Snapshot is validated (format version, chain ID, SHA-256 checksum) and all 32 object types imported.
- Snapshot file is renamed to
.used. - LIB is promoted to
head_block_numso P2P synopsis starts from the snapshot head. - Fork database is seeded with the snapshot head block.
- P2P starts syncing from LIB + 1.
Restart Safety
| Restart scenario | What happens |
|---|---|
| 1st start (no shared_memory, file exists) | Imports snapshot, renames to .used |
| Restart (shared_memory exists) | Skips import |
Restart (shared_memory wiped, file is .used) | Skips import |
| Force re-import | --resync-blockchain + fresh snapshot file |
The --snapshot flag is safe to leave on the command line permanently.
DLT Rolling Block Log
When running in DLT mode (loaded from snapshot), the main block_log is empty. A separate DLT rolling block log (dlt_block_log) stores the most recent irreversible blocks.
- Enables P2P block serving (peers can request recent blocks for fork resolution).
- Enables API calls like
get_blockfor recent blocks. - Stored in
dlt_block_log.loganddlt_block_log.indexin the blockchain data directory. - Rolling window: when the log exceeds
dlt-block-log-max-blocks, old blocks are truncated from the front.
dlt-block-log-max-blocks = 100000Crash Recovery: --replay-from-snapshot
When shared_memory.bin is corrupted after an unclean shutdown, use this mode:
# Specify snapshot path explicitly
vizd --replay-from-snapshot --snapshot /data/snapshots/snapshot-block-79273800.vizjson --plugin snapshot
# Auto-discover the latest snapshot
vizd --replay-from-snapshot --snapshot-auto-latest --plugin snapshotRecovery steps:
- Wipes
shared_memory.bin(always — assumes corruption). - Imports snapshot state.
- Replays
dlt_block_logblocks beyond the snapshot head. - Resumes P2P sync from the replayed head.
| Aspect | --snapshot | --replay-from-snapshot |
|---|---|---|
| Shared memory check | Skips if exists | Always wipes |
| Snapshot rename | Renames to .used | Does not rename |
| DLT block log replay | No | Yes |
| Use case | Bootstrap | Crash recovery |
Automatic Runtime Recovery: --auto-recover-from-snapshot
Enabled by default (true). When shared memory corruption is detected during block processing or block generation, the node:
- Closes the database.
- Finds the latest snapshot in
snapshot-dir. - Wipes shared memory, imports snapshot, replays
dlt_block_log. - Resumes P2P sync — no restart required.
Prerequisites:
plugin = snapshotmust be enabled.- Snapshots must exist in
snapshot-dir.
To disable (e.g., for debugging):
vizd --no-auto-recover-from-snapshotP2P Snapshot Sync
Nodes can download snapshots directly from trusted peers over TCP.
Server configuration
plugin = snapshot
allow-snapshot-serving = true
snapshot-serve-endpoint = 0.0.0.0:8092
snapshot-every-n-blocks = 28800
snapshot-dir = /data/viz-snapshotsClient configuration
trusted-snapshot-peer = seed1.viz.world:8092
trusted-snapshot-peer = seed2.viz.world:8092
trusted-snapshot-peer = seed3.viz.world:8092
sync-snapshot-from-trusted-peer = trueThe client connects to each trusted peer, selects the one with the highest block number, downloads the snapshot in 1 MB chunks, verifies the SHA-256 checksum, and imports it.
Security features: max 2 GB snapshot size, trusted peer list, rate limiting, 60-second connection deadline, streaming checksum verification.
Snapshot File Format
{
"header": {
"version": 1,
"chain_id": "...",
"snapshot_block_num": 12345678,
"snapshot_block_id": "...",
"snapshot_block_time": "2025-01-01T00:00:00",
"last_irreversible_block_num": 12345660,
"payload_checksum": "sha256...",
"object_counts": { "account": 50000, ... }
},
"state": {
"dynamic_global_property": [ ... ],
"account": [ ... ],
...
}
}Included Object Types (32 total)
Critical (11): dynamic_global_property, witness_schedule, hardfork_property, account, account_authority, validator, witness_vote, block_summary, content, content_vote, block_post_validation
Important (15): transaction, vesting_delegation, vesting_delegation_expiration, fix_vesting_delegation, withdraw_vesting_route, escrow, proposal, required_approval, committee_request, committee_vote, invite, award_shares_expire, paid_subscription, paid_subscribe, witness_penalty_expire
Optional (5): content_type, account_metadata, master_authority_history, account_recovery_request, change_recovery_account_request
Recommended Production Config
plugin = snapshot
# Create a snapshot every ~24 hours
snapshot-every-n-blocks = 28800
snapshot-dir = /data/viz-snapshots
# Auto-delete snapshots older than 90 days
snapshot-max-age-days = 90
# DLT rolling block log: keep last 100k blocks
dlt-block-log-max-blocks = 100000
shared-file-size = 4G
plugin = p2p
p2p-seed-node = seed1.viz.world:2001Docker Quick Reference
| Task | Command |
|---|---|
| Start with periodic snapshots | Add snapshot-every-n-blocks to config, restart container |
| One-shot snapshot | VIZD_EXTRA_OPTS="--create-snapshot /var/lib/vizd/snapshots/snap.json --plugin snapshot" |
| Load from snapshot | VIZD_EXTRA_OPTS="--snapshot /var/lib/vizd/snapshots/snap.json --plugin snapshot" |
| Crash recovery | VIZD_EXTRA_OPTS="--replay-from-snapshot --snapshot-auto-latest --plugin snapshot" |
| Auto-recovery (default) | Enabled by default; ensure plugin = snapshot and snapshot-every-n-blocks are set |
See also: Chain Plugin, Shared Memory, Block Log, P2P Sync Scenarios.