From 320bf02938e313c08b30d0851c95b723015d5e8f Mon Sep 17 00:00:00 2001 From: prathamesh0 <42446521+prathamesh0@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:36:03 +0530 Subject: [PATCH] Fetch txs only for blocks having relevant events (#436) * Fix address filter usage in rpc-eth-client getLogs implementation * Avoid fetching block txs when no relevant logs exist --- .../src/templates/indexer-template.handlebars | 2 +- packages/rpc-eth-client/src/eth-client.ts | 2 +- packages/util/src/indexer.ts | 48 +++++++++++-------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/packages/codegen/src/templates/indexer-template.handlebars b/packages/codegen/src/templates/indexer-template.handlebars index 6d5ee5da..e573651f 100644 --- a/packages/codegen/src/templates/indexer-template.handlebars +++ b/packages/codegen/src/templates/indexer-template.handlebars @@ -626,7 +626,7 @@ export class Indexer implements IndexerInterface { } async fetchEventsAndSaveBlocks (blocks: DeepPartial[]): Promise<{ blockProgress: BlockProgress, events: DeepPartial[] }[]> { - return this._baseIndexer.fetchEventsAndSaveBlocks(blocks, this.parseEventNameAndArgs.bind(this)) + return this._baseIndexer.fetchEventsAndSaveBlocks(blocks, this.parseEventNameAndArgs.bind(this)); } async saveBlockAndFetchEvents (block: DeepPartial): Promise<[BlockProgress, DeepPartial[]]> { diff --git a/packages/rpc-eth-client/src/eth-client.ts b/packages/rpc-eth-client/src/eth-client.ts index e68fada0..419585d7 100644 --- a/packages/rpc-eth-client/src/eth-client.ts +++ b/packages/rpc-eth-client/src/eth-client.ts @@ -279,7 +279,7 @@ export class EthClient implements EthClientInterface { let logs = logsByAddress.flat(); // If no addresses provided to filter - if (!logs.length) { + if (!addresses.length) { logs = await this._provider.getLogs({ fromBlock, toBlock diff --git a/packages/util/src/indexer.ts b/packages/util/src/indexer.ts index 8914fbed..f0dadb35 100644 --- a/packages/util/src/indexer.ts +++ b/packages/util/src/indexer.ts @@ -301,7 +301,7 @@ export class Indexer { } // Fetch logs for block range of given blocks - let logsPromise: Promise; + let logs: any; const fromBlock = blocks[0].blockNumber; const toBlock = blocks[blocks.length - 1].blockNumber; @@ -312,20 +312,43 @@ export class Indexer { return watchedContract.address; }); - logsPromise = this._ethClient.getLogsForBlockRange({ + ({ logs } = await this._ethClient.getLogsForBlockRange({ fromBlock, toBlock, addresses - }); + })); } else { - logsPromise = this._ethClient.getLogsForBlockRange({ fromBlock, toBlock }); + ({ logs } = await this._ethClient.getLogsForBlockRange({ fromBlock, toBlock })); } + // Skip further processing if no relevant logs found in the entire block range + if (!logs.length) { + return new Map(); + } + + // Sort logs according to blockhash + const logsMap: Map = new Map(); + logs.forEach((log: any) => { + const { blockHash: logBlockHash } = log; + assert(typeof logBlockHash === 'string'); + + if (!logsMap.has(logBlockHash)) { + logsMap.set(logBlockHash, []); + } + + logsMap.get(logBlockHash).push(log); + }); + // Fetch transactions for given blocks const transactionsMap: Map = new Map(); const transactionPromises = blocks.map(async (block) => { assert(block.blockHash); + // Skip fetching txs if no relevant logs found in this block + if (!logsMap.has(block.blockHash)) { + return; + } + const blockWithTransactions = await this._ethClient.getBlockWithTransactions({ blockHash: block.blockHash, blockNumber: block.blockNumber }); const { allEthHeaderCids: { @@ -342,20 +365,7 @@ export class Indexer { transactionsMap.set(block.blockHash, transactions); }); - const [{ logs }] = await Promise.all([logsPromise, ...transactionPromises]); - - // Sort logs according to blockhash - const logsMap: Map = new Map(); - logs.forEach((log: any) => { - const { blockHash: logBlockHash } = log; - assert(typeof logBlockHash === 'string'); - - if (!logsMap.has(logBlockHash)) { - logsMap.set(logBlockHash, []); - } - - logsMap.get(logBlockHash).push(log); - }); + await Promise.all(transactionPromises); // Map db ready events according to blockhash const dbEventsMap: Map[]> = new Map(); @@ -364,7 +374,7 @@ export class Indexer { assert(blockHash); const logs = logsMap.get(blockHash) || []; - const transactions = transactionsMap.get(blockHash); + const transactions = transactionsMap.get(blockHash) || []; const dbEvents = this.createDbEventsFromLogsAndTxs(blockHash, logs, transactions, parseEventNameAndArgs); dbEventsMap.set(blockHash, dbEvents);