From c2070a80cb0d60c35747307720e4b3394a08c2c3 Mon Sep 17 00:00:00 2001 From: Nabarun Gogoi Date: Fri, 17 Nov 2023 11:58:43 +0530 Subject: [PATCH] Handle null block error in rpc-eth-client (#477) * Remove block-size-cache util methods as full block with size fetched already * Handle null block error in rpc-eth-client * Upgrade package versions --- lerna.json | 2 +- packages/cache/package.json | 2 +- packages/cli/package.json | 12 +-- packages/codegen/package.json | 4 +- .../src/templates/package-template.handlebars | 10 +-- packages/graph-node/package.json | 10 +-- packages/ipld-eth-client/package.json | 6 +- packages/peer/package.json | 2 +- packages/rpc-eth-client/package.json | 8 +- packages/rpc-eth-client/src/eth-client.ts | 34 +++++--- packages/solidity-mapper/package.json | 2 +- packages/test/package.json | 2 +- packages/tracing-client/package.json | 2 +- packages/util/package.json | 8 +- packages/util/src/block-size-cache.ts | 81 ------------------- packages/util/src/common.ts | 63 +++++++-------- packages/util/src/constants.ts | 2 - packages/util/src/fill.ts | 7 +- packages/util/src/index-block.ts | 12 +-- packages/util/src/indexer.ts | 8 +- packages/util/src/job-runner.ts | 30 ++++--- packages/util/src/types.ts | 4 +- 22 files changed, 119 insertions(+), 192 deletions(-) delete mode 100644 packages/util/src/block-size-cache.ts diff --git a/lerna.json b/lerna.json index 22025c81..13fda4e8 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "0.2.72", + "version": "0.2.73", "npmClient": "yarn", "useWorkspaces": true, "command": { diff --git a/packages/cache/package.json b/packages/cache/package.json index e32dcfb2..4bd9ebbb 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/cache", - "version": "0.2.72", + "version": "0.2.73", "description": "Generic object cache", "main": "dist/index.js", "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index d4a9b927..acec0b58 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/cli", - "version": "0.2.72", + "version": "0.2.73", "main": "dist/index.js", "license": "AGPL-3.0", "scripts": { @@ -12,13 +12,13 @@ }, "dependencies": { "@apollo/client": "^3.7.1", - "@cerc-io/cache": "^0.2.72", - "@cerc-io/ipld-eth-client": "^0.2.72", + "@cerc-io/cache": "^0.2.73", + "@cerc-io/ipld-eth-client": "^0.2.73", "@cerc-io/libp2p": "^0.42.2-laconic-0.1.4", "@cerc-io/nitro-node": "^0.1.15", - "@cerc-io/peer": "^0.2.72", - "@cerc-io/rpc-eth-client": "^0.2.72", - "@cerc-io/util": "^0.2.72", + "@cerc-io/peer": "^0.2.73", + "@cerc-io/rpc-eth-client": "^0.2.73", + "@cerc-io/util": "^0.2.73", "@ethersproject/providers": "^5.4.4", "@graphql-tools/utils": "^9.1.1", "@ipld/dag-cbor": "^8.0.0", diff --git a/packages/codegen/package.json b/packages/codegen/package.json index 3bfc1f94..4ee26d56 100644 --- a/packages/codegen/package.json +++ b/packages/codegen/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/codegen", - "version": "0.2.72", + "version": "0.2.73", "description": "Code generator", "private": true, "main": "index.js", @@ -20,7 +20,7 @@ }, "homepage": "https://github.com/cerc-io/watcher-ts#readme", "dependencies": { - "@cerc-io/util": "^0.2.72", + "@cerc-io/util": "^0.2.73", "@graphql-tools/load-files": "^6.5.2", "@poanet/solidity-flattener": "https://github.com/vulcanize/solidity-flattener.git", "@solidity-parser/parser": "^0.13.2", diff --git a/packages/codegen/src/templates/package-template.handlebars b/packages/codegen/src/templates/package-template.handlebars index f29018ce..79631a65 100644 --- a/packages/codegen/src/templates/package-template.handlebars +++ b/packages/codegen/src/templates/package-template.handlebars @@ -41,12 +41,12 @@ "homepage": "https://github.com/cerc-io/watcher-ts#readme", "dependencies": { "@apollo/client": "^3.3.19", - "@cerc-io/cli": "^0.2.72", - "@cerc-io/ipld-eth-client": "^0.2.72", - "@cerc-io/solidity-mapper": "^0.2.72", - "@cerc-io/util": "^0.2.72", + "@cerc-io/cli": "^0.2.73", + "@cerc-io/ipld-eth-client": "^0.2.73", + "@cerc-io/solidity-mapper": "^0.2.73", + "@cerc-io/util": "^0.2.73", {{#if (subgraphPath)}} - "@cerc-io/graph-node": "^0.2.72", + "@cerc-io/graph-node": "^0.2.73", {{/if}} "@ethersproject/providers": "^5.4.4", "debug": "^4.3.1", diff --git a/packages/graph-node/package.json b/packages/graph-node/package.json index 40e2f332..97a56518 100644 --- a/packages/graph-node/package.json +++ b/packages/graph-node/package.json @@ -1,10 +1,10 @@ { "name": "@cerc-io/graph-node", - "version": "0.2.72", + "version": "0.2.73", "main": "dist/index.js", "license": "AGPL-3.0", "devDependencies": { - "@cerc-io/solidity-mapper": "^0.2.72", + "@cerc-io/solidity-mapper": "^0.2.73", "@ethersproject/providers": "^5.4.4", "@graphprotocol/graph-ts": "^0.22.0", "@nomiclabs/hardhat-ethers": "^2.0.2", @@ -51,9 +51,9 @@ "dependencies": { "@apollo/client": "^3.3.19", "@cerc-io/assemblyscript": "0.19.10-watcher-ts-0.1.2", - "@cerc-io/cache": "^0.2.72", - "@cerc-io/ipld-eth-client": "^0.2.72", - "@cerc-io/util": "^0.2.72", + "@cerc-io/cache": "^0.2.73", + "@cerc-io/ipld-eth-client": "^0.2.73", + "@cerc-io/util": "^0.2.73", "@types/json-diff": "^0.5.2", "@types/yargs": "^17.0.0", "bn.js": "^4.11.9", diff --git a/packages/ipld-eth-client/package.json b/packages/ipld-eth-client/package.json index 63a888d9..bce118ce 100644 --- a/packages/ipld-eth-client/package.json +++ b/packages/ipld-eth-client/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/ipld-eth-client", - "version": "0.2.72", + "version": "0.2.73", "description": "IPLD ETH Client", "main": "dist/index.js", "scripts": { @@ -20,8 +20,8 @@ "homepage": "https://github.com/cerc-io/watcher-ts#readme", "dependencies": { "@apollo/client": "^3.7.1", - "@cerc-io/cache": "^0.2.72", - "@cerc-io/util": "^0.2.72", + "@cerc-io/cache": "^0.2.73", + "@cerc-io/util": "^0.2.73", "cross-fetch": "^3.1.4", "debug": "^4.3.1", "ethers": "^5.4.4", diff --git a/packages/peer/package.json b/packages/peer/package.json index 9ec6717d..32351e0a 100644 --- a/packages/peer/package.json +++ b/packages/peer/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/peer", - "version": "0.2.72", + "version": "0.2.73", "description": "libp2p module", "main": "dist/index.js", "exports": "./dist/index.js", diff --git a/packages/rpc-eth-client/package.json b/packages/rpc-eth-client/package.json index bbfe2856..56d33403 100644 --- a/packages/rpc-eth-client/package.json +++ b/packages/rpc-eth-client/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/rpc-eth-client", - "version": "0.2.72", + "version": "0.2.73", "description": "RPC ETH Client", "main": "dist/index.js", "scripts": { @@ -19,9 +19,9 @@ }, "homepage": "https://github.com/cerc-io/watcher-ts#readme", "dependencies": { - "@cerc-io/cache": "^0.2.72", - "@cerc-io/ipld-eth-client": "^0.2.72", - "@cerc-io/util": "^0.2.72", + "@cerc-io/cache": "^0.2.73", + "@cerc-io/ipld-eth-client": "^0.2.73", + "@cerc-io/util": "^0.2.73", "chai": "^4.3.4", "ethers": "^5.4.4", "left-pad": "^1.3.0", diff --git a/packages/rpc-eth-client/src/eth-client.ts b/packages/rpc-eth-client/src/eth-client.ts index 5913193b..1029def6 100644 --- a/packages/rpc-eth-client/src/eth-client.ts +++ b/packages/rpc-eth-client/src/eth-client.ts @@ -10,6 +10,7 @@ import { encodeHeader, escapeHexString, EthClient as EthClientInterface, EthFull import { padKey } from '@cerc-io/ipld-eth-client'; const FUTURE_BLOCK_ERROR = "requested a future epoch (beyond 'latest')"; +const NULL_BLOCK_ERROR = 'requested epoch was a null round'; export interface Config { cache: Cache | undefined; @@ -93,10 +94,7 @@ export class EthClient implements EthClientInterface { } ]; } catch (err: any) { - // Check and ignore future block error - if (!(err.code === errors.SERVER_ERROR && err.error && err.error.message === FUTURE_BLOCK_ERROR)) { - throw err; - } + return this._handleGetBlockErrors(err); } finally { console.timeEnd(`time:eth-client#getBlockWithTransactions-${JSON.stringify({ blockNumber, blockHash })}`); } @@ -138,10 +136,7 @@ export class EthClient implements EthClientInterface { ]; } } catch (err: any) { - // Check and ignore future block error - if (!(err.code === errors.SERVER_ERROR && err.error && err.error.message === FUTURE_BLOCK_ERROR)) { - throw err; - } + return this._handleGetBlockErrors(err); } finally { console.timeEnd(`time:eth-client#getBlocks-${JSON.stringify({ blockNumber, blockHash })}`); } @@ -153,7 +148,7 @@ export class EthClient implements EthClientInterface { }; } - async getFullBlocks ({ blockNumber, blockHash }: { blockNumber?: number, blockHash?: string }): Promise { + async getFullBlocks ({ blockNumber, blockHash }: { blockNumber?: number, blockHash?: string }): Promise> { const blockNumberHex = blockNumber ? utils.hexValue(blockNumber) : undefined; const blockHashOrBlockNumber = blockHash ?? blockNumberHex; assert(blockHashOrBlockNumber); @@ -207,10 +202,7 @@ export class EthClient implements EthClientInterface { }]; } } catch (err: any) { - // Check and ignore future block error - if (!(err.code === errors.SERVER_ERROR && err.error && err.error.message === FUTURE_BLOCK_ERROR)) { - throw err; - } + return this._handleGetBlockErrors(err); } finally { console.timeEnd(`time:eth-client#getFullBlocks-${JSON.stringify({ blockNumber, blockHash })}`); } @@ -379,4 +371,20 @@ export class EthClient implements EthClientInterface { return result; } + + _handleGetBlockErrors (err: any): Array { + if (err.code === errors.SERVER_ERROR && err.error) { + // Check null block error and return null array + if (err.error.message === NULL_BLOCK_ERROR) { + return [null]; + } + + // Check and ignore future block error + if (err.error.message === FUTURE_BLOCK_ERROR) { + return []; + } + } + + throw err; + } } diff --git a/packages/solidity-mapper/package.json b/packages/solidity-mapper/package.json index aa6444e5..9cdc3808 100644 --- a/packages/solidity-mapper/package.json +++ b/packages/solidity-mapper/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/solidity-mapper", - "version": "0.2.72", + "version": "0.2.73", "main": "dist/index.js", "license": "AGPL-3.0", "devDependencies": { diff --git a/packages/test/package.json b/packages/test/package.json index 91d01054..9e1e6127 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/test", - "version": "0.2.72", + "version": "0.2.73", "main": "dist/index.js", "license": "AGPL-3.0", "private": true, diff --git a/packages/tracing-client/package.json b/packages/tracing-client/package.json index f89634c9..a4f4e333 100644 --- a/packages/tracing-client/package.json +++ b/packages/tracing-client/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/tracing-client", - "version": "0.2.72", + "version": "0.2.73", "description": "ETH VM tracing client", "main": "dist/index.js", "scripts": { diff --git a/packages/util/package.json b/packages/util/package.json index df8dc0ff..8db92f39 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,13 +1,13 @@ { "name": "@cerc-io/util", - "version": "0.2.72", + "version": "0.2.73", "main": "dist/index.js", "license": "AGPL-3.0", "dependencies": { "@apollo/utils.keyvaluecache": "^1.0.1", "@cerc-io/nitro-node": "^0.1.15", - "@cerc-io/peer": "^0.2.72", - "@cerc-io/solidity-mapper": "^0.2.72", + "@cerc-io/peer": "^0.2.73", + "@cerc-io/solidity-mapper": "^0.2.73", "@cerc-io/ts-channel": "1.0.3-ts-nitro-0.1.1", "@ethersproject/properties": "^5.7.0", "@ethersproject/providers": "^5.4.4", @@ -52,7 +52,7 @@ "yargs": "^17.0.1" }, "devDependencies": { - "@cerc-io/cache": "^0.2.72", + "@cerc-io/cache": "^0.2.73", "@nomiclabs/hardhat-waffle": "^2.0.1", "@types/bunyan": "^1.8.8", "@types/express": "^4.17.14", diff --git a/packages/util/src/block-size-cache.ts b/packages/util/src/block-size-cache.ts deleted file mode 100644 index 9dfd762e..00000000 --- a/packages/util/src/block-size-cache.ts +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright 2022 Vulcanize, Inc. -// - -import { utils, providers, errors } from 'ethers'; -import debug from 'debug'; - -import { NULL_BLOCK_ERROR } from './constants'; - -const log = debug('vulcanize:block-size-cache'); - -// Number of blocks to cache after current block being processed. -const BLOCK_SIZE_CACHE_BUFFER = 10; -// Block height interval at which blockSizeMap is cleared. -// If the block being processed is divisible by BLOCK_SIZE_MAP_CLEAR_HEIGHT_INTERVAL then blocks below that height are removed from the map. -const BLOCK_SIZE_MAP_CLEAR_HEIGHT_INTERVAL = 50; - -const blockSizeMap: Map = new Map(); -let blockSizeMapLatestHeight = -1; - -export const getCachedBlockSize = async (provider: providers.JsonRpcProvider, blockHash: string, blockNumber: number): Promise => { - const block = blockSizeMap.get(blockHash); - cacheBlockSizesAsync(provider, blockNumber); - - if (!block) { - console.time(`time:misc#getCachedBlockSize-eth_getBlockByHash-${blockNumber}`); - const { size } = await provider.send('eth_getBlockByHash', [blockHash, false]); - console.timeEnd(`time:misc#getCachedBlockSize-eth_getBlockByHash-${blockNumber}`); - - return size; - } - - return block.size; -}; - -const cacheBlockSizesAsync = async (provider: providers.JsonRpcProvider, blockNumber: number): Promise => { - const endBlockHeight = blockNumber + BLOCK_SIZE_CACHE_BUFFER; - - if (blockSizeMapLatestHeight < 0) { - blockSizeMapLatestHeight = blockNumber; - } - - if (endBlockHeight > blockSizeMapLatestHeight) { - const startBlockHeight = Math.max(blockNumber, blockSizeMapLatestHeight + 1); - blockSizeMapLatestHeight = endBlockHeight; - - // Start prefetching blocks after latest height in blockSizeMap. - for (let i = startBlockHeight; i <= endBlockHeight; i++) { - try { - console.time(`time:misc#cacheBlockSizesAsync-eth_getBlockByNumber-${i}`); - const block = await provider.send('eth_getBlockByNumber', [utils.hexStripZeros(utils.hexlify(i)), false]); - - if (block) { - const { size, hash } = block; - blockSizeMap.set(hash, { size, blockNumber: i }); - } else { - log(`No block found at height ${i}`); - } - } catch (err: any) { - // Handle null block error in case of Lotus EVM - if (!(err.code === errors.SERVER_ERROR && err.error && err.error.message === NULL_BLOCK_ERROR)) { - throw err; - } - - log(`Block ${i} requested was null (FEVM); Fetching next block`); - } finally { - console.timeEnd(`time:misc#cacheBlockSizesAsync-eth_getBlockByNumber-${i}`); - } - } - } - - // At interval clear previous blocks below height blockNumber from map. - if (blockNumber % BLOCK_SIZE_MAP_CLEAR_HEIGHT_INTERVAL === 0) { - log(`cacheBlockSizesAsync-clear-map-below-${blockNumber}`); - const previousBlockHashes = Array.from(blockSizeMap.entries()) - .filter(([, value]) => value.blockNumber <= blockNumber) - .map(([blockHash]) => blockHash); - - previousBlockHashes.forEach(blockHash => blockSizeMap.delete(blockHash)); - } -}; diff --git a/packages/util/src/common.ts b/packages/util/src/common.ts index 8222a4c9..39683a66 100644 --- a/packages/util/src/common.ts +++ b/packages/util/src/common.ts @@ -1,7 +1,6 @@ import debug from 'debug'; import assert from 'assert'; import { DeepPartial } from 'typeorm'; -import { errors } from 'ethers'; import JSONbig from 'json-bigint'; import { @@ -10,8 +9,7 @@ import { QUEUE_BLOCK_CHECKPOINT, JOB_KIND_PRUNE, JOB_KIND_INDEX, - UNKNOWN_EVENT_NAME, - NULL_BLOCK_ERROR + UNKNOWN_EVENT_NAME } from './constants'; import { JobQueue } from './job-queue'; import { BlockProgressInterface, IndexerInterface, EventInterface, EthFullTransaction, EthFullBlock } from './types'; @@ -78,38 +76,37 @@ export const fetchBlocksAtHeight = async ( // Try fetching blocks from eth-server until found. while (!blocks.length) { - try { - console.time('time:common#_fetchBlocks-eth-server'); - blocks = await indexer.getBlocks({ blockNumber }); + console.time(`time:common#_fetchBlocks-eth-server-${blockNumber}`); + const ethFullBlocks = await indexer.getBlocks({ blockNumber }); + console.timeEnd(`time:common#_fetchBlocks-eth-server-${blockNumber}`); - if (!blocks.length) { - log(`No blocks fetched for block number ${blockNumber}, retrying after ${jobQueueConfig.blockDelayInMilliSecs} ms delay.`); - await wait(jobQueueConfig.blockDelayInMilliSecs); - } else { - blocks.forEach(block => { - blockAndEventsMap.set( - block.blockHash, - { - // Block is set later in job-runner when saving to database - block: {} as BlockProgressInterface, - events: [], - ethFullBlock: block, - // Transactions are set later in job-runner when fetching events - ethFullTransactions: [] - } - ); - }); - } - } catch (err: any) { - // Handle null block error in case of Lotus EVM - if (!(err.code === errors.SERVER_ERROR && err.error && err.error.message === NULL_BLOCK_ERROR)) { - throw err; - } - - log(`Block ${blockNumber} requested was null (FEVM); Fetching next block`); + // Check if all blocks are null and increment blockNumber to index next block number + if (ethFullBlocks.every(block => block === null)) { blockNumber++; - } finally { - console.timeEnd('time:common#_fetchBlocks-eth-server'); + log(`Block ${blockNumber} requested was null (FEVM); Fetching next block`); + continue; + } + + // Fitler null blocks + blocks = ethFullBlocks.filter(block => Boolean(block)) as EthFullBlock[]; + + if (!blocks.length) { + log(`No blocks fetched for block number ${blockNumber}, retrying after ${jobQueueConfig.blockDelayInMilliSecs} ms delay.`); + await wait(jobQueueConfig.blockDelayInMilliSecs); + } else { + blocks.forEach(block => { + blockAndEventsMap.set( + block.blockHash, + { + // Block is set later in job-runner when saving to database + block: {} as BlockProgressInterface, + events: [], + ethFullBlock: block, + // Transactions are set later in job-runner when fetching events + ethFullTransactions: [] + } + ); + }); } } diff --git a/packages/util/src/constants.ts b/packages/util/src/constants.ts index 8861a660..7c1fd66e 100644 --- a/packages/util/src/constants.ts +++ b/packages/util/src/constants.ts @@ -30,5 +30,3 @@ export const DEFAULT_PREFETCH_BATCH_SIZE = 10; export const DEFAULT_MAX_GQL_CACHE_SIZE = Math.pow(2, 20) * 8; // 8 MB export const SUPPORTED_PAID_RPC_METHODS = ['eth_getBlockByHash', 'eth_getStorageAt', 'eth_getBlockByNumber']; - -export const NULL_BLOCK_ERROR = 'requested epoch was a null round'; diff --git a/packages/util/src/fill.ts b/packages/util/src/fill.ts index 8e5ed001..11a1c7d9 100644 --- a/packages/util/src/fill.ts +++ b/packages/util/src/fill.ts @@ -5,7 +5,7 @@ import debug from 'debug'; import { JobQueue } from './job-queue'; -import { IndexerInterface } from './types'; +import { EthFullBlock, IndexerInterface } from './types'; import { wait } from './misc'; import { processBlockByNumber } from './common'; import { DEFAULT_PREFETCH_BATCH_SIZE } from './constants'; @@ -107,7 +107,7 @@ const prefetchBlocks = async ( let blockNumbers = [...Array(batchEndBlock - i).keys()].map(n => n + i); log('Fetching blockNumbers:', blockNumbers); - let blocks = []; + let blocks: EthFullBlock[] = []; // Fetch blocks again if there are missing blocks. while (true) { @@ -117,7 +117,8 @@ const prefetchBlocks = async ( const missingIndex = res.findIndex(blocks => blocks.length === 0); if (missingIndex < 0) { - blocks = res.flat(); + // Filter null blocks + blocks = res.flat().filter(block => Boolean(block)) as EthFullBlock[]; break; } diff --git a/packages/util/src/index-block.ts b/packages/util/src/index-block.ts index 61a6e467..c752f45f 100644 --- a/packages/util/src/index-block.ts +++ b/packages/util/src/index-block.ts @@ -22,12 +22,14 @@ export const indexBlock = async ( console.time('time:index-block#getBlocks-ipld-eth-server'); const blocks = await indexer.getBlocks({ blockNumber: argv.block }); - blockProgressEntities = blocks.map((block: any): Partial => { - block.blockTimestamp = Number(block.timestamp); - block.blockNumber = Number(block.blockNumber); + // Filter null blocks and transform to BlockProgress type + blockProgressEntities = blocks.filter(block => Boolean(block)) + .map((block: any): Partial => { + block.blockTimestamp = Number(block.timestamp); + block.blockNumber = Number(block.blockNumber); - return block; - }); + return block; + }); console.timeEnd('time:index-block#getBlocks-ipld-eth-server'); } diff --git a/packages/util/src/indexer.ts b/packages/util/src/indexer.ts index e227d9e1..af00bb94 100644 --- a/packages/util/src/indexer.ts +++ b/packages/util/src/indexer.ts @@ -291,7 +291,7 @@ export class Indexer { return res; } - async getBlocks (blockFilter: { blockNumber?: number, blockHash?: string }): Promise { + async getBlocks (blockFilter: { blockNumber?: number, blockHash?: string }): Promise> { assert(blockFilter.blockHash || blockFilter.blockNumber); const blocks = await this._ethClient.getFullBlocks(blockFilter); @@ -394,6 +394,7 @@ export class Indexer { console.time(`time:indexer#fetchAndSaveFilteredEventsAndBlocks-fetch-blocks-txs-${fromBlock}-${toBlock}`); const blocksPromises = Array.from(blockLogsMap.keys()).map(async (blockHash) => { const [fullBlock] = await this._ethClient.getFullBlocks({ blockHash }); + assert(fullBlock); const block = { ...fullBlock, @@ -401,7 +402,10 @@ export class Indexer { blockNumber: Number(fullBlock.blockNumber) }; - return { block, fullBlock } as { block: DeepPartial; fullBlock: EthFullBlock }; + return { + block: block as DeepPartial, + fullBlock + }; }); const ethFullTxPromises = txHashes.map(async txHash => { diff --git a/packages/util/src/job-runner.ts b/packages/util/src/job-runner.ts index d8656727..1dd102ff 100644 --- a/packages/util/src/job-runner.ts +++ b/packages/util/src/job-runner.ts @@ -521,30 +521,28 @@ export class JobRunner { const newPriority = (priority || 0) + 1; if (!parentBlock || parentBlock.blockHash !== parentHash) { - const blocks = await this._indexer.getBlocks({ blockHash: parentHash }); + const [block] = await this._indexer.getBlocks({ blockHash: parentHash }); - if (!blocks.length) { + if (!block) { const message = `No blocks at parentHash ${parentHash}, aborting`; log(message); throw new Error(message); } - blocks.forEach(block => { - this._blockAndEventsMap.set( - block.blockHash, - { - // block is set later in job when saving to database - block: {} as BlockProgressInterface, - events: [], - ethFullBlock: block, - // Transactions are set later in job when fetching events - ethFullTransactions: [] - } - ); - }); + this._blockAndEventsMap.set( + block.blockHash, + { + // block is set later in job when saving to database + block: {} as BlockProgressInterface, + events: [], + ethFullBlock: block, + // Transactions are set later in job when fetching events + ethFullTransactions: [] + } + ); - const [{ cid: parentCid, blockNumber: parentBlockNumber, parentHash: grandparentHash, timestamp: parentTimestamp }] = blocks; + const { cid: parentCid, blockNumber: parentBlockNumber, parentHash: grandparentHash, timestamp: parentTimestamp } = block; await this.jobQueue.pushJob(QUEUE_BLOCK_PROCESSING, { kind: JOB_KIND_INDEX, diff --git a/packages/util/src/types.ts b/packages/util/src/types.ts index 6dbd3c31..ff2f6469 100644 --- a/packages/util/src/types.ts +++ b/packages/util/src/types.ts @@ -138,7 +138,7 @@ export interface EthClient { getFullBlocks({ blockNumber, blockHash }: { blockNumber?: number; blockHash?: string; - }): Promise; + }): Promise>; getFullTransaction(txHash: string, blockNumber?: number): Promise; getBlockByHash(blockHash?: string): Promise; getLogs(vars: { @@ -167,7 +167,7 @@ export interface IndexerInterface { getEvent (id: string): Promise getSyncStatus (): Promise getStateSyncStatus (): Promise - getBlocks (blockFilter: { blockHash?: string, blockNumber?: number }): Promise + getBlocks (blockFilter: { blockHash?: string, blockNumber?: number }): Promise> getBlocksAtHeight (height: number, isPruned: boolean): Promise getLatestCanonicalBlock (): Promise getLatestStateIndexedBlock (): Promise