Skip to content
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: estimate_gas doesn't reflect changes in mirror-node #2409

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions packages/relay/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ const parseNumericEnvVar = (envVarName: string, fallbackConstantKey: string): nu
* @param value
* @returns tinybarValue
*/
const weibarHexToTinyBarInt = (value: string): number | null => {
const weibarHexToTinyBarInt = (value: bigint | boolean | number | string | null | undefined): number | null => {
if (value && value !== '0x') {
const weiBigInt = BigInt(value);
const coefBigInt = BigInt(constants.TINYBAR_TO_WEIBAR_COEF);
Expand Down Expand Up @@ -220,19 +220,19 @@ const numberTo0x = (input: number | BigNumber | bigint): string => {
return EMPTY_HEX + input.toString(16);
};

const nullableNumberTo0x = (input: number | BigNumber): string | null => {
const nullableNumberTo0x = (input: number | BigNumber | bigint | null): string | null => {
return input == null ? null : numberTo0x(input);
};

const nanOrNumberTo0x = (input: number | BigNumber): string => {
const nanOrNumberTo0x = (input: number | BigNumber | bigint | null): string => {
return input == null || Number.isNaN(input) ? numberTo0x(0) : numberTo0x(input);
};

const toHash32 = (value: string): string => {
return value.substring(0, 66);
};

const toNullableBigNumber = (value: string): string | null => {
const toNullableBigNumber = (value: string | null): string | null => {
if (typeof value === 'string') {
return new BN(value).toString();
}
Expand Down Expand Up @@ -265,7 +265,10 @@ const toHexString = (byteArray) => {
return encoded;
};

const isValidEthereumAddress = (address: string): boolean => {
const isValidEthereumAddress = (address: string | null | undefined): boolean => {
if (!address) {
return false;
}
return new RegExp(constants.BASE_HEX_REGEX + '{40}$').test(address);
};

Expand Down
8 changes: 6 additions & 2 deletions packages/relay/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { Block, Log, Receipt, Transaction } from './lib/model';
import { JsonRpcError, predefined } from './lib/errors/JsonRpcError';
import WebSocketError from './lib/errors/WebSocketError';
import { MirrorNodeClientError } from './lib/errors/MirrorNodeClientError';
import { MirrorNodeClient } from './lib/clients';
import { IContractCallRequest, MirrorNodeClient } from './lib/clients';
import { IFilterService } from './lib/services/ethService/ethFilterService/IFilterService';
import { IDebugService } from './lib/services/debugService/IDebugService';

Expand Down Expand Up @@ -67,7 +67,11 @@ export interface Eth {

coinbase(requestId?: string): JsonRpcError;

estimateGas(transaction: any, blockParam: string | null, requestId?: string): Promise<string | JsonRpcError>;
estimateGas(
transaction: IContractCallRequest,
blockParam: string | null,
requestId?: string,
): Promise<string | JsonRpcError>;

gasPrice(requestId?: string): Promise<string>;

Expand Down
54 changes: 46 additions & 8 deletions packages/relay/src/lib/clients/mirrorNodeClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*-
/* -
*
* Hedera JSON RPC Relay
*
Expand All @@ -19,7 +19,7 @@
*/

import Axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import { MirrorNodeClientError } from './../errors/MirrorNodeClientError';
import { MirrorNodeClientError } from '../errors/MirrorNodeClientError';
import { Logger } from 'pino';
import constants from './../constants';
import { Histogram, Registry } from 'prom-client';
Expand All @@ -30,8 +30,8 @@ import { SDKClientError } from '../errors/SDKClientError';
import { install as betterLookupInstall } from 'better-lookup';
import { CacheService } from '../services/cacheService/cacheService';

const http = require('http');
const https = require('https');
import http from 'http';
import https from 'https';

type REQUEST_METHODS = 'GET' | 'POST';

Expand All @@ -58,6 +58,27 @@ export interface IContractLogsResultsParams {
topic3?: string | string[];
}

export interface IContractCallRequest {
block?: string;
estimate?: boolean;
from?: string;
to?: string | null;
gas?: number | string;
gasPrice?: number | string;
value?: number | string | null;
data?: string | null;
input?: string;
}

export interface IContractCallResponse {
result?: string;
errorMessage?: string;
statusCode?: number;
_status?: {
messages: Array<{ message: string; detail: string; data: string }>;
};
}

export class MirrorNodeClient {
private static GET_ACCOUNTS_BY_ID_ENDPOINT = 'accounts/';
private static GET_BALANCE_ENDPOINT = 'balances';
Expand Down Expand Up @@ -148,9 +169,18 @@ export class MirrorNodeClient {
*/
private readonly register: Registry;

private mirrorResponseHistogram;
/**
* The histogram used for tracking the response time of the mirror node.
* @private
*/
private readonly mirrorResponseHistogram: Histogram;

/**
* The cache service used for caching responses.
* @private
*/
private readonly cacheService: CacheService;

static readonly EVM_ADDRESS_REGEX: RegExp = /\/accounts\/([\d\.]+)/;

static mirrorNodeContractResultsPageMax = parseInt(process.env.MIRROR_NODE_CONTRACT_RESULTS_PG_MAX!) || 25;
Expand Down Expand Up @@ -698,7 +728,7 @@ export class MirrorNodeClient {
* the mirror node DB and `transaction_index` or `block_number` is returned as `undefined`. A single re-fetch is sufficient to
* resolve this problem.
* @param transactionIdOrHash
* @param requestId
* @param requestIdPrefix
*/
public async getContractResultWithRetry(transactionIdOrHash: string, requestIdPrefix?: string) {
const contractResult = await this.getContractResult(transactionIdOrHash, requestIdPrefix);
Expand Down Expand Up @@ -973,7 +1003,15 @@ export class MirrorNodeClient {
return this.get(`${apiEndpoint}${queryParams}`, MirrorNodeClient.CONTRACT_ADDRESS_STATE_ENDPOINT, requestIdPrefix);
}

public async postContractCall(callData: string, requestIdPrefix?: string) {
/**
* Send a contract call request to mirror node
* @param callData {IContractCallRequest} contract call request data
* @param requestIdPrefix {string} optional request id prefix
*/
public async postContractCall(
callData: IContractCallRequest,
requestIdPrefix?: string,
): Promise<IContractCallResponse> {
return this.post(
MirrorNodeClient.CONTRACT_CALL_ENDPOINT,
callData,
Expand Down Expand Up @@ -1006,7 +1044,6 @@ export class MirrorNodeClient {
* Check if transaction fail is because of contract revert and try to fetch and log the reason.
*
* @param e
* @param requestId
* @param requestIdPrefix
*/
public async getContractRevertReasonFromTransaction(e: any, requestIdPrefix: string): Promise<any | undefined> {
Expand Down Expand Up @@ -1084,6 +1121,7 @@ export class MirrorNodeClient {
* @param searchableTypes the types to search for
* @param callerName calling method name
* @param requestIdPrefix the request id prefix message
* @param retries the number of retries
* @returns entity object or null if not found
*/
public async resolveEntityType(
Expand Down
3 changes: 2 additions & 1 deletion packages/relay/src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*-
/* -
*
* Hedera JSON RPC Relay
*
Expand Down Expand Up @@ -92,6 +92,7 @@ export default {
ISTANBUL_TX_DATA_NON_ZERO_COST: 16,
TX_BASE_COST: 21_000,
TX_HOLLOW_ACCOUNT_CREATION_GAS: 587_000,
TX_CONTRACT_CALL_AVERAGE_GAS: 500_000, // TODO: For contract call return some hardcoded value (TBD)
TX_DEFAULT_GAS_DEFAULT: 400_000,
TX_CREATE_EXTRA: 32_000,
TX_DATA_ZERO_COST: 4,
Expand Down
Loading
Loading