On-disk store

Architecture

Lookups go to packed history, not a UTXO set. If you have more than one kind of disk, split hot and cold. Schema 20 is current on the 0.x line; the format still moves before 1.0. Some upgrades rebuild indexes without a full re-sync.

One-screen picture

The archive is the truth. Outputs and spends stay on the fast disk. Inputs and witness can live on something cheaper. Wallet indexes cost extra disk if you serve Electrum.

Ordinary files under --datadir. --datadir-cold holds inwit only. There is no LevelDB coins database. Table names and versions: SCHEMA.md.

Class A / B / C

Three jobs in one store. The split is what you buy disk for.

Class A — archive

Headers, outputs (hot), inputs and witness (cold), and spend marks. --datadir-cold puts inwit on the second volume. Everything you touch on the confirm path stays on the hot datadir.

Class B — indexes (optional)

Electrum scripthash history and silent payment tweaks. Extra disk you choose, not a faster sync. Off until you turn wallet serving on.

Class C — tip

Which chain is best, and at what height each transaction was created. Spentness is a mark on the output that created the coin—not a delete from a UTXO set.

How lookups work

Spentness, history, and reconstruction — without a UTXO set.

Question Path
txid → transaction Tip-hot txid index, then the packed body. Newer transactions resolve first.
height → block txs Best-chain height → the contiguous archive range for that block.
scripthash / SP tweaks Electrum wallet index joined with packed outs, spentness, and the mempool. Silent payment tweaks are served on the same Electrum surface.
Is this output spent? A mark on the output that created it. No separate UTXO hash table.
Serve historical block wire Rebuild from packed outs and inwit. Recent tip can come from the live wire cache.

Compared with bitcoin core (store)

The archive is the truth. core’s truth is a UTXO chainstate plus block files.

Concern rbitcoin bitcoin core (typical)
Primary store Packed archive tables; no UTXO set blocks/blk*.dat + undo + LevelDB chainstate (UTXO)
Historical blocks Reconstruct from packed outs + inwit; IBD getdata serves from archive spans Serve raw blk / undo
Spentness Annotations on creates; no mutable UTXO set as truth Coins view / UTXO mutations
Txid lookup Full archive txid index, written during IBD. Not optional. Optional txindex; otherwise not the hot path
Electrum / Esplora In-process Electrum, including silent payment tweaks External indexer over core (Fulcrum, ElectrumX, …)
JSON-RPC Optional documented subset; decode helpers; cookie or user/pass; template selector, no stratum Large core surface including wallet and mining
Script verification In-tree Rust scripts; rust-bitcoin types; libsecp256k1 for ECDSA/Schnorr libbitcoinconsensus / C++ interpreter
IBD RAM No coins cache. Modest process RSS; the OS page cache is the cache Multi‑GiB dbcache to keep the UTXO set hot
IBD wall-clock IBD in the same neighborhood as core. One measured run, not a warranty. assumevalid / default IBD on the same class of host

Independent code still has to match the chain. See Security → What the tests cover.

Compared with external Electrum indexers

The node that validates is the node that serves. There is no second process reading blk files.

Concern rbitcoin Typical external indexer
Data source Validating node + archive in one process Reads core RPC or blk files after the fact
Wallet indexes In-process scripthash + silent payment tweaks Separate DB built by scanning history
Unconfirmed Mempool attached in-process Depends on core mempool RPC
Consensus This binary validates blocks/scripts Trusts the node it indexes

Full archival only. There is no prune switch. Wallet indexes are extra disk when you serve Electrum. The format will change before 1.0. Current tables: SCHEMA.md.

Deep docs (node repo)

Get started

Grab a Release, or build musl with Nix.