diff --git a/indexer/indexer.go b/indexer/indexer.go index aaf9a1cb..94d9aa6a 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -254,18 +254,38 @@ func (indexer *Indexer) runIndexer() { defer indexer.runMutex.Unlock() for { + runIndexerLoop := true + genesis, err := indexer.rpcClient.GetGenesis() if err != nil { logger.Errorf("Indexer Error while fetching genesis: %v", err) + runIndexerLoop = false } else if genesis != nil { genesisTime := uint64(genesis.Data.GenesisTime) if genesisTime != utils.Config.Chain.GenesisTimestamp { logger.Warnf("Genesis time from RPC does not match the genesis time from explorer configuration.") + runIndexerLoop = false } if genesis.Data.GenesisForkVersion.String() != utils.Config.Chain.Config.GenesisForkVersion { logger.Warnf("Genesis fork version from RPC does not match the genesis fork version explorer configuration.") + runIndexerLoop = false } + } + + if runIndexerLoop { + syncStatus, err := indexer.rpcClient.GetNodeSyncing() + if err != nil { + logger.Errorf("Indexer Error while fetching syncing status: %v", err) + runIndexerLoop = false + } else if syncStatus != nil { + if syncStatus.Data.IsSyncing { + logger.Errorf("Cannot run indexer, beacon node is synchronizing.") + runIndexerLoop = false + } + } + } + if runIndexerLoop { err := indexer.runIndexerLoop() if err == nil { break diff --git a/rpc/beaconapi.go b/rpc/beaconapi.go index 8cfb827f..c69d54b3 100644 --- a/rpc/beaconapi.go +++ b/rpc/beaconapi.go @@ -109,6 +109,24 @@ func (bc *BeaconClient) GetGenesis() (*rpctypes.StandardV1GenesisResponse, error return &parsedGenesis, nil } +func (bc *BeaconClient) GetNodeSyncing() (*rpctypes.StandardV1NodeSyncingResponse, error) { + resGenesis, err := bc.get(fmt.Sprintf("%s/eth/v1/node/syncing", bc.endpoint)) + if err != nil { + if err == errNotFound { + // no block found + return nil, nil + } + return nil, fmt.Errorf("error retrieving syncing status: %v", err) + } + + var parsedSyncingStatus rpctypes.StandardV1NodeSyncingResponse + err = json.Unmarshal(resGenesis, &parsedSyncingStatus) + if err != nil { + return nil, fmt.Errorf("error parsing syncing status response: %v", err) + } + return &parsedSyncingStatus, nil +} + func (bc *BeaconClient) GetLatestBlockHead() (*rpctypes.StandardV1BeaconHeaderResponse, error) { resHeaders, err := bc.get(fmt.Sprintf("%s/eth/v1/beacon/headers/head", bc.endpoint)) if err != nil { diff --git a/rpctypes/beaconapi.go b/rpctypes/beaconapi.go index e7becf53..aaa8b8e7 100644 --- a/rpctypes/beaconapi.go +++ b/rpctypes/beaconapi.go @@ -93,3 +93,13 @@ type StandardV1GenesisResponse struct { type StandardV1BlobSidecarsResponse struct { Data []BlobSidecar `json:"data"` } + +type StandardV1NodeSyncingResponse struct { + Data struct { + HeadSlot Uint64Str `json:"head_slot"` + SyncDistance Uint64Str `json:"sync_distance"` + IsSyncing bool `json:"is_syncing"` + IsOptimistic bool `json:"is_optimistic"` + ElOffline bool `json:"el_offline"` + } `json:"data"` +}