Skip to content

Commit

Permalink
Add chain tracker to track chain head (#77)
Browse files Browse the repository at this point in the history
### TL;DR

Implemented a ChainTracker to monitor and report the latest block number in the current chain.

### What changed?

- Added a new `ChainHead` metric in `metrics.go` to track the latest block number.
- Created a new `chain_tracker.go` file with a `ChainTracker` struct and associated methods.
- The `ChainTracker` polls the RPC at regular intervals to fetch the latest block number.
- Updated the `Orchestrator` to start the `ChainTracker` alongside other components.

### How to test?

1. Run the indexer with the new changes.
2. Monitor the `chain_tracker_chain_head` metric using Prometheus or a similar monitoring tool.
3. Verify that the metric is updating at regular intervals (default: every 5 minutes).
4. Compare the reported chain head with the actual latest block number on the blockchain to ensure accuracy.

### Why make this change?

This change allows for real-time tracking of the blockchain's progress, providing valuable information about the current state of the chain. This can be useful for:

1. Monitoring the health of the blockchain network.
2. Detecting potential network issues or delays.
3. Providing context for other indexer operations and metrics.
4. Enabling more accurate synchronization and data consistency checks.
  • Loading branch information
AmineAfia authored Oct 1, 2024
1 parent a2bd508 commit 0b38f8a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
8 changes: 8 additions & 0 deletions internal/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ var LastFetchedBlock = promauto.NewGauge(prometheus.GaugeOpts{
Help: "The last block number fetched by the worker from the RPC",
})

// ChainTracker Metrics
var (
ChainHead = promauto.NewGauge(prometheus.GaugeOpts{
Name: "chain_tracker_chain_head",
Help: "The latest block number in the current chain",
})
)

// Poller metrics
var (
PolledBatchSize = promauto.NewGauge(prometheus.GaugeOpts{
Expand Down
53 changes: 53 additions & 0 deletions internal/orchestrator/chain_tracker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package orchestrator

import (
"context"
"time"

"github.com/rs/zerolog/log"
"github.com/thirdweb-dev/indexer/internal/common"
"github.com/thirdweb-dev/indexer/internal/metrics"
)

const DEFAULT_CHAIN_TRACKER_POLL_INTERVAL = 300000 // 5 minutes

type ChainTracker struct {
rpc common.RPC
triggerIntervalMs int
}

func NewChainTracker(rpc common.RPC) *ChainTracker {

return &ChainTracker{
rpc: rpc,
triggerIntervalMs: DEFAULT_CHAIN_TRACKER_POLL_INTERVAL,
}
}

func (ct *ChainTracker) Start() {
interval := time.Duration(ct.triggerIntervalMs) * time.Millisecond
ticker := time.NewTicker(interval)

log.Debug().Msgf("Chain tracker running")
go func() {
for range ticker.C {
latestBlockNumber, err := ct.getLatestBlockNumber()
if err != nil {
log.Error().Err(err).Msg("Error getting latest block number")
continue
}
metrics.ChainHead.Set(float64(latestBlockNumber) / 100)
}
}()

// Keep the program running (otherwise it will exit)
select {}
}

func (ct *ChainTracker) getLatestBlockNumber() (uint64, error) {
blockNumber, err := ct.rpc.EthClient.BlockNumber(context.Background())
if err != nil {
return 0, err
}
return blockNumber, nil
}
8 changes: 8 additions & 0 deletions internal/orchestrator/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,13 @@ func (o *Orchestrator) Start() {
}()
}

// The chain tracker is always running
wg.Add(1)
go func() {
defer wg.Done()
chainTracker := NewChainTracker(o.rpc)
chainTracker.Start()
}()

wg.Wait()
}

0 comments on commit 0b38f8a

Please sign in to comment.