The archive and reading the past
Ordinary ZooBC nodes keep only recent history: 30 to 60 days of blocks and their three newest snapshots. The archive answers questions about the distant past, such as an account's balance three years ago: every snapshot since block 0, spread over the decentralised storage rather than kept on one machine, and checkable byte by byte against the spine chain.
What every node keeps
Every 172,800 blocks (about 30 days) on mainnet, each node writes a snapshot: the whole state of the chain, every balance, registry seat and record, as of 760 blocks below that height. Nodes stagger the work, but every node's bytes are identical. A snapshot is one CBOR document, cut into chunks of 102,400 bytes that are named by their SHA3-256 hashes. Its manifest, with the hash of the whole file, the hash of every chunk and the reference height, is published in a block of the spine chain, the slow chain of daily blocks co-signed by two thirds of the registered seats.
Nothing in a snapshot is signed. Its authority is the co-signed spine block that names it, so a snapshot is authentic whoever serves it, as long as its bytes match the manifest's hashes. Snapshots are also how a new node joins quickly (snapshots and fast sync).
Each node keeps only its three newest snapshot generations on its own disk. That is all a node needs to help others join, and keeping every snapshot ever made on every node would cost each operator more disk every month. Old blocks are pruned as well (pruning of history).
The archive
From version 0.5.8 it is the decentralised storage, not every node, that keeps every snapshot from block 0. Each snapshot's chunks are held by five registered nodes chosen by lot (storage_replication), as for the pieces of any stored file (decentralised storage pool). Every node keeps only its last three snapshots; no node keeps them all.
No single machine holds the history, so no single operator can lose it or withhold it. An archive server run by one organisation, even the ZooBC Foundation, would be exactly that single point. Nothing is thrown away either: the archive goes back to the very first snapshot.
Holding archive chunks is part of a registered node's storage duty. Each storage epoch, 10 % of the longevity pool is paid in equal parts to the nodes that prove the sampled chunks (pools).
Reading the past
A reader who wants the state at a past time walks the spine back to the snapshot taken at that time and reads its manifest. It fetches the snapshot's chunks from their holders and checks each one against its hash in the manifest, so a holder cannot slip in a false chunk. Then it reassembles the snapshot, checks the hash of the whole, and rebuilds the state at that height: every balance, seat and record of that moment. No single node holds the history, and no archival node is needed.
The checks need no trust in the holders: the spine is co-signed by the seats, and its manifests fix the hash of every chunk, so a false chunk shows at once.
Other ways to see the past
- A longevity deposit keeps one chosen transaction, and its block, on every node for as long as the deposit lasts (paying to keep data (longevity)).
- An operator can keep all history on its own node with
keep_all_history; that is a local choice, not the default. - Archival nodes run an indexing service beside a node and serve the explorer's search and statistics (explorer and archival nodes).