Skip to content

Commit

Permalink
refactor to address code review comments
Browse files Browse the repository at this point in the history
Signed-off-by: lukelee-sl <[email protected]>
  • Loading branch information
lukelee-sl committed Jul 26, 2022
1 parent fb28bd3 commit eea0081
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 66 deletions.
4 changes: 2 additions & 2 deletions packages/relay/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
*
*/

import {Block, Log, Receipt, Transaction} from './lib/model';
import {JsonRpcError} from './lib/errors';
import { Block, Log, Receipt, Transaction } from './lib/model';
import { JsonRpcError } from './lib/errors/JsonRpcError';

export { JsonRpcError };

Expand Down
2 changes: 1 addition & 1 deletion packages/relay/src/lib/clients/mirrorNodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/

import Axios, { AxiosInstance } from 'axios';
import { MirrorNodeClientError } from '../errors';
import { MirrorNodeClientError } from './../errors/MirrorNodeClientError';
import { Logger } from "pino";
import constants from './../constants';
import { Histogram, Registry } from 'prom-client';
Expand Down
55 changes: 30 additions & 25 deletions packages/relay/src/lib/clients/sdkClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import { BigNumber } from '@hashgraph/sdk/lib/Transfer';
import { Logger } from "pino";
import { Gauge, Histogram, Registry } from 'prom-client';
import constants from './../constants';
import { SDKClientError } from '../errors';
import { SDKClientError } from './../errors/SDKClientError';

const _ = require('lodash');

Expand Down Expand Up @@ -166,7 +166,7 @@ export class SDKClient {
async getTinyBarGasFee(callerName: string): Promise<number> {
const feeSchedules = await this.getFeeSchedule(callerName);
if (_.isNil(feeSchedules.current) || feeSchedules.current?.transactionFeeSchedule === undefined) {
throw new SDKClientError('Invalid FeeSchedules proto format');
throw new SDKClientError({}, 'Invalid FeeSchedules proto format');
}

for (const schedule of feeSchedules.current?.transactionFeeSchedule) {
Expand All @@ -178,7 +178,7 @@ export class SDKClient {
}
}

throw new SDKClientError(`${constants.ETH_FUNCTIONALITY_CODE} code not found in feeSchedule`);
throw new SDKClientError({}, `${constants.ETH_FUNCTIONALITY_CODE} code not found in feeSchedule`);
}

async getFileIdBytes(address: string, callerName: string): Promise<Uint8Array> {
Expand Down Expand Up @@ -253,16 +253,18 @@ export class SDKClient {
return resp;
}
catch (e: any) {
const statusCode = e.status ? e.status._code : Status.Unknown._code;
this.logger.debug(`Consensus Node query response: ${query.constructor.name} ${statusCode}`);
this.captureMetrics(
SDKClient.queryMode,
query.constructor.name,
e.status,
query._queryPayment?.toTinybars().toNumber(),
callerName);
const sdkClientError = new SDKClientError(e);
if(sdkClientError.isValidNetworkError()) {
this.logger.debug(`Consensus Node query response: ${query.constructor.name} ${sdkClientError.statusCode}`);
this.captureMetrics(
SDKClient.queryMode,
query.constructor.name,
sdkClientError.status,
query._queryPayment?.toTinybars().toNumber(),
callerName);
}

throw new SDKClientError(e.message, e?.status?._code);
throw sdkClientError;
}
};

Expand All @@ -275,23 +277,25 @@ export class SDKClient {
return resp;
}
catch (e: any) {
const statusCode = e.status ? e.status._code : Status.Unknown._code;
this.logger.info(`Consensus Node ${transactionType} transaction response: ${statusCode}`);
this.captureMetrics(
SDKClient.transactionMode,
transactionType,
statusCode,
0,
callerName);
const sdkClientError = new SDKClientError(e);
if(sdkClientError.isValidNetworkError()) {
this.logger.info(`Consensus Node ${transactionType} transaction response: ${sdkClientError.statusCode}`);
this.captureMetrics(
SDKClient.transactionMode,
transactionType,
sdkClientError.statusCode,
0,
callerName);
}

throw new SDKClientError(e.message, e?.status?._code);
throw sdkClientError;
}
};

