diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index 00b947aff..acb24cf76 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -45,6 +45,7 @@ import { MirrorNodeTransactionRecord, RequestDetails, } from '../types'; +import { EthImpl } from '../eth'; type REQUEST_METHODS = 'GET' | 'POST'; @@ -733,6 +734,7 @@ export class MirrorNodeClient { response != undefined && response.transaction_index != undefined && response.block_number != undefined && + response.block_hash != EthImpl.emptyHex && response.result === 'SUCCESS' ) { await this.cacheService.set( @@ -749,14 +751,21 @@ export class MirrorNodeClient { /** * In some very rare cases the /contracts/results api is called before all the data is saved in - * the mirror node DB and `transaction_index` or `block_number` is returned as `undefined`. A single re-fetch is sufficient to - * resolve this problem. + * the mirror node DB and `transaction_index` or `block_number` is returned as `undefined` or `block_hash` as `0x`. + * A single re-fetch is sufficient to resolve this problem. * @param {string} transactionIdOrHash - The transaction ID or hash * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ public async getContractResultWithRetry(transactionIdOrHash: string, requestDetails: RequestDetails) { const contractResult = await this.getContractResult(transactionIdOrHash, requestDetails); - if (contractResult && !(contractResult.transaction_index && contractResult.block_number)) { + if ( + contractResult && + !( + contractResult.transaction_index && + contractResult.block_number && + contractResult.block_hash != EthImpl.emptyHex + ) + ) { return this.getContractResult(transactionIdOrHash, requestDetails); } return contractResult; diff --git a/packages/relay/tests/lib/mirrorNodeClient.spec.ts b/packages/relay/tests/lib/mirrorNodeClient.spec.ts index c3362578d..9e9d2fda2 100644 --- a/packages/relay/tests/lib/mirrorNodeClient.spec.ts +++ b/packages/relay/tests/lib/mirrorNodeClient.spec.ts @@ -625,6 +625,35 @@ describe('MirrorNodeClient', async function () { expect(mock.history.get.length).to.eq(2); // is called twice }); + it('`getContractResultsWithRetry` by hash retries once because of block_hash equals 0x', async () => { + const hash = '0x2a563af33c4871b51a8b108aa2fe1dd5280a30dfb7236170ae5e5e7957eb3391'; + mock.onGet(`contracts/results/${hash}`).replyOnce(200, { ...detailedContractResult, block_hash: '0x' }); + mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); + + const result = await mirrorNodeInstance.getContractResultWithRetry(hash, requestDetails); + expect(result).to.exist; + expect(result.block_hash).equal(detailedContractResult.block_hash); + expect(mock.history.get.length).to.eq(2); + }); + + it('`getContractResultsWithRetry` by hash retries once because of missing transaction_index, block_number and block_hash equals 0x', async () => { + const hash = '0x2a563af33c4871b51a8b108aa2fe1dd5280a30dfb7236170ae5e5e7957eb6393'; + mock.onGet(`contracts/results/${hash}`).replyOnce(200, { + ...detailedContractResult, + transaction_index: undefined, + block_number: undefined, + block_hash: '0x', + }); + mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); + + const result = await mirrorNodeInstance.getContractResultWithRetry(hash, requestDetails); + expect(result).to.exist; + expect(result.transaction_index).equal(detailedContractResult.transaction_index); + expect(result.block_number).equal(detailedContractResult.block_number); + expect(result.block_hash).equal(detailedContractResult.block_hash); + expect(mock.history.get.length).to.eq(2); + }); + it('`getContractResults` detailed', async () => { mock .onGet(`contracts/results?limit=100&order=asc`)