Skip to content

iotexproject/iotex-analyser

Repository files navigation

IoTeX Analyser

License: Apache 2.0 Go Report Card Latest Release Docker Image

IoTeX Analyser indexes data from the IoTeX blockchain into the database of your choice (PostgreSQL, MySQL, SQLite, ClickHouse) and exposes it for downstream querying — including a managed GraphQL endpoint via Hasura.

It is built around a dynamic plugin system: indexing logic ships as Go plugins (.so files) that can be loaded and unloaded at runtime, with no service restart. A growing library of 58+ built-in plugins covers common needs (blocks, actions, ERC20/721/1155, staking, rewards, gas tracking, account income, …), and you can drop in your own.

Technical architecture


Table of Contents


Quick Start

The fastest way to try Analyser is via Docker Compose, which provisions both Postgres and the Analyser service:

docker-compose up

To use a prebuilt image directly:

docker pull ghcr.io/iotexproject/iotex-analyser:latest

Available image tags:

  • :latest — latest tagged release (recommended)
  • :vX.Y.Z — pinned release version
  • :main — bleeding edge from main
  • :sha-<short> — exact commit

Configuration

Analyser is configured via a YAML file. A minimal config.yml:

server:
  # Plugins to load on startup
  plugins:
    - block.so

database:
  driver: postgres        # postgres | mysql | sqlite3 | clickhouse
  host: 127.0.0.1
  port: 5432
  user: postgres
  password: ${DB_PASSWORD}
  name: iotex

iotex:
  chainEndPoint: api.iotex.one:80   # mainnet (use api.testnet.iotex.one:80 for testnet)

blockDB:
  dbPath: chain.db

log:
  zap:
    level: info

Note: Never commit real credentials. Use environment variable substitution (${VAR}) or a separate untracked config file.

Bootstrapping with a Snapshot

Indexing from genesis takes time. Speed it up with a pre-indexed chain.db snapshot:

Drop the file at the path referenced by blockDB.dbPath and Analyser will resume from the snapshot.


Building from Source

Requirements

  • Go 1.23+
  • make
  • A working C linker (plugins use -buildmode=plugin, which requires glibc — Alpine without gcompat won't work for local builds)

Build

Clone and build the binary plus all plugins:

git clone https://github.com/iotexproject/iotex-analyser.git
cd iotex-analyser
make            # binary + every plugin under plugins/

Or build individual targets:

make build              # binary only
make plugin name=block  # one plugin (produces block.so)
make dev                # binary + all plugins with -race for development

Running the Server

Start the server:

./iotex-analyser -c config.yml server

Manage plugins at runtime via a second process (the running server picks up changes automatically):

./iotex-analyser -c config.yml plugin load   simple.so
./iotex-analyser -c config.yml plugin unload simple.so
./iotex-analyser -c config.yml plugin info

Plugin System

Each plugin is a Go package compiled to a .so file with -buildmode=plugin, exposing a single Plugin variable that satisfies the Adapter interface:

type Adapter interface {
    Name() string
    Version() string
    Type() Type
    Start(context.Context) error
    Stop(context.Context) error
    PutBlock(context.Context, *block.Block) error
}

For better throughput, plugins may also implement PutBlocks(ctx, []*block.Block) error to process blocks in batches.

Writing a Plugin

package main

import (
    "context"
    "fmt"

    "github.com/iotexproject/iotex-analyser/db"
    "github.com/iotexproject/iotex-analyser/plugin"
    "github.com/iotexproject/iotex-core/v2/blockchain/block"
)

type simplePlugin struct{}

func (simplePlugin) Name() string         { return "simple" }
func (simplePlugin) Version() string      { return "0.0.1" }
func (simplePlugin) Type() plugin.Type    { return plugin.TypeStandard }
func (simplePlugin) Start(context.Context) error { return nil }
func (simplePlugin) Stop(context.Context) error  { return nil }

func (s simplePlugin) PutBlock(ctx context.Context, blk *block.Block) error {
    fmt.Printf("block height: %d\n", blk.Height())
    return db.UpdateIndexHeight(s.Name(), blk.Height())
}

// Exported symbol — must be named "Plugin".
var Plugin = simplePlugin{}

Build it:

make plugin name=simple

Loading and Unloading at Runtime

./iotex-analyser -c config.yml plugin load   simple.so
./iotex-analyser -c config.yml plugin unload simple.so

After load, you should see output from your plugin in the server logs, e.g.:

block height: 1
block height: 2
block height: 3

Built-in Plugins

A non-exhaustive sample — see plugins/ for the full list:


GraphQL API

Hasura sits in front of the indexed Postgres database and serves a GraphQL API automatically.


Releases

Releases are cut manually using release.sh:

./release.sh v1.18.1

The script validates the working tree, tags the commit, pushes the tag, and creates a GitHub Release with auto-generated notes. The tag push triggers GitHub Actions to build and publish the Docker image as both :vX.Y.Z and :latest on ghcr.io.


Contributing

Contributions are welcome. The general flow:

  1. Open an issue to discuss non-trivial changes before starting work.
  2. Fork and create a feature branch.
  3. Add tests for new functionality where possible.
  4. Open a PR against main.

Useful commands while developing:

make dev          # build with -race for local testing
go test ./...     # run unit tests

License

Apache License 2.0 — see LICENSE.

About

async analyser for iotex

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages