diff --git a/packages/codegen/src/templates/indexer-template.handlebars b/packages/codegen/src/templates/indexer-template.handlebars index 17512faa7..1983f6f73 100644 --- a/packages/codegen/src/templates/indexer-template.handlebars +++ b/packages/codegen/src/templates/indexer-template.handlebars @@ -8,7 +8,7 @@ import debug from 'debug'; {{#if queries}} import JSONbig from 'json-bigint'; {{/if}} -import { ethers } from 'ethers'; +import { ethers, constants } from 'ethers'; {{#if (subgraphPath)}} import { SelectionNode } from 'graphql'; {{/if}} @@ -493,7 +493,11 @@ export class Indexer implements IndexerInterface { return this._db.getStateSyncStatus(); } - async updateStateSyncStatusIndexedBlock (blockNumber: number, force?: boolean): Promise { + async updateStateSyncStatusIndexedBlock (blockNumber: number, force?: boolean): Promise { + if (!this._serverConfig.enableState) { + return; + } + const dbTx = await this._db.createTransactionRunner(); let res; @@ -527,10 +531,14 @@ export class Indexer implements IndexerInterface { return res; } - async getLatestCanonicalBlock (): Promise { + async getLatestCanonicalBlock (): Promise { const syncStatus = await this.getSyncStatus(); assert(syncStatus); + if (syncStatus.latestCanonicalBlockHash === constants.HashZero) { + return; + } + const latestCanonicalBlock = await this.getBlockProgress(syncStatus.latestCanonicalBlockHash); assert(latestCanonicalBlock); diff --git a/packages/graph-node/test/utils/indexer.ts b/packages/graph-node/test/utils/indexer.ts index 9992e9639..41d469f50 100644 --- a/packages/graph-node/test/utils/indexer.ts +++ b/packages/graph-node/test/utils/indexer.ts @@ -189,16 +189,16 @@ export class Indexer implements IndexerInterface { return undefined; } - async updateStateSyncStatusIndexedBlock (blockNumber: number, force?: boolean): Promise { - return {} as StateSyncStatusInterface; + async updateStateSyncStatusIndexedBlock (blockNumber: number, force?: boolean): Promise { + return undefined; } async updateStateSyncStatusCheckpointBlock (blockNumber: number, force?: boolean): Promise { return {} as StateSyncStatusInterface; } - async getLatestCanonicalBlock (): Promise { - return {} as BlockProgressInterface; + async getLatestCanonicalBlock (): Promise { + return undefined; } isWatchedContract (address : string): ContractInterface | undefined { diff --git a/packages/util/src/common.ts b/packages/util/src/common.ts index 0a430ee25..150c597f4 100644 --- a/packages/util/src/common.ts +++ b/packages/util/src/common.ts @@ -321,7 +321,7 @@ export const processEvents = async (indexer: IndexerInterface, block: BlockProgr // We might not have parsed this event yet. This can happen if the contract was added // as a result of a previous event in the same block. if (event.eventName === UNKNOWN_EVENT_NAME) { - const logObj = JSON.parse(event.extraInfo); + const logObj = JSONbigNative.parse(event.extraInfo); assert(indexer.parseEventNameAndArgs); assert(typeof watchedContract !== 'boolean'); @@ -422,7 +422,7 @@ export const processEventsInSubgraphOrder = async (indexer: IndexerInterface, bl // We might not have parsed this event yet. This can happen if the contract was added // as a result of a previous event in the same block. if (event.eventName === UNKNOWN_EVENT_NAME) { - const logObj = JSON.parse(event.extraInfo); + const logObj = JSONbigNative.parse(event.extraInfo); assert(indexer.parseEventNameAndArgs); assert(typeof watchedContract !== 'boolean'); @@ -481,12 +481,11 @@ export const createPruningJob = async (jobQueue: JobQueue, latestCanonicalBlockN * @param blockHash * @param blockNumber */ -export const createHooksJob = async (jobQueue: JobQueue, blockHash: string, blockNumber: number): Promise => { +export const createHooksJob = async (jobQueue: JobQueue, blockHash: string): Promise => { await jobQueue.pushJob( QUEUE_HOOKS, { - blockHash, - blockNumber + blockHash } ); }; diff --git a/packages/util/src/job-runner.ts b/packages/util/src/job-runner.ts index c476faf81..9cc90e1bb 100644 --- a/packages/util/src/job-runner.ts +++ b/packages/util/src/job-runner.ts @@ -112,7 +112,12 @@ export class JobRunner { // Create a hooks job for parent block of latestCanonicalBlock pruning for first block is skipped as it is assumed to be a canonical block. const latestCanonicalBlock = await this._indexer.getLatestCanonicalBlock(); - await createHooksJob(this.jobQueue, latestCanonicalBlock.parentHash, latestCanonicalBlock.blockNumber - 1); + + // Check if latestCanonicalBlock is undefined incase of null block in FEVM + if (latestCanonicalBlock) { + await createHooksJob(this.jobQueue, latestCanonicalBlock.parentHash); + } + break; } @@ -145,16 +150,19 @@ export class JobRunner { } async processHooks (job: any): Promise { - const { data: { blockHash, blockNumber } } = job; + // Get the block and current stateSyncStatus. + const [blockProgress, stateSyncStatus] = await Promise.all([ + this._indexer.getBlockProgress(job.data.blockHash), + this._indexer.getStateSyncStatus() + ]); - // Get the current stateSyncStatus. - const stateSyncStatus = await this._indexer.getStateSyncStatus(); + assert(blockProgress); + const { blockHash, blockNumber, parentHash } = blockProgress; if (stateSyncStatus) { if (stateSyncStatus.latestIndexedBlockNumber < (blockNumber - 1)) { // Create hooks job for parent block. - const [parentBlock] = await this._indexer.getBlocksAtHeight(blockNumber - 1, false); - await createHooksJob(this.jobQueue, parentBlock.blockHash, parentBlock.blockNumber); + await createHooksJob(this.jobQueue, parentHash); const message = `State for blockNumber ${blockNumber - 1} not indexed yet, aborting`; log(message); @@ -186,32 +194,33 @@ export class JobRunner { // Get the current stateSyncStatus. const stateSyncStatus = await this._indexer.getStateSyncStatus(); - assert(stateSyncStatus); - if (stateSyncStatus.latestCheckpointBlockNumber >= 0) { - if (stateSyncStatus.latestCheckpointBlockNumber < (blockNumber - 1)) { - // Create a checkpoint job for parent block. - const [parentBlock] = await this._indexer.getBlocksAtHeight(blockNumber - 1, false); - await createCheckpointJob(this.jobQueue, parentBlock.blockHash, parentBlock.blockNumber); + if (stateSyncStatus) { + if (stateSyncStatus.latestCheckpointBlockNumber >= 0) { + if (stateSyncStatus.latestCheckpointBlockNumber < (blockNumber - 1)) { + // Create a checkpoint job for parent block. + const [parentBlock] = await this._indexer.getBlocksAtHeight(blockNumber - 1, false); + await createCheckpointJob(this.jobQueue, parentBlock.blockHash, parentBlock.blockNumber); - const message = `Checkpoints for blockNumber ${blockNumber - 1} not processed yet, aborting`; - log(message); + const message = `Checkpoints for blockNumber ${blockNumber - 1} not processed yet, aborting`; + log(message); - throw new Error(message); - } + throw new Error(message); + } - if (stateSyncStatus.latestCheckpointBlockNumber > (blockNumber - 1)) { - log(`Checkpoints for blockNumber ${blockNumber} already processed`); + if (stateSyncStatus.latestCheckpointBlockNumber > (blockNumber - 1)) { + log(`Checkpoints for blockNumber ${blockNumber} already processed`); - return; + return; + } } - } - // Process checkpoints for the given block. - await this._indexer.processCheckpoint(blockHash); + // Process checkpoints for the given block. + await this._indexer.processCheckpoint(blockHash); - // Update the stateSyncStatus. - await this._indexer.updateStateSyncStatusCheckpointBlock(blockNumber); + // Update the stateSyncStatus. + await this._indexer.updateStateSyncStatusCheckpointBlock(blockNumber); + } await this.jobQueue.markComplete(job); } diff --git a/packages/util/src/types.ts b/packages/util/src/types.ts index 84f331e83..839e41814 100644 --- a/packages/util/src/types.ts +++ b/packages/util/src/types.ts @@ -91,7 +91,7 @@ export interface IndexerInterface { getStateSyncStatus (): Promise getBlocks (blockFilter: { blockHash?: string, blockNumber?: number }): Promise getBlocksAtHeight (height: number, isPruned: boolean): Promise - getLatestCanonicalBlock (): Promise + getLatestCanonicalBlock (): Promise getLatestStateIndexedBlock (): Promise getBlockEvents (blockHash: string, where: Where, queryOptions: QueryOptions): Promise> getAncestorAtDepth (blockHash: string, depth: number): Promise @@ -102,7 +102,7 @@ export interface IndexerInterface { updateSyncStatusChainHead (blockHash: string, blockNumber: number, force?: boolean): Promise updateSyncStatusIndexedBlock (blockHash: string, blockNumber: number, force?: boolean): Promise updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force?: boolean): Promise - updateStateSyncStatusIndexedBlock (blockNumber: number, force?: boolean): Promise + updateStateSyncStatusIndexedBlock (blockNumber: number, force?: boolean): Promise updateStateSyncStatusCheckpointBlock (blockNumber: number, force?: boolean): Promise markBlocksAsPruned (blocks: BlockProgressInterface[]): Promise saveEventEntity (dbEvent: EventInterface): Promise