-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: enhanced reliability of eth RPC methods with null checks and retry mechanisms #3349
base: main
Are you sure you want to change the base?
Conversation
Test Results 20 files - 4 312 suites - 49 38m 13s ⏱️ - 22m 7s For more details on these failures, see this check. Results for commit 051f326. ± Comparison against base commit 90739e1. This pull request removes 6 tests.
♻️ This comment has been updated with latest results. |
675eb4a
to
d265305
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
Some considerations
@@ -334,7 +335,7 @@ export class CommonService implements ICommonService { | |||
new Log({ | |||
address: log.address, | |||
blockHash: toHash32(log.block_hash), | |||
blockNumber: numberTo0x(log.block_number), | |||
blockNumber: nullableNumberTo0x(log.block_number), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Why would a block number be null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is one of the strange cases where block_number
, transaction_index
, or blockHash
are falsy, leading to 500 errors. The retry mechanism should address the issue. Should I revert this change and throw a more informative error message even if those fields remain falsy after the retry? Hmm maybe that would be better so the clients can resubmit the requests themselves other than having null in the response. Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, if a retry is ensured to resolve the issue then maybe we can manage one iteration in the short term.
We should open up an issue in the mirror node repo to investigate this issue so this can be resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not return a nullable (or casted to 0x) block number IMO. This might seriously mess up third-party tools like the graph.
@@ -620,7 +620,10 @@ export class MirrorNodeClient { | |||
requestDetails, | |||
); | |||
|
|||
await this.cacheService.set(cachedLabel, block, MirrorNodeClient.GET_BLOCK_ENDPOINT, requestDetails); | |||
if (block) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if I understand correctly, but the errors described in the issue were because of caching null blocks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an issue I noticed and an attempt securing the code. While it may or may not be directly related to the problem, we should ensure the block is not null before storing it in the cache. Otherwise, we risk repeatedly retrieving null from the cache, which likely has a TTL.
936f1e9
to
b959fc7
Compare
19d9838
to
e1c8fd0
Compare
3b96fc4
to
aad493c
Compare
Signed-off-by: Logan Nguyen <[email protected]>
Signed-off-by: Logan Nguyen <[email protected]>
Signed-off-by: Logan Nguyen <[email protected]>
a5a0e1f
to
78fa644
Compare
…Contract MN methods Signed-off-by: Logan Nguyen <[email protected]>
bac3c74
to
d7f5829
Compare
this.logger.warn( | ||
e, | ||
`${requestDetails.formattedRequestId} Transaction failed while executing transaction via the SDK: transactionId=${transaction.transactionId}, callerName=${callerName}, txConstructorName=${txConstructorName}`, | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for Rereviewers:
This is an effort to enhance debugging.
await relay.pollForValidTransactionReceipt(transactionHash); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for Rereviewers:
This is an effort to stablize the flaky test.
Signed-off-by: Logan Nguyen <[email protected]>
Signed-off-by: Logan Nguyen <[email protected]>
Signed-off-by: Logan Nguyen <[email protected]> Revert "fix: reverted licenses" This reverts commit d3c860a. Reapply "fix: reverted licenses" This reverts commit 50a9acd5031490f3f805042a70bfdae7c589146d.
Signed-off-by: Logan Nguyen <[email protected]>
d6756f0
to
8687322
Compare
@@ -175,6 +177,20 @@ export class CommonService implements ICommonService { | |||
returnLatest?: boolean, | |||
): Promise<any> { | |||
if (!returnLatest && this.blockTagIsLatestOrPending(blockNumberOrTagOrHash)) { | |||
if (this.logger.isLevelEnabled('debug')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: why is it needed to query for the log level? can we just interpolate the log message? https://github.com/pinojs/pino/blob/main/docs/api.md#interpolationvalues-any
This would be just to simplify the log logic.
requestDetails: RequestDetails, | ||
): Promise<any> { | ||
const shortDelay = 500; | ||
const contractResult = await this[methodName](...args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was this issue with calling getContractResult
directly? I see all calls to getContractResultWithRetry
use the same methodName=this.mirrorNodeClient.getContractResults.name
, is there any other benefit of calling it indirectly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes, there’s a rare case where the contract result contains null fields, as mentioned here: #3349 (comment). Calling getContractResultWithRetry() will invoke getContractResult, and if this rare case occurs, it will attempt the call again. The plan is to release this change first to gather more information about the getContractResult issue and eventually open a ticket on the MN side for further investigation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG, one question/thought that might be resolved before merging.
…k_hash is empty Signed-off-by: Logan Nguyen <[email protected]>
9f2e473
to
051f326
Compare
Quality Gate failedFailed conditions |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3349 +/- ##
==========================================
- Coverage 85.30% 84.83% -0.47%
==========================================
Files 69 69
Lines 4688 4721 +33
Branches 1050 1063 +13
==========================================
+ Hits 3999 4005 +6
- Misses 374 399 +25
- Partials 315 317 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Description:
Numerous requests for
eth_getBlockByNumber
andeth_getBlockByHash
have been reported as failing with errors such asCannot read properties of null
andReceived an invalid integer type: null
.Additionally,
eth_getTransactionReceipt
is also reported to be failing withError invoking RPC: Invalid parameter: hashOrNumber
.These issues stem from regressions in the
getBlock()
method, which lacks adequate null checks in certain areas. This pull request addresses the problem by implementing proper null checks and enhancing fallback mechanisms and error handling.Partially, the results of contracts and log responses from the Mirror Node occasionally contain undefined fields, such as transaction_index, block_hash, block_number, and log_index. This issue may arise because the Mirror Node database does not have sufficient time to save all the information before it is fetched. This PR adds a retry mechanism to the fetching methods that checks for these cases, waits for a specified duration, and then retries the fetch operation.
Related issue(s):
Fixes #3345
Fixes #3351
Notes for reviewer:
Checklist