ethindexer

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2026 License: MIT Imports: 17 Imported by: 0

README

ethindexer

CI Go Reference

ethindexer is a lightweight Go library for indexing Ethereum logs.

It handles backfilling, live indexing, checkpointing, reorg recovery, and resumable restarts. Applications only need to provide state with a Process method.

Install

go get github.com/LeTamanoir/ethindexer

Usage

See examples/weth for a complete example.

How it works

The first call to Process restores the latest finalized checkpoint when one exists, then backfills through the supplied target. Pass a nil target to use the node's latest head.

Each subsequent target is checked against the indexed head. Gaps use block-range queries through the finalized head and reorg-safe block-hash queries afterward. On a parent hash mismatch, the indexer restores the finalized checkpoint and replays the canonical chain.

Start block               Finalized block           Staged      Latest
     |                          |                     |           |
     S --------[...]----------- F ------------------- S --------- L
                                  <- FinalityDepth ->

The indexer keeps two checkpoints:

  • Finalized (F): durable restart point.
  • Staged (S): pending checkpoint promoted once it is old enough.

This lets the indexer resume quickly while avoiding committing state that may still be affected by reorgs.

Indexing state

State must provide a Process method:

func (s *State) Process(ctx context.Context, logs []types.Log) error
state := &WETH{
    Balances:   make(map[common.Address]uint256.Int),
    Allowances: make(map[common.Address]map[common.Address]uint256.Int),
}

idx := &ethindexer.Indexer[*WETH]{
    Client:    client,
    DataDir:   ".ethindexer",
    FromBlock: deploymentBlock,
    Filter: ethindexer.Filter{
        Addresses: []common.Address{contractAddress},
    },
    State: state,
}
if err := idx.Process(ctx, nil); err != nil {
    return err
}

State is automatically encoded into checkpoints with encoding/gob. It must be a pointer so checkpoints can restore it in place. Its persisted fields must be gob-compatible; state with custom serialization requirements can implement gob.GobEncoder and gob.GobDecoder.

Applications that need custom initialization can use HasCheckpoint before calling Process:

hasCheckpoint, err := idx.HasCheckpoint()
if err != nil {
    return err
}
if !hasCheckpoint {
    if err := state.Init(ctx); err != nil {
        return err
    }
}

CachedFilterLogs is available for explicit historical block-range queries and caches results in DataDir. ClearCheckpoint removes finalized and staged checkpoints while preserving those cached ranges.

FromBlock and Filter define the indexed log stream. Tunables such as FinalityDepth, MaxBlockRange, CheckpointInterval, and MaxConcurrency are configured directly on Indexer.

Development

just check
go test ./...

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BlockRange added in v0.4.0

type BlockRange struct {
	From uint64
	To   uint64
}

BlockRange is an inclusive block range.

func ChunkBlockRange added in v0.4.0

func ChunkBlockRange(from, to, size uint64) []BlockRange

ChunkBlockRange splits the inclusive block range [from, to] into ranges containing at most size blocks.

type ChainReader

type ChainReader interface {
	FilterLogs(context.Context, ethereum.FilterQuery) ([]types.Log, error)
	HeaderByNumber(context.Context, *big.Int) (*types.Header, error)
}

ChainReader provides access to Ethereum logs and block headers.

type Filter

type Filter struct {
	// Addresses restrict logs to the given contract addresses.
	// See [ethereum.FilterQuery.Addresses].
	Addresses []common.Address

	// Topics restrict logs by indexed event topics.
	// See [ethereum.FilterQuery.Topics].
	Topics [][]common.Hash
}

Filter specifies which logs the indexer fetches.

type Indexer

type Indexer[S State] struct {
	// Client provides access to Ethereum logs and block headers.
	Client ChainReader

	// DataDir stores checkpoints and cached log batches.
	DataDir string

	// FromBlock is the first block to index.
	FromBlock uint64

	// Filter specifies which logs the indexer fetches.
	Filter Filter

	// LogFunc receives indexer log events.
	LogFunc func(msg string, args ...any)

	// MaxBlockRange is the maximum block span per backfill request.
	MaxBlockRange uint64

	// FinalityDepth is the block depth considered finalized.
	FinalityDepth uint64

	// CheckpointInterval is the minimum number of blocks between staged checkpoints.
	CheckpointInterval uint64

	// MaxConcurrency bounds concurrent header fetches.
	MaxConcurrency int

	// State receives matching logs and is persisted in checkpoints with
	// encoding/gob. It must be a pointer so checkpoints can restore it in place.
	State S
	// contains filtered or unexported fields
}

Indexer indexes Ethereum logs into State from a finalized block onward, handling reorgs and gob-encoded checkpoints.

func (*Indexer[S]) CachedFilterLogs added in v0.4.0

func (i *Indexer[S]) CachedFilterLogs(ctx context.Context, f Filter, r BlockRange) ([]types.Log, error)

CachedFilterLogs returns logs matching filter in the inclusive block range, using the cache in DataDir when available.

func (*Indexer[S]) ClearCheckpoint added in v0.4.0

func (i *Indexer[S]) ClearCheckpoint() error

ClearCheckpoint removes finalized and staged checkpoints from DataDir while preserving cached log ranges.

func (*Indexer[S]) HasCheckpoint added in v0.4.0

func (i *Indexer[S]) HasCheckpoint() (bool, error)

HasCheckpoint reports whether a finalized checkpoint exists in DataDir.

func (*Indexer[S]) Process

func (i *Indexer[S]) Process(ctx context.Context, h *types.Header) error

Process ingests a target head, restoring State on its first call. A nil head selects the node's latest head.

type State added in v0.4.0

type State interface {
	Process(context.Context, []types.Log) error
}

State processes Ethereum logs into checkpointed application state.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL