# Index Schema
The index is stored as three RocksDB databases:
- `txstore`
- `history`
- `cache`
### Indexing process
The indexing is done in the two phase, where each can be done concurrently within itself.
The first phase populates the `txstore` database, the second phase populates the `history` database.
NOTE: in order to construct the history rows for spending inputs in phase #2, we rely on having the transactions being processed at phase #1, so they can be looked up efficiently (using parallel point lookups).
After the indexing is completed, both funding and spending are indexed as independent rows under `H{scripthash}`, so that they can be queried in-order in one go.
### `txstore`
Each block results in the following new rows:
* `"B{blockhash}" → "{header}"`
* `"X{blockhash}" → "{txids}"` (list of txids included in the block)
* `"M{blockhash}" → "{metadata}"` (block weight, size and number of txs)
* `"D{blockhash}" → ""` (signifies the block is done processing)
Each transaction results in the following new rows:
* `"T{txid}" → "{serialized-transaction}"`
* `"C{txid}{confirmed-blockhash}" → ""` (a list of blockhashes where `txid` was seen to be confirmed)
Each output results in the following new row:
* `"O{txid}{vout}" → "{scriptpubkey}{value}"`
When the indexer is synced up to the tip of the chain, the hash of the tip is saved as following:
* `"t" → "{blockhash}"`
### `history`
Each funding output (except for provably unspendable ones when `--index-unspendables` is not enabled) results in the following new rows (`H` is for history, `F` is for funding):
* `"H{funding-scripthash}{funding-height}F{funding-txid:vout}{value}" → ""`
* `"a{funding-address-str}" → ""` (for prefix address search, only saved when `--address-search` is enabled)
Each spending input (except the coinbase) results in the following new rows (`S` is for spending):
* `"H{funding-scripthash}{spending-height}S{spending-txid:vin}{funding-txid:vout}{value}" → ""`
* `"S{funding-txid:vout}{spending-txid:vin}" → ""`
If transaction output include colored coins, it results in the following new row:
* `"B{block-height}c{color-id}" → ""` (block_height is latest block height which colored coin used)
colored coin's issuances results in the following new rows (`I` is for issuing):
* `"C{color-id}{issuance-height}I{issuing-txid}{value}" → ""`
Every transfer results in the following new row (`T` is for transferring):
* `"C{color-id}{transfer-height}T{transferring-txid}{value}" → ""`
Every burn (unspendable output) results in the following new row (`B` is for burning):
* `"C{color-id}{burn-height}B{burning-txid}{value}" → ""`
### `cache`
Holds a cache for aggregated stats and unspent TXOs of scripthashes.
The cache is created on-demand, the first time the scripthash is requested by a user.
The cached data is kept next to the `blockhash` the cache is up-to-date for.
When requesting data, the cache is updated with the new history rows added since the `blockhash`.
If the `blockhash` was since orphaned, the cache is removed and re-computed.
* `"A{scripthash}{color_id}" → "{stats}{blockhash}"` (where `stats` is composed of `tx_count`, `funded_txo_{count,sum}` and `spent_txo_{count,sum}`)
* `"U{scripthash}" → "{utxo}{blockhash}"` (where `utxo` is a set of `(txid,vout)` outpoints)
Stats for issued colored coins:
* `"z{color-id}" → "{issued_stats}{blockhash}"` (where `issued_stats` is composed of `tx_count`, `issued_tx_count`, `transferred_tx_count`, `burned_tx_count`, `issued_sum`, `transferred_sum`, `burned_sum`)