executeGetTransactionRecord = async (resp: TransactionResponse, transactionName: string, callerName: string): Promise<TransactionRecord> => {
try {
if (!resp.getRecord) {
throw new SDKClientError(`Invalid response format, expected record availability: ${JSON.stringify(resp)}`);
throw new SDKClientError({}, `Invalid response format, expected record availability: ${JSON.stringify(resp)}`);
}

const transactionRecord: TransactionRecord = await resp.getRecord(this.clientMain);
Expand All @@ -306,16 +310,17 @@ export class SDKClient {
}
catch (e: any) {
// capture sdk record retrieval errors and shorten familiar stack trace
if (e.status && e.status._code) {
const sdkClientError = new SDKClientError(e);
if(sdkClientError.isValidNetworkError()) {
this.captureMetrics(
SDKClient.transactionMode,
transactionName,
e.status,
sdkClientError.status,
0,
callerName);
}

throw new SDKClientError(e.message, e?.status?._code);
throw sdkClientError;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
*
*/

import { Status } from "@hashgraph/sdk";

export class JsonRpcError {
public code: number;
public message: string;
Expand Down Expand Up @@ -108,28 +106,4 @@ export const predefined = {
code: -32602,
message: 'Value below 10_000_000_000 wei which is 1 tinybar'
}),
};

export class SDKClientError extends Error {
public statusCode: number;

constructor(message: string, statusCode?: number) {
super(message);
this.statusCode = statusCode ? statusCode : Status.Unknown._code;
this.name = "SDKClientError";

Object.setPrototypeOf(this, SDKClientError.prototype);
}
}

export class MirrorNodeClientError extends Error {
public statusCode: number;

constructor(message: string, statusCode: number) {
super(message);
this.statusCode = statusCode;
this.name = "MirrorNodeClientError";

Object.setPrototypeOf(this, MirrorNodeClientError.prototype);
}
}
};
31 changes: 31 additions & 0 deletions packages/relay/src/lib/errors/MirrorNodeClientError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

/*-
*
* Hedera JSON RPC Relay
*
* Copyright (C) 2022 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

export class MirrorNodeClientError extends Error {
public statusCode: number;

constructor(message: string, statusCode: number) {
super(message);
this.statusCode = statusCode;

Object.setPrototypeOf(this, MirrorNodeClientError.prototype);
}
}
55 changes: 55 additions & 0 deletions packages/relay/src/lib/errors/SDKClientError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*-
*
* Hedera JSON RPC Relay
*
* Copyright (C) 2022 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import { Status } from "@hashgraph/sdk";

export class SDKClientError extends Error {
public status: Status = Status.Unknown;
private validNetworkError: boolean = false;

constructor(e: any, message?: string) {
super(e && e.status && e.status._code ? e.message : message);

if(e && e.status && e.status._code) {
this.validNetworkError = true;
this.status = e.status;
}

Object.setPrototypeOf(this, SDKClientError.prototype);
}

get statusCode(): number {
return this.status._code;
}

public isValidNetworkError(): boolean {
return this.validNetworkError;
}

public isInvalidAccountId(): boolean {
return this.isValidNetworkError() && this.statusCode === Status.InvalidAccountId._code;
}

public isInvalidContractId(): boolean {
return this.isValidNetworkError() &&
(this.statusCode === Status.InvalidContractId._code || this.message?.includes(Status.InvalidContractId.toString()));
}
}

9 changes: 5 additions & 4 deletions packages/relay/src/lib/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { BigNumber } from '@hashgraph/sdk/lib/Transfer';
import { Logger } from 'pino';
import { Block, Transaction, Log } from './model';
import { MirrorNodeClient, SDKClient } from './clients';
import { JsonRpcError, predefined, SDKClientError } from './errors';
import { JsonRpcError, predefined } from './errors/JsonRpcError';
import { SDKClientError } from './errors/SDKClientError';
import constants from './constants';
import { Precheck } from './precheck';

Expand Down Expand Up @@ -233,7 +234,7 @@ export class EthImpl implements Eth {
'transaction_type': EthImpl.ethTxType
}
]
};
};
}

if (networkFees && Array.isArray(networkFees.fees)) {
Expand Down Expand Up @@ -456,7 +457,7 @@ export class EthImpl implements Eth {
} catch (e: any) {
if(e instanceof SDKClientError) {
// handle INVALID_ACCOUNT_ID
if (e.statusCode === Status.InvalidAccountId._code) {
if (e.isInvalidAccountId()) {
this.logger.debug(`Unable to find account ${account} in block ${JSON.stringify(blockNumber)}(${blockNumberOrTag}), returning 0x0 balance`);
cache.set(cachedLabel, EthImpl.zeroHex, constants.CACHE_TTL.ONE_HOUR);
return EthImpl.zeroHex;
Expand Down Expand Up @@ -490,7 +491,7 @@ export class EthImpl implements Eth {
} catch (e: any) {
if(e instanceof SDKClientError) {
// handle INVALID_CONTRACT_ID
if (e.statusCode === Status.InvalidContractId._code || e?.message?.includes(Status.InvalidContractId.toString())) {
if (e.isInvalidContractId()) {
this.logger.debug('Unable to find code for contract %s in block "%s", returning 0x0, err code: %s', address, blockNumber, e.statusCode);
cache.set(cachedLabel, '0x0', constants.CACHE_TTL.ONE_HOUR);
return '0x0';
Expand Down
2 changes: 1 addition & 1 deletion packages/relay/src/lib/precheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/

import * as ethers from 'ethers';
import { predefined } from './errors';
import { predefined } from './errors/JsonRpcError';
import { MirrorNodeClient, SDKClient } from './clients';
import { EthImpl } from './eth';
import { Logger } from 'pino';
Expand Down
11 changes: 8 additions & 3 deletions packages/relay/tests/lib/eth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import pino from 'pino';
import { Block, Transaction } from '../../src/lib/model';
import constants from '../../src/lib/constants';
import { SDKClient } from '../../src/lib/clients';
import { SDKClientError } from '../../src/lib/errors';
import { SDKClientError } from '../../src/lib/errors/SDKClientError';

const logger = pino();
const registry = new Registry();
Expand Down Expand Up @@ -904,7 +904,10 @@ describe('Eth calls using MirrorNode', async function () {
mock.onGet(`accounts/${contractAddress1}`).reply(200, {
account: contractAddress1
});
sdkClientStub.getAccountBalanceInWeiBar.throws(new SDKClientError("eth_getBalance exception", 15));
sdkClientStub.getAccountBalanceInWeiBar.throws(new SDKClientError(
{status: {
_code: 15
}}));

const resNoCache = await ethImpl.getBalance(contractAddress1, null);
const resCached = await ethImpl.getBalance(contractAddress1, null);
Expand Down Expand Up @@ -947,7 +950,9 @@ describe('Eth calls using MirrorNode', async function () {

describe('eth_getCode', async function() {
it('should return cached value', async () => {
sdkClientStub.getContractByteCode.throws(new SDKClientError("eth_getBalance exception", 16));
sdkClientStub.getContractByteCode.throws(new SDKClientError({status: {
_code: 16
}}));

const resNoCache = await ethImpl.getCode(contractAddress1, null);
const resCached = await ethImpl.getCode(contractAddress1, null);
Expand Down
2 changes: 1 addition & 1 deletion packages/server/tests/acceptance/rpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { AccountBalanceQuery, ContractFunctionParameters } from '@hashgraph/sdk'
import parentContractJson from '../contracts/Parent.json';
import basicContractJson from '../contracts/Basic.json';
import logsContractJson from '../contracts/Logs.json';
import { predefined } from '../../../relay/src/lib/errors';
import { predefined } from '../../../relay/src/lib/errors/JsonRpcError';

describe('RPC Server Acceptance Tests', function () {
this.timeout(240 * 1000); // 240 seconds
Expand Down
2 changes: 1 addition & 1 deletion packages/server/tests/clients/relayClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { ethers, providers } from 'ethers';
import { Logger } from 'pino';
import Assertions from '../helpers/assertions';
import { predefined } from '../../../relay/src/lib/errors';
import { predefined } from '../../../relay/src/lib/errors/JsonRpcError';

export default class RelayClient {

Expand Down
2 changes: 1 addition & 1 deletion packages/server/tests/helpers/assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/
import { expect } from 'chai';
import { ethers, BigNumber } from 'ethers';
import { JsonRpcError, predefined } from '../../../relay/src/lib/errors';
import { JsonRpcError, predefined } from '../../../relay/src/lib/errors/JsonRpcError';
import { Utils } from './utils';

export default class Assertions {
Expand Down

0 comments on commit eea0081

Please sign in to comment.