diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 4625c24..953b828 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -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{ diff --git a/internal/orchestrator/chain_tracker.go b/internal/orchestrator/chain_tracker.go new file mode 100644 index 0000000..8489af4 --- /dev/null +++ b/internal/orchestrator/chain_tracker.go @@ -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 +} diff --git a/internal/orchestrator/orchestrator.go b/internal/orchestrator/orchestrator.go index 8e3d477..5168ba2 100644 --- a/internal/orchestrator/orchestrator.go +++ b/internal/orchestrator/orchestrator.go @@ -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() }