Skip to content

Commit

Permalink
fix: added getContractResultsLogsWithRetry()
Browse files Browse the repository at this point in the history
Signed-off-by: Logan Nguyen <[email protected]>
  • Loading branch information
quiet-node committed Dec 23, 2024
1 parent b173a17 commit 49f84bb
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
43 changes: 40 additions & 3 deletions packages/relay/src/lib/clients/mirrorNodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -892,14 +892,25 @@ export class MirrorNodeClient {
return this.getQueryParams(queryParamObject);
}

public async getContractResultsLogs(
/**
* In some very rare cases the /contracts/results/logs api is called before all the data is saved in
* the mirror node DB and `transaction_index`, `block_number`, or `index` is returned as `undefined`.
* A single re-fetch is sufficient to resolve this problem.
*
* @param {RequestDetails} requestDetails - Details used for logging and tracking the request.
* @param {IContractLogsResultsParams} [contractLogsResultsParams] - Parameters for querying contract logs results.
* @param {ILimitOrderParams} [limitOrderParams] - Parameters for limit and order when fetching the logs.
* @returns {Promise<any[]>} - A promise resolving to the paginated contract logs results.
*/
public async getContractResultsLogsWithRetry(
requestDetails: RequestDetails,
contractLogsResultsParams?: IContractLogsResultsParams,
limitOrderParams?: ILimitOrderParams,
) {
): Promise<any[]> {
const shortDelay = 250;
const queryParams = this.prepareLogsParams(contractLogsResultsParams, limitOrderParams);

return this.getPaginatedResults(
const logResults = await this.getPaginatedResults(
`${MirrorNodeClient.GET_CONTRACT_RESULT_LOGS_ENDPOINT}${queryParams}`,
MirrorNodeClient.GET_CONTRACT_RESULT_LOGS_ENDPOINT,
MirrorNodeClient.CONTRACT_RESULT_LOGS_PROPERTY,
Expand All @@ -908,6 +919,32 @@ export class MirrorNodeClient {
1,
MirrorNodeClient.mirrorNodeContractResultsLogsPageMax,
);

if (logResults) {
for (const log of logResults) {
if (log && (log.transaction_index == null || log.block_number == null || log.index == null)) {
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(

Check warning on line 927 in packages/relay/src/lib/clients/mirrorNodeClient.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/clients/mirrorNodeClient.ts#L927

Added line #L927 was not covered by tests
`${requestDetails.formattedRequestId} Contract result log contains undefined transaction_index, block_number, or index: transaction_hash:${log.transaction_hash}, transaction_index:${log.transaction_index}, block_number=${log.block_number}, log_index=${log.index}. Retrying after a delay of ${shortDelay} ms.`,
);
}

// Backoff before repeating request
await new Promise((r) => setTimeout(r, shortDelay));
return await this.getPaginatedResults(
`${MirrorNodeClient.GET_CONTRACT_RESULT_LOGS_ENDPOINT}${queryParams}`,
MirrorNodeClient.GET_CONTRACT_RESULT_LOGS_ENDPOINT,
MirrorNodeClient.CONTRACT_RESULT_LOGS_PROPERTY,
requestDetails,
[],
1,
MirrorNodeClient.mirrorNodeContractResultsLogsPageMax,
);
}
}
}

return logResults;
}

public async getContractResultsLogsByAddress(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export class CommonService implements ICommonService {
if (address) {
logResults = await this.getLogsByAddress(address, params, requestDetails);
} else {
logResults = await this.mirrorNodeClient.getContractResultsLogs(requestDetails, params);
logResults = await this.mirrorNodeClient.getContractResultsLogsWithRetry(requestDetails, params);
}

if (!logResults) {
Expand Down
2 changes: 1 addition & 1 deletion packages/relay/tests/lib/mirrorNodeClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ describe('MirrorNodeClient', async function () {
it('`getContractResultsLogs` ', async () => {
mock.onGet(`contracts/results/logs?limit=100&order=asc`).reply(200, { logs: [log] });

const results = await mirrorNodeInstance.getContractResultsLogs(requestDetails);
const results = await mirrorNodeInstance.getContractResultsLogsWithRetry(requestDetails);
expect(results).to.exist;
expect(results.length).to.gt(0);
const firstResult = results[0];
Expand Down

0 comments on commit 49f84bb

Please sign in to comment.