Delta synchronization

A full UTXO snapshot is many gigabytes. Clients can't afford to re-download one per block. BitcoinPIR servers publish a snapshot chain: one large base snapshot at height V0, then small deltas stacking on top.

The client tracks its own last-known version and asks the server's catalog for the shortest chain of deltas that will bring it up to the current tip. The SDK resolves this as a BFS on the (base_height → tip_height) graph, and caps the chain at MAX_DELTA_CHAIN_LENGTH = 5 steps — beyond that it's cheaper to just fetch a fresh snapshot.

// pir-sdk/src/sync.rs:15
pub const MAX_DELTA_CHAIN_LENGTH: usize = 5;
V0 full snapshot ~2 GB Δ₁ ~15 MB Δ₂ ~18 MB Δ₃ ~22 MB V3 current tip merged view each Δ is itself PIR-queried and Merkle-verified — never downloaded whole
A client at V0 walks a BFS-shortest chain of deltas to reach V3. Longer chains fall back to fetching the latest full snapshot.

An important subtlety: the deltas aren't applied as plain data overlays. Each delta is its own PIR-queryable cuckoo dataset with its own Merkle root. The client issues the same padded, Merkle-verified query path against each one, then merges the results. If no delta contains a hit, the client also needs Merkle-verified absence proofs from every delta — otherwise a missing delta could hide a recent spend.