diff --git a/src/common/indexer/elastic/elastic.indexer.service.ts b/src/common/indexer/elastic/elastic.indexer.service.ts index e8d12fd6d..b11bdc238 100644 --- a/src/common/indexer/elastic/elastic.indexer.service.ts +++ b/src/common/indexer/elastic/elastic.indexer.service.ts @@ -255,6 +255,18 @@ export class ElasticIndexerService implements IndexerInterface { return await this.elasticService.getItem('executionresults', 'hash', hash); } + async getExecutionResultsForHashes(hashes: string[]): Promise { + if (!hashes || hashes.length === 0) { + return []; + } + + const elasticQuery = ElasticQuery.create() + .withPagination({ from: 0, size: hashes.length + 1 }) + .withShouldCondition(hashes.map(h => QueryType.Match('_id', h))); + + return await this.elasticService.getList('executionresults', 'hash', elasticQuery); + } + async getBlockByMiniBlockHash(miniBlockHash: string): Promise { const elasticQuery = ElasticQuery.create() .withCondition(QueryConditionOptions.must, [QueryType.Match('miniBlocksHashes', miniBlockHash)]) diff --git a/src/common/indexer/indexer.interface.ts b/src/common/indexer/indexer.interface.ts index 19e1d3cef..5511e8a8e 100644 --- a/src/common/indexer/indexer.interface.ts +++ b/src/common/indexer/indexer.interface.ts @@ -76,6 +76,8 @@ export interface IndexerInterface { getExecutionResults(hash: string): Promise + getExecutionResultsForHashes(hashes: string[]): Promise + getBlockByMiniBlockHash(miniBlockHash: string): Promise getMiniBlock(miniBlockHash: string): Promise diff --git a/src/common/indexer/indexer.service.ts b/src/common/indexer/indexer.service.ts index b0dd2e11d..05bf39d9f 100644 --- a/src/common/indexer/indexer.service.ts +++ b/src/common/indexer/indexer.service.ts @@ -171,6 +171,11 @@ export class IndexerService implements IndexerInterface { return await this.indexerInterface.getExecutionResults(hash); } + @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) + async getExecutionResultsForHashes(hashes: string[]): Promise { + return await this.indexerInterface.getExecutionResultsForHashes(hashes); + } + @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) async getBlockByMiniBlockHash(miniBlockHash: string): Promise { return await this.indexerInterface.getBlockByMiniBlockHash(miniBlockHash); diff --git a/src/endpoints/blocks/block.service.ts b/src/endpoints/blocks/block.service.ts index 26f6421ef..cc3214f90 100644 --- a/src/endpoints/blocks/block.service.ts +++ b/src/endpoints/blocks/block.service.ts @@ -39,6 +39,16 @@ export class BlockService { async getBlocks(filter: BlockFilter, queryPagination: QueryPagination, withProposerIdentity?: boolean): Promise { const result = await this.indexerService.getBlocks(filter, queryPagination); + const executionResultsMap = await this.fetchExecutionResultsForBlocks(result as any[]); + if (executionResultsMap.size > 0) { + for (const item of result as any[]) { + const executionResult = executionResultsMap.get(item.hash); + if (executionResult) { + ApiUtils.mergeObjects(item, executionResult); + } + } + } + const blocks = await Promise.all(result.map(async (item) => { const blockRaw = await this.computeProposerAndValidators(item); @@ -58,6 +68,41 @@ export class BlockService { return blocks; } + private async fetchExecutionResultsForBlocks(items: any[]): Promise> { + const map = new Map(); + if (!items || items.length === 0) { + return map; + } + + const supernovaEnableEpoch = await this.getSupernovaEnableEpoch(); + if (supernovaEnableEpoch === -1) { + return map; + } + + const eligible = items.filter((r: any) => (r?.epoch ?? -1) >= supernovaEnableEpoch); + if (eligible.length === 0) { + return map; + } + + const hashes = eligible.map((r: any) => r.hash).filter(Boolean); + if (hashes.length === 0) { + return map; + } + + try { + const executionResults = await this.indexerService.getExecutionResultsForHashes(hashes); + for (const er of executionResults as any[]) { + if (er?.hash) { + map.set(er.hash, er); + } + } + } catch { + return map; + } + + return map; + } + private async applyProposerIdentity(blocks: Block[]): Promise { const proposerBlses = blocks.map(x => x.proposer); @@ -176,7 +221,7 @@ export class BlockService { async getSupernovaEnableEpoch(): Promise { const enableEpochs = await this.getNetworkEnableEpochs(); - return enableEpochs["erd_supernova_enable_epoch"] ?? -1; + return enableEpochs?.["erd_supernova_enable_epoch"] ?? -1; } async getNetworkEnableEpochs(): Promise> {