Skip to content

Commit

Permalink
Index start blocks to create init states of watched contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
prathamesh0 committed Nov 27, 2023
1 parent 39af780 commit 0ae9262
Showing 1 changed file with 46 additions and 12 deletions.
58 changes: 46 additions & 12 deletions packages/util/src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,22 @@ export class Indexer {
return blocks;
}

async getBlockWithFullBlock (blockFilter: { blockNumber?: number, blockHash?: string }): Promise<{ block: DeepPartial<BlockProgressInterface>, fullBlock: EthFullBlock }> {
const [fullBlock] = await this.getBlocks(blockFilter);
assert(fullBlock);

const block = {
...fullBlock,
blockTimestamp: Number(fullBlock.timestamp),
blockNumber: Number(fullBlock.blockNumber)
};

return {
block: block as DeepPartial<BlockProgressInterface>,
fullBlock
};
}

async getBlockProgress (blockHash: string): Promise<BlockProgressInterface | undefined> {
return this._db.getBlockProgress(blockHash);
}
Expand Down Expand Up @@ -394,6 +410,17 @@ export class Indexer {

const { addresses, topics } = this._createLogsFilters(eventSignaturesMap);

// Create a set of starting blocks of watched contracts in range [fromBlock, toBlock]
// TODO: Optimize (avoid template contracts)
const watchedBlockNumbers = Object.keys(this._watchedContracts).reduce((acc: Set<number>, address: string) => {
const startBlock = this._watchedContracts[address].startingBlock;
if (startBlock >= fromBlock && startBlock <= toBlock) {
acc.add(startBlock);
}

return acc;
}, new Set());

const { logs } = await this._ethClient.getLogsForBlockRange({
fromBlock,
toBlock,
Expand All @@ -410,19 +437,13 @@ export class Indexer {
// Fetch blocks with transactions for the logs returned
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 } = await this.getBlockWithFullBlock({ blockHash });

const block = {
...fullBlock,
blockTimestamp: Number(fullBlock.timestamp),
blockNumber: Number(fullBlock.blockNumber)
};
// Remove this block from watchedBlockNumbers set as it's already fetched
assert(block.blockNumber);
watchedBlockNumbers.delete(block.blockNumber);

return {
block: block as DeepPartial<BlockProgressInterface>,
fullBlock
};
return { block, fullBlock };
});

const ethFullTxPromises = txHashes.map(async txHash => {
Expand All @@ -432,6 +453,19 @@ export class Indexer {
const blocks = await Promise.all(blocksPromises);
const ethFullTxs = await Promise.all(ethFullTxPromises);

// Fetch starting blocks for watched contracts
const watchedBlocks = await Promise.all(
Array.from(watchedBlockNumbers).map(async (blockNumber) => this.getBlockWithFullBlock({ blockNumber }))
);

// Merge and sort the two block lists
const sortedBlocks = [...blocks, ...watchedBlocks].sort((b1, b2) => {
assert(b1.block.blockNumber);
assert(b2.block.blockNumber);

return b1.block.blockNumber - b2.block.blockNumber;
});

const ethFullTxsMap = ethFullTxs.reduce((acc: Map<string, EthFullTransaction>, ethFullTx) => {
acc.set(ethFullTx.ethTransactionCidByTxHash.txHash, ethFullTx);
return acc;
Expand All @@ -441,7 +475,7 @@ export class Indexer {

// Map db ready events according to blockhash
console.time(`time:indexer#fetchAndSaveFilteredEventsAndBlocks-db-save-blocks-events-${fromBlock}-${toBlock}`);
const blockWithDbEventsPromises = blocks.map(async ({ block, fullBlock }) => {
const blockWithDbEventsPromises = sortedBlocks.map(async ({ block, fullBlock }) => {
const blockHash = block.blockHash;
assert(blockHash);
const logs = blockLogsMap.get(blockHash) || [];
Expand Down

0 comments on commit 0ae9262

Please sign in to comment.