# What Is Old Faithful?

Understanding the Old Faithful project, it's purpose, and how to get started.

Historically speaking, the Solana ledger has only been available via Google Big Table requests. This has large cost implications and doesn't fit the decentralized ethos of blockchains to make the entire history available to review.

Yellowstone Old Faithful, or Old Faithful for short, is an open-sourced project designed to provide a solution to this problem in the Solana ecosystem.

It is a collection of tooling that can produce Content Addressable Archives (CAR's) from RocksDB archives created by Solana warehouse nodes and serve them using a standard RPC/gRPC interface.

## Content Addressable Archives (CAR's)

The core of the Old Faithful is history archives in Content Addressable aRchives (CAR) format ([overview](https://web3.storage/docs/concepts/car/), [specs](https://ipld.io/specs/transport/car/carv1/)). These represent a verifiable, immutable view of Solana's history. The CAR files that this project generates follow a [schema](https://github.com/rpcpool/yellowstone-faithful/blob/main/ledger.ipldsch) specifically developed for Solana’s historical archives.

The content's addressable nature means that each epoch, block, transaction, and shredding is uniquely identified by a content hash. By knowing this content hash, a user can retrieve a specific object of interest in a trustless manner, i.e., retrieve an object verifiably from a non-trusted source.&#x20;

The tooling operates on (end of epoch) snapshots generated using the default `solana-ledger-tool` that's used by Solana warehouse nodes to record the full epoch into a single archive. No changes to the default Solana tools are required to produce such archives for Old Faithful.&#x20;

[Read more about Generating Old Faithful archives.](/running-old-faithful/sourcing-data/generating-from-rocksdb)

## Full History Archive

The second component of the Old Faithful project is **OF1**, a full genesis archive that contains every block from the genesis to the epoch before the ongoing one (the CAR file is generated from the rocksdb snapshot generated at the end of the epoch, with all processing expect it to be online within 10-20h after epoch end).

Triton provides a full copy of this ledger at [**https://files.old-faithful.net**](https://files.old-faithful.net/) that you can download to get started without needing to build the CAR's from the RocksDB archives yourself. This archived is stored in Amsterdam, download using servers nearby for best throughput.

[Read more about hosting your own copy of Old Faithful archives.](/running-old-faithful/requirements)

## Standard RPC Interface

Make standard Solana RPC requests to retrieve historical blocks and transactions. Existing tooling can integrate seamlessly to a full archive record.

[See examples of all JSON-RPC methods supported by Old Faithful.](/references/rpc-methods)

## &#x20;gRPC Interface

Most methods available in JSON-RPC can be done via gRPC too, and we've also implemented **StreamTransactions** and **StreamBlocks** for efficient server side filtering of large troves of data.

[See examples of all gRPC methods supported by Old Faithful.](/references/grpc-methods)

## Jetstream

For large ingests, in alternative to running the OF client, you may should use the Jetstream client that connects directly to the archive at [**https://files.old-faithful.net**](https://files.old-faithful.net/) and streams all data via geyser or to Clickhouse.&#x20;

[Read more about Jetstream client.](/usage/jetstreamer)

## Geyser Integrations

There is a Geyser integration that provides an easy way to perform ETL with already existing Solana Geyser plugins. You can run this on an epoch CAR file and receive Geyser notifications with blocks and transactions.

[Read more about using the Geyser integration.](#geyser-integration-and-rust-library)

## Homogenous Storage

Retrievals can be made via IPFS, the Filecoin network, or even by hosting the CAR files yourself on disk, a CEPH cluster, S3 or alternative compatible object storage services, HTTP (CDN), etc.&#x20;

The only real requirement is that the retrieval source you provide either publishes a standard Unix filesystem API or supports an HTTP API with **range** requests support.

[Read more about the various data sources available.](/running-old-faithful/sourcing-data)


# Architecture


# CAR's & CID's

In the archives, each Epoch, Block, and Transaction gets a computed content identifier. These content identifiers can uniquely identify any of these elements when retrieving either from a locally stored CAR file or from IPFS or Filecoin.

indexes are used to map Solana's slot numbers, transaction signatures, or epoch numbers onto CIDs.

To learn more about CIDs, you can dive deep into the IPFS documentation [here](https://docs.ipfs.tech/concepts/content-addressing/).

From <https://docs.ipfs.tech/concepts/content-addressing/#what-is-a-cid>:

> A content identifier, or CID, is a label used to point to material in IPFS. It doesn’t indicate where the content is stored, but it forms a kind of address based on the content itself. CIDs are short, regardless of the size of their underlying content. CIDs are based on the content’s cryptographic hash. That means:
>
> * Any difference in the content will produce a different CID
> * The same content added to two different IPFS nodes using the same settings will produce the same CID.

The CAR files and CIDs generated by Old Faithful are reproducible and will be the same regardless of which RocksDB ledger archive they are generated from.

This means that entities that are running archive nodes and store RocksDB ledger archives can easily generate their own CIDs for the same blocks and transactions and compare them to the ones being generated by the Old Faithful project theory.&#x20;

This means you can also choose to run a node that just generates and stores the CIDs but not the durable data and then compare those CIDs to the ones provided by Faithful. Using these CIDs, you can retrieve the actual data at any time without trusting anyone but your own data-generating nodes.


# Indexes

Indexes are needed to map Solana’s block numbers, transaction signatures, and addresses to their respective Content Identifiers. These indexes have been developed as part of this project. There are four content identifier indexes that the Old Faithful index generation can provide:

* **slot-to-cid**: Lookup a CID based on a slot number
* **tx-to-cid:** Lookup a CID based on a transaction signature
* **cid-to-offset-and-size**: Index for a specific CAR file, used by the local RPC server (see above) to find CIDs in a car file
* **sig-exists**: Index to check whether a specific signature exists in an epoch.

In addition, Old Faithful supports an index  `gsfa` that maps Solana addresses to a list of transaction signatures. This allows Old Faithful to support “Get Signatures For Address.”


# Requirements

Hosting your own local version of the archive is ideal for large-scale users such as infrastructure providers, explorers, or those wishing to access the archives with the highest possible throughput and lowest possible latency.

There are two parts to hosting the data:

* CAR files
* Indexes

### CAR Files

We recommend that you host the indexes on high-speed local or network storage. The critical element for high performance is that the indexes can be accessed with low latency. The CAR files themselves can be stored on somewhat higher-latency storage.

To get started on hosting your own archive, you have a few different options:

* Run warehouse nodes to [generate new car files continuously from Solana ledger copies](/running-old-faithful/sourcing-data/generating-from-rocksdb/warehouse-nodes)
* If you want a full or partial historical archive, you can:
  * [Generate your own archive from historical ledger copies](/running-old-faithful/sourcing-data/generating-from-rocksdb/historical-blocks)
  * [Clone OF1](/running-old-faithful/sourcing-data/of1)

### Indexes

Indexes are much easier to generate locally, but you may still pull them from the sources above.


# Sourcing Data

The Solana ledger is absolutely massive. In CAR format&#x20;

&#x20;Understanding the requirements of your use-case and what data you require is a critical first step to provisioning an Old Faithful installation.

There are several places you can get data from, each with their own varying degrees of complexity and hardware requirements.

## OF1&#x20;

Triton One provides a complete copy of all the files required to run Old Faithful, called OF1.&#x20;

This archive is currently completely free to use, and is a great way to get started with Old Faithful.&#x20;

Read more about OF1 [here](/running-old-faithful/sourcing-data/of1).

## Generating from RocksDB

Solana warehouse nodes archive the network ledger in a format called [RocksDB](https://rocksdb.org/). These archives can be used with the Yellowstone `radiance` fork to generate Old Faithful compatible CAR's.

Read more about generating from RocksDB [here](#generating-from-rocksdb).&#x20;


# OF1

Triton One maintains a a full copy of the Solana ledger in CAR archive format. This implementation is provided with a grant from Solana Foundation.

We aim to provide each CAR and indexes within 4 epochs of the epoch closing. you can check the status of each epoch using the [CAR Report](https://github.com/rpcpool/yellowstone-faithful/blob/gha-report/docs/CAR-REPORT.md).

### Sourcing Files

You can download all files required to run a complete local version of Old Faithful at `https://files.old-faithful.net`. \
\
The [OF1 Files](/references/of1-files) page has an index of all the files in each epoch.


# Filecoin

You can publish Old Faithful-based archives with a Filecoin storage provider. This would allow you to use the Filecoin retrieval modes with your preferred provider.

## For warehouse operators

### Flow v1

The basic flow of uploading Old Faithful data to Filecoin involves:

1. [Generating](broken://pages/BdW5XOrODYWlWjQuty8d) the CAR file for the epoch (or [cloning it](broken://pages/xLDustRx8FIcIcEqY5hn))
2. Splitting the car file into suitable sized chunks for ingest into filecoin (32 GiB), saving the metadata.yaml produced as part of the process (will be needed for [retrievals](/running-old-faithful/installation-and-setup/configuration-files/filecoin-v1-retrievals)).
3. Using boost to create deals for the split files, creating a deals.csv file in the process (see format below).
4. Once the deals are ingested, you can use the [Filecoin v1 version of retrievals](/running-old-faithful/installation-and-setup/configuration-files/filecoin-v1-retrievals).

#### Deals.csv file format

The deals.csv file format should contain the following headers as the first line (and then the corresponding values under each value):

* provider
* deal\_uuid
* file\_name
* URL
* commp\_piece\_cid
* file\_size
* padded\_size
* payload\_cid

<details>

<summary>Sample deals.csv</summary>

```csv
provider,deal_uuid,file_name,url,commp_piece_cid,file_size,padded_size,payload_cid
f02366527,db161970-b4ab-4a05-bae4-b0e559a48806,sp-epoch-100-baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi.car,https://filecoin-car-storage-cdn.b-cdn.net/100/sp-epoch-100-baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi.car,baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi,30000000796,34359738368,bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i
f02366527,cd27c9bd-4d26-4deb-9579-6821e42bdbdd,sp-epoch-100-baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy.car,https://filecoin-car-storage-cdn.b-cdn.net/100/sp-epoch-100-baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy.car,baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy,30000000081,34359738368,bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i
f02366527,c9237f39-0cfc-48ba-a4b8-7163f4543305,sp-epoch-100-baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii.car,https://filecoin-car-storage-cdn.b-cdn.net/100/sp-epoch-100-baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii.car,baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii,2937660613,4294967296,bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i
f02366527,473a2c70-8f0f-498b-b539-d3f0e50a4579,sp-epoch-100-baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi.car,https://filecoin-car-storage-cdn.b-cdn.net/100/sp-epoch-100-baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi.car,baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi,30000000796,34359738368,bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i
f02366527,6b0a5754-371c-4cd9-8553-c26dc37a0763,sp-epoch-100-baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy.car,https://filecoin-car-storage-cdn.b-cdn.net/100/sp-epoch-100-baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy.car,baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy,30000000081,34359738368,bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i
f02366527,63e14784-ac0b-44a9-8e3b-0395b654a519,sp-epoch-100-baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii.car,https://filecoin-car-storage-cdn.b-cdn.net/100/sp-epoch-100-baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii.car,baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii,2937660613,4294967296,bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i
```

</details>

### Flow v2

{% hint style="info" %}
Flow v2 for generating CAR files will be necessary to support [Filecoin v2 retrievals](/running-old-faithful/installation-and-setup/configuration-files/filecoin-v2-retrievals). It is still in progress and involves the use of a new split tool.
{% endhint %}

## For storage providers

If you are a Filecoin storage provider, you can participate in the Old Faithful project by partnering with a Solana warehouse node operator that generates CAR file deals.&#x20;


# Generating from RocksDB

Old Faithful uses the `radiance` tool from the Firedancer team to provide an interface to the RocksDB Solana ledger archives.

We have forked the project to add the ability to generate a full CAR, you will need to download and build the binaries in order to generate CAR's that are compatible with Old Faithful.

{% embed url="<https://github.com/rpcpool/radiance-triton-faithful/tree/main>" %}

The radiance tool utilizes the RocksDB snapshots generated by [Warehouse](https://github.com/solana-labs/solana-bigtable) nodes. From these snapshots, a CAR file per epoch is generated.

### Filecoin Considerations

If you intend to host this car in Filecoin, you'll need to have it processed by Filecoin tools such as [split-and-commp](https://github.com/rpcpool/go-fil-dataprep/) which will then create the necessary metadata for making the filecoin deal.


# Creating indexes

Once the radiance tooling has been used to prepare a car file (or if you have downloaded a car file externally), you can generate indexes from this car file by using the `faithful-cli`:

```
NAME:
   faithful CLI index - Create various kinds of indexes for CAR files.

USAGE:
   faithful CLI index command [command options] [arguments...]

DESCRIPTION:
   Create various kinds of indexes for CAR files.

COMMANDS:
   cid-to-offset  
   slot-to-cid    
   sig-to-cid     
   all            Create all the necessary indexes for a Solana epoch.
   gsfa           
   sig-exists     
   help, h        Shows a list of commands or help for one command

OPTIONS:
   --help, -h  show help
```

### Examples

* `faithful-cli index all <car-file> <output-dir>`: Generate all **required** indexes for a CAR file.
* `faithful-cli index gsfa <epoch-number> <car-file> <output-dir>`: Generate the gsfa index for a CAR file.

NOTES:

* You need to have the CAR file available locally.
* The `cid_to_offset_and_size` index has an older version, which you can specify with `cid_to_offset`instead of `cid_to_offset_and_size`.

### Flags:

* `--tmp-dir=/path/to/tmp/dir`: Where to store temporary files. Defaults to the system temp dir. (optional)
* `--verify`: Verify the indexes after generation. (optional)
* `--network=<network>`: Network to use for the gsfa index. Defaults to `mainnet` (other options: `testnet`, `devnet`). (optional)


# Historical blocks

You need to source RocksDB ledger copies from those epochs to gather the raw data for historical blocks.  These are available from the following sources:

* Solana Foundation (public, Google Storage)
  * gs\://mainnet-beta-ledger-us-ny5
  * gs\://mainnet-beta-ledger-europe-fr2
  * gs\://mainnet-beta-ledger-asia-sg1
* Triton One (private)
  * For access, contact Triton One.

Once you have downloaded the RocksDB ledger archives, you can run the Radiance tool to generate a car file for an epoch. Ensure you have all the slots available in the RocksDB ledger archive for the epoch. You may need to download multiple ledger snapshots to have a full set of slots available. Once you know you have a RocksDB dataset that covers all the slots for the epoch, run the radiance tool like follows:

```
radiance car create2 107 --db=46223992/rocksdb --out=/storage/car/epoch-107.car
```

This will produce a car file called epoch-107.car containing all the blocks and transactions for that epoch. To specify multiple ledger snapshots, you can provide the db command line parameter multiple times `--db=12312/rocksdb --db=52321/rocksdb`.  The radiance tooling will automatically stitch the RocksDB ledger archives together to form a full epoch car file.&#x20;

## Check mode

You can check if your current ledger has the slots you require to generate the epoch-107.car by adding the following flag:

```
--check
```

This will ensure that the radiance car create2 command will walk through and check that it has all the slots.

## Shred revisions (epoch <=  32)

The shred format changed around epoch 32.

Add the following flag for epochs up to 32&#x20;

```
--shred-revision=1
```

When generating epoch 32 itself, you need to provide the following flags:

```
--shred-revision=1 --next-shred-revision-activation-slot=10367766

```

Note: Depending on what snapshots you use to generate this CAR file, this shred revision transition may occur on epoch 22.

## Epoch 208

While generating the OF1 archive, Triton One could not find a ledger file covering approximately 495 slots during Epoch 208. Since the ledger data was missing, Triton worked with Anza Labs to recreate a ledger for these 495 slots to build an Old Faithful CAR file for this epoch.&#x20;

The gap exists between slots 89856108 and 89856602 (inclusive).

For generating Epoch 208, you should, therefore, add this ledger copy as a CLI argument to radiance:

<pre><code><strong>--db epoch-208-rocksdb/
</strong></code></pre>

For more information about generating your own version of this ledger and validating that it is correct, see the [Epoch 208](#epoch-208) page under Validation.


# Warehouse nodes

To generate the Old Faithful archives on an ongoing basis, we recommend that you run a Warehouse node. A warehouse node is just a Solana node set up with some start-up/stop scripts that generate archives per epoch. Warehouse nodes have been used to create the ledger copies that Old Faithful bases itself on. They have also been used to keep the older BigTable archives current.

There are some examples and details about running a warehouse node here:

{% embed url="<https://github.com/solana-labs/solana-bigtable>" %}

With Old Faithful you use the rocksdb ledger copies generated by the warehouse nodes to generate the archives in content addressable format (CAR). &#x20;


# Installation & Setup

Three software projects comprise Old Faithful:

* [Faithful](http://github.com/rpcpool/yellowstone-faithful), used for running the [RPC server ](/usage/rpc-server)and [creating the necessary indexes](/running-old-faithful/sourcing-data/generating-from-rocksdb/creating-indexes) for the RPC server
* [Radiance](http://github.com/rpcpool/radiance-triton-faithful/), used for processing[ warehouse nodes’ ledger  archives and producing CAR files](/running-old-faithful/sourcing-data/generating-from-rocksdb/warehouse-nodes)
* [PoH check car,](https://github.com/rpcpool/poh-check-car) used for [validating PoH of Old Faithful](/usage/validation) car files.

You can also [interact with Old Faithful through standard Filecoin tooling](/running-old-faithful/installation-and-setup/configuration-files/filecoin-v1-retrievals) like [Lassie](https://github.com/filecoin-project/lassie).

You only need the Faithful CLI if you are interested in working with the Faithful dataset and retrieving data.

## Building and installing Radiance

You will need to build Radiance with RocksDB support following the guide here:

<https://github.com/rpcpool/radiance-triton-faithful/blob/main/INSTALL.md>


# Building Old Faithful

Basic installation of faithful can be done by downloading the repository and building it (requires Golang >1.20):

```sh
$ git clone https://github.com/rpcpool/yellowstone-faithful.git
$ make
```

There are also binary builds for Linux available at <https://github.com/rpcpool/yellowstone-faithful/releases>.

### jsonParsed Support

If you want jsonParsed support in the RPC server, you will need to compile some additional Rust dependencies. \
\
To understand why this is the case, read [here](/running-old-faithful/installation-and-setup/building-old-faithful/jsonparsed-support).


# \`jsonParsed\` Support

{% hint style="success" %}

### Optional Feature

If you don't need `jsonParsed` support, you do not need to complete any of the following steps!
{% endhint %}

Old Faithful is written primarily in Golang. Because Solana is written in Rust, the most optimal way for Old Faithful to parse transactions into a JSON format is to rely on the official Solana SDK's for parsing.&#x20;

Because of this, the compilation step of Old Faithful requires an additional step to enable `jsonParsed` support.

### Requirements

* Install Golang >1.20

### Compiling

After building the `faithful-cli` binary, run this command in the same folder:

```
make jsonparsed-linux
```

You can use this binary to use Old Faithful identical as before, with the added `jsonParsed` feature.


# Preparing Data

Every epoch that you wish to host in Old Faithful requires at least the following files to be available to the `faithful-rpc` process:

* Epoch CAR
* Indexes:
  * `slot-to-cid`
  * `tx-to-cid`
  * `cid-to-offset-and-size`
  * `sig-exists`
  * Optionally, `gsfa` if you wish to use `getSignaturesForAddress`&#x20;

How you source these is up to you! Old Faithful is designed to allow flexibility in which epochs you wish to support, and what type of storage it's located on.

{% hint style="warning" %}

### GSFA Index

The GSFA index stores a mapping of every signature for every address in that epoch, and can be used to quickly find all the transactions associated with a specified address across the Old Faithful dataset.\
\
Because of this fast random read requirement, it is \*highly\* suggested to store the `gsfa` indexes on a local NVMe disk for best performance, especially when hosting a large number of epochs.
{% endhint %}

### Supported Transport Protocols

Old Faithful supports local filesystem, HTTP/HTTPS (including S3), and Filecoin for CAR file and index storage.

Detailed instructions for each transport protocol can be found at:

* [OF1](/running-old-faithful/sourcing-data/of1)
* [Filecoin](/running-old-faithful/sourcing-data/filecoin)
* [Generating from RocksDB](/running-old-faithful/sourcing-data/generating-from-rocksdb)


# Configuration Files

To configure the Old Faithful RPC server, you create a YAML configuration file per epoch of data you want the server to support.&#x20;

You can provide as few or as many epochs as you want, just make sure each has it's own configuration file.

### Storage

Store the configuration files on disk in a folder that can be accessed by the Old Faithful binary.

A common folder structure is like this

<pre data-full-width="false"><code><strong>configs/
</strong>  epoch-0.yml
  epoch-2.yml
  epoch-3.yml
  ...
</code></pre>

### Old Faithful YAML Config File Format

* `version`: current version is 1
* `epoch`: the epoch that this config file is for, an Old Faithful server can only host one config per epoch
* `genesis`: (only used for epoch 0), provide a URI to a genesis file if you want to serve epoch 0.
* `data`: retrieval configuration for the block/transaction data&#x20;
  * `car`: used for [Filecoin v1,](/running-old-faithful/installation-and-setup/configuration-files/filecoin-v1-retrievals) [http](/running-old-faithful/installation-and-setup/configuration-files/http), and [local file system](/running-old-faithful/installation-and-setup/configuration-files/local-file-system) retrievals
  * `filecoin`: used for [Filecoin v2](/running-old-faithful/installation-and-setup/configuration-files/filecoin-v2-retrievals) retrievals
* `indexes`: retrieval configuration for the index data (each index header is a `uri` argument)
  * `slot_to_cid`: provide a local file system path or HTTP URI to the slot-to-cid index
  * `cid_to_offset_and_size`: provide a local file system path or HTTP URI to the cid-to-offset-and-size index
  * `sig_to_cid`: provide a local file system path or HTTP URI to the sig-to-cid index&#x20;
  * `sig_exists`: provide a local file system path or HTTP URI to the sig exists index
  * `gsfa`: provide a local file system path to an unpacked `gsfa` index folder.&#x20;
    * If you want to use a remote URI, you need to start the faithful RPC with `--gsfa-only-signatures.`

<details>

<summary>Sample config file</summary>

```yaml
epoch: 0 # epoch number (required)
version: 1 # version number (required)
data: # data section (required)
  car:
    # Source the data from a CAR file (car-mode).
    # The URI can be a local filepath or an HTTP url.
    # This makes the indexes.cid_to_offset_and_size required.
    # If you are running in filecoin-mode, you can omit the car section entirely.
    uri: /media/runner/solana/cars/epoch-0.car
  filecoin:
    # filecoin-mode section: source the data directly from filecoin.
    # If you are running in car-mode, you can omit this section.
    # if enable=true, then the data will be sourced from filecoin.
    # if enable=false, then the data will be sourced from a CAR file (see 'car' section above).
    enable: false
genesis: # genesis section (required for epoch 0 only)
  # Local filepath to the genesis tarball.
  # You can download the genesis tarball from
  # wget https://api.mainnet-beta.solana.com/genesis.tar.bz2
  uri: /media/runner/solana/genesis.tar.bz2
indexes: # indexes section (required)
  cid_to_offset_and_size:
    # Required when using a CAR file; you can provide either a local filepath or a HTTP url.
    # Not used when running in filecoin-mode.
    uri: '/media/runner/solana/indexes/epoch-0/epoch-0-bafyreifljyxj55v6jycjf2y7tdibwwwqx75eqf5mn2thip2sswyc536zqq-mainnet-cid-to-offset-and-size.index'
  slot_to_cid:
    # required (always); you can provide either a local filepath or a HTTP url:
    uri: '/media/runner/solana/indexes/epoch-0/epoch-0-bafyreifljyxj55v6jycjf2y7tdibwwwqx75eqf5mn2thip2sswyc536zqq-mainnet-slot-to-cid.index'
  sig_to_cid:
    # required (always); you can provide either a local filepath or a HTTP url:
    uri: '/media/runner/solana/indexes/epoch-0/epoch-0-bafyreifljyxj55v6jycjf2y7tdibwwwqx75eqf5mn2thip2sswyc536zqq-mainnet-sig-to-cid.index'
  sig_exists:
    # required (always); you can provide either a local filepath or a HTTP url:
    uri: '/media/runner/solana/indexes/epoch-0/epoch-0-bafyreifljyxj55v6jycjf2y7tdibwwwqx75eqf5mn2thip2sswyc536zqq-mainnet-sig-exists.index'
  gsfa: # getSignaturesForAddress index
    # optional; must be a local directory path.
    uri: '/media/runner/solana/indexes/epoch-0/gsfa/epoch-0-bafyreifljyxj55v6jycjf2y7tdibwwwqx75eqf5mn2thip2sswyc536zqq-gsfa.indexdir'
```

</details>


# Local file system

Local file system mode is the simplest mode of retrieval and also provides the fastest response times for RPC calls.

&#x20;In this mode, you host the CAR files locally as files on a file system. Depending on the epoch range you are wanting to support, this can require a very large amount of storage (\~350TB as of Epoch 827).

You can also host the indexes locally for best performance or mix with some indexes locally and some remotely.

<pre><code><strong>data/
</strong><strong>  0/
</strong><strong>    epoch-0.car
</strong><strong>    epoch-0.cid
</strong><strong>    epoch-0-bafy...-mainnet-cid-to-offset-and-size.index
</strong><strong>    epoch-0-bafy...-mainnet-sig-exists.index
</strong><strong>    gsfa/
</strong><strong>      ...
</strong></code></pre>

### Local Filesystem Example Configuration File

This is an example epoch 100 configuration that targets local files:

```yaml
version: 1
epoch: 100
data:
  car:
    uri: /of1/100/epoch-100.car
indexes:
  cid_to_offset_and_size:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-cid-to-offset-and-size.index
  slot_to_cid:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-slot-to-cid.index
  sig_to_cid:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-to-cid.index
  sig_exists:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-exists.index
```

Be aware that a full local clone of the OF1 genesis archive runs in multiple 100s of TB.&#x20;

### Split retrievals

If your file system or network file system store does not like serving large files, you can configure split retrievals for the local file system in the same way they work for [HTTP retrievals](/running-old-faithful/installation-and-setup/configuration-files/http#split-retrievals-advanced).


# HTTP

To use HTTP retrievals, you only need to point your config file to an HTTP endpoint that hosts the epoch-NNN.car file, which supports HTTP range requests.&#x20;

```yaml
version: 1
epoch: 100
data:
  car:
    uri: https://files.old-faithful.net/100/epoch-100.car
indexes:
  cid_to_offset_and_size:
    uri: https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-cid-to-offset-and-size.index
  slot_to_cid:
    uri: https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-slot-to-cid.index
  sig_to_cid:
    uri:  https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-to-cid.index
  sig_exists:
    uri: https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-exists.index
```

### Split retrievals (advanced)

If your remote storage solution cannot handle large monolithic files like the 600 GiB files we produce, you can also use split retrievals in HTTP mode, similar to how they work in Filecoin v1 retrievals.

You can use [go-fil-dataprep](https://github.com/rpcpool/go-fil-dataprep) to split the files in any size you want. This tool will also generate metadata.yaml. After you have generated metadata.yaml and the split, you need to create a map from this tool's “piece CIDs” and the URI of the specific pieces.

A sample config file for this use case would look like this (NOTE: this is just a sample; we currently do not host split retrievals on <https://files.old-faithful.net>):

```yaml
version: 1
epoch: 100
data:
  car:
    from_pieces:
      metadata:
        uri: https://files.old-faithful.net/100/metadata.yaml
      piece_to_uri:
        baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi:
          uri: https://files.old-faithful.net/100/baga6ea4seaqiogvxkc4cjgbimal52zgaqwo5ugcvy2bc72nrerro3wtzy47jepi.car
        baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy:
          uri: https://files.old-faithful.net/100/baga6ea4seaqowdba7qkhqxw3umullabn7mx377we7vu3klguccuderfqclzpsiy.car
        baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii:
          uri: https://files.old-faithful.net/100/baga6ea4seaqhky3ydiwp5toduhxpzt7oxm5cctuvrjbmkq5gzf3s6arayindoii.car
indexes:
  cid_to_offset_and_size:
    uri: https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-cid-to-offset-and-size.index
  slot_to_cid:
    uri: https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-slot-to-cid.index
  sig_to_cid:
    uri:  https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-to-cid.index
  sig_exists:
    uri: https://files.old-faithful.net/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-exists.index
```


# Filecoin v1 retrievals

V1 retrievals on Filecoin are done using HTTP range requests to Storage providers hosting the files. Currently, this requires that you provide multiple pieces of information:

* A metadata.yml file that specifies the way that the full epoch car file was split into Filecoin pieces
* A deals.csv file that maps the individual Filecoin pieces to storage providers

A sample config file for an epoch using Filecoin v1 retrievals would look like this:

```yaml
version: 1
epoch: 100
data:
  car:
    from_pieces:
      deals:
        uri: '/of1/100/deals.csv'
      metadata:
        uri: '/of1/100/metadata.yaml'
indexes:
  cid_to_offset_and_size:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-cid-to-offset-and-size.index
  slot_to_cid:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-slot-to-cid.index
  sig_to_cid:
    uri:  /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-to-cid.index
  sig_exists:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-exists.index
  gsfa:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-gsfa.indexdir
```

All indexes except gsfa can use either a local file system URL or an HTTP URL.&#x20;


# Filecoin v2 retrievals

{% hint style="warning" %}

## Here Be Dragons!

Filecoin v2 retrieval is still in progress! \
\
If you experience issues with this format, please open a Github ticket with as much information as you can so we can debug faster!
{% endhint %}

A new piece-based splitting format simplifies Filecoin retrievals.&#x20;

This allows for a much more convenient configuration of Filecoin retrievals and supports other Filecoin protocols like bit swap and graphsync.

To configure Filecoin v2 retrievals, you specify a Subset CID (a Subset is a range of Slots in an Epoch). For the OF1 archive, we intend to publish Subset CIDs in an easy-to-retrieve place. You can also specify an optional list of storage\_providers from which you want to fetch the data.

```yaml
version: 1
epoch: 100
data:
  filecoin:
    enable: true
    subset_cids: 
      - bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i
      - bafyreibqt212roysxlxctgb52xxn27ectsll2xsfk24qar7ga6vusdjn32
    storage_providers:
      - f02366527
indexes:
  slot_to_cid:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-slot-to-cid.index
  sig_to_cid:
    uri:  /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-to-cid.index
  sig_exists:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-sig-exists.index
  gsfa:
    uri: /of1/100/epoch-100-bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i-mainnet-gsfa.indexdir
```


# Start Old Faithful

After you have compiled the Old Faithful binaries, running the RPC server is as simple as running this command:

```
/path/to/binary/faithful-cli [options] rpc configs/ 
```


# Software integrations

Integrating with the Old Faithful dataset should be relatively easy, considering that there are CAR file format readers in many languages:

* JS: <https://github.com/ipld/js-car>
* Golang: <https://github.com/ipld/go-car>
* Rust: <https://github.com/rpcpool/yellowstone-faithful/tree/main/geyser-plugin-runner>

The schema for the CAR files is available here: <https://github.com/rpcpool/yellowstone-faithful/blob/main/ledger.ipldsch>


# RPC server

## Overview

Old Faithful ships with an RPC server that supports [gRPC](/references/grpc-methods) and [JSON-RPC](/references/rpc-methods).&#x20;

## Command line

The RPC server is available via the `faithful-cli rpc` command.

The command accepts a list of [epoch config files](https://github.com/rpcpool/yellowstone-faithful#epoch-configuration-files) and dirs as arguments. Each config file is specific for an epoch and provides the location of the block/transaction data and the indexes for that epoch. The indexes are used to map Solana block numbers, transaction signatures, and addresses to their respective CIDs. The indexes are generated from the CAR file and can be generated via the `faithful-cli index` command (see [Index generation](https://github.com/rpcpool/yellowstone-faithful#index-generation)).

It supports the following flags:

* `--listen`: The address to listen on, e.g. `--listen=:8888`
* `--include`: You can specify one or more (reuse the same flag multiple times) glob patterns to include files or dirs that match them, e.g. `--include=/path/epoch-*.yml`.
* `--exclude`: You can specify one or more (reuse the same flag multiple times) glob patterns to exclude files or dirs that match them, e.g. `--exclude=/something-*/epoch-*.yml`.
* `--debug`: Enable debug logging.
* `--proxy`: Proxy requests to a downstream RPC server if the data can't be found in the archive, e.g. `--proxy=/path/to/my-rpc.json`. See [RPC server proxying](https://github.com/rpcpool/yellowstone-faithful#rpc-server-proxying) for more details.
* `--gsfa-only-signatures`: When enabled, the RPC server will only return signatures for getSignaturesForAddress requests instead of the full transaction data.
* `--watch`: When specified, all the provided epoch files and dirs will be watched for changes, and the RPC server will automatically reload the data when changes are detected. Usage: `--watch` (boolean flag). This is useful when you want to provide just a folder and add new epochs to it without restarting the server.
* `--epoch-load-concurrency=2`: Epochs to load in parallel when starting the RPC server. Defaults to the number of CPUs. This is useful when you have a lot of epochs and want to speed up the initial load time.
* `--max-cache=<megabytes>`: Memory to use for caching. Defaults to 0 (no limit). This is useful when you want to limit the memory usage of the RPC server.

NOTES:

* By default, the RPC server doesn't support the `jsonParsed` format. You need to build the RPC server with the `make jsonParsed-linux` flag to enable this.

## Remote vs. local indexes

Indexes can be utilized either over HTTP or via a local file system. Currently, we do not host the indexes on Filecoin, though this may change in the future.&#x20;

We highly recommend storing indexes locally on high-speed storage for the best performance. The GSFA index required to support getSignaturesForAddress can currently not be used remotely.&#x20;

If you want to rely on remote indexes, you can leave out the GSFA index or specify the GSFA index to return only the signatures and not the transaction body. In this mode, you can use a remote gSFA index. To enable this mode, run faithful-cli in the following way:

```bash
faithful-cli rpc -gsfa-only-signatures=true 455.yml 
```

## Proxying

The RPC server provides a proxy mode that allows it to forward traffic it can't serve to a downstream RPC server. To configure this, provide the command line argument `--proxy=/path/to/faithful-proxy-config.json`pointing it to a config file. The config file should look like this:

```
{
	"target": "https://api.mainnet-beta.solana.com",
	"headers": {
		"My-Header": "My-Value"
	},
	"proxyFailedRequests": true
}
```

The `proxyFailedRequests` flag will make the RPC server proxy not only RPC methods that it doesn't support but also retry requests that failed to be served from the archives (e.g. a `getBlock` request that failed to be served from the archives because that epoch is unavailable).

## Log Levels

You can set the desired log verbosity level by using the `-v` flag. The levels are from 0 to 5, where 0 is the least verbose and 5 is the most verbose. The default level is 2.

Example:

```
faithful-cli -v=5 rpc 455.yml
```


# Jetstreamer

One of the best and easier ways to get started using Old Faithful archive is to use Jetstreamer client developed by Anza. It's optimized to pull data directly from the archive (no storage requirements) at very high throughput allowing you to perform a full ingest within days.&#x20;

Jetstreamer can stream the data to any geyser plugin, Clickhouse or you can write your own jetstream plugin for everything else.

Keep in mind the CAR file archive is physically stored in Amsterdam, run from nearby for best results.

See the repo to get started <https://github.com/anza-xyz/jetstreamer>


# Geyser

The Old Faithful project provides a geyser runner to set up simple ETL pipelines using [existing Geyser plugins](https://github.com/rpcpool/solana-geyser-park). This can help you integrate Solana history data into your existing data stores, backfill pipelines, and other tooling.

The example code:

<https://github.com/rpcpool/yellowstone-faithful/tree/main/geyser-plugin-runner>


# 3rd Party Tools

Several CAR format readers exist for reading CAR's in your language of choice:

* JS SDK: <https://github.com/ipld/js-car>
* Golang SDK: <https://github.com/ipld/go-car>
* Rust: <https://github.com/lamports-dev/yellowstone-faithful-car-parser>

Old Faithful specific tools

* Geyser Plugin Runner: <https://github.com/rpcpool/yellowstone-faithful/tree/main/geyser-plugin-runner>
* Jetstreamer: <https://github.com/anza-xyz/jetstreamer>

### Schema

The schema for the CAR file format can be found at <https://github.com/rpcpool/yellowstone-faithful/blob/main/ledger.ipldsch>


# Validation

The Old Faithful archives have been fully validated to represent a true state of the chain.

## Blockhashes and parent/child relationships

During the generation of the CAR files, Old Faithful validates that each block generated has the correct links with the parent/child. This includes validating that each epoch's last block/first block links correctly with the slots in the following epochs.

This ensures that there is a complete set of blocks from block 0 to the current block.&#x20;

## Proof of History

Old Faithful supports full validation of Proof of History. In OF1, every epoch’s PoH has been validated with one exception (see [Epoch 208](/usage/validation/epoch-208)).  Outputs from our validation of the history can be found at <https://files.old-faithful.net/\\><epoch>/poh-check-\<epoch>.log.&#x20;

For example, <https://files.old-faithful.net/100/poh-check-100.log>:

```
I1109 13:00:28.125613  217304 main.go:130] Roots: 1
I1109 13:00:28.125641  217304 main.go:133] - bafyreibqt2nvroysxlxctgb52xxn27ectsllv2xyka4qar7ga6vupmbs3i (Epoch CID)
PrevBlockHash: 47PrqQ4MJrT4G2GB7uHk5CdZadTKspB5HgDszzxHPJc2
EOF
I1109 13:15:10.275042  217304 main.go:345] Waiting for all nodes to be parsed...
I1109 13:15:10.275046  217304 main.go:347] All nodes parsed.
I1109 13:15:10.275049  217304 main.go:349] Waiting to receive all results...
I1109 13:15:10.292252  217304 main.go:352] All results received
I1109 13:15:10.292261  217304 main.go:354] Waiting for all assertions to finish...
I1109 13:15:10.292840  217304 main.go:356] All assertions finished
I1109 13:15:10.292847  217304 main.go:359] Last block hash for slot 43631999: FUPcPKdnNUWRrwyDqpyAdMqX7XH6rvGM7eEHYYN2KX6M
I1109 13:15:10.292855  217304 main.go:360] Number of checked entries: 110,592,602
I1109 13:15:10.292858  217304 main.go:361] Number of hashes: 345,600,000,000
I1109 13:15:10.292861  217304 main.go:363] Successfully checked PoH on CAR file
I1109 13:15:10.292862  217304 main.go:143] Finished in 14m42.167217686s
I1109 13:15:10.292864  217304 main.go:144] Read 196980689 nodes from CAR file
I1109 13:15:10.292870  217304 main.go:59] CAR file checked successfully
I1109 13:15:10.292872  217304 main.go:53] Took 14m42.170098595s

```

To run this check yourself, you use the poh-check-car tool from <https://github.com/rpcpool/poh-check-car>.  Sample usage of this tool:

```sh
$ poh-check-car \
	--workers=12 \
	--auto \
	--epoch=0 \
	--car=/media/laptop/solana-history/cars/epoch-0.car
```


# Reproducibility

You will have identical archives with identical CIDs if you generate archives from the same RocksDB ledger.

However, because transaction logs are included in the Old Faithful output, we cannot guarantee reproducibility across two RocksDB ledgers. For example, if you have two warehouse nodes generating Old Faithful archives from their local snapshot state, these may produce different transaction execution logs.&#x20;

This could happen, for example, if the two nodes run different Solana versions. The execution logs from the transactions are not validated and are not part of the validated set of the blockchain. They are metadata produced during the transaction's execution by the node executing them.


# Epoch 208

Since the ledger data [for about 495 slots (89856108 and 89856602) is missing](/running-old-faithful/sourcing-data/generating-from-rocksdb/historical-blocks#epoch-208), we do not have PoH data for these slots. This means that the [PoH validation](/usage/validation) that was conducted on the other slots could not be completed.

Triton One worked with engineers from Anza Labs to solve this issue, which involves sourcing transaction and block data from Google BigTable and validating it through replay. Replaying such old blocks is difficult, but Anza Labs has created a special version of `solana-ledger-tool` to support this replay.

## Basic Theory

The basic theory of this validation is:

1. We have an account state snapshot, including a slot immediately before the gap, and another account state snapshot, which includes a slot immediately after the gap.
2. These account snapshots are based on two slots for which we have valid PoH information.
3. We have validated the PoH hashes for the two slots (before and after the gap) on which the account state snapshots are based.
4. We then replay the transactions sourced from Bigtable and validate that the bank hashes produced at each slot are valid.&#x20;
5. After replay, we can produce an account state snapshot. This snapshot must match the one available after the Epoch 208 ledger gap.

Going through this process, we can produce a new valid ledger for these 495 slots to generate the bank hashes.

## Availability of Bank Hashes

While the data to recompute POH is lost, we still have the bank hashes available, as these are included in the votes submitted by the validators. Bank hashes (see <https://github.com/solana-labs/solana/blob/005c825b5c27bd57df9b0aadf0edb2e02215add0/runtime/src/bank.rs#L7047-L7052>) contain:

* Previous block hash
* A hash of the delta of all accounts during the slot
* The number of signatures in the block
* The last blockhash of the block (i.e., the one referred to as the block’s ”blockhash”).

As part of the replay of epoch 208, the bank hashes are recomputed and can be compared with those inside the votes submitted by the validators. We can also compute the stake weight of the votes based on the data available in BigTable. Since votes are signed by the validators, they cannot be forged.&#x20;

This means that during replay, you can reproduce the bank hashes.&#x20;

## Performing your own validation of Epoch 208

Currently, Triton One and Anza Labs have validated Epoch 208. We encourage other parties to run their own validation. The tooling is basic but should enable you to re-run the validation completely. You will need access to the required slots of a Google Bigtable archive (or other archive).

### Pre-requisites

#### Hardware specs

To verify, you need at least the following hardware specs:

* 40 GiB available RAM (total system memory recommended at least 64 GiB)
* 2 TiB available disk space (ideally NVME)
* OS: Ubuntu 22.04.2 LTS&#x20;

```sh
# print used memory, should have at lest 40 GiB available
free -h

# print available disk space,m should have at least 2TiB available
df -h

# print ubuntu version; must be 22.04 LTS
lsb_release -a

# print current version; must be at least GLIBC_2.32; GLIBC 2.35 is good
ldd --version
```

#### Bigtable access (or other ledger store)

You need read-only credentials for a Google Bigtable copy of the Solana history or an equivalent source. If you want to reproduce it but do not have access to your own Bigtable, you can contact Anza Labs or Triton One to request access.

#### Ledger and account snapshots

You need to download the account snapshots that you can use to compare against. The pre-account snapshot is hosted by Anza and is available in a Google Cloud storage bucket called mainnet-beta-ledger-us-ny5. This was produced by warehouse nodes running at the time. This snapshot is from a ledger that has been [validated in the normal Old Faithful process](/usage/validation).&#x20;

The RocksDB snapshot at <https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89423444/rocksdb.tar.bz2> runs up to slot 89856107. Ledger tool reports:

```
Ledger has data for 424323 slots 89423444 to 89856107
```

The latest account state snapshot before the missing slots is at slot 8985546. <https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89855469/snapshot-89855469-9i59TwLmzXvbomizFZNuXgPygtx8zJ3P4nWDQuNxrTxK.tar.zst>).

After the gap, the ledger snapshot at <https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89855469/rocksdb.tar.bz2> starts at 89856602. Ledger tool reports:

```
Ledger has data for 424529 slots 89856602 to 90288016
```

The account state snapshot after the gap that we have available is at 89865552 <https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89855469/hourly/snapshot-89865552-CWFaiDterTZ1EFQrJkFghnnzERFJNNFT2USBnYTssxsF.tar.zst>

This means that if you want to use the existing snapshots for validation, you need to replay between at least slot 89855469 and 89865552 (10083 slots).

### Building solana-ledger-tool

A special version of the `solana-ledger-tool` has been prepared, which has a patch to allow running the verification and skipping PoH verification (since PoH data is missing).

````shell
git clone git@github.com:solana-labs/solana-ledger-gap.git
cd solana-ledger-gap
git checkout origin/steviez_v1.7.9

# install dependencies
sudo apt-get install \
    build-essential \
    pkg-config \
    libudev-dev llvm libclang-dev \
    protobuf-compiler \
    libssl-dev \
    apt-file

# install rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
. "$HOME/.cargo/env"

cd ledger-tool

nano Cargo.toml
# add the following lines to [dependencies]
```
openssl-sys = "0.9.58"
openssl = "0.10.30"
```

# install rust nightly 1.57.0
rustup install nightly-2021-12-06
rustup toolchain install nightly-2021-12-06

# build solana-ledger-tool
cargo +nightly-2021-12-06 build --release

# the final binary is located at ./target/release/solana-ledger-tool
./solana-ledger-gap/target/release/solana-ledger-tool

# copy the binary to a location that is in the PATH (e.g. /usr/local/bin)
cp ./target/release/solana-ledger-tool /usr/local/bin/solana-ledger-tool
````

### Running verification

Running the verification will take some time. We recommend using a `tmux` session with an unlimited scrollback buffer to run the verification.

```sh

# create a working directory
export WORKING_DIR_E208=/solana/e208
mkdir $WORKING_DIR_E208
mkdir $WORKING_DIR_E208/ledger
cd $WORKING_DIR_E208

# download the pre-gap snapshots
apt install -y aria2 pv bzip2 lbzip2 zstd
aria2c -x 16 -s 16 -d $WORKING_DIR_E208/ledger https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89423444/rocksdb.tar.bz2
aria2c -x 16 -s 16 -d $WORKING_DIR_E208/ledger https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89855469/snapshot-89855469-9i59TwLmzXvbomizFZNuXgPygtx8zJ3P4nWDQuNxrTxK.tar.zst

# get genesis file
cd $WORKING_DIR_E208/ledger
wget https://api.mainnet-beta.solana.com/genesis.tar.bz2
tar -xvf genesis.tar.bz2 -C $WORKING_DIR_E208/ledger/

# extract rocksdb (will take ~10 minutes; 2 hours if using networked storage)
cd $WORKING_DIR_E208/ledger
pv rocksdb.tar.bz2 | tar -x -I lbzip2 -C ./

# Step 0: Create a snapshot immediately before the gap
# This will take ~10 minutes
alias solana-ledger-tool="$WORKING_DIR_E208/solana-ledger-tool"
sudo sysctl -w vm.max_map_count=1400000
sudo sysctl --system
cd $WORKING_DIR_E208/ledger
solana-ledger-tool create-snapshot --ledger ./ 89856107 ./

# Step I: Recreate shreds for the missing blocks (you will need bigtable credentials)
# You need a service account key for bigtable in JSON format (to the Solana Foundation's bigtable)
# It will be used to fetch the missing blocks.
export GOOGLE_APPLICATION_CREDENTIALS=/solana/e208/bigtable.json
solana-ledger-tool bigtable reconstruct-replayable-blocks --ledger ./ --store-transaction-status --starting-slot 89856107 --ending-slot 89856602 --snapshot-archive-path=$WORKING_DIR_E208/ledger/snapshot-89856107-2Uvbz6becuTbDVLdoUXfYN81wcwR5AxVGLJFbkG5Vy2w.tar.zst

# verify bounds
# should be: slots 89423444 to 89856602
solana-ledger-tool bounds --ledger $WORKING_DIR_E208/ledger

# create a snapshot after the gap
RUST_LOG=solana=info,solana_ledger::blockstore_processor=trace solana-ledger-tool create-snapshot --skip-poh-verify --ledger $WORKING_DIR_E208/ledger 89856602 $WORKING_DIR_E208/ledger/89856602/
# this will generate /solana/e208/ledger/89856602/snapshot-89856602-HZTS2FDwEFJFq3XiX6wHrS2297nsfbfRU69bqFkJDXZk.tar.zst

# Now, we need to take that and use it
---

# get Full State After the Gap
mkdir $WORKING_DIR_E208/ledger-after-gap
cd $WORKING_DIR_E208/ledger-after-gap
aria2c -x 16 -s 16 -d $WORKING_DIR_E208/ledger-after-gap https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89855469/rocksdb.tar.bz2
aria2c -x 16 -s 16 -d $WORKING_DIR_E208/ledger-after-gap https://storage.googleapis.com/mainnet-beta-ledger-us-ny5/89855469/hourly/snapshot-89865552-CWFaiDterTZ1EFQrJkFghnnzERFJNNFT2USBnYTssxsF.tar.zst

pv rocksdb.tar.bz2 | tar -x -I lbzip2 -C ./

# copy genesis file
cp $WORKING_DIR_E208/ledger/genesis.bin $WORKING_DIR_E208/ledger-after-gap/genesis.bin

# verify bounds: should be `Ledger has data for 424529 slots 89856602 to 90288016`
solana-ledger-tool bounds --ledger $WORKING_DIR_E208/ledger-after-gap

# Now we can use the snapshot at 89856602 and the ledger-after-gap to create a new snapshot at 89865552,
# which should have the same hash as the downloaded snapshot-89865552-CWFaiDterTZ1EFQrJkFghnnzERFJNNFT2USBnYTssxsF.tar.zst
solana-ledger-tool create-snapshot \
    --skip-poh-verify \
    --ledger $WORKING_DIR_E208/ledger-after-gap \
    --snapshot-archive-path $WORKING_DIR_E208/ledger/89856602/ \
    89865552 $WORKING_DIR_E208/ledger-after-gap/89865552/

```

After running this process, the `$WORKING_DIR_E208/ledger-after-gap/89865552/` should have a file with the same filename as `snapshot-89865552-CWFaiDterTZ1EFQrJkFghnnzERFJNNFT2USBnYTssxsF.tar.zst`We can verify the filename hash to confirm that the snapshots are identical. We can also extract and validate that the two account states match identically (i.e., have the exact same accounts and account data).&#x20;

{% hint style="info" %}
The two archive files, however, are slightly different in size since the process isn’t precisely reproducible regarding the specific compressed file. If used on the two snapshot-\*.tar.zst files, SHA256SUM will return two different hashes. However, if compared, the contents (account states) are the same.
{% endhint %}


# Sharp Edges

Understanding some of the edge cases with Old Faithful that can cause pain if you're not careful

## Early Epochs

### Protobuf Decoding

Sometime around epoch 157 the `solana-validator` warehousing process changed from `bincode` to `protobuf`.&#x20;

Because this was not an on-chain feature activation and only an internal change, there is no discreet slot boundary where you can expect this transition to occur. It instead relies on when the warehousing process was upgraded to the version that switched to protocol buffers.

The [OF1](/running-old-faithful/sourcing-data/of1) files have this transition at **epoch 157** but this can/will be different for other warehousing systems.

### No Transaction Metadata

Some early epochs contain transactions without these transactions were warehoused by the validator without metadata and thus do not have any associated with them in the Old Faithful archives.

You should not see this occur on epochs above 157.


# RPC Methods

The JSON-RPC API follows the standard Solana RPC API and supports the following methods:

* [getBlock](https://solana.com/docs/rpc/http/getblock)
* [getTransaction](https://solana.com/docs/rpc/http/gettransaction)
* [getSignaturesForAddress](https://solana.com/docs/rpc/http/getsignaturesforaddress)
* [getBlockTime](https://solana.com/docs/rpc/http/getblocktime)
* [getGenesisHash](https://solana.com/docs/rpc/http/getgenesishash) (for epoch 0)
* [getFirstAvailableBlock](https://solana.com/docs/rpc/http/getfirstavailableblock)
* [getSlot](https://solana.com/docs/rpc/http/getslot)
* [getVersion](https://solana.com/docs/rpc/http/getversion)


# gRPC Methods

gRPC supports most methods as the JSON-RPC endpoint - except for gSFA - plus two new streaming methods for transactions and blocks, full list below:

* [getBlock](https://solana.com/docs/rpc/http/getblock)
* [getTransaction](https://solana.com/docs/rpc/http/gettransaction)
* [~~getSignaturesForAddress~~](https://solana.com/docs/rpc/http/getsignaturesforaddress)
* [getBlockTime](https://solana.com/docs/rpc/http/getblocktime)
* [getGenesisHash](https://solana.com/docs/rpc/http/getgenesishash) (for epoch 0)
* [getFirstAvailableBlock](https://solana.com/docs/rpc/http/getfirstavailableblock)
* [getSlot](https://solana.com/docs/rpc/http/getslot)
* [getVersion](https://solana.com/docs/rpc/http/getversion)
* [StreamTransactions](https://docs.old-faithful.net/references/pages/AptwvVXVRgBMBbzs3Y4z#oldfaithful.oldfaithful-streamtransactions)
* [StreamBlocks](https://docs.old-faithful.net/references/pages/AptwvVXVRgBMBbzs3Y4z#oldfaithful.oldfaithful-streamblocks)


# Examples

{% hint style="success" %}

### Token Optional

The `x-token` header is only required if you have enabled it in the configuration or you are accessing a hosted Old Faithful version that requires it.
{% endhint %}

{% hint style="warning" %}

## Protocol File

All `grpcurl` commands require the proto file to be passed. You can find it [here](https://raw.githubusercontent.com/rpcpool/yellowstone-faithful/refs/heads/main/old-faithful-proto/proto/old-faithful.proto).
{% endhint %}

## Unary Methods

Unary commands return a single response. \
\
They are similar to standard JSON-RPC methods, but you can send an arbitrary number of messages over a persistent, bi-direction connection.

### OldFaithful.OldFaithful/GetVersion

```bash
grpcurl \
  -proto old-faithful.proto \
  -d '' \
  -H 'x-token: <redacted-token>' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/GetVersion
```

### OldFaithful.OldFaithful/GetBlockTime

```bash
grpcurl \
  -proto old-faithful.proto \
  -H 'x-token: <redacted-token>' \
  -d '{"slot": 307152000}' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/GetBlockTime
```

### OldFaithful.OldFaithful/GetBlock

```
grpcurl \
  -proto old-faithful.proto \
  -H 'x-token: <redacted-token>' \
  -d '{"slot": 307152000}' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/GetBlock
```

### OldFaithful.OldFaithful/GetTransaction

```
grpcurl \
  -proto old-faithful.proto \
  -H 'x-token: <redacted-token>' \
  -d '{"signature": "GbXoI+D7hhgeiUwovUhtaxog6zsxFcd5PKfhQM85GR6+NqmiFmQDf9cCCVj8BRj+DR1RvgR/E2E/ckbSGuQKCg=="}' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/GetTransaction
```

## Streaming Methods

Streaming methods will stream the response to the client.  These methods allow you to retrieve data in large contiguous chunks, scoped by a `start_slot` and `end_slot` parameter.

Streaming commands also support a filter that will reduce the messages you receive.&#x20;

### OldFaithful.OldFaithful/StreamBlocks

The following filters are available for `StreamBlocks`:

* `account_include`: Array of base58 strings

#### No Filters

```
grpcurl \
  -proto old-faithful.proto \
  -H 'x-token: <redacted-token>' \
  -d '{"start_slot": 307152000, "end_slot": 307152010}' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/StreamBlocks
```

#### Filtered

```
grpcurl \
  -proto old-faithful.proto \
  -H 'x-token: <redacted-token>' \
  -d '{"start_slot": 307152000, "end_slot": 307152010, "filter": {"account_include": ["Vote111111111111111111111111111111111111111"]}}' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/StreamBlocks
```

### OldFaithful.OldFaithful/StreamTransactions

The following filters are available for `StreamTransactions`:

* `vote`: boolean
* `failed` : boolean
* `account_include`: Array of base58 strings
* `account_exclude`: Array of base58 strings
* `account_required`: Array of base58 strings

#### No Filters

```
grpcurl \
  -proto old-faithful.proto \
  -H 'x-token: <redacted-token>' \
  -d '{"start_slot": 307152000, "end_slot": 307152010}' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/StreamTransactions
```

#### Filtered

```
grpcurl \
  -proto old-faithful.proto \
  -H 'x-token: <redacted-token>' \
  -d '{"start_slot": 307152000, "end_slot": 307152010, "filter": {"vote": false, "failed": true}}' \
  customer-endpoint-2608.mainnet.rpcpool.com:443 \
  OldFaithful.OldFaithful/StreamTransactions
```


# CLI Arguments

## Overview

Old Faithful ships with an RPC server that supports [gRPC](/references/grpc-methods) and [JSON-RPC](/references/rpc-methods).&#x20;

## Command line

The RPC server is available via the `faithful-cli rpc` command.

The command accepts a list of [epoch config files](https://github.com/rpcpool/yellowstone-faithful#epoch-configuration-files) and dirs as arguments. Each config file is specific for an epoch and provides the location of the block/transaction data and the indexes for that epoch. The indexes are used to map Solana block numbers, transaction signatures, and addresses to their respective CIDs. The indexes are generated from the CAR file and can be generated via the `faithful-cli index` command (see [Index generation](https://github.com/rpcpool/yellowstone-faithful#index-generation)).

It supports the following flags:

* `--listen`: The address to listen on, e.g. `--listen=:8888`
* `--include`: You can specify one or more (reuse the same flag multiple times) glob patterns to include files or dirs that match them, e.g. `--include=/path/epoch-*.yml`.
* `--exclude`: You can specify one or more (reuse the same flag multiple times) glob patterns to exclude files or dirs that match them, e.g. `--exclude=/something-*/epoch-*.yml`.
* `--debug`: Enable debug logging.
* `--proxy`: Proxy requests to a downstream RPC server if the data can't be found in the archive, e.g. `--proxy=/path/to/my-rpc.json`. See [RPC server proxying](https://github.com/rpcpool/yellowstone-faithful#rpc-server-proxying) for more details.
* `--gsfa-only-signatures`: When enabled, the RPC server will only return signatures for getSignaturesForAddress requests instead of the full transaction data.
* `--watch`: When specified, all the provided epoch files and dirs will be watched for changes, and the RPC server will automatically reload the data when changes are detected. Usage: `--watch` (boolean flag). This is useful when you want to provide just a folder and add new epochs to it without restarting the server.
* `--epoch-load-concurrency=2`: Epochs to load in parallel when starting the RPC server. Defaults to the number of CPUs. This is useful when you have a lot of epochs and want to speed up the initial load time.
* `--max-cache=<megabytes>`: Memory to use for caching. Defaults to 0 (no limit). This is useful when you want to limit the memory usage of the RPC server.


# CAR Report

Triton One produces a CAR Report that can be used to quickly identify what CAR's are availabe in the OF1 archive system.

You can view it here: <https://github.com/rpcpool/yellowstone-faithful/blob/gha-report/docs/CAR-REPORT.md>


# CID Lookup API

{% hint style="info" %}
Support for these endpoints is currently in progress.
{% endhint %}

You can look up CIDs for individual slots or transactions by using our hosted service:

* **Transaction signatures**: **`https://cid.old-faithful.net/api/v1/sig-to-cid/<sig>`**
* **Blocks**: **`https://cid.old-faithful.net/api/v1/slot-to-cid/<slot>`**

If the CID is available, the API will return the CID for the block or transaction.

A HTTP 404 response indicates the transaction or slot is unavailable in Old Faithful.


# OF1 Files

OF1: Old Faithful Reference Archive

## Files

Each epoch is stored at `https://files.old-faithful.net/{EPOCH}/` .&#x20;

This folder contains many files that can be used to assist in running your own Old Faithful installation, or validating the results of your own archives.

{% hint style="success" %}

#### Placeholder Legend

* `{EPOCH}` - Epoch Number (e.g. `0`)
* `{CID}` - Epoch CID (found by retrieving `epoch-{EPOCH}.cid`
  {% endhint %}

```
- epoch-{EPOCH}.car
- epoch-{EPOCH}.sha256
- epoch-{EPOCH}.cid
- {EPOCH}.slots.txt
- {EPOCH}.recap.yaml
- epoch-{EPOCH}-gsfa.index.tar.zstd
- epoch-{EPOCH}-{CID}-mainnet-cid-to-offset-and-size.index
- epoch-{EPOCH}-{CID}-mainnet-sig-exists.index
- epoch-{EPOCH}-{CID}-mainnet-sig-to-cid.index
- epoch-{EPOCH}-{CID}-mainnet-slot-to-blocktime.index
- epoch-{EPOCH}-{CID}-mainnet-slot-to-cid.index
```


