Snapshots
Snapshots are verified checkpoints of finalized NOOSChain state. They let a node start from a known-good chain height without replaying every historical block from genesis, while still preserving the deterministic rules that make sync, replay, and state-root verification trustworthy.
Use this page for the general model. Operators should use Snapshots For Operators and Backup/Restore/Recovery for commands and recovery procedures. Nooschain developers should use Snapshot Internals for format and implementation details.
What Snapshots Are For
A snapshot captures consensus and deterministic materialized state at one finalized height. After import, the snapshot becomes a local chain checkpoint:
- replay can continue from the checkpoint instead of genesis;
- sync can request blocks after the checkpoint height;
- the first post-checkpoint block must extend the checkpoint block hash;
- state-root verification uses the engine metadata recorded on the snapshot;
- Raft followers can use the same checkpoint model during
InstallSnapshot.
Snapshots are useful for:
- bootstrapping a fresh observer;
- restoring a node from a verified archive;
- proving backup and restore drills;
- catching up a lagging Raft follower;
- continuing replay after a large historical prefix has been checkpointed;
- preserving governed protocol and state-root engine metadata across restore.
A snapshot is not a fork-choice rule, not a replacement for consensus, and not a blind database copy. Import verifies the snapshot before it becomes local chain state.
What A Snapshot Contains
Snapshot format version 1 captures finalized state in deterministic categories.
| Category | Examples |
|---|---|
| Chain identity | chainId, height, block hash, state root, protocol version, state-root engine version. |
| Chain actors | organizations, users, nodes, validators, chain access rules, validator status, voting power, endpoints, Raft URLs. |
| Transactions and buckets | transactions, account nonces, buckets, bucket access rules, bucket index schemas, bucket keys, encrypted-record metadata, public record indexes. |
| Protocol state | protocol upgrades, state-root engine activations, block/checkpoint metadata. |
| Smart contracts | contract code, manifests, registry entries, runtime activation and rollout rows, contract instances, releases, contract state, contract events, call results, migration rows. |
| State-root data | state leaves, SMT root metadata, state-root engine metadata. |
| Snapshot metadata | table metadata, row counts, content hashes, deterministic snapshotHash. |
The important idea is that a snapshot contains consensus-relevant state and the deterministic materialized tables needed to resume execution. It does not carry local node opinions or operational history.
What A Snapshot Excludes
Snapshots intentionally exclude local operational data:
- trusted peers;
- peer scores;
- gossip propagation state;
- chain incidents;
- auth sessions;
- operator tokens;
- private keys;
- raw DEKs;
- plaintext payloads;
- local contract readiness rows;
- contract metrics;
- local Nervos sidecar checkpoint files.
Smart contract readiness is recomputed after restore from the restored manifest, bucket availability, payload availability, permissions, and Wasmtime sidecar health. Local metrics resume from post-restore calls.
Normal snapshots also do not bundle local Nervos sidecar checkpoint files. Those files are a local acceleration cache. After importing a Nervos snapshot, the node can hydrate the sidecar from imported state_leaves and export a fresh verified local checkpoint.
Export Modes
consensus_state_only is the default export mode. It omits local ciphertext by setting encrypted payload fields to unavailable in the exported artifact. This is the safest mode for bootstrap, replay, and most backup drills because ciphertext availability is not consensus state.
include_local_ciphertext includes encrypted payload bytes only for records where the exporting node has ciphertext locally. It still never includes plaintext or raw keys. This mode can help local recovery, but it exposes ciphertext availability and should be handled as sensitive operational data.
For the encryption boundary, see Encryption Model and Payload Backfill.
Recipe: Create A Snapshot
Use this recipe when you want a verified bootstrap or backup artifact from the current finalized chain head.
- Run the command on the node host or another trusted machine that can connect directly to the node database.
- Set
DATABASE_URLto the database/schema you want to export. - Export a packaged archive in the default
consensus_state_onlymode. - Verify the archive before moving it, storing it, or using it for restore.
- Store the archive with your normal backup controls.
PowerShell:
$env:DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain"
npm run noos -- snapshots export --output .\snapshot.noosnap.tar.gz --mode consensus_state_only
npm run noos -- snapshots verify --file .\snapshot.noosnap.tar.gzBash:
DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain" \
npm run noos -- snapshots export --output ./snapshot.noosnap.tar.gz --mode consensus_state_only
DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain" \
npm run noos -- snapshots verify --file ./snapshot.noosnap.tar.gzThe result is a snapshot archive that can bootstrap a new node without carrying local ciphertext. This is the recommended default for network bootstrap and most restore drills.
If you are doing local recovery and explicitly need ciphertext already present on the exporting node, use include_local_ciphertext:
npm run noos -- snapshots export --output .\snapshot-with-ciphertext.noosnap.tar.gz --mode include_local_ciphertext
npm run noos -- snapshots verify --file .\snapshot-with-ciphertext.noosnap.tar.gzTreat include_local_ciphertext archives as sensitive operational artifacts. They still do not include plaintext or raw keys, but they can reveal encrypted payload bytes and ciphertext availability.
Recipe: Restore From A Snapshot
Use this recipe to bootstrap an empty node database from a verified snapshot archive. This is the normal restore path for a fresh observer or replacement database.
- Stop the target node process.
- Create or select an empty target database/schema.
- Set
DATABASE_URLto that target. - Verify the archive before import.
- Import with
empty_database_only. - Run chain verification before returning the node to service.
- Start the node and let it sync blocks after the imported checkpoint.
PowerShell:
$env:DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain_restore"
npm run noos -- snapshots verify --file .\snapshot.noosnap.tar.gz
npm run noos -- snapshots import --file .\snapshot.noosnap.tar.gz --mode empty_database_only --yes
npm run verify:chainBash:
DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain_restore" \
npm run noos -- snapshots verify --file ./snapshot.noosnap.tar.gz
DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain_restore" \
npm run noos -- snapshots import --file ./snapshot.noosnap.tar.gz --mode empty_database_only --yes
DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain_restore" \
npm run verify:chainAfter import, the restored node has a checkpoint at the snapshot height. It does not have fabricated blocks before that height. Future sync starts at checkpoint.height + 1, and the first synced block must extend the checkpoint block hash.
For production restores, also run replay verification when historical blocks are available, confirm trusted peers and node identity configuration, and follow Backup/Restore/Recovery. Do not use operator restore on a non-empty production database unless you are deliberately following the guarded disaster-recovery procedure.
Verification
Snapshot verification checks both the artifact and the chain commitments it claims to represent. Verification includes:
- document or archive shape;
- table declarations and row counts;
- primary-key uniqueness;
- references between included tables;
- ciphertext export-mode rules;
- state-root engine metadata;
- deterministic snapshot hash;
- rebuilt state root from the snapshot's consensus state rows.
The snapshot hash is canonical. Non-deterministic metadata such as a local file path is not part of consensus meaning. exportedAt is useful operator metadata, not a state transition.
An imported snapshot is accepted only after verification succeeds. Failed imports must not partially mutate canonical chain tables.
Snapshots, Replay, And Sync
Snapshot import writes a chain checkpoint. The checkpoint records the imported height, block hash, state root, protocol version, and state-root engine version.
Replay from a snapshot uses snapshot_checkpoint mode. It verifies the imported checkpoint first, then replays blocks from checkpoint.height + 1. A snapshot-only node does not invent historical blocks before the checkpoint; full genesis replay still requires genesis plus historical block data.
Sync after a snapshot also starts after the checkpoint height. The first synced or produced block after import must use previous_hash equal to the checkpoint block hash. This prevents a node from silently extending a different history.
See Replay Verification and Sync, Gossip, And Verification.
State-Root Engines And Checkpoints
Snapshots preserve the state-root engine that produced the checkpoint. A snapshot taken after a governed nervos-smt-v2 activation carries that engine metadata and the activation state needed to continue correctly after import.
This matters because a node's current environment defaults are not allowed to reinterpret historical state. After import, continuation uses the engine recorded by imported history. If the selected engine is unavailable or reports the wrong protocol/checkpoint metadata, execution and replay fail closed.
For the general sidecar model, see State Root and Nervos SMT Sidecar.
Raft InstallSnapshot
Raft snapshot catch-up uses the same checkpoint idea. When a follower is too far behind, a Raft leader can send a snapshot through InstallSnapshot. The follower verifies the snapshot before importing it, records a checkpoint at the snapshot height, and then applies later committed blocks after that checkpoint.
Raft snapshot transfer does not make the follower trust the leader's raw PostgreSQL tables. The follower still verifies the artifact, state root, checkpoint metadata, and post-checkpoint block continuity.
Operational Boundary
Snapshot export and import are local operator jobs. Large exports are intentionally not exposed as Admin GUI or HTTP export workflows because they can be expensive enough to block the node web server.
The operator CLI works with local database access through DATABASE_URL and can export, verify, import, pack, and unpack snapshot archives. Operator restore is a guarded disaster-recovery path and should be used only with explicit review.
Use Snapshots For Operators for the full command reference and Backup/Restore/Recovery for production recovery sequences.
Limitations
- Historical snapshot export is not implemented yet; export targets the latest finalized height.
- Snapshot import does not perform automatic reorg, fork repair, or pruning.
- Snapshot-only nodes cannot fully replay from genesis unless historical blocks are also available.
- Streaming imports persist snapshot metadata and the snapshot file path rather than storing a huge JSON document in PostgreSQL.
- Persistent SMT nodes are reconstructed from verified snapshot state during import; future formats may include compact SMT node data.
- Raft snapshot transfer currently sends one full snapshot document. Chunking, compression, resumable transfer, and streaming transfer are future work.