This code implements a fast and parallelized indexer of C-chain that fetches data needed for various Flare protocols. It saves the data in a MySQL database.
The indexer is implemented in Go (tested with version 1.24). A running MySQL database to save the data is needed (we provide a docker-compose.yaml file for automatic deployment of a database).
The configuration is read from a toml file. Config file can be specified using the command line parameter --config, e.g., ./flare-cchain-indexer --config config.toml.
The default config file name is config.toml.
Use config.example.toml as the single config template. It includes full mode/indexer/db/chain/logger/timeout examples and comments.
indexer.mode = "fsp": use this when running as part of the FSP provider stack. Required FSP transactions/logs are hardcoded and auto-applied, so you do not need to specify[[indexer.collect_transactions]]or[[indexer.collect_logs]]in config (you can still add extra entries; they are merged and deduplicated). FSP startup also does selective indexing for required reward-epoch metadata windows instead of blindly indexing full historical ranges, which makes startup significantly faster. In this mode,indexer.start_indexanddb.history_dropare ignored; retention is derived fromindexer.history_epochs.indexer.mode = "full": use this for a generic C-chain indexer. In this mode you should define what to index via[[indexer.collect_transactions]]and[[indexer.collect_logs]].
Contracts in [[indexer.collect_transactions]] and [[indexer.collect_logs]] can be specified either by contract_address = "0x..." or by contract_name = "FlareSystemsManager". When a name is provided, the indexer resolves it to an address at startup via the on-chain ContractRegistry, so addresses that differ across networks (or change between deployments) do not need to be hardcoded in config. FSP mode's built-in collectors all use name-based resolution.
The behavior described in this section applies to full mode only. FSP mode derives its start block and retention from indexer.history_epochs, and ignores both indexer.start_index and db.history_drop.
If the C chain indexer has been previously run and there is existing data in the database,
subsequent runs will resume indexing from after the last indexed block. Only when starting with an
empty database will the indexer have to decide where to start. Normally this will be based on the
history drop configuration parameter - if the history drop is 14 days for example then the indexer
will start indexing from the block that was mined 14 days ago. If the history drop is disabled (set
to 0) then the indexer will start from the configured start_index block or from block 0 if not
set.
In case the indexer has been previously run and you need more historical data, you can increase
the history drop parameter or disable history drop and set the start_index to the desired
starting block. You can manually delete all existing data from the database in order to trigger
re-indexing from the new starting block. You can also set the drop_table_at_start parameter to
true to have the indexer drop existing tables at startup and force re-indexing - though remember to
set it back to false afterwards to avoid losing data on subsequent runs.
In internal/database/docker we provide a simple database. Navigate to the folder and run
docker-compose upSimply run
go run ./cmd/indexer --config config.tomlor build and run the binaries with
go build -o flare-cchain-indexer ./cmd/indexer
./flare-cchain-indexer --config config.tomlThe indexer exposes GET /health on port 8080.
- Returns
503while startup catchup/backfill is still running. - Returns
200after startup is complete and the indexer has entered continuous indexing mode.
Example:
curl -i http://localhost:8080/healthThere is an integration test which checks the historical indexing against known transactions and
logs on Coston2. To run this test you will need a MySQL server and a Coston2 node, preferably one that is not rate-limited.
The integration test is configured via test/config_test.toml. You can execute it with:
$ go test ./cmd/indexerAdditionally, a mocked-chain integration test is available in test/indexer_test.go. It uses test/config_test.toml for configuration. You can run it using:
go test ./testTo run tests with coverage analysis across all packages, save the results to coverage.out, and convert the report into an interactive HTML file run:
go test -v -coverpkg=./... -coverprofile=coverage.out ./...
go tool cover -html=coverage.outFile benchmarks/songbird_test.go contains a benchmark test for indexing the FTSO protocol on the Songbird network. It processes 10,000 blocks and analyzes them. The test configuration is specified in benchmarks/config_benchmark.toml. To run the benchmark (replacing 10x with any desired number of repetitions), use:
go test -benchmem -run=^$ -benchtime 10x -bench ^BenchmarkBlockRequests$ ./benchmarks