# Index Schema

The index is stored at a single RocksDB database using the following schema:

## Block headers

|  Code  | Header
| ------ | ---------------------- |
| `b'B'` | `serialized header`    |

## Transaction output index

Allows efficiently finding transaction funding a specific output:

|  Code  | Output Hash               |   |  Funding TxID      | Funding Output Index | Funding value  |
| ------ | ------------------------  | - | ------------------ | -------------------- | -------------- |
| `b'H'` | `outpointhash` (32 bytes) |   | `txid` (32 bytes)  | `varint`             | `varint`       |

## Output to token index

Allows for efficiently checking if output modifies token (create, spends, mints, etc).

|  Code  | Output Hash               | Token ID                |   | Amount                          |
| ------ | ------------------------  | ----------------------- | - | ------------------------------- |
| `b'K'` | `outpointhash` (32 bytes) | `tokenid` (32+ bytes)   |   | `varint` (consensus serialized) |

In Nexa, subgroup tokenID's have the same prefix as their parent and are longer. The parent is
32 bytes, while subgroup's are variable in length.

Amount is serialized in the same way as it is in a `script_pubkey`.

## Token to output index

Allows to lookup tokin origin and full token history.

| Code   | Token ID              | Subtoken ID / commitment | Funding output hash |   |
| ------ | --------------------- | ------------------------ | ------------------- | - |
| `b'A'` | `tokenid` (32 bytes)  | `data` (variable length) | `outpointhash`      |   |

For tokens that are not subtokens (nexa) / do not have commitment (bch), `data` is an empty vector.

For nexa, the fields `tokenid` + `data` concatinated make the full token ID.

## ScriptSig to output index

Allows efficiently finding all funding transactions for a specific address:

|  Code  | Script Hash Prefix   | Flags  |   | Funding output hash |
| ------ | -------------------- | ------ | - |-------------------- |
| `b'O'` | `SHA256(script)`     | 1 byte |   | `outpointhash`      |

Flags:
- `0x00`: Generic output
- `0x01`: Output has token

## Transaction input index

Allows efficiently finding spending transaction of a specific output:

|  Code  | Output Hash               |   | Spending TxID         | Input index |
| ------ | ------------------------- | - | --------------------- | ----------- |
| `b'I'` | `output hash` (32 bytes)  |   | `txid` (32 bytes)     | `u32`       |

## TxID to confirmation height index

In order to save storage space, we store the full transaction IDs once, and use their 8-byte prefixes for the indexes above.

|  Code  | Transaction ID    |   | Confirmed height   |
| ------ | ----------------- | - | ------------------ |
| `b'T'` | `txid` (32 bytes) |   | `varint`           |

Note that this mapping allows us to use `getrawtransaction` RPC to retrieve actual transaction data from without `-txindex` enabled
(by explicitly specifying the [blockhash](https://github.com/bitcoin/bitcoin/commit/497d0e014cc79d46531d570e74e4aeae72db602d)).

## CashAccount index

Allows finding all transactions containing CashAccount registration by name and block height.

|  Code  | Account name              | Registration TxID Prefix   |   |
| ------ | ------------------------- | -------------------------- | - |
| `b'C'` | `SHA256(name#height)`     | `txid`                     |   |

## Other prefixes in use

- `b'L'` - Latest header tip
- `b'VER` - Database version marker
