Reference / Verified archive

Verified archive

Check your chain history against a signed canonical archive, repair what diverges, or restore a fresh instance from it.

JobCommand
Check raw identity columnssl verify raw --against <latest.json>
Check every published datasetsl verify all --against <latest.json>
Check one decodersl verify decode:ft_transfer --against <latest.json>
Also check payload columnssl verify --against <latest.json> --deep
Plan a repairsl repair --against <archive>
Write the repairsl repair --against <archive> --apply
Restore a fresh instancesl bootstrap --against <archive>
Read the node attestationGET attestations/<digest>/node.json
Read operational statusGET status.json

<latest.json> is the signed pointer. Start there.

sl verify raw --against https://pub-08fa583203de40b2b154e6a56624adc2.r2.dev/secondlayer/mainnet/canonical/v1/latest.json

Read-only. Digests stay on your machine. Default target is raw.

TargetChecks
rawblocks, transactions, events
allEvery dataset the manifest publishes
decode:<name>That decoder's datasets
subgraph:<name>That subgraph's datasets

No matching dataset in the manifest is exit 2.

Clean output exits 0. Divergence names the ranges:

 1 of 175 ranges diverge from the archive.

RANGE              DATASET  STATUS        EXPECTED  LOCAL
-----------------  -------  ------------  --------  -----
8500000-8549999    blocks   data differs  50000     50000

These ranges hold different data than the signed archive.

Equal row counts with differing data means the same heights hold different blocks — a fork point left on the losing branch.

Exit codes

CodeMeaning
0Local data matches the archive.
1Divergence found; every divergent range is listed.
2Unanchored — the archive was unreachable or its signature failed.

2 is never success. Not being able to check differs from being fine.

Flags

FlagEffect
--against <manifest>Archive latest.json, a snapshot manifest URL, or a local path. Required.
--quickIdentity columns only. Default.
--deepAlso recompute semantic digests (raw_tx, event data, function_args).
--anchorRequire a verified archive signature.
--from-block <n> / --to-block <n>Limit the checked range.
--countsAlso compare transaction and event row counts. Slower.
--semanticAlias of --deep.
--public-key <pem>Pin the signing key instead of fetching it.
--insecureCompare without verifying the signature. Result is unverified.
--jsonMachine-readable report on stdout.
sl repair --against <archive>            # plan
sl repair --against <archive> --apply    # write it

Dry-run by default. The plan names exact heights, not ranges:

HEIGHT   ACTION   LOCAL         ARCHIVE
-------  -------  ------------  -------
8501111  replace  0xd4deb46c6d  0xedb6ba8322

Each partition is hashed against the signed digest before any row is read. One transaction per partition — an interrupted repair leaves no half-corrected range.

Heights the archive doesn't have

Local heights absent from the archive are reported, never deleted — transactions and events reference them.

Decoded rows are not rebuilt. Re-run your decoders for repaired ranges.

sl bootstrap --against <archive>

Shows both timings before it starts, then restores and verifies itself:

coverage   genesis 8,745,422
signature  verified

  sync from genesis    ~19.4 days (estimate)
  restore from archive ~2.3 hours

Refuses a database that already holds blocks — use sl repair for an existing instance. --to-block <n> stops early; -y skips the prompt.

Immutable, digest-addressed Parquet partitions on R2, published from a repeatable-read snapshot of a production Stacks index. Three datasets — blocks, transactions, events — partitioned by height.

ObjectContents
latest.jsonSigned pointer at the current snapshot. Start here.
snapshots/<digest>.jsonSigned manifest: coverage, counts, per-object digests, finality rule, audit.
blocks/, transactions/, events/Range-partitioned Parquet, digest in the filename.
digests/<range>-<sha16>.parquetPer-height sidecar: one row per height with the block digest and rolled-up transaction and event digests.
attestations/<digest>/node.jsonSigned independent node audit. coverage is the attested window; stats is exact; mismatches[] is a capped sample.
status.jsonShort-cache operational state: fresh, lagging, stale, gap, failed-audit, source-unavailable.
reports/incidents/Signed incident reports, newest first via index.json.

Publishing is append-only. Each partition carries a SHA-256 over its bytes and a semantic-v1 digest over its canonical encoding. The manifest is ed25519-signed.

LevelMeans
db-reconstructiveExports from one repeatable-read snapshot restore deterministically. Does not prove no historical callback was omitted.
node-attestedBlock identities (hash, index_block_hash) also match an independently synced stacks-node for the window in node.json. Transactions and events stay db-reconstructive — the node does not expose execution raw_result or events.
observer-attestedDigests match independently retained raw observer history.

The manifest states its level per range. Most of the chain is db-reconstructive. A published node.json upgrades only the listed coverage window.

Not an SLA

The archive is a best-effort public utility, not a hosted service. Verification is free and always will be.

CLI for the full command set; Verification for per-transaction inclusion proofs.