From 4c0869e38a13482fcc27bc89e19b691a87c3ab0e Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Fri, 30 Aug 2024 15:44:51 +0300 Subject: [PATCH 01/48] Makes ip address of request available in application layer Signed-off-by: Konstantina Blazhukova --- packages/relay/src/index.ts | 37 ++- .../relay/src/lib/clients/mirrorNodeClient.ts | 18 +- packages/relay/src/lib/clients/sdkClient.ts | 165 +++++----- packages/relay/src/lib/eth.ts | 309 +++++++++++------- packages/relay/src/lib/poller.ts | 8 +- .../ethCommonService/ICommonService.ts | 4 +- .../ethService/ethCommonService/index.ts | 16 +- .../ethFilterService/IFilterService.ts | 12 +- .../ethService/ethFilterService/index.ts | 13 +- .../relay/src/lib/types/IRequestDetails.ts | 4 + packages/server/src/koaJsonRpc/index.ts | 7 + packages/server/src/server.ts | 39 ++- packages/server/src/types/types.ts | 4 + 13 files changed, 374 insertions(+), 262 deletions(-) create mode 100644 packages/relay/src/lib/types/IRequestDetails.ts create mode 100644 packages/server/src/types/types.ts diff --git a/packages/relay/src/index.ts b/packages/relay/src/index.ts index 3c95d53ce5..78dceae2b5 100644 --- a/packages/relay/src/index.ts +++ b/packages/relay/src/index.ts @@ -26,6 +26,7 @@ import { MirrorNodeClientError } from './lib/errors/MirrorNodeClientError'; import { MirrorNodeClient } from './lib/clients'; import { IFilterService } from './lib/services/ethService/ethFilterService/IFilterService'; import { IDebugService } from './lib/services/debugService/IDebugService'; +import { IRequestDetails } from '../src/lib/types/IRequestDetails'; export { JsonRpcError, predefined, MirrorNodeClientError, WebSocketError }; @@ -62,9 +63,9 @@ export interface Net { } export interface Eth { - blockNumber(requestId?: string): Promise; + blockNumber(requestIdPrefix: string): Promise; - call(call: any, blockParam: string | object | null, requestId?: string): Promise; + call(call: any, blockParam: string | object | null, requestDetails: IRequestDetails): Promise; coinbase(requestId?: string): JsonRpcError; @@ -74,19 +75,19 @@ export interface Eth { requestId?: string, ): Promise; - gasPrice(requestId?: string): Promise; + gasPrice(requestDetails: IRequestDetails): Promise; - getBalance(account: string, blockNumber: string | null, requestId?: string): Promise; + getBalance(account: string, blockNumber: string | null, requestIdPrefix: string): Promise; - getBlockByHash(hash: string, showDetails: boolean, requestId?: string): Promise; + getBlockByHash(hash: string, showDetails: boolean, requestDetails: IRequestDetails): Promise; - getBlockByNumber(blockNum: string, showDetails: boolean, requestId?: string): Promise; + getBlockByNumber(blockNum: string, showDetails: boolean, requestDetails: IRequestDetails): Promise; - getBlockTransactionCountByHash(hash: string, requestId?: string): Promise; + getBlockTransactionCountByHash(hash: string, requestIdPrefix: string): Promise; - getBlockTransactionCountByNumber(blockNum: string, requestId?: string): Promise; + getBlockTransactionCountByNumber(blockNum: string, requestIdPrefix: string): Promise; - getCode(address: string, blockNumber: string | null, requestId?: string): Promise; + getCode(address: string, blockNumber: string | null, requestDetails: IRequestDetails): Promise; chainId(requestId?: string): string; @@ -99,17 +100,21 @@ export interface Eth { requestId?: string, ): Promise; - getStorageAt(address: string, slot: string, blockNumber: string | null, requestId?: string): Promise; + getStorageAt(requestIdPrefix: string, address: string, slot: string, blockNumber: string | null): Promise; getTransactionByBlockHashAndIndex(hash: string, index: string, requestId?: string): Promise; - getTransactionByBlockNumberAndIndex(blockNum: string, index: string, requestId?: string): Promise; + getTransactionByBlockNumberAndIndex( + blockNum: string, + index: string, + requestIdPrefix: string, + ): Promise; - getTransactionByHash(hash: string, requestId?: string): Promise; + getTransactionByHash(hash: string, requestIdPrefix: string): Promise; - getTransactionCount(address: string, blockNum: string, requestId?: string): Promise; + getTransactionCount(address: string, blockNum: string, requestIdPrefix: string): Promise; - getTransactionReceipt(hash: string, requestId?: string): Promise; + getTransactionReceipt(hash: string, requestDetails: IRequestDetails): Promise; getUncleByBlockHashAndIndex(requestId?: string): Promise; @@ -125,7 +130,7 @@ export interface Eth { blockCount: number, newestBlock: string, rewardPercentiles: Array | null, - requestId?: string, + requestDetails: IRequestDetails, ): Promise; hashrate(requestId?: string): Promise; @@ -136,7 +141,7 @@ export interface Eth { protocolVersion(requestId?: string): JsonRpcError; - sendRawTransaction(transaction: string, requestId: string): Promise; + sendRawTransaction(transaction: string, requestDetails: IRequestDetails): Promise; sendTransaction(requestId?: string): JsonRpcError; diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index 244347b2b5..5f8141f72a 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -591,10 +591,10 @@ export class MirrorNodeClient { } public async getBlocks( + requestIdPrefix: string, blockNumber?: number | string[], timestamp?: string, limitOrderParams?: ILimitOrderParams, - requestIdPrefix?: string, ) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'block.number', blockNumber); @@ -825,9 +825,9 @@ export class MirrorNodeClient { } public async getContractResultsLogs( + requestIdPrefix: string, contractLogsResultsParams?: IContractLogsResultsParams, limitOrderParams?: ILimitOrderParams, - requestIdPrefix?: string, ) { const queryParams = this.prepareLogsParams(contractLogsResultsParams, limitOrderParams); @@ -867,22 +867,22 @@ export class MirrorNodeClient { ); } - public async getEarliestBlock(requestId?: string) { + public async getEarliestBlock(requestIdPrefix: string) { const cachedLabel = `${constants.CACHE_KEY.GET_BLOCK}.earliest`; const cachedResponse: any = await this.cacheService.getAsync( cachedLabel, MirrorNodeClient.GET_BLOCKS_ENDPOINT, - requestId, + requestIdPrefix, ); if (cachedResponse != undefined) { return cachedResponse; } const blocks = await this.getBlocks( + requestIdPrefix, undefined, undefined, this.getLimitOrderQueryParam(1, MirrorNodeClient.ORDER.ASC), - requestId, ); if (blocks && blocks.blocks.length > 0) { const block = blocks.blocks[0]; @@ -891,7 +891,7 @@ export class MirrorNodeClient { block, MirrorNodeClient.GET_BLOCKS_ENDPOINT, constants.CACHE_TTL.ONE_DAY, - requestId, + requestIdPrefix, ); return block; } @@ -899,12 +899,12 @@ export class MirrorNodeClient { return null; } - public async getLatestBlock(requestIdPrefix?: string) { + public async getLatestBlock(requestIdPrefix: string) { return this.getBlocks( + requestIdPrefix, undefined, undefined, this.getLimitOrderQueryParam(1, MirrorNodeClient.ORDER.DESC), - requestIdPrefix, ); } @@ -924,7 +924,7 @@ export class MirrorNodeClient { ); } - public async getNetworkFees(timestamp?: string, order?: string, requestIdPrefix?: string) { + public async getNetworkFees(requestIdPrefix: string, timestamp?: string, order?: string) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'timestamp', timestamp); this.setQueryParam(queryParamObject, 'order', order); diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index 1478530eb4..b6445917ea 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -62,6 +62,7 @@ import { JsonRpcError, predefined } from './../errors/JsonRpcError'; import { CacheService } from '../services/cacheService/cacheService'; import { formatRequestIdMessage, weibarHexToTinyBarInt } from '../../formatters'; import { ITransactionRecordMetric, IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../types'; +import { IRequestDetails } from '../types/IRequestDetails'; const _ = require('lodash'); const LRU = require('lru-cache'); @@ -162,13 +163,17 @@ export class SDKClient { * @param {string} [requestId] - Optional request ID for tracking the request. * @returns {Promise} - A promise that resolves to the account balance. */ - async getAccountBalance(account: string, callerName: string, requestId?: string): Promise { + async getAccountBalance( + account: string, + callerName: string, + requestDetails: IRequestDetails, + ): Promise { return this.executeQuery( new AccountBalanceQuery().setAccountId(AccountId.fromString(account)), this.clientMain, callerName, account, - requestId, + requestDetails, ); } @@ -179,8 +184,12 @@ export class SDKClient { * @returns {Promise} The balance of the account in tinybars. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ - async getAccountBalanceInTinyBar(account: string, callerName: string, requestId?: string): Promise { - const balance = await this.getAccountBalance(account, callerName, requestId); + async getAccountBalanceInTinyBar( + account: string, + callerName: string, + requestDetails: IRequestDetails, + ): Promise { + const balance = await this.getAccountBalance(account, callerName, requestDetails); return balance.hbars.to(HbarUnit.Tinybar); } @@ -192,8 +201,12 @@ export class SDKClient { * @returns {Promise} The balance of the account in weiBars. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ - async getAccountBalanceInWeiBar(account: string, callerName: string, requestId?: string): Promise { - const balance = await this.getAccountBalance(account, callerName, requestId); + async getAccountBalanceInWeiBar( + account: string, + callerName: string, + requestDetails: IRequestDetails, + ): Promise { + const balance = await this.getAccountBalance(account, callerName, requestDetails); return SDKClient.HbarToWeiBar(balance); } @@ -205,13 +218,13 @@ export class SDKClient { * @returns {Promise} The information about the account. * @throws {SDKClientError} Throws an SDK client error if the account info retrieval fails. */ - async getAccountInfo(address: string, callerName: string, requestId?: string): Promise { + async getAccountInfo(address: string, callerName: string, requestDetails: IRequestDetails): Promise { return this.executeQuery( new AccountInfoQuery().setAccountId(AccountId.fromString(address)), this.clientMain, callerName, address, - requestId, + requestDetails, ); } @@ -230,7 +243,7 @@ export class SDKClient { realm: number | Long, address: string, callerName: string, - requestId?: string, + requestDetails: IRequestDetails, ): Promise { const contractByteCodeQuery = new ContractByteCodeQuery().setContractId( ContractId.fromEvmAddress(shard, realm, address), @@ -242,7 +255,7 @@ export class SDKClient { this.clientMain, callerName, address, - requestId, + requestDetails, ); } @@ -254,13 +267,17 @@ export class SDKClient { * @returns {Promise} The balance of the contract. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ - async getContractBalance(contract: string, callerName: string, requestId?: string): Promise { + async getContractBalance( + contract: string, + callerName: string, + requestDetails: IRequestDetails, + ): Promise { return this.executeQuery( new AccountBalanceQuery().setContractId(ContractId.fromString(contract)), this.clientMain, callerName, contract, - requestId, + requestDetails, ); } @@ -273,8 +290,12 @@ export class SDKClient { * @returns {Promise} The contract balance in weiBars. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ - async getContractBalanceInWeiBar(account: string, callerName: string, requestId?: string): Promise { - const balance = await this.getContractBalance(account, callerName, requestId); + async getContractBalanceInWeiBar( + account: string, + callerName: string, + requestDetails: IRequestDetails, + ): Promise { + const balance = await this.getContractBalance(account, callerName, requestDetails); return SDKClient.HbarToWeiBar(balance); } @@ -285,8 +306,8 @@ export class SDKClient { * @returns {Promise} The exchange rates. * @throws {SDKClientError} Throws an SDK client error if the exchange rates file retrieval or parsing fails. */ - async getExchangeRate(callerName: string, requestId?: string): Promise { - const exchangeFileBytes = await this.getFileIdBytes(constants.EXCHANGE_RATE_FILE_ID, callerName, requestId); + async getExchangeRate(callerName: string, requestDetails: IRequestDetails): Promise { + const exchangeFileBytes = await this.getFileIdBytes(constants.EXCHANGE_RATE_FILE_ID, callerName, requestDetails); return ExchangeRates.fromBytes(exchangeFileBytes); } @@ -298,8 +319,8 @@ export class SDKClient { * @returns {Promise} The fee schedules. * @throws {SDKClientError} Throws an SDK client error if the fee schedule file retrieval or parsing fails. */ - async getFeeSchedule(callerName: string, requestId?: string): Promise { - const feeSchedulesFileBytes = await this.getFileIdBytes(constants.FEE_SCHEDULE_FILE_ID, callerName, requestId); + async getFeeSchedule(callerName: string, requestDetails: IRequestDetails): Promise { + const feeSchedulesFileBytes = await this.getFileIdBytes(constants.FEE_SCHEDULE_FILE_ID, callerName, requestDetails); return FeeSchedules.fromBytes(feeSchedulesFileBytes); } @@ -314,17 +335,17 @@ export class SDKClient { * @returns {Promise} The gas fee in tinybars. * @throws {SDKClientError} Throws an SDK client error if the fee schedules or exchange rates are invalid. */ - async getTinyBarGasFee(callerName: string, requestId?: string): Promise { + async getTinyBarGasFee(callerName: string, requestDetails: IRequestDetails): Promise { const cachedResponse: number | undefined = await this.cacheService.getAsync( constants.CACHE_KEY.GET_TINYBAR_GAS_FEE, callerName, - requestId, + requestDetails.requestIdPrefix, ); if (cachedResponse) { return cachedResponse; } - const feeSchedules = await this.getFeeSchedule(callerName, requestId); + const feeSchedules = await this.getFeeSchedule(callerName, requestDetails); if (_.isNil(feeSchedules.current) || feeSchedules.current?.transactionFeeSchedule === undefined) { throw new SDKClientError({}, 'Invalid FeeSchedules proto format'); } @@ -332,7 +353,7 @@ export class SDKClient { for (const schedule of feeSchedules.current?.transactionFeeSchedule) { if (schedule.hederaFunctionality?._code === constants.ETH_FUNCTIONALITY_CODE && schedule.fees !== undefined) { // get exchange rate & convert to tiny bar - const exchangeRates = await this.getExchangeRate(callerName, requestId); + const exchangeRates = await this.getExchangeRate(callerName, requestDetails); const tinyBars = this.convertGasPriceToTinyBars(schedule.fees[0].servicedata, exchangeRates); await this.cacheService.set( @@ -340,7 +361,7 @@ export class SDKClient { tinyBars, callerName, undefined, - requestId, + requestDetails.requestIdPrefix, ); return tinyBars; } @@ -357,13 +378,13 @@ export class SDKClient { * @returns {Promise} The contents of the file as a byte array. * @throws {SDKClientError} Throws an SDK client error if the file query fails. */ - async getFileIdBytes(address: string, callerName: string, requestId?: string): Promise { + async getFileIdBytes(address: string, callerName: string, requestDetails: IRequestDetails): Promise { return this.executeQuery( new FileContentsQuery().setFileId(address), this.clientMain, callerName, address, - requestId, + requestDetails, ); } @@ -384,6 +405,7 @@ export class SDKClient { async submitEthereumTransaction( transactionBuffer: Uint8Array, callerName: string, + requestDetails: IRequestDetails, originalCallerAddress: string, networkGasPriceInWeiBars: number, currentNetworkExchangeRateInCents: number, @@ -393,7 +415,6 @@ export class SDKClient { const ethereumTransaction = new EthereumTransaction(); const interactingEntity = ethereumTransactionData.toJSON()['to'].toString(); let fileId: FileId | null = null; - const requestIdPrefix = formatRequestIdMessage(requestId); // if callData's size is greater than `fileAppendChunkSize` => employ HFS to create new file to carry the rest of the contents of callData if (ethereumTransactionData.callData.length <= this.fileAppendChunkSize) { @@ -408,7 +429,7 @@ export class SDKClient { hexCallDataLength, this.fileAppendChunkSize, currentNetworkExchangeRateInCents, - requestId, + requestDetails.requestIdPrefix, ); if (shouldPreemptivelyLimit) { @@ -419,13 +440,13 @@ export class SDKClient { fileId = await this.createFile( ethereumTransactionData.callData, this.clientMain, - requestId, + requestDetails, callerName, interactingEntity, originalCallerAddress, ); if (!fileId) { - throw new SDKClientError({}, `${requestIdPrefix} No fileId created for transaction. `); + throw new SDKClientError({}, `${requestDetails.requestIdPrefix} No fileId created for transaction. `); } ethereumTransactionData.callData = new Uint8Array(); ethereumTransaction.setEthereumData(ethereumTransactionData.toBytes()).setCallDataFileId(fileId); @@ -442,7 +463,7 @@ export class SDKClient { ethereumTransaction, callerName, interactingEntity, - requestId, + requestDetails, true, originalCallerAddress, ), @@ -466,7 +487,7 @@ export class SDKClient { gas: number, from: string, callerName: string, - requestId?: string, + requestDetails: IRequestDetails, ): Promise { const contract = SDKClient.prune0x(to); const contractId = contract.startsWith('00000000000') @@ -488,7 +509,7 @@ export class SDKClient { contractCallQuery.setPaymentTransactionId(TransactionId.generate(this.clientMain.operatorAccountId)); } - return this.executeQuery(contractCallQuery, this.clientMain, callerName, to, requestId); + return this.executeQuery(contractCallQuery, this.clientMain, callerName, to, requestDetails); } /** @@ -509,21 +530,20 @@ export class SDKClient { gas: number, from: string, callerName: string, - requestId?: string, + requestDetails: IRequestDetails, ): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); let retries = 0; let resp; while (parseInt(process.env.CONTRACT_QUERY_TIMEOUT_RETRIES || '1') > retries) { try { - resp = await this.submitContractCallQuery(to, data, gas, from, callerName, requestId); + resp = await this.submitContractCallQuery(to, data, gas, from, callerName, requestDetails); return resp; } catch (e: any) { const sdkClientError = new SDKClientError(e, e.message); if (sdkClientError.isTimeoutExceeded()) { const delay = retries * 1000; this.logger.trace( - `${requestIdPrefix} Contract call query failed with status ${sdkClientError.message}. Retrying again after ${delay} ms ...`, + `${requestDetails.requestIdPrefix} Contract call query failed with status ${sdkClientError.message}. Retrying again after ${delay} ms ...`, ); retries++; await new Promise((r) => setTimeout(r, delay)); @@ -555,7 +575,7 @@ export class SDKClient { client: Client, maxRetries: number, currentRetry: number, - requestId?: string, + requestIdPrefix?: string, ): Promise<{ resp: any; cost: Hbar }> { const baseMultiplier = constants.QUERY_COST_INCREMENTATION_STEP; const multiplier = Math.pow(baseMultiplier, currentRetry); @@ -569,8 +589,8 @@ export class SDKClient { const sdkClientError = new SDKClientError(e, e.message); if (maxRetries > currentRetry && sdkClientError.isInsufficientTxFee()) { const newRetry = currentRetry + 1; - this.logger.info(`${requestId} Retrying query execution with increased cost, retry number: ${newRetry}`); - return await this.increaseCostAndRetryExecution(query, baseCost, client, maxRetries, newRetry, requestId); + this.logger.info(`${requestIdPrefix} Retrying query execution with increased cost, retry number: ${newRetry}`); + return await this.increaseCostAndRetryExecution(query, baseCost, client, maxRetries, newRetry, requestIdPrefix); } throw e; @@ -592,10 +612,11 @@ export class SDKClient { client: Client, callerName: string, interactingEntity: string, - requestId?: string, + requestDetails: IRequestDetails, ): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); const queryConstructorName = query.constructor.name; + const requestIdPrefix = requestDetails?.requestIdPrefix; + const queryType = query.constructor.name; let queryResponse: any = null; let queryCost: number | undefined = undefined; let status: string = ''; @@ -605,7 +626,7 @@ export class SDKClient { try { if (query.paymentTransactionId) { const baseCost = await query.getCost(this.clientMain); - const res = await this.increaseCostAndRetryExecution(query, baseCost, client, 3, 0, requestId); + const res = await this.increaseCostAndRetryExecution(query, baseCost, client, 3, 0, requestIdPrefix); queryResponse = res.resp; queryCost = res.cost.toTinybars().toNumber(); } else { @@ -670,11 +691,10 @@ export class SDKClient { transaction: Transaction, callerName: string, interactingEntity: string, - requestId: string, + requestDetails: IRequestDetails, shouldThrowHbarLimit: boolean, originalCallerAddress: string, ): Promise { - const formattedRequestId = formatRequestIdMessage(requestId); const txConstructorName = transaction.constructor.name; let transactionId: string = ''; let transactionResponse: TransactionResponse | null = null; @@ -685,7 +705,7 @@ export class SDKClient { constants.EXECUTION_MODE.TRANSACTION, callerName, originalCallerAddress, - requestId, + requestDetails.requestIdPrefix, ); if (shouldLimit) { throw predefined.HBAR_RATE_LIMIT_EXCEEDED; @@ -693,7 +713,7 @@ export class SDKClient { } try { - this.logger.info(`${formattedRequestId} Execute ${txConstructorName} transaction`); + this.logger.info(`${requestDetails.requestIdPrefix} Execute ${txConstructorName} transaction`); transactionResponse = await transaction.execute(this.clientMain); transactionId = transactionResponse.transactionId.toString(); @@ -702,7 +722,7 @@ export class SDKClient { const transactionReceipt = await transactionResponse.getReceipt(this.clientMain); this.logger.info( - `${formattedRequestId} Successfully execute ${txConstructorName} transaction: transactionId=${transactionResponse.transactionId}, callerName=${callerName}, status=${transactionReceipt.status}(${transactionReceipt.status._code})`, + `${requestDetails.requestIdPrefix} Successfully execute ${txConstructorName} transaction: transactionId=${transactionResponse.transactionId}, callerName=${callerName}, status=${transactionReceipt.status}(${transactionReceipt.status._code})`, ); return transactionResponse; } catch (e: any) { @@ -719,12 +739,12 @@ export class SDKClient { this.logger.warn( sdkClientError, - `${formattedRequestId} Fail to execute ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, + `${requestDetails.requestIdPrefix} Fail to execute ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, ); if (!transactionResponse) { throw predefined.INTERNAL_ERROR( - `${formattedRequestId} Transaction execution returns a null value: transactionId=${transaction.transactionId}, callerName=${callerName}, txConstructorName=${txConstructorName}`, + `${requestDetails.requestIdPrefix} Transaction execution returns a null value: transactionId=${transaction.transactionId}, callerName=${callerName}, txConstructorName=${txConstructorName}`, ); } return transactionResponse; @@ -733,7 +753,7 @@ export class SDKClient { this.eventEmitter.emit(constants.EVENTS.EXECUTE_TRANSACTION, { transactionId, callerName, - requestId, + requestId: requestDetails.requestIdPrefix, txConstructorName, operatorAccountId: this.clientMain.operatorAccountId!.toString(), interactingEntity, @@ -758,11 +778,10 @@ export class SDKClient { transaction: FileAppendTransaction, callerName: string, interactingEntity: string, - requestId: string, + requestDetails: IRequestDetails, shouldThrowHbarLimit: boolean, originalCallerAddress: string, ): Promise { - const formattedRequestId = formatRequestIdMessage(requestId); const txConstructorName = transaction.constructor.name; let transactionResponses: TransactionResponse[] | null = null; @@ -772,7 +791,7 @@ export class SDKClient { constants.EXECUTION_MODE.TRANSACTION, callerName, originalCallerAddress, - requestId, + requestDetails.requestIdPrefix, ); if (shouldLimit) { throw predefined.HBAR_RATE_LIMIT_EXCEEDED; @@ -780,17 +799,17 @@ export class SDKClient { } try { - this.logger.info(`${formattedRequestId} Execute ${txConstructorName} transaction`); + this.logger.info(`${requestDetails.requestIdPrefix} Execute ${txConstructorName} transaction`); transactionResponses = await transaction.executeAll(this.clientMain); this.logger.info( - `${formattedRequestId} Successfully execute all ${transactionResponses.length} ${txConstructorName} transactions: callerName=${callerName}, status=${Status.Success}(${Status.Success._code})`, + `${requestDetails.requestIdPrefix} Successfully execute all ${transactionResponses.length} ${txConstructorName} transactions: callerName=${callerName}, status=${Status.Success}(${Status.Success._code})`, ); } catch (e: any) { const sdkClientError = new SDKClientError(e, e.message); this.logger.warn( - `${formattedRequestId} Fail to executeAll for ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, transactionType=${txConstructorName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, + `${requestDetails.requestIdPrefix} Fail to executeAll for ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, transactionType=${txConstructorName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, ); throw sdkClientError; } finally { @@ -800,7 +819,7 @@ export class SDKClient { this.eventEmitter.emit(constants.EVENTS.EXECUTE_TRANSACTION, { transactionId: transactionResponse.transactionId.toString(), callerName, - requestId, + requestId: requestDetails.requestIdPrefix, txConstructorName, operatorAccountId: this.clientMain.operatorAccountId!.toString(), interactingEntity, @@ -825,12 +844,11 @@ export class SDKClient { async createFile( callData: Uint8Array, client: Client, - requestId: string, + requestDetails: IRequestDetails, callerName: string, interactingEntity: string, originalCallerAddress: string, ): Promise { - const formattedRequestId = formatRequestIdMessage(requestId); const hexedCallData = Buffer.from(callData).toString('hex'); const fileCreateTx = new FileCreateTransaction() @@ -841,7 +859,7 @@ export class SDKClient { fileCreateTx, callerName, interactingEntity, - formattedRequestId, + requestDetails, true, originalCallerAddress, ); @@ -859,7 +877,7 @@ export class SDKClient { fileAppendTx, callerName, interactingEntity, - formattedRequestId, + requestDetails, true, originalCallerAddress, ); @@ -871,14 +889,16 @@ export class SDKClient { this.clientMain, callerName, interactingEntity, - requestId, + requestDetails, ); if (fileInfo.size.isZero()) { - this.logger.warn(`${requestId} File ${fileId} is empty.`); - throw new SDKClientError({}, `${requestId} Created file is empty. `); + this.logger.warn(`${requestDetails.requestIdPrefix} File ${fileId} is empty.`); + throw new SDKClientError({}, `${requestDetails.requestIdPrefix} Created file is empty. `); } - this.logger.trace(`${formattedRequestId} Created file with fileId: ${fileId} and file size ${fileInfo.size}`); + this.logger.trace( + `${requestDetails.requestIdPrefix} Created file with fileId: ${fileId} and file size ${fileInfo.size}`, + ); } return fileId; @@ -897,13 +917,11 @@ export class SDKClient { */ async deleteFile( fileId: FileId, - requestId: string, + requestDetails: IRequestDetails, callerName: string, interactingEntity: string, originalCallerAddress: string, ): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); - try { const fileDeleteTx = new FileDeleteTransaction() .setFileId(fileId) @@ -914,7 +932,7 @@ export class SDKClient { fileDeleteTx, callerName, interactingEntity, - requestId, + requestDetails, false, originalCallerAddress, ); @@ -924,16 +942,16 @@ export class SDKClient { this.clientMain, callerName, interactingEntity, - requestId, + requestDetails, ); if (fileInfo.isDeleted) { - this.logger.trace(`${requestIdPrefix} Deleted file with fileId: ${fileId}`); + this.logger.trace(`${requestDetails.requestIdPrefix} Deleted file with fileId: ${fileId}`); } else { - this.logger.warn(`${requestIdPrefix} Fail to delete file with fileId: ${fileId} `); + this.logger.warn(`${requestDetails.requestIdPrefix} Fail to delete file with fileId: ${fileId} `); } } catch (error: any) { - this.logger.warn(`${requestIdPrefix} ${error['message']} `); + this.logger.warn(`${requestDetails.requestIdPrefix} ${error['message']} `); } } @@ -982,7 +1000,6 @@ export class SDKClient { let gasUsed: number = 0; let transactionFee: number = 0; let txRecordChargeAmount: number = 0; - const formattedRequestId = formatRequestIdMessage(requestId); try { this.logger.trace( `${formattedRequestId} Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`, diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index a612251e5e..6287be2479 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -59,6 +59,8 @@ import { formatTransactionIdWithoutQueryParams, getFunctionSelector, } from '../formatters'; +import { IRequestDetails } from './types/IRequestDetails'; +import { time } from 'console'; const _ = require('lodash'); const createHash = require('keccak'); @@ -325,7 +327,7 @@ export class EthImpl implements Eth { blockCount: number, newestBlock: string, rewardPercentiles: Array | null, - requestIdPrefix?: string, + requestDetails: IRequestDetails, ): Promise { const maxResults = process.env.TEST === 'true' @@ -333,15 +335,15 @@ export class EthImpl implements Eth { : Number(process.env.FEE_HISTORY_MAX_RESULTS); this.logger.trace( - `${requestIdPrefix} feeHistory(blockCount=${blockCount}, newestBlock=${newestBlock}, rewardPercentiles=${rewardPercentiles})`, + `${requestDetails.requestIdPrefix} feeHistory(blockCount=${blockCount}, newestBlock=${newestBlock}, rewardPercentiles=${rewardPercentiles})`, ); try { - const latestBlockNumber = await this.translateBlockTag(EthImpl.blockLatest, requestIdPrefix); + const latestBlockNumber = await this.translateBlockTag(EthImpl.blockLatest, requestDetails.requestIdPrefix); const newestBlockNumber = newestBlock == EthImpl.blockLatest || newestBlock == EthImpl.blockPending ? latestBlockNumber - : await this.translateBlockTag(newestBlock, requestIdPrefix); + : await this.translateBlockTag(newestBlock, requestDetails.requestIdPrefix); if (newestBlockNumber > latestBlockNumber) { return predefined.REQUEST_BEYOND_HEAD_BLOCK(newestBlockNumber, latestBlockNumber); @@ -359,14 +361,18 @@ export class EthImpl implements Eth { blockCount = 1; oldestBlock = 1; } - const gasPriceFee = await this.gasPrice(requestIdPrefix); + const gasPriceFee = await this.gasPrice(requestDetails); feeHistory = this.getRepeatedFeeHistory(blockCount, oldestBlock, rewardPercentiles, gasPriceFee); } else { // once we finish testing and refining Fixed Fee method, we can remove this else block to clean up code const cacheKey = `${constants.CACHE_KEY.FEE_HISTORY}_${blockCount}_${newestBlock}_${rewardPercentiles?.join( '', )}`; - const cachedFeeHistory = await this.cacheService.getAsync(cacheKey, EthImpl.ethFeeHistory, requestIdPrefix); + const cachedFeeHistory = await this.cacheService.getAsync( + cacheKey, + EthImpl.ethFeeHistory, + requestDetails.requestIdPrefix, + ); if (cachedFeeHistory) { feeHistory = cachedFeeHistory; @@ -376,30 +382,36 @@ export class EthImpl implements Eth { newestBlockNumber, latestBlockNumber, rewardPercentiles, - requestIdPrefix, + requestDetails, ); } if (newestBlock != EthImpl.blockLatest && newestBlock != EthImpl.blockPending) { - await this.cacheService.set(cacheKey, feeHistory, EthImpl.ethFeeHistory, undefined, requestIdPrefix); + await this.cacheService.set( + cacheKey, + feeHistory, + EthImpl.ethFeeHistory, + undefined, + requestDetails.requestIdPrefix, + ); } } return feeHistory; } catch (e) { - this.logger.error(e, `${requestIdPrefix} Error constructing default feeHistory`); + this.logger.error(e, `${requestDetails.requestIdPrefix} Error constructing default feeHistory`); return EthImpl.feeHistoryEmptyResponse; } } - private async getFeeByBlockNumber(blockNumber: number, requestIdPrefix?: string): Promise { + private async getFeeByBlockNumber(blockNumber: number, requestDetails: IRequestDetails): Promise { let fee = 0; try { - const block = await this.mirrorNodeClient.getBlock(blockNumber, requestIdPrefix); - fee = await this.getFeeWeibars(EthImpl.ethFeeHistory, requestIdPrefix, `lte:${block.timestamp.to}`); + const block = await this.mirrorNodeClient.getBlock(blockNumber, requestDetails.requestIdPrefix); + fee = await this.getFeeWeibars(EthImpl.ethFeeHistory, requestDetails, `lte:${block.timestamp.to}`); } catch (error) { this.logger.warn( error, - `${requestIdPrefix} Fee history cannot retrieve block or fee. Returning ${fee} fee for block ${blockNumber}`, + `${requestDetails.requestIdPrefix} Fee history cannot retrieve block or fee. Returning ${fee} fee for block ${blockNumber}`, ); } @@ -436,7 +448,7 @@ export class EthImpl implements Eth { newestBlockNumber: number, latestBlockNumber: number, rewardPercentiles: Array | null, - requestIdPrefix?: string, + requestDetails: IRequestDetails, ): Promise { // include newest block number in the total block count const oldestBlockNumber = Math.max(0, newestBlockNumber - blockCount + 1); @@ -449,18 +461,18 @@ export class EthImpl implements Eth { // get fees from oldest to newest blocks for (let blockNumber = oldestBlockNumber; blockNumber <= newestBlockNumber; blockNumber++) { - const fee = await this.getFeeByBlockNumber(blockNumber, requestIdPrefix); + const fee = await this.getFeeByBlockNumber(blockNumber, requestDetails); feeHistory.baseFeePerGas?.push(fee); feeHistory.gasUsedRatio?.push(EthImpl.defaultGasUsedRatio); } // get latest block fee - let nextBaseFeePerGas = _.last(feeHistory.baseFeePerGas); + let nextBaseFeePerGas: string = _.last(feeHistory.baseFeePerGas); if (latestBlockNumber > newestBlockNumber) { // get next block fee if the newest block is not the latest - nextBaseFeePerGas = await this.getFeeByBlockNumber(newestBlockNumber + 1, requestIdPrefix); + nextBaseFeePerGas = await this.getFeeByBlockNumber(newestBlockNumber + 1, requestDetails); } if (nextBaseFeePerGas) { @@ -474,24 +486,28 @@ export class EthImpl implements Eth { return feeHistory; } - private async getFeeWeibars(callerName: string, requestIdPrefix?: string, timestamp?: string): Promise { + private async getFeeWeibars( + callerName: string, + requestDetails: IRequestDetails, + timestamp?: string, + ): Promise { let networkFees; try { - networkFees = await this.mirrorNodeClient.getNetworkFees(timestamp, undefined, requestIdPrefix); + networkFees = await this.mirrorNodeClient.getNetworkFees(requestDetails.requestIdPrefix, timestamp, undefined); } catch (e: any) { this.logger.warn( e, - `${requestIdPrefix} Mirror Node threw an error while retrieving fees. Fallback to consensus node.`, + `${requestDetails.requestIdPrefix} Mirror Node threw an error while retrieving fees. Fallback to consensus node.`, ); } if (_.isNil(networkFees)) { - this.logger.debug(`${requestIdPrefix} Mirror Node returned no network fees. Fallback to consensus node.`); + this.logger.debug(`${requestDetails.requestIdPrefix} Mirror Node returned no network fees. Fallback to consensus node.`); networkFees = { fees: [ { - gas: await this.hapiService.getSDKClient().getTinyBarGasFee(callerName, requestIdPrefix), + gas: await this.hapiService.getSDKClient().getTinyBarGasFee(callerName, requestDetails), transaction_type: EthImpl.ethTxType, }, ], @@ -514,7 +530,7 @@ export class EthImpl implements Eth { /** * Gets the most recent block number. */ - async blockNumber(requestIdPrefix?: string): Promise { + async blockNumber(requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} blockNumber()`); return await this.common.getLatestBlockNumber(requestIdPrefix); } @@ -522,7 +538,7 @@ export class EthImpl implements Eth { /** * Gets the most recent block number and timestamp.to which represents the block finality. */ - async blockNumberTimestamp(caller: string, requestIdPrefix?: string): Promise { + async blockNumberTimestamp(caller: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} blockNumber()`); const cacheKey = `${constants.CACHE_KEY.ETH_BLOCK_NUMBER}`; @@ -559,7 +575,7 @@ export class EthImpl implements Eth { async estimateGas( transaction: IContractCallRequest, _blockParam: string | null, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { const callData = transaction.data ? transaction.data : transaction.input; const callDataSize = callData ? callData.length : 0; @@ -622,7 +638,7 @@ export class EthImpl implements Eth { */ private async predefinedGasForTransaction( transaction: IContractCallRequest, - requestIdPrefix?: string, + requestIdPrefix: string, error?: any, ): Promise { const isSimpleTransfer = !!transaction?.to && (!transaction.data || transaction.data === '0x'); @@ -737,30 +753,30 @@ export class EthImpl implements Eth { * @returns {Promise} The current gas price in weibars as a hexadecimal string. * @throws Will throw an error if unable to retrieve the gas price. */ - async gasPrice(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} eth_gasPrice`); + async gasPrice(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} eth_gasPrice`); try { let gasPrice: number | undefined = await this.cacheService.getAsync( constants.CACHE_KEY.GAS_PRICE, EthImpl.ethGasPrice, - requestIdPrefix, + requestDetails.requestIdPrefix, ); if (!gasPrice) { - gasPrice = Utils.addPercentageBufferToGasPrice(await this.getFeeWeibars(EthImpl.ethGasPrice, requestIdPrefix)); + gasPrice = Utils.addPercentageBufferToGasPrice(await this.getFeeWeibars(EthImpl.ethGasPrice, requestDetails)); await this.cacheService.set( constants.CACHE_KEY.GAS_PRICE, gasPrice, EthImpl.ethGasPrice, this.ethGasPRiceCacheTtlMs, - requestIdPrefix, + requestDetails.requestIdPrefix, ); } return numberTo0x(gasPrice); } catch (error) { - throw this.common.genericErrorHandler(error, `${requestIdPrefix} Failed to retrieve gasPrice`); + throw this.common.genericErrorHandler(error, `${requestDetails.requestIdPrefix} Failed to retrieve gasPrice`); } } @@ -880,8 +896,8 @@ export class EthImpl implements Eth { async getStorageAt( address: string, slot: string, + requestIdPrefix: string, blockNumberOrTagOrHash?: string | null, - requestIdPrefix?: string, ): Promise { this.logger.trace( `${requestIdPrefix} getStorageAt(address=${address}, slot=${slot}, blockNumberOrOrHashTag=${blockNumberOrTagOrHash})`, @@ -889,7 +905,7 @@ export class EthImpl implements Eth { let result = EthImpl.zeroHex32Byte; // if contract or slot not found then return 32 byte 0 - const blockResponse = await this.common.getHistoricalBlockResponse(blockNumberOrTagOrHash, false, requestIdPrefix); + const blockResponse = await this.common.getHistoricalBlockResponse(requestIdPrefix, blockNumberOrTagOrHash, false); // To save a request to the mirror node for `latest` and `pending` blocks, we directly return null from `getHistoricalBlockResponse` // But if a block number or `earliest` tag is passed and the mirror node returns `null`, we should throw an error. if (!this.common.blockTagIsLatestOrPending(blockNumberOrTagOrHash) && blockResponse == null) { @@ -932,7 +948,7 @@ export class EthImpl implements Eth { * @param blockNumberOrTagOrHash * @param requestIdPrefix */ - async getBalance(account: string, blockNumberOrTagOrHash: string | null, requestIdPrefix?: string): Promise { + async getBalance(account: string, blockNumberOrTagOrHash: string | null, requestIdPrefix: string): Promise { const latestBlockTolerance = 1; this.logger.trace(`${requestIdPrefix} getBalance(account=${account}, blockNumberOrTag=${blockNumberOrTagOrHash})`); @@ -986,7 +1002,7 @@ export class EthImpl implements Eth { try { if (!this.common.blockTagIsLatestOrPending(blockNumberOrTagOrHash)) { - const block = await this.common.getHistoricalBlockResponse(blockNumberOrTagOrHash, true, requestIdPrefix); + const block = await this.common.getHistoricalBlockResponse(requestIdPrefix, blockNumberOrTagOrHash, true); if (block) { blockNumber = block.number; @@ -1072,6 +1088,7 @@ export class EthImpl implements Eth { // save in cache the current balance for the account and blockNumberOrTag cachedBalance = numberTo0x(weibars); + this.logger.trace('Value cached balance', cachedBalance); await this.cacheService.set( cacheKey, cachedBalance, @@ -1096,7 +1113,8 @@ export class EthImpl implements Eth { * @param blockNumber * @param requestIdPrefix */ - async getCode(address: string, blockNumber: string | null, requestIdPrefix?: string): Promise { + async getCode(address: string, blockNumber: string | null, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails?.requestIdPrefix; if (!EthImpl.isBlockParamValid(blockNumber)) { throw predefined.UNKNOWN_BLOCK( `The value passed is not a valid blockHash/blockNumber/blockTag value: ${blockNumber}`, @@ -1156,7 +1174,7 @@ export class EthImpl implements Eth { const bytecode = await this.hapiService .getSDKClient() - .getContractByteCode(0, 0, address, EthImpl.ethGetCode, requestIdPrefix); + .getContractByteCode(0, 0, address, EthImpl.ethGetCode, requestDetails); return prepend0x(Buffer.from(bytecode).toString('hex')); } catch (e: any) { if (e instanceof SDKClientError) { @@ -1204,16 +1222,25 @@ export class EthImpl implements Eth { * @param showDetails * @param requestIdPrefix */ - async getBlockByHash(hash: string, showDetails: boolean, requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} getBlockByHash(hash=${hash}, showDetails=${showDetails})`); + async getBlockByHash(hash: string, showDetails: boolean, requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} getBlockByHash(hash=${hash}, showDetails=${showDetails})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_BLOCK_BY_HASH}_${hash}_${showDetails}`; - let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByHash, requestIdPrefix); + let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByHash, requestDetails.requestIdPrefix); if (!block) { - block = await this.getBlock(hash, showDetails, requestIdPrefix).catch((e: any) => { - throw this.common.genericErrorHandler(e, `${requestIdPrefix} Failed to retrieve block for hash ${hash}`); + block = await this.getBlock(hash, showDetails, requestDetails).catch((e: any) => { + throw this.common.genericErrorHandler( + e, + `${requestDetails.requestIdPrefix} Failed to retrieve block for hash ${hash}`, + ); }); - await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByHash, undefined, requestIdPrefix); + await this.cacheService.set( + cacheKey, + block, + EthImpl.ethGetBlockByHash, + undefined, + requestDetails.requestIdPrefix, + ); } return block; @@ -1225,21 +1252,27 @@ export class EthImpl implements Eth { * @param showDetails * @param requestIdPrefix */ - async getBlockByNumber(blockNumOrTag: string, showDetails: boolean, requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} getBlockByNumber(blockNum=${blockNumOrTag}, showDetails=${showDetails})`); + async getBlockByNumber( + blockNumOrTag: string, + showDetails: boolean, + requestDetails: IRequestDetails, + ): Promise { + this.logger.trace( + `${requestDetails.requestIdPrefix} getBlockByNumber(blockNum=${blockNumOrTag}, showDetails=${showDetails})`, + ); const cacheKey = `${constants.CACHE_KEY.ETH_GET_BLOCK_BY_NUMBER}_${blockNumOrTag}_${showDetails}`; - let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByNumber, requestIdPrefix); + let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByNumber, requestDetails.requestIdPrefix); if (!block) { - block = await this.getBlock(blockNumOrTag, showDetails, requestIdPrefix).catch((e: any) => { + block = await this.getBlock(blockNumOrTag, showDetails, requestDetails).catch((e: any) => { throw this.common.genericErrorHandler( e, - `${requestIdPrefix} Failed to retrieve block for blockNum ${blockNumOrTag}`, + `${requestDetails.requestIdPrefix} Failed to retrieve block for blockNum ${blockNumOrTag}`, ); }); if (!this.common.blockTagIsLatestOrPending(blockNumOrTag)) { - await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, undefined, requestIdPrefix); + await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, undefined, requestDetails.requestIdPrefix); } } @@ -1290,7 +1323,7 @@ export class EthImpl implements Eth { * @param blockNumOrTag * @param requestIdPrefix */ - async getBlockTransactionCountByNumber(blockNumOrTag: string, requestIdPrefix?: string): Promise { + async getBlockTransactionCountByNumber(blockNumOrTag: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} getBlockTransactionCountByNumber(blockNum=${blockNumOrTag}, showDetails=%o)`); const blockNum = await this.translateBlockTag(blockNumOrTag, requestIdPrefix); @@ -1337,7 +1370,7 @@ export class EthImpl implements Eth { async getTransactionByBlockHashAndIndex( blockHash: string, transactionIndex: string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { this.logger.trace( `${requestIdPrefix} getTransactionByBlockHashAndIndex(hash=${blockHash}, index=${transactionIndex})`, @@ -1367,7 +1400,7 @@ export class EthImpl implements Eth { async getTransactionByBlockNumberAndIndex( blockNumOrTag: string, transactionIndex: string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { this.logger.trace( `${requestIdPrefix} getTransactionByBlockNumberAndIndex(blockNum=${blockNumOrTag}, index=${transactionIndex})`, @@ -1401,7 +1434,7 @@ export class EthImpl implements Eth { async getTransactionCount( address: string, blockNumOrTag: string | null, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { this.logger.trace(`${requestIdPrefix} getTransactionCount(address=${address}, blockNumOrTag=${blockNumOrTag})`); @@ -1447,8 +1480,8 @@ export class EthImpl implements Eth { async parseRawTxAndPrecheck( transaction: string, + requestDetails: IRequestDetails, networkGasPriceInWeiBars: number, - requestIdPrefix?: string, ): Promise { let interactingEntity = ''; let originatingAddress = ''; @@ -1458,14 +1491,14 @@ export class EthImpl implements Eth { interactingEntity = parsedTx.to?.toString() || ''; originatingAddress = parsedTx.from?.toString() || ''; this.logger.trace( - `${requestIdPrefix} sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, + `${requestDetails.requestIdPrefix} sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, ); - await this.precheck.sendRawTransactionCheck(parsedTx, networkGasPriceInWeiBars, requestIdPrefix); + await this.precheck.sendRawTransactionCheck(parsedTx, networkGasPriceInWeiBars, requestDetails.requestIdPrefix); return parsedTx; } catch (e: any) { this.logger.warn( - `${requestIdPrefix} Error on precheck sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, + `${requestDetails.requestIdPrefix} Error on precheck sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, ); throw this.common.genericErrorHandler(e); } @@ -1541,18 +1574,17 @@ export class EthImpl implements Eth { * @param transaction * @param requestId */ - async sendRawTransaction(transaction: string, requestId: string): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); + async sendRawTransaction(transaction: string, requestDetails: IRequestDetails): Promise { if (transaction?.length >= constants.FUNCTION_SELECTOR_CHAR_LENGTH) this.ethExecutionsCounter .labels(EthImpl.ethSendRawTransaction, transaction.substring(0, constants.FUNCTION_SELECTOR_CHAR_LENGTH)) .inc(); const networkGasPriceInWeiBars = Utils.addPercentageBufferToGasPrice( - await this.getFeeWeibars(EthImpl.ethGasPrice, requestIdPrefix), + await this.getFeeWeibars(EthImpl.ethGasPrice, requestDetails), ); - const parsedTx = await this.parseRawTxAndPrecheck(transaction, networkGasPriceInWeiBars, requestIdPrefix); + const parsedTx = await this.parseRawTxAndPrecheck(transaction, requestDetails, networkGasPriceInWeiBars); const originalCallerAddress = parsedTx.from?.toString() || ''; const transactionBuffer = Buffer.from(EthImpl.prune0x(transaction), 'hex'); let fileId: FileId | null = null; @@ -1563,10 +1595,11 @@ export class EthImpl implements Eth { .submitEthereumTransaction( transactionBuffer, EthImpl.ethSendRawTransaction, + requestDetails, originalCallerAddress, networkGasPriceInWeiBars, - await this.getCurrentNetworkExchangeRateInCents(requestIdPrefix), - requestIdPrefix, + await this.getCurrentNetworkExchangeRateInCents(requestDetails.requestIdPrefix), + requestDetails.requestIdPrefix ); txSubmitted = true; @@ -1585,17 +1618,17 @@ export class EthImpl implements Eth { this.mirrorNodeClient.getContractResult.name, [formattedId], this.mirrorNodeClient.getMirrorNodeRequestRetryCount(), - requestIdPrefix, + requestDetails.requestIdPrefix, ); if (!contractResult) { - this.logger.warn(`${requestIdPrefix} No record retrieved`); + this.logger.warn(`${requestDetails.requestIdPrefix} No record retrieved`); throw predefined.INTERNAL_ERROR(`No matching record found for transaction id ${txId}`); } if (contractResult.hash == null) { this.logger.error( - `${requestIdPrefix} The ethereumHash can never be null for an ethereum transaction, and yet it was!!`, + `${requestDetails.requestIdPrefix} The ethereumHash can never be null for an ethereum transaction, and yet it was!!`, ); throw predefined.INTERNAL_ERROR(); } @@ -1608,7 +1641,7 @@ export class EthImpl implements Eth { transactionBuffer, txSubmitted, parsedTx, - requestIdPrefix, + requestDetails.requestIdPrefix, ); } finally { /** @@ -1618,7 +1651,7 @@ export class EthImpl implements Eth { if (fileId) { this.hapiService .getSDKClient() - .deleteFile(fileId, requestIdPrefix, EthImpl.ethSendRawTransaction, fileId.toString(), originalCallerAddress); + .deleteFile(fileId, requestDetails, EthImpl.ethSendRawTransaction, fileId.toString(), originalCallerAddress); } } } @@ -1633,8 +1666,9 @@ export class EthImpl implements Eth { async call( call: IContractCallRequest, blockParam: string | object | null, - requestIdPrefix?: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; const callData = call.data ? call.data : call.input; // log request this.logger.info( @@ -1650,7 +1684,7 @@ export class EthImpl implements Eth { .inc(); } - const blockNumberOrTag = await this.extractBlockNumberOrTag(blockParam, requestIdPrefix); + const blockNumberOrTag = await this.extractBlockNumberOrTag(blockParam, requestDetails); await this.performCallChecks(call); // Get a reasonable value for "gas" if it is not specified. @@ -1677,7 +1711,7 @@ export class EthImpl implements Eth { } else { //temporary workaround until precompiles are implemented in Mirror node evm module // Execute the call and get the response - result = await this.callMirrorNode(call, gas, call.value, blockNumberOrTag, requestIdPrefix); + result = await this.callMirrorNode(call, gas, call.value, blockNumberOrTag, requestDetails); } this.logger.debug(`${requestIdPrefix} eth_call response: ${JSON.stringify(result)}`); @@ -1705,7 +1739,7 @@ export class EthImpl implements Eth { value: string | number; }, transactionIndex: string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { const contractResults = await this.mirrorNodeClient.getContractResults( { @@ -1729,7 +1763,7 @@ export class EthImpl implements Eth { // according to EIP-1898 (https://eips.ethereum.org/EIPS/eip-1898) block param can either be a string (blockNumber or Block Tag) or an object (blockHash or blockNumber) private async extractBlockNumberOrTag( blockParam: string | object | null, - requestIdPrefix: string | undefined, + requestDetails: IRequestDetails, ): Promise { if (!blockParam) { return null; @@ -1743,7 +1777,7 @@ export class EthImpl implements Eth { } if (blockParam['blockHash'] != null) { - return await this.getBlockNumberFromHash(blockParam['blockHash'], requestIdPrefix); + return await this.getBlockNumberFromHash(blockParam['blockHash'], requestDetails); } // if is an object but doesn't have blockNumber or blockHash, then it's an invalid blockParam @@ -1754,7 +1788,7 @@ export class EthImpl implements Eth { if (typeof blockParam === 'string' && blockParam.length > 0) { // if string is a blockHash, we return its corresponding blockNumber if (EthImpl.isBlockHash(blockParam)) { - return await this.getBlockNumberFromHash(blockParam, requestIdPrefix); + return await this.getBlockNumberFromHash(blockParam, requestDetails); } else { return blockParam; } @@ -1763,8 +1797,8 @@ export class EthImpl implements Eth { return null; } - private async getBlockNumberFromHash(blockHash: string, requestIdPrefix: string | undefined): Promise { - const block = await this.getBlockByHash(blockHash, false, requestIdPrefix); + private async getBlockNumberFromHash(blockHash: string, requestDetails: IRequestDetails): Promise { + const block = await this.getBlockByHash(blockHash, false, requestDetails); if (block != null) { return block.number; } else { @@ -1777,12 +1811,12 @@ export class EthImpl implements Eth { gas: number | null, value: number | string | null | undefined, block: string | null, - requestIdPrefix?: string, + requestDetails: IRequestDetails, ): Promise { let callData: IContractCallRequest = {}; try { this.logger.debug( - `${requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" at blockBlockNumberOrTag: "${block}" using mirror-node.`, + `${requestDetails.requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" at blockBlockNumberOrTag: "${block}" using mirror-node.`, call.to, gas, call.data, @@ -1797,7 +1831,10 @@ export class EthImpl implements Eth { ...(block !== null ? { block } : {}), }; - const contractCallResponse = await this.mirrorNodeClient.postContractCall(callData, requestIdPrefix); + const contractCallResponse = await this.mirrorNodeClient.postContractCall( + callData, + requestDetails.requestIdPrefix, + ); return contractCallResponse?.result ? prepend0x(contractCallResponse.result) : EthImpl.emptyHex; } catch (e: any) { if (e instanceof JsonRpcError) { @@ -1816,7 +1853,7 @@ export class EthImpl implements Eth { if (e.isContractReverted()) { this.logger.trace( - `${requestIdPrefix} mirror node eth_call request encountered contract revert. message: ${e.message}, details: ${e.detail}, data: ${e.data}`, + `${requestDetails.requestIdPrefix} mirror node eth_call request encountered contract revert. message: ${e.message}, details: ${e.detail}, data: ${e.data}`, ); return predefined.CONTRACT_REVERT(e.detail || e.message, e.data); } @@ -1827,15 +1864,17 @@ export class EthImpl implements Eth { const errorTypeMessage = e.isNotSupported() || e.isNotSupportedSystemContractOperaton() ? 'Unsupported' : 'Unhandled'; this.logger.trace( - `${requestIdPrefix} ${errorTypeMessage} mirror node eth_call request, retrying with consensus node. details: ${JSON.stringify( + `${ + requestDetails.requestIdPrefix + } ${errorTypeMessage} mirror node eth_call request, retrying with consensus node. details: ${JSON.stringify( callData, )} with error: "${e.message}"`, ); - return await this.callConsensusNode(call, gas, requestIdPrefix); + return await this.callConsensusNode(call, gas, requestDetails); } } - this.logger.error(e, `${requestIdPrefix} Failed to successfully submit eth_call`); + this.logger.error(e, `${requestDetails.requestIdPrefix} Failed to successfully submit eth_call`); return predefined.INTERNAL_ERROR(e.message.toString()); } @@ -1848,14 +1887,18 @@ export class EthImpl implements Eth { * @param gas * @param requestIdPrefix */ - async callConsensusNode(call: any, gas: number | null, requestIdPrefix?: string): Promise { + async callConsensusNode( + call: any, + gas: number | null, + requestDetails: IRequestDetails, + ): Promise { // Execute the call and get the response if (!gas) { gas = Number.parseInt(this.defaultGas); } this.logger.debug( - `${requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" using consensus-node.`, + `${requestDetails.requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" using consensus-node.`, call.to, gas, call.data, @@ -1881,16 +1924,16 @@ export class EthImpl implements Eth { } const cacheKey = `${constants.CACHE_KEY.ETH_CALL}:${call.from || ''}.${call.to}.${data}`; - const cachedResponse = await this.cacheService.getAsync(cacheKey, EthImpl.ethCall, requestIdPrefix); + const cachedResponse = await this.cacheService.getAsync(cacheKey, EthImpl.ethCall, requestDetails.requestIdPrefix); if (cachedResponse != undefined) { - this.logger.debug(`${requestIdPrefix} eth_call returned cached response: ${cachedResponse}`); + this.logger.debug(`${requestDetails.requestIdPrefix} eth_call returned cached response: ${cachedResponse}`); return cachedResponse; } const contractCallResponse = await this.hapiService .getSDKClient() - .submitContractCallQueryWithRetry(call.to, call.data, gas, call.from, EthImpl.ethCall, requestIdPrefix); + .submitContractCallQueryWithRetry(call.to, call.data, gas, call.from, EthImpl.ethCall, requestDetails); if (contractCallResponse) { const formattedCallReponse = prepend0x(Buffer.from(contractCallResponse.asBytes()).toString('hex')); @@ -1899,7 +1942,7 @@ export class EthImpl implements Eth { formattedCallReponse, EthImpl.ethCall, this.ethCallCacheTtl, - requestIdPrefix, + requestDetails.requestIdPrefix, ); return formattedCallReponse; } @@ -1908,7 +1951,7 @@ export class EthImpl implements Eth { `Invalid contractCallResponse from consensus-node: ${JSON.stringify(contractCallResponse)}`, ); } catch (e: any) { - this.logger.error(e, `${requestIdPrefix} Failed to successfully submit contractCallQuery`); + this.logger.error(e, `${requestDetails.requestIdPrefix} Failed to successfully submit contractCallQuery`); if (e instanceof JsonRpcError) { return e; } @@ -1934,7 +1977,7 @@ export class EthImpl implements Eth { async resolveEvmAddress( address: string, - requestIdPrefix?: string, + requestIdPrefix: string, searchableTypes = [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT], ): Promise { if (!address) return address; @@ -1964,7 +2007,7 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getTransactionByHash(hash: string, requestIdPrefix?: string): Promise { + async getTransactionByHash(hash: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} getTransactionByHash(hash=${hash})`, hash); const contractResult = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestIdPrefix); @@ -2010,23 +2053,28 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getTransactionReceipt(hash: string, requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} getTransactionReceipt(${hash})`); + async getTransactionReceipt(hash: string, requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} getTransactionReceipt(${hash})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_TRANSACTION_RECEIPT}_${hash}`; const cachedResponse = await this.cacheService.getAsync( cacheKey, EthImpl.ethGetTransactionReceipt, - requestIdPrefix, + requestDetails.requestIdPrefix, ); if (cachedResponse) { this.logger.debug( - `${requestIdPrefix} getTransactionReceipt returned cached response: ${JSON.stringify(cachedResponse)}`, + `${requestDetails.requestIdPrefix} getTransactionReceipt returned cached response: ${JSON.stringify( + cachedResponse, + )}`, ); return cachedResponse; } - const receiptResponse = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestIdPrefix); + const receiptResponse = await this.mirrorNodeClient.getContractResultWithRetry( + hash, + requestDetails.requestIdPrefix, + ); if (receiptResponse === null || receiptResponse.hash === undefined) { // handle synthetic transactions const syntheticLogs = await this.common.getLogsWithParams( @@ -2034,16 +2082,16 @@ export class EthImpl implements Eth { { 'transaction.hash': hash, }, - requestIdPrefix, + requestDetails.requestIdPrefix, ); // no tx found if (!syntheticLogs.length) { - this.logger.trace(`${requestIdPrefix} no receipt for ${hash}`); + this.logger.trace(`${requestDetails.requestIdPrefix} no receipt for ${hash}`); return null; } - const gasPriceForTimestamp = await this.getCurrentGasPriceForBlock(syntheticLogs[0].blockHash); + const gasPriceForTimestamp = await this.getCurrentGasPriceForBlock(syntheticLogs[0].blockHash, requestDetails); const receipt: ITransactionReceipt = { blockHash: syntheticLogs[0].blockHash, blockNumber: syntheticLogs[0].blockNumber, @@ -2062,18 +2110,18 @@ export class EthImpl implements Eth { type: null, // null from HAPI transactions }; - this.logger.trace(`${requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); + this.logger.trace(`${requestDetails.requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); await this.cacheService.set( cacheKey, receipt, EthImpl.ethGetTransactionReceipt, constants.CACHE_TTL.ONE_DAY, - requestIdPrefix, + requestDetails.requestIdPrefix, ); return receipt; } else { - const effectiveGas = await this.getCurrentGasPriceForBlock(receiptResponse.blockHash); + const effectiveGas = await this.getCurrentGasPriceForBlock(receiptResponse.blockHash, requestDetails); // support stricter go-eth client which requires the transaction hash property on logs const logs = receiptResponse.logs.map((log) => { return new Log({ @@ -2092,8 +2140,8 @@ export class EthImpl implements Eth { const receipt: ITransactionReceipt = { blockHash: toHash32(receiptResponse.block_hash), blockNumber: numberTo0x(receiptResponse.block_number), - from: await this.resolveEvmAddress(receiptResponse.from, requestIdPrefix), - to: await this.resolveEvmAddress(receiptResponse.to, requestIdPrefix), + from: await this.resolveEvmAddress(receiptResponse.from, requestDetails.requestIdPrefix), + to: await this.resolveEvmAddress(receiptResponse.to, requestDetails.requestIdPrefix), cumulativeGasUsed: numberTo0x(receiptResponse.block_gas_used), gasUsed: nanOrNumberTo0x(receiptResponse.gas_used), contractAddress: receiptResponse.address, @@ -2113,26 +2161,26 @@ export class EthImpl implements Eth { : prepend0x(ASCIIToHex(receiptResponse.error_message)); } - this.logger.trace(`${requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); + this.logger.trace(`${requestDetails.requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); await this.cacheService.set( cacheKey, receipt, EthImpl.ethGetTransactionReceipt, constants.CACHE_TTL.ONE_DAY, - requestIdPrefix, + requestDetails.requestIdPrefix, ); return receipt; } } - private async getCurrentGasPriceForBlock(blockHash: string, requestIdPrefix?: string): Promise { - const block = await this.getBlockByHash(blockHash, false); + private async getCurrentGasPriceForBlock(blockHash: string, requestDetails: IRequestDetails): Promise { + const block = await this.getBlockByHash(blockHash, false, requestDetails); const timestampDecimal = parseInt(block ? block.timestamp : '0', 16); const timestampDecimalString = timestampDecimal > 0 ? timestampDecimal.toString() : ''; const gasPriceForTimestamp = await this.getFeeWeibars( EthImpl.ethGetTransactionReceipt, - requestIdPrefix, + requestDetails, timestampDecimalString, ); @@ -2180,7 +2228,7 @@ export class EthImpl implements Eth { * @param requestIdPrefix * @private */ - private async translateBlockTag(tag: string | null, requestIdPrefix?: string): Promise { + private async translateBlockTag(tag: string | null, requestIdPrefix: string): Promise { if (this.common.blockTagIsLatestOrPending(tag)) { return Number(await this.blockNumber(requestIdPrefix)); } else if (tag === EthImpl.blockEarliest) { @@ -2190,7 +2238,7 @@ export class EthImpl implements Eth { } } - private getCappedBlockGasLimit(gasString: string | undefined, requestIdPrefix?: string): number | null { + private getCappedBlockGasLimit(gasString: string | undefined, requestIdPrefix: string): number | null { if (!gasString) { // Return null and don't include in the mirror node call, as mirror is doing this estimation on the go. return null; @@ -2213,7 +2261,7 @@ export class EthImpl implements Eth { showDetails: boolean, logs: Log[], transactionsArray: Array, - requestIdPrefix?: string, + requestIdPrefix: string, ): Array { let filteredLogs: Log[]; if (showDetails) { @@ -2249,9 +2297,13 @@ export class EthImpl implements Eth { private async getBlock( blockHashOrNumber: string, showDetails: boolean, - requestIdPrefix?: string, + requestDetails: IRequestDetails, ): Promise { - const blockResponse = await this.common.getHistoricalBlockResponse(blockHashOrNumber, true, requestIdPrefix); + const blockResponse = await this.common.getHistoricalBlockResponse( + requestDetails.requestIdPrefix, + blockHashOrNumber, + true, + ); if (blockResponse == null) return null; const timestampRange = blockResponse.timestamp; @@ -2259,13 +2311,13 @@ export class EthImpl implements Eth { const contractResults = await this.mirrorNodeClient.getContractResults( { timestamp: timestampRangeParams }, undefined, - requestIdPrefix, + requestDetails.requestIdPrefix, ); const gasUsed = blockResponse.gas_used; const params = { timestamp: timestampRangeParams }; // get contract results logs using block timestamp range - const logs = await this.common.getLogsWithParams(null, params, requestIdPrefix); + const logs = await this.common.getLogsWithParams(null, params, requestDetails.requestIdPrefix); if (contractResults == null && logs.length == 0) { // contract result not found @@ -2281,16 +2333,21 @@ export class EthImpl implements Eth { // prepare transactionArray let transactionArray: any[] = []; for (const contractResult of contractResults) { - contractResult.from = await this.resolveEvmAddress(contractResult.from, requestIdPrefix, [ + contractResult.from = await this.resolveEvmAddress(contractResult.from, requestDetails.requestIdPrefix, [ constants.TYPE_ACCOUNT, ]); - contractResult.to = await this.resolveEvmAddress(contractResult.to, requestIdPrefix); + contractResult.to = await this.resolveEvmAddress(contractResult.to, requestDetails.requestIdPrefix); contractResult.chain_id = contractResult.chain_id || this.chain; transactionArray.push(showDetails ? formatContractResult(contractResult) : contractResult.hash); } - transactionArray = this.populateSyntheticTransactions(showDetails, logs, transactionArray, requestIdPrefix); + transactionArray = this.populateSyntheticTransactions( + showDetails, + logs, + transactionArray, + requestDetails.requestIdPrefix, + ); transactionArray = showDetails ? _.uniqBy(transactionArray, 'hash') : _.uniq(transactionArray); const formattedReceipts: IReceiptRootHash[] = ReceiptsRootUtils.buildReceiptRootHashes( @@ -2301,7 +2358,7 @@ export class EthImpl implements Eth { const blockHash = toHash32(blockResponse.hash); return new Block({ - baseFeePerGas: await this.gasPrice(requestIdPrefix), + baseFeePerGas: await this.gasPrice(requestDetails), difficulty: EthImpl.zeroHex, extraData: EthImpl.emptyHex, gasLimit: numberTo0x(constants.BLOCK_GAS_LIMIT), @@ -2428,7 +2485,7 @@ export class EthImpl implements Eth { return numberTo0x(transactionResult.nonce + 1); // nonce is 0 indexed } - private async getAccountNonceForEarliestBlock(requestIdPrefix?: string): Promise { + private async getAccountNonceForEarliestBlock(requestIdPrefix: string): Promise { const block = await this.mirrorNodeClient.getEarliestBlock(requestIdPrefix); if (block == null) { throw predefined.INTERNAL_ERROR('No network blocks found'); @@ -2446,7 +2503,7 @@ export class EthImpl implements Eth { private async getAccountNonceForHistoricBlock( address: string, blockNumOrHash: number | string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { let getBlock; const isParamBlockNum = typeof blockNumOrHash === 'number' ? true : false; @@ -2481,7 +2538,7 @@ export class EthImpl implements Eth { toBlock: string | 'latest', address: string | string[] | null, topics: any[] | null, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { return this.common.getLogs(blockHash, fromBlock, toBlock, address, topics, requestIdPrefix); } diff --git a/packages/relay/src/lib/poller.ts b/packages/relay/src/lib/poller.ts index 32cc23348f..61d3149b73 100644 --- a/packages/relay/src/lib/poller.ts +++ b/packages/relay/src/lib/poller.ts @@ -21,6 +21,7 @@ import { Eth } from '../index'; import { Logger } from 'pino'; import { Registry, Gauge } from 'prom-client'; +import { IRequestDetails } from './types/IRequestDetails'; export interface Poll { tag: string; @@ -87,7 +88,10 @@ export class Poller { poll.lastPolled = this.latestBlock; } else if (event === this.NEW_HEADS_EVENT && this.newHeadsEnabled) { - data = await this.eth.getBlockByNumber('latest', filters?.includeTransactions ?? false); + data = await this.eth.getBlockByNumber('latest', filters?.includeTransactions ?? false, { + requestIdPrefix: '', + requestIp: '', + } as IRequestDetails); data.jsonrpc = '2.0'; poll.lastPolled = this.latestBlock; } else { @@ -114,7 +118,7 @@ export class Poller { start() { this.logger.info(`${LOGGER_PREFIX} Starting polling with interval=${this.pollingInterval}`); this.interval = setInterval(async () => { - this.latestBlock = await this.eth.blockNumber(); + this.latestBlock = await this.eth.blockNumber(''); this.poll(); }, this.pollingInterval); } diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts b/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts index 6587c96fb7..441a3b6d7a 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts @@ -31,9 +31,9 @@ export interface ICommonService { ): Promise; getHistoricalBlockResponse( + requestIdPrefix: string, blockNumberOrTag?: string | null, returnLatest?: boolean, - requestIdPrefix?: string | undefined, ): Promise; getLatestBlockNumber(requestIdPrefix?: string): Promise; @@ -46,7 +46,7 @@ export interface ICommonService { getLogsByAddress(address: string | [string], params: any, requestIdPrefix): Promise; - getLogsWithParams(address: string | [string] | null, params, requestIdPrefix?: string): Promise; + getLogsWithParams(address: string | [string] | null, param, requestIdPrefix: string): Promise; getLogs( blockHash: string | null, diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts index 3439c53f9b..611bba9a3c 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts @@ -102,7 +102,7 @@ export class CommonService implements ICommonService { params: any, fromBlock: string, toBlock: string, - requestIdPrefix?: string, + requestIdPrefix: string, address?: string | string[] | null, ) { if (this.blockTagIsLatestOrPending(toBlock)) { @@ -124,7 +124,7 @@ export class CommonService implements ICommonService { let toBlockNum; params.timestamp = []; - const fromBlockResponse = await this.getHistoricalBlockResponse(fromBlock, true, requestIdPrefix); + const fromBlockResponse = await this.getHistoricalBlockResponse(requestIdPrefix, fromBlock, true); if (!fromBlockResponse) { return false; } @@ -135,7 +135,7 @@ export class CommonService implements ICommonService { params.timestamp.push(`lte:${fromBlockResponse.timestamp.to}`); } else { fromBlockNum = parseInt(fromBlockResponse.number); - const toBlockResponse = await this.getHistoricalBlockResponse(toBlock, true, requestIdPrefix); + const toBlockResponse = await this.getHistoricalBlockResponse(requestIdPrefix, toBlock, true); if (toBlockResponse != null) { params.timestamp.push(`lte:${toBlockResponse.timestamp.to}`); toBlockNum = parseInt(toBlockResponse.number); @@ -167,9 +167,9 @@ export class CommonService implements ICommonService { * @param returnLatest */ public async getHistoricalBlockResponse( + requestIdPrefix: string, blockNumberOrTagOrHash?: string | null, returnLatest?: boolean, - requestIdPrefix?: string | undefined, ): Promise { if (!returnLatest && this.blockTagIsLatestOrPending(blockNumberOrTagOrHash)) { return null; @@ -203,7 +203,7 @@ export class CommonService implements ICommonService { /** * Gets the most recent block number. */ - public async getLatestBlockNumber(requestIdPrefix?: string): Promise { + public async getLatestBlockNumber(requestIdPrefix: string): Promise { // check for cached value const cacheKey = `${constants.CACHE_KEY.ETH_BLOCK_NUMBER}`; const blockNumberCached = await this.cacheService.getAsync( @@ -297,14 +297,14 @@ export class CommonService implements ICommonService { return logs; } - public async getLogsWithParams(address: string | string[] | null, params, requestIdPrefix?: string): Promise { + public async getLogsWithParams(address: string | string[] | null, params, requestIdPrefix: string): Promise { const EMPTY_RESPONSE = []; let logResults; if (address) { logResults = await this.getLogsByAddress(address, params, requestIdPrefix); } else { - logResults = await this.mirrorNodeClient.getContractResultsLogs(params, undefined, requestIdPrefix); + logResults = await this.mirrorNodeClient.getContractResultsLogs(requestIdPrefix, params, undefined); } if (!logResults) { @@ -337,7 +337,7 @@ export class CommonService implements ICommonService { toBlock: string | 'latest', address: string | string[] | null, topics: any[] | null, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { const EMPTY_RESPONSE = []; const params: any = {}; diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts index efa42823d8..ca0b3b8222 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts @@ -25,18 +25,18 @@ export interface IFilterService { newFilter( fromBlock: string, toBlock: string, + requestIdPrefix: string, address?: string, topics?: any[], - requestIdPrefix?: string, ): Promise; - newBlockFilter(requestIdPrefix?: string): Promise; + newBlockFilter(requestIdPrefix: string): Promise; - uninstallFilter(filterId: string, requestId?: string): Promise; + uninstallFilter(filterId: string, requestIdPrefix: string): Promise; - newPendingTransactionFilter(requestIdPrefix?: string): JsonRpcError; + newPendingTransactionFilter(requestIdPrefix: string): JsonRpcError; - getFilterLogs(filterId: string, requestId?: string): Promise; + getFilterLogs(filterId: string, requestIdPrefix: string): Promise; - getFilterChanges(filterId: string, requestIdPrefix?: string): Promise; + getFilterChanges(filterId: string, requestIdPrefix: string): Promise; } diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts index 1cde8120ad..7f2fee9b53 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts @@ -78,7 +78,7 @@ export class FilterService implements IFilterService { * @param params * @param requestIdPrefix */ - async createFilter(type: string, params: any, requestIdPrefix?: string): Promise { + async createFilter(type: string, params: any, requestIdPrefix: string): Promise { const filterId = generateRandomHex(); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; await this.cacheService.set( @@ -116,9 +116,9 @@ export class FilterService implements IFilterService { async newFilter( fromBlock: string = 'latest', toBlock: string = 'latest', + requestIdPrefix: string, address?: string, topics?: any[], - requestIdPrefix?: string, ): Promise { this.logger.trace( `${requestIdPrefix} newFilter(fromBlock=${fromBlock}, toBlock=${toBlock}, address=${address}, topics=${topics})`, @@ -147,7 +147,7 @@ export class FilterService implements IFilterService { } } - async newBlockFilter(requestIdPrefix?: string): Promise { + async newBlockFilter(requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} newBlockFilter()`); try { FilterService.requireFiltersEnabled(); @@ -178,12 +178,12 @@ export class FilterService implements IFilterService { return false; } - public newPendingTransactionFilter(requestIdPrefix?: string | undefined): JsonRpcError { + public newPendingTransactionFilter(requestIdPrefix: string): JsonRpcError { this.logger.trace(`${requestIdPrefix} newPendingTransactionFilter()`); return predefined.UNSUPPORTED_METHOD; } - public async getFilterLogs(filterId: string, requestIdPrefix?: string | undefined): Promise { + public async getFilterLogs(filterId: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} getFilterLogs(${filterId})`); FilterService.requireFiltersEnabled(); @@ -203,7 +203,7 @@ export class FilterService implements IFilterService { ); } - public async getFilterChanges(filterId: string, requestIdPrefix?: string): Promise { + public async getFilterChanges(filterId: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} getFilterChanges(${filterId})`); FilterService.requireFiltersEnabled(); @@ -235,6 +235,7 @@ export class FilterService implements IFilterService { ) + 1; } else if (filter.type === constants.FILTER.TYPE.NEW_BLOCK) { result = await this.mirrorNodeClient.getBlocks( + requestIdPrefix, [`gt:${filter.lastQueried || filter.params.blockAtCreation}`], undefined, { diff --git a/packages/relay/src/lib/types/IRequestDetails.ts b/packages/relay/src/lib/types/IRequestDetails.ts new file mode 100644 index 0000000000..c4f6a9990a --- /dev/null +++ b/packages/relay/src/lib/types/IRequestDetails.ts @@ -0,0 +1,4 @@ +export type IRequestDetails = { + requestIdPrefix: string; + requestIp: string; +}; diff --git a/packages/server/src/koaJsonRpc/index.ts b/packages/server/src/koaJsonRpc/index.ts index f32313dc30..971f09fb55 100644 --- a/packages/server/src/koaJsonRpc/index.ts +++ b/packages/server/src/koaJsonRpc/index.ts @@ -72,10 +72,12 @@ export default class KoaJsonRpc { private readonly methodResponseHistogram: Histogram; private requestId: string; + private ipRequest: string; constructor(logger: Logger, register: Registry, opts?: { limit: string | null }) { this.koaApp = new Koa(); this.requestId = ''; + this.ipRequest = ''; this.registry = Object.create(null); this.registryTotal = Object.create(null); this.methodConfig = methodConfiguration; @@ -106,6 +108,7 @@ export default class KoaJsonRpc { rpcApp(): (ctx: Koa.Context, _next: Koa.Next) => Promise { return async (ctx: Koa.Context, _next: Koa.Next) => { this.requestId = ctx.state.reqId; + this.ipRequest = ctx.request.ip; ctx.set(REQUEST_ID_HEADER_NAME, this.requestId); if (ctx.request.method !== 'POST') { @@ -257,6 +260,10 @@ export default class KoaJsonRpc { return this.requestId; } + getIpRequest(): string { + return this.ipRequest; + } + hasInvalidRequestId(body: IJsonRpcRequest): boolean { const hasId = hasOwnProperty(body, 'id'); if (this.requestIdIsOptional && !hasId) { diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index d0a42a08fa..c265a49bc0 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -29,6 +29,7 @@ import fs from 'fs'; import { v4 as uuid } from 'uuid'; import { formatRequestIdMessage } from './formatters'; import cors from 'koa-cors'; +import { IRequestDetails } from './types/types'; const mainLogger = pino({ name: 'hedera-json-rpc-relay', @@ -197,9 +198,18 @@ app.getKoaApp().use(async (ctx, next) => { return next(); }); -const logAndHandleResponse = async (methodName: any, methodParams: any, methodFunction: any) => { +const logAndHandleResponse = async (methodName: string, methodParams: any[], methodFunction: any) => { const requestId = app.getRequestId(); + const requestIp = app.getIpRequest(); const requestIdPrefix = requestId ? formatRequestIdMessage(requestId) : ''; + const requestDetails: IRequestDetails = { requestIdPrefix, requestIp }; + const methodsToPassRequestDetails = [ + 'eth_getCode', + 'eth_call', + 'eth_sendRawTransaction', + 'eth_feeHistory', + 'eth_getTransactionReceipt', + ]; try { const methodValidations = Validator.METHODS[methodName]; @@ -210,7 +220,8 @@ const logAndHandleResponse = async (methodName: any, methodParams: any, methodFu Validator.validateParams(methodParams, methodValidations); } - const response = await methodFunction(requestIdPrefix); + const passRequestDetails = methodsToPassRequestDetails.includes(methodName); + const response = await methodFunction(passRequestDetails ? requestDetails : requestId); if (response instanceof JsonRpcError) { // log error only if it is not a contract revert, otherwise log it as debug if (response.code === predefined.CONTRACT_REVERT().code) { @@ -314,8 +325,8 @@ app.useRpc('eth_getBalance', async (params: any) => { * returns: Bytecode - hex encoded bytes */ app.useRpc('eth_getCode', async (params: any) => { - return logAndHandleResponse('eth_getCode', params, (requestId) => - relay.eth().getCode(params?.[0], params?.[1], requestId), + return logAndHandleResponse('eth_getCode', params, (requestDetails) => + relay.eth().getCode(params?.[0], params?.[1], requestDetails), ); }); @@ -383,7 +394,9 @@ app.useRpc('eth_getTransactionCount', async (params: any) => { * returns: Value - hex encoded bytes */ app.useRpc('eth_call', async (params: any) => { - return logAndHandleResponse('eth_call', params, (requestId) => relay.eth().call(params?.[0], params?.[1], requestId)); + return logAndHandleResponse('eth_call', params, (requestDetails) => + relay.eth().call(params?.[0], params?.[1], requestDetails), + ); }); /** @@ -393,8 +406,8 @@ app.useRpc('eth_call', async (params: any) => { * returns: Transaction hash - 32 byte hex value */ app.useRpc('eth_sendRawTransaction', async (params: any) => { - return logAndHandleResponse('eth_sendRawTransaction', params, (requestId) => - relay.eth().sendRawTransaction(params?.[0], requestId), + return logAndHandleResponse('eth_sendRawTransaction', params, (requestDetails) => + relay.eth().sendRawTransaction(params?.[0], requestDetails), ); }); @@ -405,8 +418,8 @@ app.useRpc('eth_sendRawTransaction', async (params: any) => { * returns: Transaction Receipt - object */ app.useRpc('eth_getTransactionReceipt', async (params: any) => { - return logAndHandleResponse('eth_getTransactionReceipt', params, (requestId) => - relay.eth().getTransactionReceipt(params?.[0], requestId), + return logAndHandleResponse('eth_getTransactionReceipt', params, (requestDetails) => + relay.eth().getTransactionReceipt(params?.[0], requestDetails), ); }); @@ -448,8 +461,8 @@ app.useRpc('eth_getTransactionByHash', async (params: any) => { * - reward - Array of effective priority fee per gas data. */ app.useRpc('eth_feeHistory', async (params: any) => { - return logAndHandleResponse('eth_feeHistory', params, (requestId) => - relay.eth().feeHistory(Number(params?.[0]), params?.[1], params?.[2], requestId), + return logAndHandleResponse('eth_feeHistory', params, (requestDetails) => + relay.eth().feeHistory(Number(params?.[0]), params?.[1], params?.[2], requestDetails), ); }); @@ -501,7 +514,7 @@ app.useRpc('eth_getLogs', async (params: any) => { */ app.useRpc('eth_getStorageAt', async (params: any) => { return logAndHandleResponse('eth_getStorageAt', params, (requestId) => - relay.eth().getStorageAt(params?.[0], params?.[1], params?.[2], requestId), + relay.eth().getStorageAt(requestId, params?.[0], params?.[1], params?.[2]), ); }); @@ -708,7 +721,7 @@ app.useRpc('eth_newFilter', async (params: any) => { relay .eth() .filterService() - .newFilter(filter?.fromBlock, filter?.toBlock, filter?.address, filter?.topics, requestId), + .newFilter(filter?.fromBlock, filter?.toBlock, requestId, filter?.address, filter?.topics), ); }); diff --git a/packages/server/src/types/types.ts b/packages/server/src/types/types.ts new file mode 100644 index 0000000000..c4f6a9990a --- /dev/null +++ b/packages/server/src/types/types.ts @@ -0,0 +1,4 @@ +export type IRequestDetails = { + requestIdPrefix: string; + requestIp: string; +}; From 4fb59a3129d66d3a8b7ed2ddb9b88fd99271fa92 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 4 Sep 2024 12:48:06 +0300 Subject: [PATCH 02/48] Fixes failing unit tests Signed-off-by: Konstantina Blazhukova --- packages/relay/tests/helpers.ts | 4 +- packages/relay/tests/lib/eth/eth_call.spec.ts | 75 +++++++++---- .../tests/lib/eth/eth_estimateGas.spec.ts | 48 ++++---- .../tests/lib/eth/eth_feeHistory.spec.ts | 42 +++---- .../relay/tests/lib/eth/eth_gasPrice.spec.ts | 28 +++-- .../tests/lib/eth/eth_getBalance.spec.ts | 2 +- .../tests/lib/eth/eth_getBlockByHash.spec.ts | 24 ++-- .../lib/eth/eth_getBlockByNumber.spec.ts | 61 +++++----- .../tests/lib/eth/eth_getStorageAt.spec.ts | 33 +++++- .../lib/eth/eth_getTransactionReceipt.spec.ts | 28 +++-- .../lib/eth/eth_sendRawTransaction.spec.ts | 17 +-- .../relay/tests/lib/mirrorNodeClient.spec.ts | 4 +- packages/relay/tests/lib/openrpc.spec.ts | 49 +++++---- packages/relay/tests/lib/sdkClient.spec.ts | 30 +++-- .../tests/lib/services/eth/filter.spec.ts | 104 ++++++++++-------- 15 files changed, 336 insertions(+), 213 deletions(-) diff --git a/packages/relay/tests/helpers.ts b/packages/relay/tests/helpers.ts index 7aa3d6ec23..cedce4c6e0 100644 --- a/packages/relay/tests/helpers.ts +++ b/packages/relay/tests/helpers.ts @@ -73,10 +73,10 @@ const getRequestId = () => { return formatRequestIdMessage(uuid()); }; -export const ethCallFailing = async (ethImpl, args, block, assertFunc) => { +export const ethCallFailing = async (ethImpl, args, block, requestDetails, assertFunc) => { let hasError = false; try { - await ethImpl.call(args, block); + await ethImpl.call(args, block, requestDetails); } catch (error: any) { hasError = true; assertFunc(error); diff --git a/packages/relay/tests/lib/eth/eth_call.spec.ts b/packages/relay/tests/lib/eth/eth_call.spec.ts index 9381d21c13..03d920747c 100644 --- a/packages/relay/tests/lib/eth/eth_call.spec.ts +++ b/packages/relay/tests/lib/eth/eth_call.spec.ts @@ -56,6 +56,7 @@ import { } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; import { IContractCallRequest, IContractCallResponse } from '../../../src/lib/types/IMirrorNode'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -75,11 +76,16 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }; + let requestDetails: IRequestDetails; + let requestIdPrefix: string; + this.beforeEach(() => { // reset cache and restMock cacheService.clear(); restMock.reset(); + requestIdPrefix = `[Request ID: testId]`; + requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -130,6 +136,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }, 'latest', + requestDetails, (error) => { expect(error.message).to.equal( `Invalid Contract Address: ${EthImpl.zeroHex}. Expected length of 42 chars but was 3.`, @@ -149,7 +156,11 @@ describe('@ethCall Eth Call spec', async function () { evm_address: defaultCallData.from, }); restMock.onGet(`contracts/${defaultCallData.to}`).reply(200, DEFAULT_CONTRACT); - await ethImpl.call({ ...defaultCallData, gas: `0x${defaultCallData.gas.toString(16)}` }, 'latest'); + await ethImpl.call( + { ...defaultCallData, gas: `0x${defaultCallData.gas.toString(16)}` }, + 'latest', + requestDetails, + ); assert(callMirrorNodeSpy.calledOnce); process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallConesneusFF; @@ -166,7 +177,11 @@ describe('@ethCall Eth Call spec', async function () { evm_address: defaultCallData.from, }); restMock.onGet(`contracts/${defaultCallData.to}`).reply(200, DEFAULT_CONTRACT); - await ethImpl.call({ ...defaultCallData, gas: `0x${defaultCallData.gas.toString(16)}` }, 'latest'); + await ethImpl.call( + { ...defaultCallData, gas: `0x${defaultCallData.gas.toString(16)}` }, + 'latest', + requestDetails, + ); assert(callMirrorNodeSpy.calledOnce); process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallConesneusFF; @@ -182,7 +197,11 @@ describe('@ethCall Eth Call spec', async function () { evm_address: defaultCallData.from, }); restMock.onGet(`contracts/${defaultCallData.to}`).reply(200, DEFAULT_CONTRACT); - await ethImpl.call({ ...defaultCallData, gas: `0x${defaultCallData.gas.toString(16)}` }, 'latest'); + await ethImpl.call( + { ...defaultCallData, gas: `0x${defaultCallData.gas.toString(16)}` }, + 'latest', + requestDetails, + ); assert(callConsensusNodeSpy.calledOnce); process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallConesneusFF; @@ -203,6 +222,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }, 'latest', + requestDetails, ), ).to.eventually.be.fulfilled.and.equal('0x1'); }); @@ -223,6 +243,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }, 'latest', + requestDetails, ), ).to.eventually.be.fulfilled.and.equal('0x1'); }); @@ -257,6 +278,7 @@ describe('@ethCall Eth Call spec', async function () { data: CONTRACT_CALL_DATA, }, 'latest', + requestDetails, ); sinon.assert.calledWith( @@ -285,6 +307,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }, 'latest', + requestDetails, ); sinon.assert.calledWith( @@ -314,7 +337,7 @@ describe('@ethCall Eth Call spec', async function () { }, }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); }); @@ -327,7 +350,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect((result as JsonRpcError).code).to.equal(-32014); expect((result as JsonRpcError).message).to.equal( @@ -343,7 +366,7 @@ describe('@ethCall Eth Call spec', async function () { }, }); - const result = await ethImpl.call(ETH_CALL_REQ_ARGS, 'latest'); + const result = await ethImpl.call(ETH_CALL_REQ_ARGS, 'latest', requestDetails); sinon.assert.calledWith( sdkClientStub.submitContractCallQueryWithRetry, @@ -374,6 +397,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }, 'latest', + requestDetails, ); expect(result).to.equal('0x00'); await new Promise((r) => setTimeout(r, 50)); @@ -383,7 +407,7 @@ describe('@ethCall Eth Call spec', async function () { const expectedError = predefined.INVALID_CONTRACT_ADDRESS(CONTRACT_ADDRESS_2); sdkClientStub.submitContractCallQueryWithRetry.throws(expectedError); - const call: string | JsonRpcError = await ethImpl.call(ETH_CALL_REQ_ARGS, 'latest'); + const call: string | JsonRpcError = await ethImpl.call(ETH_CALL_REQ_ARGS, 'latest', requestDetails); expect((call as JsonRpcError).code).to.equal(expectedError.code); expect((call as JsonRpcError).message).to.equal(expectedError.message); @@ -395,7 +419,7 @@ describe('@ethCall Eth Call spec', async function () { predefined.CONTRACT_REVERT(defaultErrorMessageText, defaultErrorMessageHex), ); - const result = await ethImpl.call(ETH_CALL_REQ_ARGS, 'latest'); + const result = await ethImpl.call(ETH_CALL_REQ_ARGS, 'latest', requestDetails); expect(result).to.exist; expect((result as JsonRpcError).code).to.equal(3); @@ -412,6 +436,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }, 'latest', + requestDetails, ]; await RelayAssertions.assertRejection( @@ -435,6 +460,7 @@ describe('@ethCall Eth Call spec', async function () { gas: 5_000_000, }, 'latest', + requestDetails, ); expect(result).to.exist; @@ -478,7 +504,7 @@ describe('@ethCall Eth Call spec', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_3_EMPTY_BYTECODE); web3Mock.onPost(`contracts/call`).replyOnce(200, {}); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x'); }); @@ -494,7 +520,7 @@ describe('@ethCall Eth Call spec', async function () { web3Mock.history.post = []; - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(web3Mock.history.post.length).to.gte(1); expect(web3Mock.history.post[0].data).to.equal(JSON.stringify({ ...callData, estimate: false, block: 'latest' })); @@ -512,7 +538,7 @@ describe('@ethCall Eth Call spec', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); }); @@ -524,7 +550,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); }); @@ -537,7 +563,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); }); @@ -568,7 +594,7 @@ describe('@ethCall Eth Call spec', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); // Relay is called with value in Weibars - const result = await ethImpl.call({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, 'latest'); + const result = await ethImpl.call({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, 'latest', requestDetails); expect(result).to.equal('0x00'); }); @@ -581,7 +607,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; await mockContractCall({ ...callData, block: 'latest' }, false, 429, mockData.tooManyRequests); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect((result as JsonRpcError).code).to.eq(-32605); }); @@ -596,7 +622,7 @@ describe('@ethCall Eth Call spec', async function () { }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.contractReverted); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect((result as JsonRpcError).code).to.eq(3); expect((result as JsonRpcError).message).to.contain(mockData.contractReverted._status.messages[0].message); @@ -620,7 +646,7 @@ describe('@ethCall Eth Call spec', async function () { }, }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); sinon.assert.calledWith( sdkClientStub.submitContractCallQueryWithRetry, @@ -645,7 +671,7 @@ describe('@ethCall Eth Call spec', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.contractReverted); sinon.reset(); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); sinon.assert.notCalled(sdkClientStub.submitContractCallQueryWithRetry); expect(result).to.not.be.null; expect((result as JsonRpcError).code).to.eq(3); @@ -674,7 +700,7 @@ describe('@ethCall Eth Call spec', async function () { }, }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.exist; expect((result as JsonRpcError).code).to.eq(3); @@ -692,6 +718,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }, 'latest', + requestDetails, ]; await RelayAssertions.assertRejection( @@ -713,7 +740,7 @@ describe('@ethCall Eth Call spec', async function () { }; await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.invalidTransaction); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect(result).to.equal('0x'); }); @@ -728,7 +755,7 @@ describe('@ethCall Eth Call spec', async function () { }; await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.failInvalid); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect(result).to.equal('0x'); }); @@ -741,7 +768,7 @@ describe('@ethCall Eth Call spec', async function () { }; await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: EXAMPLE_CONTRACT_BYTECODE }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.eq(EXAMPLE_CONTRACT_BYTECODE); }); @@ -752,7 +779,7 @@ describe('@ethCall Eth Call spec', async function () { }; await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: EXAMPLE_CONTRACT_BYTECODE }); - const result = await ethImpl.call(callData, 'latest'); + const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.eq(EXAMPLE_CONTRACT_BYTECODE); }); @@ -864,7 +891,7 @@ describe('@ethCall Eth Call spec', async function () { await ethImpl.contractCallFormat(transaction); - const expectedGasPrice = await ethImpl.gasPrice(); + const expectedGasPrice = await ethImpl.gasPrice(requestDetails); expect(transaction.gasPrice).to.equal(parseInt(expectedGasPrice)); }); diff --git a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts index 75bbbf8e85..85d4facbdb 100644 --- a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts +++ b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts @@ -52,6 +52,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { this.timeout(10000); let { restMock, web3Mock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger, registry } = generateEthTestEnv(); + let requestIdPrefix; async function mockContractCall( callData: IContractCallRequest, @@ -81,6 +82,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { cacheService.clear(); restMock.reset(); + requestIdPrefix = `[Request ID: testId]`; sdkClientStub = createStubInstance(SDKClient); getSdkClientStub = stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); ethImplOverridden = new EthImpl(hapiServiceInstance, mirrorNodeInstance, logger, '0x12a', registry, cacheService); @@ -110,7 +112,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - const gas = await ethImpl.estimateGas(callData, null); + const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); @@ -122,7 +124,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - const gas = await ethImpl.estimateGas(callData, null); + const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(constants.TX_CONTRACT_CALL_AVERAGE_GAS)); }); @@ -133,7 +135,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 200, { result: `0x61A80` }); - const gas = await ethImpl.estimateGas(callData, null); + const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); expect((gas as string).toLowerCase()).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT).toLowerCase()); }); @@ -145,7 +147,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 200, { result: `0x61A80` }); - const gas = await ethImpl.estimateGas({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, null); + const gas = await ethImpl.estimateGas({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, null, requestIdPrefix); expect((gas as string).toLowerCase()).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT).toLowerCase()); }); @@ -155,7 +157,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - const gas = await ethImpl.estimateGas({ data: '0x01' }, null); + const gas = await ethImpl.estimateGas({ data: '0x01' }, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(Precheck.transactionIntrinsicGasCost(callData.data!))); }); @@ -169,7 +171,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(200, { address: RECEIVER_ADDRESS }); - const gas = await ethImpl.estimateGas(callData, null); + const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(constants.TX_BASE_COST)); }); @@ -182,7 +184,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(200, { address: RECEIVER_ADDRESS }); - const result = await ethImpl.estimateGas(callData, null); + const result = await ethImpl.estimateGas(callData, null, requestIdPrefix); expect(result).to.not.be.null; expect((result as JsonRpcError).code).to.eq(-32602); }); @@ -201,6 +203,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, + requestIdPrefix, ); expect(gas).to.equal(EthImpl.gasTxBaseCost); }); @@ -219,6 +222,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, + requestIdPrefix, ); restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(404); @@ -228,6 +232,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, + requestIdPrefix, ); expect(gasBeforeCache).to.equal(EthImpl.gasTxBaseCost); @@ -248,6 +253,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, + requestIdPrefix, ); expect(hollowAccountGasCreation).to.equal(EthImpl.gasTxHollowAccountCreation); @@ -265,6 +271,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 0, }, null, + requestIdPrefix, ); expect(result).to.exist; @@ -286,7 +293,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 200, { result: `0x14b662` }); - const gas = await ethImpl.estimateGas(callData, null); + const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); expect((gas as string).toLowerCase()).to.equal(numberTo0x(gasEstimation).toLowerCase()); }); @@ -303,6 +310,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: null, }, null, + requestIdPrefix, ); expect(result).to.exist; @@ -316,7 +324,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { const callData: IContractCallRequest = {}; await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - const gas = await ethImpl.estimateGas({}, null); + const gas = await ethImpl.estimateGas({}, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); @@ -324,7 +332,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { const callData: IContractCallRequest = {}; await mockContractCall(callData, true, 200, { result: numberTo0x(defaultGasOverride) }); - const gas = await ethImplOverridden.estimateGas({}, null); + const gas = await ethImplOverridden.estimateGas({}, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(defaultGasOverride)); }); @@ -337,7 +345,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { await mockContractCall(callData, true, 501, contractsCallResponse); - const gas = await ethImpl.estimateGas({ data: '' }, null); + const gas = await ethImpl.estimateGas({ data: '' }, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); @@ -347,7 +355,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - const gas = await ethImplOverridden.estimateGas({ data: '' }, null); + const gas = await ethImplOverridden.estimateGas({ data: '' }, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(defaultGasOverride)); }); @@ -360,7 +368,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); mockGetAccount(RECEIVER_ADDRESS, 200, { account: '0.0.1234', evm_address: RECEIVER_ADDRESS }); - const gas = await ethImpl.estimateGas(callData, null); + const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(constants.TX_BASE_COST)); }); @@ -370,7 +378,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - const gas = await ethImplOverridden.estimateGas({ data: '0x' }, null); + const gas = await ethImplOverridden.estimateGas({ data: '0x' }, null, requestIdPrefix); expect(gas).to.equal(numberTo0x(defaultGasOverride)); }); @@ -388,7 +396,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; await mockContractCall(transaction, true, 400, contractCallResult); - const estimatedGas = await ethImpl.estimateGas(transaction, id); + const estimatedGas = await ethImpl.estimateGas(transaction, id, requestIdPrefix); expect(estimatedGas).to.equal(numberTo0x(Precheck.transactionIntrinsicGasCost(transaction.data!))); }); @@ -408,7 +416,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }, }); - const result: any = await ethImpl.estimateGas(transaction, id); + const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); expect(result).to.equal(numberTo0x(Precheck.transactionIntrinsicGasCost(transaction.data!))); process.env.ESTIMATE_GAS_THROWS = estimateGasThrows; @@ -427,7 +435,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }, }); - const result: any = await ethImpl.estimateGas(transaction, id); + const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); expect(result.data).to.equal( '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c496e76616c6964206e756d626572206f6620726563697069656e747300000000', @@ -453,7 +461,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }, }); - const result: any = await ethImpl.estimateGas(transaction, id); + const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); expect(result.data).to.equal(encodedCustomError); expect(result.message).to.equal(`execution reverted: ${decodedMessage}`); @@ -477,7 +485,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }, }); - const result: any = await ethImpl.estimateGas(transaction, id); + const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); expect(result.data).to.equal(encodedGenericError); expect(result.message).to.equal(`execution reverted: ${decodedMessage}`); @@ -496,7 +504,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }, }); - const result: any = await ethImpl.estimateGas({ ...transaction, data: '0x', value: '0x1' }, id); + const result: any = await ethImpl.estimateGas({ ...transaction, data: '0x', value: '0x1' }, id, requestIdPrefix); expect(result).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); diff --git a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts index dca3b5f67e..d21852904a 100644 --- a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts +++ b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts @@ -38,6 +38,8 @@ import { } from './eth-config'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { request } from 'http'; dotenv.config({ path: path.resolve(__dirname, '../../test.env') }); use(chaiAsPromised); @@ -45,6 +47,7 @@ use(chaiAsPromised); let sdkClientStub; let getSdkClientStub; let currentMaxBlockRange: number; +let requestDetails: IRequestDetails; describe('@ethFeeHistory using MirrorNode', async function () { this.timeout(10000); @@ -55,6 +58,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { cacheService.clear(); restMock.reset(); + requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -95,7 +99,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { it('eth_feeHistory', async function () { previousFees.fees[2].gas += 1; - const feeHistory = await ethImpl.feeHistory(2, 'latest', [25, 75]); + const feeHistory = await ethImpl.feeHistory(2, 'latest', [25, 75], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['baseFeePerGas'].length).to.equal(3); @@ -111,38 +115,38 @@ describe('@ethFeeHistory using MirrorNode', async function () { }); it('eth_feeHistory with latest param', async function () { - const feeHistory = await ethImpl.feeHistory(1, 'latest', [25, 75]); + const feeHistory = await ethImpl.feeHistory(1, 'latest', [25, 75], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq('0x' + BLOCK_NUMBER_3); }); it('eth_feeHistory with pending param', async function () { - const feeHistory = await ethImpl.feeHistory(1, 'pending', [25, 75]); + const feeHistory = await ethImpl.feeHistory(1, 'pending', [25, 75], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq('0x' + BLOCK_NUMBER_3); }); it('eth_feeHistory with finalized param', async function () { - const feeHistory = await ethImpl.feeHistory(1, 'finalized', [25, 75]); + const feeHistory = await ethImpl.feeHistory(1, 'finalized', [25, 75], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq('0x' + BLOCK_NUMBER_3); }); it('eth_feeHistory with safe param', async function () { - const feeHistory = await ethImpl.feeHistory(1, 'safe', [25, 75]); + const feeHistory = await ethImpl.feeHistory(1, 'safe', [25, 75], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq('0x' + BLOCK_NUMBER_3); }); it('eth_feeHistory with earliest param', async function () { const firstBlockIndex = 0; - const feeHistory = await ethImpl.feeHistory(1, 'earliest', [25, 75]); + const feeHistory = await ethImpl.feeHistory(1, 'earliest', [25, 75], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq('0x' + firstBlockIndex); }); it('eth_feeHistory with number param', async function () { - const feeHistory = await ethImpl.feeHistory(1, '0x' + BLOCK_NUMBER_3, [25, 75]); + const feeHistory = await ethImpl.feeHistory(1, '0x' + BLOCK_NUMBER_3, [25, 75], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq('0x' + BLOCK_NUMBER_3); }); @@ -157,7 +161,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { restMock.onGet(`blocks/${blockNumber}`).reply(200, { ...DEFAULT_BLOCK, number: blockNumber }), ); - const feeHistory = await ethImpl.feeHistory(200, '0x9', [0]); + const feeHistory = await ethImpl.feeHistory(200, '0x9', [0], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.equal(`0x0`); @@ -175,8 +179,8 @@ describe('@ethFeeHistory using MirrorNode', async function () { restMock.onGet(`blocks/${latestBlock.number}`).reply(200, latestBlock); restMock.onGet(`network/fees?timestamp=lte:${latestBlock.timestamp.to}`).reply(200, latestFees); - const firstFeeHistory = await ethImpl.feeHistory(1, hexBlockNumber, null); - const secondFeeHistory = await ethImpl.feeHistory(1, hexBlockNumber, null); + const firstFeeHistory = await ethImpl.feeHistory(1, hexBlockNumber, null, requestDetails); + const secondFeeHistory = await ethImpl.feeHistory(1, hexBlockNumber, null, requestDetails); expect(firstFeeHistory).to.exist; expect(firstFeeHistory['baseFeePerGas'][0]).to.equal(BASE_FEE_PER_GAS_HEX); @@ -207,7 +211,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { }); it('eth_feeHistory on mirror 404', async function () { - const feeHistory = await ethImpl.feeHistory(1, 'latest', [25, 75]); + const feeHistory = await ethImpl.feeHistory(1, 'latest', [25, 75], requestDetails); feeHistoryOnErrorExpect(feeHistory); const rewards = feeHistory['reward'][0]; expect(rewards[0]).to.equal('0x0'); @@ -215,7 +219,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { }); it('eth_feeHistory on mirror 500', async function () { - const feeHistory = await ethImpl.feeHistory(1, 'latest', null); + const feeHistory = await ethImpl.feeHistory(1, 'latest', null, requestDetails); feeHistoryOnErrorExpect(feeHistory); }); }); @@ -256,7 +260,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { const countBlocks = 2; - const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', [25, 75]); + const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', [25, 75], requestDetails); checkCommonFeeHistoryFields(feeHistory); expect(feeHistory['oldestBlock']).to.eq(numberTo0x(latestBlockNumber - countBlocks + 1)); @@ -270,7 +274,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { const countBlocks = 5; - const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', []); + const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', [], requestDetails); checkCommonFeeHistoryFields(feeHistory); expect(feeHistory['oldestBlock']).to.eq(numberTo0x(latestBlockNumber - countBlocks + 1)); @@ -284,7 +288,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { const countBlocks = 5; - const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', []); + const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', [], requestDetails); checkCommonFeeHistoryFields(feeHistory); expect(feeHistory['oldestBlock']).to.eq(numberTo0x(latestBlockNumber - countBlocks + 1)); @@ -298,7 +302,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { const countBlocks = 5; - const feeHistory = await ethImpl.feeHistory(countBlocks, 'pending', []); + const feeHistory = await ethImpl.feeHistory(countBlocks, 'pending', [], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq(numberTo0x(latestBlockNumber - countBlocks + 1)); @@ -312,7 +316,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { restMock.onGet(`blocks/1`).reply(200, latestBlock); const countBlocks = 1; - const feeHistory = await ethImpl.feeHistory(countBlocks, 'earliest', []); + const feeHistory = await ethImpl.feeHistory(countBlocks, 'earliest', [], requestDetails); expect(feeHistory).to.exist; expect(feeHistory['oldestBlock']).to.eq(numberTo0x(1)); @@ -328,7 +332,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { const countBlocks = 2; - const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', []); + const feeHistory = await ethImpl.feeHistory(countBlocks, 'latest', [], requestDetails); checkCommonFeeHistoryFields(feeHistory); expect(feeHistory['oldestBlock']).to.eq(numberTo0x(latestBlockNumber - countBlocks + 1)); @@ -337,7 +341,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(404, {}); restMock.onGet(`blocks/${latestBlock.number}`).reply(404, {}); - const feeHistoryUsingCache = await ethImpl.feeHistory(countBlocks, 'latest', []); + const feeHistoryUsingCache = await ethImpl.feeHistory(countBlocks, 'latest', [], requestDetails); checkCommonFeeHistoryFields(feeHistoryUsingCache); expect(feeHistoryUsingCache['oldestBlock']).to.eq(numberTo0x(latestBlockNumber - countBlocks + 1)); expect(feeHistoryUsingCache['baseFeePerGas'].length).to.eq(countBlocks + 1); diff --git a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts index e9f9e456f2..1f0adf9cc8 100644 --- a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts +++ b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts @@ -31,6 +31,8 @@ import { predefined } from '../../../src/lib/errors/JsonRpcError'; import RelayAssertions from '../../assertions'; import { generateEthTestEnv } from './eth-helpers'; import { toHex } from '../../helpers'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { request } from 'http'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -38,6 +40,7 @@ use(chaiAsPromised); let sdkClientStub; let getSdkClientStub; let currentMaxBlockRange: number; +let requestDetails: IRequestDetails; describe('@ethGasPrice Gas Price spec', async function () { this.timeout(10000); @@ -48,6 +51,7 @@ describe('@ethGasPrice Gas Price spec', async function () { cacheService.clear(); restMock.reset(); + requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -63,20 +67,20 @@ describe('@ethGasPrice Gas Price spec', async function () { describe('@ethGasPrice', async function () { it('eth_gasPrice', async function () { - const weiBars = await ethImpl.gasPrice(); + const weiBars = await ethImpl.gasPrice(requestDetails); const expectedWeiBars = DEFAULT_NETWORK_FEES.fees[2].gas * constants.TINYBAR_TO_WEIBAR_COEF; expect(weiBars).to.equal(numberTo0x(expectedWeiBars)); }); it('eth_gasPrice with cached value', async function () { - const firstGasResult = await ethImpl.gasPrice(); + const firstGasResult = await ethImpl.gasPrice(requestDetails); const modifiedNetworkFees = { ...DEFAULT_NETWORK_FEES }; modifiedNetworkFees.fees[2].gas = DEFAULT_NETWORK_FEES.fees[2].gas * 100; restMock.onGet(`network/fees`).reply(200, modifiedNetworkFees); - const secondGasResult = await ethImpl.gasPrice(); + const secondGasResult = await ethImpl.gasPrice(requestDetails); expect(firstGasResult).to.equal(secondGasResult); }); @@ -88,7 +92,9 @@ describe('@ethGasPrice Gas Price spec', async function () { restMock.onGet(`network/fees`).reply(200, partialNetworkFees); - await RelayAssertions.assertRejection(predefined.COULD_NOT_ESTIMATE_GAS_PRICE, ethImpl.gasPrice, true, ethImpl); + await RelayAssertions.assertRejection(predefined.COULD_NOT_ESTIMATE_GAS_PRICE, ethImpl.gasPrice, true, ethImpl, [ + requestDetails, + ]); }); describe('@ethGasPrice different value for GAS_PRICE_PERCENTAGE_BUFFER env', async function () { @@ -101,12 +107,12 @@ describe('@ethGasPrice Gas Price spec', async function () { for (let testCaseName in GAS_PRICE_PERCENTAGE_BUFFER_TESTCASES) { it(testCaseName, async function () { const GAS_PRICE_PERCENTAGE_BUFFER = GAS_PRICE_PERCENTAGE_BUFFER_TESTCASES[testCaseName]; - const initialGasPrice = await ethImpl.gasPrice(); + const initialGasPrice = await ethImpl.gasPrice(requestDetails); process.env.GAS_PRICE_PERCENTAGE_BUFFER = GAS_PRICE_PERCENTAGE_BUFFER; await cacheService.clear(); - const gasPriceWithBuffer = await ethImpl.gasPrice(); + const gasPriceWithBuffer = await ethImpl.gasPrice(requestDetails); process.env.GAS_PRICE_PERCENTAGE_BUFFER = '0'; const expectedInitialGasPrice = toHex(DEFAULT_NETWORK_FEES.fees[2].gas * constants.TINYBAR_TO_WEIBAR_COEF); @@ -137,12 +143,18 @@ describe('@ethGasPrice Gas Price spec', async function () { const fauxGasWeiBarHex = '0x13e52b9abe000'; sdkClientStub.getTinyBarGasFee.returns(fauxGasTinyBars); - const gas = await ethImpl.gasPrice(); + const gas = await ethImpl.gasPrice(requestDetails); expect(gas).to.equal(fauxGasWeiBarHex); }); it('eth_gasPrice with no network fees records found', async function () { - await RelayAssertions.assertRejection(predefined.COULD_NOT_ESTIMATE_GAS_PRICE, ethImpl.gasPrice, true, ethImpl); + await RelayAssertions.assertRejection( + predefined.COULD_NOT_ESTIMATE_GAS_PRICE, + ethImpl.gasPrice, + true, + ethImpl, + [requestDetails], + ); }); }); }); diff --git a/packages/relay/tests/lib/eth/eth_getBalance.spec.ts b/packages/relay/tests/lib/eth/eth_getBalance.spec.ts index 274157f83d..19dbabb298 100644 --- a/packages/relay/tests/lib/eth/eth_getBalance.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBalance.spec.ts @@ -92,7 +92,7 @@ describe('@ethGetBalance using MirrorNode', async function () { // next call should use cache restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(404, {}); - const resBalanceCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null); + const resBalanceCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, `[Request ID: testId]`); expect(resBalanceCached).to.equal(resBalance); // Third call should return new number using mirror node diff --git a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts index d2ea6e35e6..20fa90e735 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts @@ -56,6 +56,7 @@ import { DEFAULT_BLOCK_RECEIPTS_ROOT_HASH, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -64,6 +65,7 @@ let sdkClientStub; let getSdkClientStub; let currentMaxBlockRange: number; let ethImplLowTransactionCount: EthImpl; +let requestDetails: IRequestDetails; describe('@ethGetBlockByHash using MirrorNode', async function () { this.timeout(10000); @@ -77,6 +79,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { cacheService.clear(); restMock.reset(); + requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -113,7 +116,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, gasUsed: TOTAL_GAS_USED, @@ -133,7 +136,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const res = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const res = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); RelayAssertions.assertBlock(res, { transactions: [CONTRACT_HASH_1, CONTRACT_HASH_2], hash: BLOCK_HASH_TRIMMED, @@ -154,7 +157,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, gasUsed: TOTAL_GAS_USED, @@ -176,7 +179,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, gasUsed: TOTAL_GAS_USED, @@ -194,7 +197,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); for (let i = 0; i < 3; i++) { - const result = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); expect(result).to.exist; expect(result).to.not.be.null; if (result) { @@ -211,7 +214,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, defaultContractResults); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, true); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, true, requestDetails); RelayAssertions.assertBlock( result, { @@ -234,7 +237,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { restMock.onGet(CONTRACTS_RESULTS_NEXT_URL).reply(200, defaultContractResults); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, true); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, true, requestDetails); RelayAssertions.assertBlock( result, { @@ -268,7 +271,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { ) .reply(200, { logs: [] }); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, true); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, true, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, gasUsed: numberTo0x(randomBlock.gas_used), @@ -284,7 +287,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { // mirror node request mocks restMock.onGet(`blocks/${BLOCK_HASH}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); expect(result).to.equal(null); }); @@ -305,6 +308,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { await RelayAssertions.assertRejection(predefined.INTERNAL_ERROR(), ethImpl.getBlockByHash, false, ethImpl, [ BLOCK_HASH, false, + requestDetails, ]); }); @@ -320,7 +324,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { .reply(200, defaultDetailedContractResults); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const args = [BLOCK_HASH, true]; + const args = [BLOCK_HASH, true, requestDetails]; await RelayAssertions.assertRejection( predefined.MAX_BLOCK_SIZE(77), diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index ba3da3da1f..0e0d45973a 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -73,6 +73,7 @@ import { } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; import { fail } from 'assert'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -88,6 +89,8 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { generateEthTestEnv(true); const results = defaultContractResults.results; const TOTAL_GAS_USED = numberTo0x(results[0].gas_used + results[1].gas_used); + let requestIdPrefix: string; + let requestDetails: IRequestDetails; const veriftAggregatedInfo = (result) => { // verify aggregated info @@ -112,6 +115,8 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.reset(); restMock.resetHandlers(); + requestIdPrefix = `[Request ID: testId]`; + requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -146,19 +151,19 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { it('"eth_blockNumber" should return the latest block number', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); - const blockNumber = await ethImpl.blockNumber(); + const blockNumber = await ethImpl.blockNumber(requestIdPrefix); expect(blockNumber).to.be.eq(blockNumber); }); it('"eth_blockNumber" should return the latest block number using cache', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); - const blockNumber = await ethImpl.blockNumber(); + const blockNumber = await ethImpl.blockNumber(requestIdPrefix); expect(numberTo0x(DEFAULT_BLOCK.number)).to.be.eq(blockNumber); // Second call should return the same block number using cache restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(400, DEFAULT_BLOCKS_RES); - const blockNumber2 = await ethImpl.blockNumber(); + const blockNumber2 = await ethImpl.blockNumber(requestIdPrefix); expect(blockNumber2).to.be.eq(blockNumber); // expire cache, instead of waiting for ttl we clear it to simulate expiry faster. @@ -168,7 +173,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [{ ...DEFAULT_BLOCK, number: newBlockNumber }], }); - const blockNumber3 = await ethImpl.blockNumber(); + const blockNumber3 = await ethImpl.blockNumber(requestIdPrefix); expect(numberTo0x(newBlockNumber)).to.be.eq(blockNumber3); }); @@ -186,9 +191,9 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { .replyOnce(200, DEFAULT_BLOCKS_RES); try { - await ethImpl.blockNumber(); + await ethImpl.blockNumber(requestIdPrefix); } catch (error) {} - const blockNumber = await ethImpl.blockNumber(); + const blockNumber = await ethImpl.blockNumber(requestIdPrefix); expect(blockNumber).to.be.eq(blockNumber); }); @@ -216,7 +221,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { it('eth_getBlockByNumber with match', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, defaultContractResults); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, @@ -234,7 +239,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { results: [...defaultContractResults.results, ...defaultContractResults.results], }); - const res = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false); + const res = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false, requestDetails); RelayAssertions.assertBlock(res, { transactions: [CONTRACT_HASH_1, CONTRACT_HASH_2], hash: BLOCK_HASH_TRIMMED, @@ -252,7 +257,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { }); restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, defaultContractResults); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, @@ -270,7 +275,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { it('eth_getBlockByNumber with match paginated', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, LINKS_NEXT_RES); restMock.onGet(CONTRACTS_RESULTS_NEXT_URL).reply(200, defaultContractResults); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, @@ -285,10 +290,10 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { it('eth_getBlockByNumber should return cached result', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, defaultContractResults); - const resBeforeCache = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false); + const resBeforeCache = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false, requestDetails); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(404); - const resAfterCache = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false); + const resAfterCache = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false, requestDetails); expect(resBeforeCache).to.eq(resAfterCache); }); @@ -296,7 +301,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { it('eth_getBlockByHash with match', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, defaultContractResults); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); RelayAssertions.assertBlock(result, { hash: BLOCK_HASH_TRIMMED, gasUsed: TOTAL_GAS_USED, @@ -311,7 +316,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, LINKS_NEXT_RES); restMock.onGet(CONTRACTS_RESULTS_NEXT_URL).reply(200, defaultContractResults); - const result = await ethImpl.getBlockByHash(BLOCK_HASH, false); + const result = await ethImpl.getBlockByHash(BLOCK_HASH, false, requestDetails); const toMatch = { hash: BLOCK_HASH_TRIMMED, gasUsed: TOTAL_GAS_USED, @@ -330,7 +335,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOST_RECENT_BLOCK); restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, { results: [] }); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, { logs: [] }); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), false, requestDetails); if (result) { // verify aggregated info veriftAggregatedInfo(result); @@ -349,7 +354,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOST_RECENT_BLOCK); restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, defaultContractResults); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), true); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), true, requestDetails); if (result) { veriftAggregatedInfo(result); expect(result.gasUsed).equal(TOTAL_GAS_USED); @@ -369,7 +374,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(CONTRACT_QUERY).reply(200, CONTRACT_RESPONSE_MOCK); restMock.onGet(LOG_QUERY).reply(200, LOGS_RESPONSE_MOCK); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER_WITH_SYN_TXN), true); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER_WITH_SYN_TXN), true, requestDetails); if (result) { result.transactions.forEach((txn) => { expect(txn.maxFeePerGas).to.exist; @@ -387,7 +392,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, LINKS_NEXT_RES); restMock.onGet(CONTRACTS_RESULTS_NEXT_URL).reply(200, defaultContractResults); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), true); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), true, requestDetails); if (result) { // verify aggregated info veriftAggregatedInfo(result); @@ -406,7 +411,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOST_RECENT_BLOCK); restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, DEFAULT_CONTRACT_RES_REVERT); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, { logs: [] }); - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), true); + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), true, requestDetails); if (result) { veriftAggregatedInfo(result); expect(result.gasUsed).equal(numberTo0x(GAS_USED_1)); @@ -421,7 +426,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOST_RECENT_BLOCK); - const result = await ethImpl.getBlockByNumber(BLOCK_NUMBER.toString(), false); + const result = await ethImpl.getBlockByNumber(BLOCK_NUMBER.toString(), false, requestDetails); expect(result).to.equal(null); }); @@ -447,7 +452,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { }); it('eth_getBlockByNumber with latest tag', async function () { - const result = await ethImpl.getBlockByNumber('latest', false); + const result = await ethImpl.getBlockByNumber('latest', false, requestDetails); // check that we only made the expected number of requests with the expected urls expect(restMock.history.get.length).equal(TOTAL_GET_CALLS_EXECUTED); expect(restMock.history.get[0].url).equal(BLOCKS_LIMIT_ORDER_URL); @@ -465,24 +470,24 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, LINKS_NEXT_RES); restMock.onGet(CONTRACTS_RESULTS_NEXT_URL).reply(200, defaultContractResults); - const result = await ethImpl.getBlockByNumber('latest', false); + const result = await ethImpl.getBlockByNumber('latest', false, requestDetails); confirmResult(result); }); it('eth_getBlockByNumber with pending tag', async function () { - const result = await ethImpl.getBlockByNumber('pending', false); + const result = await ethImpl.getBlockByNumber('pending', false, requestDetails); confirmResult(result); }); it('eth_getBlockByNumber with earliest tag', async function () { restMock.onGet(`blocks/0`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockByNumber('earliest', false); + const result = await ethImpl.getBlockByNumber('earliest', false, requestDetails); confirmResult(result); }); it('eth_getBlockByNumber with finalized tag', async function () { - const result = await ethImpl.getBlockByNumber('finalized', false); + const result = await ethImpl.getBlockByNumber('finalized', false, requestDetails); // check that we only made the expected number of requests with the expected urls expect(restMock.history.get.length).equal(TOTAL_GET_CALLS_EXECUTED); expect(restMock.history.get[0].url).equal(BLOCKS_LIMIT_ORDER_URL); @@ -497,7 +502,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { }); it('eth_getBlockByNumber with safe tag', async function () { - const result = await ethImpl.getBlockByNumber('safe', false); + const result = await ethImpl.getBlockByNumber('safe', false, requestDetails); // check that we only made the expected number of requests with the expected urls expect(restMock.history.get.length).equal(TOTAL_GET_CALLS_EXECUTED); expect(restMock.history.get[0].url).equal(BLOCKS_LIMIT_ORDER_URL); @@ -515,7 +520,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(`blocks/3735929054`).reply(200, DEFAULT_BLOCK); restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, BLOCKS_RES); - const result = await ethImpl.getBlockByNumber('0xdeadc0de', false); + const result = await ethImpl.getBlockByNumber('0xdeadc0de', false, requestDetails); confirmResult(result); }); }); @@ -533,7 +538,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { .reply(200, defaultDetailedContractResults); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - const args = [numberTo0x(BLOCK_NUMBER), true]; + const args = [numberTo0x(BLOCK_NUMBER), true, requestDetails]; await RelayAssertions.assertRejection( predefined.MAX_BLOCK_SIZE(77), diff --git a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts index 9c552380e7..30436e78b8 100644 --- a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts @@ -56,6 +56,7 @@ let currentMaxBlockRange: number; describe('@ethGetStorageAt eth_getStorageAt spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + let requestIdPrefix: string; function confirmResult(result: string) { expect(result).to.exist; @@ -68,6 +69,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { cacheService.clear(); restMock.reset(); + requestIdPrefix = `[Request ID: testId]`; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -93,7 +95,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { ) .reply(200, DEFAULT_CURRENT_CONTRACT_STATE); - const result = await ethImpl.getStorageAt(CONTRACT_ADDRESS_1, '0x101', numberTo0x(BLOCK_NUMBER)); + const result = await ethImpl.getStorageAt(CONTRACT_ADDRESS_1, '0x101', requestIdPrefix, numberTo0x(BLOCK_NUMBER)); confirmResult(result); // verify slot value @@ -108,7 +110,12 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { ) .reply(200, DEFAULT_CURRENT_CONTRACT_STATE); - const result = await ethImpl.getStorageAt(CONTRACT_ADDRESS_1, '0x0000101', numberTo0x(BLOCK_NUMBER)); + const result = await ethImpl.getStorageAt( + CONTRACT_ADDRESS_1, + '0x0000101', + requestIdPrefix, + numberTo0x(BLOCK_NUMBER), + ); confirmResult(result); // verify slot value @@ -126,6 +133,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, + requestIdPrefix, numberTo0x(BLOCK_NUMBER), ); confirmResult(result); @@ -145,6 +153,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, + requestIdPrefix, BLOCK_HASH, ); confirmResult(result); @@ -164,6 +173,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_CURRENT_CONTRACT_STATE.state[0].slot, + requestIdPrefix, 'latest', ); confirmResult(result); @@ -182,6 +192,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_CURRENT_CONTRACT_STATE.state[0].slot, + requestIdPrefix, 'finalized', ); confirmResult(result); @@ -200,6 +211,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_CURRENT_CONTRACT_STATE.state[0].slot, + requestIdPrefix, 'safe', ); confirmResult(result); @@ -220,6 +232,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, + requestIdPrefix, ); confirmResult(result); @@ -229,7 +242,12 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { it('eth_getStorageAt should throw a predefined RESOURCE_NOT_FOUND when block not found', async function () { restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, null); - const args = [CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, numberTo0x(BLOCK_NUMBER)]; + const args = [ + CONTRACT_ADDRESS_1, + defaultDetailedContractResults.state_changes[0].slot, + requestIdPrefix, + numberTo0x(BLOCK_NUMBER), + ]; await RelayAssertions.assertRejection( predefined.RESOURCE_NOT_FOUND(), @@ -248,7 +266,12 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { ) .reply(200, DEFAULT_CONTRACT_STATE_EMPTY_ARRAY); - const result = await ethImpl.getStorageAt(CONTRACT_ADDRESS_1, wrongSlot, numberTo0x(BLOCK_NUMBER)); + const result = await ethImpl.getStorageAt( + CONTRACT_ADDRESS_1, + wrongSlot, + requestIdPrefix, + numberTo0x(BLOCK_NUMBER), + ); expect(result).to.equal(EthImpl.zeroHex32Byte); }); @@ -263,6 +286,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_OLDER_CONTRACT_STATE.state[0].slot, + requestIdPrefix, numberTo0x(OLDER_BLOCK.number), ); expect(result).to.equal(DEFAULT_OLDER_CONTRACT_STATE.state[0].value); @@ -279,6 +303,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_OLDER_CONTRACT_STATE.state[0].slot, + requestIdPrefix, numberTo0x(OLDER_BLOCK.number), ); expect(result).to.equal(ethers.ZeroHash); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts index 3df66deddc..181d578616 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts @@ -29,6 +29,8 @@ import RelayAssertions from '../../assertions'; import { DEFAULT_BLOCK, EMPTY_LOGS_RESPONSE } from './eth-config'; import { defaultErrorMessageHex } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; +import { ITransactionReceipt } from '../../../src/lib/types/ITransactionReceipt'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -37,10 +39,14 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func this.timeout(10000); let { restMock, ethImpl, cacheService } = generateEthTestEnv(); let sandbox: sinon.SinonSandbox; + let requestDetails: IRequestDetails; + let requestIdPrefix: string; this.beforeAll(() => { // @ts-ignore sandbox = createSandbox(); + requestIdPrefix = `[Request ID: testId]`; + requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; }); const contractEvmAddress = '0xd8db0b1dbf8ba6721ef5256ad5fe07d72d1d04b9'; @@ -157,7 +163,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func restMock .onGet(`contracts/results/logs?transaction.hash=${txHash}&limit=100&order=asc`) .reply(200, EMPTY_LOGS_RESPONSE); - const receipt = await ethImpl.getTransactionReceipt(txHash); + const receipt = await ethImpl.getTransactionReceipt(txHash, requestDetails); expect(receipt).to.be.null; }); @@ -174,9 +180,9 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func restMock.onGet(`contracts/results/${defaultTxHash}`).reply(200, defaultDetailedContractResultByHash); restMock.onGet(`contracts/${defaultDetailedContractResultByHash.created_contract_ids[0]}`).reply(404); stubBlockAndFeesFunc(sandbox); - const receipt = await ethImpl.getTransactionReceipt(defaultTxHash); + const receipt = await ethImpl.getTransactionReceipt(defaultTxHash, requestDetails); - const currentGasPrice = await ethImpl.gasPrice('valid receipt on match TEST'); + const currentGasPrice = await ethImpl.gasPrice(requestDetails); // Assert the data format RelayAssertions.assertTransactionReceipt(receipt, defaultReceipt, { @@ -189,7 +195,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func restMock.onGet(`contracts/${defaultDetailedContractResultByHash.created_contract_ids[0]}`).replyOnce(404); stubBlockAndFeesFunc(sandbox); for (let i = 0; i < 3; i++) { - const receipt = await ethImpl.getTransactionReceipt(defaultTxHash); + const receipt = await ethImpl.getTransactionReceipt(defaultTxHash, requestDetails); expect(receipt).to.exist; if (receipt == null) return; expect(RelayAssertions.validateHash(receipt.transactionHash, 64)).to.eq(true); @@ -207,7 +213,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func evm_address: contractEvmAddress, }); stubBlockAndFeesFunc(sandbox); - const receipt = await ethImpl.getTransactionReceipt(defaultTxHash); + const receipt = await ethImpl.getTransactionReceipt(defaultTxHash, requestDetails); expect(receipt).to.exist; if (receipt == null) return; @@ -230,7 +236,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, contractResult); restMock.onGet(`contracts/${defaultDetailedContractResultByHash.created_contract_ids[0]}`).reply(404); stubBlockAndFeesFunc(sandbox); - const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash); + const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash, requestDetails); expect(receipt).to.exist; if (receipt == null) return; @@ -247,7 +253,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func restMock.onGet(`contracts/results/${defaultTxHash}`).reply(200, receiptWith0xBloom); restMock.onGet(`contracts/${defaultDetailedContractResultByHash.created_contract_ids[0]}`).reply(404); stubBlockAndFeesFunc(sandbox); - const receipt = await ethImpl.getTransactionReceipt(defaultTxHash); + const receipt = await ethImpl.getTransactionReceipt(defaultTxHash, requestDetails); expect(receipt).to.exist; if (receipt == null) return; @@ -267,7 +273,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, receiptWithErrorMessage); restMock.onGet(`contracts/${defaultDetailedContractResultByHash.created_contract_ids[0]}`).reply(404); stubBlockAndFeesFunc(sandbox); - const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash); + const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash, requestDetails); expect(receipt).to.exist; expect(receipt.revertReason).to.eq(defaultErrorMessageHex); @@ -284,7 +290,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, receiptWithNullGasUsed); restMock.onGet(`contracts/${defaultDetailedContractResultByHash.created_contract_ids[0]}`).reply(404); stubBlockAndFeesFunc(sandbox); - const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash); + const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash, requestDetails); expect(receipt).to.exist; if (receipt == null) return; @@ -306,7 +312,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func evm_address: contractEvmAddress, }); stubBlockAndFeesFunc(sandbox); - const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash); + const receipt = await ethImpl.getTransactionReceipt(uniqueTxHash, requestDetails); expect(receipt).to.exist; @@ -335,7 +341,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func cacheService.set(cacheKey, cacheReceipt, EthImpl.ethGetTransactionReceipt); // w no mirror node requests - const receipt = await ethImpl.getTransactionReceipt(defaultTxHash); + const receipt = await ethImpl.getTransactionReceipt(defaultTxHash, requestDetails); // Assert the matching reciept expect(receipt.blockHash).to.eq(cacheReceipt.blockHash); diff --git a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts index 7a0ac92fdc..33700c8c53 100644 --- a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts +++ b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts @@ -31,6 +31,7 @@ import RelayAssertions from '../../assertions'; import { getRequestId, mockData, signTransaction } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; import { SDKClientError } from '../../../src/lib/errors/SDKClientError'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -42,12 +43,14 @@ let currentMaxBlockRange: number; describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + let requestDetails: IRequestDetails; this.beforeEach(() => { // reset cache and restMock cacheService.clear(); restMock.reset(); + requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -114,7 +117,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () ethImpl.sendRawTransaction, false, ethImpl, - [txHash, getRequestId()], + [txHash, requestDetails], ); }); @@ -123,7 +126,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () restMock.onGet(`transactions/${transactionId}`).reply(200, null); - const resultingHash = await ethImpl.sendRawTransaction(signed, getRequestId()); + const resultingHash = await ethImpl.sendRawTransaction(signed, requestDetails); expect(resultingHash).to.equal(ethereumHash); }); @@ -140,7 +143,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () fileId: null, }); - const response = (await ethImpl.sendRawTransaction(signed, getRequestId())) as JsonRpcError; + const response = (await ethImpl.sendRawTransaction(signed, requestDetails)) as JsonRpcError; expect(response.code).to.equal(predefined.INTERNAL_ERROR().code); expect(`Error invoking RPC: ${response.message}`).to.equal(predefined.INTERNAL_ERROR(response.message).message); @@ -158,7 +161,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () fileId: null, }); - const response = (await ethImpl.sendRawTransaction(signed, getRequestId())) as JsonRpcError; + const response = (await ethImpl.sendRawTransaction(signed, requestDetails)) as JsonRpcError; expect(response.code).to.equal(predefined.INTERNAL_ERROR().code); expect(`Error invoking RPC: ${response.message}`).to.equal(predefined.INTERNAL_ERROR(response.message).message); @@ -175,7 +178,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () }); const signed = await signTransaction(transaction); - const resultingHash = await ethImpl.sendRawTransaction(signed, getRequestId()); + const resultingHash = await ethImpl.sendRawTransaction(signed, requestDetails); expect(resultingHash).to.equal(ethereumHash); }); @@ -191,7 +194,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () const signed = await signTransaction(transaction); - const resultingHash = await ethImpl.sendRawTransaction(signed, getRequestId()); + const resultingHash = await ethImpl.sendRawTransaction(signed, requestDetails); expect(resultingHash).to.equal(ethereumHash); sinon.assert.calledOnce(sdkClientStub.submitEthereumTransaction); }); @@ -203,7 +206,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () const signed = await signTransaction(transaction); - const response = (await ethImpl.sendRawTransaction(signed, getRequestId())) as JsonRpcError; + const response = (await ethImpl.sendRawTransaction(signed, requestDetails)) as JsonRpcError; expect(response.code).to.equal(predefined.INTERNAL_ERROR().code); expect(`Error invoking RPC: ${response.message}`).to.equal(predefined.INTERNAL_ERROR(response.message).message); sinon.assert.calledOnce(sdkClientStub.submitEthereumTransaction); diff --git a/packages/relay/tests/lib/mirrorNodeClient.spec.ts b/packages/relay/tests/lib/mirrorNodeClient.spec.ts index 88172e44b8..55607e27d2 100644 --- a/packages/relay/tests/lib/mirrorNodeClient.spec.ts +++ b/packages/relay/tests/lib/mirrorNodeClient.spec.ts @@ -347,7 +347,7 @@ describe('MirrorNodeClient', async function () { .onGet(`blocks?block.number=${number}&limit=100&order=asc`) .reply(200, { blocks: [block], links: { next: null } }); - const result = await mirrorNodeInstance.getBlocks(number); + const result = await mirrorNodeInstance.getBlocks(`[Request ID: testId]`, number); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -363,7 +363,7 @@ describe('MirrorNodeClient', async function () { .onGet(`blocks?timestamp=${timestamp}&limit=100&order=asc`) .reply(200, { blocks: [block], links: { next: null } }); - const result = await mirrorNodeInstance.getBlocks(undefined, timestamp); + const result = await mirrorNodeInstance.getBlocks(`[Request ID: testId]`, undefined, timestamp); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); diff --git a/packages/relay/tests/lib/openrpc.spec.ts b/packages/relay/tests/lib/openrpc.spec.ts index a245b4a806..99b88d3de7 100644 --- a/packages/relay/tests/lib/openrpc.spec.ts +++ b/packages/relay/tests/lib/openrpc.spec.ts @@ -35,6 +35,7 @@ import { Registry } from 'prom-client'; import { EthImpl } from '../../src/lib/eth'; import { SDKClient } from '../../src/lib/clients'; import { MirrorNodeClient } from '../../src/lib/clients/mirrorNodeClient'; +import type { IRequestDetails } from '../../src/lib/types/IRequestDetails'; import openRpcSchema from '../../../../docs/openrpc.json'; import { @@ -94,8 +95,12 @@ describe('Open RPC Specification', function () { let rpcDocument: any; let methodsResponseSchema: { [method: string]: any }; let ethImpl: EthImpl; + let requestDetails: IRequestDetails; + let requestIdPrefix: string; this.beforeAll(async () => { + requestIdPrefix = `[Request ID: testId]`; + requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; rpcDocument = await parseOpenRPCDocument(JSON.stringify(openRpcSchema)); methodsResponseSchema = rpcDocument.methods.reduce( (res: { [method: string]: any }, method: any) => ({ @@ -250,7 +255,7 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_blockNumber"', async function () { - const response = await ethImpl.blockNumber(); + const response = await ethImpl.blockNumber(requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_blockNumber, response); }); @@ -269,19 +274,19 @@ describe('Open RPC Specification', function () { it('should execute "eth_estimateGas"', async function () { mock.onGet(`accounts/undefined${noTransactions}`).reply(404); - const response = await ethImpl.estimateGas({}, null); + const response = await ethImpl.estimateGas({}, null, requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_estimateGas, response); }); it('should execute "eth_feeHistory"', async function () { - const response = await ethImpl.feeHistory(1, 'latest', [0]); + const response = await ethImpl.feeHistory(1, 'latest', [0], requestDetails); validateResponseSchema(methodsResponseSchema.eth_feeHistory, response); }); it('should execute "eth_gasPrice"', async function () { - const response = await ethImpl.gasPrice(); + const response = await ethImpl.gasPrice(requestDetails); validateResponseSchema(methodsResponseSchema.eth_gasPrice, response); }); @@ -293,25 +298,25 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_getBlockByHash" with hydrated = true', async function () { - const response = await ethImpl.getBlockByHash(blockHash, true); + const response = await ethImpl.getBlockByHash(blockHash, true, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBlockByHash, response); }); it('should execute "eth_getBlockByHash" with hydrated = false', async function () { - const response = await ethImpl.getBlockByHash(blockHash, true); + const response = await ethImpl.getBlockByHash(blockHash, true, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBlockByHash, response); }); it('should execute "eth_getBlockByNumber" with hydrated = true', async function () { - const response = await ethImpl.getBlockByNumber(numberTo0x(blockNumber), true); + const response = await ethImpl.getBlockByNumber(numberTo0x(blockNumber), true, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBlockByNumber, response); }); it('should execute "eth_getBlockByNumber" with hydrated = false', async function () { - const response = await ethImpl.getBlockByNumber(numberTo0x(blockNumber), false); + const response = await ethImpl.getBlockByNumber(numberTo0x(blockNumber), false, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBlockByNumber, response); }); @@ -323,33 +328,33 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_getBlockTransactionCountByNumber" with block tag', async function () { - const response = await ethImpl.getBlockTransactionCountByNumber('latest'); + const response = await ethImpl.getBlockTransactionCountByNumber('latest', requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_getBlockTransactionCountByNumber, response); }); it('should execute "eth_getBlockTransactionCountByNumber" with block number', async function () { - const response = await ethImpl.getBlockTransactionCountByNumber('0x3'); + const response = await ethImpl.getBlockTransactionCountByNumber('0x3', requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_getBlockTransactionCountByNumber, response); }); it('should execute "eth_getCode" with block tag', async function () { mock.onGet(`tokens/${defaultContractResults.results[0].contract_id}`).reply(404); - const response = await ethImpl.getCode(contractAddress1, 'latest'); + const response = await ethImpl.getCode(contractAddress1, 'latest', requestDetails); validateResponseSchema(methodsResponseSchema.eth_getCode, response); }); it('should execute "eth_getCode" with block number', async function () { mock.onGet(`tokens/${defaultContractResults.results[0].contract_id}`).reply(404); - const response = await ethImpl.getCode(contractAddress1, '0x3'); + const response = await ethImpl.getCode(contractAddress1, '0x3', requestDetails); validateResponseSchema(methodsResponseSchema.eth_getCode, response); }); it('should execute "eth_getLogs" with no filters', async function () { - const response = await ethImpl.getLogs(null, 'latest', 'latest', null, null); + const response = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails.requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_getLogs, response); }); @@ -374,13 +379,17 @@ describe('Open RPC Specification', function () { mock.onGet(`contracts/${log.address}`).reply(200, defaultContract); } - const response = await ethImpl.getLogs(null, 'latest', 'latest', null, defaultLogTopics); + const response = await ethImpl.getLogs(null, 'latest', 'latest', null, defaultLogTopics, requestDetails.requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_getLogs, response); }); it('should execute "eth_getTransactionByBlockHashAndIndex"', async function () { - const response = await ethImpl.getTransactionByBlockHashAndIndex(defaultBlock.hash, numberTo0x(defaultBlock.count)); + const response = await ethImpl.getTransactionByBlockHashAndIndex( + defaultBlock.hash, + numberTo0x(defaultBlock.count), + requestIdPrefix, + ); validateResponseSchema(methodsResponseSchema.eth_getTransactionByBlockHashAndIndex, response); }); @@ -389,13 +398,14 @@ describe('Open RPC Specification', function () { const response = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(defaultBlock.number), numberTo0x(defaultBlock.count), + requestIdPrefix, ); validateResponseSchema(methodsResponseSchema.eth_getTransactionByBlockNumberAndIndex, response); }); it('should execute "eth_getTransactionByHash"', async function () { - const response = await ethImpl.getTransactionByHash(defaultTxHash); + const response = await ethImpl.getTransactionByHash(defaultTxHash, requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_getTransactionByHash, response); }); @@ -405,7 +415,7 @@ describe('Open RPC Specification', function () { .onGet(`accounts/${contractAddress1}${noTransactions}`) .reply(200, { account: contractAddress1, ethereum_nonce: 5 }); mock.onGet(`contracts/${contractAddress1}${noTransactions}`).reply(404); - const response = await ethImpl.getTransactionCount(contractAddress1, 'latest'); + const response = await ethImpl.getTransactionCount(contractAddress1, 'latest', requestIdPrefix); validateResponseSchema(methodsResponseSchema.eth_getTransactionCount, response); }); @@ -414,7 +424,7 @@ describe('Open RPC Specification', function () { mock.onGet(`contracts/${defaultDetailedContractResultByHash.created_contract_ids[0]}`).reply(404); sinon.stub(ethImpl, 'getCurrentGasPriceForBlock').resolves('0xad78ebc5ac620000'); - const response = await ethImpl.getTransactionReceipt(defaultTxHash); + const response = await ethImpl.getTransactionReceipt(defaultTxHash, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getTransactionReceipt, response); }); @@ -474,7 +484,8 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_sendRawTransaction"', async function () { - const response = await ethImpl.sendRawTransaction(signedTransactionHash, getRequestId()); + const response = await ethImpl.sendRawTransaction(signedTransactionHash, requestDetails); + validateResponseSchema(methodsResponseSchema.eth_sendRawTransaction, response); }); diff --git a/packages/relay/tests/lib/sdkClient.spec.ts b/packages/relay/tests/lib/sdkClient.spec.ts index 5fb374b0d3..8a511ce113 100644 --- a/packages/relay/tests/lib/sdkClient.spec.ts +++ b/packages/relay/tests/lib/sdkClient.spec.ts @@ -59,6 +59,7 @@ import { FileDeleteTransaction, TransactionRecordQuery, } from '@hashgraph/sdk'; +import { IRequestDetails } from '../../src/lib/types/IRequestDetails'; config({ path: resolve(__dirname, '../test.env') }); const registry = new Registry(); @@ -75,6 +76,8 @@ describe('SdkClient', async function () { let eventEmitter: EventEmitter; let metricService: MetricService; let mirrorNodeClient: MirrorNodeClient; + let transactionService: TransactionService; + let requestDetails: IRequestDetails; const feeSchedules = { current: { @@ -94,6 +97,7 @@ describe('SdkClient', async function () { } as unknown as FeeSchedules; before(() => { + requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; const hederaNetwork = process.env.HEDERA_NETWORK!; if (hederaNetwork in constants.CHAIN_IDS) { client = Client.forName(hederaNetwork); @@ -219,7 +223,7 @@ describe('SdkClient', async function () { const convertGasPriceToTinyBarsStub = sinon.stub(sdkClient, 'convertGasPriceToTinyBars').callsFake(() => 0x160c); for (let i = 0; i < 5; i++) { - await sdkClient.getTinyBarGasFee(''); + await sdkClient.getTinyBarGasFee('', requestDetails); } sinon.assert.calledOnce(getFeeScheduleStub); @@ -2279,10 +2283,11 @@ describe('SdkClient', async function () { await sdkClient.submitEthereumTransaction( transactionBuffer, mockedCallerName, + requestDetails, randomAccountAddress, mockedNetworkGasPrice, mockedExchangeRateIncents, - requestId, + requestDetails.requestIdPrefix, ); expect.fail(`Expected an error but nothing was thrown`); } catch (error: any) { @@ -2338,10 +2343,11 @@ describe('SdkClient', async function () { await sdkClient.submitEthereumTransaction( transactionBuffer, mockedCallerName, + requestDetails, randomAccountAddress, mockedNetworkGasPrice, mockedExchangeRateIncents, - requestId, + requestDetails.requestIdPrefix, ); expect(queryStub.called).to.be.true; @@ -2384,7 +2390,7 @@ describe('SdkClient', async function () { const response = await sdkClient.createFile( callData, client, - requestId, + requestDetails, mockedCallerName, mockedInteractingEntity, randomAccountAddress, @@ -2421,7 +2427,7 @@ describe('SdkClient', async function () { new FileAppendTransaction(), mockedCallerName, mockedInteractingEntity, - requestId, + requestDetails, true, randomAccountAddress, ); @@ -2447,7 +2453,7 @@ describe('SdkClient', async function () { new FileAppendTransaction(), mockedCallerName, mockedInteractingEntity, - requestId, + requestDetails, true, randomAccountAddress, ); @@ -2500,7 +2506,7 @@ describe('SdkClient', async function () { const response = await sdkClient.createFile( callData, client, - requestId, + requestDetails, mockedCallerName, mockedInteractingEntity, randomAccountAddress, @@ -2525,7 +2531,7 @@ describe('SdkClient', async function () { hbarLimitMock.expects('addExpense').withArgs(mockedTransactionRecordFee).once(); hbarLimitMock.expects('shouldLimit').never(); - await sdkClient.deleteFile(fileId, requestId, mockedCallerName, mockedInteractingEntity, randomAccountAddress); + await sdkClient.deleteFile(fileId, requestDetails, mockedCallerName, mockedInteractingEntity, randomAccountAddress); expect(deleteFileStub.called).to.be.true; expect(fileInfoQueryStub.called).to.be.true; @@ -2543,7 +2549,7 @@ describe('SdkClient', async function () { client, mockedCallerName, mockedInteractingEntity, - requestId, + requestDetails, ); expect(result).to.equal(fileInfo); @@ -2562,7 +2568,7 @@ describe('SdkClient', async function () { client, mockedCallerName, mockedInteractingEntity, - requestId, + requestDetails, ); expect(result).to.equal(fileInfo); @@ -2590,7 +2596,7 @@ describe('SdkClient', async function () { new EthereumTransaction().setCallDataFileId(fileId).setEthereumData(transactionBuffer), mockedCallerName, mockedInteractingEntity, - requestId, + requestDetails, true, randomAccountAddress, ); @@ -2640,7 +2646,7 @@ describe('SdkClient', async function () { new EthereumTransaction().setCallDataFileId(fileId).setEthereumData(transactionBuffer), mockedCallerName, mockedInteractingEntity, - requestId, + requestDetails, true, randomAccountAddress, ); diff --git a/packages/relay/tests/lib/services/eth/filter.spec.ts b/packages/relay/tests/lib/services/eth/filter.spec.ts index 3196cf9041..d27f857af4 100644 --- a/packages/relay/tests/lib/services/eth/filter.spec.ts +++ b/packages/relay/tests/lib/services/eth/filter.spec.ts @@ -32,6 +32,7 @@ import RelayAssertions from '../../../assertions'; import { predefined } from '../../../../src'; import { CacheService } from '../../../../src/lib/services/cacheService/cacheService'; import * as sinon from 'sinon'; +import { request } from 'http'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); const logger = pino(); @@ -56,6 +57,7 @@ describe('Filter API Test Suite', async function () { const LATEST_BLOCK_QUERY = 'blocks?limit=1&order=desc'; const BLOCK_BY_NUMBER_QUERY = 'blocks'; let logFilterObject; + let requestIdPrefix; const validateFilterCache = async (filterId, expectedFilterType, expectedParams = {}) => { const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; @@ -71,6 +73,7 @@ describe('Filter API Test Suite', async function () { this.beforeAll(() => { cacheMock = sinon.createSandbox(); + requestIdPrefix = `[Request ID: testId]`; blockFilterObject = { type: constants.FILTER.TYPE.NEW_BLOCK, params: { @@ -160,7 +163,7 @@ describe('Filter API Test Suite', async function () { it('FILTER_API_ENABLED=true', async function () { process.env.FILTER_API_ENABLED = 'true'; restMock.onGet(LATEST_BLOCK_QUERY).reply(200, { blocks: [{ ...defaultBlock }] }); - const filterId = await filterService.newFilter(); + const filterId = await filterService.newFilter(undefined, undefined, requestIdPrefix); expect(filterId).to.exist; expect(RelayAssertions.validateHash(filterId, 32)).to.eq(true, 'returns valid filterId'); @@ -173,7 +176,7 @@ describe('Filter API Test Suite', async function () { `contracts/results/logs?timestamp=gte:${defaultBlock.timestamp.from}×tamp=lte:${defaultBlock.timestamp.to}&limit=100&order=asc`, ) .reply(200, defaultLogs1); - const filterChanges = await filterService.getFilterChanges(filterId); + const filterChanges = await filterService.getFilterChanges(filterId, requestIdPrefix); expect(filterChanges).to.exist; cacheMock.restore(); @@ -231,27 +234,30 @@ describe('Filter API Test Suite', async function () { }); it('Returns a valid filterId', async function () { - expect(RelayAssertions.validateHash(await filterService.newFilter(), 32)).to.eq( - true, - 'with default param values', - ); - expect(RelayAssertions.validateHash(await filterService.newFilter(numberHex), 32)).to.eq(true, 'with fromBlock'); - expect(RelayAssertions.validateHash(await filterService.newFilter(numberHex, 'latest'), 32)).to.eq( - true, - 'with fromBlock, toBlock', - ); expect( - RelayAssertions.validateHash(await filterService.newFilter(numberHex, 'latest', defaultEvmAddress), 32), + RelayAssertions.validateHash(await filterService.newFilter(undefined, undefined, requestIdPrefix), 32), + ).to.eq(true, 'with default param values'); + expect( + RelayAssertions.validateHash(await filterService.newFilter(numberHex, undefined, requestIdPrefix), 32), + ).to.eq(true, 'with fromBlock'); + expect( + RelayAssertions.validateHash(await filterService.newFilter(numberHex, 'latest', requestIdPrefix), 32), + ).to.eq(true, 'with fromBlock, toBlock'); + expect( + RelayAssertions.validateHash( + await filterService.newFilter(numberHex, 'latest', requestIdPrefix, defaultEvmAddress), + 32, + ), ).to.eq(true, 'with fromBlock, toBlock, address'); expect( RelayAssertions.validateHash( - await filterService.newFilter(numberHex, 'latest', defaultEvmAddress, defaultLogTopics), + await filterService.newFilter(numberHex, 'latest', requestIdPrefix, defaultEvmAddress, defaultLogTopics), 32, ), ).to.eq(true, 'with fromBlock, toBlock, address, topics'); expect( RelayAssertions.validateHash( - await filterService.newFilter(numberHex, 'latest', defaultEvmAddress, defaultLogTopics, getRequestId()), + await filterService.newFilter(numberHex, 'latest', requestIdPrefix, defaultEvmAddress, defaultLogTopics), 32, ), ).to.eq(true, 'with all parameters'); @@ -261,9 +267,9 @@ describe('Filter API Test Suite', async function () { const filterId = await filterService.newFilter( numberHex, 'latest', + requestIdPrefix, defaultEvmAddress, defaultLogTopics, - getRequestId(), ); validateFilterCache(filterId, constants.FILTER.TYPE.LOG, { fromBlock: numberHex, @@ -301,11 +307,17 @@ describe('Filter API Test Suite', async function () { // block range is valid expect( - RelayAssertions.validateHash(await filterService.newFilter(blockNumberHexes[1400], blockNumberHexes[1500]), 32), + RelayAssertions.validateHash( + await filterService.newFilter(blockNumberHexes[1400], blockNumberHexes[1500], requestIdPrefix), + 32, + ), + ).to.eq(true); + expect( + RelayAssertions.validateHash( + await filterService.newFilter(blockNumberHexes[1400], 'latest', requestIdPrefix), + 32, + ), ).to.eq(true); - expect(RelayAssertions.validateHash(await filterService.newFilter(blockNumberHexes[1400], 'latest'), 32)).to.eq( - true, - ); }); }); @@ -339,7 +351,9 @@ describe('Filter API Test Suite', async function () { }); it('Returns a valid filterId', async function () { - expect(RelayAssertions.validateHash(await filterService.newBlockFilter(), 32)).to.eq(true); + expect( + RelayAssertions.validateHash(await filterService.newBlockFilter(undefined, undefined, requestIdPrefix), 32), + ).to.eq(true); }); it('Creates a filter with type=new_block', async function () { @@ -353,7 +367,11 @@ describe('Filter API Test Suite', async function () { describe('eth_getFilterLogs', async function () { it('should throw FILTER_NOT_FOUND for type=newBlock', async function () { cacheMock.stub(cacheService, 'getAsync').returns(undefined); - const filterIdBlockType = await filterService.createFilter(constants.FILTER.TYPE.NEW_BLOCK, filterObject); + const filterIdBlockType = await filterService.createFilter( + constants.FILTER.TYPE.NEW_BLOCK, + filterObject, + requestIdPrefix, + ); await RelayAssertions.assertRejection( predefined.FILTER_NOT_FOUND, filterService.getFilterLogs, @@ -368,6 +386,7 @@ describe('Filter API Test Suite', async function () { const filterIdBlockType = await filterService.createFilter( constants.FILTER.TYPE.PENDING_TRANSACTION, filterObject, + requestIdPrefix, ); await RelayAssertions.assertRejection( predefined.FILTER_NOT_FOUND, @@ -400,7 +419,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter('0x1'); + const filterId = await filterService.newFilter('0x1', undefined, requestIdPrefix); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -412,7 +431,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId); + const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); expect(logs).to.not.be.empty; logs.every((log) => expect(Number(log.blockNumber)).to.be.greaterThan(1)); @@ -437,7 +456,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter(null, '0x3'); + const filterId = await filterService.newFilter(null, '0x3', requestIdPrefix); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -450,7 +469,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId); + const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); expect(logs).to.not.be.empty; logs.every((log) => expect(Number(log.blockNumber)).to.be.lessThan(3)); @@ -471,7 +490,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter(null, null, defaultEvmAddress); + const filterId = await filterService.newFilter(null, null, requestIdPrefix, defaultEvmAddress); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock @@ -485,7 +504,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId); + const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); expect(logs).to.not.be.empty; logs.every((log) => expect(log.address).to.equal(defaultEvmAddress)); @@ -511,7 +530,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter(null, null, null, customTopic); + const filterId = await filterService.newFilter(null, null, requestIdPrefix, null, customTopic); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -524,7 +543,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId); + const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); expect(logs).to.not.be.empty; logs.every((log) => expect(log.topics).to.deep.equal(customTopic)); @@ -585,7 +604,7 @@ describe('Filter API Test Suite', async function () { .onThirdCall() .returns({ ...blockFilterObject, lastQueried: defaultBlock.number + 4 }); - const result = await filterService.getFilterChanges(existingFilterId); + const result = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); expect(result).to.exist; expect(result.length).to.eq(3, 'returns correct number of blocks'); @@ -593,7 +612,7 @@ describe('Filter API Test Suite', async function () { expect(result[1]).to.eq('0x2'); expect(result[2]).to.eq('0x3'); - const secondResult = await filterService.getFilterChanges(existingFilterId); + const secondResult = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); expect(secondResult).to.exist; expect(secondResult.length).to.eq(0, 'second call returns no block hashes'); }); @@ -624,10 +643,10 @@ describe('Filter API Test Suite', async function () { .onSecondCall() .returns({ ...blockFilterObject, lastQueried: defaultBlock.number + 1 }); - const resultCurrentBlock = await filterService.getFilterChanges(existingFilterId); + const resultCurrentBlock = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); expect(resultCurrentBlock).to.not.be.empty; - const resultSameBlock = await filterService.getFilterChanges(existingFilterId); + const resultSameBlock = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); expect(resultSameBlock).to.be.empty; }); @@ -653,7 +672,7 @@ describe('Filter API Test Suite', async function () { .reply(200, filteredLogs); restMock.onGet('blocks/1').reply(200, { ...defaultBlock, block_number: 1 }); - const filterId = await filterService.newFilter('0x1'); + const filterId = await filterService.newFilter('0x1', undefined, requestIdPrefix); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -665,7 +684,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterChanges(filterId); + const logs = await filterService.getFilterChanges(filterId, requestIdPrefix); expect(logs).to.not.be.empty; logs.every((log) => expect(Number(log.blockNumber)).to.equal(9)); }); @@ -679,7 +698,7 @@ describe('Filter API Test Suite', async function () { .reply(200, []); restMock.onGet('blocks/1').reply(200, { ...defaultBlock, block_number: 1 }); - const filterId = await filterService.newFilter('0x1'); + const filterId = await filterService.newFilter('0x1', undefined, requestIdPrefix); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -690,7 +709,7 @@ describe('Filter API Test Suite', async function () { fromBlock: 1, }, }); - const logs = await filterService.getFilterChanges(filterId); + const logs = await filterService.getFilterChanges(filterId, requestIdPrefix); expect(logs).to.be.empty; }); @@ -701,17 +720,10 @@ describe('Filter API Test Suite', async function () { }); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${existingFilterId}`; - cacheService.set( - cacheKey, - blockFilterObject, - filterService.ethGetFilterChanges, - constants.FILTER.TTL, - undefined, - true, - ); + cacheService.set(cacheKey, blockFilterObject, filterService.ethGetFilterChanges, constants.FILTER.TTL, undefined); cacheMock.stub(cacheService, 'getAsync').returns(blockFilterObject); - const blocks = await filterService.getFilterChanges(existingFilterId); + const blocks = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); expect(blocks).to.be.empty; }); }); From f2697b65857efaa70e16f0c7f543921a1b2e5712 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 4 Sep 2024 15:48:46 +0300 Subject: [PATCH 03/48] Fixes conflicts Signed-off-by: Konstantina Blazhukova --- packages/relay/src/lib/clients/sdkClient.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index b6445917ea..3d38244460 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -616,7 +616,6 @@ export class SDKClient { ): Promise { const queryConstructorName = query.constructor.name; const requestIdPrefix = requestDetails?.requestIdPrefix; - const queryType = query.constructor.name; let queryResponse: any = null; let queryCost: number | undefined = undefined; let status: string = ''; @@ -1002,7 +1001,7 @@ export class SDKClient { let txRecordChargeAmount: number = 0; try { this.logger.trace( - `${formattedRequestId} Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`, + `${requestId} Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`, ); const transactionRecord = await new TransactionRecordQuery() @@ -1023,7 +1022,7 @@ export class SDKClient { const sdkClientError = new SDKClientError(e, e.message); this.logger.warn( e, - `${formattedRequestId} Error raised during TransactionRecordQuery: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, recordStatus=${sdkClientError.status} (${sdkClientError.status._code}), cost=${transactionFee}, gasUsed=${gasUsed}`, + `${requestId} Error raised during TransactionRecordQuery: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, recordStatus=${sdkClientError.status} (${sdkClientError.status._code}), cost=${transactionFee}, gasUsed=${gasUsed}`, ); throw sdkClientError; } From 732f4f21cf10da3e96f44a7d709c82ec36335b31 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 4 Sep 2024 15:50:26 +0300 Subject: [PATCH 04/48] Adds requestDetails to estimate gas Signed-off-by: Konstantina Blazhukova --- packages/relay/src/index.ts | 2 +- packages/relay/src/lib/eth.ts | 27 ++++++++++++++-------- packages/relay/tests/lib/sdkClient.spec.ts | 8 ++++++- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/relay/src/index.ts b/packages/relay/src/index.ts index 78dceae2b5..bb86cc96be 100644 --- a/packages/relay/src/index.ts +++ b/packages/relay/src/index.ts @@ -72,7 +72,7 @@ export interface Eth { estimateGas( transaction: IContractCallRequest, blockParam: string | null, - requestId?: string, + requestDetails: IRequestDetails, ): Promise; gasPrice(requestDetails: IRequestDetails): Promise; diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 6287be2479..89ac10a3eb 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -575,8 +575,9 @@ export class EthImpl implements Eth { async estimateGas( transaction: IContractCallRequest, _blockParam: string | null, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; const callData = transaction.data ? transaction.data : transaction.input; const callDataSize = callData ? callData.length : 0; @@ -591,7 +592,7 @@ export class EthImpl implements Eth { ); try { - const response = await this.estimateGasFromMirrorNode(transaction, requestIdPrefix); + const response = await this.estimateGasFromMirrorNode(transaction, requestDetails); if (response?.result) { this.logger.info(`${requestIdPrefix} Returning gas: ${response.result}`); return prepend0x(trimPrecedingZeros(response.result)); @@ -620,11 +621,11 @@ export class EthImpl implements Eth { */ private async estimateGasFromMirrorNode( transaction: IContractCallRequest, - requestIdPrefix?: string, + requestDetails: IRequestDetails, ): Promise { - await this.contractCallFormat(transaction, requestIdPrefix); + await this.contractCallFormat(transaction, requestDetails); const callData = { ...transaction, estimate: true }; - return this.mirrorNodeClient.postContractCall(callData, requestIdPrefix); + return this.mirrorNodeClient.postContractCall(callData, requestDetails.requestIdPrefix); } /** @@ -711,14 +712,14 @@ export class EthImpl implements Eth { * @param transaction * @param requestIdPrefix */ - async contractCallFormat(transaction: IContractCallRequest, requestIdPrefix?: string): Promise { + async contractCallFormat(transaction: IContractCallRequest, requestDetails: IRequestDetails): Promise { if (transaction.value) { transaction.value = weibarHexToTinyBarInt(transaction.value); } if (transaction.gasPrice) { transaction.gasPrice = parseInt(transaction.gasPrice.toString()); } else { - transaction.gasPrice = await this.gasPrice(requestIdPrefix).then((gasPrice) => parseInt(gasPrice)); + transaction.gasPrice = await this.gasPrice(requestDetails).then((gasPrice) => parseInt(gasPrice)); } if (transaction.gas) { transaction.gas = parseInt(transaction.gas.toString()); @@ -728,7 +729,7 @@ export class EthImpl implements Eth { transaction.from = this.hapiService.getMainClientInstance().operatorPublicKey?.toEvmAddress(); } else { const operatorId = this.hapiService.getMainClientInstance().operatorAccountId!.toString(); - const operatorAccount = await this.getAccount(operatorId, requestIdPrefix); + const operatorAccount = await this.getAccount(operatorId, requestDetails.requestIdPrefix); transaction.from = operatorAccount?.evm_address; } } @@ -1272,7 +1273,13 @@ export class EthImpl implements Eth { }); if (!this.common.blockTagIsLatestOrPending(blockNumOrTag)) { - await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, undefined, requestDetails.requestIdPrefix); + await this.cacheService.set( + cacheKey, + block, + EthImpl.ethGetBlockByNumber, + undefined, + requestDetails.requestIdPrefix, + ); } } @@ -1690,7 +1697,7 @@ export class EthImpl implements Eth { // Get a reasonable value for "gas" if it is not specified. const gas = this.getCappedBlockGasLimit(call.gas?.toString(), requestIdPrefix); - await this.contractCallFormat(call, requestIdPrefix); + await this.contractCallFormat(call, requestDetails); const selector = getFunctionSelector(call.data!); diff --git a/packages/relay/tests/lib/sdkClient.spec.ts b/packages/relay/tests/lib/sdkClient.spec.ts index 8a511ce113..c27a3e8cb6 100644 --- a/packages/relay/tests/lib/sdkClient.spec.ts +++ b/packages/relay/tests/lib/sdkClient.spec.ts @@ -2531,7 +2531,13 @@ describe('SdkClient', async function () { hbarLimitMock.expects('addExpense').withArgs(mockedTransactionRecordFee).once(); hbarLimitMock.expects('shouldLimit').never(); - await sdkClient.deleteFile(fileId, requestDetails, mockedCallerName, mockedInteractingEntity, randomAccountAddress); + await sdkClient.deleteFile( + fileId, + requestDetails, + mockedCallerName, + mockedInteractingEntity, + randomAccountAddress, + ); expect(deleteFileStub.called).to.be.true; expect(fileInfoQueryStub.called).to.be.true; From a109e0fff9c33113266ae610e74d3056a01de2d0 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 4 Sep 2024 15:53:10 +0300 Subject: [PATCH 05/48] Adds request details param to estimate gas unit tests Signed-off-by: Konstantina Blazhukova --- .../tests/lib/eth/eth_estimateGas.spec.ts | 244 ++++++++++-------- 1 file changed, 141 insertions(+), 103 deletions(-) diff --git a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts index 85d4facbdb..729b297bb3 100644 --- a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts +++ b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts @@ -39,6 +39,7 @@ import { ONE_TINYBAR_IN_WEI_HEX, RECEIVER_ADDRESS, } from './eth-config'; +import { IRequestDetails } from '../../../dist/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -50,18 +51,20 @@ let currentMaxBlockRange: number; describe('@ethEstimateGas Estimate Gas spec', async function () { this.timeout(10000); - let { restMock, web3Mock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger, registry } = + const { restMock, web3Mock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger, registry } = generateEthTestEnv(); - let requestIdPrefix; + let requestIdPrefix: string; + let requestDetails: IRequestDetails; async function mockContractCall( callData: IContractCallRequest, estimate: boolean, statusCode: number, result: IContractCallResponse, + requestDetails: IRequestDetails, ) { const formattedData = { ...callData, estimate }; - await ethImpl.contractCallFormat(formattedData); + await ethImpl.contractCallFormat(formattedData, requestDetails); return web3Mock.onPost('contracts/call', formattedData).reply(statusCode, result); } @@ -83,6 +86,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { restMock.reset(); requestIdPrefix = `[Request ID: testId]`; + requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; sdkClientStub = createStubInstance(SDKClient); getSdkClientStub = stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); ethImplOverridden = new EthImpl(hapiServiceInstance, mirrorNodeInstance, logger, '0x12a', registry, cacheService); @@ -110,9 +114,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { gasPrice: '0x0', data: null, }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); - const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); + const gas = await ethImpl.estimateGas(callData, null, requestDetails); expect(gas).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); @@ -122,9 +126,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { from: '0x81cb089c285e5ee3a7353704fb114955037443af', to: RECEIVER_ADDRESS, }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); - const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); + const gas = await ethImpl.estimateGas(callData, null, requestDetails); expect(gas).to.equal(numberTo0x(constants.TX_CONTRACT_CALL_AVERAGE_GAS)); }); @@ -133,9 +137,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { data: '0x608060405234801561001057600080fd5b506040516107893803806107898339818101604052810190610032919061015a565b806000908051906020019061004892919061004f565b50506102f6565b82805461005b90610224565b90600052602060002090601f01602090048101928261007d57600085556100c4565b82601f1061009657805160ff19168380011785556100c4565b828001600101855582156100c4579182015b828111156100c35782518255916020019190600101906100a8565b5b5090506100d191906100d5565b5090565b5b808211156100ee5760008160009055506001016100d6565b5090565b6000610105610100846101c0565b61019b565b90508281526020810184848401111561011d57600080fd5b6101288482856101f1565b509392505050565b600082601f83011261014157600080fd5b81516101518482602086016100f2565b91505092915050565b60006020828403121561016c57600080fd5b600082015167ffffffffffffffff81111561018657600080fd5b61019284828501610130565b91505092915050565b60006101a56101b6565b90506101b18282610256565b919050565b6000604051905090565b600067ffffffffffffffff8211156101db576101da6102b6565b5b6101e4826102e5565b9050602081019050919050565b60005b8381101561020f5780820151818401526020810190506101f4565b8381111561021e576000848401525b50505050565b6000600282049050600182168061023c57607f821691505b602082108114156102505761024f610287565b5b50919050565b61025f826102e5565b810181811067ffffffffffffffff8211171561027e5761027d6102b6565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b610484806103056000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610057575b600080fd5b6100556004803603810190610050919061022c565b610075565b005b61005f61008f565b60405161006c91906102a6565b60405180910390f35b806000908051906020019061008b929190610121565b5050565b60606000805461009e9061037c565b80601f01602080910402602001604051908101604052809291908181526020018280546100ca9061037c565b80156101175780601f106100ec57610100808354040283529160200191610117565b820191906000526020600020905b8154815290600101906020018083116100fa57829003601f168201915b5050505050905090565b82805461012d9061037c565b90600052602060002090601f01602090048101928261014f5760008555610196565b82601f1061016857805160ff1916838001178555610196565b82800160010185558215610196579182015b8281111561019557825182559160200191906001019061017a565b5b5090506101a391906101a7565b5090565b5b808211156101c05760008160009055506001016101a8565b5090565b60006101d76101d2846102ed565b6102c8565b9050828152602081018484840111156101ef57600080fd5b6101fa84828561033a565b509392505050565b600082601f83011261021357600080fd5b81356102238482602086016101c4565b91505092915050565b60006020828403121561023e57600080fd5b600082013567ffffffffffffffff81111561025857600080fd5b61026484828501610202565b91505092915050565b60006102788261031e565b6102828185610329565b9350610292818560208601610349565b61029b8161043d565b840191505092915050565b600060208201905081810360008301526102c0818461026d565b905092915050565b60006102d26102e3565b90506102de82826103ae565b919050565b6000604051905090565b600067ffffffffffffffff8211156103085761030761040e565b5b6103118261043d565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b8381101561036757808201518184015260208101905061034c565b83811115610376576000848401525b50505050565b6000600282049050600182168061039457607f821691505b602082108114156103a8576103a76103df565b5b50919050565b6103b78261043d565b810181811067ffffffffffffffff821117156103d6576103d561040e565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fea264697066735822122070d157c4efbb3fba4a1bde43cbba5b92b69f2fc455a650c0dfb61e9ed3d4bd6364736f6c634300080400330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b696e697469616c5f6d7367000000000000000000000000000000000000000000', from: '0x81cb089c285e5ee3a7353704fb114955037443af', }; - await mockContractCall(callData, true, 200, { result: `0x61A80` }); + await mockContractCall(callData, true, 200, { result: `0x61A80` }, requestDetails); - const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); + const gas = await ethImpl.estimateGas(callData, null, requestDetails); expect((gas as string).toLowerCase()).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT).toLowerCase()); }); @@ -145,9 +149,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { from: '0x81cb089c285e5ee3a7353704fb114955037443af', value: 1, }; - await mockContractCall(callData, true, 200, { result: `0x61A80` }); + await mockContractCall(callData, true, 200, { result: `0x61A80` }, requestDetails); - const gas = await ethImpl.estimateGas({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, null, requestIdPrefix); + const gas = await ethImpl.estimateGas({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, null, requestDetails); expect((gas as string).toLowerCase()).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT).toLowerCase()); }); @@ -155,9 +159,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { const callData: IContractCallRequest = { data: '0x01', }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); - const gas = await ethImpl.estimateGas({ data: '0x01' }, null, requestIdPrefix); + const gas = await ethImpl.estimateGas({ data: '0x01' }, null, requestDetails); expect(gas).to.equal(numberTo0x(Precheck.transactionIntrinsicGasCost(callData.data!))); }); @@ -168,10 +172,12 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { to: RECEIVER_ADDRESS, value: '0x2540BE400', }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(200, { address: RECEIVER_ADDRESS }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); + restMock + .onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`) + .reply(200, { address: RECEIVER_ADDRESS }, requestDetails); - const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); + const gas = await ethImpl.estimateGas(callData, null, requestDetails); expect(gas).to.equal(numberTo0x(constants.TX_BASE_COST)); }); @@ -181,10 +187,12 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { from: '0x81cb089c285e5ee3a7353704fb114955037443af', to: RECEIVER_ADDRESS, }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); - restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(200, { address: RECEIVER_ADDRESS }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); + restMock + .onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`) + .reply(200, { address: RECEIVER_ADDRESS }, requestDetails); - const result = await ethImpl.estimateGas(callData, null, requestIdPrefix); + const result = await ethImpl.estimateGas(callData, null, requestDetails); expect(result).to.not.be.null; expect((result as JsonRpcError).code).to.eq(-32602); }); @@ -194,7 +202,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { to: RECEIVER_ADDRESS, value: 10, //in tinybars }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(200, { address: RECEIVER_ADDRESS }); const gas = await ethImpl.estimateGas( @@ -203,7 +211,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, - requestIdPrefix, + requestDetails, ); expect(gas).to.equal(EthImpl.gasTxBaseCost); }); @@ -213,7 +221,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { to: RECEIVER_ADDRESS, value: 10, //in tinybars }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(200, { address: RECEIVER_ADDRESS }); const gasBeforeCache = await ethImpl.estimateGas( @@ -222,7 +230,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, - requestIdPrefix, + requestDetails, ); restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(404); @@ -232,7 +240,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, - requestIdPrefix, + requestDetails, ); expect(gasBeforeCache).to.equal(EthImpl.gasTxBaseCost); @@ -244,7 +252,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { to: RECEIVER_ADDRESS, value: 10, //in tinybars }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); restMock.onGet(`accounts/${RECEIVER_ADDRESS}${NO_TRANSACTIONS}`).reply(404); const hollowAccountGasCreation = await ethImpl.estimateGas( @@ -253,7 +261,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { value: 100_000_000_000, }, null, - requestIdPrefix, + requestDetails, ); expect(hollowAccountGasCreation).to.equal(EthImpl.gasTxHollowAccountCreation); @@ -264,14 +272,14 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { to: RECEIVER_ADDRESS, value: 0, //in tinybars }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); const result = await ethImpl.estimateGas( { to: RECEIVER_ADDRESS, value: 0, }, null, - requestIdPrefix, + requestDetails, ); expect(result).to.exist; @@ -291,9 +299,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { input: '0x81cb089c285e5ee3a7353704fb114955037443af85e5ee3a7353704fb114955037443af85e5ee3a7353704fb114955037443af85e5ee3a7353704fb114955037443af', }; - await mockContractCall(callData, true, 200, { result: `0x14b662` }); + await mockContractCall(callData, true, 200, { result: `0x14b662` }, requestDetails); - const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); + const gas = await ethImpl.estimateGas(callData, null, requestDetails); expect((gas as string).toLowerCase()).to.equal(numberTo0x(gasEstimation).toLowerCase()); }); @@ -303,14 +311,14 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { to: RECEIVER_ADDRESS, value: null, //in tinybars }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); const result = await ethImpl.estimateGas( { to: RECEIVER_ADDRESS, value: null, }, null, - requestIdPrefix, + requestDetails, ); expect(result).to.exist; @@ -322,17 +330,17 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { it('should eth_estimateGas empty call returns transfer cost', async function () { const callData: IContractCallRequest = {}; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); - const gas = await ethImpl.estimateGas({}, null, requestIdPrefix); + const gas = await ethImpl.estimateGas({}, null, requestDetails); expect(gas).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); it('should eth_estimateGas empty call returns transfer cost with overridden default gas', async function () { const callData: IContractCallRequest = {}; - await mockContractCall(callData, true, 200, { result: numberTo0x(defaultGasOverride) }); + await mockContractCall(callData, true, 200, { result: numberTo0x(defaultGasOverride) }, requestDetails); - const gas = await ethImplOverridden.estimateGas({}, null, requestIdPrefix); + const gas = await ethImplOverridden.estimateGas({}, null, requestDetails); expect(gas).to.equal(numberTo0x(defaultGasOverride)); }); @@ -343,9 +351,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { }; const contractsCallResponse: IContractCallResponse = { errorMessage: '', statusCode: 501 }; - await mockContractCall(callData, true, 501, contractsCallResponse); + await mockContractCall(callData, true, 501, contractsCallResponse, requestDetails); - const gas = await ethImpl.estimateGas({ data: '' }, null, requestIdPrefix); + const gas = await ethImpl.estimateGas({ data: '' }, null, requestDetails); expect(gas).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); @@ -353,9 +361,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { const callData: IContractCallRequest = { data: '', }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); - const gas = await ethImplOverridden.estimateGas({ data: '' }, null, requestIdPrefix); + const gas = await ethImplOverridden.estimateGas({ data: '' }, null, requestDetails); expect(gas).to.equal(numberTo0x(defaultGasOverride)); }); @@ -365,10 +373,10 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { to: RECEIVER_ADDRESS, value: '0x1', }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); mockGetAccount(RECEIVER_ADDRESS, 200, { account: '0.0.1234', evm_address: RECEIVER_ADDRESS }); - const gas = await ethImpl.estimateGas(callData, null, requestIdPrefix); + const gas = await ethImpl.estimateGas(callData, null, requestDetails); expect(gas).to.equal(numberTo0x(constants.TX_BASE_COST)); }); @@ -376,9 +384,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { const callData: IContractCallRequest = { data: '0x0', }; - await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }); + await mockContractCall(callData, true, 501, { errorMessage: '', statusCode: 501 }, requestDetails); - const gas = await ethImplOverridden.estimateGas({ data: '0x' }, null, requestIdPrefix); + const gas = await ethImplOverridden.estimateGas({ data: '0x' }, null, requestDetails); expect(gas).to.equal(numberTo0x(defaultGasOverride)); }); @@ -394,9 +402,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { ], }, }; - await mockContractCall(transaction, true, 400, contractCallResult); + await mockContractCall(transaction, true, 400, contractCallResult, requestDetails); - const estimatedGas = await ethImpl.estimateGas(transaction, id, requestIdPrefix); + const estimatedGas = await ethImpl.estimateGas(transaction, id, requestDetails); expect(estimatedGas).to.equal(numberTo0x(Precheck.transactionIntrinsicGasCost(transaction.data!))); }); @@ -404,38 +412,50 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { it('should eth_estimateGas with contract revert and message does not equal executionReverted and ESTIMATE_GAS_THROWS is set to false', async function () { const estimateGasThrows = process.env.ESTIMATE_GAS_THROWS; process.env.ESTIMATE_GAS_THROWS = 'false'; - await mockContractCall(transaction, true, 400, { - _status: { - messages: [ - { - message: 'data field invalid hexadecimal string', - detail: '', - data: '', - }, - ], + await mockContractCall( + transaction, + true, + 400, + { + _status: { + messages: [ + { + message: 'data field invalid hexadecimal string', + detail: '', + data: '', + }, + ], + }, }, - }); + requestDetails, + ); - const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); + const result: any = await ethImpl.estimateGas(transaction, id, requestDetails); expect(result).to.equal(numberTo0x(Precheck.transactionIntrinsicGasCost(transaction.data!))); process.env.ESTIMATE_GAS_THROWS = estimateGasThrows; }); it('should eth_estimateGas with contract revert and message equals "execution reverted: Invalid number of recipients"', async function () { - await mockContractCall(transaction, true, 400, { - _status: { - messages: [ - { - data: '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c496e76616c6964206e756d626572206f6620726563697069656e747300000000', - detail: 'Invalid number of recipients', - message: 'CONTRACT_REVERT_EXECUTED', - }, - ], + await mockContractCall( + transaction, + true, + 400, + { + _status: { + messages: [ + { + data: '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c496e76616c6964206e756d626572206f6620726563697069656e747300000000', + detail: 'Invalid number of recipients', + message: 'CONTRACT_REVERT_EXECUTED', + }, + ], + }, }, - }); + requestDetails, + ); - const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); + const result: any = await ethImpl.estimateGas(transaction, id, requestDetails); expect(result.data).to.equal( '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c496e76616c6964206e756d626572206f6620726563697069656e747300000000', @@ -449,19 +469,25 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { const encodedMessage = new AbiCoder().encode(['string'], [decodedMessage]).replace('0x', ''); const encodedCustomError = customErrorSignature + encodedMessage; - await mockContractCall(transaction, true, 400, { - _status: { - messages: [ - { - message: 'CONTRACT_REVERT_EXECUTED', - detail: decodedMessage, - data: encodedCustomError, - }, - ], + await mockContractCall( + transaction, + true, + 400, + { + _status: { + messages: [ + { + message: 'CONTRACT_REVERT_EXECUTED', + detail: decodedMessage, + data: encodedCustomError, + }, + ], + }, }, - }); + requestDetails, + ); - const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); + const result: any = await ethImpl.estimateGas(transaction, id, requestDetails); expect(result.data).to.equal(encodedCustomError); expect(result.message).to.equal(`execution reverted: ${decodedMessage}`); @@ -473,38 +499,50 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { const encodedMessage = new AbiCoder().encode(['string'], [decodedMessage]).replace('0x', ''); const encodedGenericError = defaultErrorSignature + encodedMessage; - await mockContractCall(transaction, true, 400, { - _status: { - messages: [ - { - message: 'CONTRACT_REVERT_EXECUTED', - detail: decodedMessage, - data: encodedGenericError, - }, - ], + await mockContractCall( + transaction, + true, + 400, + { + _status: { + messages: [ + { + message: 'CONTRACT_REVERT_EXECUTED', + detail: decodedMessage, + data: encodedGenericError, + }, + ], + }, }, - }); + requestDetails, + ); - const result: any = await ethImpl.estimateGas(transaction, id, requestIdPrefix); + const result: any = await ethImpl.estimateGas(transaction, id, requestDetails); expect(result.data).to.equal(encodedGenericError); expect(result.message).to.equal(`execution reverted: ${decodedMessage}`); }); it('should eth_estimateGas handles a 501 unimplemented response from the mirror node correctly by returning default gas', async function () { - await mockContractCall(transaction, true, 501, { - _status: { - messages: [ - { - message: 'Auto account creation is not supported.', - detail: '', - data: '', - }, - ], + await mockContractCall( + transaction, + true, + 501, + { + _status: { + messages: [ + { + message: 'Auto account creation is not supported.', + detail: '', + data: '', + }, + ], + }, }, - }); + requestDetails, + ); - const result: any = await ethImpl.estimateGas({ ...transaction, data: '0x', value: '0x1' }, id, requestIdPrefix); + const result: any = await ethImpl.estimateGas({ ...transaction, data: '0x', value: '0x1' }, id, requestDetails); expect(result).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT)); }); @@ -517,7 +555,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { gas: '0xd97010', }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.value).to.eq(1110); expect(transaction.gasPrice).to.eq(1000000); expect(transaction.gas).to.eq(14250000); @@ -535,7 +573,7 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { gas: '0xd97010', }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.data).to.eq(inputValue); expect(transaction.data).to.not.eq(dataValue); expect(transaction.input).to.be.undefined; From 46e0fb4818d77eacd63db0e7e0d19fa4599d5123 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 4 Sep 2024 16:06:51 +0300 Subject: [PATCH 06/48] Adds request detail to eth_call unit tests Signed-off-by: Konstantina Blazhukova --- packages/relay/tests/lib/eth/eth_call.spec.ts | 85 ++++++++++++------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/packages/relay/tests/lib/eth/eth_call.spec.ts b/packages/relay/tests/lib/eth/eth_call.spec.ts index 03d920747c..f68dff5ab8 100644 --- a/packages/relay/tests/lib/eth/eth_call.spec.ts +++ b/packages/relay/tests/lib/eth/eth_call.spec.ts @@ -516,7 +516,7 @@ describe('@ethCall Eth Call spec', async function () { }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); + await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }, requestDetails); web3Mock.history.post = []; @@ -536,7 +536,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); + await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }, requestDetails); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); @@ -549,7 +549,7 @@ describe('@ethCall Eth Call spec', async function () { data: CONTRACT_CALL_DATA, gas: MAX_GAS_LIMIT, }; - await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); + await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }, requestDetails); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); }); @@ -562,7 +562,7 @@ describe('@ethCall Eth Call spec', async function () { data: CONTRACT_CALL_DATA, gas: MAX_GAS_LIMIT, }; - await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); + await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }, requestDetails); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); }); @@ -590,7 +590,7 @@ describe('@ethCall Eth Call spec', async function () { block: 'latest', }; - await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }); + await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: '0x00' }, requestDetails); restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); // Relay is called with value in Weibars @@ -606,7 +606,7 @@ describe('@ethCall Eth Call spec', async function () { data: CONTRACT_CALL_DATA, gas: MAX_GAS_LIMIT, }; - await mockContractCall({ ...callData, block: 'latest' }, false, 429, mockData.tooManyRequests); + await mockContractCall({ ...callData, block: 'latest' }, false, 429, mockData.tooManyRequests, requestDetails); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect((result as JsonRpcError).code).to.eq(-32605); @@ -621,7 +621,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.contractReverted); + await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.contractReverted, requestDetails); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect((result as JsonRpcError).code).to.eq(3); @@ -638,7 +638,7 @@ describe('@ethCall Eth Call spec', async function () { }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - await mockContractCall({ ...callData, block: 'latest' }, false, 501, mockData.notSuported); + await mockContractCall({ ...callData, block: 'latest' }, false, 501, mockData.notSuported, requestDetails); sdkClientStub.submitContractCallQueryWithRetry.returns({ asBytes: function () { @@ -669,7 +669,7 @@ describe('@ethCall Eth Call spec', async function () { }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.contractReverted); + await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.contractReverted, requestDetails); sinon.reset(); const result = await ethImpl.call(callData, 'latest', requestDetails); sinon.assert.notCalled(sdkClientStub.submitContractCallQueryWithRetry); @@ -688,17 +688,23 @@ describe('@ethCall Eth Call spec', async function () { }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - await mockContractCall({ ...callData, block: 'latest' }, false, 400, { - _status: { - messages: [ - { - message: '', - detail: defaultErrorMessageText, - data: defaultErrorMessageHex, - }, - ], + await mockContractCall( + { ...callData, block: 'latest' }, + false, + 400, + { + _status: { + messages: [ + { + message: '', + detail: defaultErrorMessageText, + data: defaultErrorMessageHex, + }, + ], + }, }, - }); + requestDetails, + ); const result = await ethImpl.call(callData, 'latest', requestDetails); @@ -739,7 +745,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; - await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.invalidTransaction); + await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.invalidTransaction, requestDetails); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect(result).to.equal('0x'); @@ -754,7 +760,7 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT, }; - await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.failInvalid); + await mockContractCall({ ...callData, block: 'latest' }, false, 400, mockData.failInvalid, requestDetails); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.be.not.null; expect(result).to.equal('0x'); @@ -767,7 +773,13 @@ describe('@ethCall Eth Call spec', async function () { from: ACCOUNT_ADDRESS_1, }; - await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: EXAMPLE_CONTRACT_BYTECODE }); + await mockContractCall( + { ...callData, block: 'latest' }, + false, + 200, + { result: EXAMPLE_CONTRACT_BYTECODE }, + requestDetails, + ); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.eq(EXAMPLE_CONTRACT_BYTECODE); }); @@ -778,7 +790,13 @@ describe('@ethCall Eth Call spec', async function () { from: ACCOUNT_ADDRESS_1, }; - await mockContractCall({ ...callData, block: 'latest' }, false, 200, { result: EXAMPLE_CONTRACT_BYTECODE }); + await mockContractCall( + { ...callData, block: 'latest' }, + false, + 200, + { result: EXAMPLE_CONTRACT_BYTECODE }, + requestDetails, + ); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.eq(EXAMPLE_CONTRACT_BYTECODE); }); @@ -788,9 +806,10 @@ describe('@ethCall Eth Call spec', async function () { estimate: boolean, statusCode: number, result: IContractCallResponse, + requestDetails: IRequestDetails, ) { const formattedCallData = { ...callData, estimate }; - await ethImpl.contractCallFormat(formattedCallData); + await ethImpl.contractCallFormat(formattedCallData, requestDetails); return web3Mock.onPost('contracts/call', formattedCallData).reply(statusCode, result); } }); @@ -811,7 +830,7 @@ describe('@ethCall Eth Call spec', async function () { value: '0x2540BE400', }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.value).to.equal(1); }); @@ -820,7 +839,7 @@ describe('@ethCall Eth Call spec', async function () { gasPrice: '1000000000', }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.gasPrice).to.equal(1000000000); }); @@ -830,7 +849,7 @@ describe('@ethCall Eth Call spec', async function () { gas: '50000', }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.gas).to.equal(50000); }); @@ -842,7 +861,7 @@ describe('@ethCall Eth Call spec', async function () { input: inputValue, data: dataValue, }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.data).to.eq(inputValue); expect(transaction.data).to.not.eq(dataValue); expect(transaction.input).to.be.undefined; @@ -853,7 +872,7 @@ describe('@ethCall Eth Call spec', async function () { const transaction = { data: dataValue, }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.data).to.eq(dataValue); }); @@ -862,7 +881,7 @@ describe('@ethCall Eth Call spec', async function () { input: 'input data', }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); // @ts-ignore expect(transaction.data).to.equal('input data'); @@ -876,7 +895,7 @@ describe('@ethCall Eth Call spec', async function () { gas: '50000', }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.value).to.equal(1); expect(transaction.gasPrice).to.equal(1000000000); @@ -889,7 +908,7 @@ describe('@ethCall Eth Call spec', async function () { gasPrice: undefined, }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); const expectedGasPrice = await ethImpl.gasPrice(requestDetails); expect(transaction.gasPrice).to.equal(parseInt(expectedGasPrice)); @@ -902,7 +921,7 @@ describe('@ethCall Eth Call spec', async function () { from: undefined, }; - await ethImpl.contractCallFormat(transaction); + await ethImpl.contractCallFormat(transaction, requestDetails); expect(transaction.from).to.equal(operatorEvmAddress); }); From 445f3c8a074ed6d66c6d25f8a17fb91a5a4888de Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 5 Sep 2024 11:54:03 +0300 Subject: [PATCH 07/48] passes requestDetail wherever needed Signed-off-by: Konstantina Blazhukova --- packages/server/src/server.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index c265a49bc0..4eafb4c352 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -199,8 +199,11 @@ app.getKoaApp().use(async (ctx, next) => { }); const logAndHandleResponse = async (methodName: string, methodParams: any[], methodFunction: any) => { + logger.debug('Method name: ' + methodName); const requestId = app.getRequestId(); + logger.debug('Request id' + requestId); const requestIp = app.getIpRequest(); + logger.debug('Request ip' + requestIp); const requestIdPrefix = requestId ? formatRequestIdMessage(requestId) : ''; const requestDetails: IRequestDetails = { requestIdPrefix, requestIp }; const methodsToPassRequestDetails = [ @@ -209,6 +212,10 @@ const logAndHandleResponse = async (methodName: string, methodParams: any[], met 'eth_sendRawTransaction', 'eth_feeHistory', 'eth_getTransactionReceipt', + 'eth_getBlockByNumber', + 'eth_estimateGas', + 'eth_getBlockByHash', + 'eth_gasPrice', ]; try { @@ -221,7 +228,7 @@ const logAndHandleResponse = async (methodName: string, methodParams: any[], met } const passRequestDetails = methodsToPassRequestDetails.includes(methodName); - const response = await methodFunction(passRequestDetails ? requestDetails : requestId); + const response = await methodFunction(passRequestDetails ? requestDetails : requestIdPrefix); if (response instanceof JsonRpcError) { // log error only if it is not a contract revert, otherwise log it as debug if (response.code === predefined.CONTRACT_REVERT().code) { @@ -347,8 +354,8 @@ app.useRpc('eth_chainId', async () => { * returns: Block object */ app.useRpc('eth_getBlockByNumber', async (params: any) => { - return logAndHandleResponse('eth_getBlockByNumber', params, (requestId) => - relay.eth().getBlockByNumber(params?.[0], Boolean(params?.[1]), requestId), + return logAndHandleResponse('eth_getBlockByNumber', params, (requestDetails) => + relay.eth().getBlockByNumber(params?.[0], Boolean(params?.[1]), requestDetails), ); }); @@ -360,8 +367,8 @@ app.useRpc('eth_getBlockByNumber', async (params: any) => { * returns: Block object */ app.useRpc('eth_getBlockByHash', async (params: any) => { - return logAndHandleResponse('eth_getBlockByHash', params, (requestId) => - relay.eth().getBlockByHash(params?.[0], Boolean(params?.[1]), requestId), + return logAndHandleResponse('eth_getBlockByHash', params, (requestDetails) => + relay.eth().getBlockByHash(params?.[0], Boolean(params?.[1]), requestDetails), ); }); @@ -371,7 +378,7 @@ app.useRpc('eth_getBlockByHash', async (params: any) => { * returns: Gas price - hex encoded integer */ app.useRpc('eth_gasPrice', async () => { - return logAndHandleResponse('eth_gasPrice', [], (requestId) => relay.eth().gasPrice(requestId)); + return logAndHandleResponse('eth_gasPrice', [], (requestDetails) => relay.eth().gasPrice(requestDetails)); }); /** From 3dec6a5c543b8e462ad80a8db8a2841856be3e81 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Mon, 9 Sep 2024 16:30:16 +0300 Subject: [PATCH 08/48] Makes requestIdPrefix required Signed-off-by: Konstantina Blazhukova --- .../relay/src/lib/clients/cache/redisCache.ts | 2 +- .../relay/src/lib/clients/mirrorNodeClient.ts | 82 +++++----- .../ethAddressHbarSpendingPlanRepository.ts | 4 +- .../hbarLimiter/hbarSpendingPlanRepository.ts | 34 ++-- packages/relay/src/lib/env.txt | 150 ++++++++++++++++++ packages/relay/src/lib/eth.ts | 23 +-- packages/relay/src/lib/precheck.ts | 8 +- packages/relay/src/lib/relay.ts | 2 +- .../lib/services/cacheService/cacheService.ts | 4 +- .../services/debugService/IDebugService.ts | 4 +- .../src/lib/services/debugService/index.ts | 30 ++-- .../ethService/ethCommonService/index.ts | 4 +- .../ethService/ethFilterService/index.ts | 2 +- .../hbarLimitService/IHbarLimitService.ts | 2 +- .../lib/services/hbarLimitService/index.ts | 31 ++-- packages/server/src/server.ts | 2 +- 16 files changed, 272 insertions(+), 112 deletions(-) create mode 100644 packages/relay/src/lib/env.txt diff --git a/packages/relay/src/lib/clients/cache/redisCache.ts b/packages/relay/src/lib/clients/cache/redisCache.ts index a2ed6867b5..3f0f2804e0 100644 --- a/packages/relay/src/lib/clients/cache/redisCache.ts +++ b/packages/relay/src/lib/clients/cache/redisCache.ts @@ -128,7 +128,7 @@ export class RedisCache implements IRedisCacheClient { * @param {string} [requestIdPrefix] - The optional request ID prefix. * @returns {Promise} The cached value or null if not found. */ - async get(key: string, callingMethod: string, requestIdPrefix?: string | undefined): Promise { + async get(key: string, callingMethod: string, requestIdPrefix: string): Promise { const client = await this.getConnectedClient(); const result = await client.get(key); if (result) { diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index 5f8141f72a..e2ae0197d8 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -313,17 +313,20 @@ export class MirrorNodeClient { path: string, pathLabel: string, method: REQUEST_METHODS, + requestIdPrefix: string, data?: any, - requestIdPrefix?: string, retries?: number, ): Promise { const start = Date.now(); // extract request id from prefix and remove trailing ']' character + this.logger.debug(requestIdPrefix); + this.logger.debug(`${method} + ${path} + ${requestIdPrefix}`); const requestId = requestIdPrefix ?.split(MirrorNodeClient.REQUEST_PREFIX_SEPARATOR)[1] .replace(MirrorNodeClient.REQUEST_PREFIX_TRAILING_BRACKET, MirrorNodeClient.EMPTY_STRING) || MirrorNodeClient.EMPTY_STRING; + console.log('Request id', requestId); const controller = new AbortController(); try { const axiosRequestConfig: AxiosRequestConfig = { @@ -370,19 +373,21 @@ export class MirrorNodeClient { return null; } - async get(path: string, pathLabel: string, requestIdPrefix?: string, retries?: number): Promise { - return this.request(path, pathLabel, 'GET', null, requestIdPrefix, retries); + async get(path: string, pathLabel: string, requestIdPrefix: string, retries?: number): Promise { + console.log('Mirron node getting data'); + console.log(requestIdPrefix); + return this.request(path, pathLabel, 'GET', requestIdPrefix, null, retries); } async post( path: string, data: any, pathLabel: string, - requestIdPrefix?: string, + requestIdPrefix: string, retries?: number, ): Promise { if (!data) data = {}; - return this.request(path, pathLabel, 'POST', data, requestIdPrefix, retries); + return this.request(path, pathLabel, 'POST', requestIdPrefix, data, retries); } /** @@ -426,7 +431,7 @@ export class MirrorNodeClient { url: string, pathLabel: string, resultProperty: string, - requestIdPrefix?: string, + requestIdPrefix: string, results = [], page = 1, pageMax: number = constants.MAX_MIRROR_NODE_PAGINATION, @@ -452,7 +457,7 @@ export class MirrorNodeClient { } } - public async getAccount(idOrAliasOrEvmAddress: string, requestIdPrefix?: string, retries?: number) { + public async getAccount(idOrAliasOrEvmAddress: string, requestIdPrefix: string, retries?: number) { return this.get( `${MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT}${idOrAliasOrEvmAddress}?transactions=false`, MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT, @@ -465,7 +470,7 @@ export class MirrorNodeClient { idOrAliasOrEvmAddress: string, timestampTo: string, numberOfTransactions: number = 1, - requestIdPrefix?: string, + requestIdPrefix: string, ) { const queryParamObject = {}; this.setQueryParam( @@ -487,7 +492,7 @@ export class MirrorNodeClient { ); } - public async getAccountPageLimit(idOrAliasOrEvmAddress: string, requestIdPrefix?: string) { + public async getAccountPageLimit(idOrAliasOrEvmAddress: string, requestIdPrefix: string) { return this.get( `${MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT}${idOrAliasOrEvmAddress}?limit=${constants.MIRROR_NODE_QUERY_LIMIT}`, MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT, @@ -498,7 +503,7 @@ export class MirrorNodeClient { * To be used to make paginated calls for the account information when the * transaction count exceeds the constant MIRROR_NODE_QUERY_LIMIT. *******************************************************************************/ - public async getAccountPaginated(url: string, requestIdPrefix?: string) { + public async getAccountPaginated(url: string, requestIdPrefix: string) { const queryParamObject = {}; const accountId = this.extractAccountIdFromUrl(url, requestIdPrefix); const params = new URLSearchParams(url.split('?')[1]); @@ -541,7 +546,7 @@ export class MirrorNodeClient { accountId: string, timestampFrom: string, timestampTo: string, - requestIdPrefix?: string, + requestIdPrefix: string, ) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'account.id', accountId); @@ -557,7 +562,7 @@ export class MirrorNodeClient { ); } - public async getBalanceAtTimestamp(accountId: string, timestamp?: string, requestIdPrefix?: string) { + public async getBalanceAtTimestamp(accountId: string, requestIdPrefix: string, timestamp?: string) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'account.id', accountId); this.setQueryParam(queryParamObject, 'timestamp', timestamp); @@ -569,7 +574,7 @@ export class MirrorNodeClient { ); } - public async getBlock(hashOrBlockNumber: string | number, requestIdPrefix?: string) { + public async getBlock(hashOrBlockNumber: string | number, requestIdPrefix: string) { const cachedLabel = `${constants.CACHE_KEY.GET_BLOCK}.${hashOrBlockNumber}`; const cachedResponse: any = await this.cacheService.getAsync( cachedLabel, @@ -608,7 +613,7 @@ export class MirrorNodeClient { ); } - public async getContract(contractIdOrAddress: string, requestIdPrefix?: string, retries?: number) { + public async getContract(contractIdOrAddress: string, requestIdPrefix: string, retries?: number) { return this.get( `${MirrorNodeClient.GET_CONTRACT_ENDPOINT}${contractIdOrAddress}`, MirrorNodeClient.GET_CONTRACT_ENDPOINT, @@ -621,12 +626,12 @@ export class MirrorNodeClient { return `${constants.CACHE_KEY.GET_CONTRACT}.valid.${contractIdOrAddress}`; } - public async getIsValidContractCache(contractIdOrAddress, requestIdPrefix?: string): Promise { + public async getIsValidContractCache(contractIdOrAddress, requestIdPrefix: string): Promise { const cachedLabel = this.getIsValidContractCacheLabel(contractIdOrAddress); return await this.cacheService.getAsync(cachedLabel, MirrorNodeClient.GET_CONTRACT_ENDPOINT, requestIdPrefix); } - public async isValidContract(contractIdOrAddress: string, requestIdPrefix?: string, retries?: number) { + public async isValidContract(contractIdOrAddress: string, requestIdPrefix: string, retries?: number) { const cachedResponse: any = await this.getIsValidContractCache(contractIdOrAddress, requestIdPrefix); if (cachedResponse != undefined) { return cachedResponse; @@ -646,7 +651,7 @@ export class MirrorNodeClient { return valid; } - public async getContractId(contractIdOrAddress: string, requestIdPrefix?: string, retries?: number) { + public async getContractId(contractIdOrAddress: string, requestIdPrefix: string, retries?: number) { const cachedLabel = `${constants.CACHE_KEY.GET_CONTRACT}.id.${contractIdOrAddress}`; const cachedResponse: any = await this.cacheService.getAsync( cachedLabel, @@ -679,9 +684,13 @@ export class MirrorNodeClient { return null; } - public async getContractResult(transactionIdOrHash: string, requestIdPrefix?: string) { + public async getContractResult(transactionIdOrHash: string, requestIdPrefix: string) { const cacheKey = `${constants.CACHE_KEY.GET_CONTRACT_RESULT}.${transactionIdOrHash}`; - const cachedResponse = await this.cacheService.getAsync(cacheKey, MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT); + const cachedResponse = await this.cacheService.getAsync( + cacheKey, + MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT, + requestIdPrefix, + ); if (cachedResponse) { return cachedResponse; @@ -718,7 +727,7 @@ export class MirrorNodeClient { * @param transactionIdOrHash * @param requestIdPrefix */ - public async getContractResultWithRetry(transactionIdOrHash: string, requestIdPrefix?: string) { + public async getContractResultWithRetry(transactionIdOrHash: string, requestIdPrefix: string) { const contractResult = await this.getContractResult(transactionIdOrHash, requestIdPrefix); if (contractResult && !(contractResult.transaction_index && contractResult.block_number)) { return this.getContractResult(transactionIdOrHash, requestIdPrefix); @@ -727,9 +736,9 @@ export class MirrorNodeClient { } public async getContractResults( + requestIdPrefix: string, contractResultsParams?: IContractResultsParams, limitOrderParams?: ILimitOrderParams, - requestIdPrefix?: string, ) { const queryParamObject = {}; this.setContractResultsParams(queryParamObject, contractResultsParams); @@ -746,7 +755,7 @@ export class MirrorNodeClient { ); } - public async getContractResultsDetails(contractId: string, timestamp: string, requestIdPrefix?: string) { + public async getContractResultsDetails(contractId: string, timestamp: string, requestIdPrefix: string) { return this.get( `${this.getContractResultsDetailsByContractIdAndTimestamp(contractId, timestamp)}`, MirrorNodeClient.GET_CONTRACT_RESULTS_DETAILS_BY_CONTRACT_ID_ENDPOINT, @@ -754,7 +763,7 @@ export class MirrorNodeClient { ); } - public async getContractsResultsActions(transactionIdOrHash: string, requestIdPrefix?: string): Promise { + public async getContractsResultsActions(transactionIdOrHash: string, requestIdPrefix: string): Promise { return this.get( `${this.getContractResultsActionsByTransactionIdPath(transactionIdOrHash)}`, MirrorNodeClient.GET_CONTRACTS_RESULTS_ACTIONS, @@ -764,7 +773,7 @@ export class MirrorNodeClient { public async getContractsResultsOpcodes( transactionIdOrHash: string, - requestIdPrefix?: string, + requestIdPrefix: string, params?: { memory?: boolean; stack?: boolean; storage?: boolean }, ): Promise { const queryParams = params ? this.getQueryParams(params) : ''; @@ -777,9 +786,9 @@ export class MirrorNodeClient { public async getContractResultsByAddress( contractIdOrAddress: string, + requestIdPrefix: string, contractResultsParams?: IContractResultsParams, limitOrderParams?: ILimitOrderParams, - requestIdPrefix?: string, ) { const queryParamObject = {}; this.setContractResultsParams(queryParamObject, contractResultsParams); @@ -795,7 +804,7 @@ export class MirrorNodeClient { public async getContractResultsByAddressAndTimestamp( contractIdOrAddress: string, timestamp: string, - requestIdPrefix?: string, + requestIdPrefix: string, ) { const apiPath = MirrorNodeClient.getContractResultsByAddressAndTimestampPath(contractIdOrAddress, timestamp); return this.get( @@ -844,9 +853,9 @@ export class MirrorNodeClient { public async getContractResultsLogsByAddress( address: string, + requestIdPrefix: string, contractLogsResultsParams?: IContractLogsResultsParams, limitOrderParams?: ILimitOrderParams, - requestIdPrefix?: string, ) { if (address === ethers.ZeroAddress) return []; @@ -912,15 +921,14 @@ export class MirrorNodeClient { return { limit: limit, order: order }; } - public async getNetworkExchangeRate(requestId: string, timestamp?: string) { - const formattedRequestId = formatRequestIdMessage(requestId); + public async getNetworkExchangeRate(requestIdPrefix: string, timestamp?: string) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'timestamp', timestamp); const queryParams = this.getQueryParams(queryParamObject); return this.get( `${MirrorNodeClient.GET_NETWORK_EXCHANGERATE_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_NETWORK_EXCHANGERATE_ENDPOINT, - formattedRequestId, + requestIdPrefix, ); } @@ -971,7 +979,7 @@ export class MirrorNodeClient { ); } - public async getTokenById(tokenId: string, requestIdPrefix?: string, retries?: number) { + public async getTokenById(tokenId: string, requestIdPrefix: string, retries?: number) { return this.get( `${MirrorNodeClient.GET_TOKENS_ENDPOINT}/${tokenId}`, MirrorNodeClient.GET_TOKENS_ENDPOINT, @@ -984,21 +992,21 @@ export class MirrorNodeClient { address: string, blockEndTimestamp: string | undefined, limit: number, - requestIdPrefix?: string, + requestIdPrefix: string, ) { // retrieve the timestamp of the contract const contractResultsParams: IContractResultsParams = blockEndTimestamp ? { timestamp: `lte:${blockEndTimestamp}` } : {}; const limitOrderParams: ILimitOrderParams = this.getLimitOrderQueryParam(limit, 'desc'); - return this.getContractResultsByAddress(address, contractResultsParams, limitOrderParams, requestIdPrefix); + return this.getContractResultsByAddress(address, requestIdPrefix, contractResultsParams, limitOrderParams); } public async getContractStateByAddressAndSlot( address: string, slot: string, + requestIdPrefix: string, blockEndTimestamp?: string, - requestIdPrefix?: string, ) { const limitOrderParams: ILimitOrderParams = this.getLimitOrderQueryParam( constants.MIRROR_NODE_QUERY_LIMIT, @@ -1026,7 +1034,7 @@ export class MirrorNodeClient { */ public async postContractCall( callData: IContractCallRequest, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { return this.post( MirrorNodeClient.CONTRACT_CALL_ENDPOINT, @@ -1037,7 +1045,7 @@ export class MirrorNodeClient { ); } - public async getTransactionById(transactionId: string, nonce: number | undefined, requestIdPrefix?: string) { + public async getTransactionById(transactionId: string, nonce: number | undefined, requestIdPrefix: string) { const formattedId = formatTransactionId(transactionId); if (formattedId == null) { return formattedId; @@ -1144,7 +1152,7 @@ export class MirrorNodeClient { entityIdentifier: string, searchableTypes: any[] = [constants.TYPE_CONTRACT, constants.TYPE_ACCOUNT, constants.TYPE_TOKEN], callerName: string, - requestIdPrefix?: string, + requestIdPrefix: string, retries?: number, ) { const cachedLabel = `${constants.CACHE_KEY.RESOLVE_ENTITY_TYPE}_${entityIdentifier}`; diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts index 90a90b918c..df37222494 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts @@ -51,9 +51,9 @@ export class EthAddressHbarSpendingPlanRepository { * @param {string} ethAddress - The ETH address to search for. * @returns {Promise} - The associated plan for the ETH address. */ - async findByAddress(ethAddress: string): Promise { + async findByAddress(ethAddress: string, requestIdPrefix: string): Promise { const key = this.getKey(ethAddress); - const addressPlan = await this.cache.getAsync(key, 'findByAddress'); + const addressPlan = await this.cache.getAsync(key, 'findByAddress', requestIdPrefix); if (!addressPlan) { throw new EthAddressHbarSpendingPlanNotFoundError(ethAddress); } diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts index 3bfbac5d3c..c747a2f36c 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts @@ -55,9 +55,9 @@ export class HbarSpendingPlanRepository { * @param id - The ID of the plan to get. * @returns {Promise} - The hbar spending plan object. */ - async findById(id: string): Promise { + async findById(id: string, requestIdPrefix: string): Promise { const key = this.getKey(id); - const plan = await this.cache.getAsync(key, 'findById'); + const plan = await this.cache.getAsync(key, 'findById', requestIdPrefix); if (!plan) { throw new HbarSpendingPlanNotFoundError(id); } @@ -73,12 +73,12 @@ export class HbarSpendingPlanRepository { * @param id - The ID of the plan. * @returns {Promise} - The detailed hbar spending plan object. */ - async findByIdWithDetails(id: string): Promise { - const plan = await this.findById(id); + async findByIdWithDetails(id: string, requestIdPrefix: string): Promise { + const plan = await this.findById(id, requestIdPrefix); return new HbarSpendingPlan({ ...plan, spendingHistory: [], - spentToday: await this.getSpentToday(id), + spentToday: await this.getSpentToday(id, requestIdPrefix), }); } @@ -107,8 +107,8 @@ export class HbarSpendingPlanRepository { * @param id - The ID of the plan. * @returns {Promise} - A promise that resolves if the plan exists and is active, or rejects if not. */ - async checkExistsAndActive(id: string): Promise { - const plan = await this.findById(id); + async checkExistsAndActive(id: string, requestIdPrefix: string): Promise { + const plan = await this.findById(id, requestIdPrefix); if (!plan.active) { throw new HbarSpendingPlanNotActiveError(id); } @@ -119,8 +119,8 @@ export class HbarSpendingPlanRepository { * @param id - The ID of the plan. * @returns {Promise} - A promise that resolves with the spending history. */ - async getSpendingHistory(id: string): Promise { - await this.checkExistsAndActive(id); + async getSpendingHistory(id: string, requestIdPrefix: string): Promise { + await this.checkExistsAndActive(id, requestIdPrefix); this.logger.trace(`Retrieving spending history for HbarSpendingPlan with ID ${id}...`); const key = this.getSpendingHistoryKey(id); @@ -134,8 +134,8 @@ export class HbarSpendingPlanRepository { * @param amount - The amount to add to the plan's spending. * @returns {Promise} - A promise that resolves with the new length of the spending history. */ - async addAmountToSpendingHistory(id: string, amount: number): Promise { - await this.checkExistsAndActive(id); + async addAmountToSpendingHistory(id: string, amount: number, requestIdPrefix: string): Promise { + await this.checkExistsAndActive(id, requestIdPrefix); this.logger.trace(`Adding ${amount} to spending history for HbarSpendingPlan with ID ${id}...`); const key = this.getSpendingHistoryKey(id); @@ -148,12 +148,12 @@ export class HbarSpendingPlanRepository { * @param id - The ID of the plan. * @returns {Promise} - A promise that resolves with the amount spent today. */ - async getSpentToday(id: string): Promise { - await this.checkExistsAndActive(id); + async getSpentToday(id: string, requestIdPrefix: string): Promise { + await this.checkExistsAndActive(id, requestIdPrefix); this.logger.trace(`Retrieving spentToday for HbarSpendingPlan with ID ${id}...`); const key = this.getSpentTodayKey(id); - return this.cache.getAsync(key, 'getSpentToday').then((spentToday) => parseInt(spentToday ?? '0')); + return this.cache.getAsync(key, 'getSpentToday', requestIdPrefix).then((spentToday) => parseInt(spentToday ?? '0')); } /** @@ -174,11 +174,11 @@ export class HbarSpendingPlanRepository { * @param amount - The amount to add. * @returns {Promise} - A promise that resolves when the operation is complete. */ - async addAmountToSpentToday(id: string, amount: number): Promise { - await this.checkExistsAndActive(id); + async addAmountToSpentToday(id: string, amount: number, requestIdPrefix: string): Promise { + await this.checkExistsAndActive(id, requestIdPrefix); const key = this.getSpentTodayKey(id); - if (!(await this.cache.getAsync(key, 'addAmountToSpentToday'))) { + if (!(await this.cache.getAsync(key, 'addAmountToSpentToday', requestIdPrefix))) { this.logger.trace(`No spending yet for HbarSpendingPlan with ID ${id}, setting spentToday to ${amount}...`); await this.cache.set(key, amount, 'addAmountToSpentToday', this.oneDayInMillis); } else { diff --git a/packages/relay/src/lib/env.txt b/packages/relay/src/lib/env.txt new file mode 100644 index 0000000000..d6eea35a1f --- /dev/null +++ b/packages/relay/src/lib/env.txt @@ -0,0 +1,150 @@ +apiVersion: v1 +data: + BATCH_REQUESTS_ENABLED: "true" + CACHE_MAX: "4000" + CHAIN_ID: "295" + CONSENSUS_MAX_EXECUTION_TIME: "15000" + CONTRACT_CALL_GAS_LIMIT: "50000000" + CONTRACT_QUERY_TIMEOUT_RETRIES: "3" + DEFAULT_RATE_LIMIT: "200" + DEV_MODE: "false" + ETH_CALL_CACHE_TTL: "200" + ETH_CALL_DEFAULT_TO_CONSENSUS_NODE: "false" + ETH_CALL_MAX_REQUEST_PER_SDK_INSTANCE: "20" + ETH_GET_LOGS_BLOCK_RANGE_LIMIT: "1000" + ETH_POPULATE_SYNTHETIC_CONTRACT_RESULTS: "true" + FILE_APPEND_MAX_CHUNKS: "26" + HAPI_CLIENT_DURATION_RESET: "3.6e+06" + HAPI_CLIENT_ERROR_RESET: '[50]' + HAPI_CLIENT_TRANSACTION_RESET: "50" + HBAR_RATE_LIMIT_DURATION: "120000" + HBAR_RATE_LIMIT_PREEMTIVE_CHECK: "true" + HBAR_RATE_LIMIT_TINYBAR: "277777777" + HEDERA_NETWORK: '{"3.130.52.236:50211":"0.0.4"}' + HOT_FIX_FILE_APPEND_FEE: "120000000" + HOT_FIX_FILE_CREATE_FEE: "100000000" + INPUT_SIZE_LIMIT: "1" + LIMIT_DURATION: "60000" + LOG_LEVEL: trace + MIRROR_NODE_CONTRACT_RESULTS_LOGS_PG_MAX: "200" + MIRROR_NODE_GET_CONTRACT_RESULTS_RETRIES: "10" + MIRROR_NODE_HTTP_KEEP_ALIVE: "true" + MIRROR_NODE_LIMIT_PARAM: "100" + MIRROR_NODE_RETRIES: "0" + MIRROR_NODE_RETRY_DELAY: "2000" + MIRROR_NODE_TIMEOUT: "30000" + MIRROR_NODE_URL: https://mainnet-public.mirrornode.hedera.com + RATE_LIMIT_DISABLED: "false" + REDIS_ENABLED: "true" + REDIS_URL: redis://10.171.140.116:6379 + SDK_REQUEST_TIMEOUT: "15000" + SERVER_PORT: "7546" + SUBSCRIPTIONS_ENABLED: "false" + TIER_1_RATE_LIMIT: "100" + TIER_2_RATE_LIMIT: "200" + TIER_3_RATE_LIMIT: "400" + WEB_SOCKET_PORT: "8546" +kind: ConfigMap +metadata: + annotations: + meta.helm.sh/release-name: mainnet-hashio + meta.helm.sh/release-namespace: mainnet + creationTimestamp: "2023-03-01T16:40:18Z" + labels: + app: mainnet-hashio + app.kubernetes.io/instance: mainnet-hashio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: mainnet-hashio + app.kubernetes.io/version: 0.26.0-SNAPSHOT + helm.sh/chart: hedera-json-rpc-relay-0.26.0-SNAPSHOT + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:CHAIN_ID: {} + f:CONTRACT_QUERY_TIMEOUT_RETRIES: {} + f:DEFAULT_RATE_LIMIT: {} + f:DEV_MODE: {} + f:ETH_CALL_CACHE_TTL: {} + f:ETH_GET_LOGS_BLOCK_RANGE_LIMIT: {} + f:HAPI_CLIENT_DURATION_RESET: {} + f:HAPI_CLIENT_TRANSACTION_RESET: {} + f:INPUT_SIZE_LIMIT: {} + f:LIMIT_DURATION: {} + f:MIRROR_NODE_LIMIT_PARAM: {} + f:MIRROR_NODE_URL: {} + f:RATE_LIMIT_DISABLED: {} + f:SERVER_PORT: {} + f:SUBSCRIPTIONS_ENABLED: {} + f:TIER_1_RATE_LIMIT: {} + f:TIER_2_RATE_LIMIT: {} + f:TIER_3_RATE_LIMIT: {} + f:WEB_SOCKET_PORT: {} + f:metadata: + f:annotations: + .: {} + f:meta.helm.sh/release-name: {} + f:meta.helm.sh/release-namespace: {} + f:labels: + .: {} + f:app: {} + f:app.kubernetes.io/instance: {} + f:app.kubernetes.io/managed-by: {} + f:app.kubernetes.io/name: {} + f:app.kubernetes.io/version: {} + f:helm.sh/chart: {} + manager: helm + operation: Update + time: "2023-07-13T17:15:56Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + f:HEDERA_NETWORK: {} + f:REDIS_URL: {} + manager: kubectl-edit + operation: Update + time: "2024-03-11T18:34:36Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + f:BATCH_REQUESTS_ENABLED: {} + f:CACHE_MAX: {} + f:CONSENSUS_MAX_EXECUTION_TIME: {} + f:CONTRACT_CALL_GAS_LIMIT: {} + f:ETH_CALL_DEFAULT_TO_CONSENSUS_NODE: {} + f:ETH_CALL_MAX_REQUEST_PER_SDK_INSTANCE: {} + f:ETH_POPULATE_SYNTHETIC_CONTRACT_RESULTS: {} + f:FILE_APPEND_MAX_CHUNKS: {} + f:HAPI_CLIENT_ERROR_RESET: {} + f:LOG_LEVEL: {} + f:MIRROR_NODE_CONTRACT_RESULTS_LOGS_PG_MAX: {} + f:MIRROR_NODE_GET_CONTRACT_RESULTS_RETRIES: {} + f:MIRROR_NODE_HTTP_KEEP_ALIVE: {} + f:MIRROR_NODE_RETRIES: {} + f:MIRROR_NODE_RETRY_DELAY: {} + f:MIRROR_NODE_TIMEOUT: {} + f:REDIS_ENABLED: {} + f:SDK_REQUEST_TIMEOUT: {} + manager: GoogleCloudConsole + operation: Update + time: "2024-05-17T15:54:57Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + f:HBAR_RATE_LIMIT_DURATION: {} + f:HBAR_RATE_LIMIT_PREEMTIVE_CHECK: {} + f:HBAR_RATE_LIMIT_TINYBAR: {} + f:HOT_FIX_FILE_APPEND_FEE: {} + f:HOT_FIX_FILE_CREATE_FEE: {} + manager: unknown + operation: Update + time: "2024-08-13T15:41:32Z" + name: mainnet-hashio + namespace: mainnet + resourceVersion: "578640270" + uid: 2465adbe-72e0-4504-85ea-ca36c790b142 diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 89ac10a3eb..04397a62cd 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -625,6 +625,7 @@ export class EthImpl implements Eth { ): Promise { await this.contractCallFormat(transaction, requestDetails); const callData = { ...transaction, estimate: true }; + console.log('Before post contract call'); return this.mirrorNodeClient.postContractCall(callData, requestDetails.requestIdPrefix); } @@ -697,7 +698,7 @@ export class EthImpl implements Eth { * @param {string} requestIdPrefix the prefix for the request ID * @returns {Promise} the account (if such exists for the given address) */ - private async getAccount(address: string, requestIdPrefix?: string): Promise { + private async getAccount(address: string, requestIdPrefix: string): Promise { const key = `${constants.CACHE_KEY.ACCOUNT}_${address}`; let account = await this.cacheService.getAsync(key, EthImpl.ethEstimateGas, requestIdPrefix); if (!account) { @@ -916,7 +917,7 @@ export class EthImpl implements Eth { const blockEndTimestamp = blockResponse?.timestamp?.to; await this.mirrorNodeClient - .getContractStateByAddressAndSlot(address, slot, blockEndTimestamp, requestIdPrefix) + .getContractStateByAddressAndSlot(address, slot, requestIdPrefix, blockEndTimestamp) .then((response) => { if (response !== null && response.state.length > 0) { result = response.state[0].value; @@ -970,7 +971,7 @@ export class EthImpl implements Eth { if (blockNumberOrTagOrHash != null && blockNumberOrTagOrHash.length > 32) { isHash = true; - blockHashNumber = await this.mirrorNodeClient.getBlock(blockNumberOrTagOrHash); + blockHashNumber = await this.mirrorNodeClient.getBlock(blockNumberOrTagOrHash, requestIdPrefix); } const currentBlockNumber = isHash ? Number(blockHashNumber.number) : Number(blockNumberOrTagOrHash); @@ -1017,8 +1018,8 @@ export class EthImpl implements Eth { if (timeDiff > constants.BALANCES_UPDATE_INTERVAL) { const balance = await this.mirrorNodeClient.getBalanceAtTimestamp( account, - block.timestamp.from, requestIdPrefix, + block.timestamp.from, ); balanceFound = true; if (balance?.balances?.length) { @@ -1292,7 +1293,7 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getBlockTransactionCountByHash(hash: string, requestIdPrefix?: string): Promise { + async getBlockTransactionCountByHash(hash: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} getBlockTransactionCountByHash(hash=${hash}, showDetails=%o)`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_TRANSACTION_COUNT_BY_HASH}_${hash}`; @@ -1749,12 +1750,12 @@ export class EthImpl implements Eth { requestIdPrefix: string, ): Promise { const contractResults = await this.mirrorNodeClient.getContractResults( + requestIdPrefix, { [blockParam.title]: blockParam.value, transactionIndex: Number(transactionIndex), }, undefined, - requestIdPrefix, ); if (!contractResults[0]) return null; @@ -2316,9 +2317,9 @@ export class EthImpl implements Eth { const timestampRange = blockResponse.timestamp; const timestampRangeParams = [`gte:${timestampRange.from}`, `lte:${timestampRange.to}`]; const contractResults = await this.mirrorNodeClient.getContractResults( + requestDetails.requestIdPrefix, { timestamp: timestampRangeParams }, undefined, - requestDetails.requestIdPrefix, ); const gasUsed = blockResponse.gas_used; const params = { timestamp: timestampRangeParams }; @@ -2422,7 +2423,7 @@ export class EthImpl implements Eth { return numberTo0x(block.count); } - private async getAccountLatestEthereumNonce(address: string, requestId?: string): Promise { + private async getAccountLatestEthereumNonce(address: string, requestId: string): Promise { const accountData = await this.mirrorNodeClient.getAccount(address, requestId); if (accountData) { // with HIP 729 ethereum_nonce should always be 0+ and null. Historical contracts may have a null value as the nonce was not tracked, return default EVM compliant 0x1 in this case @@ -2444,7 +2445,7 @@ export class EthImpl implements Eth { private async getAcccountNonceFromContractResult( address: string, blockNumOrHash: any, - requestIdPrefix: string | undefined, + requestIdPrefix: string, ): Promise { // get block timestamp for blockNum const block = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestIdPrefix); // consider caching error responses @@ -2480,7 +2481,7 @@ export class EthImpl implements Eth { ); } - const accountResult = await this.mirrorNodeClient.getAccount(transactionResult.from); + const accountResult = await this.mirrorNodeClient.getAccount(transactionResult.from, requestIdPrefix); if (accountResult.evm_address !== address.toLowerCase()) { this.logger.warn( @@ -2520,7 +2521,7 @@ export class EthImpl implements Eth { } if (!isParamBlockNum) { - getBlock = await this.mirrorNodeClient.getBlock(blockNumOrHash); + getBlock = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestIdPrefix); } const blockNum = isParamBlockNum ? blockNumOrHash : getBlock.number; diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index 1c09d1be85..28c93b551c 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -71,11 +71,7 @@ export class Precheck { * @param {number} networkGasPriceInWeiBars - The predefined gas price of the network in weibar. * @param {string} [requestId] - The request ID. */ - async sendRawTransactionCheck( - parsedTx: ethers.Transaction, - networkGasPriceInWeiBars: number, - requestId?: string, - ): Promise { + async sendRawTransactionCheck(parsedTx: ethers.Transaction, gasPrice: number, requestId: string): Promise { this.transactionType(parsedTx, requestId); this.gasLimit(parsedTx, requestId); const mirrorAccountInfo = await this.verifyAccount(parsedTx, requestId); @@ -92,7 +88,7 @@ export class Precheck { * @param {string} [requestId] - The request ID. * @returns {Promise} A Promise. */ - async verifyAccount(tx: Transaction, requestId?: string): Promise { + async verifyAccount(tx: Transaction, requestId: string): Promise { const requestIdPrefix = formatRequestIdMessage(requestId); // verify account const accountInfo = await this.mirrorNodeClient.getAccount(tx.from!, requestId); diff --git a/packages/relay/src/lib/relay.ts b/packages/relay/src/lib/relay.ts index e30b0232ee..ff856997b7 100644 --- a/packages/relay/src/lib/relay.ts +++ b/packages/relay/src/lib/relay.ts @@ -193,7 +193,7 @@ export class RelayImpl implements Relay { // Invoked when the registry collects its metrics' values. // Allows for updated account balance tracking try { - const account = await mirrorNodeClient.getAccount(clientMain.operatorAccountId!.toString()); + const account = await mirrorNodeClient.getAccount(clientMain.operatorAccountId!.toString(), ''); const accountBalance = account.balance?.balance; this.labels({ accountId: clientMain.operatorAccountId?.toString() }).set(accountBalance); } catch (e: any) { diff --git a/packages/relay/src/lib/services/cacheService/cacheService.ts b/packages/relay/src/lib/services/cacheService/cacheService.ts index 1d21fcacca..9d461e512b 100644 --- a/packages/relay/src/lib/services/cacheService/cacheService.ts +++ b/packages/relay/src/lib/services/cacheService/cacheService.ts @@ -202,7 +202,7 @@ export class CacheService { * @param {string} [requestIdPrefix] - The optional request ID prefix. * @returns {Promise} A Promise that resolves with the cached value or null if not found. */ - private async getFromSharedCache(key: string, callingMethod: string, requestIdPrefix?: string): Promise { + private async getFromSharedCache(key: string, callingMethod: string, requestIdPrefix: string): Promise { try { this.cacheMethodsCounter .labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.GET_ASYNC) @@ -228,7 +228,7 @@ export class CacheService { * @returns {Promise} A Promise that resolves with the cached value or null if not found. * @template T - The type of the cached value. */ - public async getAsync(key: string, callingMethod: string, requestIdPrefix?: string): Promise { + public async getAsync(key: string, callingMethod: string, requestIdPrefix: string): Promise { if (this.isSharedCacheEnabled) { return await this.getFromSharedCache(key, callingMethod, requestIdPrefix); } else { diff --git a/packages/relay/src/lib/services/debugService/IDebugService.ts b/packages/relay/src/lib/services/debugService/IDebugService.ts index a57566ab49..5ea9c484ee 100644 --- a/packages/relay/src/lib/services/debugService/IDebugService.ts +++ b/packages/relay/src/lib/services/debugService/IDebugService.ts @@ -26,7 +26,7 @@ export interface IDebugService { transactionIdOrHash: string, tracer: TracerType, tracerConfig: ITracerConfig, - requestIdPrefix?: string, + requestIdPrefix: string, ) => Promise; - resolveAddress: (address: string, types?: string[], requestIdPrefix?: string) => Promise; + resolveAddress: (address: string, requestIdPrefix: string, types?: string[]) => Promise; } diff --git a/packages/relay/src/lib/services/debugService/index.ts b/packages/relay/src/lib/services/debugService/index.ts index 6ee0b7ae51..669a18b0ba 100644 --- a/packages/relay/src/lib/services/debugService/index.ts +++ b/packages/relay/src/lib/services/debugService/index.ts @@ -99,7 +99,7 @@ export class DebugService implements IDebugService { transactionIdOrHash: string, tracer: TracerType, tracerConfig: ITracerConfig, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { this.logger.trace(`${requestIdPrefix} debug_traceTransaction(${transactionIdOrHash})`); try { @@ -122,7 +122,7 @@ export class DebugService implements IDebugService { * @param {string} requestIdPrefix - The request prefix id. * @returns {Promise<[] | any>} The formatted actions response in an array. */ - async formatActionsResult(result: any, requestIdPrefix?: string): Promise<[] | any> { + async formatActionsResult(result: any, requestIdPrefix: string): Promise<[] | any> { return await Promise.all( result.map(async (action, index) => { const { resolvedFrom, resolvedTo } = await this.resolveMultipleAddresses( @@ -206,8 +206,8 @@ export class DebugService implements IDebugService { */ async resolveAddress( address: string, + requestIdPrefix: string, types = [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT], - requestIdPrefix?: string, ): Promise { // if the address is null or undefined we return it as is if (!address) return address; @@ -233,15 +233,15 @@ export class DebugService implements IDebugService { async resolveMultipleAddresses( from: string, to: string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise<{ resolvedFrom: string; resolvedTo: string }> { const [resolvedFrom, resolvedTo] = await Promise.all([ - this.resolveAddress( - from, - [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT], - requestIdPrefix, - ), - this.resolveAddress(to, [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT], requestIdPrefix), + this.resolveAddress(from, requestIdPrefix, [ + constants.TYPE_CONTRACT, + constants.TYPE_TOKEN, + constants.TYPE_ACCOUNT, + ]), + this.resolveAddress(to, requestIdPrefix, [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT]), ]); return { resolvedFrom, resolvedTo }; @@ -261,7 +261,7 @@ export class DebugService implements IDebugService { async callOpcodeLogger( transactionIdOrHash: string, tracerConfig: IOpcodeLoggerConfig, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { try { const options = { @@ -289,15 +289,11 @@ export class DebugService implements IDebugService { * @param {string} requestIdPrefix - The request prefix id. * @returns {Promise} The formatted response. */ - async callTracer( - transactionHash: string, - tracerConfig: ICallTracerConfig, - requestIdPrefix?: string, - ): Promise { + async callTracer(transactionHash: string, tracerConfig: ICallTracerConfig, requestIdPrefix: string): Promise { try { const [actionsResponse, transactionsResponse] = await Promise.all([ this.mirrorNodeClient.getContractsResultsActions(transactionHash, requestIdPrefix), - this.mirrorNodeClient.getContractResultWithRetry(transactionHash), + this.mirrorNodeClient.getContractResultWithRetry(transactionHash, requestIdPrefix), ]); if (!actionsResponse || !transactionsResponse) { throw predefined.RESOURCE_NOT_FOUND(`Failed to retrieve contract results for transaction ${transactionHash}`); diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts index 611bba9a3c..aa1c17c97f 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts @@ -253,7 +253,7 @@ export class CommonService implements ICommonService { throw predefined.INTERNAL_ERROR(error.message.toString()); } - public async validateBlockHashAndAddTimestampToParams(params: any, blockHash: string, requestIdPrefix?: string) { + public async validateBlockHashAndAddTimestampToParams(params: any, blockHash: string, requestIdPrefix: string) { try { const block = await this.mirrorNodeClient.getBlock(blockHash, requestIdPrefix); if (block) { @@ -285,7 +285,7 @@ export class CommonService implements ICommonService { public async getLogsByAddress(address: string | string[], params: any, requestIdPrefix) { const addresses = Array.isArray(address) ? address : [address]; const logPromises = addresses.map((addr) => - this.mirrorNodeClient.getContractResultsLogsByAddress(addr, params, undefined, requestIdPrefix), + this.mirrorNodeClient.getContractResultsLogsByAddress(addr, requestIdPrefix, params, undefined), ); const logResults = await Promise.all(logPromises); diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts index 7f2fee9b53..f4bfd57f1a 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts @@ -163,7 +163,7 @@ export class FilterService implements IFilterService { } } - public async uninstallFilter(filterId: string, requestIdPrefix?: string | undefined): Promise { + public async uninstallFilter(filterId: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} uninstallFilter(${filterId})`); FilterService.requireFiltersEnabled(); diff --git a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts index ef0da42e57..6406c970da 100644 --- a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts +++ b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts @@ -24,8 +24,8 @@ export interface IHbarLimitService { mode: string, methodName: string, ethAddress: string, + requestId: string, ipAddress?: string, - requestId?: string, estimatedTxFee?: number, ): Promise; addExpense(cost: number, ethAddress: string, ipAddress?: string): Promise; diff --git a/packages/relay/src/lib/services/hbarLimitService/index.ts b/packages/relay/src/lib/services/hbarLimitService/index.ts index 8a0ec03b83..e2f9bf644d 100644 --- a/packages/relay/src/lib/services/hbarLimitService/index.ts +++ b/packages/relay/src/lib/services/hbarLimitService/index.ts @@ -169,8 +169,8 @@ export class HbarLimitService implements IHbarLimitService { mode: string, methodName: string, ethAddress: string, + requestId: string, ipAddress?: string, - requestId?: string, estimatedTxFee: number = 0, ): Promise { const requestIdPrefix = formatRequestIdMessage(requestId); @@ -183,7 +183,7 @@ export class HbarLimitService implements IHbarLimitService { } const user = `(ethAddress=${ethAddress}, ipAddress=${ipAddress})`; this.logger.trace(`${requestIdPrefix} Checking if ${user} should be limited...`); - let spendingPlan = await this.getSpendingPlan(ethAddress, ipAddress); + let spendingPlan = await this.getSpendingPlan(ethAddress, requestIdPrefix, ipAddress); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress); @@ -208,18 +208,17 @@ export class HbarLimitService implements IHbarLimitService { * @param {string} [requestId] - An optional unique request ID for tracking the request. * @returns {Promise} - A promise that resolves when the expense has been added. */ - async addExpense(cost: number, ethAddress: string, ipAddress?: string, requestId?: string): Promise { + async addExpense(cost: number, ethAddress: string, requestIdPrefix: string, ipAddress?: string): Promise { if (!ethAddress && !ipAddress) { throw new Error('Cannot add expense without an eth address or ip address'); } - let spendingPlan = await this.getSpendingPlan(ethAddress, ipAddress); + let spendingPlan = await this.getSpendingPlan(ethAddress, requestIdPrefix, ipAddress); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress); } - const requestIdPrefix = formatRequestIdMessage(requestId); this.logger.trace( `${requestIdPrefix} Adding expense of ${cost} to spending plan with ID ${spendingPlan.id}, new spentToday=${ spendingPlan.spentToday + cost @@ -231,7 +230,7 @@ export class HbarLimitService implements IHbarLimitService { this.dailyUniqueSpendingPlansCounter[spendingPlan.subscriptionType].inc(1); } - await this.hbarSpendingPlanRepository.addAmountToSpentToday(spendingPlan.id, cost); + await this.hbarSpendingPlanRepository.addAmountToSpentToday(spendingPlan.id, cost, requestIdPrefix); this.remainingBudget -= cost; this.hbarLimitRemainingGauge.set(this.remainingBudget); @@ -333,10 +332,14 @@ export class HbarLimitService implements IHbarLimitService { * @returns {Promise} - A promise that resolves with the spending plan or null if none exists. * @private */ - private async getSpendingPlan(ethAddress: string, ipAddress?: string): Promise { + private async getSpendingPlan( + ethAddress: string, + requestIdPrefix: string, + ipAddress?: string, + ): Promise { if (ethAddress) { try { - return await this.getSpendingPlanByEthAddress(ethAddress); + return await this.getSpendingPlanByEthAddress(ethAddress, requestIdPrefix); } catch (error) { this.logger.warn(error, `Failed to get spending plan for eth address '${ethAddress}'`); } @@ -357,9 +360,15 @@ export class HbarLimitService implements IHbarLimitService { * @returns {Promise} - A promise that resolves with the spending plan. * @private */ - private async getSpendingPlanByEthAddress(ethAddress: string): Promise { - const ethAddressHbarSpendingPlan = await this.ethAddressHbarSpendingPlanRepository.findByAddress(ethAddress); - return this.hbarSpendingPlanRepository.findByIdWithDetails(ethAddressHbarSpendingPlan.planId); + private async getSpendingPlanByEthAddress( + ethAddress: string, + requestIdPrefix: string, + ): Promise { + const ethAddressHbarSpendingPlan = await this.ethAddressHbarSpendingPlanRepository.findByAddress( + ethAddress, + requestIdPrefix, + ); + return this.hbarSpendingPlanRepository.findByIdWithDetails(ethAddressHbarSpendingPlan.planId, requestIdPrefix); } /** diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index 4eafb4c352..459637cf5d 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -521,7 +521,7 @@ app.useRpc('eth_getLogs', async (params: any) => { */ app.useRpc('eth_getStorageAt', async (params: any) => { return logAndHandleResponse('eth_getStorageAt', params, (requestId) => - relay.eth().getStorageAt(requestId, params?.[0], params?.[1], params?.[2]), + relay.eth().getStorageAt(params?.[0], params?.[1], requestId, params?.[2]), ); }); From 21a6d8d486c321bbeaad0b34de7753dcb4499268 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Mon, 9 Sep 2024 16:32:47 +0300 Subject: [PATCH 09/48] Fixes tests Signed-off-by: Konstantina Blazhukova --- packages/relay/src/lib/eth.ts | 2 +- .../tests/acceptance/rpc_batch1.spec.ts | 9 +++++++-- .../tests/acceptance/rpc_batch2.spec.ts | 6 +++--- packages/server/tests/clients/relayClient.ts | 20 +++++++++---------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 04397a62cd..aa3483c823 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -1715,7 +1715,7 @@ export class EthImpl implements Eth { let result: string | JsonRpcError = ''; try { if (shouldForceToConsensus || shouldDefaultToConsensus) { - result = await this.callConsensusNode(call, gas, requestIdPrefix); + result = await this.callConsensusNode(call, gas, requestDetails); } else { //temporary workaround until precompiles are implemented in Mirror node evm module // Execute the call and get the response diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 6680f884fd..729d364315 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -41,6 +41,7 @@ import RelayCalls from '../../tests/helpers/constants'; // Other imports import { numberTo0x, prepend0x } from '../../../../packages/relay/src/formatters'; import constants from '../../../relay/src/lib/constants'; +import { IRequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/IRequestDetails'; const Address = RelayCalls; describe('@api-batch-1 RPC Server Acceptance Tests', function () { @@ -55,8 +56,10 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { let parentContractAddress: string; let mirrorContractDetails; let requestId: string; + let requestIdPrefix: string; let account2Address: string; let expectedGasPrice: string; + let requestDetails: IRequestDetails; const CHAIN_ID = process.env.CHAIN_ID || '0x12a'; const INCORRECT_CHAIN_ID = 999; @@ -84,7 +87,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { this.beforeAll(async () => { requestId = Utils.generateRequestId(); - const requestIdPrefix = Utils.formatRequestIdMessage(requestId); + requestIdPrefix = Utils.formatRequestIdMessage(requestId); + requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; + expectedGasPrice = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GAS_PRICE, [], requestId); const initialAccount: AliasAccount = global.accounts[0]; @@ -175,7 +180,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestId, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); diff --git a/packages/server/tests/acceptance/rpc_batch2.spec.ts b/packages/server/tests/acceptance/rpc_batch2.spec.ts index cb66a2e1bb..248a064601 100644 --- a/packages/server/tests/acceptance/rpc_batch2.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch2.spec.ts @@ -91,7 +91,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { this.beforeAll(async () => { requestId = Utils.generateRequestId(); const requestIdPrefix = Utils.formatRequestIdMessage(requestId); - expectedGasPrice = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GAS_PRICE, [], requestId); + expectedGasPrice = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GAS_PRICE, [], requestIdPrefix); const initialAccount: AliasAccount = global.accounts[0]; @@ -868,7 +868,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { requestId, ); - const gasPrice = await relay.gasPrice(); + const gasPrice = await relay.gasPrice(requestId); const transaction = { value: 0, gasLimit: 50000, @@ -881,7 +881,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { maxFeePerGas: gasPrice, type: 2, }; - + console.log('sign transaction'); const signedTx = await accounts[1].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const txReceipt = await relay.call( diff --git a/packages/server/tests/clients/relayClient.ts b/packages/server/tests/clients/relayClient.ts index 1427a6a64c..1dd39b3313 100644 --- a/packages/server/tests/clients/relayClient.ts +++ b/packages/server/tests/clients/relayClient.ts @@ -40,9 +40,7 @@ export default class RelayClient { * @param params * @param requestId */ - async call(methodName: string, params: any[], requestId?: string) { - const requestIdPrefix = Utils.formatRequestIdMessage(requestId); - + async call(methodName: string, params: any[], requestIdPrefix: string) { const result = await this.provider.send(methodName, params); this.logger.trace( `${requestIdPrefix} [POST] to relay '${methodName}' with params [${JSON.stringify( @@ -81,11 +79,11 @@ export default class RelayClient { methodName: string, params: any[], expectedRpcError = predefined.INTERNAL_ERROR(), - requestId?: string, + requestId: string, ) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); try { - const res = await this.call(methodName, params, requestId); + const res = await this.call(methodName, params, requestIdPrefix); this.logger.trace( `${requestIdPrefix} [POST] to relay '${methodName}' with params [${params}] returned ${JSON.stringify(res)}`, ); @@ -111,9 +109,10 @@ export default class RelayClient { * @param params * @param requestId */ - async callUnsupported(methodName: string, params: any[], requestId?: string) { + async callUnsupported(methodName: string, params: any[], requestId: string) { try { - await this.call(methodName, params, requestId); + const requestIdPrefix = Utils.formatRequestIdMessage(requestId); + await this.call(methodName, params, requestIdPrefix); Assertions.expectedError(); } catch (e: any) { Assertions.unsupportedResponse(e?.response?.bodyJson); @@ -151,7 +150,7 @@ export default class RelayClient { * @param signedTx * @param requestId */ - async sendRawTransaction(signedTx, requestId?: string): Promise { + async sendRawTransaction(signedTx, requestId: string): Promise { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); this.logger.debug(`${requestIdPrefix} [POST] to relay for eth_sendRawTransaction`); return this.provider.send('eth_sendRawTransaction', [signedTx]); @@ -162,7 +161,8 @@ export default class RelayClient { * * Returns the result of eth_gasPrice as a Number. */ - async gasPrice(requestId?: string): Promise { - return Number(await this.call('eth_gasPrice', [], requestId)); + async gasPrice(requestId: string): Promise { + const requestIdPrefix = Utils.formatRequestIdMessage(requestId); + return Number(await this.call('eth_gasPrice', [], requestIdPrefix)); } } From a2b2a2deed013ce8d275b08933090c72416a7ad7 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Mon, 9 Sep 2024 19:34:14 +0300 Subject: [PATCH 10/48] Fixes unit tests Signed-off-by: Konstantina Blazhukova --- .../relay/src/lib/clients/mirrorNodeClient.ts | 3 - packages/relay/src/lib/eth.ts | 1 - packages/relay/tests/lib/eth/eth_call.spec.ts | 16 +++-- ...eth_getBlockTransactionCountByHash.spec.ts | 7 +- ...h_getBlockTransactionCountByNumber.spec.ts | 19 +++--- .../relay/tests/lib/eth/eth_getCode.spec.ts | 20 +++--- .../relay/tests/lib/eth/eth_getLogs.spec.ts | 54 +++++++++------ ..._getTransactionByBlockHashAndIndex.spec.ts | 12 +++- ...etTransactionByBlockNumberAndIndex.spec.ts | 37 +++++++++-- .../lib/eth/eth_getTransactionByHash.spec.ts | 31 ++++----- .../lib/eth/eth_getTransactionCount.spec.ts | 35 +++++----- .../hbarSpendingPlanRepository.spec.ts | 66 +++++++++++-------- .../cacheService/cacheService.spec.ts | 28 ++++---- .../lib/services/debugService/debug.spec.ts | 5 +- .../hbarLimitService/hbarLimitService.spec.ts | 23 +++---- .../tests/acceptance/rpc_batch2.spec.ts | 2 +- 16 files changed, 215 insertions(+), 144 deletions(-) diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index e2ae0197d8..a12858cd6c 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -326,7 +326,6 @@ export class MirrorNodeClient { ?.split(MirrorNodeClient.REQUEST_PREFIX_SEPARATOR)[1] .replace(MirrorNodeClient.REQUEST_PREFIX_TRAILING_BRACKET, MirrorNodeClient.EMPTY_STRING) || MirrorNodeClient.EMPTY_STRING; - console.log('Request id', requestId); const controller = new AbortController(); try { const axiosRequestConfig: AxiosRequestConfig = { @@ -374,8 +373,6 @@ export class MirrorNodeClient { } async get(path: string, pathLabel: string, requestIdPrefix: string, retries?: number): Promise { - console.log('Mirron node getting data'); - console.log(requestIdPrefix); return this.request(path, pathLabel, 'GET', requestIdPrefix, null, retries); } diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index aa3483c823..f270f63f0b 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -625,7 +625,6 @@ export class EthImpl implements Eth { ): Promise { await this.contractCallFormat(transaction, requestDetails); const callData = { ...transaction, estimate: true }; - console.log('Before post contract call'); return this.mirrorNodeClient.postContractCall(callData, requestDetails.requestIdPrefix); } diff --git a/packages/relay/tests/lib/eth/eth_call.spec.ts b/packages/relay/tests/lib/eth/eth_call.spec.ts index f68dff5ab8..8bdefb54bc 100644 --- a/packages/relay/tests/lib/eth/eth_call.spec.ts +++ b/packages/relay/tests/lib/eth/eth_call.spec.ts @@ -572,10 +572,16 @@ describe('@ethCall Eth Call spec', async function () { ...defaultCallData, gas: 25_000_000, }; - await mockContractCall({ ...callData, gas: constants.MAX_GAS_PER_SEC, block: 'latest' }, false, 200, { - result: '0x00', - }); - const res = await ethImpl.call(callData, 'latest'); + await mockContractCall( + { ...callData, gas: constants.MAX_GAS_PER_SEC, block: 'latest' }, + false, + 200, + { + result: '0x00', + }, + requestDetails, + ); + const res = await ethImpl.call(callData, 'latest', requestDetails); expect(res).to.equal('0x00'); }); @@ -965,6 +971,7 @@ describe('@ethCall Eth Call spec', async function () { data: REDIRECTED_SELECTOR, }, 'latest', + requestDetails, ); assert(callConsensusNodeSpy.calledOnce); @@ -978,6 +985,7 @@ describe('@ethCall Eth Call spec', async function () { data: NON_REDIRECTED_SELECTOR, }, 'latest', + requestDetails, ); assert(callConsensusNodeSpy.notCalled); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts index cf29a97be1..b35a42129b 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts @@ -43,6 +43,7 @@ let getSdkClientStub; describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const requestIdPrefix = `[Request ID: testId]`; this.beforeEach(() => { // reset cache and restMock @@ -63,7 +64,7 @@ describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function ( // mirror node request mocks restMock.onGet(`blocks/${BLOCK_HASH}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH); + const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -71,7 +72,7 @@ describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function ( restMock.onGet(`blocks/${BLOCK_HASH}`).replyOnce(200, DEFAULT_BLOCK); for (let i = 0; i < 3; i++) { - const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH); + const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); } }); @@ -80,7 +81,7 @@ describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function ( // mirror node request mocks restMock.onGet(`blocks/${BLOCK_HASH}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); - const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH); + const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestIdPrefix); expect(result).to.equal(null); }); }); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts index 188acf8dcb..ccd1017de2 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts @@ -45,6 +45,7 @@ let getSdkClientStub; describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const requestIdPrefix = `[Request ID: testId]`; this.beforeEach(() => { // reset cache and restMock @@ -65,7 +66,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function // mirror node request mocks restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString()); + const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -73,7 +74,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(`blocks/${BLOCK_NUMBER}`).replyOnce(200, DEFAULT_BLOCK); for (let i = 0; i < 3; i++) { - const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString()); + const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); } }); @@ -82,7 +83,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function cacheService.clear(); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); - const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString()); + const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestIdPrefix); expect(result).to.equal(null); }); @@ -91,7 +92,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('latest'); + const result = await ethImpl.getBlockTransactionCountByNumber('latest', requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -100,7 +101,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('finalized'); + const result = await ethImpl.getBlockTransactionCountByNumber('finalized', requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -109,7 +110,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('safe'); + const result = await ethImpl.getBlockTransactionCountByNumber('safe', requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -118,7 +119,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('pending'); + const result = await ethImpl.getBlockTransactionCountByNumber('pending', requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -126,7 +127,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function // mirror node request mocks restMock.onGet(`blocks/0`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('earliest'); + const result = await ethImpl.getBlockTransactionCountByNumber('earliest', requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -134,7 +135,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function // mirror node request mocks restMock.onGet(`blocks/3735929054`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('0xdeadc0de'); + const result = await ethImpl.getBlockTransactionCountByNumber('0xdeadc0de', requestIdPrefix); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); }); diff --git a/packages/relay/tests/lib/eth/eth_getCode.spec.ts b/packages/relay/tests/lib/eth/eth_getCode.spec.ts index e475dcea8f..3fdba8f7bb 100644 --- a/packages/relay/tests/lib/eth/eth_getCode.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getCode.spec.ts @@ -51,6 +51,8 @@ describe('@ethGetCode using MirrorNode', async function () { let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); let validBlockParam = [null, 'earliest', 'latest', 'pending', 'finalized', 'safe', '0x0', '0x369ABF']; let invalidBlockParam = ['hedera', 'ethereum', '0xhbar', '0x369ABF369ABF369ABF369ABF']; + const requestIdPrefix = `[Request ID: testId]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; this.beforeEach(() => { // reset cache and restMock @@ -86,20 +88,20 @@ describe('@ethGetCode using MirrorNode', async function () { }), ); - const resNoCache = await ethImpl.getCode(CONTRACT_ADDRESS_1, null); - const resCached = await ethImpl.getCode(CONTRACT_ADDRESS_1, null); + const resNoCache = await ethImpl.getCode(CONTRACT_ADDRESS_1, null, requestDetails); + const resCached = await ethImpl.getCode(CONTRACT_ADDRESS_1, null, requestDetails); expect(resNoCache).to.equal(EthImpl.emptyHex); expect(resCached).to.equal(EthImpl.emptyHex); }); it('should return the runtime_bytecode from the mirror node', async () => { - const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, null); + const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, null, requestDetails); expect(res).to.equal(MIRROR_NODE_DEPLOYED_BYTECODE); }); it('should return the bytecode from SDK if Mirror Node returns 404', async () => { restMock.onGet(`contracts/${CONTRACT_ADDRESS_1}`).reply(404, DEFAULT_CONTRACT); - const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, null); + const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, null, requestDetails); expect(res).to.equal(DEPLOYED_BYTECODE); }); @@ -108,7 +110,7 @@ describe('@ethGetCode using MirrorNode', async function () { ...DEFAULT_CONTRACT, runtime_bytecode: EthImpl.emptyHex, }); - const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, null); + const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, null, requestDetails); expect(res).to.equal(DEPLOYED_BYTECODE); }); @@ -119,7 +121,7 @@ describe('@ethGetCode using MirrorNode', async function () { const redirectBytecode = `6080604052348015600f57600080fd5b506000610167905077618dc65e${HTS_TOKEN_ADDRESS.slice( 2, )}600052366000602037600080366018016008845af43d806000803e8160008114605857816000f35b816000fdfea2646970667358221220d8378feed472ba49a0005514ef7087017f707b45fb9bf56bb81bb93ff19a238b64736f6c634300080b0033`; - const res = await ethImpl.getCode(HTS_TOKEN_ADDRESS, null); + const res = await ethImpl.getCode(HTS_TOKEN_ADDRESS, null, requestDetails); expect(res).to.equal(redirectBytecode); }); @@ -127,13 +129,13 @@ describe('@ethGetCode using MirrorNode', async function () { restMock.onGet(`contracts/${EthImpl.iHTSAddress}`).reply(200, DEFAULT_CONTRACT); restMock.onGet(`accounts/${EthImpl.iHTSAddress}${NO_TRANSACTIONS}`).reply(404, null); - const res = await ethImpl.getCode(EthImpl.iHTSAddress, null); + const res = await ethImpl.getCode(EthImpl.iHTSAddress, null, requestDetails); expect(res).to.equal(EthImpl.invalidEVMInstruction); }); validBlockParam.forEach((blockParam) => { it(`should pass the validate param check with blockParam=${blockParam} and return the bytecode`, async () => { - const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, blockParam); + const res = await ethImpl.getCode(CONTRACT_ADDRESS_1, blockParam, requestDetails); expect(res).to.equal(MIRROR_NODE_DEPLOYED_BYTECODE); }); }); @@ -141,7 +143,7 @@ describe('@ethGetCode using MirrorNode', async function () { invalidBlockParam.forEach((blockParam) => { it(`should throw INVALID_PARAMETER JsonRpcError with invalid blockParam=${blockParam}`, async () => { try { - await ethImpl.getCode(EthImpl.iHTSAddress, blockParam); + await ethImpl.getCode(EthImpl.iHTSAddress, blockParam, requestDetails); expect(true).to.eq(false); } catch (error: any) { const expectedError = predefined.UNKNOWN_BLOCK( diff --git a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts index 27746b29e6..52aa77008b 100644 --- a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts @@ -81,6 +81,8 @@ describe('@ethGetLogs using MirrorNode', async function () { logs: [DEFAULT_LOGS.logs[0], DEFAULT_LOGS.logs[1]], }; + const requestIdPrefix = `[Request ID: testId]`; + this.beforeEach(() => { // reset cache and restMock cacheService.clear(); @@ -129,7 +131,7 @@ describe('@ethGetLogs using MirrorNode', async function () { let errorReceived = false; try { - await ethImpl.getLogs(null, null, null, null, null); + await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); } catch (error) { errorReceived = true; expect(error.statusCode).to.equal(400); @@ -154,7 +156,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, { ...DEFAULT_CONTRACT, contract_id: `0.0.105${index}` }); }); - const result = await ethImpl.getLogs(null, null, null, null, null); + const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); expect(result).to.exist; expect(result.length).to.eq(4); @@ -179,7 +181,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, { ...DEFAULT_CONTRACT, contract_id: `0.0.105${index}` }); }); - const result = await ethImpl.getLogs(null, null, null, null, null); + const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); expect(result).to.exist; expect(result.length).to.eq(4); @@ -227,7 +229,7 @@ describe('@ethGetLogs using MirrorNode', async function () { }); //setting mirror node limit to 2 for this test only process.env['MIRROR_NODE_LIMIT_PARAM'] = '2'; - const result = await ethImpl.getLogs(null, null, null, null, null); + const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); //resetting mirror node limit to 100 process.env['MIRROR_NODE_LIMIT_PARAM'] = '100'; expect(result).to.exist; @@ -255,7 +257,7 @@ describe('@ethGetLogs using MirrorNode', async function () { .onGet(`contracts/${filteredLogs.logs[0].address}`) .reply(200, { ...DEFAULT_CONTRACT, evm_address: defaultEvmAddress }); - const result = await ethImpl.getLogs(null, null, null, null, null); + const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); expect(result).to.exist; expect(result.length).to.eq(1); @@ -272,7 +274,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, CONTRACT_ADDRESS_1, null); + const result = await ethImpl.getLogs(null, null, null, CONTRACT_ADDRESS_1, null, requestIdPrefix); expect(result).to.exist; @@ -310,7 +312,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet('blocks/1').reply(200, fromBlock); restMock.onGet('blocks/1003').reply(200, toBlock); - const result = await ethImpl.getLogs(null, '0x1', '0x3eb', address, null); + const result = await ethImpl.getLogs(null, '0x1', '0x3eb', address, null, requestIdPrefix); expect(result).to.exist; @@ -340,7 +342,14 @@ describe('@ethGetLogs using MirrorNode', async function () { } restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - const result = await ethImpl.getLogs(null, null, null, [CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2], null); + const result = await ethImpl.getLogs( + null, + null, + null, + [CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2], + null, + requestIdPrefix, + ); expect(result).to.exist; @@ -362,7 +371,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(BLOCK_HASH, null, null, null, null); + const result = await ethImpl.getLogs(BLOCK_HASH, null, null, null, null, requestIdPrefix); expect(result).to.exist; expectLogData1(result[0]); @@ -394,7 +403,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null); + const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null, requestIdPrefix); expect(result).to.exist; expectLogData1(result[0]); @@ -407,7 +416,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet('blocks/5').reply(200, DEFAULT_BLOCK); restMock.onGet('blocks/16').reply(404, NOT_FOUND_RES); - const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null); + const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null, requestIdPrefix); expect(result).to.exist; expect(result).to.be.empty; @@ -426,7 +435,7 @@ describe('@ethGetLogs using MirrorNode', async function () { .reply(200, filteredLogs); restMock.onGet(`contracts/${filteredLogs.logs[0].address}`).reply(200, DEFAULT_CONTRACT); - const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null); + const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null, requestIdPrefix); expect(result).to.exist; expectLogData1(result[0]); @@ -445,7 +454,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [latestBlock] }); restMock.onGet('blocks/16').reply(200, fromBlock); restMock.onGet('blocks/5').reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null); + const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null, requestIdPrefix); expect(result).to.exist; expect(result).to.be.empty; @@ -472,7 +481,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, 'latest', null, null, null); + const result = await ethImpl.getLogs(null, 'latest', null, null, null, requestIdPrefix); expect(result).to.exist; expectLogData1(result[0]); @@ -498,7 +507,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet('blocks/1').reply(200, fromBlock); restMock.onGet('blocks/1003').reply(200, toBlock); - await ethGetLogsFailing(ethImpl, [null, '0x1', '0x3eb', address, null], (error) => { + await ethGetLogsFailing(ethImpl, [null, '0x1', '0x3eb', address, null, requestIdPrefix], (error) => { expect(error.message).to.equal('Exceeded maximum block range: 1000'); }); }); @@ -523,7 +532,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_LOG_TOPICS); + const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_LOG_TOPICS, requestIdPrefix); expect(result).to.exist; expectLogData1(result[0]); @@ -547,7 +556,7 @@ describe('@ethGetLogs using MirrorNode', async function () { for (const log of filteredLogs.logs) { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_NULL_LOG_TOPICS); + const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_NULL_LOG_TOPICS, requestIdPrefix); expect(result).to.exist; expect(result[0].topics.length).to.eq(DEFAULT_LOGS_4[0].topics.length); @@ -577,7 +586,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, '0x5', '0x10', null, DEFAULT_LOG_TOPICS); + const result = await ethImpl.getLogs(null, '0x5', '0x10', null, DEFAULT_LOG_TOPICS, requestIdPrefix); expectLogData1(result[0]); expectLogData2(result[1]); @@ -587,7 +596,14 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [latestBlock] }); restMock.onGet('blocks/0').reply(200, DEFAULT_BLOCK); restMock.onGet('blocks/latest').reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getLogs(null, '0x0', 'latest', ethers.ZeroAddress, DEFAULT_LOG_TOPICS); + const result = await ethImpl.getLogs( + null, + '0x0', + 'latest', + ethers.ZeroAddress, + DEFAULT_LOG_TOPICS, + requestIdPrefix, + ); expect(result.length).to.eq(0); expect(result).to.deep.equal([]); }); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts index 2b071c1194..c941d30b65 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts @@ -52,6 +52,7 @@ use(chaiAsPromised); let sdkClientStub; let getSdkClientStub; +const requestIdPrefix = `[Request ID: testId]`; function verifyAggregatedInfo(result: Transaction | null) { // verify aggregated info @@ -100,7 +101,11 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio restMock .onGet(`contracts/${CONTRACT_ADDRESS_1}/results/${CONTRACT_TIMESTAMP_1}`) .reply(200, defaultDetailedContractResults); - const result = await ethImpl.getTransactionByBlockHashAndIndex(DEFAULT_BLOCK.hash, numberTo0x(DEFAULT_BLOCK.count)); + const result = await ethImpl.getTransactionByBlockHashAndIndex( + DEFAULT_BLOCK.hash, + numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, + ); expect(result).to.exist; expect(result).to.not.be.null; @@ -137,6 +142,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); expect(result).to.equal(null); }); @@ -147,6 +153,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); expect(result).to.equal(null); }); @@ -164,6 +171,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); expect(result).to.be.an.instanceOf(Transaction); }); @@ -182,6 +190,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); expect(result).to.be.an.instanceOf(Transaction2930); }); @@ -202,6 +211,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); expect(result).to.be.an.instanceOf(Transaction1559); }); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts index 6578717e47..1e3b32084f 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts @@ -65,7 +65,7 @@ function verifyAggregatedInfo(result: Transaction | null) { describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - + const requestIdPrefix = `[Request ID: testId]`; this.beforeEach(() => { // reset cache and restMock cacheService.clear(); @@ -103,6 +103,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(DEFAULT_BLOCK.number), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); verifyAggregatedInfo(result); @@ -123,6 +124,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(randomBlock.number), numberTo0x(randomBlock.count), + requestIdPrefix, ); expect(result).to.exist; expect(result).to.not.be.null; @@ -141,6 +143,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(DEFAULT_BLOCK.number), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); expect(result).to.equal(null); }); @@ -176,6 +179,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(DEFAULT_BLOCK.number), numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); expect(result).to.equal(null); }); @@ -187,7 +191,11 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct .onGet(contractResultsByNumberByIndexURL(DEFAULT_BLOCK.number, DEFAULT_BLOCK.count)) .reply(200, defaultContractResults); - const result = await ethImpl.getTransactionByBlockNumberAndIndex('latest', numberTo0x(DEFAULT_BLOCK.count)); + const result = await ethImpl.getTransactionByBlockNumberAndIndex( + 'latest', + numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, + ); verifyAggregatedInfo(result); }); @@ -198,7 +206,11 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct .onGet(contractResultsByNumberByIndexURL(DEFAULT_BLOCK.number, DEFAULT_BLOCK.count)) .reply(200, defaultContractResults); - const result = await ethImpl.getTransactionByBlockNumberAndIndex('finalized', numberTo0x(DEFAULT_BLOCK.count)); + const result = await ethImpl.getTransactionByBlockNumberAndIndex( + 'finalized', + numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, + ); verifyAggregatedInfo(result); }); @@ -209,7 +221,11 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct .onGet(contractResultsByNumberByIndexURL(DEFAULT_BLOCK.number, DEFAULT_BLOCK.count)) .reply(200, defaultContractResults); - const result = await ethImpl.getTransactionByBlockNumberAndIndex('safe', numberTo0x(DEFAULT_BLOCK.count)); + const result = await ethImpl.getTransactionByBlockNumberAndIndex( + 'safe', + numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, + ); verifyAggregatedInfo(result); }); @@ -220,7 +236,11 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct .onGet(contractResultsByNumberByIndexURL(DEFAULT_BLOCK.number, DEFAULT_BLOCK.count)) .reply(200, defaultContractResults); - const result = await ethImpl.getTransactionByBlockNumberAndIndex('pending', numberTo0x(DEFAULT_BLOCK.count)); + const result = await ethImpl.getTransactionByBlockNumberAndIndex( + 'pending', + numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, + ); verifyAggregatedInfo(result); }); @@ -228,7 +248,11 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct // mirror node request mocks restMock.onGet(contractResultsByNumberByIndexURL(0, DEFAULT_BLOCK.count)).reply(200, defaultContractResults); - const result = await ethImpl.getTransactionByBlockNumberAndIndex('earliest', numberTo0x(DEFAULT_BLOCK.count)); + const result = await ethImpl.getTransactionByBlockNumberAndIndex( + 'earliest', + numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, + ); verifyAggregatedInfo(result); }); @@ -240,6 +264,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( '0xdeadc0de' + '', numberTo0x(DEFAULT_BLOCK.count), + requestIdPrefix, ); verifyAggregatedInfo(result); }); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts index 4b4106a225..54975e48f8 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts @@ -78,6 +78,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi v: 1, nonce: 9, }; + const requestIdPrefix = `[Request ID: testId]`; this.beforeEach(function () { restMock.reset(); @@ -96,7 +97,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi type: 0, }); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.be.an.instanceOf(Transaction); }); @@ -108,7 +109,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi access_list: [], }); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.be.an.instanceOf(Transaction2930); }); @@ -122,7 +123,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi max_priority_fee_per_gas: '0x47', }); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.be.an.instanceOf(Transaction1559); }); @@ -133,21 +134,21 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi .onGet(`contracts/results/logs?transaction.hash=${uniqueTxHash}&limit=100&order=asc`) .reply(200, EMPTY_LOGS_RESPONSE); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.equal(null); }); it('account should be cached', async function () { restMock.onGet(`contracts/results/${DEFAULT_TX_HASH}`).reply(200, defaultDetailedContractResultByHash); - const resBeforeCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH); + const resBeforeCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); restMock.onGet(`accounts/${defaultFromLongZeroAddress}${NO_TRANSACTIONS}`).reply(404); - const resAfterCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH); + const resAfterCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); expect(resBeforeCache).to.deep.equal(resAfterCache); }); it('returns correct transaction for existing hash', async function () { restMock.onGet(`contracts/results/${DEFAULT_TX_HASH}`).reply(200, defaultDetailedContractResultByHash); - const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH); + const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); RelayAssertions.assertTransaction(result, { ...DEFAULT_TRANSACTION, maxFeePerGas: '0x55', @@ -165,7 +166,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x97cad7b827375d12d73af57b6a3f84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithZeroXZeroValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); RelayAssertions.assertTransaction(result, { ...DEFAULT_TRANSACTION, maxFeePerGas: '0x55', @@ -183,7 +184,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.not.be.null; expect(result).to.exist; @@ -198,7 +199,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x0aaad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.not.be.null; expect(result).to.exist; @@ -214,7 +215,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0xb4cad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.not.be.null; expect(result).to.exist; @@ -229,7 +230,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640534'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.not.be.null; expect(result).to.exist; @@ -244,7 +245,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640511'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.not.be.null; expect(result).to.exist; @@ -261,7 +262,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52d1a53ec640511'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); expect(result).to.not.be.null; expect(result).to.exist; @@ -276,7 +277,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi .onGet(`contracts/results/${DEFAULT_TX_HASH}`) .reply(200, DEFAULT_DETAILED_CONTRACT_RESULT_BY_HASH_REVERTED); - const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH); + const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); RelayAssertions.assertTransaction(result, { ...DEFAULT_TRANSACTION, maxFeePerGas: '0x55', diff --git a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts index 7687a92249..40bbe046c7 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts @@ -43,6 +43,7 @@ let currentMaxBlockRange: number; describe('@ethGetTransactionCount eth_getTransactionCount spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const requestIdPrefix = `[Request ID: testId]`; const blockNumber = mockData.blocks.blocks[2].number; const blockNumberHex = numberTo0x(blockNumber); const transactionId = '0.0.1078@1686183420.196506746'; @@ -96,7 +97,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x0 nonce for no block consideration with not found acoount', async () => { restMock.onGet(contractPath).reply(404, mockData.notFound); restMock.onGet(accountPath).reply(404, mockData.notFound); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); @@ -104,56 +105,56 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return latest nonce for no block consideration but valid account', async () => { restMock.onGet(contractPath).reply(404, mockData.notFound); restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return 0x0 nonce for block 0 consideration', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '0'); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '0', requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); it('should return 0x0 nonce for block 1 consideration', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '1'); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '1', requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); it('should return latest nonce for latest block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return latest nonce for finalized block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockFinalized); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockFinalized, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return latest nonce for latest block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockSafe); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockSafe, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return latest nonce for pending block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockPending); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockPending, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return 0x0 nonce for earliest block with valid block', async () => { restMock.onGet(earliestBlockPath).reply(200, { blocks: [mockData.blocks.blocks[0]] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); @@ -199,7 +200,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(`0x${defaultDetailedContractResults.nonce + 1}`); }); @@ -232,7 +233,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function }); restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); @@ -240,7 +241,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x0 nonce for historical numerical block with no ethereum transactions found', async () => { restMock.onGet(transactionPath(MOCK_ACCOUNT_ADDR, 2)).reply(200, { transactions: [] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); @@ -248,7 +249,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x1 nonce for historical numerical block with a single ethereum transactions found', async () => { restMock.onGet(transactionPath(MOCK_ACCOUNT_ADDR, 2)).reply(200, { transactions: [{}] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.oneHex); }); @@ -279,7 +280,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex); + const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(3)); }); @@ -292,7 +293,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function restMock .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex); + const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); @@ -311,7 +312,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x1 for pre-hip-729 contracts with nonce=null', async () => { restMock.onGet(accountPath).reply(200, { ...mockData.account, ethereum_nonce: null }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.oneHex); }); @@ -325,7 +326,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function restMock .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockHash); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockHash, requestIdPrefix); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(2)); }); diff --git a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts index df230cfa13..c10374cfa1 100644 --- a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts +++ b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts @@ -39,6 +39,7 @@ chai.use(chaiAsPromised); describe('HbarSpendingPlanRepository', function () { const logger = pino(); const registry = new Registry(); + const requestIdPrefix = `[Request ID: testId]`; const tests = (isSharedCacheEnabled: boolean) => { let cacheService: CacheService; @@ -72,13 +73,15 @@ describe('HbarSpendingPlanRepository', function () { it('creates a plan successfully', async () => { const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); - await expect(repository.findByIdWithDetails(createdPlan.id)).to.be.eventually.deep.equal(createdPlan); + await expect(repository.findByIdWithDetails(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal( + createdPlan, + ); }); }); describe('findById', () => { it('throws an error if plan is not found by ID', async () => { - await expect(repository.findById('non-existent-id')).to.be.eventually.rejectedWith( + await expect(repository.findById('non-existent-id', requestIdPrefix)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID non-existent-id not found`, ); @@ -87,13 +90,13 @@ describe('HbarSpendingPlanRepository', function () { it('returns a plan by ID', async () => { const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); - await expect(repository.findById(createdPlan.id)).to.be.eventually.deep.equal(createdPlan); + await expect(repository.findById(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal(createdPlan); }); }); describe('findByIdWithDetails', () => { it('throws an error if plan is not found by ID', async () => { - await expect(repository.findByIdWithDetails('non-existent-id')).to.be.eventually.rejectedWith( + await expect(repository.findByIdWithDetails('non-existent-id', requestIdPrefix)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID non-existent-id not found`, ); @@ -102,13 +105,15 @@ describe('HbarSpendingPlanRepository', function () { it('returns a plan by ID', async () => { const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); - await expect(repository.findByIdWithDetails(createdPlan.id)).to.be.eventually.deep.equal(createdPlan); + await expect(repository.findByIdWithDetails(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal( + createdPlan, + ); }); }); describe('getSpendingHistory', () => { it('throws an error if plan not found by ID', async () => { - await expect(repository.getSpendingHistory('non-existent-id')).to.be.eventually.rejectedWith( + await expect(repository.getSpendingHistory('non-existent-id', requestIdPrefix)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID non-existent-id not found`, ); @@ -117,7 +122,7 @@ describe('HbarSpendingPlanRepository', function () { it('returns an empty array if spending history is empty', async () => { const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); - const spendingHistory = await repository.getSpendingHistory(createdPlan.id); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); expect(spendingHistory).to.deep.equal([]); }); @@ -129,7 +134,7 @@ describe('HbarSpendingPlanRepository', function () { const hbarSpending = { amount: 100, timestamp: new Date() } as IHbarSpendingRecord; await cacheService.rPush(key, hbarSpending, 'test'); - const spendingHistory = await repository.getSpendingHistory(createdPlan.id); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); expect(spendingHistory).to.have.lengthOf(1); expect(spendingHistory[0].amount).to.equal(hbarSpending.amount); expect(spendingHistory[0].timestamp).to.be.a('Date'); @@ -140,12 +145,12 @@ describe('HbarSpendingPlanRepository', function () { it('adds amount to spending history', async () => { const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); - await expect(repository.getSpendingHistory(createdPlan.id)).to.be.eventually.deep.equal([]); + await expect(repository.getSpendingHistory(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal([]); const amount = 100; - await repository.addAmountToSpendingHistory(createdPlan.id, amount); + await repository.addAmountToSpendingHistory(createdPlan.id, amount, requestIdPrefix); - const spendingHistory = await repository.getSpendingHistory(createdPlan.id); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); expect(spendingHistory).to.have.lengthOf(1); expect(spendingHistory[0].amount).to.equal(amount); expect(spendingHistory[0].timestamp).to.be.a('Date'); @@ -154,14 +159,14 @@ describe('HbarSpendingPlanRepository', function () { it('adds multiple amounts to spending history', async () => { const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); - await expect(repository.getSpendingHistory(createdPlan.id)).to.be.eventually.deep.equal([]); + await expect(repository.getSpendingHistory(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal([]); const amounts = [100, 200, 300]; for (const amount of amounts) { - await repository.addAmountToSpendingHistory(createdPlan.id, amount); + await repository.addAmountToSpendingHistory(createdPlan.id, amount, requestIdPrefix); } - const spendingHistory = await repository.getSpendingHistory(createdPlan.id); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); expect(spendingHistory).to.have.lengthOf(3); expect(spendingHistory.map((entry) => entry.amount)).to.deep.equal(amounts); }); @@ -170,7 +175,7 @@ describe('HbarSpendingPlanRepository', function () { const id = 'non-existent-id'; const amount = 100; - await expect(repository.addAmountToSpendingHistory(id, amount)).to.be.eventually.rejectedWith( + await expect(repository.addAmountToSpendingHistory(id, amount, requestIdPrefix)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID ${id} not found`, ); @@ -200,9 +205,9 @@ describe('HbarSpendingPlanRepository', function () { const createdPlan = await repository.create(subscriptionType); const amount = 50; - await repository.addAmountToSpentToday(createdPlan.id, amount); + await repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix); - const spentToday = await repository.getSpentToday(createdPlan.id); + const spentToday = await repository.getSpentToday(createdPlan.id, requestIdPrefix); expect(spentToday).to.equal(amount); }); @@ -210,21 +215,22 @@ describe('HbarSpendingPlanRepository', function () { const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); - const spentToday = await repository.getSpentToday(createdPlan.id); + const spentToday = await repository.getSpentToday(createdPlan.id, requestIdPrefix); expect(spentToday).to.equal(0); }); it('should expire spent today key at the end of the day', async () => { + const requestIdPrefix = `[Request ID: testId]`; const subscriptionType = SubscriptionType.BASIC; const createdPlan = await repository.create(subscriptionType); const amount = 50; - await repository.addAmountToSpentToday(createdPlan.id, amount); - await expect(repository.getSpentToday(createdPlan.id)).to.eventually.equal(amount); + await repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix); + await expect(repository.getSpentToday(createdPlan.id, requestIdPrefix)).to.eventually.equal(amount); await new Promise((resolve) => setTimeout(resolve, mockedOneDayInMillis + 100)); - await expect(repository.getSpentToday(createdPlan.id)).to.eventually.equal(0); + await expect(repository.getSpentToday(createdPlan.id, requestIdPrefix)).to.eventually.equal(0); }); }); @@ -257,17 +263,17 @@ describe('HbarSpendingPlanRepository', function () { const createdPlan = await repository.create(subscriptionType); const amount = 50; - await repository.addAmountToSpentToday(createdPlan.id, amount); + await repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix); - const plan = await repository.findByIdWithDetails(createdPlan.id); + const plan = await repository.findByIdWithDetails(createdPlan.id, requestIdPrefix); expect(plan).to.not.be.null; expect(plan!.spentToday).to.equal(amount); // Add more to spent today const newAmount = 100; - await repository.addAmountToSpentToday(createdPlan.id, newAmount); + await repository.addAmountToSpentToday(createdPlan.id, newAmount, requestIdPrefix); - const updatedPlan = await repository.findByIdWithDetails(createdPlan.id); + const updatedPlan = await repository.findByIdWithDetails(createdPlan.id, requestIdPrefix); expect(updatedPlan).to.not.be.null; expect(updatedPlan!.spentToday).to.equal(amount + newAmount); }); @@ -276,7 +282,7 @@ describe('HbarSpendingPlanRepository', function () { const id = 'non-existent-id'; const amount = 50; - await expect(repository.addAmountToSpentToday(id, amount)).to.be.eventually.rejectedWith( + await expect(repository.addAmountToSpentToday(id, amount, requestIdPrefix)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID ${id} not found`, ); @@ -291,7 +297,9 @@ describe('HbarSpendingPlanRepository', function () { await cacheService.set(key, { ...createdPlan, active: false }, 'test'); const amount = 50; - await expect(repository.addAmountToSpentToday(createdPlan.id, amount)).to.be.eventually.rejectedWith( + await expect( + repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix), + ).to.be.eventually.rejectedWith( HbarSpendingPlanNotActiveError, `HbarSpendingPlan with ID ${createdPlan.id} is not active`, ); @@ -301,7 +309,7 @@ describe('HbarSpendingPlanRepository', function () { describe('checkExistsAndActive', () => { it('throws error if plan does not exist when checking if exists and active', async () => { const id = 'non-existent-id'; - await expect(repository.checkExistsAndActive(id)).to.be.eventually.rejectedWith( + await expect(repository.checkExistsAndActive(id, requestIdPrefix)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID ${id} not found`, ); @@ -315,7 +323,7 @@ describe('HbarSpendingPlanRepository', function () { const key = `${repository['collectionKey']}:${createdPlan.id}`; await cacheService.set(key, { ...createdPlan, active: false }, 'test'); - await expect(repository.checkExistsAndActive(createdPlan.id)).to.be.eventually.rejectedWith( + await expect(repository.checkExistsAndActive(createdPlan.id, requestIdPrefix)).to.be.eventually.rejectedWith( HbarSpendingPlanNotActiveError, `HbarSpendingPlan with ID ${createdPlan.id} is not active`, ); diff --git a/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts b/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts index 95ad7b6deb..8b207cb250 100644 --- a/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts +++ b/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts @@ -39,7 +39,7 @@ chai.use(chaiAsPromised); describe('CacheService Test Suite', async function () { this.timeout(10000); - + const requestIdPrefix = `[Request ID: testId]`; const describeKeysTestSuite = () => { describe('keys', async function () { it('should retrieve all keys', async function () { @@ -154,7 +154,7 @@ describe('CacheService Test Suite', async function () { const value = 'value'; await cacheService.set(key, value, callingMethod); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); }); @@ -165,7 +165,7 @@ describe('CacheService Test Suite', async function () { await cacheService.set(key, value, callingMethod); await cacheService.delete(key, callingMethod); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; }); @@ -175,7 +175,7 @@ describe('CacheService Test Suite', async function () { const value = 'value'; await cacheService.set(key, value, callingMethod); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); }); @@ -189,7 +189,7 @@ describe('CacheService Test Suite', async function () { await cacheService.multiSet(entries, callingMethod); for (const [key, value] of Object.entries(entries)) { - const valueFromCache = await cacheService.getAsync(key, callingMethod); + const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(valueFromCache).eq(value); } }); @@ -200,7 +200,7 @@ describe('CacheService Test Suite', async function () { const amount = 5; await cacheService.set(key, 10, callingMethod); - const newValue = await cacheService.incrBy(key, amount, callingMethod); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).to.equal(15); }); @@ -212,7 +212,7 @@ describe('CacheService Test Suite', async function () { const value = 'item'; await cacheService.rPush(key, value, callingMethod); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).to.deep.equal([value]); }); @@ -303,7 +303,7 @@ describe('CacheService Test Suite', async function () { await cacheService.set(key, value, callingMethod); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); }); @@ -315,7 +315,7 @@ describe('CacheService Test Suite', async function () { await cacheService.delete(key, callingMethod); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; }); @@ -325,7 +325,7 @@ describe('CacheService Test Suite', async function () { await cacheService.set(key, value, callingMethod); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); }); @@ -333,7 +333,7 @@ describe('CacheService Test Suite', async function () { await cacheService.multiSet(multiSetEntries, callingMethod); for (const [key, value] of Object.entries(multiSetEntries)) { - const valueFromCache = await cacheService.getAsync(key, callingMethod); + const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(valueFromCache).eq(value); } }); @@ -345,7 +345,7 @@ describe('CacheService Test Suite', async function () { await cacheService.multiSet(multiSetEntries, callingMethod); for (const [key, value] of Object.entries(multiSetEntries)) { - const valueFromCache = await cacheService.getAsync(key, callingMethod); + const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(valueFromCache).eq(value); } }); @@ -354,7 +354,7 @@ describe('CacheService Test Suite', async function () { const key = 'string'; await cacheService.disconnectRedisClient(); - const cachedValue = await cacheService.getAsync(key, callingMethod); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(null); }); @@ -366,7 +366,7 @@ describe('CacheService Test Suite', async function () { await expect(cacheService.set(key, value, callingMethod)).to.eventually.not.be.rejected; - const internalCacheRes = await cacheService.getAsync(key, callingMethod); + const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(internalCacheRes).to.eq(value); }); diff --git a/packages/relay/tests/lib/services/debugService/debug.spec.ts b/packages/relay/tests/lib/services/debugService/debug.spec.ts index 0f7eb97523..6230493457 100644 --- a/packages/relay/tests/lib/services/debugService/debug.spec.ts +++ b/packages/relay/tests/lib/services/debugService/debug.spec.ts @@ -526,14 +526,15 @@ describe('Debug API Test Suite', async function () { }); describe('resolveAddress', async function () { + const requestIdPrefix = `[Request ID: testId]`; it('should return null address with invalid parameters in resolveAddress', async function () { - const address = await debugService.resolveAddress(null!); + const address = await debugService.resolveAddress(null!, requestIdPrefix); expect(address).to.be.null; }); it('should return passed address on notFound entity from the mirror node', async function () { restMock.onGet(ACCOUNT_BY_ADDRESS).reply(404, notFound); - const address = await debugService.resolveAddress(accountAddress); + const address = await debugService.resolveAddress(accountAddress, requestIdPrefix); expect(address).to.eq(accountAddress); }); }); diff --git a/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts b/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts index e5dace01b4..72c405bc3f 100644 --- a/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts +++ b/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts @@ -53,6 +53,7 @@ describe('HbarLimitService', function () { const mockRequestId = getRequestId(); const mockPlanId = uuidV4(randomBytes(16)); + const requestIdPrefix = `[Request ID: testId]`; let hbarLimitService: HbarLimitService; let hbarSpendingPlanRepositoryStub: sinon.SinonStubbedInstance; let ethAddressHbarSpendingPlanRepositoryStub: sinon.SinonStubbedInstance; @@ -151,7 +152,7 @@ describe('HbarLimitService', function () { it('should return true if the total daily budget is exceeded', async function () { // @ts-ignore hbarLimitService.remainingBudget = 0; - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestIdPrefix); expect(result).to.be.true; }); @@ -454,7 +455,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService['getSpendingPlan'](mockEthAddress); + const result = await hbarLimitService['getSpendingPlan'](mockEthAddress, requestIdPrefix); expect(result).to.deep.equal(spendingPlan); }); @@ -476,7 +477,7 @@ describe('HbarLimitService', function () { const error = new EthAddressHbarSpendingPlanNotFoundError(mockEthAddress); ethAddressHbarSpendingPlanRepositoryStub.findByAddress.rejects(error); - const result = await hbarLimitService['getSpendingPlan'](mockEthAddress); + const result = await hbarLimitService['getSpendingPlan'](mockEthAddress, requestIdPrefix); expect(result).to.be.null; }); @@ -493,7 +494,7 @@ describe('HbarLimitService', function () { describe('getSpendingPlanByEthAddress', function () { const testGetSpendingPlanByEthAddressError = async (error: Error, errorClass: any) => { - const result = hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress); + const result = hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress, requestIdPrefix); await expect(result).to.be.eventually.rejectedWith(errorClass, error.message); }; @@ -531,7 +532,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress); + const result = await hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress, requestIdPrefix); expect(result).to.deep.equal(spendingPlan); }); @@ -612,7 +613,7 @@ describe('HbarLimitService', function () { 'updateAverageDailyUsagePerSubscriptionType', ); - await hbarLimitService.addExpense(expense, ethAddress, ipAddress); + await hbarLimitService.addExpense(expense, ethAddress, requestIdPrefix, ipAddress); expect(hbarSpendingPlanRepositoryStub.addAmountToSpentToday.calledOnceWith(mockPlanId, expense)).to.be.true; // @ts-ignore @@ -636,9 +637,9 @@ describe('HbarLimitService', function () { ); for (const { ethAddress, ipAddress } of testCases) { // @ts-ignore - await expect(hbarLimitService.addExpense(100, ethAddress, ipAddress)).to.be.eventually.rejectedWith( - 'Cannot add expense without an eth address or ip address', - ); + await expect( + hbarLimitService.addExpense(100, ethAddress, requestIdPrefix, ipAddress), + ).to.be.eventually.rejectedWith('Cannot add expense without an eth address or ip address'); } }); @@ -650,7 +651,7 @@ describe('HbarLimitService', function () { ); ethAddressHbarSpendingPlanRepositoryStub.save.resolves(); - await hbarLimitService.addExpense(100, mockEthAddress); + await hbarLimitService.addExpense(100, mockEthAddress, requestIdPrefix); expect(hbarSpendingPlanRepositoryStub.create.calledOnce).to.be.true; expect(ethAddressHbarSpendingPlanRepositoryStub.save.calledOnce).to.be.true; @@ -676,7 +677,7 @@ describe('HbarLimitService', function () { hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(createSpendingPlan(mockPlanId)); hbarSpendingPlanRepositoryStub.addAmountToSpentToday.rejects(new Error('Failed to add expense')); - await expect(hbarLimitService.addExpense(100, mockEthAddress)).to.be.eventually.rejectedWith( + await expect(hbarLimitService.addExpense(100, mockEthAddress, requestIdPrefix)).to.be.eventually.rejectedWith( 'Failed to add expense', ); }); diff --git a/packages/server/tests/acceptance/rpc_batch2.spec.ts b/packages/server/tests/acceptance/rpc_batch2.spec.ts index 248a064601..c848789fc6 100644 --- a/packages/server/tests/acceptance/rpc_batch2.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch2.spec.ts @@ -881,7 +881,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { maxFeePerGas: gasPrice, type: 2, }; - console.log('sign transaction'); + const signedTx = await accounts[1].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const txReceipt = await relay.call( From 8b51e5aef9e10c24cd5a3b38519f97576defb4c1 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Tue, 10 Sep 2024 15:33:13 +0300 Subject: [PATCH 11/48] Fixes ws batch1 tests Signed-off-by: Konstantina Blazhukova --- packages/ws-server/tests/acceptance/estimateGas.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ws-server/tests/acceptance/estimateGas.spec.ts b/packages/ws-server/tests/acceptance/estimateGas.spec.ts index 62cab70515..55750ebb69 100644 --- a/packages/ws-server/tests/acceptance/estimateGas.spec.ts +++ b/packages/ws-server/tests/acceptance/estimateGas.spec.ts @@ -40,13 +40,15 @@ describe('@web-socket-batch-1 eth_estimateGas', async function () { gasPriceDeviation: number, ethersWsProvider: WebSocketProvider, requestId = 'eth_estimateGas'; + let requestDetails; before(async () => { requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '2500000000'; //25 Hbar - const neededAccounts: number = 1; + requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; + accounts.push( ...(await Utils.createMultipleAliasAccounts( mirrorNode, From 0aa4c4fe8809b2853aee28498f47907d52869f62 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Tue, 10 Sep 2024 17:53:39 +0300 Subject: [PATCH 12/48] Makes RequestDetails object available to all methods in the server Signed-off-by: Konstantina Blazhukova --- packages/relay/src/index.ts | 69 ++-- packages/relay/src/lib/eth.ts | 309 +++++++++--------- packages/relay/src/lib/poller.ts | 9 +- .../services/debugService/IDebugService.ts | 3 +- .../src/lib/services/debugService/index.ts | 4 +- packages/server/src/server.ts | 144 ++++---- 6 files changed, 278 insertions(+), 260 deletions(-) diff --git a/packages/relay/src/index.ts b/packages/relay/src/index.ts index bb86cc96be..6b4bf69581 100644 --- a/packages/relay/src/index.ts +++ b/packages/relay/src/index.ts @@ -63,11 +63,11 @@ export interface Net { } export interface Eth { - blockNumber(requestIdPrefix: string): Promise; + blockNumber(requestDetails: IRequestDetails): Promise; call(call: any, blockParam: string | object | null, requestDetails: IRequestDetails): Promise; - coinbase(requestId?: string): JsonRpcError; + coinbase(requestDetails: IRequestDetails): JsonRpcError; estimateGas( transaction: IContractCallRequest, @@ -77,19 +77,19 @@ export interface Eth { gasPrice(requestDetails: IRequestDetails): Promise; - getBalance(account: string, blockNumber: string | null, requestIdPrefix: string): Promise; + getBalance(account: string, blockNumber: string | null, requestDetails: IRequestDetails): Promise; getBlockByHash(hash: string, showDetails: boolean, requestDetails: IRequestDetails): Promise; getBlockByNumber(blockNum: string, showDetails: boolean, requestDetails: IRequestDetails): Promise; - getBlockTransactionCountByHash(hash: string, requestIdPrefix: string): Promise; + getBlockTransactionCountByHash(hash: string, requestDetails: IRequestDetails): Promise; - getBlockTransactionCountByNumber(blockNum: string, requestIdPrefix: string): Promise; + getBlockTransactionCountByNumber(blockNum: string, requestDetails: IRequestDetails): Promise; getCode(address: string, blockNumber: string | null, requestDetails: IRequestDetails): Promise; - chainId(requestId?: string): string; + chainId(requestDetails: IRequestDetails): string; getLogs( blockHash: string | null, @@ -97,34 +97,47 @@ export interface Eth { toBlock: string | null, address: string | string[] | null, topics: any[] | null, - requestId?: string, + requestDetails: IRequestDetails, ): Promise; - getStorageAt(requestIdPrefix: string, address: string, slot: string, blockNumber: string | null): Promise; + getStorageAt( + requestDetails: IRequestDetails, + address: string, + slot: string, + blockNumber: string | null, + ): Promise; - getTransactionByBlockHashAndIndex(hash: string, index: string, requestId?: string): Promise; + getTransactionByBlockHashAndIndex( + hash: string, + index: string, + requestDetails: IRequestDetails, + ): Promise; getTransactionByBlockNumberAndIndex( blockNum: string, index: string, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise; - getTransactionByHash(hash: string, requestIdPrefix: string): Promise; + getTransactionByHash(hash: string, requestDetails: IRequestDetails): Promise; - getTransactionCount(address: string, blockNum: string, requestIdPrefix: string): Promise; + getTransactionCount( + address: string, + blockNum: string, + requestDetails: IRequestDetails, + ): Promise; getTransactionReceipt(hash: string, requestDetails: IRequestDetails): Promise; - getUncleByBlockHashAndIndex(requestId?: string): Promise; + getUncleByBlockHashAndIndex(requestDetails: IRequestDetails): Promise; - getUncleByBlockNumberAndIndex(requestId?: string): Promise; + getUncleByBlockNumberAndIndex(requestDetails: IRequestDetails): Promise; - getUncleCountByBlockHash(requestId?: string): Promise; + getUncleCountByBlockHash(requestDetails: IRequestDetails): Promise; - getUncleCountByBlockNumber(requestId?: string): Promise; + getUncleCountByBlockNumber(requestDetails: IRequestDetails): Promise; - getWork(requestId?: string): JsonRpcError; + getWork(requestDetails: IRequestDetails): JsonRpcError; feeHistory( blockCount: number, @@ -133,29 +146,29 @@ export interface Eth { requestDetails: IRequestDetails, ): Promise; - hashrate(requestId?: string): Promise; + hashrate(requestDetails: IRequestDetails): Promise; - maxPriorityFeePerGas(requestId?: string): Promise; + maxPriorityFeePerGas(requestDetails: IRequestDetails): Promise; - mining(requestId?: string): Promise; + mining(requestDetails: IRequestDetails): Promise; - protocolVersion(requestId?: string): JsonRpcError; + protocolVersion(requestDetails: IRequestDetails): JsonRpcError; sendRawTransaction(transaction: string, requestDetails: IRequestDetails): Promise; - sendTransaction(requestId?: string): JsonRpcError; + sendTransaction(requestDetails: IRequestDetails): JsonRpcError; - sign(requestId?: string): JsonRpcError; + sign(requestDetails: IRequestDetails): JsonRpcError; - signTransaction(requestId?: string): JsonRpcError; + signTransaction(requestDetails: IRequestDetails): JsonRpcError; - submitHashrate(requestId?: string): JsonRpcError; + submitHashrate(requestDetails: IRequestDetails): JsonRpcError; - submitWork(requestId?: string): Promise; + submitWork(requestDetails: IRequestDetails): Promise; - syncing(requestId?: string): Promise; + syncing(requestDetails: IRequestDetails): Promise; - accounts(requestId?: string): Array; + accounts(requestDetails: IRequestDetails): Array; filterService(): IFilterService; diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index f270f63f0b..00158e07a0 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -308,8 +308,8 @@ export class EthImpl implements Eth { * This method is implemented to always return an empty array. This is in alignment * with the behavior of Infura. */ - accounts(requestIdPrefix?: string): never[] { - this.logger.trace(`${requestIdPrefix} accounts()`); + accounts(requestDetails: IRequestDetails): never[] { + this.logger.trace(`${requestDetails.requestIdPrefix} accounts()`); return EthImpl.accounts; } @@ -329,21 +329,22 @@ export class EthImpl implements Eth { rewardPercentiles: Array | null, requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; const maxResults = process.env.TEST === 'true' ? constants.DEFAULT_FEE_HISTORY_MAX_RESULTS : Number(process.env.FEE_HISTORY_MAX_RESULTS); this.logger.trace( - `${requestDetails.requestIdPrefix} feeHistory(blockCount=${blockCount}, newestBlock=${newestBlock}, rewardPercentiles=${rewardPercentiles})`, + `${requestIdPrefix} feeHistory(blockCount=${blockCount}, newestBlock=${newestBlock}, rewardPercentiles=${rewardPercentiles})`, ); try { - const latestBlockNumber = await this.translateBlockTag(EthImpl.blockLatest, requestDetails.requestIdPrefix); + const latestBlockNumber = await this.translateBlockTag(EthImpl.blockLatest, requestDetails); const newestBlockNumber = newestBlock == EthImpl.blockLatest || newestBlock == EthImpl.blockPending ? latestBlockNumber - : await this.translateBlockTag(newestBlock, requestDetails.requestIdPrefix); + : await this.translateBlockTag(newestBlock, requestDetails); if (newestBlockNumber > latestBlockNumber) { return predefined.REQUEST_BEYOND_HEAD_BLOCK(newestBlockNumber, latestBlockNumber); @@ -398,20 +399,21 @@ export class EthImpl implements Eth { return feeHistory; } catch (e) { - this.logger.error(e, `${requestDetails.requestIdPrefix} Error constructing default feeHistory`); + this.logger.error(e, `${requestIdPrefix} Error constructing default feeHistory`); return EthImpl.feeHistoryEmptyResponse; } } private async getFeeByBlockNumber(blockNumber: number, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; let fee = 0; try { - const block = await this.mirrorNodeClient.getBlock(blockNumber, requestDetails.requestIdPrefix); + const block = await this.mirrorNodeClient.getBlock(blockNumber, requestIdPrefix); fee = await this.getFeeWeibars(EthImpl.ethFeeHistory, requestDetails, `lte:${block.timestamp.to}`); } catch (error) { this.logger.warn( error, - `${requestDetails.requestIdPrefix} Fee history cannot retrieve block or fee. Returning ${fee} fee for block ${blockNumber}`, + `${requestIdPrefix} Fee history cannot retrieve block or fee. Returning ${fee} fee for block ${blockNumber}`, ); } @@ -530,7 +532,8 @@ export class EthImpl implements Eth { /** * Gets the most recent block number. */ - async blockNumber(requestIdPrefix: string): Promise { + async blockNumber(requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} blockNumber()`); return await this.common.getLatestBlockNumber(requestIdPrefix); } @@ -538,7 +541,8 @@ export class EthImpl implements Eth { /** * Gets the most recent block number and timestamp.to which represents the block finality. */ - async blockNumberTimestamp(caller: string, requestIdPrefix: string): Promise { + async blockNumberTimestamp(caller: string, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} blockNumber()`); const cacheKey = `${constants.CACHE_KEY.ETH_BLOCK_NUMBER}`; @@ -563,8 +567,8 @@ export class EthImpl implements Eth { * the same value. This can be specified via an environment variable * `CHAIN_ID`. */ - chainId(requestIdPrefix?: string): string { - this.logger.trace(`${requestIdPrefix} chainId()`); + chainId(requestDetails: IRequestDetails): string { + this.logger.trace(`${requestDetails.requestIdPrefix} chainId()`); return this.chain; } @@ -598,7 +602,7 @@ export class EthImpl implements Eth { return prepend0x(trimPrecedingZeros(response.result)); } else { this.logger.error(`${requestIdPrefix} No gas estimate returned from mirror-node: ${JSON.stringify(response)}`); - return this.predefinedGasForTransaction(transaction, requestIdPrefix); + return this.predefinedGasForTransaction(transaction, requestDetails); } } catch (e: any) { this.logger.error( @@ -608,7 +612,7 @@ export class EthImpl implements Eth { if (this.estimateGasThrows && e instanceof MirrorNodeClientError && e.isContractRevertOpcodeExecuted()) { return predefined.CONTRACT_REVERT(e.detail ?? e.message, e.data); } - return this.predefinedGasForTransaction(transaction, requestIdPrefix, e); + return this.predefinedGasForTransaction(transaction, requestDetails, e); } } @@ -639,9 +643,10 @@ export class EthImpl implements Eth { */ private async predefinedGasForTransaction( transaction: IContractCallRequest, - requestIdPrefix: string, + requestDetails: IRequestDetails, error?: any, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; const isSimpleTransfer = !!transaction?.to && (!transaction.data || transaction.data === '0x'); const isContractCall = !!transaction?.to && transaction?.data && transaction.data.length >= constants.FUNCTION_SELECTOR_CHAR_LENGTH; @@ -657,7 +662,7 @@ export class EthImpl implements Eth { ); } // when account exists return default base gas - if (await this.getAccount(transaction.to!, requestIdPrefix)) { + if (await this.getAccount(transaction.to!, requestDetails)) { this.logger.warn(`${requestIdPrefix} Returning predefined gas for simple transfer: ${EthImpl.gasTxBaseCost}`); return EthImpl.gasTxBaseCost; } @@ -697,7 +702,8 @@ export class EthImpl implements Eth { * @param {string} requestIdPrefix the prefix for the request ID * @returns {Promise} the account (if such exists for the given address) */ - private async getAccount(address: string, requestIdPrefix: string): Promise { + private async getAccount(address: string, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; const key = `${constants.CACHE_KEY.ACCOUNT}_${address}`; let account = await this.cacheService.getAsync(key, EthImpl.ethEstimateGas, requestIdPrefix); if (!account) { @@ -729,7 +735,7 @@ export class EthImpl implements Eth { transaction.from = this.hapiService.getMainClientInstance().operatorPublicKey?.toEvmAddress(); } else { const operatorId = this.hapiService.getMainClientInstance().operatorAccountId!.toString(); - const operatorAccount = await this.getAccount(operatorId, requestDetails.requestIdPrefix); + const operatorAccount = await this.getAccount(operatorId, requestDetails); transaction.from = operatorAccount?.evm_address; } } @@ -784,105 +790,105 @@ export class EthImpl implements Eth { /** * Gets whether this "Ethereum client" is a miner. We don't mine, so this always returns false. */ - async mining(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} mining()`); + async mining(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} mining()`); return false; } /** * TODO Needs docs, or be removed? */ - async submitWork(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} submitWork()`); + async submitWork(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} submitWork()`); return false; } /** * TODO Needs docs, or be removed? */ - async syncing(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} syncing()`); + async syncing(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} syncing()`); return false; } /** * Always returns null. There are no uncles in Hedera. */ - async getUncleByBlockHashAndIndex(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} getUncleByBlockHashAndIndex()`); + async getUncleByBlockHashAndIndex(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} getUncleByBlockHashAndIndex()`); return null; } /** * Always returns null. There are no uncles in Hedera. */ - async getUncleByBlockNumberAndIndex(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} getUncleByBlockNumberAndIndex()`); + async getUncleByBlockNumberAndIndex(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} getUncleByBlockNumberAndIndex()`); return null; } /** * Always returns '0x0'. There are no uncles in Hedera. */ - async getUncleCountByBlockHash(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} getUncleCountByBlockHash()`); + async getUncleCountByBlockHash(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} getUncleCountByBlockHash()`); return EthImpl.zeroHex; } /** * Always returns '0x0'. There are no uncles in Hedera. */ - async getUncleCountByBlockNumber(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} getUncleCountByBlockNumber()`); + async getUncleCountByBlockNumber(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} getUncleCountByBlockNumber()`); return EthImpl.zeroHex; } /** * TODO Needs docs, or be removed? */ - async hashrate(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} hashrate()`); + async hashrate(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} hashrate()`); return EthImpl.zeroHex; } /** * Always returns UNSUPPORTED_METHOD error. */ - getWork(requestIdPrefix?: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} getWork()`); + getWork(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} getWork()`); return predefined.UNSUPPORTED_METHOD; } /** * Unsupported methods always return UNSUPPORTED_METHOD error. */ - submitHashrate(requestIdPrefix?: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} submitHashrate()`); + submitHashrate(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} submitHashrate()`); return predefined.UNSUPPORTED_METHOD; } - signTransaction(requestIdPrefix?: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} signTransaction()`); + signTransaction(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} signTransaction()`); return predefined.UNSUPPORTED_METHOD; } - sign(requestIdPrefix?: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} sign()`); + sign(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} sign()`); return predefined.UNSUPPORTED_METHOD; } - sendTransaction(requestIdPrefix?: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} sendTransaction()`); + sendTransaction(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} sendTransaction()`); return predefined.UNSUPPORTED_METHOD; } - protocolVersion(requestIdPrefix?: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} protocolVersion()`); + protocolVersion(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} protocolVersion()`); return predefined.UNSUPPORTED_METHOD; } - coinbase(requestIdPrefix?: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} coinbase()`); + coinbase(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} coinbase()`); return predefined.UNSUPPORTED_METHOD; } @@ -895,11 +901,12 @@ export class EthImpl implements Eth { * @param requestIdPrefix */ async getStorageAt( + requestDetails: IRequestDetails, address: string, slot: string, - requestIdPrefix: string, blockNumberOrTagOrHash?: string | null, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace( `${requestIdPrefix} getStorageAt(address=${address}, slot=${slot}, blockNumberOrOrHashTag=${blockNumberOrTagOrHash})`, ); @@ -949,7 +956,12 @@ export class EthImpl implements Eth { * @param blockNumberOrTagOrHash * @param requestIdPrefix */ - async getBalance(account: string, blockNumberOrTagOrHash: string | null, requestIdPrefix: string): Promise { + async getBalance( + account: string, + blockNumberOrTagOrHash: string | null, + requestDetails: IRequestDetails, + ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; const latestBlockTolerance = 1; this.logger.trace(`${requestIdPrefix} getBalance(account=${account}, blockNumberOrTag=${blockNumberOrTagOrHash})`); @@ -965,7 +977,7 @@ export class EthImpl implements Eth { this.logger.trace(`${requestIdPrefix} returning cached value ${cacheKey}:${JSON.stringify(blockNumberCached)}`); latestBlock = { blockNumber: blockNumberCached, timeStampTo: '0' }; } else { - latestBlock = await this.blockNumberTimestamp(EthImpl.ethGetBalance, requestIdPrefix); + latestBlock = await this.blockNumberTimestamp(EthImpl.ethGetBalance, requestDetails); } if (blockNumberOrTagOrHash != null && blockNumberOrTagOrHash.length > 32) { @@ -983,7 +995,7 @@ export class EthImpl implements Eth { // If ever we get the latest block from cache, and blockNumberOrTag is not latest, then we need to get the block timestamp // This should rarely happen. if (blockNumberOrTagOrHash !== EthImpl.blockLatest && latestBlock.timeStampTo === '0') { - latestBlock = await this.blockNumberTimestamp(EthImpl.ethGetBalance, requestIdPrefix); + latestBlock = await this.blockNumberTimestamp(EthImpl.ethGetBalance, requestDetails); } } @@ -1224,24 +1236,16 @@ export class EthImpl implements Eth { * @param requestIdPrefix */ async getBlockByHash(hash: string, showDetails: boolean, requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} getBlockByHash(hash=${hash}, showDetails=${showDetails})`); + const requestIdPrefix = requestDetails.requestIdPrefix; + this.logger.trace(`${requestIdPrefix} getBlockByHash(hash=${hash}, showDetails=${showDetails})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_BLOCK_BY_HASH}_${hash}_${showDetails}`; - let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByHash, requestDetails.requestIdPrefix); + let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByHash, requestIdPrefix); if (!block) { block = await this.getBlock(hash, showDetails, requestDetails).catch((e: any) => { - throw this.common.genericErrorHandler( - e, - `${requestDetails.requestIdPrefix} Failed to retrieve block for hash ${hash}`, - ); + throw this.common.genericErrorHandler(e, `${requestIdPrefix} Failed to retrieve block for hash ${hash}`); }); - await this.cacheService.set( - cacheKey, - block, - EthImpl.ethGetBlockByHash, - undefined, - requestDetails.requestIdPrefix, - ); + await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByHash, undefined, requestIdPrefix); } return block; @@ -1258,28 +1262,21 @@ export class EthImpl implements Eth { showDetails: boolean, requestDetails: IRequestDetails, ): Promise { - this.logger.trace( - `${requestDetails.requestIdPrefix} getBlockByNumber(blockNum=${blockNumOrTag}, showDetails=${showDetails})`, - ); + const requestIdPrefix = requestDetails.requestIdPrefix; + this.logger.trace(`${requestIdPrefix} getBlockByNumber(blockNum=${blockNumOrTag}, showDetails=${showDetails})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_BLOCK_BY_NUMBER}_${blockNumOrTag}_${showDetails}`; - let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByNumber, requestDetails.requestIdPrefix); + let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByNumber, requestIdPrefix); if (!block) { block = await this.getBlock(blockNumOrTag, showDetails, requestDetails).catch((e: any) => { throw this.common.genericErrorHandler( e, - `${requestDetails.requestIdPrefix} Failed to retrieve block for blockNum ${blockNumOrTag}`, + `${requestIdPrefix} Failed to retrieve block for blockNum ${blockNumOrTag}`, ); }); if (!this.common.blockTagIsLatestOrPending(blockNumOrTag)) { - await this.cacheService.set( - cacheKey, - block, - EthImpl.ethGetBlockByNumber, - undefined, - requestDetails.requestIdPrefix, - ); + await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, undefined, requestIdPrefix); } } @@ -1292,7 +1289,8 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getBlockTransactionCountByHash(hash: string, requestIdPrefix: string): Promise { + async getBlockTransactionCountByHash(hash: string, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} getBlockTransactionCountByHash(hash=${hash}, showDetails=%o)`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_TRANSACTION_COUNT_BY_HASH}_${hash}`; @@ -1330,9 +1328,13 @@ export class EthImpl implements Eth { * @param blockNumOrTag * @param requestIdPrefix */ - async getBlockTransactionCountByNumber(blockNumOrTag: string, requestIdPrefix: string): Promise { + async getBlockTransactionCountByNumber( + blockNumOrTag: string, + requestDetails: IRequestDetails, + ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} getBlockTransactionCountByNumber(blockNum=${blockNumOrTag}, showDetails=%o)`); - const blockNum = await this.translateBlockTag(blockNumOrTag, requestIdPrefix); + const blockNum = await this.translateBlockTag(blockNumOrTag, requestDetails); const cacheKey = `${constants.CACHE_KEY.ETH_GET_TRANSACTION_COUNT_BY_NUMBER}_${blockNum}`; const cachedResponse = await this.cacheService.getAsync( @@ -1377,8 +1379,9 @@ export class EthImpl implements Eth { async getTransactionByBlockHashAndIndex( blockHash: string, transactionIndex: string, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace( `${requestIdPrefix} getTransactionByBlockHashAndIndex(hash=${blockHash}, index=${transactionIndex})`, ); @@ -1387,7 +1390,7 @@ export class EthImpl implements Eth { return await this.getTransactionByBlockHashOrBlockNumAndIndex( { title: 'blockHash', value: blockHash }, transactionIndex, - requestIdPrefix, + requestDetails, ); } catch (error) { throw this.common.genericErrorHandler( @@ -1407,18 +1410,19 @@ export class EthImpl implements Eth { async getTransactionByBlockNumberAndIndex( blockNumOrTag: string, transactionIndex: string, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace( `${requestIdPrefix} getTransactionByBlockNumberAndIndex(blockNum=${blockNumOrTag}, index=${transactionIndex})`, ); - const blockNum = await this.translateBlockTag(blockNumOrTag, requestIdPrefix); + const blockNum = await this.translateBlockTag(blockNumOrTag, requestDetails); try { return await this.getTransactionByBlockHashOrBlockNumAndIndex( { title: 'blockNumber', value: blockNum }, transactionIndex, - requestIdPrefix, + requestDetails, ); } catch (error) { throw this.common.genericErrorHandler( @@ -1441,8 +1445,9 @@ export class EthImpl implements Eth { async getTransactionCount( address: string, blockNumOrTag: string | null, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} getTransactionCount(address=${address}, blockNumOrTag=${blockNumOrTag})`); // cache considerations for high load @@ -1462,11 +1467,11 @@ export class EthImpl implements Eth { // if latest or pending, get latest ethereumNonce from mirror node account API nonceCount = await this.getAccountLatestEthereumNonce(address, requestIdPrefix); } else if (blockNumOrTag === EthImpl.blockEarliest) { - nonceCount = await this.getAccountNonceForEarliestBlock(requestIdPrefix); + nonceCount = await this.getAccountNonceForEarliestBlock(requestDetails); } else if (!isNaN(blockNum) && blockNumOrTag.length != EthImpl.blockHashLength && blockNum > 0) { - nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNum, requestIdPrefix); + nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNum, requestDetails); } else if (blockNumOrTag.length == EthImpl.blockHashLength && blockNumOrTag.startsWith(EthImpl.emptyHex)) { - nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNumOrTag, requestIdPrefix); + nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNumOrTag, requestDetails); } else { // return a '-39001: Unknown block' error per api-spec throw predefined.UNKNOWN_BLOCK(); @@ -1505,7 +1510,7 @@ export class EthImpl implements Eth { return parsedTx; } catch (e: any) { this.logger.warn( - `${requestDetails.requestIdPrefix} Error on precheck sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, + `${requestIdPrefix} Error on precheck sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, ); throw this.common.genericErrorHandler(e); } @@ -1582,6 +1587,7 @@ export class EthImpl implements Eth { * @param requestId */ async sendRawTransaction(transaction: string, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; if (transaction?.length >= constants.FUNCTION_SELECTOR_CHAR_LENGTH) this.ethExecutionsCounter .labels(EthImpl.ethSendRawTransaction, transaction.substring(0, constants.FUNCTION_SELECTOR_CHAR_LENGTH)) @@ -1625,17 +1631,17 @@ export class EthImpl implements Eth { this.mirrorNodeClient.getContractResult.name, [formattedId], this.mirrorNodeClient.getMirrorNodeRequestRetryCount(), - requestDetails.requestIdPrefix, + requestIdPrefix, ); if (!contractResult) { - this.logger.warn(`${requestDetails.requestIdPrefix} No record retrieved`); + this.logger.warn(`${requestIdPrefix} No record retrieved`); throw predefined.INTERNAL_ERROR(`No matching record found for transaction id ${txId}`); } if (contractResult.hash == null) { this.logger.error( - `${requestDetails.requestIdPrefix} The ethereumHash can never be null for an ethereum transaction, and yet it was!!`, + `${requestIdPrefix} The ethereumHash can never be null for an ethereum transaction, and yet it was!!`, ); throw predefined.INTERNAL_ERROR(); } @@ -1648,7 +1654,7 @@ export class EthImpl implements Eth { transactionBuffer, txSubmitted, parsedTx, - requestDetails.requestIdPrefix, + requestIdPrefix, ); } finally { /** @@ -1746,8 +1752,9 @@ export class EthImpl implements Eth { value: string | number; }, transactionIndex: string, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; const contractResults = await this.mirrorNodeClient.getContractResults( requestIdPrefix, { @@ -1820,10 +1827,11 @@ export class EthImpl implements Eth { block: string | null, requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; let callData: IContractCallRequest = {}; try { this.logger.debug( - `${requestDetails.requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" at blockBlockNumberOrTag: "${block}" using mirror-node.`, + `${requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" at blockBlockNumberOrTag: "${block}" using mirror-node.`, call.to, gas, call.data, @@ -1838,10 +1846,7 @@ export class EthImpl implements Eth { ...(block !== null ? { block } : {}), }; - const contractCallResponse = await this.mirrorNodeClient.postContractCall( - callData, - requestDetails.requestIdPrefix, - ); + const contractCallResponse = await this.mirrorNodeClient.postContractCall(callData, requestIdPrefix); return contractCallResponse?.result ? prepend0x(contractCallResponse.result) : EthImpl.emptyHex; } catch (e: any) { if (e instanceof JsonRpcError) { @@ -1860,7 +1865,7 @@ export class EthImpl implements Eth { if (e.isContractReverted()) { this.logger.trace( - `${requestDetails.requestIdPrefix} mirror node eth_call request encountered contract revert. message: ${e.message}, details: ${e.detail}, data: ${e.data}`, + `${requestIdPrefix} mirror node eth_call request encountered contract revert. message: ${e.message}, details: ${e.detail}, data: ${e.data}`, ); return predefined.CONTRACT_REVERT(e.detail || e.message, e.data); } @@ -1871,9 +1876,7 @@ export class EthImpl implements Eth { const errorTypeMessage = e.isNotSupported() || e.isNotSupportedSystemContractOperaton() ? 'Unsupported' : 'Unhandled'; this.logger.trace( - `${ - requestDetails.requestIdPrefix - } ${errorTypeMessage} mirror node eth_call request, retrying with consensus node. details: ${JSON.stringify( + `${requestIdPrefix} ${errorTypeMessage} mirror node eth_call request, retrying with consensus node. details: ${JSON.stringify( callData, )} with error: "${e.message}"`, ); @@ -1881,7 +1884,7 @@ export class EthImpl implements Eth { } } - this.logger.error(e, `${requestDetails.requestIdPrefix} Failed to successfully submit eth_call`); + this.logger.error(e, `${requestIdPrefix} Failed to successfully submit eth_call`); return predefined.INTERNAL_ERROR(e.message.toString()); } @@ -1899,13 +1902,14 @@ export class EthImpl implements Eth { gas: number | null, requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; // Execute the call and get the response if (!gas) { gas = Number.parseInt(this.defaultGas); } this.logger.debug( - `${requestDetails.requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" using consensus-node.`, + `${requestIdPrefix} Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" using consensus-node.`, call.to, gas, call.data, @@ -1934,7 +1938,7 @@ export class EthImpl implements Eth { const cachedResponse = await this.cacheService.getAsync(cacheKey, EthImpl.ethCall, requestDetails.requestIdPrefix); if (cachedResponse != undefined) { - this.logger.debug(`${requestDetails.requestIdPrefix} eth_call returned cached response: ${cachedResponse}`); + this.logger.debug(`${requestIdPrefix} eth_call returned cached response: ${cachedResponse}`); return cachedResponse; } @@ -1949,7 +1953,7 @@ export class EthImpl implements Eth { formattedCallReponse, EthImpl.ethCall, this.ethCallCacheTtl, - requestDetails.requestIdPrefix, + requestIdPrefix, ); return formattedCallReponse; } @@ -1958,7 +1962,7 @@ export class EthImpl implements Eth { `Invalid contractCallResponse from consensus-node: ${JSON.stringify(contractCallResponse)}`, ); } catch (e: any) { - this.logger.error(e, `${requestDetails.requestIdPrefix} Failed to successfully submit contractCallQuery`); + this.logger.error(e, `${requestIdPrefix} Failed to successfully submit contractCallQuery`); if (e instanceof JsonRpcError) { return e; } @@ -2014,7 +2018,8 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getTransactionByHash(hash: string, requestIdPrefix: string): Promise { + async getTransactionByHash(hash: string, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} getTransactionByHash(hash=${hash})`, hash); const contractResult = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestIdPrefix); @@ -2061,27 +2066,23 @@ export class EthImpl implements Eth { * @param requestIdPrefix */ async getTransactionReceipt(hash: string, requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} getTransactionReceipt(${hash})`); + const requestIdPrefix = requestDetails.requestIdPrefix; + this.logger.trace(`${requestIdPrefix} getTransactionReceipt(${hash})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_TRANSACTION_RECEIPT}_${hash}`; const cachedResponse = await this.cacheService.getAsync( cacheKey, EthImpl.ethGetTransactionReceipt, - requestDetails.requestIdPrefix, + requestIdPrefix, ); if (cachedResponse) { this.logger.debug( - `${requestDetails.requestIdPrefix} getTransactionReceipt returned cached response: ${JSON.stringify( - cachedResponse, - )}`, + `${requestIdPrefix} getTransactionReceipt returned cached response: ${JSON.stringify(cachedResponse)}`, ); return cachedResponse; } - const receiptResponse = await this.mirrorNodeClient.getContractResultWithRetry( - hash, - requestDetails.requestIdPrefix, - ); + const receiptResponse = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestIdPrefix); if (receiptResponse === null || receiptResponse.hash === undefined) { // handle synthetic transactions const syntheticLogs = await this.common.getLogsWithParams( @@ -2089,12 +2090,12 @@ export class EthImpl implements Eth { { 'transaction.hash': hash, }, - requestDetails.requestIdPrefix, + requestIdPrefix, ); // no tx found if (!syntheticLogs.length) { - this.logger.trace(`${requestDetails.requestIdPrefix} no receipt for ${hash}`); + this.logger.trace(`${requestIdPrefix} no receipt for ${hash}`); return null; } @@ -2117,14 +2118,14 @@ export class EthImpl implements Eth { type: null, // null from HAPI transactions }; - this.logger.trace(`${requestDetails.requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); + this.logger.trace(`${requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); await this.cacheService.set( cacheKey, receipt, EthImpl.ethGetTransactionReceipt, constants.CACHE_TTL.ONE_DAY, - requestDetails.requestIdPrefix, + requestIdPrefix, ); return receipt; } else { @@ -2147,8 +2148,8 @@ export class EthImpl implements Eth { const receipt: ITransactionReceipt = { blockHash: toHash32(receiptResponse.block_hash), blockNumber: numberTo0x(receiptResponse.block_number), - from: await this.resolveEvmAddress(receiptResponse.from, requestDetails.requestIdPrefix), - to: await this.resolveEvmAddress(receiptResponse.to, requestDetails.requestIdPrefix), + from: await this.resolveEvmAddress(receiptResponse.from, requestIdPrefix), + to: await this.resolveEvmAddress(receiptResponse.to, requestIdPrefix), cumulativeGasUsed: numberTo0x(receiptResponse.block_gas_used), gasUsed: nanOrNumberTo0x(receiptResponse.gas_used), contractAddress: receiptResponse.address, @@ -2168,14 +2169,14 @@ export class EthImpl implements Eth { : prepend0x(ASCIIToHex(receiptResponse.error_message)); } - this.logger.trace(`${requestDetails.requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); + this.logger.trace(`${requestIdPrefix} receipt for ${hash} found in block ${receipt.blockNumber}`); await this.cacheService.set( cacheKey, receipt, EthImpl.ethGetTransactionReceipt, constants.CACHE_TTL.ONE_DAY, - requestDetails.requestIdPrefix, + requestIdPrefix, ); return receipt; } @@ -2232,12 +2233,12 @@ export class EthImpl implements Eth { * most recent block, 'earliest' is 0, numbers become numbers. * * @param tag null, a number, or 'latest', 'pending', or 'earliest' - * @param requestIdPrefix + * @param requestDetails * @private */ - private async translateBlockTag(tag: string | null, requestIdPrefix: string): Promise { + private async translateBlockTag(tag: string | null, requestDetails: IRequestDetails): Promise { if (this.common.blockTagIsLatestOrPending(tag)) { - return Number(await this.blockNumber(requestIdPrefix)); + return Number(await this.blockNumber(requestDetails)); } else if (tag === EthImpl.blockEarliest) { return 0; } else { @@ -2268,7 +2269,7 @@ export class EthImpl implements Eth { showDetails: boolean, logs: Log[], transactionsArray: Array, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Array { let filteredLogs: Log[]; if (showDetails) { @@ -2286,7 +2287,9 @@ export class EthImpl implements Eth { }); } - this.logger.trace(`${requestIdPrefix} Synthetic transaction hashes will be populated in the block response`); + this.logger.trace( + `${requestDetails.requestIdPrefix} Synthetic transaction hashes will be populated in the block response`, + ); return transactionsArray; } @@ -2306,17 +2309,14 @@ export class EthImpl implements Eth { showDetails: boolean, requestDetails: IRequestDetails, ): Promise { - const blockResponse = await this.common.getHistoricalBlockResponse( - requestDetails.requestIdPrefix, - blockHashOrNumber, - true, - ); + const requestIdPrefix = requestDetails.requestIdPrefix; + const blockResponse = await this.common.getHistoricalBlockResponse(requestIdPrefix, blockHashOrNumber, true); if (blockResponse == null) return null; const timestampRange = blockResponse.timestamp; const timestampRangeParams = [`gte:${timestampRange.from}`, `lte:${timestampRange.to}`]; const contractResults = await this.mirrorNodeClient.getContractResults( - requestDetails.requestIdPrefix, + requestIdPrefix, { timestamp: timestampRangeParams }, undefined, ); @@ -2324,7 +2324,7 @@ export class EthImpl implements Eth { const params = { timestamp: timestampRangeParams }; // get contract results logs using block timestamp range - const logs = await this.common.getLogsWithParams(null, params, requestDetails.requestIdPrefix); + const logs = await this.common.getLogsWithParams(null, params, requestIdPrefix); if (contractResults == null && logs.length == 0) { // contract result not found @@ -2340,21 +2340,16 @@ export class EthImpl implements Eth { // prepare transactionArray let transactionArray: any[] = []; for (const contractResult of contractResults) { - contractResult.from = await this.resolveEvmAddress(contractResult.from, requestDetails.requestIdPrefix, [ + contractResult.from = await this.resolveEvmAddress(contractResult.from, requestIdPrefix, [ constants.TYPE_ACCOUNT, ]); - contractResult.to = await this.resolveEvmAddress(contractResult.to, requestDetails.requestIdPrefix); + contractResult.to = await this.resolveEvmAddress(contractResult.to, requestIdPrefix); contractResult.chain_id = contractResult.chain_id || this.chain; transactionArray.push(showDetails ? formatContractResult(contractResult) : contractResult.hash); } - transactionArray = this.populateSyntheticTransactions( - showDetails, - logs, - transactionArray, - requestDetails.requestIdPrefix, - ); + transactionArray = this.populateSyntheticTransactions(showDetails, logs, transactionArray, requestDetails); transactionArray = showDetails ? _.uniqBy(transactionArray, 'hash') : _.uniq(transactionArray); const formattedReceipts: IReceiptRootHash[] = ReceiptsRootUtils.buildReceiptRootHashes( @@ -2444,8 +2439,9 @@ export class EthImpl implements Eth { private async getAcccountNonceFromContractResult( address: string, blockNumOrHash: any, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; // get block timestamp for blockNum const block = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestIdPrefix); // consider caching error responses if (block == null) { @@ -2492,8 +2488,8 @@ export class EthImpl implements Eth { return numberTo0x(transactionResult.nonce + 1); // nonce is 0 indexed } - private async getAccountNonceForEarliestBlock(requestIdPrefix: string): Promise { - const block = await this.mirrorNodeClient.getEarliestBlock(requestIdPrefix); + private async getAccountNonceForEarliestBlock(requestDetails: IRequestDetails): Promise { + const block = await this.mirrorNodeClient.getEarliestBlock(requestDetails.requestIdPrefix); if (block == null) { throw predefined.INTERNAL_ERROR('No network blocks found'); } @@ -2510,8 +2506,9 @@ export class EthImpl implements Eth { private async getAccountNonceForHistoricBlock( address: string, blockNumOrHash: number | string, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; let getBlock; const isParamBlockNum = typeof blockNumOrHash === 'number' ? true : false; @@ -2536,7 +2533,7 @@ export class EthImpl implements Eth { } // if valid block number, get block timestamp - return await this.getAcccountNonceFromContractResult(address, blockNum, requestIdPrefix); + return await this.getAcccountNonceFromContractResult(address, blockNum, requestDetails); } async getLogs( @@ -2545,13 +2542,13 @@ export class EthImpl implements Eth { toBlock: string | 'latest', address: string | string[] | null, topics: any[] | null, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { - return this.common.getLogs(blockHash, fromBlock, toBlock, address, topics, requestIdPrefix); + return this.common.getLogs(blockHash, fromBlock, toBlock, address, topics, requestDetails.requestIdPrefix); } - async maxPriorityFeePerGas(requestIdPrefix?: string): Promise { - this.logger.trace(`${requestIdPrefix} maxPriorityFeePerGas()`); + async maxPriorityFeePerGas(requestDetails: IRequestDetails): Promise { + this.logger.trace(`${requestDetails.requestIdPrefix} maxPriorityFeePerGas()`); return EthImpl.zeroHex; } diff --git a/packages/relay/src/lib/poller.ts b/packages/relay/src/lib/poller.ts index 61d3149b73..b012af7af2 100644 --- a/packages/relay/src/lib/poller.ts +++ b/packages/relay/src/lib/poller.ts @@ -84,6 +84,10 @@ export class Poller { 'latest', filters?.address || null, filters?.topics || null, + { + requestIdPrefix: '', + requestIp: '', + } as IRequestDetails, ); poll.lastPolled = this.latestBlock; @@ -118,7 +122,10 @@ export class Poller { start() { this.logger.info(`${LOGGER_PREFIX} Starting polling with interval=${this.pollingInterval}`); this.interval = setInterval(async () => { - this.latestBlock = await this.eth.blockNumber(''); + this.latestBlock = await this.eth.blockNumber({ + requestIdPrefix: '', + requestIp: '', + } as IRequestDetails); this.poll(); }, this.pollingInterval); } diff --git a/packages/relay/src/lib/services/debugService/IDebugService.ts b/packages/relay/src/lib/services/debugService/IDebugService.ts index 5ea9c484ee..d93dfb81da 100644 --- a/packages/relay/src/lib/services/debugService/IDebugService.ts +++ b/packages/relay/src/lib/services/debugService/IDebugService.ts @@ -20,13 +20,14 @@ import { ITracerConfig } from '../../types'; import type { TracerType } from '../../constants'; +import { IRequestDetails } from '../../types/IRequestDetails'; export interface IDebugService { debug_traceTransaction: ( transactionIdOrHash: string, tracer: TracerType, tracerConfig: ITracerConfig, - requestIdPrefix: string, + requestDetails: IRequestDetails, ) => Promise; resolveAddress: (address: string, requestIdPrefix: string, types?: string[]) => Promise; } diff --git a/packages/relay/src/lib/services/debugService/index.ts b/packages/relay/src/lib/services/debugService/index.ts index 669a18b0ba..360c3f31fd 100644 --- a/packages/relay/src/lib/services/debugService/index.ts +++ b/packages/relay/src/lib/services/debugService/index.ts @@ -29,6 +29,7 @@ import { EthImpl } from '../../eth'; import { IOpcodesResponse } from '../../clients/models/IOpcodesResponse'; import { IOpcode } from '../../clients/models/IOpcode'; import { ICallTracerConfig, IOpcodeLoggerConfig, ITracerConfig } from '../../types'; +import { IRequestDetails } from '../../types/IRequestDetails'; /** * Represents a DebugService for tracing and debugging transactions and debugging @@ -99,8 +100,9 @@ export class DebugService implements IDebugService { transactionIdOrHash: string, tracer: TracerType, tracerConfig: ITracerConfig, - requestIdPrefix: string, + requestDetails: IRequestDetails, ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} debug_traceTransaction(${transactionIdOrHash})`); try { DebugService.requireDebugAPIEnabled(); diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index 459637cf5d..bc47741941 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -115,7 +115,10 @@ app.getKoaApp().use(async (ctx, next) => { app.getKoaApp().use(async (ctx, next) => { if (ctx.url === '/health/readiness') { try { - const result = relay.eth().chainId(); + const result = relay.eth().chainId({ + requestIdPrefix: ctx.state.reqId, + requestIp: ctx.request.ip, + } as IRequestDetails); if (result.indexOf('0x12') >= 0) { ctx.status = 200; ctx.body = 'OK'; @@ -206,17 +209,6 @@ const logAndHandleResponse = async (methodName: string, methodParams: any[], met logger.debug('Request ip' + requestIp); const requestIdPrefix = requestId ? formatRequestIdMessage(requestId) : ''; const requestDetails: IRequestDetails = { requestIdPrefix, requestIp }; - const methodsToPassRequestDetails = [ - 'eth_getCode', - 'eth_call', - 'eth_sendRawTransaction', - 'eth_feeHistory', - 'eth_getTransactionReceipt', - 'eth_getBlockByNumber', - 'eth_estimateGas', - 'eth_getBlockByHash', - 'eth_gasPrice', - ]; try { const methodValidations = Validator.METHODS[methodName]; @@ -226,9 +218,7 @@ const logAndHandleResponse = async (methodName: string, methodParams: any[], met ); Validator.validateParams(methodParams, methodValidations); } - - const passRequestDetails = methodsToPassRequestDetails.includes(methodName); - const response = await methodFunction(passRequestDetails ? requestDetails : requestIdPrefix); + const response = await methodFunction(requestDetails); if (response instanceof JsonRpcError) { // log error only if it is not a contract revert, otherwise log it as debug if (response.code === predefined.CONTRACT_REVERT().code) { @@ -291,7 +281,7 @@ app.useRpc('net_version', async () => { * returns: Block number - hex encoded integer */ app.useRpc('eth_blockNumber', async () => { - return logAndHandleResponse('eth_blockNumber', [], (requestId) => relay.eth().blockNumber(requestId)); + return logAndHandleResponse('eth_blockNumber', [], (requestDetails) => relay.eth().blockNumber(requestDetails)); }); /** @@ -306,8 +296,8 @@ app.useRpc('eth_estimateGas', async (params: any) => { delete params[0].data; } - return logAndHandleResponse('eth_estimateGas', params, (requestId) => - relay.eth().estimateGas(params?.[0], params?.[1], requestId), + return logAndHandleResponse('eth_estimateGas', params, (requestDetails) => + relay.eth().estimateGas(params?.[0], params?.[1], requestDetails), ); }); @@ -319,8 +309,8 @@ app.useRpc('eth_estimateGas', async (params: any) => { * returns: Balance - hex encoded integer */ app.useRpc('eth_getBalance', async (params: any) => { - return logAndHandleResponse('eth_getBalance', params, (requestId) => - relay.eth().getBalance(params?.[0], params?.[1], requestId), + return logAndHandleResponse('eth_getBalance', params, (requestDetails) => + relay.eth().getBalance(params?.[0], params?.[1], requestDetails), ); }); @@ -343,7 +333,7 @@ app.useRpc('eth_getCode', async (params: any) => { * returns: Chain ID - integer */ app.useRpc('eth_chainId', async () => { - return logAndHandleResponse('eth_chainId', [], (requestId) => relay.eth().chainId(requestId)); + return logAndHandleResponse('eth_chainId', [], (requestDetails) => relay.eth().chainId(requestDetails)); }); /** @@ -389,8 +379,8 @@ app.useRpc('eth_gasPrice', async () => { * returns: Transaction count - hex encoded integer */ app.useRpc('eth_getTransactionCount', async (params: any) => { - return logAndHandleResponse('eth_getTransactionCount', params, (requestId) => - relay.eth().getTransactionCount(params?.[0], params?.[1], requestId), + return logAndHandleResponse('eth_getTransactionCount', params, (requestDetails) => + relay.eth().getTransactionCount(params?.[0], params?.[1], requestDetails), ); }); @@ -440,7 +430,7 @@ app.useRpc('web3_clientVersion', async () => { * returns: Accounts - hex encoded address */ app.useRpc('eth_accounts', async () => { - return logAndHandleResponse('eth_accounts', [], (requestId) => relay.eth().accounts(requestId)); + return logAndHandleResponse('eth_accounts', [], (requestDetails) => relay.eth().accounts(requestDetails)); }); /** @@ -450,8 +440,8 @@ app.useRpc('eth_accounts', async () => { * returns: Transaction Object */ app.useRpc('eth_getTransactionByHash', async (params: any) => { - return logAndHandleResponse('eth_getTransactionByHash', params, (requestId) => - relay.eth().getTransactionByHash(params[0], requestId), + return logAndHandleResponse('eth_getTransactionByHash', params, (requestDetails) => + relay.eth().getTransactionByHash(params[0], requestDetails), ); }); @@ -480,8 +470,8 @@ app.useRpc('eth_feeHistory', async (params: any) => { * returns: Block Transaction Count - Hex encoded integer */ app.useRpc('eth_getBlockTransactionCountByHash', async (params: any) => { - return logAndHandleResponse('eth_getBlockTransactionCountByHash', params, (requestId) => - relay.eth().getBlockTransactionCountByHash(params?.[0], requestId), + return logAndHandleResponse('eth_getBlockTransactionCountByHash', params, (requestDetails) => + relay.eth().getBlockTransactionCountByHash(params?.[0], requestDetails), ); }); @@ -492,8 +482,8 @@ app.useRpc('eth_getBlockTransactionCountByHash', async (params: any) => { * returns: Block Transaction Count - Hex encoded integer */ app.useRpc('eth_getBlockTransactionCountByNumber', async (params: any) => { - return logAndHandleResponse('eth_getBlockTransactionCountByNumber', params, (requestId) => - relay.eth().getBlockTransactionCountByNumber(params?.[0], requestId), + return logAndHandleResponse('eth_getBlockTransactionCountByNumber', params, (requestDetails) => + relay.eth().getBlockTransactionCountByNumber(params?.[0], requestDetails), ); }); @@ -506,8 +496,10 @@ app.useRpc('eth_getBlockTransactionCountByNumber', async (params: any) => { app.useRpc('eth_getLogs', async (params: any) => { const filter = params[0]; - return logAndHandleResponse('eth_getLogs', params, (requestId) => - relay.eth().getLogs(filter.blockHash, filter.fromBlock, filter.toBlock, filter.address, filter.topics, requestId), + return logAndHandleResponse('eth_getLogs', params, (requestDetails) => + relay + .eth() + .getLogs(filter.blockHash, filter.fromBlock, filter.toBlock, filter.address, filter.topics, requestDetails), ); }); @@ -520,8 +512,8 @@ app.useRpc('eth_getLogs', async (params: any) => { * returns: Value - The storage value */ app.useRpc('eth_getStorageAt', async (params: any) => { - return logAndHandleResponse('eth_getStorageAt', params, (requestId) => - relay.eth().getStorageAt(params?.[0], params?.[1], requestId, params?.[2]), + return logAndHandleResponse('eth_getStorageAt', params, (requestDetails) => + relay.eth().getStorageAt(params?.[0], params?.[1], requestDetails, params?.[2]), ); }); @@ -533,8 +525,8 @@ app.useRpc('eth_getStorageAt', async (params: any) => { * returns: Transaction */ app.useRpc('eth_getTransactionByBlockHashAndIndex', async (params: any) => { - return logAndHandleResponse('eth_getTransactionByBlockHashAndIndex', params, (requestId) => - relay.eth().getTransactionByBlockHashAndIndex(params?.[0], params?.[1], requestId), + return logAndHandleResponse('eth_getTransactionByBlockHashAndIndex', params, (requestDetails) => + relay.eth().getTransactionByBlockHashAndIndex(params?.[0], params?.[1], requestDetails), ); }); @@ -546,8 +538,8 @@ app.useRpc('eth_getTransactionByBlockHashAndIndex', async (params: any) => { * returns: Transaction */ app.useRpc('eth_getTransactionByBlockNumberAndIndex', async (params: any) => { - return logAndHandleResponse('eth_getTransactionByBlockNumberAndIndex', params, (requestId) => - relay.eth().getTransactionByBlockNumberAndIndex(params?.[0], params?.[1], requestId), + return logAndHandleResponse('eth_getTransactionByBlockNumberAndIndex', params, (requestDetails) => + relay.eth().getTransactionByBlockNumberAndIndex(params?.[0], params?.[1], requestDetails), ); }); @@ -561,8 +553,8 @@ app.useRpc('eth_getTransactionByBlockNumberAndIndex', async (params: any) => { * returns: null */ app.useRpc('eth_getUncleByBlockHashAndIndex', async () => { - return logAndHandleResponse('eth_getUncleByBlockHashAndIndex', [], (requestId) => - relay.eth().getUncleByBlockHashAndIndex(requestId), + return logAndHandleResponse('eth_getUncleByBlockHashAndIndex', [], (requestDetails) => + relay.eth().getUncleByBlockHashAndIndex(requestDetails), ); }); @@ -575,8 +567,8 @@ app.useRpc('eth_getUncleByBlockHashAndIndex', async () => { * returns: null */ app.useRpc('eth_getUncleByBlockNumberAndIndex', async () => { - return logAndHandleResponse('eth_getUncleByBlockNumberAndIndex', [], (requestId) => - relay.eth().getUncleByBlockNumberAndIndex(requestId), + return logAndHandleResponse('eth_getUncleByBlockNumberAndIndex', [], (requestDetails) => + relay.eth().getUncleByBlockNumberAndIndex(requestDetails), ); }); @@ -588,8 +580,8 @@ app.useRpc('eth_getUncleByBlockNumberAndIndex', async () => { * returns: 0x0 */ app.useRpc('eth_getUncleCountByBlockHash', async () => { - return logAndHandleResponse('eth_getUncleCountByBlockHash', [], (requestId) => - relay.eth().getUncleCountByBlockHash(requestId), + return logAndHandleResponse('eth_getUncleCountByBlockHash', [], (requestDetails) => + relay.eth().getUncleCountByBlockHash(requestDetails), ); }); @@ -601,8 +593,8 @@ app.useRpc('eth_getUncleCountByBlockHash', async () => { * returns: 0x0 */ app.useRpc('eth_getUncleCountByBlockNumber', async () => { - return logAndHandleResponse('eth_getUncleCountByBlockNumber', [], (requestId) => - relay.eth().getUncleCountByBlockNumber(requestId), + return logAndHandleResponse('eth_getUncleCountByBlockNumber', [], (requestDetails) => + relay.eth().getUncleCountByBlockNumber(requestDetails), ); }); @@ -613,7 +605,7 @@ app.useRpc('eth_getUncleCountByBlockNumber', async () => { * returns: code: -32000 */ app.useRpc('eth_getWork', async () => { - return logAndHandleResponse('eth_getWork', [], (requestId) => relay.eth().getWork(requestId)); + return logAndHandleResponse('eth_getWork', [], (requestDetails) => relay.eth().getWork(requestDetails)); }); /** @@ -624,7 +616,7 @@ app.useRpc('eth_getWork', async () => { * returns: 0x0 */ app.useRpc('eth_hashrate', async () => { - return logAndHandleResponse('eth_hashrate', [], (requestId) => relay.eth().hashrate(requestId)); + return logAndHandleResponse('eth_hashrate', [], (requestDetails) => relay.eth().hashrate(requestDetails)); }); /** @@ -635,7 +627,7 @@ app.useRpc('eth_hashrate', async () => { * returns: false */ app.useRpc('eth_mining', async () => { - return logAndHandleResponse('eth_mining', [], (requestId) => relay.eth().mining(requestId)); + return logAndHandleResponse('eth_mining', [], (requestDetails) => relay.eth().mining(requestDetails)); }); /** @@ -646,7 +638,7 @@ app.useRpc('eth_mining', async () => { * returns: false */ app.useRpc('eth_submitWork', async () => { - return logAndHandleResponse('eth_submitWork', [], (requestId) => relay.eth().submitWork(requestId)); + return logAndHandleResponse('eth_submitWork', [], (requestDetails) => relay.eth().submitWork(requestDetails)); }); /** @@ -656,7 +648,7 @@ app.useRpc('eth_submitWork', async () => { * returns: false */ app.useRpc('eth_syncing', async () => { - return logAndHandleResponse('eth_syncing', [], (requestId) => relay.eth().syncing(requestId)); + return logAndHandleResponse('eth_syncing', [], (requestDetails) => relay.eth().syncing(requestDetails)); }); /** @@ -677,8 +669,8 @@ app.useRpc('web3_client_version', async () => { * returns: 0x0 */ app.useRpc('eth_maxPriorityFeePerGas', async () => { - return logAndHandleResponse('eth_maxPriorityFeePerGas', [], (requestId) => - relay.eth().maxPriorityFeePerGas(requestId), + return logAndHandleResponse('eth_maxPriorityFeePerGas', [], (requestDetails) => + relay.eth().maxPriorityFeePerGas(requestDetails), ); }); @@ -687,7 +679,7 @@ app.useRpc('eth_maxPriorityFeePerGas', async () => { */ app.useRpc('debug_traceTransaction', async (params: any) => { - return logAndHandleResponse('debug_traceTransaction', params, (requestId: string) => { + return logAndHandleResponse('debug_traceTransaction', params, (requestDetails: IRequestDetails) => { const transactionIdOrHash = params[0]; let tracer: TracerType = TracerType.OpcodeLogger; let tracerConfig: ITracerConfig = {}; @@ -709,7 +701,7 @@ app.useRpc('debug_traceTransaction', async (params: any) => { } } - return relay.eth().debugService().debug_traceTransaction(transactionIdOrHash, tracer, tracerConfig, requestId); + return relay.eth().debugService().debug_traceTransaction(transactionIdOrHash, tracer, tracerConfig, requestDetails); }); }); @@ -724,27 +716,27 @@ app.useRpc('debug_traceTransaction', async (params: any) => { */ app.useRpc('eth_newFilter', async (params: any) => { const filter = params[0]; - return logAndHandleResponse('eth_newFilter', [], (requestId) => + return logAndHandleResponse('eth_newFilter', [], (requestDetails) => relay .eth() .filterService() - .newFilter(filter?.fromBlock, filter?.toBlock, requestId, filter?.address, filter?.topics), + .newFilter(filter?.fromBlock, filter?.toBlock, requestDetails, filter?.address, filter?.topics), ); }); app.useRpc('eth_getFilterLogs', async (params: any) => { - return logAndHandleResponse('eth_getFilterLogs', params, (requestId) => + return logAndHandleResponse('eth_getFilterLogs', params, (requestDetails) => relay .eth() .filterService() - .getFilterLogs(params?.[0], requestId), + .getFilterLogs(params?.[0], requestDetails), ); }); app.useRpc('eth_getFilterChanges', async (params: any) => { const filterId = params[0]; - return logAndHandleResponse('eth_getFilterChanges', [], (requestId) => - relay.eth().filterService().getFilterChanges(filterId, requestId), + return logAndHandleResponse('eth_getFilterChanges', [], (requestDetails) => + relay.eth().filterService().getFilterChanges(filterId, requestDetails), ); }); @@ -754,8 +746,8 @@ app.useRpc('eth_getFilterChanges', async (params: any) => { * returns: string */ app.useRpc('eth_newBlockFilter', async (params: any) => { - return logAndHandleResponse('eth_newBlockFilter', [], (requestId) => - relay.eth().filterService().newBlockFilter(requestId), + return logAndHandleResponse('eth_newBlockFilter', [], (requestDetails) => + relay.eth().filterService().newBlockFilter(requestDetails), ); }); @@ -763,8 +755,8 @@ app.useRpc('eth_newBlockFilter', async (params: any) => { * Not Supported */ app.useRpc('eth_newPendingTransactionFilter', async () => { - return logAndHandleResponse('eth_newPendingTransactionFilter', [], (requestId) => - relay.eth().filterService().newPendingTransactionFilter(requestId), + return logAndHandleResponse('eth_newPendingTransactionFilter', [], (requestDetails) => + relay.eth().filterService().newPendingTransactionFilter(requestDetails), ); }); @@ -775,11 +767,11 @@ app.useRpc('eth_newPendingTransactionFilter', async () => { * returns: boolean */ app.useRpc('eth_uninstallFilter', async (params: any) => { - return logAndHandleResponse('eth_uninstallFilter', params, (requestId) => + return logAndHandleResponse('eth_uninstallFilter', params, (requestDetails) => relay .eth() .filterService() - .uninstallFilter(params?.[0], requestId), + .uninstallFilter(params?.[0], requestDetails), ); }); @@ -787,27 +779,33 @@ app.useRpc('eth_uninstallFilter', async (params: any) => { * Not supported */ app.useRpc('eth_submitHashrate', async () => { - return logAndHandleResponse('eth_submitHashrate', [], (requestId) => relay.eth().submitHashrate(requestId)); + return logAndHandleResponse('eth_submitHashrate', [], (requestDetails) => relay.eth().submitHashrate(requestDetails)); }); app.useRpc('eth_signTransaction', async () => { - return logAndHandleResponse('eth_signTransaction', [], (requestId) => relay.eth().signTransaction(requestId)); + return logAndHandleResponse('eth_signTransaction', [], (requestDetails) => + relay.eth().signTransaction(requestDetails), + ); }); app.useRpc('eth_sign', async () => { - return logAndHandleResponse('eth_sign', [], (requestId) => relay.eth().sign(requestId)); + return logAndHandleResponse('eth_sign', [], (requestDetails) => relay.eth().sign(requestDetails)); }); app.useRpc('eth_sendTransaction', async () => { - return logAndHandleResponse('eth_sendTransaction', [], (requestId) => relay.eth().sendTransaction(requestId)); + return logAndHandleResponse('eth_sendTransaction', [], (requestDetails) => + relay.eth().sendTransaction(requestDetails), + ); }); app.useRpc('eth_protocolVersion', async () => { - return logAndHandleResponse('eth_protocolVersion', [], (requestId) => relay.eth().protocolVersion(requestId)); + return logAndHandleResponse('eth_protocolVersion', [], (requestDetails) => + relay.eth().protocolVersion(requestDetails), + ); }); app.useRpc('eth_coinbase', async () => { - return logAndHandleResponse('eth_coinbase', [], (requestId) => relay.eth().coinbase(requestId)); + return logAndHandleResponse('eth_coinbase', [], (requestDetails) => relay.eth().coinbase(requestDetails)); }); const rpcApp = app.rpcApp(); From 029aea2e3315f43c655664d84567daf1ac73991d Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Tue, 10 Sep 2024 21:41:45 +0300 Subject: [PATCH 13/48] Fixes unit tests after passing requestDetails to all methods in server Signed-off-by: Konstantina Blazhukova --- packages/relay/src/index.ts | 2 +- packages/relay/src/lib/eth.ts | 2 +- .../relay/tests/lib/eth/eth_common.spec.ts | 30 ++++++------ .../lib/eth/eth_getBlockByNumber.spec.ts | 22 ++++----- ...eth_getBlockTransactionCountByHash.spec.ts | 10 ++-- ...h_getBlockTransactionCountByNumber.spec.ts | 22 +++++---- .../relay/tests/lib/eth/eth_getCode.spec.ts | 2 +- .../relay/tests/lib/eth/eth_getLogs.spec.ts | 46 ++++++++----------- .../tests/lib/eth/eth_getStorageAt.spec.ts | 27 ++++++----- ..._getTransactionByBlockHashAndIndex.spec.ts | 16 +++---- ...etTransactionByBlockNumberAndIndex.spec.ts | 23 +++++----- .../lib/eth/eth_getTransactionByHash.spec.ts | 33 ++++++------- .../lib/eth/eth_getTransactionCount.spec.ts | 37 +++++++-------- packages/relay/tests/lib/precheck.spec.ts | 7 +-- 14 files changed, 141 insertions(+), 138 deletions(-) diff --git a/packages/relay/src/index.ts b/packages/relay/src/index.ts index 6b4bf69581..23d870a40b 100644 --- a/packages/relay/src/index.ts +++ b/packages/relay/src/index.ts @@ -101,9 +101,9 @@ export interface Eth { ): Promise; getStorageAt( - requestDetails: IRequestDetails, address: string, slot: string, + requestDetails: IRequestDetails, blockNumber: string | null, ): Promise; diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 00158e07a0..c623708d85 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -901,9 +901,9 @@ export class EthImpl implements Eth { * @param requestIdPrefix */ async getStorageAt( - requestDetails: IRequestDetails, address: string, slot: string, + requestDetails: IRequestDetails, blockNumberOrTagOrHash?: string | null, ): Promise { const requestIdPrefix = requestDetails.requestIdPrefix; diff --git a/packages/relay/tests/lib/eth/eth_common.spec.ts b/packages/relay/tests/lib/eth/eth_common.spec.ts index ee598c0cf1..842b21d3fc 100644 --- a/packages/relay/tests/lib/eth/eth_common.spec.ts +++ b/packages/relay/tests/lib/eth/eth_common.spec.ts @@ -24,16 +24,20 @@ import { Registry } from 'prom-client'; import pino from 'pino'; import chaiAsPromised from 'chai-as-promised'; import { RelayImpl } from '../../../src/lib/relay'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); describe('@ethCommon', async function () { let Relay: any; - + let requestIdPrefix: string; + let requestDetails: IRequestDetails; this.timeout(10000); this.beforeAll(() => { + requestIdPrefix = `[Request ID: eth_common]`; + requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; const logger = pino(); const registry = new Registry(); Relay = new RelayImpl(logger, registry); @@ -41,60 +45,60 @@ describe('@ethCommon', async function () { describe('@ethCommon', async function () { it('should execute "eth_chainId"', async function () { - const chainId = Relay.eth().chainId(); + const chainId = Relay.eth().chainId(requestDetails); expect(chainId).to.be.equal('0x' + Number(process.env.CHAIN_ID).toString(16)); }); it('should execute "eth_accounts"', async function () { - const accounts = Relay.eth().accounts(); + const accounts = Relay.eth().accounts(requestDetails); expect(accounts).to.be.an('Array'); expect(accounts.length).to.be.equal(0); }); it('should execute "eth_getUncleByBlockHashAndIndex"', async function () { - const result = await Relay.eth().getUncleByBlockHashAndIndex(); + const result = await Relay.eth().getUncleByBlockHashAndIndex(requestDetails); expect(result).to.be.null; }); it('should execute "eth_getUncleByBlockNumberAndIndex"', async function () { - const result = await Relay.eth().getUncleByBlockNumberAndIndex(); + const result = await Relay.eth().getUncleByBlockNumberAndIndex(requestDetails); expect(result).to.be.null; }); it('should execute "eth_getUncleCountByBlockHash"', async function () { - const result = await Relay.eth().getUncleCountByBlockHash(); + const result = await Relay.eth().getUncleCountByBlockHash(requestDetails); expect(result).to.eq('0x0'); }); it('should execute "eth_getUncleCountByBlockNumber"', async function () { - const result = await Relay.eth().getUncleCountByBlockNumber(); + const result = await Relay.eth().getUncleCountByBlockNumber(requestDetails); expect(result).to.eq('0x0'); }); it('should execute "eth_hashrate"', async function () { - const result = await Relay.eth().hashrate(); + const result = await Relay.eth().hashrate(requestDetails); expect(result).to.eq('0x0'); }); it('should execute "eth_mining"', async function () { - const result = await Relay.eth().mining(); + const result = await Relay.eth().mining(requestDetails); expect(result).to.eq(false); }); it('should execute "eth_submitWork"', async function () { - const result = await Relay.eth().submitWork(); + const result = await Relay.eth().submitWork(requestDetails); expect(result).to.eq(false); }); it('should execute "eth_syncing"', async function () { - const result = await Relay.eth().syncing(); + const result = await Relay.eth().syncing(requestDetails); expect(result).to.eq(false); }); it('should execute "eth_getWork"', async function () { - const result = Relay.eth().getWork(); + const result = Relay.eth().getWork(requestDetails); expect(result).to.have.property('code'); expect(result.code).to.be.equal(-32601); expect(result).to.have.property('message'); @@ -102,7 +106,7 @@ describe('@ethCommon', async function () { }); it('should execute "eth_maxPriorityFeePerGas"', async function () { - const result = await Relay.eth().maxPriorityFeePerGas(); + const result = await Relay.eth().maxPriorityFeePerGas(requestDetails); expect(result).to.eq('0x0'); }); }); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index 0e0d45973a..13f8380929 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -87,10 +87,10 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger, registry } = generateEthTestEnv(true); + const requestIdPrefix = `[Request ID: eth_getBlockByNumberTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' } as IRequestDetails; const results = defaultContractResults.results; const TOTAL_GAS_USED = numberTo0x(results[0].gas_used + results[1].gas_used); - let requestIdPrefix: string; - let requestDetails: IRequestDetails; const veriftAggregatedInfo = (result) => { // verify aggregated info @@ -115,8 +115,6 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.reset(); restMock.resetHandlers(); - requestIdPrefix = `[Request ID: testId]`; - requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -151,19 +149,19 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { it('"eth_blockNumber" should return the latest block number', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); - const blockNumber = await ethImpl.blockNumber(requestIdPrefix); + const blockNumber = await ethImpl.blockNumber(requestDetails); expect(blockNumber).to.be.eq(blockNumber); }); it('"eth_blockNumber" should return the latest block number using cache', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); - const blockNumber = await ethImpl.blockNumber(requestIdPrefix); + const blockNumber = await ethImpl.blockNumber(requestDetails); expect(numberTo0x(DEFAULT_BLOCK.number)).to.be.eq(blockNumber); // Second call should return the same block number using cache restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(400, DEFAULT_BLOCKS_RES); - const blockNumber2 = await ethImpl.blockNumber(requestIdPrefix); + const blockNumber2 = await ethImpl.blockNumber(requestDetails); expect(blockNumber2).to.be.eq(blockNumber); // expire cache, instead of waiting for ttl we clear it to simulate expiry faster. @@ -173,14 +171,14 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [{ ...DEFAULT_BLOCK, number: newBlockNumber }], }); - const blockNumber3 = await ethImpl.blockNumber(requestIdPrefix); + const blockNumber3 = await ethImpl.blockNumber(requestDetails); expect(numberTo0x(newBlockNumber)).to.be.eq(blockNumber3); }); - it('"eth_blockNumber" should throw an error if no blocks are found', async function () { + it.only('"eth_blockNumber" should throw an error if no blocks are found', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(404, BLOCK_NOT_FOUND_RES); const error = predefined.COULD_NOT_RETRIEVE_LATEST_BLOCK; - await RelayAssertions.assertRejection(error, ethImpl.blockNumber, true, ethImpl); + await RelayAssertions.assertRejection(error, ethImpl.blockNumber, true, ethImpl, [requestDetails]); }); it('"eth_blockNumber" return the latest block number on second try', async function () { @@ -191,9 +189,9 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { .replyOnce(200, DEFAULT_BLOCKS_RES); try { - await ethImpl.blockNumber(requestIdPrefix); + await ethImpl.blockNumber(requestDetails); } catch (error) {} - const blockNumber = await ethImpl.blockNumber(requestIdPrefix); + const blockNumber = await ethImpl.blockNumber(requestDetails); expect(blockNumber).to.be.eq(blockNumber); }); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts index b35a42129b..3757c13d87 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts @@ -33,6 +33,7 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -43,7 +44,8 @@ let getSdkClientStub; describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: eth_getBlockTransactionCountByHashTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' } as IRequestDetails; this.beforeEach(() => { // reset cache and restMock @@ -64,7 +66,7 @@ describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function ( // mirror node request mocks restMock.onGet(`blocks/${BLOCK_HASH}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -72,7 +74,7 @@ describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function ( restMock.onGet(`blocks/${BLOCK_HASH}`).replyOnce(200, DEFAULT_BLOCK); for (let i = 0; i < 3; i++) { - const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); } }); @@ -81,7 +83,7 @@ describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function ( // mirror node request mocks restMock.onGet(`blocks/${BLOCK_HASH}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); - const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByHash(BLOCK_HASH, requestDetails); expect(result).to.equal(null); }); }); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts index ccd1017de2..d600b145df 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts @@ -35,6 +35,7 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; +import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -45,7 +46,8 @@ let getSdkClientStub; describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: eth_getBlockTransactionCountByNumberTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' } as IRequestDetails; this.beforeEach(() => { // reset cache and restMock @@ -66,7 +68,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function // mirror node request mocks restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -74,7 +76,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(`blocks/${BLOCK_NUMBER}`).replyOnce(200, DEFAULT_BLOCK); for (let i = 0; i < 3; i++) { - const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); } }); @@ -83,7 +85,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function cacheService.clear(); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); - const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestDetails); expect(result).to.equal(null); }); @@ -92,7 +94,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('latest', requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber('latest', requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -101,7 +103,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('finalized', requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber('finalized', requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -110,7 +112,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('safe', requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber('safe', requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -119,7 +121,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('pending', requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber('pending', requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -127,7 +129,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function // mirror node request mocks restMock.onGet(`blocks/0`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('earliest', requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber('earliest', requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); @@ -135,7 +137,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function // mirror node request mocks restMock.onGet(`blocks/3735929054`).reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getBlockTransactionCountByNumber('0xdeadc0de', requestIdPrefix); + const result = await ethImpl.getBlockTransactionCountByNumber('0xdeadc0de', requestDetails); expect(result).equal(numberTo0x(BLOCK_TRANSACTION_COUNT)); }); }); diff --git a/packages/relay/tests/lib/eth/eth_getCode.spec.ts b/packages/relay/tests/lib/eth/eth_getCode.spec.ts index 3fdba8f7bb..0836361b26 100644 --- a/packages/relay/tests/lib/eth/eth_getCode.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getCode.spec.ts @@ -51,7 +51,7 @@ describe('@ethGetCode using MirrorNode', async function () { let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); let validBlockParam = [null, 'earliest', 'latest', 'pending', 'finalized', 'safe', '0x0', '0x369ABF']; let invalidBlockParam = ['hedera', 'ethereum', '0xhbar', '0x369ABF369ABF369ABF369ABF']; - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: eth_getCodeTest]`; const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; this.beforeEach(() => { diff --git a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts index 52aa77008b..ccace7a1b4 100644 --- a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts @@ -81,7 +81,8 @@ describe('@ethGetLogs using MirrorNode', async function () { logs: [DEFAULT_LOGS.logs[0], DEFAULT_LOGS.logs[1]], }; - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: eth_getLogsTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; this.beforeEach(() => { // reset cache and restMock @@ -131,7 +132,7 @@ describe('@ethGetLogs using MirrorNode', async function () { let errorReceived = false; try { - await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); + await ethImpl.getLogs(null, null, null, null, null, requestDetails); } catch (error) { errorReceived = true; expect(error.statusCode).to.equal(400); @@ -156,7 +157,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, { ...DEFAULT_CONTRACT, contract_id: `0.0.105${index}` }); }); - const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); expect(result).to.exist; expect(result.length).to.eq(4); @@ -181,7 +182,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, { ...DEFAULT_CONTRACT, contract_id: `0.0.105${index}` }); }); - const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); expect(result).to.exist; expect(result.length).to.eq(4); @@ -229,7 +230,7 @@ describe('@ethGetLogs using MirrorNode', async function () { }); //setting mirror node limit to 2 for this test only process.env['MIRROR_NODE_LIMIT_PARAM'] = '2'; - const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); //resetting mirror node limit to 100 process.env['MIRROR_NODE_LIMIT_PARAM'] = '100'; expect(result).to.exist; @@ -257,7 +258,7 @@ describe('@ethGetLogs using MirrorNode', async function () { .onGet(`contracts/${filteredLogs.logs[0].address}`) .reply(200, { ...DEFAULT_CONTRACT, evm_address: defaultEvmAddress }); - const result = await ethImpl.getLogs(null, null, null, null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); expect(result).to.exist; expect(result.length).to.eq(1); @@ -274,7 +275,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, CONTRACT_ADDRESS_1, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, null, null, CONTRACT_ADDRESS_1, null, requestDetails); expect(result).to.exist; @@ -312,7 +313,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet('blocks/1').reply(200, fromBlock); restMock.onGet('blocks/1003').reply(200, toBlock); - const result = await ethImpl.getLogs(null, '0x1', '0x3eb', address, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, '0x1', '0x3eb', address, null, requestDetails); expect(result).to.exist; @@ -371,7 +372,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(BLOCK_HASH, null, null, null, null, requestIdPrefix); + const result = await ethImpl.getLogs(BLOCK_HASH, null, null, null, null, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -403,7 +404,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -416,7 +417,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet('blocks/5').reply(200, DEFAULT_BLOCK); restMock.onGet('blocks/16').reply(404, NOT_FOUND_RES); - const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null, requestDetails); expect(result).to.exist; expect(result).to.be.empty; @@ -435,7 +436,7 @@ describe('@ethGetLogs using MirrorNode', async function () { .reply(200, filteredLogs); restMock.onGet(`contracts/${filteredLogs.logs[0].address}`).reply(200, DEFAULT_CONTRACT); - const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, '0x5', '0x10', null, null, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -454,7 +455,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [latestBlock] }); restMock.onGet('blocks/16').reply(200, fromBlock); restMock.onGet('blocks/5').reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, '0x10', '0x5', null, null, requestDetails); expect(result).to.exist; expect(result).to.be.empty; @@ -481,7 +482,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, 'latest', null, null, null, requestIdPrefix); + const result = await ethImpl.getLogs(null, 'latest', null, null, null, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -507,7 +508,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet('blocks/1').reply(200, fromBlock); restMock.onGet('blocks/1003').reply(200, toBlock); - await ethGetLogsFailing(ethImpl, [null, '0x1', '0x3eb', address, null, requestIdPrefix], (error) => { + await ethGetLogsFailing(ethImpl, [null, '0x1', '0x3eb', address, null, requestDetails], (error) => { expect(error.message).to.equal('Exceeded maximum block range: 1000'); }); }); @@ -532,7 +533,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_LOG_TOPICS, requestIdPrefix); + const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_LOG_TOPICS, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -556,7 +557,7 @@ describe('@ethGetLogs using MirrorNode', async function () { for (const log of filteredLogs.logs) { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_NULL_LOG_TOPICS, requestIdPrefix); + const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_NULL_LOG_TOPICS, requestDetails); expect(result).to.exist; expect(result[0].topics.length).to.eq(DEFAULT_LOGS_4[0].topics.length); @@ -586,7 +587,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, '0x5', '0x10', null, DEFAULT_LOG_TOPICS, requestIdPrefix); + const result = await ethImpl.getLogs(null, '0x5', '0x10', null, DEFAULT_LOG_TOPICS, requestDetails); expectLogData1(result[0]); expectLogData2(result[1]); @@ -596,14 +597,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [latestBlock] }); restMock.onGet('blocks/0').reply(200, DEFAULT_BLOCK); restMock.onGet('blocks/latest').reply(200, DEFAULT_BLOCK); - const result = await ethImpl.getLogs( - null, - '0x0', - 'latest', - ethers.ZeroAddress, - DEFAULT_LOG_TOPICS, - requestIdPrefix, - ); + const result = await ethImpl.getLogs(null, '0x0', 'latest', ethers.ZeroAddress, DEFAULT_LOG_TOPICS, requestDetails); expect(result.length).to.eq(0); expect(result).to.deep.equal([]); }); diff --git a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts index 30436e78b8..84ff4bcf7f 100644 --- a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts @@ -56,8 +56,8 @@ let currentMaxBlockRange: number; describe('@ethGetStorageAt eth_getStorageAt spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - let requestIdPrefix: string; - + const requestIdPrefix = `[Request ID: eth_getStorageAtTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; function confirmResult(result: string) { expect(result).to.exist; expect(result).to.not.be.null; @@ -69,7 +69,6 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { cacheService.clear(); restMock.reset(); - requestIdPrefix = `[Request ID: testId]`; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -95,7 +94,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { ) .reply(200, DEFAULT_CURRENT_CONTRACT_STATE); - const result = await ethImpl.getStorageAt(CONTRACT_ADDRESS_1, '0x101', requestIdPrefix, numberTo0x(BLOCK_NUMBER)); + const result = await ethImpl.getStorageAt(CONTRACT_ADDRESS_1, '0x101', requestDetails, numberTo0x(BLOCK_NUMBER)); confirmResult(result); // verify slot value @@ -113,7 +112,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, '0x0000101', - requestIdPrefix, + requestDetails, numberTo0x(BLOCK_NUMBER), ); confirmResult(result); @@ -133,7 +132,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, - requestIdPrefix, + requestDetails, numberTo0x(BLOCK_NUMBER), ); confirmResult(result); @@ -153,7 +152,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, - requestIdPrefix, + requestDetails, BLOCK_HASH, ); confirmResult(result); @@ -173,7 +172,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_CURRENT_CONTRACT_STATE.state[0].slot, - requestIdPrefix, + requestDetails, 'latest', ); confirmResult(result); @@ -192,7 +191,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_CURRENT_CONTRACT_STATE.state[0].slot, - requestIdPrefix, + requestDetails, 'finalized', ); confirmResult(result); @@ -211,7 +210,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_CURRENT_CONTRACT_STATE.state[0].slot, - requestIdPrefix, + requestDetails, 'safe', ); confirmResult(result); @@ -232,7 +231,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, - requestIdPrefix, + requestDetails, ); confirmResult(result); @@ -269,7 +268,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, wrongSlot, - requestIdPrefix, + requestDetails, numberTo0x(BLOCK_NUMBER), ); expect(result).to.equal(EthImpl.zeroHex32Byte); @@ -286,7 +285,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_OLDER_CONTRACT_STATE.state[0].slot, - requestIdPrefix, + requestDetails, numberTo0x(OLDER_BLOCK.number), ); expect(result).to.equal(DEFAULT_OLDER_CONTRACT_STATE.state[0].value); @@ -303,7 +302,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const result = await ethImpl.getStorageAt( CONTRACT_ADDRESS_1, DEFAULT_OLDER_CONTRACT_STATE.state[0].slot, - requestIdPrefix, + requestDetails, numberTo0x(OLDER_BLOCK.number), ); expect(result).to.equal(ethers.ZeroHash); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts index c941d30b65..cf468fac44 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts @@ -51,8 +51,8 @@ dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); let sdkClientStub; -let getSdkClientStub; -const requestIdPrefix = `[Request ID: testId]`; +const requestIdPrefix = `[Request ID: eth_getTransactionByBlockHashAndIndexTest]`; +const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; function verifyAggregatedInfo(result: Transaction | null) { // verify aggregated info @@ -104,7 +104,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash, numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.exist; expect(result).to.not.be.null; @@ -142,7 +142,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.equal(null); }); @@ -153,7 +153,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.equal(null); }); @@ -171,7 +171,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.be.an.instanceOf(Transaction); }); @@ -190,7 +190,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.be.an.instanceOf(Transaction2930); }); @@ -211,7 +211,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio const result = await ethImpl.getTransactionByBlockHashAndIndex( DEFAULT_BLOCK.hash.toString(), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.be.an.instanceOf(Transaction1559); }); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts index 1e3b32084f..8735b5e0d9 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts @@ -65,7 +65,8 @@ function verifyAggregatedInfo(result: Transaction | null) { describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: eth_getTransactionByBlockNumberAndIndexTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; this.beforeEach(() => { // reset cache and restMock cacheService.clear(); @@ -103,7 +104,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(DEFAULT_BLOCK.number), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); verifyAggregatedInfo(result); @@ -124,7 +125,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(randomBlock.number), numberTo0x(randomBlock.count), - requestIdPrefix, + requestDetails, ); expect(result).to.exist; expect(result).to.not.be.null; @@ -143,7 +144,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(DEFAULT_BLOCK.number), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.equal(null); }); @@ -179,7 +180,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(DEFAULT_BLOCK.number), numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); expect(result).to.equal(null); }); @@ -194,7 +195,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( 'latest', numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); verifyAggregatedInfo(result); }); @@ -209,7 +210,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( 'finalized', numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); verifyAggregatedInfo(result); }); @@ -224,7 +225,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( 'safe', numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); verifyAggregatedInfo(result); }); @@ -239,7 +240,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( 'pending', numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); verifyAggregatedInfo(result); }); @@ -251,7 +252,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( 'earliest', numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); verifyAggregatedInfo(result); }); @@ -264,7 +265,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct const result = await ethImpl.getTransactionByBlockNumberAndIndex( '0xdeadc0de' + '', numberTo0x(DEFAULT_BLOCK.count), - requestIdPrefix, + requestDetails, ); verifyAggregatedInfo(result); }); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts index 54975e48f8..87b8900b5b 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts @@ -78,7 +78,8 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi v: 1, nonce: 9, }; - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: eth_getTransactionByHashTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; this.beforeEach(function () { restMock.reset(); @@ -97,7 +98,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi type: 0, }); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.be.an.instanceOf(Transaction); }); @@ -109,7 +110,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi access_list: [], }); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.be.an.instanceOf(Transaction2930); }); @@ -123,7 +124,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi max_priority_fee_per_gas: '0x47', }); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.be.an.instanceOf(Transaction1559); }); @@ -134,21 +135,21 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi .onGet(`contracts/results/logs?transaction.hash=${uniqueTxHash}&limit=100&order=asc`) .reply(200, EMPTY_LOGS_RESPONSE); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.equal(null); }); it('account should be cached', async function () { restMock.onGet(`contracts/results/${DEFAULT_TX_HASH}`).reply(200, defaultDetailedContractResultByHash); - const resBeforeCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); + const resBeforeCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestDetails); restMock.onGet(`accounts/${defaultFromLongZeroAddress}${NO_TRANSACTIONS}`).reply(404); - const resAfterCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); + const resAfterCache = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestDetails); expect(resBeforeCache).to.deep.equal(resAfterCache); }); it('returns correct transaction for existing hash', async function () { restMock.onGet(`contracts/results/${DEFAULT_TX_HASH}`).reply(200, defaultDetailedContractResultByHash); - const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestDetails); RelayAssertions.assertTransaction(result, { ...DEFAULT_TRANSACTION, maxFeePerGas: '0x55', @@ -166,7 +167,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x97cad7b827375d12d73af57b6a3f84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithZeroXZeroValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); RelayAssertions.assertTransaction(result, { ...DEFAULT_TRANSACTION, maxFeePerGas: '0x55', @@ -184,7 +185,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.not.be.null; expect(result).to.exist; @@ -199,7 +200,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x0aaad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.not.be.null; expect(result).to.exist; @@ -215,7 +216,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0xb4cad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640533'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.not.be.null; expect(result).to.exist; @@ -230,7 +231,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640534'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.not.be.null; expect(result).to.exist; @@ -245,7 +246,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52dda53ec640511'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.not.be.null; expect(result).to.exist; @@ -262,7 +263,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi const uniqueTxHash = '0x14aad7b827375d12d73af57b6a3e84353645fd31305ea58ff52d1a53ec640511'; restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues); - const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(uniqueTxHash, requestDetails); expect(result).to.not.be.null; expect(result).to.exist; @@ -277,7 +278,7 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi .onGet(`contracts/results/${DEFAULT_TX_HASH}`) .reply(200, DEFAULT_DETAILED_CONTRACT_RESULT_BY_HASH_REVERTED); - const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestIdPrefix); + const result = await ethImpl.getTransactionByHash(DEFAULT_TX_HASH, requestDetails); RelayAssertions.assertTransaction(result, { ...DEFAULT_TRANSACTION, maxFeePerGas: '0x55', diff --git a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts index 40bbe046c7..b0e9306896 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts @@ -43,7 +43,8 @@ let currentMaxBlockRange: number; describe('@ethGetTransactionCount eth_getTransactionCount spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: eth_getTransactionCountTest]`; + const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; const blockNumber = mockData.blocks.blocks[2].number; const blockNumberHex = numberTo0x(blockNumber); const transactionId = '0.0.1078@1686183420.196506746'; @@ -97,7 +98,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x0 nonce for no block consideration with not found acoount', async () => { restMock.onGet(contractPath).reply(404, mockData.notFound); restMock.onGet(accountPath).reply(404, mockData.notFound); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); @@ -105,56 +106,56 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return latest nonce for no block consideration but valid account', async () => { restMock.onGet(contractPath).reply(404, mockData.notFound); restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return 0x0 nonce for block 0 consideration', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '0', requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '0', requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); it('should return 0x0 nonce for block 1 consideration', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '1', requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, '1', requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); it('should return latest nonce for latest block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return latest nonce for finalized block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockFinalized, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockFinalized, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return latest nonce for latest block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockSafe, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockSafe, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return latest nonce for pending block', async () => { restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockPending, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockPending, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); it('should return 0x0 nonce for earliest block with valid block', async () => { restMock.onGet(earliestBlockPath).reply(200, { blocks: [mockData.blocks.blocks[0]] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); @@ -200,7 +201,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(`0x${defaultDetailedContractResults.nonce + 1}`); }); @@ -233,7 +234,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function }); restMock.onGet(accountPath).reply(200, mockData.account); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); @@ -241,7 +242,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x0 nonce for historical numerical block with no ethereum transactions found', async () => { restMock.onGet(transactionPath(MOCK_ACCOUNT_ADDR, 2)).reply(200, { transactions: [] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.zeroHex); }); @@ -249,7 +250,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x1 nonce for historical numerical block with a single ethereum transactions found', async () => { restMock.onGet(transactionPath(MOCK_ACCOUNT_ADDR, 2)).reply(200, { transactions: [{}] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockNumberHex, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.oneHex); }); @@ -280,7 +281,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(3)); }); @@ -293,7 +294,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function restMock .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(mockData.account.evm_address, blockNumberHex, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce)); }); @@ -312,7 +313,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should return 0x1 for pre-hip-729 contracts with nonce=null', async () => { restMock.onGet(accountPath).reply(200, { ...mockData.account, ethereum_nonce: null }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, EthImpl.blockLatest, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(EthImpl.oneHex); }); @@ -326,7 +327,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function restMock .onGet(accountPathContractResultsAddress) .reply(200, { ...mockData.account, transactions: [defaultEthereumTransactions[0]] }); - const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockHash, requestIdPrefix); + const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, blockHash, requestDetails); expect(nonce).to.exist; expect(nonce).to.equal(numberTo0x(2)); }); diff --git a/packages/relay/tests/lib/precheck.spec.ts b/packages/relay/tests/lib/precheck.spec.ts index ceadf43e47..16b6a477d2 100644 --- a/packages/relay/tests/lib/precheck.spec.ts +++ b/packages/relay/tests/lib/precheck.spec.ts @@ -450,9 +450,9 @@ describe('Precheck', async function () { it(`should fail for missing account`, async function () { mock.onGet(`accounts/${parsedTx.from}${transactionsPostFix}`).reply(404, mockData.notFound); - + const requestId = `eth_precheckTest`; try { - await precheck.verifyAccount(parsedTx); + await precheck.verifyAccount(parsedTx, requestId); expectedError(); } catch (e: any) { expect(e).to.exist; @@ -463,7 +463,8 @@ describe('Precheck', async function () { it(`should not fail for matched account`, async function () { mock.onGet(`accounts/${parsedTx.from}${transactionsPostFix}`).reply(200, mirrorAccount); - const account = await precheck.verifyAccount(parsedTx); + const requestId = `eth_precheckTest`; + const account = await precheck.verifyAccount(parsedTx, requestId); expect(account.ethereum_nonce).to.eq(defaultNonce); }); From ec4f39b7b793abc708a3966ac715a9e0af537af0 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 11 Sep 2024 12:04:59 +0300 Subject: [PATCH 14/48] adds request details to ws server Signed-off-by: Konstantina Blazhukova --- packages/ws-server/src/controllers/index.ts | 9 +++++---- packages/ws-server/src/webSocketServer.ts | 5 ++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/ws-server/src/controllers/index.ts b/packages/ws-server/src/controllers/index.ts index f4b90a8a72..5614dd5dc5 100644 --- a/packages/ws-server/src/controllers/index.ts +++ b/packages/ws-server/src/controllers/index.ts @@ -32,6 +32,7 @@ import { MethodNotFound, IPRateLimitExceeded, } from '@hashgraph/json-rpc-server/dist/koaJsonRpc/lib/RpcError'; +import { IRequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/IRequestDetails'; /** * Handles sending requests to a Relay by calling a specified method with given parameters. @@ -57,7 +58,7 @@ const handleSendingRequestsToRelay = async ({ connectionIdPrefix, }): Promise => { logger.trace(`${connectionIdPrefix} ${requestIdPrefix}: Submitting request=${JSON.stringify(request)} to relay.`); - + const requestDetails = { requestIdPrefix: requestIdPrefix, requestIp: request.ip } as IRequestDetails; try { const resolvedParams = resolveParams(method, params); const [service, methodName] = method.split('_'); @@ -69,11 +70,11 @@ const handleSendingRequestsToRelay = async ({ txRes = await relay .eth() .filterService() - [methodName](...resolvedParams, requestIdPrefix); - } else { - txRes = await relay[service]()[methodName](...resolvedParams, requestIdPrefix); + [methodName](...resolvedParams, requestDetails); } + txRes = await relay[service]()[methodName](...resolvedParams, requestDetails); + if (!txRes) { logger.trace( `${connectionIdPrefix} ${requestIdPrefix}: Fail to retrieve result for request=${JSON.stringify( diff --git a/packages/ws-server/src/webSocketServer.ts b/packages/ws-server/src/webSocketServer.ts index a9ec9ca59f..47c8da7aa0 100644 --- a/packages/ws-server/src/webSocketServer.ts +++ b/packages/ws-server/src/webSocketServer.ts @@ -215,7 +215,10 @@ httpApp.use(async (ctx, next) => { } else if (ctx.url === '/health/readiness') { // readiness endpoint try { - const result = relay.eth().chainId(); + const result = relay.eth().chainId({ + requestIdPrefix: ctx.state.reqId, + requestIp: ctx.request.ip, + }); if (result.includes('0x12')) { ctx.status = 200; ctx.body = 'OK'; From d7da18b5661b4ffd749bf3440224922d60dc0495 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 11 Sep 2024 12:06:56 +0300 Subject: [PATCH 15/48] Adds request details to filter service Signed-off-by: Konstantina Blazhukova --- .../ethFilterService/IFilterService.ts | 13 ++++++----- .../ethService/ethFilterService/index.ts | 23 +++++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts index ca0b3b8222..db3d69b7cd 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts @@ -20,23 +20,24 @@ import { JsonRpcError } from '../../../errors/JsonRpcError'; import { Log } from '../../../model'; +import { IRequestDetails } from '../../../types/IRequestDetails'; export interface IFilterService { newFilter( fromBlock: string, toBlock: string, - requestIdPrefix: string, + requestDetails: IRequestDetails, address?: string, topics?: any[], ): Promise; - newBlockFilter(requestIdPrefix: string): Promise; + newBlockFilter(requestDetails: IRequestDetails): Promise; - uninstallFilter(filterId: string, requestIdPrefix: string): Promise; + uninstallFilter(filterId: string, requestDetails: IRequestDetails): Promise; - newPendingTransactionFilter(requestIdPrefix: string): JsonRpcError; + newPendingTransactionFilter(requestDetails: IRequestDetails): JsonRpcError; - getFilterLogs(filterId: string, requestIdPrefix: string): Promise; + getFilterLogs(filterId: string, requestDetails: IRequestDetails): Promise; - getFilterChanges(filterId: string, requestIdPrefix: string): Promise; + getFilterChanges(filterId: string, requestDetails: IRequestDetails): Promise; } diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts index f4bfd57f1a..5fa88b5e02 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts @@ -27,6 +27,7 @@ import { generateRandomHex } from '../../../../formatters'; import { JsonRpcError, predefined } from '../../../errors/JsonRpcError'; import { Log } from '../../../model'; import { CacheService } from '../../cacheService/cacheService'; +import { IRequestDetails } from '../../../types/IRequestDetails'; /** * Create a new Filter Service implementation. @@ -116,10 +117,11 @@ export class FilterService implements IFilterService { async newFilter( fromBlock: string = 'latest', toBlock: string = 'latest', - requestIdPrefix: string, + requestDetails: IRequestDetails, address?: string, topics?: any[], ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace( `${requestIdPrefix} newFilter(fromBlock=${fromBlock}, toBlock=${toBlock}, address=${address}, topics=${topics})`, ); @@ -147,7 +149,8 @@ export class FilterService implements IFilterService { } } - async newBlockFilter(requestIdPrefix: string): Promise { + async newBlockFilter(requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} newBlockFilter()`); try { FilterService.requireFiltersEnabled(); @@ -163,7 +166,8 @@ export class FilterService implements IFilterService { } } - public async uninstallFilter(filterId: string, requestIdPrefix: string): Promise { + public async uninstallFilter(filterId: string, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} uninstallFilter(${filterId})`); FilterService.requireFiltersEnabled(); @@ -178,12 +182,13 @@ export class FilterService implements IFilterService { return false; } - public newPendingTransactionFilter(requestIdPrefix: string): JsonRpcError { - this.logger.trace(`${requestIdPrefix} newPendingTransactionFilter()`); + public newPendingTransactionFilter(requestDetails: IRequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.requestIdPrefix} newPendingTransactionFilter()`); return predefined.UNSUPPORTED_METHOD; } - public async getFilterLogs(filterId: string, requestIdPrefix: string): Promise { + public async getFilterLogs(filterId: string, requestDetails: IRequestDetails): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} getFilterLogs(${filterId})`); FilterService.requireFiltersEnabled(); @@ -203,7 +208,11 @@ export class FilterService implements IFilterService { ); } - public async getFilterChanges(filterId: string, requestIdPrefix: string): Promise { + public async getFilterChanges( + filterId: string, + requestDetails: IRequestDetails, + ): Promise { + const requestIdPrefix = requestDetails.requestIdPrefix; this.logger.trace(`${requestIdPrefix} getFilterChanges(${filterId})`); FilterService.requireFiltersEnabled(); From dd3d178f42b14a4086414bead5b8a2804dfeb82b Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Wed, 11 Sep 2024 12:19:36 +0300 Subject: [PATCH 16/48] Makes requestId required in all methods of cacheService Signed-off-by: Konstantina Blazhukova --- .../src/lib/clients/cache/ICacheClient.ts | 12 +- .../lib/clients/cache/IRedisCacheClient.ts | 6 +- .../src/lib/clients/cache/localLRUCache.ts | 18 +-- .../relay/src/lib/clients/cache/redisCache.ts | 24 ++-- .../relay/src/lib/clients/mirrorNodeClient.ts | 16 +-- packages/relay/src/lib/clients/sdkClient.ts | 1 - .../ethAddressHbarSpendingPlanRepository.ts | 8 +- .../hbarLimiter/hbarSpendingPlanRepository.ts | 31 +++-- packages/relay/src/lib/eth.ts | 45 ++----- .../lib/services/cacheService/cacheService.ts | 30 ++--- .../ethService/ethCommonService/index.ts | 2 +- .../ethService/ethFilterService/index.ts | 4 +- .../lib/services/hbarLimitService/index.ts | 26 ++-- .../lib/eth/eth_getBlockByNumber.spec.ts | 2 +- .../cacheService/cacheService.spec.ts | 120 +++++++++--------- .../tests/acceptance/cacheService.spec.ts | 46 +++---- 16 files changed, 193 insertions(+), 198 deletions(-) diff --git a/packages/relay/src/lib/clients/cache/ICacheClient.ts b/packages/relay/src/lib/clients/cache/ICacheClient.ts index b0a2241a17..c73bff3ecc 100644 --- a/packages/relay/src/lib/clients/cache/ICacheClient.ts +++ b/packages/relay/src/lib/clients/cache/ICacheClient.ts @@ -19,16 +19,16 @@ */ export interface ICacheClient { - keys(pattern: string, callingMethod: string, requestIdPrefix?: string): Promise; - get(key: string, callingMethod: string, requestIdPrefix?: string): Promise; - set(key: string, value: any, callingMethod: string, ttl?: number, requestIdPrefix?: string): Promise; - multiSet(keyValuePairs: Record, callingMethod: string, requestIdPrefix?: string): Promise; + keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise; + get(key: string, callingMethod: string, requestIdPrefix: string): Promise; + set(key: string, value: any, callingMethod: string, requestIdPrefix: string, ttl?: number): Promise; + multiSet(keyValuePairs: Record, callingMethod: string, requestIdPrefix: string): Promise; pipelineSet( keyValuePairs: Record, callingMethod: string, + requestIdPrefix: string, ttl?: number | undefined, - requestIdPrefix?: string, ): Promise; - delete(key: string, callingMethod: string, requestIdPrefix?: string): Promise; + delete(key: string, callingMethod: string, requestIdPrefix: string): Promise; clear(): Promise; } diff --git a/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts b/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts index 704c174335..52058c7eeb 100644 --- a/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts +++ b/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts @@ -22,7 +22,7 @@ import type { ICacheClient } from './ICacheClient'; export interface IRedisCacheClient extends ICacheClient { disconnect: () => Promise; - incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix?: string): Promise; - rPush(key: string, value: any, callingMethod: string, requestIdPrefix?: string): Promise; - lRange(key: string, start: number, end: number, callingMethod: string, requestIdPrefix?: string): Promise; + incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix: string): Promise; + rPush(key: string, value: any, callingMethod: string, requestIdPrefix: string): Promise; + lRange(key: string, start: number, end: number, callingMethod: string, requestIdPrefix: string): Promise; } diff --git a/packages/relay/src/lib/clients/cache/localLRUCache.ts b/packages/relay/src/lib/clients/cache/localLRUCache.ts index 0280e0319d..eb76e9671b 100644 --- a/packages/relay/src/lib/clients/cache/localLRUCache.ts +++ b/packages/relay/src/lib/clients/cache/localLRUCache.ts @@ -101,7 +101,7 @@ export class LocalLRUCache implements ICacheClient { * @param {string} requestIdPrefix - A prefix to include in log messages (optional). * @returns {*} The cached value if found, otherwise null. */ - public async get(key: string, callingMethod: string, requestIdPrefix?: string): Promise { + public async get(key: string, callingMethod: string, requestIdPrefix: string): Promise { const value = this.cache.get(key); if (value !== undefined) { this.logger.trace( @@ -120,7 +120,7 @@ export class LocalLRUCache implements ICacheClient { * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). * @returns {Promise} The remaining TTL in milliseconds. */ - public async getRemainingTtl(key: string, callingMethod: string, requestIdPrefix?: string): Promise { + public async getRemainingTtl(key: string, callingMethod: string, requestIdPrefix: string): Promise { const remainingTtl = this.cache.getRemainingTTL(key); // in milliseconds this.logger.trace(`${requestIdPrefix} returning remaining TTL ${key}:${remainingTtl} on ${callingMethod} call`); return remainingTtl; @@ -139,8 +139,8 @@ export class LocalLRUCache implements ICacheClient { key: string, value: any, callingMethod: string, + requestIdPrefix: string, ttl?: number, - requestIdPrefix?: string, ): Promise { const resolvedTtl = ttl ?? this.options.ttl; this.logger.trace(`${requestIdPrefix} caching ${key}:${JSON.stringify(value)} for ${resolvedTtl} ms`); @@ -158,11 +158,11 @@ export class LocalLRUCache implements ICacheClient { public async multiSet( keyValuePairs: Record, callingMethod: string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { // Iterate over each entry in the keyValuePairs object for (const [key, value] of Object.entries(keyValuePairs)) { - await this.set(key, value, callingMethod, undefined, requestIdPrefix); + await this.set(key, value, callingMethod, requestIdPrefix); } } @@ -178,12 +178,12 @@ export class LocalLRUCache implements ICacheClient { public async pipelineSet( keyValuePairs: Record, callingMethod: string, + requestIdPrefix: string, ttl?: number, - requestIdPrefix?: string, ): Promise { // Iterate over each entry in the keyValuePairs object for (const [key, value] of Object.entries(keyValuePairs)) { - await this.set(key, value, callingMethod, ttl, requestIdPrefix); + await this.set(key, value, callingMethod, requestIdPrefix, ttl); } } @@ -194,7 +194,7 @@ export class LocalLRUCache implements ICacheClient { * @param {string} callingMethod - The name of the method calling the cache. * @param {string} requestIdPrefix - A prefix to include in log messages (optional). */ - public async delete(key: string, callingMethod: string, requestIdPrefix?: string): Promise { + public async delete(key: string, callingMethod: string, requestIdPrefix: string): Promise { this.logger.trace(`${requestIdPrefix} delete cache for ${key}`); this.cache.delete(key); } @@ -222,7 +222,7 @@ export class LocalLRUCache implements ICacheClient { * @param {string} requestIdPrefix - A prefix to include in log messages (optional). * @returns {Promise} An array of keys that match the pattern. */ - public async keys(pattern: string, callingMethod: string, requestIdPrefix?: string): Promise { + public async keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise { const keys = Array.from(this.cache.rkeys()); // Replace escaped special characters with placeholders diff --git a/packages/relay/src/lib/clients/cache/redisCache.ts b/packages/relay/src/lib/clients/cache/redisCache.ts index 3f0f2804e0..71db040645 100644 --- a/packages/relay/src/lib/clients/cache/redisCache.ts +++ b/packages/relay/src/lib/clients/cache/redisCache.ts @@ -151,13 +151,7 @@ export class RedisCache implements IRedisCacheClient { * @param {string} [requestIdPrefix] - The optional request ID prefix. * @returns {Promise} A Promise that resolves when the value is cached. */ - async set( - key: string, - value: any, - callingMethod: string, - ttl?: number | undefined, - requestIdPrefix?: string | undefined, - ): Promise { + async set(key: string, value: any, callingMethod: string, requestIdPrefix: string, ttl?: number): Promise { const client = await this.getConnectedClient(); const serializedValue = JSON.stringify(value); const resolvedTtl = ttl ?? this.options.ttl; // in milliseconds @@ -175,7 +169,7 @@ export class RedisCache implements IRedisCacheClient { * @param {string} requestIdPrefix - Optional request ID prefix for logging. * @returns {Promise} A Promise that resolves when the values are cached. */ - async multiSet(keyValuePairs: Record, callingMethod: string, requestIdPrefix?: string): Promise { + async multiSet(keyValuePairs: Record, callingMethod: string, requestIdPrefix: string): Promise { const client = await this.getConnectedClient(); // Serialize values const serializedKeyValuePairs: Record = {}; @@ -207,8 +201,8 @@ export class RedisCache implements IRedisCacheClient { async pipelineSet( keyValuePairs: Record, callingMethod: string, - ttl?: number | undefined, - requestIdPrefix?: string, + requestIdPrefix: string, + ttl?: number, ): Promise { const client = await this.getConnectedClient(); const resolvedTtl = ttl ?? this.options.ttl; // in milliseconds @@ -236,7 +230,7 @@ export class RedisCache implements IRedisCacheClient { * @param {string} [requestIdPrefix] - The optional request ID prefix. * @returns {Promise} A Promise that resolves when the value is deleted from the cache. */ - async delete(key: string, callingMethod: string, requestIdPrefix?: string | undefined): Promise { + async delete(key: string, callingMethod: string, requestIdPrefix: string): Promise { const client = await this.getConnectedClient(); await client.del(key); this.logger.trace(`${requestIdPrefix} delete cache for ${key} on ${callingMethod} call`); @@ -304,7 +298,7 @@ export class RedisCache implements IRedisCacheClient { * @param {string} [requestIdPrefix] The optional request ID prefix * @returns {Promise} The value of the key after incrementing */ - async incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix?: string): Promise { + async incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix: string): Promise { const client = await this.getConnectedClient(); const result = await client.incrBy(key, amount); this.logger.trace(`${requestIdPrefix} incrementing ${key} by ${amount} on ${callingMethod} call`); @@ -326,7 +320,7 @@ export class RedisCache implements IRedisCacheClient { start: number, end: number, callingMethod: string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { const client = await this.getConnectedClient(); const result = await client.lRange(key, start, end); @@ -343,7 +337,7 @@ export class RedisCache implements IRedisCacheClient { * @param {string} [requestIdPrefix] The optional request ID prefix * @returns {Promise} The length of the list after pushing */ - async rPush(key: string, value: any, callingMethod: string, requestIdPrefix?: string): Promise { + async rPush(key: string, value: any, callingMethod: string, requestIdPrefix: string): Promise { const client = await this.getConnectedClient(); const serializedValue = JSON.stringify(value); const result = await client.rPush(key, serializedValue); @@ -358,7 +352,7 @@ export class RedisCache implements IRedisCacheClient { * @param {string} [requestIdPrefix] The optional request ID prefix * @returns {Promise} The list of keys matching the pattern */ - async keys(pattern: string, callingMethod: string, requestIdPrefix?: string): Promise { + async keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise { const client = await this.getConnectedClient(); const result = await client.keys(pattern); this.logger.trace(`${requestIdPrefix} retrieving keys matching ${pattern} on ${callingMethod} call`); diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index a12858cd6c..f480da1032 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -352,7 +352,7 @@ export class MirrorNodeClient { } const ms = Date.now() - start; - this.logger.debug(`${requestId} [${method}] ${path} ${response.status} ${ms} ms`); + this.logger.debug(`${requestIdPrefix} [${method}] ${path} ${response.status} ${ms} ms`); this.mirrorResponseHistogram.labels(pathLabel, response.status?.toString()).observe(ms); return response.data; } catch (error: any) { @@ -588,7 +588,7 @@ export class MirrorNodeClient { requestIdPrefix, ); - await this.cacheService.set(cachedLabel, block, MirrorNodeClient.GET_BLOCK_ENDPOINT, undefined, requestIdPrefix); + await this.cacheService.set(cachedLabel, block, MirrorNodeClient.GET_BLOCK_ENDPOINT, requestIdPrefix); return block; } @@ -642,8 +642,8 @@ export class MirrorNodeClient { cachedLabel, valid, MirrorNodeClient.GET_CONTRACT_ENDPOINT, - constants.CACHE_TTL.ONE_DAY, requestIdPrefix, + constants.CACHE_TTL.ONE_DAY, ); return valid; } @@ -672,8 +672,8 @@ export class MirrorNodeClient { cachedLabel, id, MirrorNodeClient.GET_CONTRACT_ENDPOINT, - constants.CACHE_TTL.ONE_DAY, requestIdPrefix, + constants.CACHE_TTL.ONE_DAY, ); return id; } @@ -709,8 +709,8 @@ export class MirrorNodeClient { cacheKey, response, MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT, - constants.CACHE_TTL.ONE_HOUR, requestIdPrefix, + constants.CACHE_TTL.ONE_HOUR, ); } @@ -896,8 +896,8 @@ export class MirrorNodeClient { cachedLabel, block, MirrorNodeClient.GET_BLOCKS_ENDPOINT, - constants.CACHE_TTL.ONE_DAY, requestIdPrefix, + constants.CACHE_TTL.ONE_DAY, ); return block; } @@ -1179,7 +1179,7 @@ export class MirrorNodeClient { type: constants.TYPE_CONTRACT, entity: contract, }; - await this.cacheService.set(cachedLabel, response, callerName, undefined, requestIdPrefix); + await this.cacheService.set(cachedLabel, response, callerName, requestIdPrefix); return response; } } @@ -1234,7 +1234,7 @@ export class MirrorNodeClient { type, entity: data.value, }; - await this.cacheService.set(cachedLabel, response, callerName, undefined, requestIdPrefix); + await this.cacheService.set(cachedLabel, response, callerName, requestIdPrefix); return response; } diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index 3d38244460..8e55f5193e 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -360,7 +360,6 @@ export class SDKClient { constants.CACHE_KEY.GET_TINYBAR_GAS_FEE, tinyBars, callerName, - undefined, requestDetails.requestIdPrefix, ); return tinyBars; diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts index df37222494..faadde0a99 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts @@ -67,9 +67,9 @@ export class EthAddressHbarSpendingPlanRepository { * @param {IEthAddressHbarSpendingPlan} addressPlan - The plan to save. * @returns {Promise} - A promise that resolves when the ETH address is linked to the plan. */ - async save(addressPlan: IEthAddressHbarSpendingPlan): Promise { + async save(addressPlan: IEthAddressHbarSpendingPlan, requestIdPrefix: string): Promise { const key = this.getKey(addressPlan.ethAddress); - await this.cache.set(key, addressPlan, 'save', this.threeMonthsInMillis); + await this.cache.set(key, addressPlan, 'save', requestIdPrefix, this.threeMonthsInMillis); this.logger.trace(`Saved EthAddressHbarSpendingPlan with address ${addressPlan.ethAddress}`); } @@ -79,9 +79,9 @@ export class EthAddressHbarSpendingPlanRepository { * @param {string} ethAddress - The ETH address to unlink the plan from. * @returns {Promise} - A promise that resolves when the ETH address is unlinked from the plan. */ - async delete(ethAddress: string): Promise { + async delete(ethAddress: string, requestIdPrefix: string): Promise { const key = this.getKey(ethAddress); - await this.cache.delete(key, 'delete'); + await this.cache.delete(key, 'delete', requestIdPrefix); this.logger.trace(`Deleted EthAddressHbarSpendingPlan with address ${ethAddress}`); } diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts index c747a2f36c..820ac948f8 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts @@ -87,7 +87,7 @@ export class HbarSpendingPlanRepository { * @param subscriptionType - The subscription type of the plan to create. * @returns {Promise} - The created hbar spending plan object. */ - async create(subscriptionType: SubscriptionType): Promise { + async create(subscriptionType: SubscriptionType, requestIdPrefix: string): Promise { const plan: IDetailedHbarSpendingPlan = { id: uuidV4(randomBytes(16)), subscriptionType, @@ -98,7 +98,7 @@ export class HbarSpendingPlanRepository { }; this.logger.trace(`Creating HbarSpendingPlan with ID ${plan.id}...`); const key = this.getKey(plan.id); - await this.cache.set(key, plan, 'create', this.threeMonthsInMillis); + await this.cache.set(key, plan, 'create', requestIdPrefix, this.threeMonthsInMillis); return new HbarSpendingPlan(plan); } @@ -124,7 +124,13 @@ export class HbarSpendingPlanRepository { this.logger.trace(`Retrieving spending history for HbarSpendingPlan with ID ${id}...`); const key = this.getSpendingHistoryKey(id); - const spendingHistory = await this.cache.lRange(key, 0, -1, 'getSpendingHistory'); + const spendingHistory = await this.cache.lRange( + key, + 0, + -1, + 'getSpendingHistory', + requestIdPrefix, + ); return spendingHistory.map((entry) => new HbarSpendingRecord(entry)); } @@ -140,7 +146,7 @@ export class HbarSpendingPlanRepository { this.logger.trace(`Adding ${amount} to spending history for HbarSpendingPlan with ID ${id}...`); const key = this.getSpendingHistoryKey(id); const entry: IHbarSpendingRecord = { amount, timestamp: new Date() }; - return this.cache.rPush(key, entry, 'addAmountToSpendingHistory'); + return this.cache.rPush(key, entry, 'addAmountToSpendingHistory', requestIdPrefix); } /** @@ -180,10 +186,10 @@ export class HbarSpendingPlanRepository { const key = this.getSpentTodayKey(id); if (!(await this.cache.getAsync(key, 'addAmountToSpentToday', requestIdPrefix))) { this.logger.trace(`No spending yet for HbarSpendingPlan with ID ${id}, setting spentToday to ${amount}...`); - await this.cache.set(key, amount, 'addAmountToSpentToday', this.oneDayInMillis); + await this.cache.set(key, amount, 'addAmountToSpentToday', requestIdPrefix, this.oneDayInMillis); } else { this.logger.trace(`Adding ${amount} to spentToday for HbarSpendingPlan with ID ${id}...`); - await this.cache.incrBy(key, amount, 'addAmountToSpentToday'); + await this.cache.incrBy(key, amount, 'addAmountToSpentToday', requestIdPrefix); } } @@ -192,10 +198,15 @@ export class HbarSpendingPlanRepository { * @param {SubscriptionType} subscriptionType - The subscription type to filter by. * @returns {Promise} - A promise that resolves with the active spending plans. */ - async findAllActiveBySubscriptionType(subscriptionType: SubscriptionType): Promise { + async findAllActiveBySubscriptionType( + subscriptionType: SubscriptionType, + requestIdPrefix: string, + ): Promise { const callerMethod = this.findAllActiveBySubscriptionType.name; - const keys = await this.cache.keys(`${this.collectionKey}:*`, callerMethod); - const plans = await Promise.all(keys.map((key) => this.cache.getAsync(key, callerMethod))); + const keys = await this.cache.keys(`${this.collectionKey}:*`, callerMethod, requestIdPrefix); + const plans = await Promise.all( + keys.map((key) => this.cache.getAsync(key, callerMethod, requestIdPrefix)), + ); return Promise.all( plans .filter((plan) => plan.subscriptionType === subscriptionType && plan.active) @@ -205,7 +216,7 @@ export class HbarSpendingPlanRepository { ...plan, createdAt: new Date(plan.createdAt), spendingHistory: [], - spentToday: await this.getSpentToday(plan.id), + spentToday: await this.getSpentToday(plan.id, requestIdPrefix), }), ), ); diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index c623708d85..b9ce50acf9 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -387,13 +387,7 @@ export class EthImpl implements Eth { ); } if (newestBlock != EthImpl.blockLatest && newestBlock != EthImpl.blockPending) { - await this.cacheService.set( - cacheKey, - feeHistory, - EthImpl.ethFeeHistory, - undefined, - requestDetails.requestIdPrefix, - ); + await this.cacheService.set(cacheKey, feeHistory, EthImpl.ethFeeHistory, requestDetails.requestIdPrefix); } } @@ -554,7 +548,7 @@ export class EthImpl implements Eth { const timestamp = blocks[0].timestamp.to; const blockTimeStamp: LatestBlockNumberTimestamp = { blockNumber: currentBlock, timeStampTo: timestamp }; // save the latest block number in cache - await this.cacheService.set(cacheKey, currentBlock, caller, this.ethBlockNumberCacheTtlMs, requestIdPrefix); + await this.cacheService.set(cacheKey, currentBlock, caller, requestIdPrefix, this.ethBlockNumberCacheTtlMs); return blockTimeStamp; } @@ -708,7 +702,7 @@ export class EthImpl implements Eth { let account = await this.cacheService.getAsync(key, EthImpl.ethEstimateGas, requestIdPrefix); if (!account) { account = await this.mirrorNodeClient.getAccount(address, requestIdPrefix); - await this.cacheService.set(key, account, EthImpl.ethEstimateGas, undefined, requestIdPrefix); + await this.cacheService.set(key, account, EthImpl.ethEstimateGas, requestIdPrefix); } return account; } @@ -776,8 +770,8 @@ export class EthImpl implements Eth { constants.CACHE_KEY.GAS_PRICE, gasPrice, EthImpl.ethGasPrice, - this.ethGasPRiceCacheTtlMs, requestDetails.requestIdPrefix, + this.ethGasPRiceCacheTtlMs, ); } @@ -1106,8 +1100,8 @@ export class EthImpl implements Eth { cacheKey, cachedBalance, EthImpl.ethGetBalance, - this.ethGetBalanceCacheTtlMs, requestIdPrefix, + this.ethGetBalanceCacheTtlMs, ); return cachedBalance; @@ -1176,7 +1170,6 @@ export class EthImpl implements Eth { cachedLabel, result?.entity.runtime_bytecode, EthImpl.ethGetCode, - undefined, requestIdPrefix, ); return result?.entity.runtime_bytecode; @@ -1245,7 +1238,7 @@ export class EthImpl implements Eth { block = await this.getBlock(hash, showDetails, requestDetails).catch((e: any) => { throw this.common.genericErrorHandler(e, `${requestIdPrefix} Failed to retrieve block for hash ${hash}`); }); - await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByHash, undefined, requestIdPrefix); + await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByHash, requestIdPrefix); } return block; @@ -1276,7 +1269,7 @@ export class EthImpl implements Eth { }); if (!this.common.blockTagIsLatestOrPending(blockNumOrTag)) { - await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, undefined, requestIdPrefix); + await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, requestIdPrefix); } } @@ -1313,13 +1306,7 @@ export class EthImpl implements Eth { throw this.common.genericErrorHandler(e, `${requestIdPrefix} Failed to retrieve block for hash ${hash}`); }); - await this.cacheService.set( - cacheKey, - transactionCount, - EthImpl.ethGetTransactionCountByHash, - undefined, - requestIdPrefix, - ); + await this.cacheService.set(cacheKey, transactionCount, EthImpl.ethGetTransactionCountByHash, requestIdPrefix); return transactionCount; } @@ -1359,13 +1346,7 @@ export class EthImpl implements Eth { ); }); - await this.cacheService.set( - cacheKey, - transactionCount, - EthImpl.ethGetTransactionCountByNumber, - undefined, - requestIdPrefix, - ); + await this.cacheService.set(cacheKey, transactionCount, EthImpl.ethGetTransactionCountByNumber, requestIdPrefix); return transactionCount; } @@ -1485,7 +1466,7 @@ export class EthImpl implements Eth { blockNumOrTag === EthImpl.blockEarliest || !isNaN(blockNum) ? constants.CACHE_TTL.ONE_DAY : this.ethGetTransactionCountCacheTtl; // cache historical values longer as they don't change - await this.cacheService.set(cacheKey, nonceCount, EthImpl.ethGetTransactionCount, cacheTtl, requestIdPrefix); + await this.cacheService.set(cacheKey, nonceCount, EthImpl.ethGetTransactionCount, requestIdPrefix, cacheTtl); return nonceCount; } @@ -1952,8 +1933,8 @@ export class EthImpl implements Eth { cacheKey, formattedCallReponse, EthImpl.ethCall, - this.ethCallCacheTtl, requestIdPrefix, + this.ethCallCacheTtl, ); return formattedCallReponse; } @@ -2124,8 +2105,8 @@ export class EthImpl implements Eth { cacheKey, receipt, EthImpl.ethGetTransactionReceipt, - constants.CACHE_TTL.ONE_DAY, requestIdPrefix, + constants.CACHE_TTL.ONE_DAY, ); return receipt; } else { @@ -2175,8 +2156,8 @@ export class EthImpl implements Eth { cacheKey, receipt, EthImpl.ethGetTransactionReceipt, - constants.CACHE_TTL.ONE_DAY, requestIdPrefix, + constants.CACHE_TTL.ONE_DAY, ); return receipt; } diff --git a/packages/relay/src/lib/services/cacheService/cacheService.ts b/packages/relay/src/lib/services/cacheService/cacheService.ts index 9d461e512b..03d7221e39 100644 --- a/packages/relay/src/lib/services/cacheService/cacheService.ts +++ b/packages/relay/src/lib/services/cacheService/cacheService.ts @@ -244,7 +244,7 @@ export class CacheService { * @param {string} [requestIdPrefix] - The optional request ID prefix. * @returns {Promise} A Promise that resolves with the cached value or null if not found. */ - private async getFromInternalCache(key: string, callingMethod: string, requestIdPrefix?: string): Promise { + private async getFromInternalCache(key: string, callingMethod: string, requestIdPrefix: string): Promise { this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.GET).inc(1); return await this.internalCache.get(key, callingMethod, requestIdPrefix); @@ -264,14 +264,14 @@ export class CacheService { key: string, value: any, callingMethod: string, + requestIdPrefix: string, ttl?: number, - requestIdPrefix?: string, ): Promise { if (this.isSharedCacheEnabled) { try { this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.SET).inc(1); - await this.sharedCache.set(key, value, callingMethod, ttl, requestIdPrefix); + await this.sharedCache.set(key, value, callingMethod, requestIdPrefix, ttl); return; } catch (error) { const redisError = new RedisCacheError(error); @@ -283,7 +283,7 @@ export class CacheService { // fallback to internal cache in case of Redis error this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); - await this.internalCache.set(key, value, callingMethod, ttl, requestIdPrefix); + await this.internalCache.set(key, value, callingMethod, requestIdPrefix, ttl); } /** @@ -299,8 +299,8 @@ export class CacheService { public async multiSet( entries: Record, callingMethod: string, + requestIdPrefix: string, ttl?: number, - requestIdPrefix?: string, ): Promise { if (this.isSharedCacheEnabled) { const metricsMethod = this.shouldMultiSet ? CacheService.methods.MSET : CacheService.methods.PIPELINE; @@ -308,7 +308,7 @@ export class CacheService { if (this.shouldMultiSet) { await this.sharedCache.multiSet(entries, callingMethod, requestIdPrefix); } else { - await this.sharedCache.pipelineSet(entries, callingMethod, ttl, requestIdPrefix); + await this.sharedCache.pipelineSet(entries, callingMethod, requestIdPrefix, ttl); } this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.REDIS, metricsMethod).inc(1); @@ -322,7 +322,7 @@ export class CacheService { } // fallback to internal cache, but use pipeline, because of it's TTL support - await this.internalCache.pipelineSet(entries, callingMethod, ttl, requestIdPrefix); + await this.internalCache.pipelineSet(entries, callingMethod, requestIdPrefix, ttl); this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); } @@ -334,7 +334,7 @@ export class CacheService { * @param {string} callingMethod - The name of the method calling the cache. * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). */ - public async delete(key: string, callingMethod: string, requestIdPrefix?: string): Promise { + public async delete(key: string, callingMethod: string, requestIdPrefix: string): Promise { if (this.isSharedCacheEnabled) { try { this.cacheMethodsCounter @@ -362,7 +362,7 @@ export class CacheService { * Else the internal cache clearing is attempted. * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). */ - public async clear(requestIdPrefix?: string): Promise { + public async clear(requestIdPrefix: string): Promise { if (this.isSharedCacheEnabled) { try { await this.sharedCache.clear(); @@ -387,7 +387,7 @@ export class CacheService { * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). * @returns {Promise} A Promise that resolves with the new value of the key after incrementing. */ - public async incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix?: string): Promise { + public async incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix: string): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { this.cacheMethodsCounter @@ -412,7 +412,7 @@ export class CacheService { : undefined; this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); - await this.internalCache.set(key, newValue, callingMethod, remainingTtl, requestIdPrefix); + await this.internalCache.set(key, newValue, callingMethod, requestIdPrefix, remainingTtl); return newValue; } @@ -425,7 +425,7 @@ export class CacheService { * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). * @returns {Promise} A Promise that resolves with the new length of the list after pushing. */ - public async rPush(key: string, value: any, callingMethod: string, requestIdPrefix?: string): Promise { + public async rPush(key: string, value: any, callingMethod: string, requestIdPrefix: string): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { this.cacheMethodsCounter @@ -453,7 +453,7 @@ export class CacheService { : undefined; this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); - await this.internalCache.set(key, values, callingMethod, remainingTtl, requestIdPrefix); + await this.internalCache.set(key, values, callingMethod, requestIdPrefix, remainingTtl); return values.length; } @@ -473,7 +473,7 @@ export class CacheService { start: number, end: number, callingMethod: string, - requestIdPrefix?: string, + requestIdPrefix: string, ): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { @@ -508,7 +508,7 @@ export class CacheService { * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). * @returns {Promise} A Promise that resolves with an array of keys that match the pattern. */ - async keys(pattern: string, callingMethod: string, requestIdPrefix?: string): Promise { + async keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { return await this.sharedCache.keys(pattern, callingMethod, requestIdPrefix); diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts index aa1c17c97f..c0856fcc42 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts @@ -226,8 +226,8 @@ export class CommonService implements ICommonService { cacheKey, currentBlock, CommonService.latestBlockNumber, - this.ethBlockNumberCacheTtlMs, requestIdPrefix, + this.ethBlockNumberCacheTtlMs, ); return currentBlock; diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts index 5fa88b5e02..1db8b9387e 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts @@ -90,8 +90,8 @@ export class FilterService implements IFilterService { lastQueried: null, }, this.ethNewFilter, - constants.FILTER.TTL, requestIdPrefix, + constants.FILTER.TTL, ); this.logger.trace(`${requestIdPrefix} created filter with TYPE=${type}, params: ${params}`); return filterId; @@ -272,8 +272,8 @@ export class FilterService implements IFilterService { lastQueried: latestBlockNumber, }, this.ethGetFilterChanges, - constants.FILTER.TTL, requestIdPrefix, + constants.FILTER.TTL, ); return result; diff --git a/packages/relay/src/lib/services/hbarLimitService/index.ts b/packages/relay/src/lib/services/hbarLimitService/index.ts index e2f9bf644d..92e3dda5b5 100644 --- a/packages/relay/src/lib/services/hbarLimitService/index.ts +++ b/packages/relay/src/lib/services/hbarLimitService/index.ts @@ -186,7 +186,7 @@ export class HbarLimitService implements IHbarLimitService { let spendingPlan = await this.getSpendingPlan(ethAddress, requestIdPrefix, ipAddress); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address - spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress); + spendingPlan = await this.createBasicSpendingPlan(ethAddress, requestIdPrefix, ipAddress); } const dailyLimit = HbarLimitService.DAILY_LIMITS[spendingPlan.subscriptionType]; @@ -216,7 +216,7 @@ export class HbarLimitService implements IHbarLimitService { let spendingPlan = await this.getSpendingPlan(ethAddress, requestIdPrefix, ipAddress); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address - spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress); + spendingPlan = await this.createBasicSpendingPlan(ethAddress, requestIdPrefix, ipAddress); } this.logger.trace( @@ -235,7 +235,7 @@ export class HbarLimitService implements IHbarLimitService { this.hbarLimitRemainingGauge.set(this.remainingBudget); // Done asynchronously in the background - this.updateAverageDailyUsagePerSubscriptionType(spendingPlan.subscriptionType).then(); + this.updateAverageDailyUsagePerSubscriptionType(spendingPlan.subscriptionType, requestIdPrefix).then(); this.logger.trace( `${requestIdPrefix} HBAR rate limit expense update: cost=${cost}, remainingBudget=${this.remainingBudget}`, @@ -279,8 +279,14 @@ export class HbarLimitService implements IHbarLimitService { * @param {SubscriptionType} subscriptionType - The subscription type to update the average daily usage for. * @private {Promise} - A promise that resolves when the average daily usage has been updated. */ - private async updateAverageDailyUsagePerSubscriptionType(subscriptionType: SubscriptionType): Promise { - const plans = await this.hbarSpendingPlanRepository.findAllActiveBySubscriptionType(subscriptionType); + private async updateAverageDailyUsagePerSubscriptionType( + subscriptionType: SubscriptionType, + requestIdPrefix: string, + ): Promise { + const plans = await this.hbarSpendingPlanRepository.findAllActiveBySubscriptionType( + subscriptionType, + requestIdPrefix, + ); const totalUsage = plans.reduce((total, plan) => total + plan.spentToday, 0); const averageUsage = Math.round(totalUsage / plans.length); this.averageDailySpendingPlanUsagesGauge[subscriptionType].set(averageUsage); @@ -389,15 +395,19 @@ export class HbarLimitService implements IHbarLimitService { * @returns {Promise} - A promise that resolves with the created spending plan. * @private */ - private async createBasicSpendingPlan(ethAddress: string, ipAddress?: string): Promise { + private async createBasicSpendingPlan( + ethAddress: string, + requstIdPrefix: string, + ipAddress?: string, + ): Promise { if (!ethAddress && !ipAddress) { throw new Error('Cannot create a spending plan without an associated eth address or ip address'); } - const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC); + const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC, requstIdPrefix); if (ethAddress) { this.logger.trace(`Linking spending plan with ID ${spendingPlan.id} to eth address ${ethAddress}`); - await this.ethAddressHbarSpendingPlanRepository.save({ ethAddress, planId: spendingPlan.id }); + await this.ethAddressHbarSpendingPlanRepository.save({ ethAddress, planId: spendingPlan.id }, requstIdPrefix); } if (ipAddress) { this.logger.trace(`Linking spending plan with ID ${spendingPlan.id} to ip address ${ipAddress}`); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index 13f8380929..ef74c25c52 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -175,7 +175,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { expect(numberTo0x(newBlockNumber)).to.be.eq(blockNumber3); }); - it.only('"eth_blockNumber" should throw an error if no blocks are found', async function () { + it('"eth_blockNumber" should throw an error if no blocks are found', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(404, BLOCK_NOT_FOUND_RES); const error = predefined.COULD_NOT_RETRIEVE_LATEST_BLOCK; await RelayAssertions.assertRejection(error, ethImpl.blockNumber, true, ethImpl, [requestDetails]); diff --git a/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts b/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts index 8b207cb250..997d174d8f 100644 --- a/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts +++ b/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts @@ -39,7 +39,7 @@ chai.use(chaiAsPromised); describe('CacheService Test Suite', async function () { this.timeout(10000); - const requestIdPrefix = `[Request ID: testId]`; + const requestIdPrefix = `[Request ID: cacheServiceTest]`; const describeKeysTestSuite = () => { describe('keys', async function () { it('should retrieve all keys', async function () { @@ -48,9 +48,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); - const keys = await cacheService.keys('*', callingMethod); + const keys = await cacheService.keys('*', callingMethod, requestIdPrefix); expect(keys).to.have.members(Object.keys(entries)); }); @@ -60,9 +60,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); - const keys = await cacheService.keys('key*', callingMethod); + const keys = await cacheService.keys('key*', callingMethod, requestIdPrefix); expect(keys).to.have.members(Object.keys(entries)); }); @@ -72,9 +72,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); - const keys = await cacheService.keys('key?', callingMethod); + const keys = await cacheService.keys('key?', callingMethod, requestIdPrefix); expect(keys).to.have.members(Object.keys(entries)); }); @@ -84,9 +84,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); - const keys = await cacheService.keys('key[1-2]', callingMethod); + const keys = await cacheService.keys('key[1-2]', callingMethod, requestIdPrefix); expect(keys).to.have.members(['key1', 'key2']); }); @@ -96,10 +96,10 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); // [^3] should match all keys except key3 - const keys = await cacheService.keys('key[^3]', callingMethod); + const keys = await cacheService.keys('key[^3]', callingMethod, requestIdPrefix); expect(keys).to.have.members(['key1', 'key2']); }); @@ -109,9 +109,9 @@ describe('CacheService Test Suite', async function () { entries['keyb'] = 'value2'; entries['keyc'] = 'value3'; - await cacheService.multiSet(entries, callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); - const keys = await cacheService.keys('key[a-c]', callingMethod); + const keys = await cacheService.keys('key[a-c]', callingMethod, requestIdPrefix); expect(keys).to.have.members(Object.keys(entries)); }); @@ -119,9 +119,9 @@ describe('CacheService Test Suite', async function () { const key = 'h*llo'; const value = 'value'; - await cacheService.set(key, value, callingMethod); + await cacheService.set(key, value, callingMethod, requestIdPrefix); - const keys = await cacheService.keys('h*llo', callingMethod); + const keys = await cacheService.keys('h*llo', callingMethod, requestIdPrefix); expect(keys).to.have.members([key]); }); @@ -132,8 +132,8 @@ describe('CacheService Test Suite', async function () { entries['key3'] = 'value3'; await cacheService.disconnectRedisClient(); - await cacheService.multiSet(entries, callingMethod); - const keys = await cacheService.keys('*', callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + const keys = await cacheService.keys('*', callingMethod, requestIdPrefix); expect(keys).to.have.members(Object.keys(entries)); }); }); @@ -146,14 +146,14 @@ describe('CacheService Test Suite', async function () { }); this.afterEach(async () => { - await cacheService.clear(); + await cacheService.clear(requestIdPrefix); }); it('should be able to set and get from internal cache', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod); + await cacheService.set(key, value, callingMethod, requestIdPrefix); const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); @@ -163,8 +163,8 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod); - await cacheService.delete(key, callingMethod); + await cacheService.set(key, value, callingMethod, requestIdPrefix); + await cacheService.delete(key, callingMethod, requestIdPrefix); const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; @@ -174,7 +174,7 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod); + await cacheService.set(key, value, callingMethod, requestIdPrefix); const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); @@ -186,7 +186,7 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod); + await cacheService.multiSet(entries, callingMethod, requestIdPrefix); for (const [key, value] of Object.entries(entries)) { const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); @@ -199,7 +199,7 @@ describe('CacheService Test Suite', async function () { const key = 'counter'; const amount = 5; - await cacheService.set(key, 10, callingMethod); + await cacheService.set(key, 10, callingMethod, requestIdPrefix); const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).to.equal(15); @@ -211,7 +211,7 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const value = 'item'; - await cacheService.rPush(key, value, callingMethod); + await cacheService.rPush(key, value, callingMethod, requestIdPrefix); const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).to.deep.equal([value]); @@ -223,8 +223,8 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; - await cacheService.set(key, values, callingMethod); - const range = await cacheService.lRange(key, 0, 1, callingMethod); + await cacheService.set(key, values, callingMethod, requestIdPrefix); + const range = await cacheService.lRange(key, 0, 1, callingMethod, requestIdPrefix); expect(range).to.deep.equal(['item1', 'item2']); }); @@ -233,8 +233,8 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; - await cacheService.set(key, values, callingMethod); - const range = await cacheService.lRange(key, -2, -1, callingMethod); + await cacheService.set(key, values, callingMethod, requestIdPrefix); + const range = await cacheService.lRange(key, -2, -1, callingMethod, requestIdPrefix); expect(range).to.deep.equal(['item2', 'item3']); }); @@ -294,14 +294,14 @@ describe('CacheService Test Suite', async function () { }); this.afterEach(async () => { - await cacheService.clear(); + await cacheService.clear( requestIdPrefix); }); it('should be able to set and get from shared cache', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod); + await cacheService.set(key, value, callingMethod, requestIdPrefix); const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); @@ -311,9 +311,9 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod); + await cacheService.set(key, value, callingMethod, requestIdPrefix); - await cacheService.delete(key, callingMethod); + await cacheService.delete(key, callingMethod, requestIdPrefix); const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; @@ -323,14 +323,14 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod); + await cacheService.set(key, value, callingMethod, requestIdPrefix); const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(cachedValue).eq(value); }); it('should be able to set using multiSet and get them separately using internal cache', async function () { - await cacheService.multiSet(multiSetEntries, callingMethod); + await cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix); for (const [key, value] of Object.entries(multiSetEntries)) { const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); @@ -342,7 +342,7 @@ describe('CacheService Test Suite', async function () { // @ts-ignore cacheService['shouldMultiSet'] = false; - await cacheService.multiSet(multiSetEntries, callingMethod); + await cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix); for (const [key, value] of Object.entries(multiSetEntries)) { const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); @@ -364,7 +364,7 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.set(key, value, callingMethod)).to.eventually.not.be.rejected; + await expect(cacheService.set(key, value, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(internalCacheRes).to.eq(value); @@ -373,10 +373,10 @@ describe('CacheService Test Suite', async function () { it('should be able to multiSet to internal cache in case of Redis error', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.multiSet(multiSetEntries, callingMethod)).to.eventually.not.be.rejected; + await expect(cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; for (const [key, value] of Object.entries(multiSetEntries)) { - const internalCacheRes = await cacheService.getAsync(key, callingMethod); + const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(internalCacheRes).to.eq(value); } }); @@ -387,10 +387,10 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.multiSet(multiSetEntries, callingMethod)).to.eventually.not.be.rejected; + await expect(cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; for (const [key, value] of Object.entries(multiSetEntries)) { - const internalCacheRes = await cacheService.getAsync(key, callingMethod); + const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestIdPrefix); expect(internalCacheRes).to.eq(value); } }); @@ -398,21 +398,21 @@ describe('CacheService Test Suite', async function () { it('should be able to clear from internal cache in case of Redis error', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.clear()).to.eventually.not.be.rejected; + await expect(cacheService.clear(requestIdPrefix)).to.eventually.not.be.rejected; }); it('should be able to delete from internal cache in case of Redis error', async function () { const key = 'string'; await cacheService.disconnectRedisClient(); - await expect(cacheService.delete(key, callingMethod)).to.eventually.not.be.rejected; + await expect(cacheService.delete(key, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; }); it('should be able to set to shared cache', async function () { const key = 'string'; const value = 'value'; - await expect(cacheService.set(key, value, callingMethod)).to.eventually.not.be.rejected; + await expect(cacheService.set(key, value, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; }); it('should be able to multiset to shared cache', async function () { @@ -420,13 +420,13 @@ describe('CacheService Test Suite', async function () { items['key1'] = 'value1'; items['key2'] = 'value2'; - await expect(cacheService.multiSet(items, callingMethod)).to.eventually.not.be.rejected; + await expect(cacheService.multiSet(items, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; }); it('should be able to delete from shared cache', async function () { const key = 'string'; - await expect(cacheService.delete(key, callingMethod)).to.eventually.not.be.rejected; + await expect(cacheService.delete(key, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; }); describe('incrBy', async function () { @@ -434,8 +434,8 @@ describe('CacheService Test Suite', async function () { const key = 'counter'; const amount = 5; - await cacheService.set(key, 10, callingMethod); - const newValue = await cacheService.incrBy(key, amount, callingMethod); + await cacheService.set(key, 10, callingMethod, requestIdPrefix); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).to.equal(15); }); @@ -444,8 +444,8 @@ describe('CacheService Test Suite', async function () { const key = 'counter'; const amount = 5; - await cacheService.set(key, 10, callingMethod); - const newValue = await cacheService.incrBy(key, amount, callingMethod); + await cacheService.set(key, 10, callingMethod, requestIdPrefix); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).to.equal(15); }); @@ -456,7 +456,7 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - const newValue = await cacheService.incrBy(key, amount, callingMethod); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).to.equal(5); }); @@ -467,8 +467,8 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const value = 'item'; - await cacheService.rPush(key, value, callingMethod); - const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod); + await cacheService.rPush(key, value, callingMethod, requestIdPrefix); + const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod, requestIdPrefix); expect(cachedValue).to.deep.equal([value]); }); @@ -479,8 +479,8 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - await cacheService.rPush(key, value, callingMethod); - const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod); + await cacheService.rPush(key, value, callingMethod, requestIdPrefix); + const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod, requestIdPrefix); expect(cachedValue).to.deep.equal([value]); }); @@ -491,10 +491,10 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; for (const item of values) { - await cacheService.rPush(key, item, callingMethod); + await cacheService.rPush(key, item, callingMethod, requestIdPrefix); } - const range = await cacheService.lRange(key, 0, 1, callingMethod); + const range = await cacheService.lRange(key, 0, 1, callingMethod, requestIdPrefix); expect(range).to.deep.equal(['item1', 'item2']); }); @@ -503,10 +503,10 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; for (const item of values) { - await cacheService.rPush(key, item, callingMethod); + await cacheService.rPush(key, item, callingMethod, requestIdPrefix); } - const range = await cacheService.lRange(key, -2, -1, callingMethod); + const range = await cacheService.lRange(key, -2, -1, callingMethod, requestIdPrefix); expect(range).to.deep.equal(['item2', 'item3']); }); @@ -520,7 +520,7 @@ describe('CacheService Test Suite', async function () { await cacheService.rPush(key, item, callingMethod); } - const range = await cacheService.lRange(key, 0, 1, callingMethod); + const range = await cacheService.lRange(key, 0, 1, callingMethod, requestIdPrefix); expect(range).to.deep.equal(['item1', 'item2']); }); diff --git a/packages/server/tests/acceptance/cacheService.spec.ts b/packages/server/tests/acceptance/cacheService.spec.ts index c734a1dccd..d5c4d65eda 100644 --- a/packages/server/tests/acceptance/cacheService.spec.ts +++ b/packages/server/tests/acceptance/cacheService.spec.ts @@ -31,7 +31,7 @@ const CALLING_METHOD = 'AcceptanceTest'; describe('@cache-service Acceptance Tests for shared cache', function () { let cacheService: CacheService; - + const requestIdPrefix = `[RequestID: cacheServiceTest}]`; before(async () => { cacheService = new CacheService(global.logger, registry); await new Promise((r) => setTimeout(r, 1000)); @@ -40,22 +40,22 @@ describe('@cache-service Acceptance Tests for shared cache', function () { it('Correctly performs set, get and delete operations', async () => { const dataLabel = `${DATA_LABEL_PREFIX}1`; - await cacheService.set(dataLabel, DATA, CALLING_METHOD, undefined, undefined, true); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix, undefined); await new Promise((r) => setTimeout(r, 200)); - const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(cache).to.deep.eq(DATA, 'set method saves to shared cache'); - const cacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const cacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(cacheFromService).to.deep.eq(DATA, 'getAsync method reads correctly from shared cache'); - await cacheService.delete(dataLabel, CALLING_METHOD, undefined, true); + await cacheService.delete(dataLabel, CALLING_METHOD, requestIdPrefix); await new Promise((r) => setTimeout(r, 200)); - const deletedCache = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const deletedCache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(deletedCache).to.eq(null, 'the delete method correctly deletes from shared cache'); - const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(deletedCacheFromService).to.eq(null, 'getAsync method cannot read deleted cache'); }); @@ -63,18 +63,18 @@ describe('@cache-service Acceptance Tests for shared cache', function () { const ttl = 1000; const dataLabel = `${DATA_LABEL_PREFIX}2`; - await cacheService.set(dataLabel, DATA, CALLING_METHOD, ttl, undefined, true); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix, ttl); await new Promise((r) => setTimeout(r, 200)); - const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(cache).to.deep.eq(DATA, 'data is stored with TTL'); await new Promise((r) => setTimeout(r, ttl)); - const expiredCache = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const expiredCache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(expiredCache).to.eq(null, 'cache expires after TTL period'); - const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(deletedCacheFromService).to.eq(null, 'getAsync method cannot read expired cache'); }); @@ -85,10 +85,10 @@ describe('@cache-service Acceptance Tests for shared cache', function () { const serviceWithDisabledRedis = new CacheService(global.logger, registry); await new Promise((r) => setTimeout(r, 1000)); expect(serviceWithDisabledRedis.isRedisEnabled()).to.eq(false, 'redis is disabled'); - await serviceWithDisabledRedis.set(dataLabel, DATA, CALLING_METHOD, undefined, undefined, true); + await serviceWithDisabledRedis.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); await new Promise((r) => setTimeout(r, 200)); - const dataInLRU = await serviceWithDisabledRedis.getAsync(dataLabel, CALLING_METHOD); + const dataInLRU = await serviceWithDisabledRedis.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(dataInLRU).to.deep.eq(DATA, 'data is stored in local cache'); process.env.REDIS_ENABLED = 'true'; @@ -97,10 +97,10 @@ describe('@cache-service Acceptance Tests for shared cache', function () { it('Cache set by one instance can be accessed by another', async () => { const dataLabel = `${DATA_LABEL_PREFIX}4`; const otherServiceInstance = new CacheService(global.logger, registry); - await cacheService.set(dataLabel, DATA, CALLING_METHOD, undefined, undefined, true); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); await new Promise((r) => setTimeout(r, 200)); - const cachedData = await otherServiceInstance.getAsync(dataLabel, CALLING_METHOD); + const cachedData = await otherServiceInstance.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(cachedData).to.deep.eq(DATA, 'cached data is read correctly by other service instance'); }); @@ -108,7 +108,7 @@ describe('@cache-service Acceptance Tests for shared cache', function () { const dataLabel = `${DATA_LABEL_PREFIX}_redis_error`; let currentRedisEnabledEnv; - let cacheService; + let cacheService: CacheService; before(async () => { currentRedisEnabledEnv = process.env.REDIS_ENABLED; @@ -126,10 +126,10 @@ describe('@cache-service Acceptance Tests for shared cache', function () { }); it('test getAsync operation', async () => { - await cacheService.set(dataLabel, DATA, CALLING_METHOD, undefined, undefined); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); await new Promise((r) => setTimeout(r, 200)); - const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD); + const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(dataInLRU).to.deep.eq(DATA, 'data is stored in local cache'); }); @@ -140,21 +140,21 @@ describe('@cache-service Acceptance Tests for shared cache', function () { string: '5644', }; - await cacheService.multiSet(pairs, CALLING_METHOD, undefined, undefined); + await cacheService.multiSet(pairs, CALLING_METHOD, requestIdPrefix); await new Promise((r) => setTimeout(r, 200)); for (const key in pairs) { - const cachedValue = await cacheService.getAsync(key, CALLING_METHOD); + const cachedValue = await cacheService.getAsync(key, CALLING_METHOD, requestIdPrefix); expect(cachedValue).deep.equal(pairs[key]); } }); it('test delete operation', async () => { - await cacheService.set(dataLabel, DATA, CALLING_METHOD, undefined, undefined); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); await new Promise((r) => setTimeout(r, 200)); - await cacheService.delete(dataLabel, CALLING_METHOD); - const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD); + await cacheService.delete(dataLabel, CALLING_METHOD, requestIdPrefix); + const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); expect(dataInLRU).to.be.null; }); }); From 31aa020385ce88a907a7d04e80592db3eed9c98d Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 12 Sep 2024 12:44:48 +0300 Subject: [PATCH 17/48] Fixes polling tests Signed-off-by: Konstantina Blazhukova --- packages/relay/src/lib/poller.ts | 12 ++++++------ packages/ws-server/src/controllers/index.ts | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/relay/src/lib/poller.ts b/packages/relay/src/lib/poller.ts index b012af7af2..40125648ba 100644 --- a/packages/relay/src/lib/poller.ts +++ b/packages/relay/src/lib/poller.ts @@ -85,16 +85,16 @@ export class Poller { filters?.address || null, filters?.topics || null, { - requestIdPrefix: '', - requestIp: '', + requestIdPrefix: `[Request ID: ${event}]`, + requestIp: '0.0.0.0', } as IRequestDetails, ); poll.lastPolled = this.latestBlock; } else if (event === this.NEW_HEADS_EVENT && this.newHeadsEnabled) { data = await this.eth.getBlockByNumber('latest', filters?.includeTransactions ?? false, { - requestIdPrefix: '', - requestIp: '', + requestIdPrefix: `[Request ID: ${event}]`, + requestIp: '0.0.0.0', } as IRequestDetails); data.jsonrpc = '2.0'; poll.lastPolled = this.latestBlock; @@ -123,8 +123,8 @@ export class Poller { this.logger.info(`${LOGGER_PREFIX} Starting polling with interval=${this.pollingInterval}`); this.interval = setInterval(async () => { this.latestBlock = await this.eth.blockNumber({ - requestIdPrefix: '', - requestIp: '', + requestIdPrefix: `[Request ID: ${LOGGER_PREFIX}]`, + requestIp: '0.0.0.0', } as IRequestDetails); this.poll(); }, this.pollingInterval); diff --git a/packages/ws-server/src/controllers/index.ts b/packages/ws-server/src/controllers/index.ts index 5614dd5dc5..fb0c55d603 100644 --- a/packages/ws-server/src/controllers/index.ts +++ b/packages/ws-server/src/controllers/index.ts @@ -56,9 +56,10 @@ const handleSendingRequestsToRelay = async ({ logger, requestIdPrefix, connectionIdPrefix, + ctx, }): Promise => { logger.trace(`${connectionIdPrefix} ${requestIdPrefix}: Submitting request=${JSON.stringify(request)} to relay.`); - const requestDetails = { requestIdPrefix: requestIdPrefix, requestIp: request.ip } as IRequestDetails; + const requestDetails = { requestIdPrefix: requestIdPrefix, requestIp: '' } as IRequestDetails; try { const resolvedParams = resolveParams(method, params); const [service, methodName] = method.split('_'); @@ -71,10 +72,19 @@ const handleSendingRequestsToRelay = async ({ .eth() .filterService() [methodName](...resolvedParams, requestDetails); + } else if (methodName === 'estimateGas') { + txRes = await relay[service]()[methodName](...resolvedParams, null, requestDetails); + } else if (methodName === 'getStorageAt') { + txRes = await relay[service]()[methodName]( + resolvedParams[0], + resolvedParams[1], + requestDetails, + resolvedParams[2], + ); + } else { + txRes = await relay[service]()[methodName](...resolvedParams, requestDetails); } - txRes = await relay[service]()[methodName](...resolvedParams, requestDetails); - if (!txRes) { logger.trace( `${connectionIdPrefix} ${requestIdPrefix}: Fail to retrieve result for request=${JSON.stringify( From 09cbcbda5e90cdc9b06d82a456317d4c501ee3e7 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 12 Sep 2024 13:03:32 +0300 Subject: [PATCH 18/48] Removes unecessary 4th parameter in test for getStorageAt Signed-off-by: Konstantina Blazhukova --- packages/ws-server/tests/acceptance/getStorageAt.spec.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts index 011dadfd92..25fb863145 100644 --- a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts +++ b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts @@ -24,6 +24,7 @@ import { ethers, WebSocketProvider } from 'ethers'; import { WsTestConstant, WsTestHelper } from '../helper'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; +import { IRequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/IRequestDetails'; describe('@web-socket-batch-2 eth_getStorageAt', async function () { const METHOD_NAME = 'eth_getStorageAt'; @@ -36,7 +37,7 @@ describe('@web-socket-batch-2 eth_getStorageAt', async function () { [WsTestConstant.FAKE_TX_HASH, ''], [WsTestConstant.FAKE_TX_HASH, 36, 'latest'], [WsTestConstant.FAKE_TX_HASH, '0xhbar', 'latest'], - [WsTestConstant.FAKE_TX_HASH, '0x0', 'latest', '0xhedera'], + [WsTestConstant.FAKE_TX_HASH, '0x0', 'latest'], ]; // @notice: The simple contract artifacts (ABI & bytecode) below simply has one state at position 0, which will be assigned to the number `7` within the consutrctor after deployment @@ -55,9 +56,11 @@ describe('@web-socket-batch-2 eth_getStorageAt', async function () { accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; let requestId: string; + let requestDetails: IRequestDetails; before(async () => { - requestId = Utils.generateRequestId(); + requestId = `[Request ID: getStorageAtTest]`; + requestDetails = { requestIdPrefix: `${requestId}`, requestIp: '0.0.0.0' }; const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '2500000000'; //25 Hbar From 34844497c07e99193c7a0338c95b39eb4f734c1e Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 12 Sep 2024 13:11:13 +0300 Subject: [PATCH 19/48] Improves parameters handling in ws server Signed-off-by: Konstantina Blazhukova --- packages/ws-server/src/controllers/index.ts | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/ws-server/src/controllers/index.ts b/packages/ws-server/src/controllers/index.ts index fb0c55d603..6289c7cffb 100644 --- a/packages/ws-server/src/controllers/index.ts +++ b/packages/ws-server/src/controllers/index.ts @@ -64,6 +64,16 @@ const handleSendingRequestsToRelay = async ({ const resolvedParams = resolveParams(method, params); const [service, methodName] = method.split('_'); + // Rearrange the parameters for certain methods, since not everywhere requestDetails is last aparameter + const paramRearrangementMap: { [key: string]: (params: any[], requestDetails: IRequestDetails) => any[] } = { + estimateGas: (params, requestDetails) => [...params, null, requestDetails], + getStorageAt: (params, requestDetails) => [params[0], params[1], requestDetails, params[2]], + default: (params, requestDetails) => [...params, requestDetails], + }; + + const rearrangeParams = paramRearrangementMap[methodName] || paramRearrangementMap['default']; + const rearrangedParams = rearrangeParams(resolvedParams, requestDetails); + // Call the relay method with the resolved parameters. // Method will be validated by "verifySupportedMethod" before reaching this point. let txRes: any; @@ -71,18 +81,9 @@ const handleSendingRequestsToRelay = async ({ txRes = await relay .eth() .filterService() - [methodName](...resolvedParams, requestDetails); - } else if (methodName === 'estimateGas') { - txRes = await relay[service]()[methodName](...resolvedParams, null, requestDetails); - } else if (methodName === 'getStorageAt') { - txRes = await relay[service]()[methodName]( - resolvedParams[0], - resolvedParams[1], - requestDetails, - resolvedParams[2], - ); + [methodName](...rearrangedParams); } else { - txRes = await relay[service]()[methodName](...resolvedParams, requestDetails); + txRes = await relay[service]()[methodName](...rearrangedParams); } if (!txRes) { From 244ba0646173ade477301a03b1bfa0f79a61ab99 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 12 Sep 2024 13:16:21 +0300 Subject: [PATCH 20/48] Adds requestId to localLRUCache test Signed-off-by: Konstantina Blazhukova --- .../tests/lib/clients/localLRUCache.spec.ts | 95 ++++++++++--------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/packages/relay/tests/lib/clients/localLRUCache.spec.ts b/packages/relay/tests/lib/clients/localLRUCache.spec.ts index 446f9dcafb..97c52d554c 100644 --- a/packages/relay/tests/lib/clients/localLRUCache.spec.ts +++ b/packages/relay/tests/lib/clients/localLRUCache.spec.ts @@ -24,6 +24,7 @@ import { Registry } from 'prom-client'; import pino from 'pino'; import { LocalLRUCache } from '../../../src/lib/clients'; import constants from '../../../src/lib/constants'; +import { IRequestDetails } from '../../../dist/lib/types/IRequestDetails'; const logger = pino(); const registry = new Registry(); @@ -35,8 +36,10 @@ chai.use(chaiAsPromised); describe('LocalLRUCache Test Suite', async function () { this.timeout(10000); + let requestIdPrefix: string; this.beforeAll(() => { + requestIdPrefix = `[Request ID: localLRUCacheTest]`; localLRUCache = new LocalLRUCache(logger.child({ name: `cache` }), registry); }); @@ -46,58 +49,58 @@ describe('LocalLRUCache Test Suite', async function () { describe('verify simple cache', async function () { it('get on empty cache return null', async function () { - const cacheValue = await localLRUCache.get('test', callingMethod); + const cacheValue = await localLRUCache.get('test', callingMethod, requestIdPrefix); expect(cacheValue).to.be.null; }); it('get on valid string cache returns non null', async function () { const key = 'key'; const expectedValue = 'value'; - await localLRUCache.set(key, expectedValue, callingMethod); - const cacheValue = await localLRUCache.get(key, callingMethod); + await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); + const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid int cache returns non null', async function () { const key = 'key'; const expectedValue = 1; - await localLRUCache.set(key, expectedValue, callingMethod); - const cacheValue = await localLRUCache.get(key, callingMethod); + await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); + const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid false boolean cache returns non null', async function () { const key = 'key'; const expectedValue = false; - await localLRUCache.set(key, expectedValue, callingMethod); - const cacheValue = await localLRUCache.get(key, callingMethod); + await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); + const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid true boolean cache returns non null', async function () { const key = 'key'; const expectedValue = true; - await localLRUCache.set(key, expectedValue, callingMethod); - const cacheValue = await localLRUCache.get(key, callingMethod); + await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); + const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid object cache returns non null', async function () { const key = 'key'; const expectedValue = { key: 'value' }; - await localLRUCache.set(key, expectedValue, callingMethod); - const cacheValue = await localLRUCache.get(key, callingMethod); + await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); + const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); expect(cacheValue).to.be.equal(expectedValue); }); it('delete a valid object', async function () { const key = 'key'; const expectedValue = { key: 'value' }; - await localLRUCache.set(key, expectedValue, callingMethod); - const cacheValueBeforeDelete = await localLRUCache.get(key, callingMethod); - localLRUCache.delete(key, callingMethod); + await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); + const cacheValueBeforeDelete = await localLRUCache.get(key, callingMethod, requestIdPrefix); + localLRUCache.delete(key, callingMethod, requestIdPrefix); - const cacheValueAfterDelete = await localLRUCache.get(key, callingMethod); + const cacheValueAfterDelete = await localLRUCache.get(key, callingMethod, requestIdPrefix); expect(cacheValueBeforeDelete).to.not.be.null; expect(cacheValueAfterDelete).to.be.null; }); @@ -119,12 +122,12 @@ describe('LocalLRUCache Test Suite', async function () { }; Object.entries(keyValuePairs).forEach(([key, value]) => { - customLocalLRUCache.set(key, value, callingMethod); + customLocalLRUCache.set(key, value, callingMethod, requestIdPrefix); }); - const key1 = await customLocalLRUCache.get('key1', callingMethod); - const key2 = await customLocalLRUCache.get('key2', callingMethod); - const key3 = await customLocalLRUCache.get('key3', callingMethod); + const key1 = await customLocalLRUCache.get('key1', callingMethod, requestIdPrefix); + const key2 = await customLocalLRUCache.get('key2', callingMethod, requestIdPrefix); + const key3 = await customLocalLRUCache.get('key3', callingMethod, requestIdPrefix); // expect cache to have capped at max size expect(key1).to.be.null; // key1 should have been evicted expect(key2).to.be.equal(keyValuePairs.key2); @@ -135,10 +138,10 @@ describe('LocalLRUCache Test Suite', async function () { const customLocalLRUCache = new LocalLRUCache(logger.child({ name: `cache` }), registry); const key = 'key'; let valueCount = 0; // keep track of values sets - await customLocalLRUCache.set(key, ++valueCount, callingMethod); - await customLocalLRUCache.set(key, ++valueCount, callingMethod); - await customLocalLRUCache.set(key, ++valueCount, callingMethod); - const cacheValue = await customLocalLRUCache.get(key, callingMethod); + await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestIdPrefix); + await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestIdPrefix); + await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestIdPrefix); + const cacheValue = await customLocalLRUCache.get(key, callingMethod, requestIdPrefix); // expect cache to have latest value for key expect(cacheValue).to.be.equal(valueCount); }); @@ -146,9 +149,9 @@ describe('LocalLRUCache Test Suite', async function () { it('verify cache ttl nature', async function () { const customLocalLRUCache = new LocalLRUCache(logger.child({ name: `cache` }), registry); const key = 'key'; - await customLocalLRUCache.set(key, 'value', callingMethod, 100); // set ttl to 1 ms + await customLocalLRUCache.set(key, 'value', callingMethod, requestIdPrefix, 100); // set ttl to 1 ms await new Promise((r) => setTimeout(r, 500)); // wait for ttl to expire - const cacheValue = await customLocalLRUCache.get(key, callingMethod); + const cacheValue = await customLocalLRUCache.get(key, callingMethod, requestIdPrefix); expect(cacheValue).to.be.null; }); }); @@ -157,17 +160,17 @@ describe('LocalLRUCache Test Suite', async function () { it('should retrieve keys matching a glob-style pattern with *', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await localLRUCache.set(keys[i], `value${i}`, callingMethod); + await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); } - await expect(localLRUCache.keys('h*llo', callingMethod)).to.eventually.have.members(keys); + await expect(localLRUCache.keys('h*llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with ?', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await localLRUCache.set(keys[i], `value${i}`, callingMethod); + await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); } - await expect(localLRUCache.keys('h?llo', callingMethod)).to.eventually.have.members(keys); + await expect(localLRUCache.keys('h?llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with []', async function () { @@ -175,10 +178,10 @@ describe('LocalLRUCache Test Suite', async function () { const key2 = 'hallo'; const pattern = 'h[ae]llo'; - await localLRUCache.set(key1, 'value1', callingMethod); - await localLRUCache.set(key2, 'value2', callingMethod); + await localLRUCache.set(key1, 'value1', callingMethod, requestIdPrefix); + await localLRUCache.set(key2, 'value2', callingMethod, requestIdPrefix); - const keys = await localLRUCache.keys(pattern, callingMethod); + const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2]); }); @@ -187,10 +190,10 @@ describe('LocalLRUCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[^e]llo'; - await localLRUCache.set(key1, 'value1', callingMethod); - await localLRUCache.set(key2, 'value2', callingMethod); + await localLRUCache.set(key1, 'value1', callingMethod, requestIdPrefix); + await localLRUCache.set(key2, 'value2', callingMethod, requestIdPrefix); - const keys = await localLRUCache.keys(pattern, callingMethod); + const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2]); }); @@ -199,22 +202,22 @@ describe('LocalLRUCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[a-b]llo'; - await localLRUCache.set(key1, 'value1', callingMethod); - await localLRUCache.set(key2, 'value2', callingMethod); + await localLRUCache.set(key1, 'value1', callingMethod, requestIdPrefix); + await localLRUCache.set(key2, 'value2', callingMethod, requestIdPrefix); - const keys = await localLRUCache.keys(pattern, callingMethod); + const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2]); }); it('should retrieve keys matching a pattern with escaped special characters', async function () { const keys = ['h*llo', 'h?llo', 'h[llo', 'h]llo']; for (let i = 0; i < keys.length; i++) { - await localLRUCache.set(keys[i], `value${i}`, callingMethod); + await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); } for (const key of keys) { - await expect(localLRUCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod)).eventually.has.members([ - key, - ]); + await expect( + localLRUCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod, requestIdPrefix), + ).eventually.has.members([key]); } }); @@ -224,11 +227,11 @@ describe('LocalLRUCache Test Suite', async function () { const key3 = 'age'; const pattern = '*'; - await localLRUCache.set(key1, 'Jack', callingMethod); - await localLRUCache.set(key2, 'Stuntman', callingMethod); - await localLRUCache.set(key3, '35', callingMethod); + await localLRUCache.set(key1, 'Jack', callingMethod, requestIdPrefix); + await localLRUCache.set(key2, 'Stuntman', callingMethod, requestIdPrefix); + await localLRUCache.set(key3, '35', callingMethod, requestIdPrefix); - const keys = await localLRUCache.keys(pattern, callingMethod); + const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2, key3]); }); }); From aa46c0dab188212a5fc239e0f2cfece3db4abd12 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 12 Sep 2024 13:19:46 +0300 Subject: [PATCH 21/48] Fixes redisCache test Signed-off-by: Konstantina Blazhukova --- .../tests/lib/clients/redisCache.spec.ts | 135 +++++++++--------- 1 file changed, 69 insertions(+), 66 deletions(-) diff --git a/packages/relay/tests/lib/clients/redisCache.spec.ts b/packages/relay/tests/lib/clients/redisCache.spec.ts index 89d5a6a485..2509997106 100644 --- a/packages/relay/tests/lib/clients/redisCache.spec.ts +++ b/packages/relay/tests/lib/clients/redisCache.spec.ts @@ -33,6 +33,7 @@ describe('RedisCache Test Suite', async function () { const logger = pino(); const registry = new Registry(); const callingMethod = 'RedisCacheTest'; + const requestIdPrefix = 'redisCacheTest'; let redisCache: RedisCache; @@ -57,7 +58,7 @@ describe('RedisCache Test Suite', async function () { describe('Get and Set Test Suite', async function () { it('should get null on empty cache', async function () { - const cacheValue = await redisCache.get('test', callingMethod); + const cacheValue = await redisCache.get('test', callingMethod, requestIdPrefix); expect(cacheValue).to.be.null; }); @@ -65,9 +66,9 @@ describe('RedisCache Test Suite', async function () { const key = 'int'; const value = 1; - await redisCache.set(key, value, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).equal(value); }); @@ -75,9 +76,9 @@ describe('RedisCache Test Suite', async function () { const key = 'boolean'; const value = false; - await redisCache.set(key, value, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).equal(value); }); @@ -85,9 +86,9 @@ describe('RedisCache Test Suite', async function () { const key = 'array'; const value = ['false']; - await redisCache.set(key, value, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).deep.equal(value); }); @@ -95,9 +96,9 @@ describe('RedisCache Test Suite', async function () { const key = 'object'; const value = { result: true }; - await redisCache.set(key, value, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).deep.equal(value); }); @@ -106,14 +107,14 @@ describe('RedisCache Test Suite', async function () { const value = 1; const ttl = 500; - await redisCache.set(key, value, callingMethod, ttl); + await redisCache.set(key, value, callingMethod, requestIdPrefix, ttl); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).equal(value); await new Promise((resolve) => setTimeout(resolve, ttl + 100)); - const expiredValue = await redisCache.get(key, callingMethod); + const expiredValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(expiredValue).to.be.null; }); @@ -122,14 +123,14 @@ describe('RedisCache Test Suite', async function () { const value = 1; const ttl = 1500; - await redisCache.set(key, value, callingMethod, ttl); + await redisCache.set(key, value, callingMethod, requestIdPrefix, ttl); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).equal(value); await new Promise((resolve) => setTimeout(resolve, ttl + 100)); - const expiredValue = await redisCache.get(key, callingMethod); + const expiredValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(expiredValue).to.be.null; }); }); @@ -144,10 +145,10 @@ describe('RedisCache Test Suite', async function () { object: { result: true }, }; - await redisCache.multiSet(keyValuePairs, callingMethod); + await redisCache.multiSet(keyValuePairs, callingMethod, requestIdPrefix); for (const key in keyValuePairs) { - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).deep.equal(keyValuePairs[key]); } }); @@ -163,10 +164,10 @@ describe('RedisCache Test Suite', async function () { object: { result: true }, }; - await redisCache.pipelineSet(keyValuePairs, callingMethod); + await redisCache.pipelineSet(keyValuePairs, callingMethod, requestIdPrefix); for (const key in keyValuePairs) { - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).deep.equal(keyValuePairs[key]); } }); @@ -180,17 +181,17 @@ describe('RedisCache Test Suite', async function () { object: { result: true }, }; - await redisCache.pipelineSet(keyValuePairs, callingMethod, 500); + await redisCache.pipelineSet(keyValuePairs, callingMethod, requestIdPrefix, 500); for (const key in keyValuePairs) { - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).deep.equal(keyValuePairs[key]); } await new Promise((resolve) => setTimeout(resolve, 500)); for (const key in keyValuePairs) { - const expiredValue = await redisCache.get(key, callingMethod); + const expiredValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(expiredValue).to.be.null; } }); @@ -201,10 +202,10 @@ describe('RedisCache Test Suite', async function () { const key = 'int'; const value = 1; - await redisCache.set(key, value, callingMethod); - await redisCache.delete(key, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.delete(key, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; }); @@ -212,10 +213,10 @@ describe('RedisCache Test Suite', async function () { const key = 'boolean'; const value = false; - await redisCache.set(key, value, callingMethod); - await redisCache.delete(key, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.delete(key, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; }); @@ -223,10 +224,10 @@ describe('RedisCache Test Suite', async function () { const key = 'array'; const value = ['false']; - await redisCache.set(key, value, callingMethod); - await redisCache.delete(key, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.delete(key, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; }); @@ -234,10 +235,10 @@ describe('RedisCache Test Suite', async function () { const key = 'object'; const value = { result: true }; - await redisCache.set(key, value, callingMethod); - await redisCache.delete(key, callingMethod); + await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.delete(key, callingMethod, requestIdPrefix); - const cachedValue = await redisCache.get(key, callingMethod); + const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); expect(cachedValue).to.be.null; }); }); @@ -247,7 +248,7 @@ describe('RedisCache Test Suite', async function () { const key = 'non-existing'; const amount = 1; - const newValue = await redisCache.incrBy(key, amount, callingMethod); + const newValue = await redisCache.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).equal(amount); }); @@ -256,8 +257,8 @@ describe('RedisCache Test Suite', async function () { const initialValue = 5; const amount = 3; - await redisCache.set(key, initialValue, callingMethod); - const newValue = await redisCache.incrBy(key, amount, callingMethod); + await redisCache.set(key, initialValue, callingMethod, requestIdPrefix); + const newValue = await redisCache.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).equal(initialValue + amount); }); @@ -266,8 +267,8 @@ describe('RedisCache Test Suite', async function () { const initialValue = 5; const amount = -2; - await redisCache.set(key, initialValue, callingMethod); - const newValue = await redisCache.incrBy(key, amount, callingMethod); + await redisCache.set(key, initialValue, callingMethod, requestIdPrefix); + const newValue = await redisCache.incrBy(key, amount, callingMethod, requestIdPrefix); expect(newValue).equal(initialValue + amount); }); }); @@ -277,10 +278,10 @@ describe('RedisCache Test Suite', async function () { const key = 'non-existing-list'; const value = 'item1'; - const length = await redisCache.rPush(key, value, callingMethod); + const length = await redisCache.rPush(key, value, callingMethod, requestIdPrefix); expect(length).equal(1); - const list = await redisCache.lRange(key, 0, -1, callingMethod); + const list = await redisCache.lRange(key, 0, -1, callingMethod, requestIdPrefix); expect(list).deep.equal([value]); }); @@ -289,11 +290,11 @@ describe('RedisCache Test Suite', async function () { const initialList = ['item1']; const newValue = 'item2'; - await redisCache.rPush(key, initialList[0], callingMethod); - const length = await redisCache.rPush(key, newValue, callingMethod); + await redisCache.rPush(key, initialList[0], callingMethod, requestIdPrefix); + const length = await redisCache.rPush(key, newValue, callingMethod, requestIdPrefix); expect(length).equal(2); - const list = await redisCache.lRange(key, 0, -1, callingMethod); + const list = await redisCache.lRange(key, 0, -1, callingMethod, requestIdPrefix); expect(list).deep.equal([...initialList, newValue]); }); }); @@ -304,7 +305,7 @@ describe('RedisCache Test Suite', async function () { const start = 0; const end = 1; - const list = await redisCache.lRange(key, start, end, callingMethod); + const list = await redisCache.lRange(key, start, end, callingMethod, requestIdPrefix); expect(list).deep.equal([]); }); @@ -313,10 +314,10 @@ describe('RedisCache Test Suite', async function () { const list = ['item1', 'item2', 'item3']; for (const item of list) { - await redisCache.rPush(key, item, callingMethod); + await redisCache.rPush(key, item, callingMethod, requestIdPrefix); } - const range = await redisCache.lRange(key, 0, 1, callingMethod); + const range = await redisCache.lRange(key, 0, 1, callingMethod, requestIdPrefix); expect(range).deep.equal(['item1', 'item2']); }); }); @@ -325,17 +326,17 @@ describe('RedisCache Test Suite', async function () { it('should retrieve keys matching a glob-style pattern with *', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await redisCache.set(keys[i], `value${i}`, callingMethod); + await redisCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); } - await expect(redisCache.keys('h*llo', callingMethod)).to.eventually.have.members(keys); + await expect(redisCache.keys('h*llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with ?', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await redisCache.set(keys[i], `value${i}`, callingMethod); + await redisCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); } - await expect(redisCache.keys('h?llo', callingMethod)).to.eventually.have.members(keys); + await expect(redisCache.keys('h?llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with []', async function () { @@ -343,10 +344,10 @@ describe('RedisCache Test Suite', async function () { const key2 = 'hallo'; const pattern = 'h[ae]llo'; - await redisCache.set(key1, 'value1', callingMethod); - await redisCache.set(key2, 'value2', callingMethod); + await redisCache.set(key1, 'value1', callingMethod, requestIdPrefix); + await redisCache.set(key2, 'value2', callingMethod, requestIdPrefix); - const keys = await redisCache.keys(pattern, callingMethod); + const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2]); }); @@ -355,10 +356,10 @@ describe('RedisCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[^e]llo'; - await redisCache.set(key1, 'value1', callingMethod); - await redisCache.set(key2, 'value2', callingMethod); + await redisCache.set(key1, 'value1', callingMethod, requestIdPrefix); + await redisCache.set(key2, 'value2', callingMethod, requestIdPrefix); - const keys = await redisCache.keys(pattern, callingMethod); + const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2]); }); @@ -367,20 +368,22 @@ describe('RedisCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[a-b]llo'; - await redisCache.set(key1, 'value1', callingMethod); - await redisCache.set(key2, 'value2', callingMethod); + await redisCache.set(key1, 'value1', callingMethod, requestIdPrefix); + await redisCache.set(key2, 'value2', callingMethod, requestIdPrefix); - const keys = await redisCache.keys(pattern, callingMethod); + const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2]); }); it('should retrieve keys matching a pattern with escaped special characters', async function () { const keys = ['h*llo', 'h?llo', 'h[llo', 'h]llo']; for (let i = 0; i < keys.length; i++) { - await redisCache.set(keys[i], `value${i}`, callingMethod); + await redisCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); } for (const key of keys) { - await expect(redisCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod)).eventually.has.members([key]); + await expect( + redisCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod, requestIdPrefix), + ).eventually.has.members([key]); } }); @@ -390,11 +393,11 @@ describe('RedisCache Test Suite', async function () { const key3 = 'age'; const pattern = '*'; - await redisCache.set(key1, 'Jack', callingMethod); - await redisCache.set(key2, 'Stuntman', callingMethod); - await redisCache.set(key3, '35', callingMethod); + await redisCache.set(key1, 'Jack', callingMethod, requestIdPrefix); + await redisCache.set(key2, 'Stuntman', callingMethod, requestIdPrefix); + await redisCache.set(key3, '35', callingMethod, requestIdPrefix); - const keys = await redisCache.keys(pattern, callingMethod); + const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); expect(keys).to.include.members([key1, key2, key3]); }); }); From eb218e2da3827c40113c5ef8bf30d428d26bfd28 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 12 Sep 2024 13:27:39 +0300 Subject: [PATCH 22/48] Adds requestDetails to poller with generated request id Signed-off-by: Konstantina Blazhukova --- packages/relay/src/lib/poller.ts | 9 +++++---- packages/relay/src/utils.ts | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/relay/src/lib/poller.ts b/packages/relay/src/lib/poller.ts index 40125648ba..40a306dcd0 100644 --- a/packages/relay/src/lib/poller.ts +++ b/packages/relay/src/lib/poller.ts @@ -22,6 +22,7 @@ import { Eth } from '../index'; import { Logger } from 'pino'; import { Registry, Gauge } from 'prom-client'; import { IRequestDetails } from './types/IRequestDetails'; +import { Utils } from '../utils'; export interface Poll { tag: string; @@ -85,15 +86,15 @@ export class Poller { filters?.address || null, filters?.topics || null, { - requestIdPrefix: `[Request ID: ${event}]`, - requestIp: '0.0.0.0', + requestIdPrefix: `[Request ID: ${Utils.generateRequestId()}]`, + requestIp: '', } as IRequestDetails, ); poll.lastPolled = this.latestBlock; } else if (event === this.NEW_HEADS_EVENT && this.newHeadsEnabled) { data = await this.eth.getBlockByNumber('latest', filters?.includeTransactions ?? false, { - requestIdPrefix: `[Request ID: ${event}]`, + requestIdPrefix: `[Request ID: ${Utils.generateRequestId()}]`, requestIp: '0.0.0.0', } as IRequestDetails); data.jsonrpc = '2.0'; @@ -123,7 +124,7 @@ export class Poller { this.logger.info(`${LOGGER_PREFIX} Starting polling with interval=${this.pollingInterval}`); this.interval = setInterval(async () => { this.latestBlock = await this.eth.blockNumber({ - requestIdPrefix: `[Request ID: ${LOGGER_PREFIX}]`, + requestIdPrefix: `[Request ID: ${Utils.generateRequestId()}]`, requestIp: '0.0.0.0', } as IRequestDetails); this.poll(); diff --git a/packages/relay/src/utils.ts b/packages/relay/src/utils.ts index 463dd3793a..369b347d70 100644 --- a/packages/relay/src/utils.ts +++ b/packages/relay/src/utils.ts @@ -20,6 +20,7 @@ import { PrivateKey } from '@hashgraph/sdk'; import constants from './lib/constants'; +import crypto from 'crypto'; export class Utils { public static readonly addPercentageBufferToGasPrice = (gasPrice: number): number => { @@ -55,4 +56,13 @@ export class Utils { throw new Error(`Invalid OPERATOR_KEY_FORMAT provided: ${process.env.OPERATOR_KEY_FORMAT}`); } } + + /** + * Generates a random trace ID for requests. + * + * @returns {string} The generated random trace ID. + */ + public static generateRequestId = (): string => { + return crypto.randomUUID(); + }; } From c74859704deb0ffa8d90c1843498ef29a4d61cd0 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Thu, 12 Sep 2024 15:30:09 +0300 Subject: [PATCH 23/48] chore: draft changes Signed-off-by: Victor Yanev --- docs/design/distributed-cache.md | 24 +- packages/relay/src/index.ts | 79 ++-- .../src/lib/clients/cache/ICacheClient.ts | 14 +- .../lib/clients/cache/IRedisCacheClient.ts | 13 +- .../src/lib/clients/cache/localLRUCache.ts | 51 ++- .../relay/src/lib/clients/cache/redisCache.ts | 79 ++-- .../relay/src/lib/clients/mirrorNodeClient.ts | 261 ++++++------ packages/relay/src/lib/clients/sdkClient.ts | 138 ++++--- packages/relay/src/lib/eth.ts | 385 +++++++++--------- packages/relay/src/lib/hbarlimiter/index.ts | 24 +- packages/relay/src/lib/poller.ts | 2 +- .../lib/services/cacheService/cacheService.ts | 143 ++++--- .../services/debugService/IDebugService.ts | 6 +- .../src/lib/services/debugService/index.ts | 57 +-- .../ethCommonService/ICommonService.ts | 19 +- .../ethService/ethCommonService/index.ts | 66 +-- .../ethFilterService/IFilterService.ts | 2 +- .../ethService/ethFilterService/index.ts | 75 ++-- .../services/metricService/metricService.ts | 25 +- .../relay/src/lib/types/IRequestDetails.ts | 4 - .../relay/src/lib/types/RequestDetails.ts | 35 ++ packages/relay/src/lib/types/events.ts | 6 +- .../tests/lib/clients/redisCache.spec.ts | 141 ++++--- packages/relay/tests/lib/eth/eth_call.spec.ts | 2 +- .../relay/tests/lib/eth/eth_common.spec.ts | 2 +- .../tests/lib/eth/eth_feeHistory.spec.ts | 2 +- .../relay/tests/lib/eth/eth_gasPrice.spec.ts | 2 +- .../tests/lib/eth/eth_getBlockByHash.spec.ts | 2 +- .../lib/eth/eth_getBlockByNumber.spec.ts | 2 +- ...eth_getBlockTransactionCountByHash.spec.ts | 2 +- ...h_getBlockTransactionCountByNumber.spec.ts | 2 +- .../tests/lib/eth/eth_getStorageAt.spec.ts | 2 +- .../lib/eth/eth_getTransactionReceipt.spec.ts | 2 +- .../lib/eth/eth_sendRawTransaction.spec.ts | 2 +- packages/relay/tests/lib/hbarLimiter.spec.ts | 46 ++- .../relay/tests/lib/mirrorNodeClient.spec.ts | 18 +- packages/relay/tests/lib/openrpc.spec.ts | 6 +- packages/relay/tests/lib/sdkClient.spec.ts | 37 +- .../cacheService/cacheService.spec.ts | 149 +++---- .../tests/lib/services/eth/filter.spec.ts | 98 +++-- .../metricService/metricService.spec.ts | 2 +- 41 files changed, 1101 insertions(+), 926 deletions(-) delete mode 100644 packages/relay/src/lib/types/IRequestDetails.ts create mode 100644 packages/relay/src/lib/types/RequestDetails.ts diff --git a/docs/design/distributed-cache.md b/docs/design/distributed-cache.md index 0a323695d7..bf9178f3bb 100644 --- a/docs/design/distributed-cache.md +++ b/docs/design/distributed-cache.md @@ -19,9 +19,9 @@ Important details is that, if an operator does not want to use Redis or it went ```javascript interface ICacheClient { - get(key: string, callingMethod: string, requestIdPrefix?: string): any; - set(key: string, value: any, callingMethod: string, ttl?: number, requestIdPrefix?: string): void; - delete(key: string, callingMethod: string, requestIdPrefix?: string): void; + get(key: string, callingMethod: string): any; + set(key: string, value: any, callingMethod: string, ttl?: number): void; + delete(key: string, callingMethod: string): void; clear(): void; } ``` @@ -40,15 +40,15 @@ class LocalLRUCache implements ICacheClient{ public constructor() { this.cache = new LRU(this.options); } - get(key: string, callingMethod: string, requestIdPrefix?: string) { + get(key: string, callingMethod: string) { // Get item from internal cache implementation } - set(key: string, value: any, callingMethod: string, ttl?: number, requestIdPrefix?: string) { + set(key: string, value: any, callingMethod: string, ttl?: number) { // Set item to internal cache implementation } - delete(key: string, callingMethod: string, requestIdPrefix?: string) { + delete(key: string, callingMethod: string) { // Delete item from internal cache implementation } @@ -81,15 +81,15 @@ class RedisCache implements ICacheClient{ this.cache = client; } - get(key: string, callingMethod: string, requestIdPrefix?: string) { + get(key: string, callingMethod: string) { // Get item from shared cache implementation } - set(key: string, value: any, callingMethod: string, ttl?: number, requestIdPrefix?: string) { + set(key: string, value: any, callingMethod: string, ttl?: number) { // Set item to shared cache implementation } - delete(key: string, callingMethod: string, requestIdPrefix?: string) { + delete(key: string, callingMethod: string) { // Delete item from shared cache implementation } @@ -120,19 +120,19 @@ class CacheClientService{ const sharedCache = new RedisCache(); } - get(key: string, callingMethod: string, requestIdPrefix?: string, shared: boolean = false) { + get(key: string, callingMethod: string, shared: boolean = false) { // Depending on the shared boolean, this method decide from where it should request the data. // Fallbacks to internalCache in case of error from the shared cache. // Getting from shared cache depends on REDIS_ENABLED env. variable } - set(key: string, value: any, callingMethod: string, ttl?: number, requestIdPrefix?: string, shared: boolean = false) { + set(key: string, value: any, callingMethod: string, ttl?: number, shared: boolean = false) { // Depending on the shared boolean, this method decide where it should save the data. // Fallbacks to internalCache in case of error from the shared cache. // Setting to shared cache depends on REDIS_ENABLED env. variable } - delete(key: string, callingMethod: string, requestIdPrefix?: string, shared: boolean = false) { + delete(key: string, callingMethod: string, shared: boolean = false) { // Depending on the shared boolean, this method decide from where it should delete the data. // Fallbacks to internalCache in case of error from the shared cache. // Deleting from shared cache depends on REDIS_ENABLED env. variable diff --git a/packages/relay/src/index.ts b/packages/relay/src/index.ts index 23d870a40b..fb52f3087d 100644 --- a/packages/relay/src/index.ts +++ b/packages/relay/src/index.ts @@ -26,9 +26,10 @@ import { MirrorNodeClientError } from './lib/errors/MirrorNodeClientError'; import { MirrorNodeClient } from './lib/clients'; import { IFilterService } from './lib/services/ethService/ethFilterService/IFilterService'; import { IDebugService } from './lib/services/debugService/IDebugService'; -import { IRequestDetails } from '../src/lib/types/IRequestDetails'; +import { RequestDetails } from './lib/types/RequestDetails'; +import { SDKClientError } from './lib/errors/SDKClientError'; -export { JsonRpcError, predefined, MirrorNodeClientError, WebSocketError }; +export { JsonRpcError, predefined, MirrorNodeClientError, WebSocketError, SDKClientError }; export { RelayImpl } from './lib/relay'; @@ -63,33 +64,33 @@ export interface Net { } export interface Eth { - blockNumber(requestDetails: IRequestDetails): Promise; + blockNumber(requestDetails: RequestDetails): Promise; - call(call: any, blockParam: string | object | null, requestDetails: IRequestDetails): Promise; + call(call: any, blockParam: string | object | null, requestDetails: RequestDetails): Promise; - coinbase(requestDetails: IRequestDetails): JsonRpcError; + coinbase(requestDetails: RequestDetails): JsonRpcError; estimateGas( transaction: IContractCallRequest, blockParam: string | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise; - gasPrice(requestDetails: IRequestDetails): Promise; + gasPrice(requestDetails: RequestDetails): Promise; - getBalance(account: string, blockNumber: string | null, requestDetails: IRequestDetails): Promise; + getBalance(account: string, blockNumber: string | null, requestDetails: RequestDetails): Promise; - getBlockByHash(hash: string, showDetails: boolean, requestDetails: IRequestDetails): Promise; + getBlockByHash(hash: string, showDetails: boolean, requestDetails: RequestDetails): Promise; - getBlockByNumber(blockNum: string, showDetails: boolean, requestDetails: IRequestDetails): Promise; + getBlockByNumber(blockNum: string, showDetails: boolean, requestDetails: RequestDetails): Promise; - getBlockTransactionCountByHash(hash: string, requestDetails: IRequestDetails): Promise; + getBlockTransactionCountByHash(hash: string, requestDetails: RequestDetails): Promise; - getBlockTransactionCountByNumber(blockNum: string, requestDetails: IRequestDetails): Promise; + getBlockTransactionCountByNumber(blockNum: string, requestDetails: RequestDetails): Promise; - getCode(address: string, blockNumber: string | null, requestDetails: IRequestDetails): Promise; + getCode(address: string, blockNumber: string | null, requestDetails: RequestDetails): Promise; - chainId(requestDetails: IRequestDetails): string; + chainId(requestDetails: RequestDetails): string; getLogs( blockHash: string | null, @@ -97,78 +98,78 @@ export interface Eth { toBlock: string | null, address: string | string[] | null, topics: any[] | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise; getStorageAt( address: string, slot: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, blockNumber: string | null, ): Promise; getTransactionByBlockHashAndIndex( hash: string, index: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise; getTransactionByBlockNumberAndIndex( blockNum: string, index: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise; - getTransactionByHash(hash: string, requestDetails: IRequestDetails): Promise; + getTransactionByHash(hash: string, requestDetails: RequestDetails): Promise; getTransactionCount( address: string, blockNum: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise; - getTransactionReceipt(hash: string, requestDetails: IRequestDetails): Promise; + getTransactionReceipt(hash: string, requestDetails: RequestDetails): Promise; - getUncleByBlockHashAndIndex(requestDetails: IRequestDetails): Promise; + getUncleByBlockHashAndIndex(requestDetails: RequestDetails): Promise; - getUncleByBlockNumberAndIndex(requestDetails: IRequestDetails): Promise; + getUncleByBlockNumberAndIndex(requestDetails: RequestDetails): Promise; - getUncleCountByBlockHash(requestDetails: IRequestDetails): Promise; + getUncleCountByBlockHash(requestDetails: RequestDetails): Promise; - getUncleCountByBlockNumber(requestDetails: IRequestDetails): Promise; + getUncleCountByBlockNumber(requestDetails: RequestDetails): Promise; - getWork(requestDetails: IRequestDetails): JsonRpcError; + getWork(requestDetails: RequestDetails): JsonRpcError; feeHistory( blockCount: number, newestBlock: string, rewardPercentiles: Array | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise; - hashrate(requestDetails: IRequestDetails): Promise; + hashrate(requestDetails: RequestDetails): Promise; - maxPriorityFeePerGas(requestDetails: IRequestDetails): Promise; + maxPriorityFeePerGas(requestDetails: RequestDetails): Promise; - mining(requestDetails: IRequestDetails): Promise; + mining(requestDetails: RequestDetails): Promise; - protocolVersion(requestDetails: IRequestDetails): JsonRpcError; + protocolVersion(requestDetails: RequestDetails): JsonRpcError; - sendRawTransaction(transaction: string, requestDetails: IRequestDetails): Promise; + sendRawTransaction(transaction: string, requestDetails: RequestDetails): Promise; - sendTransaction(requestDetails: IRequestDetails): JsonRpcError; + sendTransaction(requestDetails: RequestDetails): JsonRpcError; - sign(requestDetails: IRequestDetails): JsonRpcError; + sign(requestDetails: RequestDetails): JsonRpcError; - signTransaction(requestDetails: IRequestDetails): JsonRpcError; + signTransaction(requestDetails: RequestDetails): JsonRpcError; - submitHashrate(requestDetails: IRequestDetails): JsonRpcError; + submitHashrate(requestDetails: RequestDetails): JsonRpcError; - submitWork(requestDetails: IRequestDetails): Promise; + submitWork(requestDetails: RequestDetails): Promise; - syncing(requestDetails: IRequestDetails): Promise; + syncing(requestDetails: RequestDetails): Promise; - accounts(requestDetails: IRequestDetails): Array; + accounts(requestDetails: RequestDetails): Array; filterService(): IFilterService; diff --git a/packages/relay/src/lib/clients/cache/ICacheClient.ts b/packages/relay/src/lib/clients/cache/ICacheClient.ts index c73bff3ecc..b4dfd6b576 100644 --- a/packages/relay/src/lib/clients/cache/ICacheClient.ts +++ b/packages/relay/src/lib/clients/cache/ICacheClient.ts @@ -18,17 +18,19 @@ * */ +import { RequestDetails } from '../../types/RequestDetails'; + export interface ICacheClient { - keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise; - get(key: string, callingMethod: string, requestIdPrefix: string): Promise; - set(key: string, value: any, callingMethod: string, requestIdPrefix: string, ttl?: number): Promise; - multiSet(keyValuePairs: Record, callingMethod: string, requestIdPrefix: string): Promise; + keys(pattern: string, callingMethod: string, requestDetails: RequestDetails): Promise; + get(key: string, callingMethod: string, requestDetails: RequestDetails): Promise; + set(key: string, value: any, callingMethod: string, requestDetails: RequestDetails, ttl?: number): Promise; + multiSet(keyValuePairs: Record, callingMethod: string, requestDetails: RequestDetails): Promise; pipelineSet( keyValuePairs: Record, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ttl?: number | undefined, ): Promise; - delete(key: string, callingMethod: string, requestIdPrefix: string): Promise; + delete(key: string, callingMethod: string, requestDetails: RequestDetails): Promise; clear(): Promise; } diff --git a/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts b/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts index 52058c7eeb..d72a9eac9b 100644 --- a/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts +++ b/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts @@ -19,10 +19,17 @@ */ import type { ICacheClient } from './ICacheClient'; +import { RequestDetails } from '../../types/RequestDetails'; export interface IRedisCacheClient extends ICacheClient { disconnect: () => Promise; - incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix: string): Promise; - rPush(key: string, value: any, callingMethod: string, requestIdPrefix: string): Promise; - lRange(key: string, start: number, end: number, callingMethod: string, requestIdPrefix: string): Promise; + incrBy(key: string, amount: number, callingMethod: string, requestDetails: RequestDetails): Promise; + rPush(key: string, value: any, callingMethod: string, requestDetails: RequestDetails): Promise; + lRange( + key: string, + start: number, + end: number, + callingMethod: string, + requestDetails: RequestDetails, + ): Promise; } diff --git a/packages/relay/src/lib/clients/cache/localLRUCache.ts b/packages/relay/src/lib/clients/cache/localLRUCache.ts index eb76e9671b..17ebc394ad 100644 --- a/packages/relay/src/lib/clients/cache/localLRUCache.ts +++ b/packages/relay/src/lib/clients/cache/localLRUCache.ts @@ -23,6 +23,7 @@ import { Gauge, Registry } from 'prom-client'; import { ICacheClient } from './ICacheClient'; import constants from '../../constants'; import LRUCache, { LimitedByCount, LimitedByTTL } from 'lru-cache'; +import { RequestDetails } from '../../types/RequestDetails'; /** * Represents a LocalLRUCache instance that uses an LRU (Least Recently Used) caching strategy @@ -98,14 +99,16 @@ export class LocalLRUCache implements ICacheClient { * If the value exists in the cache, updates metrics and logs the retrieval. * @param {string} key - The key associated with the cached value. * @param {string} callingMethod - The name of the method calling the cache. - * @param {string} requestIdPrefix - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {*} The cached value if found, otherwise null. */ - public async get(key: string, callingMethod: string, requestIdPrefix: string): Promise { + public async get(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { const value = this.cache.get(key); if (value !== undefined) { this.logger.trace( - `${requestIdPrefix} returning cached value ${key}:${JSON.stringify(value)} on ${callingMethod} call`, + `${requestDetails.formattedRequestId} returning cached value ${key}:${JSON.stringify( + value, + )} on ${callingMethod} call`, ); return value; } @@ -117,12 +120,14 @@ export class LocalLRUCache implements ICacheClient { * The remaining TTL of the specified key in the cache. * @param {string} key - The key to check the remaining TTL for. * @param {string} callingMethod - The name of the method calling the cache. - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The remaining TTL in milliseconds. */ - public async getRemainingTtl(key: string, callingMethod: string, requestIdPrefix: string): Promise { + public async getRemainingTtl(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { const remainingTtl = this.cache.getRemainingTTL(key); // in milliseconds - this.logger.trace(`${requestIdPrefix} returning remaining TTL ${key}:${remainingTtl} on ${callingMethod} call`); + this.logger.trace( + `${requestDetails.formattedRequestId} returning remaining TTL ${key}:${remainingTtl} on ${callingMethod} call`, + ); return remainingTtl; } @@ -133,17 +138,19 @@ export class LocalLRUCache implements ICacheClient { * @param {*} value - The value to cache. * @param {string} callingMethod - The name of the method calling the cache. * @param {number} ttl - Time to live for the cached value in milliseconds (optional). - * @param {string} requestIdPrefix - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ public async set( key: string, value: any, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ttl?: number, ): Promise { const resolvedTtl = ttl ?? this.options.ttl; - this.logger.trace(`${requestIdPrefix} caching ${key}:${JSON.stringify(value)} for ${resolvedTtl} ms`); + this.logger.trace( + `${requestDetails.formattedRequestId} caching ${key}:${JSON.stringify(value)} for ${resolvedTtl} ms`, + ); this.cache.set(key, value, { ttl: resolvedTtl }); } @@ -152,17 +159,17 @@ export class LocalLRUCache implements ICacheClient { * * @param keyValuePairs - An object where each property is a key and its value is the value to be cached. * @param callingMethod - The name of the calling method. - * @param requestIdPrefix - Optional request ID prefix for logging. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves when the values are cached. */ public async multiSet( keyValuePairs: Record, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { // Iterate over each entry in the keyValuePairs object for (const [key, value] of Object.entries(keyValuePairs)) { - await this.set(key, value, callingMethod, requestIdPrefix); + await this.set(key, value, callingMethod, requestDetails); } } @@ -172,18 +179,18 @@ export class LocalLRUCache implements ICacheClient { * @param keyValuePairs - An object where each property is a key and its value is the value to be cached. * @param callingMethod - The name of the calling method. * @param ttl - Time to live on the set values - * @param requestIdPrefix - Optional request ID prefix for logging. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {void} A Promise that resolves when the values are cached. */ public async pipelineSet( keyValuePairs: Record, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ttl?: number, ): Promise { // Iterate over each entry in the keyValuePairs object for (const [key, value] of Object.entries(keyValuePairs)) { - await this.set(key, value, callingMethod, requestIdPrefix, ttl); + await this.set(key, value, callingMethod, requestDetails, ttl); } } @@ -192,10 +199,10 @@ export class LocalLRUCache implements ICacheClient { * Logs the deletion of the cache entry. * @param {string} key - The key associated with the cached value to delete. * @param {string} callingMethod - The name of the method calling the cache. - * @param {string} requestIdPrefix - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - public async delete(key: string, callingMethod: string, requestIdPrefix: string): Promise { - this.logger.trace(`${requestIdPrefix} delete cache for ${key}`); + public async delete(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} delete cache for ${key}`); this.cache.delete(key); } @@ -219,10 +226,10 @@ export class LocalLRUCache implements ICacheClient { * Retrieves all keys in the cache that match the given pattern. * @param {string} pattern - The pattern to match keys against. * @param {string} callingMethod - The name of the method calling the cache. - * @param {string} requestIdPrefix - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} An array of keys that match the pattern. */ - public async keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise { + public async keys(pattern: string, callingMethod: string, requestDetails: RequestDetails): Promise { const keys = Array.from(this.cache.rkeys()); // Replace escaped special characters with placeholders @@ -251,7 +258,9 @@ export class LocalLRUCache implements ICacheClient { const matchingKeys = keys.filter((key) => regex.test(key)); - this.logger.trace(`${requestIdPrefix} retrieving keys matching ${pattern} on ${callingMethod} call`); + this.logger.trace( + `${requestDetails.formattedRequestId} retrieving keys matching ${pattern} on ${callingMethod} call`, + ); return matchingKeys; } } diff --git a/packages/relay/src/lib/clients/cache/redisCache.ts b/packages/relay/src/lib/clients/cache/redisCache.ts index 71db040645..3bd28ff1e5 100644 --- a/packages/relay/src/lib/clients/cache/redisCache.ts +++ b/packages/relay/src/lib/clients/cache/redisCache.ts @@ -25,6 +25,7 @@ import { Registry } from 'prom-client'; import { RedisCacheError } from '../../errors/RedisCacheError'; import constants from '../../constants'; import { IRedisCacheClient } from './IRedisCacheClient'; +import { RequestDetails } from '../../types/RequestDetails'; /** * A class that provides caching functionality using Redis. @@ -125,15 +126,17 @@ export class RedisCache implements IRedisCacheClient { * * @param {string} key - The cache key. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - The optional request ID prefix. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The cached value or null if not found. */ - async get(key: string, callingMethod: string, requestIdPrefix: string): Promise { + async get(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { const client = await this.getConnectedClient(); const result = await client.get(key); if (result) { this.logger.trace( - `${requestIdPrefix} returning cached value ${key}:${JSON.stringify(result)} on ${callingMethod} call`, + `${requestDetails.formattedRequestId} returning cached value ${key}:${JSON.stringify( + result, + )} on ${callingMethod} call`, ); // TODO: add metrics return JSON.parse(result); @@ -148,16 +151,24 @@ export class RedisCache implements IRedisCacheClient { * @param {*} value - The value to be cached. * @param {string} callingMethod - The name of the calling method. * @param {number} [ttl] - The time-to-live (expiration) of the cache item in milliseconds. - * @param {string} [requestIdPrefix] - The optional request ID prefix. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves when the value is cached. */ - async set(key: string, value: any, callingMethod: string, requestIdPrefix: string, ttl?: number): Promise { + async set( + key: string, + value: any, + callingMethod: string, + requestDetails: RequestDetails, + ttl?: number, + ): Promise { const client = await this.getConnectedClient(); const serializedValue = JSON.stringify(value); const resolvedTtl = ttl ?? this.options.ttl; // in milliseconds await client.set(key, serializedValue, { PX: resolvedTtl }); - this.logger.trace(`${requestIdPrefix} caching ${key}: ${serializedValue} on ${callingMethod} for ${resolvedTtl} s`); + this.logger.trace( + `${requestDetails.formattedRequestId} caching ${key}: ${serializedValue} on ${callingMethod} for ${resolvedTtl} s`, + ); // TODO: add metrics } @@ -166,10 +177,14 @@ export class RedisCache implements IRedisCacheClient { * * @param {Record} keyValuePairs - An object where each property is a key and its value is the value to be cached. * @param {string} callingMethod - The name of the calling method. - * @param {string} requestIdPrefix - Optional request ID prefix for logging. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves when the values are cached. */ - async multiSet(keyValuePairs: Record, callingMethod: string, requestIdPrefix: string): Promise { + async multiSet( + keyValuePairs: Record, + callingMethod: string, + requestDetails: RequestDetails, + ): Promise { const client = await this.getConnectedClient(); // Serialize values const serializedKeyValuePairs: Record = {}; @@ -186,7 +201,9 @@ export class RedisCache implements IRedisCacheClient { // Log the operation const entriesLength = Object.keys(keyValuePairs).length; - this.logger.trace(`${requestIdPrefix} caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`); + this.logger.trace( + `${requestDetails.formattedRequestId} caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`, + ); } /** @@ -195,13 +212,13 @@ export class RedisCache implements IRedisCacheClient { * @param {Record} keyValuePairs - An object where each property is a key and its value is the value to be cached. * @param {string} callingMethod - The name of the calling method. * @param {number} [ttl] - The time-to-live (expiration) of the cache item in milliseconds. - * @param {string} requestIdPrefix - Optional request ID prefix for logging. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves when the values are cached. */ async pipelineSet( keyValuePairs: Record, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ttl?: number, ): Promise { const client = await this.getConnectedClient(); @@ -219,7 +236,9 @@ export class RedisCache implements IRedisCacheClient { // Log the operation const entriesLength = Object.keys(keyValuePairs).length; - this.logger.trace(`${requestIdPrefix} caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`); + this.logger.trace( + `${requestDetails.formattedRequestId} caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`, + ); } /** @@ -227,13 +246,13 @@ export class RedisCache implements IRedisCacheClient { * * @param {string} key - The cache key. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - The optional request ID prefix. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves when the value is deleted from the cache. */ - async delete(key: string, callingMethod: string, requestIdPrefix: string): Promise { + async delete(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { const client = await this.getConnectedClient(); await client.del(key); - this.logger.trace(`${requestIdPrefix} delete cache for ${key} on ${callingMethod} call`); + this.logger.trace(`${requestDetails.formattedRequestId} delete cache for ${key} on ${callingMethod} call`); // TODO: add metrics } @@ -295,13 +314,13 @@ export class RedisCache implements IRedisCacheClient { * @param {string} key The key to increment * @param {number} amount The amount to increment by * @param {string} callingMethod The name of the calling method - * @param {string} [requestIdPrefix] The optional request ID prefix + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The value of the key after incrementing */ - async incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix: string): Promise { + async incrBy(key: string, amount: number, callingMethod: string, requestDetails: RequestDetails): Promise { const client = await this.getConnectedClient(); const result = await client.incrBy(key, amount); - this.logger.trace(`${requestIdPrefix} incrementing ${key} by ${amount} on ${callingMethod} call`); + this.logger.trace(`${requestDetails.formattedRequestId} incrementing ${key} by ${amount} on ${callingMethod} call`); return result; } @@ -312,7 +331,7 @@ export class RedisCache implements IRedisCacheClient { * @param {number} start The start index * @param {number} end The end index * @param {string} callingMethod The name of the calling method - * @param {string} [requestIdPrefix] The optional request ID prefix + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The list of elements in the range */ async lRange( @@ -320,11 +339,13 @@ export class RedisCache implements IRedisCacheClient { start: number, end: number, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { const client = await this.getConnectedClient(); const result = await client.lRange(key, start, end); - this.logger.trace(`${requestIdPrefix} retrieving range [${start}:${end}] from ${key} on ${callingMethod} call`); + this.logger.trace( + `${requestDetails.formattedRequestId} retrieving range [${start}:${end}] from ${key} on ${callingMethod} call`, + ); return result.map((item) => JSON.parse(item)); } @@ -334,14 +355,16 @@ export class RedisCache implements IRedisCacheClient { * @param {string} key The key of the list * @param {*} value The value to push * @param {string} callingMethod The name of the calling method - * @param {string} [requestIdPrefix] The optional request ID prefix + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The length of the list after pushing */ - async rPush(key: string, value: any, callingMethod: string, requestIdPrefix: string): Promise { + async rPush(key: string, value: any, callingMethod: string, requestDetails: RequestDetails): Promise { const client = await this.getConnectedClient(); const serializedValue = JSON.stringify(value); const result = await client.rPush(key, serializedValue); - this.logger.trace(`${requestIdPrefix} pushing ${serializedValue} to ${key} on ${callingMethod} call`); + this.logger.trace( + `${requestDetails.formattedRequestId} pushing ${serializedValue} to ${key} on ${callingMethod} call`, + ); return result; } @@ -349,13 +372,15 @@ export class RedisCache implements IRedisCacheClient { * Retrieves all keys matching a pattern. * @param {string} pattern The pattern to match * @param {string} callingMethod The name of the calling method - * @param {string} [requestIdPrefix] The optional request ID prefix + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The list of keys matching the pattern */ - async keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise { + async keys(pattern: string, callingMethod: string, requestDetails: RequestDetails): Promise { const client = await this.getConnectedClient(); const result = await client.keys(pattern); - this.logger.trace(`${requestIdPrefix} retrieving keys matching ${pattern} on ${callingMethod} call`); + this.logger.trace( + `${requestDetails.formattedRequestId} retrieving keys matching ${pattern} on ${callingMethod} call`, + ); return result; } } diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index f480da1032..daaab4a666 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -43,6 +43,7 @@ import { MirrorNodeTransactionRecord, IMirrorNodeTransactionRecord, } from '../types'; +import { RequestDetails } from '../types/RequestDetails'; type REQUEST_METHODS = 'GET' | 'POST'; @@ -121,9 +122,6 @@ export class MirrorNodeClient { private static readonly FORWARD_SLASH = '/'; private static readonly HTTPS_PREFIX = 'https://'; private static readonly API_V1_POST_FIX = 'api/v1/'; - private static readonly EMPTY_STRING = ''; - private static readonly REQUEST_PREFIX_SEPARATOR = ': '; - private static readonly REQUEST_PREFIX_TRAILING_BRACKET = ']'; private static readonly HTTP_GET = 'GET'; private static readonly REQUESTID_LABEL = 'requestId'; @@ -166,7 +164,7 @@ export class MirrorNodeClient { // defualt values for axios clients to mirror node const mirrorNodeTimeout = parseInt(process.env.MIRROR_NODE_TIMEOUT || '10000'); const mirrorNodeMaxRedirects = parseInt(process.env.MIRROR_NODE_MAX_REDIRECTS || '5'); - const mirrorNodeHttpKeepAlive = process.env.MIRROR_NODE_HTTP_KEEP_ALIVE === 'false' ? false : true; + const mirrorNodeHttpKeepAlive = process.env.MIRROR_NODE_HTTP_KEEP_ALIVE !== 'false'; const mirrorNodeHttpKeepAliveMsecs = parseInt(process.env.MIRROR_NODE_HTTP_KEEP_ALIVE_MSECS || '1000'); const mirrorNodeHttpMaxSockets = parseInt(process.env.MIRROR_NODE_HTTP_MAX_SOCKETS || '300'); const mirrorNodeHttpMaxTotalSockets = parseInt(process.env.MIRROR_NODE_HTTP_MAX_TOTAL_SOCKETS || '300'); @@ -180,7 +178,7 @@ export class MirrorNodeClient { ? JSON.parse(process.env.MIRROR_NODE_RETRY_CODES) : []; // we are in the process of deprecating this feature // by default will be true, unless explicitly set to false. - const useCacheableDnsLookup: boolean = process.env.MIRROR_NODE_AGENT_CACHEABLE_DNS === 'false' ? false : true; + const useCacheableDnsLookup: boolean = process.env.MIRROR_NODE_AGENT_CACHEABLE_DNS !== 'false'; const httpAgent = new http.Agent({ keepAlive: mirrorNodeHttpKeepAlive, @@ -313,24 +311,16 @@ export class MirrorNodeClient { path: string, pathLabel: string, method: REQUEST_METHODS, - requestIdPrefix: string, + requestDetails: RequestDetails, data?: any, retries?: number, ): Promise { const start = Date.now(); - // extract request id from prefix and remove trailing ']' character - this.logger.debug(requestIdPrefix); - this.logger.debug(`${method} + ${path} + ${requestIdPrefix}`); - const requestId = - requestIdPrefix - ?.split(MirrorNodeClient.REQUEST_PREFIX_SEPARATOR)[1] - .replace(MirrorNodeClient.REQUEST_PREFIX_TRAILING_BRACKET, MirrorNodeClient.EMPTY_STRING) || - MirrorNodeClient.EMPTY_STRING; const controller = new AbortController(); try { const axiosRequestConfig: AxiosRequestConfig = { headers: { - [MirrorNodeClient.REQUESTID_LABEL]: requestId, + [MirrorNodeClient.REQUESTID_LABEL]: requestDetails.requestId, }, signal: controller.signal, }; @@ -352,7 +342,7 @@ export class MirrorNodeClient { } const ms = Date.now() - start; - this.logger.debug(`${requestIdPrefix} [${method}] ${path} ${response.status} ${ms} ms`); + this.logger.debug(`${requestDetails.formattedRequestId} [${method}] ${path} ${response.status} ${ms} ms`); this.mirrorResponseHistogram.labels(pathLabel, response.status?.toString()).observe(ms); return response.data; } catch (error: any) { @@ -366,25 +356,30 @@ export class MirrorNodeClient { // always abort the request on failure as the axios call can hang until the parent code/stack times out (might be a few minutes in a server-side applications) controller.abort(); - this.handleError(error, path, pathLabel, effectiveStatusCode, method, requestIdPrefix); + this.handleError(error, path, pathLabel, effectiveStatusCode, method, requestDetails); } return null; } - async get(path: string, pathLabel: string, requestIdPrefix: string, retries?: number): Promise { - return this.request(path, pathLabel, 'GET', requestIdPrefix, null, retries); + async get( + path: string, + pathLabel: string, + requestDetails: RequestDetails, + retries?: number, + ): Promise { + return this.request(path, pathLabel, 'GET', requestDetails, null, retries); } async post( path: string, data: any, pathLabel: string, - requestIdPrefix: string, + requestDetails: RequestDetails, retries?: number, ): Promise { if (!data) data = {}; - return this.request(path, pathLabel, 'POST', requestIdPrefix, data, retries); + return this.request(path, pathLabel, 'POST', requestDetails, data, retries); } /** @@ -397,8 +392,9 @@ export class MirrorNodeClient { pathLabel: string, effectiveStatusCode: number, method: REQUEST_METHODS, - requestIdPrefix?: string, + requestDetails: RequestDetails, ): null { + const requestIdPrefix = requestDetails.formattedRequestId; const mirrorError = new MirrorNodeClientError(error, effectiveStatusCode); const acceptedErrorResponses = MirrorNodeClient.acceptedErrorStatusesResponsePerRequestPathMap.get(pathLabel); @@ -428,12 +424,12 @@ export class MirrorNodeClient { url: string, pathLabel: string, resultProperty: string, - requestIdPrefix: string, + requestDetails: RequestDetails, results = [], page = 1, pageMax: number = constants.MAX_MIRROR_NODE_PAGINATION, ) { - const result = await this.get(url, pathLabel, requestIdPrefix); + const result = await this.get(url, pathLabel, requestDetails); if (result && result[resultProperty]) { results = results.concat(result[resultProperty]); @@ -441,24 +437,26 @@ export class MirrorNodeClient { if (page === pageMax) { // max page reached - this.logger.trace(`${requestIdPrefix} Max page reached ${pageMax} with ${results.length} results`); + this.logger.trace( + `${requestDetails.formattedRequestId} Max page reached ${pageMax} with ${results.length} results`, + ); throw predefined.PAGINATION_MAX(pageMax); } if (result?.links?.next && page < pageMax) { page++; const next = result.links.next.replace(constants.NEXT_LINK_PREFIX, ''); - return this.getPaginatedResults(next, pathLabel, resultProperty, requestIdPrefix, results, page, pageMax); + return this.getPaginatedResults(next, pathLabel, resultProperty, requestDetails, results, page, pageMax); } else { return results; } } - public async getAccount(idOrAliasOrEvmAddress: string, requestIdPrefix: string, retries?: number) { + public async getAccount(idOrAliasOrEvmAddress: string, requestDetails: RequestDetails, retries?: number) { return this.get( `${MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT}${idOrAliasOrEvmAddress}?transactions=false`, MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT, - requestIdPrefix, + requestDetails, retries, ); } @@ -467,7 +465,7 @@ export class MirrorNodeClient { idOrAliasOrEvmAddress: string, timestampTo: string, numberOfTransactions: number = 1, - requestIdPrefix: string, + requestDetails: RequestDetails, ) { const queryParamObject = {}; this.setQueryParam( @@ -485,24 +483,24 @@ export class MirrorNodeClient { return this.get( `${MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT}${idOrAliasOrEvmAddress}${queryParams}`, MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT, - requestIdPrefix, + requestDetails, ); } - public async getAccountPageLimit(idOrAliasOrEvmAddress: string, requestIdPrefix: string) { + public async getAccountPageLimit(idOrAliasOrEvmAddress: string, requestDetails: RequestDetails) { return this.get( `${MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT}${idOrAliasOrEvmAddress}?limit=${constants.MIRROR_NODE_QUERY_LIMIT}`, MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT, - requestIdPrefix, + requestDetails, ); } /******************************************************************************* * To be used to make paginated calls for the account information when the * transaction count exceeds the constant MIRROR_NODE_QUERY_LIMIT. *******************************************************************************/ - public async getAccountPaginated(url: string, requestIdPrefix: string) { + public async getAccountPaginated(url: string, requestDetails: RequestDetails) { const queryParamObject = {}; - const accountId = this.extractAccountIdFromUrl(url, requestIdPrefix); + const accountId = this.extractAccountIdFromUrl(url, requestDetails); const params = new URLSearchParams(url.split('?')[1]); this.setQueryParam(queryParamObject, 'limit', constants.MIRROR_NODE_QUERY_LIMIT); @@ -513,11 +511,11 @@ export class MirrorNodeClient { `${MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT}${accountId}${queryParams}`, MirrorNodeClient.GET_ACCOUNTS_BY_ID_ENDPOINT, 'transactions', - requestIdPrefix, + requestDetails, ); } - public extractAccountIdFromUrl(url: string, requestIdPrefix?: string): string | null { + public extractAccountIdFromUrl(url: string, requestDetails: RequestDetails): string | null { const substringStartIndex = url.indexOf('/accounts/') + '/accounts/'.length; if (url.startsWith('0x', substringStartIndex)) { // evm addresss @@ -525,7 +523,7 @@ export class MirrorNodeClient { const match = url.match(regex); const accountId = match ? match[1] : null; if (!accountId) { - this.logger.error(`${requestIdPrefix} Unable to extract evm address from url ${url}`); + this.logger.error(`${requestDetails.formattedRequestId} Unable to extract evm address from url ${url}`); } return String(accountId); } else { @@ -533,7 +531,7 @@ export class MirrorNodeClient { const match = url.match(MirrorNodeClient.EVM_ADDRESS_REGEX); const accountId = match ? match[1] : null; if (!accountId) { - this.logger.error(`${requestIdPrefix} Unable to extract account ID from url ${url}`); + this.logger.error(`${requestDetails.formattedRequestId} Unable to extract account ID from url ${url}`); } return String(accountId); } @@ -543,7 +541,7 @@ export class MirrorNodeClient { accountId: string, timestampFrom: string, timestampTo: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'account.id', accountId); @@ -555,11 +553,11 @@ export class MirrorNodeClient { `${MirrorNodeClient.GET_TRANSACTIONS_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_TRANSACTIONS_ENDPOINT, 'transactions', - requestIdPrefix, + requestDetails, ); } - public async getBalanceAtTimestamp(accountId: string, requestIdPrefix: string, timestamp?: string) { + public async getBalanceAtTimestamp(accountId: string, requestDetails: RequestDetails, timestamp?: string) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'account.id', accountId); this.setQueryParam(queryParamObject, 'timestamp', timestamp); @@ -567,16 +565,16 @@ export class MirrorNodeClient { return this.get( `${MirrorNodeClient.GET_BALANCE_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_BALANCE_ENDPOINT, - requestIdPrefix, + requestDetails, ); } - public async getBlock(hashOrBlockNumber: string | number, requestIdPrefix: string) { + public async getBlock(hashOrBlockNumber: string | number, requestDetails: RequestDetails) { const cachedLabel = `${constants.CACHE_KEY.GET_BLOCK}.${hashOrBlockNumber}`; const cachedResponse: any = await this.cacheService.getAsync( cachedLabel, MirrorNodeClient.GET_BLOCK_ENDPOINT, - requestIdPrefix, + requestDetails, ); if (cachedResponse) { return cachedResponse; @@ -585,15 +583,15 @@ export class MirrorNodeClient { const block = await this.get( `${MirrorNodeClient.GET_BLOCK_ENDPOINT}${hashOrBlockNumber}`, MirrorNodeClient.GET_BLOCK_ENDPOINT, - requestIdPrefix, + requestDetails, ); - await this.cacheService.set(cachedLabel, block, MirrorNodeClient.GET_BLOCK_ENDPOINT, requestIdPrefix); + await this.cacheService.set(cachedLabel, block, MirrorNodeClient.GET_BLOCK_ENDPOINT, requestDetails); return block; } public async getBlocks( - requestIdPrefix: string, + requestDetails: RequestDetails, blockNumber?: number | string[], timestamp?: string, limitOrderParams?: ILimitOrderParams, @@ -606,35 +604,35 @@ export class MirrorNodeClient { return this.get( `${MirrorNodeClient.GET_BLOCKS_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_BLOCKS_ENDPOINT, - requestIdPrefix, + requestDetails, ); } - public async getContract(contractIdOrAddress: string, requestIdPrefix: string, retries?: number) { + public async getContract(contractIdOrAddress: string, requestDetails: RequestDetails, retries?: number) { return this.get( `${MirrorNodeClient.GET_CONTRACT_ENDPOINT}${contractIdOrAddress}`, MirrorNodeClient.GET_CONTRACT_ENDPOINT, - requestIdPrefix, + requestDetails, retries, ); } - public getIsValidContractCacheLabel(contractIdOrAddress): string { + public getIsValidContractCacheLabel(contractIdOrAddress: string): string { return `${constants.CACHE_KEY.GET_CONTRACT}.valid.${contractIdOrAddress}`; } - public async getIsValidContractCache(contractIdOrAddress, requestIdPrefix: string): Promise { + public async getIsValidContractCache(contractIdOrAddress: string, requestDetails: RequestDetails): Promise { const cachedLabel = this.getIsValidContractCacheLabel(contractIdOrAddress); - return await this.cacheService.getAsync(cachedLabel, MirrorNodeClient.GET_CONTRACT_ENDPOINT, requestIdPrefix); + return await this.cacheService.getAsync(cachedLabel, MirrorNodeClient.GET_CONTRACT_ENDPOINT, requestDetails); } - public async isValidContract(contractIdOrAddress: string, requestIdPrefix: string, retries?: number) { - const cachedResponse: any = await this.getIsValidContractCache(contractIdOrAddress, requestIdPrefix); + public async isValidContract(contractIdOrAddress: string, requestDetails: RequestDetails, retries?: number) { + const cachedResponse: any = await this.getIsValidContractCache(contractIdOrAddress, requestDetails); if (cachedResponse != undefined) { return cachedResponse; } - const contract = await this.getContractId(contractIdOrAddress, requestIdPrefix, retries); + const contract = await this.getContractId(contractIdOrAddress, requestDetails, retries); const valid = contract != null; const cachedLabel = this.getIsValidContractCacheLabel(contractIdOrAddress); @@ -642,18 +640,18 @@ export class MirrorNodeClient { cachedLabel, valid, MirrorNodeClient.GET_CONTRACT_ENDPOINT, - requestIdPrefix, + requestDetails, constants.CACHE_TTL.ONE_DAY, ); return valid; } - public async getContractId(contractIdOrAddress: string, requestIdPrefix: string, retries?: number) { + public async getContractId(contractIdOrAddress: string, requestDetails: RequestDetails, retries?: number) { const cachedLabel = `${constants.CACHE_KEY.GET_CONTRACT}.id.${contractIdOrAddress}`; const cachedResponse: any = await this.cacheService.getAsync( cachedLabel, MirrorNodeClient.GET_CONTRACT_ENDPOINT, - requestIdPrefix, + requestDetails, ); if (cachedResponse != undefined) { return cachedResponse; @@ -662,7 +660,7 @@ export class MirrorNodeClient { const contract = await this.get( `${MirrorNodeClient.GET_CONTRACT_ENDPOINT}${contractIdOrAddress}`, MirrorNodeClient.GET_CONTRACT_ENDPOINT, - requestIdPrefix, + requestDetails, retries, ); @@ -672,7 +670,7 @@ export class MirrorNodeClient { cachedLabel, id, MirrorNodeClient.GET_CONTRACT_ENDPOINT, - requestIdPrefix, + requestDetails, constants.CACHE_TTL.ONE_DAY, ); return id; @@ -681,12 +679,12 @@ export class MirrorNodeClient { return null; } - public async getContractResult(transactionIdOrHash: string, requestIdPrefix: string) { + public async getContractResult(transactionIdOrHash: string, requestDetails: RequestDetails) { const cacheKey = `${constants.CACHE_KEY.GET_CONTRACT_RESULT}.${transactionIdOrHash}`; const cachedResponse = await this.cacheService.getAsync( cacheKey, MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT, - requestIdPrefix, + requestDetails, ); if (cachedResponse) { @@ -696,7 +694,7 @@ export class MirrorNodeClient { const response = await this.get( `${MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT}${transactionIdOrHash}`, MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT, - requestIdPrefix, + requestDetails, ); if ( @@ -709,7 +707,7 @@ export class MirrorNodeClient { cacheKey, response, MirrorNodeClient.GET_CONTRACT_RESULT_ENDPOINT, - requestIdPrefix, + requestDetails, constants.CACHE_TTL.ONE_HOUR, ); } @@ -721,19 +719,19 @@ 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. - * @param transactionIdOrHash - * @param requestIdPrefix + * @param {string} transactionIdOrHash - The transaction ID or hash + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - public async getContractResultWithRetry(transactionIdOrHash: string, requestIdPrefix: string) { - const contractResult = await this.getContractResult(transactionIdOrHash, requestIdPrefix); + public async getContractResultWithRetry(transactionIdOrHash: string, requestDetails: RequestDetails) { + const contractResult = await this.getContractResult(transactionIdOrHash, requestDetails); if (contractResult && !(contractResult.transaction_index && contractResult.block_number)) { - return this.getContractResult(transactionIdOrHash, requestIdPrefix); + return this.getContractResult(transactionIdOrHash, requestDetails); } return contractResult; } public async getContractResults( - requestIdPrefix: string, + requestDetails: RequestDetails, contractResultsParams?: IContractResultsParams, limitOrderParams?: ILimitOrderParams, ) { @@ -745,45 +743,45 @@ export class MirrorNodeClient { `${MirrorNodeClient.GET_CONTRACT_RESULTS_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_CONTRACT_RESULTS_ENDPOINT, 'results', - requestIdPrefix, + requestDetails, [], 1, MirrorNodeClient.mirrorNodeContractResultsPageMax, ); } - public async getContractResultsDetails(contractId: string, timestamp: string, requestIdPrefix: string) { + public async getContractResultsDetails(contractId: string, timestamp: string, requestDetails: RequestDetails) { return this.get( `${this.getContractResultsDetailsByContractIdAndTimestamp(contractId, timestamp)}`, MirrorNodeClient.GET_CONTRACT_RESULTS_DETAILS_BY_CONTRACT_ID_ENDPOINT, - requestIdPrefix, + requestDetails, ); } - public async getContractsResultsActions(transactionIdOrHash: string, requestIdPrefix: string): Promise { + public async getContractsResultsActions(transactionIdOrHash: string, requestDetails: RequestDetails): Promise { return this.get( `${this.getContractResultsActionsByTransactionIdPath(transactionIdOrHash)}`, MirrorNodeClient.GET_CONTRACTS_RESULTS_ACTIONS, - requestIdPrefix, + requestDetails, ); } public async getContractsResultsOpcodes( transactionIdOrHash: string, - requestIdPrefix: string, + requestDetails: RequestDetails, params?: { memory?: boolean; stack?: boolean; storage?: boolean }, ): Promise { const queryParams = params ? this.getQueryParams(params) : ''; return this.get( `${this.getContractResultsOpcodesByTransactionIdPath(transactionIdOrHash)}${queryParams}`, MirrorNodeClient.GET_CONTRACTS_RESULTS_OPCODES, - requestIdPrefix, + requestDetails, ); } public async getContractResultsByAddress( contractIdOrAddress: string, - requestIdPrefix: string, + requestDetails: RequestDetails, contractResultsParams?: IContractResultsParams, limitOrderParams?: ILimitOrderParams, ) { @@ -794,20 +792,20 @@ export class MirrorNodeClient { return this.get( `${MirrorNodeClient.getContractResultsByAddressPath(contractIdOrAddress)}${queryParams}`, MirrorNodeClient.GET_CONTRACT_RESULTS_BY_ADDRESS_ENDPOINT, - requestIdPrefix, + requestDetails, ); } public async getContractResultsByAddressAndTimestamp( contractIdOrAddress: string, timestamp: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ) { const apiPath = MirrorNodeClient.getContractResultsByAddressAndTimestampPath(contractIdOrAddress, timestamp); return this.get( apiPath, MirrorNodeClient.GET_CONTRACT_RESULTS_DETAILS_BY_ADDRESS_AND_TIMESTAMP_ENDPOINT, - requestIdPrefix, + requestDetails, ); } @@ -831,7 +829,7 @@ export class MirrorNodeClient { } public async getContractResultsLogs( - requestIdPrefix: string, + requestDetails: RequestDetails, contractLogsResultsParams?: IContractLogsResultsParams, limitOrderParams?: ILimitOrderParams, ) { @@ -841,7 +839,7 @@ export class MirrorNodeClient { `${MirrorNodeClient.GET_CONTRACT_RESULT_LOGS_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_CONTRACT_RESULT_LOGS_ENDPOINT, MirrorNodeClient.CONTRACT_RESULT_LOGS_PROPERTY, - requestIdPrefix, + requestDetails, [], 1, MirrorNodeClient.mirrorNodeContractResultsLogsPageMax, @@ -850,7 +848,7 @@ export class MirrorNodeClient { public async getContractResultsLogsByAddress( address: string, - requestIdPrefix: string, + requestDetails: RequestDetails, contractLogsResultsParams?: IContractLogsResultsParams, limitOrderParams?: ILimitOrderParams, ) { @@ -866,26 +864,26 @@ export class MirrorNodeClient { `${apiEndpoint}${queryParams}`, MirrorNodeClient.GET_CONTRACT_RESULT_LOGS_BY_ADDRESS_ENDPOINT, MirrorNodeClient.CONTRACT_RESULT_LOGS_PROPERTY, - requestIdPrefix, + requestDetails, [], 1, MirrorNodeClient.mirrorNodeContractResultsLogsPageMax, ); } - public async getEarliestBlock(requestIdPrefix: string) { + public async getEarliestBlock(requestDetails: RequestDetails) { const cachedLabel = `${constants.CACHE_KEY.GET_BLOCK}.earliest`; const cachedResponse: any = await this.cacheService.getAsync( cachedLabel, MirrorNodeClient.GET_BLOCKS_ENDPOINT, - requestIdPrefix, + requestDetails, ); if (cachedResponse != undefined) { return cachedResponse; } const blocks = await this.getBlocks( - requestIdPrefix, + requestDetails, undefined, undefined, this.getLimitOrderQueryParam(1, MirrorNodeClient.ORDER.ASC), @@ -896,7 +894,7 @@ export class MirrorNodeClient { cachedLabel, block, MirrorNodeClient.GET_BLOCKS_ENDPOINT, - requestIdPrefix, + requestDetails, constants.CACHE_TTL.ONE_DAY, ); return block; @@ -905,9 +903,9 @@ export class MirrorNodeClient { return null; } - public async getLatestBlock(requestIdPrefix: string) { + public async getLatestBlock(requestDetails: RequestDetails) { return this.getBlocks( - requestIdPrefix, + requestDetails, undefined, undefined, this.getLimitOrderQueryParam(1, MirrorNodeClient.ORDER.DESC), @@ -918,18 +916,18 @@ export class MirrorNodeClient { return { limit: limit, order: order }; } - public async getNetworkExchangeRate(requestIdPrefix: string, timestamp?: string) { + public async getNetworkExchangeRate(requestDetails: RequestDetails, timestamp?: string) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'timestamp', timestamp); const queryParams = this.getQueryParams(queryParamObject); return this.get( `${MirrorNodeClient.GET_NETWORK_EXCHANGERATE_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_NETWORK_EXCHANGERATE_ENDPOINT, - requestIdPrefix, + requestDetails, ); } - public async getNetworkFees(requestIdPrefix: string, timestamp?: string, order?: string) { + public async getNetworkFees(requestDetails: RequestDetails, timestamp?: string, order?: string) { const queryParamObject = {}; this.setQueryParam(queryParamObject, 'timestamp', timestamp); this.setQueryParam(queryParamObject, 'order', order); @@ -937,7 +935,7 @@ export class MirrorNodeClient { return this.get( `${MirrorNodeClient.GET_NETWORK_FEES_ENDPOINT}${queryParams}`, MirrorNodeClient.GET_NETWORK_FEES_ENDPOINT, - requestIdPrefix, + requestDetails, ); } @@ -976,11 +974,11 @@ export class MirrorNodeClient { ); } - public async getTokenById(tokenId: string, requestIdPrefix: string, retries?: number) { + public async getTokenById(tokenId: string, requestDetails: RequestDetails, retries?: number) { return this.get( `${MirrorNodeClient.GET_TOKENS_ENDPOINT}/${tokenId}`, MirrorNodeClient.GET_TOKENS_ENDPOINT, - requestIdPrefix, + requestDetails, retries, ); } @@ -989,20 +987,20 @@ export class MirrorNodeClient { address: string, blockEndTimestamp: string | undefined, limit: number, - requestIdPrefix: string, + requestDetails: RequestDetails, ) { // retrieve the timestamp of the contract const contractResultsParams: IContractResultsParams = blockEndTimestamp ? { timestamp: `lte:${blockEndTimestamp}` } : {}; const limitOrderParams: ILimitOrderParams = this.getLimitOrderQueryParam(limit, 'desc'); - return this.getContractResultsByAddress(address, requestIdPrefix, contractResultsParams, limitOrderParams); + return this.getContractResultsByAddress(address, requestDetails, contractResultsParams, limitOrderParams); } public async getContractStateByAddressAndSlot( address: string, slot: string, - requestIdPrefix: string, + requestDetails: RequestDetails, blockEndTimestamp?: string, ) { const limitOrderParams: ILimitOrderParams = this.getLimitOrderQueryParam( @@ -1021,28 +1019,28 @@ export class MirrorNodeClient { MirrorNodeClient.ADDRESS_PLACEHOLDER, address, ); - return this.get(`${apiEndpoint}${queryParams}`, MirrorNodeClient.CONTRACT_ADDRESS_STATE_ENDPOINT, requestIdPrefix); + return this.get(`${apiEndpoint}${queryParams}`, MirrorNodeClient.CONTRACT_ADDRESS_STATE_ENDPOINT, requestDetails); } /** * Send a contract call request to mirror node * @param callData {IContractCallRequest} contract call request data - * @param requestIdPrefix {string} optional request id prefix + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ public async postContractCall( callData: IContractCallRequest, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { return this.post( MirrorNodeClient.CONTRACT_CALL_ENDPOINT, callData, MirrorNodeClient.CONTRACT_CALL_ENDPOINT, - requestIdPrefix, + requestDetails, 1, // historical blocks might need 1 retry due to possible timeout from mirror node ); } - public async getTransactionById(transactionId: string, nonce: number | undefined, requestIdPrefix: string) { + public async getTransactionById(transactionId: string, nonce: number | undefined, requestDetails: RequestDetails) { const formattedId = formatTransactionId(transactionId); if (formattedId == null) { return formattedId; @@ -1057,31 +1055,34 @@ export class MirrorNodeClient { return this.get( `${apiEndpoint}${queryParams}`, MirrorNodeClient.GET_TRANSACTIONS_ENDPOINT_TRANSACTION_ID, - requestIdPrefix, + requestDetails, ); } /** * Check if transaction fail is because of contract revert and try to fetch and log the reason. * - * @param e - * @param requestIdPrefix + * @param e - The error object. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - public async getContractRevertReasonFromTransaction(e: any, requestIdPrefix: string): Promise { + public async getContractRevertReasonFromTransaction( + e: any, + requestDetails: RequestDetails, + ): Promise { if (e instanceof SDKClientError && e.isContractRevertExecuted()) { const transactionId = e.message.match(constants.TRANSACTION_ID_REGEX); if (transactionId) { - const tx = await this.getTransactionById(transactionId[0], undefined, requestIdPrefix); + const tx = await this.getTransactionById(transactionId[0], undefined, requestDetails); if (tx === null) { - this.logger.error(`${requestIdPrefix} Transaction failed with null result`); + this.logger.error(`${requestDetails.formattedRequestId} Transaction failed with null result`); return null; } else if (tx.length === 0) { - this.logger.error(`${requestIdPrefix} Transaction failed with empty result`); + this.logger.error(`${requestDetails.formattedRequestId} Transaction failed with empty result`); return null; } else if (tx?.transactions.length > 1) { const result = tx.transactions[1].result; - this.logger.error(`${requestIdPrefix} Transaction failed with result: ${result}`); + this.logger.error(`${requestDetails.formattedRequestId} Transaction failed with result: ${result}`); return result; } } @@ -1141,7 +1142,7 @@ export class MirrorNodeClient { * @param entityIdentifier the address of the contract * @param searchableTypes the types to search for * @param callerName calling method name - * @param requestIdPrefix the request id prefix message + * @param requestDetails The request details for logging and tracking. * @param retries the number of retries * @returns entity object or null if not found */ @@ -1149,14 +1150,14 @@ export class MirrorNodeClient { entityIdentifier: string, searchableTypes: any[] = [constants.TYPE_CONTRACT, constants.TYPE_ACCOUNT, constants.TYPE_TOKEN], callerName: string, - requestIdPrefix: string, + requestDetails: RequestDetails, retries?: number, ) { const cachedLabel = `${constants.CACHE_KEY.RESOLVE_ENTITY_TYPE}_${entityIdentifier}`; const cachedResponse: { type: string; entity: any } | undefined = await this.cacheService.getAsync( cachedLabel, callerName, - requestIdPrefix, + requestDetails, ); if (cachedResponse) { return cachedResponse; @@ -1171,7 +1172,7 @@ export class MirrorNodeClient { ); if (searchableTypes.find((t) => t === constants.TYPE_CONTRACT)) { - const contract = await this.getContract(entityIdentifier, requestIdPrefix, retries).catch(() => { + const contract = await this.getContract(entityIdentifier, requestDetails, retries).catch(() => { return null; }); if (contract) { @@ -1179,7 +1180,7 @@ export class MirrorNodeClient { type: constants.TYPE_CONTRACT, entity: contract, }; - await this.cacheService.set(cachedLabel, response, callerName, requestIdPrefix); + await this.cacheService.set(cachedLabel, response, callerName, requestDetails); return response; } } @@ -1189,7 +1190,7 @@ export class MirrorNodeClient { const promises = [ searchableTypes.find((t) => t === constants.TYPE_ACCOUNT) ? buildPromise( - this.getAccount(entityIdentifier, requestIdPrefix, retries).catch(() => { + this.getAccount(entityIdentifier, requestDetails, retries).catch(() => { return null; }), ) @@ -1201,7 +1202,7 @@ export class MirrorNodeClient { promises.push( searchableTypes.find((t) => t === constants.TYPE_TOKEN) ? buildPromise( - this.getTokenById(`0.0.${parseInt(entityIdentifier, 16)}`, requestIdPrefix, retries).catch(() => { + this.getTokenById(`0.0.${parseInt(entityIdentifier, 16)}`, requestDetails, retries).catch(() => { return null; }), ) @@ -1234,7 +1235,7 @@ export class MirrorNodeClient { type, entity: data.value, }; - await this.cacheService.set(cachedLabel, response, callerName, requestIdPrefix); + await this.cacheService.set(cachedLabel, response, callerName, requestDetails); return response; } @@ -1258,11 +1259,11 @@ export class MirrorNodeClient { * enough time for the expected data to be propagated to the Mirror node. * It provides a way to have an extended retry logic only in specific places */ - public async repeatedRequest(methodName: string, args: any[], repeatCount: number, requestId?: string) { + public async repeatedRequest(methodName: string, args: any[], repeatCount: number, requestDetails?: RequestDetails) { let result; for (let i = 0; i < repeatCount; i++) { try { - result = await this[methodName](...args, requestId); + result = await this[methodName](...args, requestDetails); } catch (e: any) { // note: for some methods, it will throw 404 not found error as the record is not yet recorded in mirror-node // if error is 404, `result` would be assigned as null for it to not break out the loop. @@ -1272,7 +1273,7 @@ export class MirrorNodeClient { } else { this.logger.warn( e, - `${requestId} Error raised during polling mirror node for updated records: method=${methodName}, args=${args}`, + `${requestDetails?.formattedRequestId} Error raised during polling mirror node for updated records: method=${methodName}, args=${args}`, ); } } @@ -1282,7 +1283,7 @@ export class MirrorNodeClient { } this.logger.trace( - `${requestId} Repeating request ${methodName} with args ${JSON.stringify( + `${requestDetails?.formattedRequestId} Repeating request ${methodName} with args ${JSON.stringify( args, )} retry count ${i} of ${repeatCount}. Waiting ${this.MIRROR_NODE_RETRY_DELAY} ms before repeating request`, ); @@ -1298,20 +1299,20 @@ export class MirrorNodeClient { * * @param {string} transactionId - The ID of the transaction for which the record is being retrieved. * @param {string} callerName - The name of the caller requesting the transaction record. - * @param {string} requestId - The unique identifier for the request, used for logging and tracking. * @param {string} txConstructorName - The name of the transaction constructor associated with the transaction. * @param {string} operatorAccountId - The account ID of the operator, used to calculate transaction fees. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise<{ITransactionRecordMetric}>} - An object containing the transaction fee if available, or `undefined` if the transaction record is not found. * @throws {MirrorNodeClientError} - Throws an error if no transaction record is retrieved. */ public async getTransactionRecordMetrics( transactionId: string, callerName: string, - requestId: string, txConstructorName: string, operatorAccountId: string, + requestDetails: RequestDetails, ): Promise { - const formattedRequestId = formatRequestIdMessage(requestId); + const formattedRequestId = requestDetails.formattedRequestId; this.logger.trace( `${formattedRequestId} Get transaction record via mirror node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`, @@ -1321,7 +1322,7 @@ export class MirrorNodeClient { this.getTransactionById.name, [transactionId, 0], this.MIRROR_NODE_REQUEST_RETRY_COUNT, - formattedRequestId, + requestDetails, ); if (!transactionRecords) { diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index 8e55f5193e..cf52c14a4e 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -62,7 +62,7 @@ import { JsonRpcError, predefined } from './../errors/JsonRpcError'; import { CacheService } from '../services/cacheService/cacheService'; import { formatRequestIdMessage, weibarHexToTinyBarInt } from '../../formatters'; import { ITransactionRecordMetric, IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../types'; -import { IRequestDetails } from '../types/IRequestDetails'; +import { RequestDetails } from '../types/RequestDetails'; const _ = require('lodash'); const LRU = require('lru-cache'); @@ -160,13 +160,13 @@ export class SDKClient { * * @param {string} account - The account ID to retrieve the balance for. * @param {string} callerName - The name of the caller requesting the account balance. - * @param {string} [requestId] - Optional request ID for tracking the request. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves to the account balance. */ async getAccountBalance( account: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { return this.executeQuery( new AccountBalanceQuery().setAccountId(AccountId.fromString(account)), @@ -181,13 +181,14 @@ export class SDKClient { * Retrieves the balance of an account in tinybars. * @param {string} account - The account ID to query. * @param {string} callerName - The name of the caller for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The balance of the account in tinybars. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ async getAccountBalanceInTinyBar( account: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { const balance = await this.getAccountBalance(account, callerName, requestDetails); return balance.hbars.to(HbarUnit.Tinybar); @@ -197,14 +198,14 @@ export class SDKClient { * Retrieves the balance of an account in weiBars. * @param {string} account - The account ID to query. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The balance of the account in weiBars. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ async getAccountBalanceInWeiBar( account: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { const balance = await this.getAccountBalance(account, callerName, requestDetails); return SDKClient.HbarToWeiBar(balance); @@ -214,11 +215,11 @@ export class SDKClient { * Retrieves information about an account. * @param {string} address - The account ID to query. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The information about the account. * @throws {SDKClientError} Throws an SDK client error if the account info retrieval fails. */ - async getAccountInfo(address: string, callerName: string, requestDetails: IRequestDetails): Promise { + async getAccountInfo(address: string, callerName: string, requestDetails: RequestDetails): Promise { return this.executeQuery( new AccountInfoQuery().setAccountId(AccountId.fromString(address)), this.clientMain, @@ -234,7 +235,7 @@ export class SDKClient { * @param {number | Long} realm - The realm number of the contract. * @param {string} address - The address of the contract. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The bytecode of the contract. * @throws {SDKClientError} Throws an SDK client error if the bytecode retrieval fails. */ @@ -243,7 +244,7 @@ export class SDKClient { realm: number | Long, address: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { const contractByteCodeQuery = new ContractByteCodeQuery().setContractId( ContractId.fromEvmAddress(shard, realm, address), @@ -263,14 +264,14 @@ export class SDKClient { * Retrieves the balance of a contract. * @param {string} contract - The contract ID to query. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The balance of the contract. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ async getContractBalance( contract: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { return this.executeQuery( new AccountBalanceQuery().setContractId(ContractId.fromString(contract)), @@ -286,14 +287,14 @@ export class SDKClient { * Converts the balance from Hbar to weiBars using the `HbarToWeiBar` method. * @param {string} account - The account address of the contract. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The contract balance in weiBars. * @throws {SDKClientError} Throws an SDK client error if the balance retrieval fails. */ async getContractBalanceInWeiBar( account: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { const balance = await this.getContractBalance(account, callerName, requestDetails); return SDKClient.HbarToWeiBar(balance); @@ -302,11 +303,11 @@ export class SDKClient { /** * Retrieves the current exchange rates from a file. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The exchange rates. * @throws {SDKClientError} Throws an SDK client error if the exchange rates file retrieval or parsing fails. */ - async getExchangeRate(callerName: string, requestDetails: IRequestDetails): Promise { + async getExchangeRate(callerName: string, requestDetails: RequestDetails): Promise { const exchangeFileBytes = await this.getFileIdBytes(constants.EXCHANGE_RATE_FILE_ID, callerName, requestDetails); return ExchangeRates.fromBytes(exchangeFileBytes); @@ -315,11 +316,11 @@ export class SDKClient { /** * Retrieves the fee schedule from a file. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The fee schedules. * @throws {SDKClientError} Throws an SDK client error if the fee schedule file retrieval or parsing fails. */ - async getFeeSchedule(callerName: string, requestDetails: IRequestDetails): Promise { + async getFeeSchedule(callerName: string, requestDetails: RequestDetails): Promise { const feeSchedulesFileBytes = await this.getFileIdBytes(constants.FEE_SCHEDULE_FILE_ID, callerName, requestDetails); return FeeSchedules.fromBytes(feeSchedulesFileBytes); } @@ -331,15 +332,15 @@ export class SDKClient { * MAPI does not incur any fees, while HAPI will incur a query fee. * * @param {string} callerName - The name of the caller, used for logging purposes. - * @param {string} [requestId] - Optional request ID, used for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The gas fee in tinybars. * @throws {SDKClientError} Throws an SDK client error if the fee schedules or exchange rates are invalid. */ - async getTinyBarGasFee(callerName: string, requestDetails: IRequestDetails): Promise { + async getTinyBarGasFee(callerName: string, requestDetails: RequestDetails): Promise { const cachedResponse: number | undefined = await this.cacheService.getAsync( constants.CACHE_KEY.GET_TINYBAR_GAS_FEE, callerName, - requestDetails.requestIdPrefix, + requestDetails, ); if (cachedResponse) { return cachedResponse; @@ -360,7 +361,7 @@ export class SDKClient { constants.CACHE_KEY.GET_TINYBAR_GAS_FEE, tinyBars, callerName, - requestDetails.requestIdPrefix, + requestDetails.formattedRequestId, ); return tinyBars; } @@ -373,11 +374,11 @@ export class SDKClient { * Retrieves the contents of a file identified by its ID and returns them as a byte array. * @param {string} address - The file ID or address of the file to retrieve. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The contents of the file as a byte array. * @throws {SDKClientError} Throws an SDK client error if the file query fails. */ - async getFileIdBytes(address: string, callerName: string, requestDetails: IRequestDetails): Promise { + async getFileIdBytes(address: string, callerName: string, requestDetails: RequestDetails): Promise { return this.executeQuery( new FileContentsQuery().setFileId(address), this.clientMain, @@ -394,6 +395,7 @@ export class SDKClient { * * @param {Uint8Array} transactionBuffer - The transaction data in bytes. * @param {string} callerName - The name of the caller initiating the transaction. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @param {string} originalCallerAddress - The address of the original caller making the request. * @param {number} networkGasPriceInWeiBars - The predefined gas price of the network in weibar. * @param {number} currentNetworkExchangeRateInCents - The exchange rate in cents of the current network. @@ -404,7 +406,7 @@ export class SDKClient { async submitEthereumTransaction( transactionBuffer: Uint8Array, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, originalCallerAddress: string, networkGasPriceInWeiBars: number, currentNetworkExchangeRateInCents: number, @@ -428,7 +430,7 @@ export class SDKClient { hexCallDataLength, this.fileAppendChunkSize, currentNetworkExchangeRateInCents, - requestDetails.requestIdPrefix, + requestDetails, ); if (shouldPreemptivelyLimit) { @@ -445,7 +447,7 @@ export class SDKClient { originalCallerAddress, ); if (!fileId) { - throw new SDKClientError({}, `${requestDetails.requestIdPrefix} No fileId created for transaction. `); + throw new SDKClientError({}, `${requestDetails.formattedRequestId} No fileId created for transaction. `); } ethereumTransactionData.callData = new Uint8Array(); ethereumTransaction.setEthereumData(ethereumTransactionData.toBytes()).setCallDataFileId(fileId); @@ -476,7 +478,7 @@ export class SDKClient { * @param {number} gas - The amount of gas to use for the contract call. * @param {string} from - The address of the sender in EVM format. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - Optional request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The result of the contract function call. * @throws {SDKClientError} Throws an SDK client error if the contract call query fails. */ @@ -486,7 +488,7 @@ export class SDKClient { gas: number, from: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { const contract = SDKClient.prune0x(to); const contractId = contract.startsWith('00000000000') @@ -518,7 +520,7 @@ export class SDKClient { * @param {number} gas - The amount of gas to use for the contract call. * @param {string} from - The address from which the contract call is made. * @param {string} callerName - The name of the caller for logging purposes. - * @param {string} [requestId] - The request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The result of the contract function call. * @throws {JsonRpcError} Throws an error if the error is a JSON-RPC error. * @throws {SDKClientError} Throws an SDK client error if the error is not a timeout error or if the retries are exhausted. @@ -529,7 +531,7 @@ export class SDKClient { gas: number, from: string, callerName: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { let retries = 0; let resp; @@ -542,7 +544,7 @@ export class SDKClient { if (sdkClientError.isTimeoutExceeded()) { const delay = retries * 1000; this.logger.trace( - `${requestDetails.requestIdPrefix} Contract call query failed with status ${sdkClientError.message}. Retrying again after ${delay} ms ...`, + `${requestDetails.formattedRequestId} Contract call query failed with status ${sdkClientError.message}. Retrying again after ${delay} ms ...`, ); retries++; await new Promise((r) => setTimeout(r, delay)); @@ -564,7 +566,7 @@ export class SDKClient { * @param {Client} client - The client to use for executing the query. * @param {number} maxRetries - The maximum number of retries allowed. * @param {number} currentRetry - The current retry attempt number. - * @param {string} [requestId] - The request ID for logging purposes. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise<{resp: any, cost: Hbar}>} The response of the query execution and the cost used. * @throws Will throw an error if the maximum number of retries is exceeded or if the error is not due to insufficient transaction fees. */ @@ -574,7 +576,7 @@ export class SDKClient { client: Client, maxRetries: number, currentRetry: number, - requestIdPrefix?: string, + requestDetails: RequestDetails, ): Promise<{ resp: any; cost: Hbar }> { const baseMultiplier = constants.QUERY_COST_INCREMENTATION_STEP; const multiplier = Math.pow(baseMultiplier, currentRetry); @@ -588,8 +590,10 @@ export class SDKClient { const sdkClientError = new SDKClientError(e, e.message); if (maxRetries > currentRetry && sdkClientError.isInsufficientTxFee()) { const newRetry = currentRetry + 1; - this.logger.info(`${requestIdPrefix} Retrying query execution with increased cost, retry number: ${newRetry}`); - return await this.increaseCostAndRetryExecution(query, baseCost, client, maxRetries, newRetry, requestIdPrefix); + this.logger.info( + `${requestDetails.formattedRequestId} Retrying query execution with increased cost, retry number: ${newRetry}`, + ); + return await this.increaseCostAndRetryExecution(query, baseCost, client, maxRetries, newRetry, requestDetails); } throw e; @@ -602,7 +606,7 @@ export class SDKClient { * @param {Client} client - The Hedera client to use for the query. * @param {string} callerName - The name of the caller executing the query. * @param {string} interactingEntity - The entity interacting with the query. - * @param {string} [requestId] - The optional request ID for logging and tracking. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A promise resolving to the query response. * @throws {Error} Throws an error if the query fails or if rate limits are exceeded. */ @@ -611,10 +615,10 @@ export class SDKClient { client: Client, callerName: string, interactingEntity: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { const queryConstructorName = query.constructor.name; - const requestIdPrefix = requestDetails?.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; let queryResponse: any = null; let queryCost: number | undefined = undefined; let status: string = ''; @@ -624,7 +628,7 @@ export class SDKClient { try { if (query.paymentTransactionId) { const baseCost = await query.getCost(this.clientMain); - const res = await this.increaseCostAndRetryExecution(query, baseCost, client, 3, 0, requestIdPrefix); + const res = await this.increaseCostAndRetryExecution(query, baseCost, client, 3, 0, requestDetails); queryResponse = res.resp; queryCost = res.cost.toTinybars().toNumber(); } else { @@ -667,7 +671,7 @@ export class SDKClient { gasUsed: 0, interactingEntity, status, - requestId: requestIdPrefix, + requestDetails, } as IExecuteQueryEventPayload); } } @@ -689,7 +693,7 @@ export class SDKClient { transaction: Transaction, callerName: string, interactingEntity: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, shouldThrowHbarLimit: boolean, originalCallerAddress: string, ): Promise { @@ -703,7 +707,7 @@ export class SDKClient { constants.EXECUTION_MODE.TRANSACTION, callerName, originalCallerAddress, - requestDetails.requestIdPrefix, + requestDetails, ); if (shouldLimit) { throw predefined.HBAR_RATE_LIMIT_EXCEEDED; @@ -711,7 +715,7 @@ export class SDKClient { } try { - this.logger.info(`${requestDetails.requestIdPrefix} Execute ${txConstructorName} transaction`); + this.logger.info(`${requestDetails.formattedRequestId} Execute ${txConstructorName} transaction`); transactionResponse = await transaction.execute(this.clientMain); transactionId = transactionResponse.transactionId.toString(); @@ -720,7 +724,7 @@ export class SDKClient { const transactionReceipt = await transactionResponse.getReceipt(this.clientMain); this.logger.info( - `${requestDetails.requestIdPrefix} Successfully execute ${txConstructorName} transaction: transactionId=${transactionResponse.transactionId}, callerName=${callerName}, status=${transactionReceipt.status}(${transactionReceipt.status._code})`, + `${requestDetails.formattedRequestId} Successfully execute ${txConstructorName} transaction: transactionId=${transactionResponse.transactionId}, callerName=${callerName}, status=${transactionReceipt.status}(${transactionReceipt.status._code})`, ); return transactionResponse; } catch (e: any) { @@ -737,12 +741,12 @@ export class SDKClient { this.logger.warn( sdkClientError, - `${requestDetails.requestIdPrefix} Fail to execute ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, + `${requestDetails.formattedRequestId} Fail to execute ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, ); if (!transactionResponse) { throw predefined.INTERNAL_ERROR( - `${requestDetails.requestIdPrefix} Transaction execution returns a null value: transactionId=${transaction.transactionId}, callerName=${callerName}, txConstructorName=${txConstructorName}`, + `${requestDetails.formattedRequestId} Transaction execution returns a null value: transactionId=${transaction.transactionId}, callerName=${callerName}, txConstructorName=${txConstructorName}`, ); } return transactionResponse; @@ -751,7 +755,7 @@ export class SDKClient { this.eventEmitter.emit(constants.EVENTS.EXECUTE_TRANSACTION, { transactionId, callerName, - requestId: requestDetails.requestIdPrefix, + requestDetails, txConstructorName, operatorAccountId: this.clientMain.operatorAccountId!.toString(), interactingEntity, @@ -776,7 +780,7 @@ export class SDKClient { transaction: FileAppendTransaction, callerName: string, interactingEntity: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, shouldThrowHbarLimit: boolean, originalCallerAddress: string, ): Promise { @@ -789,7 +793,7 @@ export class SDKClient { constants.EXECUTION_MODE.TRANSACTION, callerName, originalCallerAddress, - requestDetails.requestIdPrefix, + requestDetails, ); if (shouldLimit) { throw predefined.HBAR_RATE_LIMIT_EXCEEDED; @@ -797,17 +801,17 @@ export class SDKClient { } try { - this.logger.info(`${requestDetails.requestIdPrefix} Execute ${txConstructorName} transaction`); + this.logger.info(`${requestDetails.formattedRequestId} Execute ${txConstructorName} transaction`); transactionResponses = await transaction.executeAll(this.clientMain); this.logger.info( - `${requestDetails.requestIdPrefix} Successfully execute all ${transactionResponses.length} ${txConstructorName} transactions: callerName=${callerName}, status=${Status.Success}(${Status.Success._code})`, + `${requestDetails.formattedRequestId} Successfully execute all ${transactionResponses.length} ${txConstructorName} transactions: callerName=${callerName}, status=${Status.Success}(${Status.Success._code})`, ); } catch (e: any) { const sdkClientError = new SDKClientError(e, e.message); this.logger.warn( - `${requestDetails.requestIdPrefix} Fail to executeAll for ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, transactionType=${txConstructorName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, + `${requestDetails.formattedRequestId} Fail to executeAll for ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, transactionType=${txConstructorName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, ); throw sdkClientError; } finally { @@ -817,7 +821,7 @@ export class SDKClient { this.eventEmitter.emit(constants.EVENTS.EXECUTE_TRANSACTION, { transactionId: transactionResponse.transactionId.toString(), callerName, - requestId: requestDetails.requestIdPrefix, + requestId: requestDetails.formattedRequestId, txConstructorName, operatorAccountId: this.clientMain.operatorAccountId!.toString(), interactingEntity, @@ -842,7 +846,7 @@ export class SDKClient { async createFile( callData: Uint8Array, client: Client, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, callerName: string, interactingEntity: string, originalCallerAddress: string, @@ -891,11 +895,11 @@ export class SDKClient { ); if (fileInfo.size.isZero()) { - this.logger.warn(`${requestDetails.requestIdPrefix} File ${fileId} is empty.`); - throw new SDKClientError({}, `${requestDetails.requestIdPrefix} Created file is empty. `); + this.logger.warn(`${requestDetails.formattedRequestId} File ${fileId} is empty.`); + throw new SDKClientError({}, `${requestDetails.formattedRequestId} Created file is empty. `); } this.logger.trace( - `${requestDetails.requestIdPrefix} Created file with fileId: ${fileId} and file size ${fileInfo.size}`, + `${requestDetails.formattedRequestId} Created file with fileId: ${fileId} and file size ${fileInfo.size}`, ); } @@ -915,7 +919,7 @@ export class SDKClient { */ async deleteFile( fileId: FileId, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, callerName: string, interactingEntity: string, originalCallerAddress: string, @@ -944,12 +948,12 @@ export class SDKClient { ); if (fileInfo.isDeleted) { - this.logger.trace(`${requestDetails.requestIdPrefix} Deleted file with fileId: ${fileId}`); + this.logger.trace(`${requestDetails.formattedRequestId} Deleted file with fileId: ${fileId}`); } else { - this.logger.warn(`${requestDetails.requestIdPrefix} Fail to delete file with fileId: ${fileId} `); + this.logger.warn(`${requestDetails.formattedRequestId} Fail to delete file with fileId: ${fileId} `); } } catch (error: any) { - this.logger.warn(`${requestDetails.requestIdPrefix} ${error['message']} `); + this.logger.warn(`${requestDetails.formattedRequestId} ${error['message']} `); } } @@ -982,25 +986,25 @@ export class SDKClient { * * @param {string} transactionId - The ID of the transaction to retrieve metrics for. * @param {string} callerName - The name of the caller requesting the transaction record. - * @param {string} requestId - The request ID for tracking the request. * @param {string} txConstructorName - The name of the transaction constructor. * @param {string} operatorAccountId - The account ID of the operator. - * @returns {Promise} - A promise that resolves to an object containing transaction metrics. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. + * @returns {Promise} - A promise that resolves to an object containing transaction metrics. * @throws {SDKClientError} - Throws an error if an issue occurs during the transaction record query. */ public async getTransactionRecordMetrics( transactionId: string, callerName: string, - requestId: string, txConstructorName: string, operatorAccountId: string, + requestDetails: RequestDetails, ): Promise { let gasUsed: number = 0; let transactionFee: number = 0; let txRecordChargeAmount: number = 0; try { this.logger.trace( - `${requestId} Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`, + `${requestDetails.formattedRequestId} Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`, ); const transactionRecord = await new TransactionRecordQuery() @@ -1021,7 +1025,7 @@ export class SDKClient { const sdkClientError = new SDKClientError(e, e.message); this.logger.warn( e, - `${requestId} Error raised during TransactionRecordQuery: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, recordStatus=${sdkClientError.status} (${sdkClientError.status._code}), cost=${transactionFee}, gasUsed=${gasUsed}`, + `${requestDetails.formattedRequestId} Error raised during TransactionRecordQuery: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, recordStatus=${sdkClientError.status} (${sdkClientError.status._code}), cost=${transactionFee}, gasUsed=${gasUsed}`, ); throw sdkClientError; } diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index b9ce50acf9..c777434377 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -59,8 +59,8 @@ import { formatTransactionIdWithoutQueryParams, getFunctionSelector, } from '../formatters'; -import { IRequestDetails } from './types/IRequestDetails'; import { time } from 'console'; +import { RequestDetails } from './types/RequestDetails'; const _ = require('lodash'); const createHash = require('keccak'); @@ -308,8 +308,8 @@ export class EthImpl implements Eth { * This method is implemented to always return an empty array. This is in alignment * with the behavior of Infura. */ - accounts(requestDetails: IRequestDetails): never[] { - this.logger.trace(`${requestDetails.requestIdPrefix} accounts()`); + accounts(requestDetails: RequestDetails): never[] { + this.logger.trace(`${requestDetails.formattedRequestId} accounts()`); return EthImpl.accounts; } @@ -327,9 +327,9 @@ export class EthImpl implements Eth { blockCount: number, newestBlock: string, rewardPercentiles: Array | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; const maxResults = process.env.TEST === 'true' ? constants.DEFAULT_FEE_HISTORY_MAX_RESULTS @@ -369,11 +369,7 @@ export class EthImpl implements Eth { const cacheKey = `${constants.CACHE_KEY.FEE_HISTORY}_${blockCount}_${newestBlock}_${rewardPercentiles?.join( '', )}`; - const cachedFeeHistory = await this.cacheService.getAsync( - cacheKey, - EthImpl.ethFeeHistory, - requestDetails.requestIdPrefix, - ); + const cachedFeeHistory = await this.cacheService.getAsync(cacheKey, EthImpl.ethFeeHistory, requestDetails); if (cachedFeeHistory) { feeHistory = cachedFeeHistory; @@ -387,7 +383,7 @@ export class EthImpl implements Eth { ); } if (newestBlock != EthImpl.blockLatest && newestBlock != EthImpl.blockPending) { - await this.cacheService.set(cacheKey, feeHistory, EthImpl.ethFeeHistory, requestDetails.requestIdPrefix); + await this.cacheService.set(cacheKey, feeHistory, EthImpl.ethFeeHistory, requestDetails); } } @@ -398,16 +394,15 @@ export class EthImpl implements Eth { } } - private async getFeeByBlockNumber(blockNumber: number, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + private async getFeeByBlockNumber(blockNumber: number, requestDetails: RequestDetails): Promise { let fee = 0; try { - const block = await this.mirrorNodeClient.getBlock(blockNumber, requestIdPrefix); + const block = await this.mirrorNodeClient.getBlock(blockNumber, requestDetails); fee = await this.getFeeWeibars(EthImpl.ethFeeHistory, requestDetails, `lte:${block.timestamp.to}`); } catch (error) { this.logger.warn( error, - `${requestIdPrefix} Fee history cannot retrieve block or fee. Returning ${fee} fee for block ${blockNumber}`, + `${requestDetails.formattedRequestId} Fee history cannot retrieve block or fee. Returning ${fee} fee for block ${blockNumber}`, ); } @@ -444,7 +439,7 @@ export class EthImpl implements Eth { newestBlockNumber: number, latestBlockNumber: number, rewardPercentiles: Array | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { // include newest block number in the total block count const oldestBlockNumber = Math.max(0, newestBlockNumber - blockCount + 1); @@ -482,24 +477,20 @@ export class EthImpl implements Eth { return feeHistory; } - private async getFeeWeibars( - callerName: string, - requestDetails: IRequestDetails, - timestamp?: string, - ): Promise { + private async getFeeWeibars(callerName: string, requestDetails: RequestDetails, timestamp?: string): Promise { let networkFees; try { - networkFees = await this.mirrorNodeClient.getNetworkFees(requestDetails.requestIdPrefix, timestamp, undefined); + networkFees = await this.mirrorNodeClient.getNetworkFees(requestDetails, timestamp, undefined); } catch (e: any) { this.logger.warn( e, - `${requestDetails.requestIdPrefix} Mirror Node threw an error while retrieving fees. Fallback to consensus node.`, + `${requestDetails.formattedRequestId} Mirror Node threw an error while retrieving fees. Fallback to consensus node.`, ); } if (_.isNil(networkFees)) { - this.logger.debug(`${requestDetails.requestIdPrefix} Mirror Node returned no network fees. Fallback to consensus node.`); + this.logger.debug(`${requestDetails.formattedRequestId} Mirror Node returned no network fees. Fallback to consensus node.`); networkFees = { fees: [ { @@ -526,29 +517,27 @@ export class EthImpl implements Eth { /** * Gets the most recent block number. */ - async blockNumber(requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; - this.logger.trace(`${requestIdPrefix} blockNumber()`); - return await this.common.getLatestBlockNumber(requestIdPrefix); + async blockNumber(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} blockNumber()`); + return await this.common.getLatestBlockNumber(requestDetails); } /** * Gets the most recent block number and timestamp.to which represents the block finality. */ - async blockNumberTimestamp(caller: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; - this.logger.trace(`${requestIdPrefix} blockNumber()`); + async blockNumberTimestamp(caller: string, requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} blockNumber()`); const cacheKey = `${constants.CACHE_KEY.ETH_BLOCK_NUMBER}`; - const blocksResponse = await this.mirrorNodeClient.getLatestBlock(requestIdPrefix); + const blocksResponse = await this.mirrorNodeClient.getLatestBlock(requestDetails); const blocks = blocksResponse !== null ? blocksResponse.blocks : null; if (Array.isArray(blocks) && blocks.length > 0) { const currentBlock = numberTo0x(blocks[0].number); const timestamp = blocks[0].timestamp.to; const blockTimeStamp: LatestBlockNumberTimestamp = { blockNumber: currentBlock, timeStampTo: timestamp }; // save the latest block number in cache - await this.cacheService.set(cacheKey, currentBlock, caller, requestIdPrefix, this.ethBlockNumberCacheTtlMs); + await this.cacheService.set(cacheKey, currentBlock, caller, requestDetails, this.ethBlockNumberCacheTtlMs); return blockTimeStamp; } @@ -561,8 +550,8 @@ export class EthImpl implements Eth { * the same value. This can be specified via an environment variable * `CHAIN_ID`. */ - chainId(requestDetails: IRequestDetails): string { - this.logger.trace(`${requestDetails.requestIdPrefix} chainId()`); + chainId(requestDetails: RequestDetails): string { + this.logger.trace(`${requestDetails.formattedRequestId} chainId()`); return this.chain; } @@ -573,9 +562,9 @@ export class EthImpl implements Eth { async estimateGas( transaction: IContractCallRequest, _blockParam: string | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; const callData = transaction.data ? transaction.data : transaction.input; const callDataSize = callData ? callData.length : 0; @@ -614,16 +603,16 @@ export class EthImpl implements Eth { * Executes an estimate contract call gas request in the mirror node. * * @param {IContractCallRequest} transaction The transaction data for the contract call. - * @param requestIdPrefix The prefix for the request ID. + * @param {RequestDetails} requestDetails The request details for logging and tracking. * @returns {Promise} the response from the mirror node */ private async estimateGasFromMirrorNode( transaction: IContractCallRequest, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { await this.contractCallFormat(transaction, requestDetails); const callData = { ...transaction, estimate: true }; - return this.mirrorNodeClient.postContractCall(callData, requestDetails.requestIdPrefix); + return this.mirrorNodeClient.postContractCall(callData, requestDetails); } /** @@ -631,16 +620,16 @@ export class EthImpl implements Eth { * This method is used when the mirror node fails to return a gas estimate. * * @param {IContractCallRequest} transaction The transaction data for the contract call. - * @param {string} requestIdPrefix The prefix for the request ID. + * @param {RequestDetails} requestDetails The request details for logging and tracking. * @param error (Optional) received error from the mirror-node contract call request. * @returns {Promise} the calculated gas cost for the transaction */ private async predefinedGasForTransaction( transaction: IContractCallRequest, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, error?: any, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; const isSimpleTransfer = !!transaction?.to && (!transaction.data || transaction.data === '0x'); const isContractCall = !!transaction?.to && transaction?.data && transaction.data.length >= constants.FUNCTION_SELECTOR_CHAR_LENGTH; @@ -693,16 +682,15 @@ export class EthImpl implements Eth { * if not found, it fetches it from the mirror node. * * @param {string} address the address of the account - * @param {string} requestIdPrefix the prefix for the request ID + * @param {RequestDetails} requestDetails the request details for logging and tracking * @returns {Promise} the account (if such exists for the given address) */ - private async getAccount(address: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + private async getAccount(address: string, requestDetails: RequestDetails): Promise { const key = `${constants.CACHE_KEY.ACCOUNT}_${address}`; - let account = await this.cacheService.getAsync(key, EthImpl.ethEstimateGas, requestIdPrefix); + let account = await this.cacheService.getAsync(key, EthImpl.ethEstimateGas, requestDetails); if (!account) { - account = await this.mirrorNodeClient.getAccount(address, requestIdPrefix); - await this.cacheService.set(key, account, EthImpl.ethEstimateGas, requestIdPrefix); + account = await this.mirrorNodeClient.getAccount(address, requestDetails); + await this.cacheService.set(key, account, EthImpl.ethEstimateGas, requestDetails); } return account; } @@ -712,7 +700,7 @@ export class EthImpl implements Eth { * @param transaction * @param requestIdPrefix */ - async contractCallFormat(transaction: IContractCallRequest, requestDetails: IRequestDetails): Promise { + async contractCallFormat(transaction: IContractCallRequest, requestDetails: RequestDetails): Promise { if (transaction.value) { transaction.value = weibarHexToTinyBarInt(transaction.value); } @@ -754,13 +742,13 @@ export class EthImpl implements Eth { * @returns {Promise} The current gas price in weibars as a hexadecimal string. * @throws Will throw an error if unable to retrieve the gas price. */ - async gasPrice(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} eth_gasPrice`); + async gasPrice(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} eth_gasPrice`); try { let gasPrice: number | undefined = await this.cacheService.getAsync( constants.CACHE_KEY.GAS_PRICE, EthImpl.ethGasPrice, - requestDetails.requestIdPrefix, + requestDetails, ); if (!gasPrice) { @@ -770,119 +758,119 @@ export class EthImpl implements Eth { constants.CACHE_KEY.GAS_PRICE, gasPrice, EthImpl.ethGasPrice, - requestDetails.requestIdPrefix, + requestDetails, this.ethGasPRiceCacheTtlMs, ); } return numberTo0x(gasPrice); } catch (error) { - throw this.common.genericErrorHandler(error, `${requestDetails.requestIdPrefix} Failed to retrieve gasPrice`); + throw this.common.genericErrorHandler(error, `${requestDetails.formattedRequestId} Failed to retrieve gasPrice`); } } /** * Gets whether this "Ethereum client" is a miner. We don't mine, so this always returns false. */ - async mining(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} mining()`); + async mining(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} mining()`); return false; } /** * TODO Needs docs, or be removed? */ - async submitWork(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} submitWork()`); + async submitWork(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} submitWork()`); return false; } /** * TODO Needs docs, or be removed? */ - async syncing(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} syncing()`); + async syncing(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} syncing()`); return false; } /** * Always returns null. There are no uncles in Hedera. */ - async getUncleByBlockHashAndIndex(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} getUncleByBlockHashAndIndex()`); + async getUncleByBlockHashAndIndex(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} getUncleByBlockHashAndIndex()`); return null; } /** * Always returns null. There are no uncles in Hedera. */ - async getUncleByBlockNumberAndIndex(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} getUncleByBlockNumberAndIndex()`); + async getUncleByBlockNumberAndIndex(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} getUncleByBlockNumberAndIndex()`); return null; } /** * Always returns '0x0'. There are no uncles in Hedera. */ - async getUncleCountByBlockHash(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} getUncleCountByBlockHash()`); + async getUncleCountByBlockHash(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} getUncleCountByBlockHash()`); return EthImpl.zeroHex; } /** * Always returns '0x0'. There are no uncles in Hedera. */ - async getUncleCountByBlockNumber(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} getUncleCountByBlockNumber()`); + async getUncleCountByBlockNumber(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} getUncleCountByBlockNumber()`); return EthImpl.zeroHex; } /** * TODO Needs docs, or be removed? */ - async hashrate(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} hashrate()`); + async hashrate(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} hashrate()`); return EthImpl.zeroHex; } /** * Always returns UNSUPPORTED_METHOD error. */ - getWork(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} getWork()`); + getWork(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} getWork()`); return predefined.UNSUPPORTED_METHOD; } /** * Unsupported methods always return UNSUPPORTED_METHOD error. */ - submitHashrate(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} submitHashrate()`); + submitHashrate(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} submitHashrate()`); return predefined.UNSUPPORTED_METHOD; } - signTransaction(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} signTransaction()`); + signTransaction(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} signTransaction()`); return predefined.UNSUPPORTED_METHOD; } - sign(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} sign()`); + sign(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} sign()`); return predefined.UNSUPPORTED_METHOD; } - sendTransaction(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} sendTransaction()`); + sendTransaction(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} sendTransaction()`); return predefined.UNSUPPORTED_METHOD; } - protocolVersion(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} protocolVersion()`); + protocolVersion(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} protocolVersion()`); return predefined.UNSUPPORTED_METHOD; } - coinbase(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} coinbase()`); + coinbase(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} coinbase()`); return predefined.UNSUPPORTED_METHOD; } @@ -897,17 +885,17 @@ export class EthImpl implements Eth { async getStorageAt( address: string, slot: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, blockNumberOrTagOrHash?: string | null, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace( `${requestIdPrefix} getStorageAt(address=${address}, slot=${slot}, blockNumberOrOrHashTag=${blockNumberOrTagOrHash})`, ); let result = EthImpl.zeroHex32Byte; // if contract or slot not found then return 32 byte 0 - const blockResponse = await this.common.getHistoricalBlockResponse(requestIdPrefix, blockNumberOrTagOrHash, false); + const blockResponse = await this.common.getHistoricalBlockResponse(requestDetails, blockNumberOrTagOrHash, false); // To save a request to the mirror node for `latest` and `pending` blocks, we directly return null from `getHistoricalBlockResponse` // But if a block number or `earliest` tag is passed and the mirror node returns `null`, we should throw an error. if (!this.common.blockTagIsLatestOrPending(blockNumberOrTagOrHash) && blockResponse == null) { @@ -917,7 +905,7 @@ export class EthImpl implements Eth { const blockEndTimestamp = blockResponse?.timestamp?.to; await this.mirrorNodeClient - .getContractStateByAddressAndSlot(address, slot, requestIdPrefix, blockEndTimestamp) + .getContractStateByAddressAndSlot(address, slot, requestDetails, blockEndTimestamp) .then((response) => { if (response !== null && response.state.length > 0) { result = response.state[0].value; @@ -953,9 +941,9 @@ export class EthImpl implements Eth { async getBalance( account: string, blockNumberOrTagOrHash: string | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; const latestBlockTolerance = 1; this.logger.trace(`${requestIdPrefix} getBalance(account=${account}, blockNumberOrTag=${blockNumberOrTagOrHash})`); @@ -965,7 +953,7 @@ export class EthImpl implements Eth { if (!this.common.blockTagIsLatestOrPending(blockNumberOrTagOrHash)) { let blockHashNumber, isHash; const cacheKey = `${constants.CACHE_KEY.ETH_BLOCK_NUMBER}`; - const blockNumberCached = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBalance, requestIdPrefix); + const blockNumberCached = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBalance, requestDetails); if (blockNumberCached) { this.logger.trace(`${requestIdPrefix} returning cached value ${cacheKey}:${JSON.stringify(blockNumberCached)}`); @@ -976,7 +964,7 @@ export class EthImpl implements Eth { if (blockNumberOrTagOrHash != null && blockNumberOrTagOrHash.length > 32) { isHash = true; - blockHashNumber = await this.mirrorNodeClient.getBlock(blockNumberOrTagOrHash, requestIdPrefix); + blockHashNumber = await this.mirrorNodeClient.getBlock(blockNumberOrTagOrHash, requestDetails); } const currentBlockNumber = isHash ? Number(blockHashNumber.number) : Number(blockNumberOrTagOrHash); @@ -996,7 +984,7 @@ export class EthImpl implements Eth { // check cache first // create a key for the cache const cacheKey = `${constants.CACHE_KEY.ETH_GET_BALANCE}-${account}-${blockNumberOrTagOrHash}`; - let cachedBalance = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBalance, requestIdPrefix); + let cachedBalance = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBalance, requestDetails); if (cachedBalance && this.shouldUseCacheForBalance(blockNumberOrTagOrHash)) { this.logger.trace(`${requestIdPrefix} returning cached value ${cacheKey}:${JSON.stringify(cachedBalance)}`); return cachedBalance; @@ -1009,7 +997,7 @@ export class EthImpl implements Eth { try { if (!this.common.blockTagIsLatestOrPending(blockNumberOrTagOrHash)) { - const block = await this.common.getHistoricalBlockResponse(requestIdPrefix, blockNumberOrTagOrHash, true); + const block = await this.common.getHistoricalBlockResponse(requestDetails, blockNumberOrTagOrHash, true); if (block) { blockNumber = block.number; @@ -1023,7 +1011,7 @@ export class EthImpl implements Eth { if (timeDiff > constants.BALANCES_UPDATE_INTERVAL) { const balance = await this.mirrorNodeClient.getBalanceAtTimestamp( account, - requestIdPrefix, + requestDetails, block.timestamp.from, ); balanceFound = true; @@ -1035,7 +1023,7 @@ export class EthImpl implements Eth { else { let currentBalance = 0; let balanceFromTxs = 0; - mirrorAccount = await this.mirrorNodeClient.getAccountPageLimit(account, requestIdPrefix); + mirrorAccount = await this.mirrorNodeClient.getAccountPageLimit(account, requestDetails); if (mirrorAccount) { if (mirrorAccount.balance) { currentBalance = mirrorAccount.balance.balance; @@ -1051,10 +1039,7 @@ export class EthImpl implements Eth { const nextPageTimeMarker = nextPageParams.get('timestamp'); // If nextPageTimeMarker is greater than the block.timestamp.to, then we need to paginate to get the transactions for the block.timestamp.to if (nextPageTimeMarker && nextPageTimeMarker?.split(':')[1] >= block.timestamp.to) { - const pagedTransactions = await this.mirrorNodeClient.getAccountPaginated( - nextPage, - requestIdPrefix, - ); + const pagedTransactions = await this.mirrorNodeClient.getAccountPaginated(nextPage, requestDetails); mirrorAccount.transactions = mirrorAccount.transactions.concat(pagedTransactions); } // If nextPageTimeMarker is less than the block.timestamp.to, then just run the getBalanceAtBlockTimestamp function in this case as well. @@ -1076,7 +1061,7 @@ export class EthImpl implements Eth { if (!balanceFound && !mirrorAccount) { // If no balance and no account, then we need to make a request to the mirror node for the account. - mirrorAccount = await this.mirrorNodeClient.getAccountPageLimit(account, requestIdPrefix); + mirrorAccount = await this.mirrorNodeClient.getAccountPageLimit(account, requestDetails); // Test if exists here if (mirrorAccount !== null && mirrorAccount !== undefined) { balanceFound = true; @@ -1100,7 +1085,7 @@ export class EthImpl implements Eth { cacheKey, cachedBalance, EthImpl.ethGetBalance, - requestIdPrefix, + requestDetails, this.ethGetBalanceCacheTtlMs, ); @@ -1120,8 +1105,8 @@ export class EthImpl implements Eth { * @param blockNumber * @param requestIdPrefix */ - async getCode(address: string, blockNumber: string | null, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails?.requestIdPrefix; + async getCode(address: string, blockNumber: string | null, requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; if (!EthImpl.isBlockParamValid(blockNumber)) { throw predefined.UNKNOWN_BLOCK( `The value passed is not a valid blockHash/blockNumber/blockTag value: ${blockNumber}`, @@ -1142,7 +1127,7 @@ export class EthImpl implements Eth { const cachedResponse: string | undefined = await this.cacheService.getAsync( cachedLabel, EthImpl.ethGetCode, - requestIdPrefix, + requestDetails, ); if (cachedResponse != undefined) { return cachedResponse; @@ -1153,7 +1138,7 @@ export class EthImpl implements Eth { address, [constants.TYPE_CONTRACT, constants.TYPE_TOKEN], EthImpl.ethGetCode, - requestIdPrefix, + requestDetails, ); if (result) { if (result?.type === constants.TYPE_TOKEN) { @@ -1170,7 +1155,7 @@ export class EthImpl implements Eth { cachedLabel, result?.entity.runtime_bytecode, EthImpl.ethGetCode, - requestIdPrefix, + requestDetails, ); return result?.entity.runtime_bytecode; } @@ -1228,17 +1213,17 @@ export class EthImpl implements Eth { * @param showDetails * @param requestIdPrefix */ - async getBlockByHash(hash: string, showDetails: boolean, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + async getBlockByHash(hash: string, showDetails: boolean, requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getBlockByHash(hash=${hash}, showDetails=${showDetails})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_BLOCK_BY_HASH}_${hash}_${showDetails}`; - let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByHash, requestIdPrefix); + let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByHash, requestDetails); if (!block) { block = await this.getBlock(hash, showDetails, requestDetails).catch((e: any) => { throw this.common.genericErrorHandler(e, `${requestIdPrefix} Failed to retrieve block for hash ${hash}`); }); - await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByHash, requestIdPrefix); + await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByHash, requestDetails); } return block; @@ -1253,13 +1238,13 @@ export class EthImpl implements Eth { async getBlockByNumber( blockNumOrTag: string, showDetails: boolean, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getBlockByNumber(blockNum=${blockNumOrTag}, showDetails=${showDetails})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_BLOCK_BY_NUMBER}_${blockNumOrTag}_${showDetails}`; - let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByNumber, requestIdPrefix); + let block = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetBlockByNumber, requestDetails); if (!block) { block = await this.getBlock(blockNumOrTag, showDetails, requestDetails).catch((e: any) => { throw this.common.genericErrorHandler( @@ -1269,7 +1254,7 @@ export class EthImpl implements Eth { }); if (!this.common.blockTagIsLatestOrPending(blockNumOrTag)) { - await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, requestIdPrefix); + await this.cacheService.set(cacheKey, block, EthImpl.ethGetBlockByNumber, requestDetails); } } @@ -1282,15 +1267,15 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getBlockTransactionCountByHash(hash: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + async getBlockTransactionCountByHash(hash: string, requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getBlockTransactionCountByHash(hash=${hash}, showDetails=%o)`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_TRANSACTION_COUNT_BY_HASH}_${hash}`; const cachedResponse = await this.cacheService.getAsync( cacheKey, EthImpl.ethGetTransactionCountByHash, - requestIdPrefix, + requestDetails, ); if (cachedResponse) { this.logger.debug( @@ -1300,13 +1285,13 @@ export class EthImpl implements Eth { } const transactionCount = await this.mirrorNodeClient - .getBlock(hash, requestIdPrefix) + .getBlock(hash, requestDetails) .then((block) => EthImpl.getTransactionCountFromBlockResponse(block)) .catch((e: any) => { throw this.common.genericErrorHandler(e, `${requestIdPrefix} Failed to retrieve block for hash ${hash}`); }); - await this.cacheService.set(cacheKey, transactionCount, EthImpl.ethGetTransactionCountByHash, requestIdPrefix); + await this.cacheService.set(cacheKey, transactionCount, EthImpl.ethGetTransactionCountByHash, requestDetails); return transactionCount; } @@ -1317,9 +1302,9 @@ export class EthImpl implements Eth { */ async getBlockTransactionCountByNumber( blockNumOrTag: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getBlockTransactionCountByNumber(blockNum=${blockNumOrTag}, showDetails=%o)`); const blockNum = await this.translateBlockTag(blockNumOrTag, requestDetails); @@ -1327,7 +1312,7 @@ export class EthImpl implements Eth { const cachedResponse = await this.cacheService.getAsync( cacheKey, EthImpl.ethGetTransactionCountByNumber, - requestIdPrefix, + requestDetails, ); if (cachedResponse) { this.logger.debug( @@ -1337,7 +1322,7 @@ export class EthImpl implements Eth { } const transactionCount = await this.mirrorNodeClient - .getBlock(blockNum, requestIdPrefix) + .getBlock(blockNum, requestDetails) .then((block) => EthImpl.getTransactionCountFromBlockResponse(block)) .catch((e: any) => { throw this.common.genericErrorHandler( @@ -1346,7 +1331,7 @@ export class EthImpl implements Eth { ); }); - await this.cacheService.set(cacheKey, transactionCount, EthImpl.ethGetTransactionCountByNumber, requestIdPrefix); + await this.cacheService.set(cacheKey, transactionCount, EthImpl.ethGetTransactionCountByNumber, requestDetails); return transactionCount; } @@ -1360,9 +1345,9 @@ export class EthImpl implements Eth { async getTransactionByBlockHashAndIndex( blockHash: string, transactionIndex: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace( `${requestIdPrefix} getTransactionByBlockHashAndIndex(hash=${blockHash}, index=${transactionIndex})`, ); @@ -1391,9 +1376,9 @@ export class EthImpl implements Eth { async getTransactionByBlockNumberAndIndex( blockNumOrTag: string, transactionIndex: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace( `${requestIdPrefix} getTransactionByBlockNumberAndIndex(blockNum=${blockNumOrTag}, index=${transactionIndex})`, ); @@ -1426,14 +1411,14 @@ export class EthImpl implements Eth { async getTransactionCount( address: string, blockNumOrTag: string | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getTransactionCount(address=${address}, blockNumOrTag=${blockNumOrTag})`); // cache considerations for high load const cacheKey = `eth_getTransactionCount_${address}_${blockNumOrTag}`; - let nonceCount = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetTransactionCount, requestIdPrefix); + let nonceCount = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetTransactionCount, requestDetails); if (nonceCount) { this.logger.trace(`${requestIdPrefix} returning cached value ${cacheKey}:${JSON.stringify(nonceCount)}`); return nonceCount; @@ -1466,14 +1451,14 @@ export class EthImpl implements Eth { blockNumOrTag === EthImpl.blockEarliest || !isNaN(blockNum) ? constants.CACHE_TTL.ONE_DAY : this.ethGetTransactionCountCacheTtl; // cache historical values longer as they don't change - await this.cacheService.set(cacheKey, nonceCount, EthImpl.ethGetTransactionCount, requestIdPrefix, cacheTtl); + await this.cacheService.set(cacheKey, nonceCount, EthImpl.ethGetTransactionCount, requestDetails, cacheTtl); return nonceCount; } async parseRawTxAndPrecheck( transaction: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, networkGasPriceInWeiBars: number, ): Promise { let interactingEntity = ''; @@ -1484,10 +1469,10 @@ export class EthImpl implements Eth { interactingEntity = parsedTx.to?.toString() || ''; originatingAddress = parsedTx.from?.toString() || ''; this.logger.trace( - `${requestDetails.requestIdPrefix} sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, + `${requestDetails.formattedRequestId} sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, ); - await this.precheck.sendRawTransactionCheck(parsedTx, networkGasPriceInWeiBars, requestDetails.requestIdPrefix); + await this.precheck.sendRawTransactionCheck(parsedTx, networkGasPriceInWeiBars, requestDetails.formattedRequestId); return parsedTx; } catch (e: any) { this.logger.warn( @@ -1503,11 +1488,11 @@ export class EthImpl implements Eth { transactionBuffer, txSubmitted, parsedTx, - requestIdPrefix, + requestDetails, ): Promise { this.logger.error( e, - `${requestIdPrefix} Failed to successfully submit sendRawTransaction for transaction ${transaction}`, + `${requestDetails.formattedRequestId} Failed to successfully submit sendRawTransaction for transaction ${transaction}`, ); if (e instanceof JsonRpcError) { return e; @@ -1522,21 +1507,23 @@ export class EthImpl implements Eth { // running a polling loop to give mirror node enough time to update account nonce let accountNonce: number | null = null; for (let i = 0; i < mirrorNodeGetContractResultRetries; i++) { - const accountInfo = await this.mirrorNodeClient.getAccount(parsedTx.from!, requestIdPrefix); + const accountInfo = await this.mirrorNodeClient.getAccount(parsedTx.from!, requestDetails); if (accountInfo.ethereum_nonce !== parsedTx.nonce) { accountNonce = accountInfo.ethereum_nonce; break; } this.logger.trace( - `${requestIdPrefix} Repeating retry to poll for updated account nonce. Count ${i} of ${mirrorNodeGetContractResultRetries}. Waiting ${this.mirrorNodeClient.getMirrorNodeRetryDelay()} ms before initiating a new request`, + `${ + requestDetails.formattedRequestId + } Repeating retry to poll for updated account nonce. Count ${i} of ${mirrorNodeGetContractResultRetries}. Waiting ${this.mirrorNodeClient.getMirrorNodeRetryDelay()} ms before initiating a new request`, ); await new Promise((r) => setTimeout(r, this.mirrorNodeClient.getMirrorNodeRetryDelay())); } if (!accountNonce) { - this.logger.warn(`${requestIdPrefix} Cannot find updated account nonce.`); - throw predefined.INTERNAL_ERROR(`Cannot find updated account nonce for WRONG_NONCE error.`); + this.logger.warn(`${requestDetails.formattedRequestId} Cannot find updated account nonce.`); + throw predefined.INTERNAL_ERROR(`Cannot find updated account nonce for WRONT_NONCE error.`); } if (parsedTx.nonce > accountNonce) { @@ -1551,11 +1538,11 @@ export class EthImpl implements Eth { return predefined.INTERNAL_ERROR(e.message.toString()); } - await this.mirrorNodeClient.getContractRevertReasonFromTransaction(e, requestIdPrefix); + await this.mirrorNodeClient.getContractRevertReasonFromTransaction(e, requestDetails); this.logger.error( e, - `${requestIdPrefix} Failed sendRawTransaction during record retrieval for transaction ${transaction}, returning computed hash`, + `${requestDetails.formattedRequestId} Failed sendRawTransaction during record retrieval for transaction ${transaction}, returning computed hash`, ); //Return computed hash if unable to retrieve EthereumHash from record due to error return prepend0x(createHash('keccak256').update(transactionBuffer).digest('hex')); @@ -1567,8 +1554,8 @@ export class EthImpl implements Eth { * @param transaction * @param requestId */ - async sendRawTransaction(transaction: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + async sendRawTransaction(transaction: string, requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; if (transaction?.length >= constants.FUNCTION_SELECTOR_CHAR_LENGTH) this.ethExecutionsCounter .labels(EthImpl.ethSendRawTransaction, transaction.substring(0, constants.FUNCTION_SELECTOR_CHAR_LENGTH)) @@ -1612,7 +1599,7 @@ export class EthImpl implements Eth { this.mirrorNodeClient.getContractResult.name, [formattedId], this.mirrorNodeClient.getMirrorNodeRequestRetryCount(), - requestIdPrefix, + requestDetails, ); if (!contractResult) { @@ -1635,7 +1622,7 @@ export class EthImpl implements Eth { transactionBuffer, txSubmitted, parsedTx, - requestIdPrefix, + requestDetails, ); } finally { /** @@ -1660,9 +1647,9 @@ export class EthImpl implements Eth { async call( call: IContractCallRequest, blockParam: string | object | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; const callData = call.data ? call.data : call.input; // log request this.logger.info( @@ -1733,11 +1720,11 @@ export class EthImpl implements Eth { value: string | number; }, transactionIndex: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; const contractResults = await this.mirrorNodeClient.getContractResults( - requestIdPrefix, + requestDetails, { [blockParam.title]: blockParam.value, transactionIndex: Number(transactionIndex), @@ -1748,7 +1735,7 @@ export class EthImpl implements Eth { if (!contractResults[0]) return null; const resolvedToAddress = await this.resolveEvmAddress(contractResults[0].to, requestIdPrefix); - const resolvedFromAddress = await this.resolveEvmAddress(contractResults[0].from, requestIdPrefix, [ + const resolvedFromAddress = await this.resolveEvmAddress(contractResults[0].from, requestDetails, [ constants.TYPE_ACCOUNT, ]); @@ -1758,7 +1745,7 @@ export class EthImpl implements Eth { // according to EIP-1898 (https://eips.ethereum.org/EIPS/eip-1898) block param can either be a string (blockNumber or Block Tag) or an object (blockHash or blockNumber) private async extractBlockNumberOrTag( blockParam: string | object | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { if (!blockParam) { return null; @@ -1792,7 +1779,7 @@ export class EthImpl implements Eth { return null; } - private async getBlockNumberFromHash(blockHash: string, requestDetails: IRequestDetails): Promise { + private async getBlockNumberFromHash(blockHash: string, requestDetails: RequestDetails): Promise { const block = await this.getBlockByHash(blockHash, false, requestDetails); if (block != null) { return block.number; @@ -1806,9 +1793,9 @@ export class EthImpl implements Eth { gas: number | null, value: number | string | null | undefined, block: string | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; let callData: IContractCallRequest = {}; try { this.logger.debug( @@ -1881,9 +1868,9 @@ export class EthImpl implements Eth { async callConsensusNode( call: any, gas: number | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; // Execute the call and get the response if (!gas) { gas = Number.parseInt(this.defaultGas); @@ -1933,7 +1920,7 @@ export class EthImpl implements Eth { cacheKey, formattedCallReponse, EthImpl.ethCall, - requestIdPrefix, + requestDetails, this.ethCallCacheTtl, ); return formattedCallReponse; @@ -1969,7 +1956,7 @@ export class EthImpl implements Eth { async resolveEvmAddress( address: string, - requestIdPrefix: string, + requestDetails: RequestDetails, searchableTypes = [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT], ): Promise { if (!address) return address; @@ -1978,7 +1965,7 @@ export class EthImpl implements Eth { address, searchableTypes, EthImpl.ethGetCode, - requestIdPrefix, + requestDetails, 0, ); let resolvedAddress = address; @@ -1999,8 +1986,8 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getTransactionByHash(hash: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + async getTransactionByHash(hash: string, requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getTransactionByHash(hash=${hash})`, hash); const contractResult = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestIdPrefix); @@ -2011,7 +1998,7 @@ export class EthImpl implements Eth { { 'transaction.hash': hash, }, - requestIdPrefix, + requestDetails, ); // no tx found @@ -2029,7 +2016,7 @@ export class EthImpl implements Eth { ); } - const fromAddress = await this.resolveEvmAddress(contractResult.from, requestIdPrefix, [constants.TYPE_ACCOUNT]); + const fromAddress = await this.resolveEvmAddress(contractResult.from, requestDetails, [constants.TYPE_ACCOUNT]); const toAddress = await this.resolveEvmAddress(contractResult.to, requestIdPrefix); contractResult.chain_id = contractResult.chain_id || this.chain; @@ -2046,16 +2033,12 @@ export class EthImpl implements Eth { * @param hash * @param requestIdPrefix */ - async getTransactionReceipt(hash: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + async getTransactionReceipt(hash: string, requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getTransactionReceipt(${hash})`); const cacheKey = `${constants.CACHE_KEY.ETH_GET_TRANSACTION_RECEIPT}_${hash}`; - const cachedResponse = await this.cacheService.getAsync( - cacheKey, - EthImpl.ethGetTransactionReceipt, - requestIdPrefix, - ); + const cachedResponse = await this.cacheService.getAsync(cacheKey, EthImpl.ethGetTransactionReceipt, requestDetails); if (cachedResponse) { this.logger.debug( `${requestIdPrefix} getTransactionReceipt returned cached response: ${JSON.stringify(cachedResponse)}`, @@ -2071,7 +2054,7 @@ export class EthImpl implements Eth { { 'transaction.hash': hash, }, - requestIdPrefix, + requestDetails, ); // no tx found @@ -2105,7 +2088,7 @@ export class EthImpl implements Eth { cacheKey, receipt, EthImpl.ethGetTransactionReceipt, - requestIdPrefix, + requestDetails, constants.CACHE_TTL.ONE_DAY, ); return receipt; @@ -2156,14 +2139,14 @@ export class EthImpl implements Eth { cacheKey, receipt, EthImpl.ethGetTransactionReceipt, - requestIdPrefix, + requestDetails, constants.CACHE_TTL.ONE_DAY, ); return receipt; } } - private async getCurrentGasPriceForBlock(blockHash: string, requestDetails: IRequestDetails): Promise { + private async getCurrentGasPriceForBlock(blockHash: string, requestDetails: RequestDetails): Promise { const block = await this.getBlockByHash(blockHash, false, requestDetails); const timestampDecimal = parseInt(block ? block.timestamp : '0', 16); const timestampDecimalString = timestampDecimal > 0 ? timestampDecimal.toString() : ''; @@ -2217,7 +2200,7 @@ export class EthImpl implements Eth { * @param requestDetails * @private */ - private async translateBlockTag(tag: string | null, requestDetails: IRequestDetails): Promise { + private async translateBlockTag(tag: string | null, requestDetails: RequestDetails): Promise { if (this.common.blockTagIsLatestOrPending(tag)) { return Number(await this.blockNumber(requestDetails)); } else if (tag === EthImpl.blockEarliest) { @@ -2250,7 +2233,7 @@ export class EthImpl implements Eth { showDetails: boolean, logs: Log[], transactionsArray: Array, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Array { let filteredLogs: Log[]; if (showDetails) { @@ -2269,7 +2252,7 @@ export class EthImpl implements Eth { } this.logger.trace( - `${requestDetails.requestIdPrefix} Synthetic transaction hashes will be populated in the block response`, + `${requestDetails.formattedRequestId} Synthetic transaction hashes will be populated in the block response`, ); return transactionsArray; @@ -2288,16 +2271,16 @@ export class EthImpl implements Eth { private async getBlock( blockHashOrNumber: string, showDetails: boolean, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; - const blockResponse = await this.common.getHistoricalBlockResponse(requestIdPrefix, blockHashOrNumber, true); + const requestIdPrefix = requestDetails.formattedRequestId; + const blockResponse = await this.common.getHistoricalBlockResponse(requestDetails, blockHashOrNumber, true); if (blockResponse == null) return null; const timestampRange = blockResponse.timestamp; const timestampRangeParams = [`gte:${timestampRange.from}`, `lte:${timestampRange.to}`]; const contractResults = await this.mirrorNodeClient.getContractResults( - requestIdPrefix, + requestDetails, { timestamp: timestampRangeParams }, undefined, ); @@ -2305,7 +2288,7 @@ export class EthImpl implements Eth { const params = { timestamp: timestampRangeParams }; // get contract results logs using block timestamp range - const logs = await this.common.getLogsWithParams(null, params, requestIdPrefix); + const logs = await this.common.getLogsWithParams(null, params, requestDetails); if (contractResults == null && logs.length == 0) { // contract result not found @@ -2321,9 +2304,7 @@ export class EthImpl implements Eth { // prepare transactionArray let transactionArray: any[] = []; for (const contractResult of contractResults) { - contractResult.from = await this.resolveEvmAddress(contractResult.from, requestIdPrefix, [ - constants.TYPE_ACCOUNT, - ]); + contractResult.from = await this.resolveEvmAddress(contractResult.from, requestDetails, [constants.TYPE_ACCOUNT]); contractResult.to = await this.resolveEvmAddress(contractResult.to, requestIdPrefix); contractResult.chain_id = contractResult.chain_id || this.chain; @@ -2420,9 +2401,9 @@ export class EthImpl implements Eth { private async getAcccountNonceFromContractResult( address: string, blockNumOrHash: any, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; // get block timestamp for blockNum const block = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestIdPrefix); // consider caching error responses if (block == null) { @@ -2434,7 +2415,7 @@ export class EthImpl implements Eth { address, block.timestamp.to, 2, - requestIdPrefix, + requestDetails, ); if (ethereumTransactions == null || ethereumTransactions.transactions.length === 0) { return EthImpl.zeroHex; @@ -2449,7 +2430,7 @@ export class EthImpl implements Eth { // get the transaction result for the latest transaction const transactionResult = await this.mirrorNodeClient.getContractResult( ethereumTransactions.transactions[0].transaction_id, - requestIdPrefix, + requestDetails, ); if (transactionResult == null) { throw predefined.RESOURCE_NOT_FOUND( @@ -2469,8 +2450,8 @@ export class EthImpl implements Eth { return numberTo0x(transactionResult.nonce + 1); // nonce is 0 indexed } - private async getAccountNonceForEarliestBlock(requestDetails: IRequestDetails): Promise { - const block = await this.mirrorNodeClient.getEarliestBlock(requestDetails.requestIdPrefix); + private async getAccountNonceForEarliestBlock(requestDetails: RequestDetails): Promise { + const block = await this.mirrorNodeClient.getEarliestBlock(requestDetails.formattedRequestId); if (block == null) { throw predefined.INTERNAL_ERROR('No network blocks found'); } @@ -2487,9 +2468,9 @@ export class EthImpl implements Eth { private async getAccountNonceForHistoricBlock( address: string, blockNumOrHash: number | string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; let getBlock; const isParamBlockNum = typeof blockNumOrHash === 'number' ? true : false; @@ -2523,13 +2504,13 @@ export class EthImpl implements Eth { toBlock: string | 'latest', address: string | string[] | null, topics: any[] | null, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - return this.common.getLogs(blockHash, fromBlock, toBlock, address, topics, requestDetails.requestIdPrefix); + return this.common.getLogs(blockHash, fromBlock, toBlock, address, topics, requestDetails.formattedRequestId); } - async maxPriorityFeePerGas(requestDetails: IRequestDetails): Promise { - this.logger.trace(`${requestDetails.requestIdPrefix} maxPriorityFeePerGas()`); + async maxPriorityFeePerGas(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} maxPriorityFeePerGas()`); return EthImpl.zeroHex; } diff --git a/packages/relay/src/lib/hbarlimiter/index.ts b/packages/relay/src/lib/hbarlimiter/index.ts index 818d442e7b..b7bc9858f8 100644 --- a/packages/relay/src/lib/hbarlimiter/index.ts +++ b/packages/relay/src/lib/hbarlimiter/index.ts @@ -20,9 +20,9 @@ import { Logger } from 'pino'; import constants from '../constants'; -import { predefined } from '../errors/JsonRpcError'; import { Registry, Counter, Gauge } from 'prom-client'; import { formatRequestIdMessage } from '../../formatters'; +import { RequestDetails } from '../types/RequestDetails'; export default class HbarLimit { private enabled: boolean = false; @@ -79,7 +79,7 @@ export default class HbarLimit { * @param {string} mode - The mode of the transaction or request. * @param {string} methodName - The name of the method being invoked. * @param {string} originalCallerAddress - The address of the original caller making the request. - * @param {string} [requestId] - An optional unique request ID for tracking the request. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {boolean} - Returns `true` if the rate limit should be enforced, otherwise `false`. */ shouldLimit( @@ -87,13 +87,13 @@ export default class HbarLimit { mode: string, methodName: string, originalCallerAddress: string, - requestId?: string, + requestDetails: RequestDetails, ): boolean { if (!this.enabled) { return false; } - const requestIdPrefix = formatRequestIdMessage(requestId); + const requestIdPrefix = requestDetails.formattedRequestId; // check if the caller is a whitelisted caller if (this.isAccountWhiteListed(originalCallerAddress)) { @@ -104,7 +104,7 @@ export default class HbarLimit { } if (this.shouldResetLimiter(currentDateNow)) { - this.resetLimiter(currentDateNow, requestIdPrefix); + this.resetLimiter(currentDateNow, requestDetails); } if (this.remainingBudget <= 0) { @@ -172,21 +172,19 @@ export default class HbarLimit { /** * Add expense to the remaining budget. */ - addExpense(cost: number, currentDateNow: number, requestId?: string) { - const requestIdPrefix = formatRequestIdMessage(requestId); - + addExpense(cost: number, currentDateNow: number, requestDetails: RequestDetails) { if (!this.enabled) { return; } if (this.shouldResetLimiter(currentDateNow)) { - this.resetLimiter(currentDateNow, requestIdPrefix); + this.resetLimiter(currentDateNow, requestDetails); } this.remainingBudget -= cost; this.hbarLimitRemainingGauge.set(this.remainingBudget); this.logger.trace( - `${requestIdPrefix} HBAR rate limit expense update: cost=${cost}, remainingBudget=${this.remainingBudget}, resetTimestamp=${this.reset}`, + `${requestDetails.formattedRequestId} HBAR rate limit expense update: cost=${cost}, remainingBudget=${this.remainingBudget}, resetTimestamp=${this.reset}`, ); } @@ -264,17 +262,17 @@ export default class HbarLimit { * Decides whether it should reset budget and timer. */ private shouldResetLimiter(currentDateNow: number): boolean { - return this.reset < currentDateNow ? true : false; + return this.reset < currentDateNow; } /** * Reset budget to the total allowed and reset timer to current time plus duration. */ - private resetLimiter(currentDateNow: number, requestIdPrefix: string) { + private resetLimiter(currentDateNow: number, requestDetails: RequestDetails) { this.reset = currentDateNow + this.duration; this.remainingBudget = this.total; this.logger.trace( - `${requestIdPrefix} HBAR Rate Limit reset: remainingBudget= ${this.remainingBudget}, newResetTimestamp= ${this.reset}`, + `${requestDetails.formattedRequestId} HBAR Rate Limit reset: remainingBudget= ${this.remainingBudget}, newResetTimestamp= ${this.reset}`, ); } } diff --git a/packages/relay/src/lib/poller.ts b/packages/relay/src/lib/poller.ts index 40a306dcd0..7f73957704 100644 --- a/packages/relay/src/lib/poller.ts +++ b/packages/relay/src/lib/poller.ts @@ -21,7 +21,7 @@ import { Eth } from '../index'; import { Logger } from 'pino'; import { Registry, Gauge } from 'prom-client'; -import { IRequestDetails } from './types/IRequestDetails'; +import { IRequestDetails } from './types/RequestDetails'; import { Utils } from '../utils'; export interface Poll { diff --git a/packages/relay/src/lib/services/cacheService/cacheService.ts b/packages/relay/src/lib/services/cacheService/cacheService.ts index 03d7221e39..e10e53c238 100644 --- a/packages/relay/src/lib/services/cacheService/cacheService.ts +++ b/packages/relay/src/lib/services/cacheService/cacheService.ts @@ -23,6 +23,7 @@ import { Counter, Registry } from 'prom-client'; import { ICacheClient } from '../../clients/cache/ICacheClient'; import { LocalLRUCache, RedisCache } from '../../clients'; import { RedisCacheError } from '../../errors/RedisCacheError'; +import { RequestDetails } from '../../types/RequestDetails'; /** * A service that manages caching using different cache implementations based on configuration. @@ -199,24 +200,29 @@ export class CacheService { * * @param {string} key - The cache key. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - The optional request ID prefix. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves with the cached value or null if not found. */ - private async getFromSharedCache(key: string, callingMethod: string, requestIdPrefix: string): Promise { + private async getFromSharedCache(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { try { this.cacheMethodsCounter .labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.GET_ASYNC) .inc(1); - return await this.sharedCache.get(key, callingMethod, requestIdPrefix); + return await this.sharedCache.get(key, callingMethod, requestDetails); } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while getting the cache from Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while getting the cache from Redis. Fallback to internal cache.`, +>>>>>>> c7c5c919 (chore: draft changes) ); // fallback to internal cache in case of Redis error - return await this.getFromInternalCache(key, callingMethod, requestIdPrefix); + return await this.getFromInternalCache(key, callingMethod, requestDetails); } } @@ -224,15 +230,15 @@ export class CacheService { * If SharedCacheEnabled will use shared, otherwise will fallback to internal cache. * @param {string} key - The cache key. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - The optional request ID prefix. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves with the cached value or null if not found. * @template T - The type of the cached value. */ - public async getAsync(key: string, callingMethod: string, requestIdPrefix: string): Promise { + public async getAsync(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { if (this.isSharedCacheEnabled) { - return await this.getFromSharedCache(key, callingMethod, requestIdPrefix); + return await this.getFromSharedCache(key, callingMethod, requestDetails); } else { - return await this.getFromInternalCache(key, callingMethod, requestIdPrefix); + return await this.getFromInternalCache(key, callingMethod, requestDetails); } } @@ -241,13 +247,13 @@ export class CacheService { * * @param {string} key - The cache key. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - The optional request ID prefix. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves with the cached value or null if not found. */ - private async getFromInternalCache(key: string, callingMethod: string, requestIdPrefix: string): Promise { + private async getFromInternalCache(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.GET).inc(1); - return await this.internalCache.get(key, callingMethod, requestIdPrefix); + return await this.internalCache.get(key, callingMethod, requestDetails); } /** @@ -258,32 +264,37 @@ export class CacheService { * @param {*} value - The value to cache. * @param {string} callingMethod - The name of the method calling the cache. * @param {number} ttl - Time to live for the cached value in milliseconds (optional). - * @param {string} requestIdPrefix - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ public async set( key: string, value: any, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ttl?: number, ): Promise { if (this.isSharedCacheEnabled) { try { this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.SET).inc(1); - await this.sharedCache.set(key, value, callingMethod, requestIdPrefix, ttl); + await this.sharedCache.set(key, value, callingMethod, requestDetails, ttl); return; } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while setting the cache to Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while setting the cache to Redis. Fallback to internal cache.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } // fallback to internal cache in case of Redis error this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); - await this.internalCache.set(key, value, callingMethod, requestIdPrefix, ttl); + await this.internalCache.set(key, value, callingMethod, requestDetails, ttl); } /** @@ -294,21 +305,21 @@ export class CacheService { * @param {Record} entries - An object containing key-value pairs to cache. * @param {string} callingMethod - The name of the method calling the cache. * @param {number} [ttl] - Time to live for the cached value in milliseconds (optional). - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ public async multiSet( entries: Record, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ttl?: number, ): Promise { if (this.isSharedCacheEnabled) { const metricsMethod = this.shouldMultiSet ? CacheService.methods.MSET : CacheService.methods.PIPELINE; try { if (this.shouldMultiSet) { - await this.sharedCache.multiSet(entries, callingMethod, requestIdPrefix); + await this.sharedCache.multiSet(entries, callingMethod, requestDetails); } else { - await this.sharedCache.pipelineSet(entries, callingMethod, requestIdPrefix, ttl); + await this.sharedCache.pipelineSet(entries, callingMethod, requestDetails, ttl); } this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.REDIS, metricsMethod).inc(1); @@ -316,13 +327,18 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while setting the cache to Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while setting the cache to Redis. Fallback to internal cache.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } // fallback to internal cache, but use pipeline, because of it's TTL support - await this.internalCache.pipelineSet(entries, callingMethod, requestIdPrefix, ttl); + await this.internalCache.pipelineSet(entries, callingMethod, requestDetails, ttl); this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); } @@ -332,37 +348,42 @@ export class CacheService { * Else the internal cache deletion is attempted. * @param {string} key - The key associated with the cached value to delete. * @param {string} callingMethod - The name of the method calling the cache. - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - public async delete(key: string, callingMethod: string, requestIdPrefix: string): Promise { + public async delete(key: string, callingMethod: string, requestDetails: RequestDetails): Promise { if (this.isSharedCacheEnabled) { try { this.cacheMethodsCounter .labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.DELETE) .inc(1); - await this.sharedCache.delete(key, callingMethod, requestIdPrefix); + await this.sharedCache.delete(key, callingMethod, requestDetails); return; } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while deleting cache from Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while deleting cache from Redis.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } // fallback to internal cache in case of Redis error this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.DELETE).inc(1); - await this.internalCache.delete(key, callingMethod, requestIdPrefix); + await this.internalCache.delete(key, callingMethod, requestDetails); } /** * Clears the cache. * If the shared cache is enabled and an error occurs while clearing it, just logs the error. * Else the internal cache clearing is attempted. - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - public async clear(requestIdPrefix: string): Promise { + public async clear(requestDetails: RequestDetails): Promise { if (this.isSharedCacheEnabled) { try { await this.sharedCache.clear(); @@ -370,7 +391,12 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while clearing Redis cache. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while clearing Redis cache.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -384,35 +410,45 @@ export class CacheService { * @param {string} key - The key to increment. * @param {number} amount - The amount to increment by. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves with the new value of the key after incrementing. */ - public async incrBy(key: string, amount: number, callingMethod: string, requestIdPrefix: string): Promise { + public async incrBy( + key: string, + amount: number, + callingMethod: string, + requestDetails: RequestDetails, + ): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { this.cacheMethodsCounter .labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.INCR_BY) .inc(1); - return await this.sharedCache.incrBy(key, amount, callingMethod, requestIdPrefix); + return await this.sharedCache.incrBy(key, amount, callingMethod, requestDetails); } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while incrementing cache in Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while incrementing cache in Redis.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } // Fallback to internal cache - const value = await this.getFromInternalCache(key, callingMethod, requestIdPrefix); + const value = await this.getFromInternalCache(key, callingMethod, requestDetails); const newValue = value + amount; const remainingTtl = this.internalCache instanceof LocalLRUCache - ? await this.internalCache.getRemainingTtl(key, callingMethod, requestIdPrefix) + ? await this.internalCache.getRemainingTtl(key, callingMethod, requestDetails) : undefined; this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); - await this.internalCache.set(key, newValue, callingMethod, requestIdPrefix, remainingTtl); + await this.internalCache.set(key, newValue, callingMethod, requestDetails, remainingTtl); return newValue; } @@ -422,38 +458,43 @@ export class CacheService { * @param {string} key - The key of the list. * @param {*} value - The value to push. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves with the new length of the list after pushing. */ - public async rPush(key: string, value: any, callingMethod: string, requestIdPrefix: string): Promise { + public async rPush(key: string, value: any, callingMethod: string, requestDetails: RequestDetails): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { this.cacheMethodsCounter .labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.RPUSH) .inc(1); - return await this.sharedCache.rPush(key, value, callingMethod, requestIdPrefix); + return await this.sharedCache.rPush(key, value, callingMethod, requestDetails); } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while pushing cache in Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while pushing cache in Redis.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } // Fallback to internal cache - const values = (await this.getFromInternalCache(key, callingMethod, requestIdPrefix)) ?? []; + const values = (await this.getFromInternalCache(key, callingMethod, requestDetails)) ?? []; if (!Array.isArray(values)) { throw new Error(`Value at key ${key} is not an array`); } values.push(value); const remainingTtl = this.internalCache instanceof LocalLRUCache - ? await this.internalCache.getRemainingTtl(key, callingMethod, requestIdPrefix) + ? await this.internalCache.getRemainingTtl(key, callingMethod, requestDetails) : undefined; this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1); - await this.internalCache.set(key, values, callingMethod, requestIdPrefix, remainingTtl); + await this.internalCache.set(key, values, callingMethod, requestDetails, remainingTtl); return values.length; } @@ -464,7 +505,7 @@ export class CacheService { * @param {number} start - The start index of the range. * @param {number} end - The end index of the range. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves with the values in the range. * @template T - The type of the values in the list. */ @@ -473,7 +514,7 @@ export class CacheService { start: number, end: number, callingMethod: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { @@ -481,17 +522,22 @@ export class CacheService { .labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.LRANGE) .inc(1); - return await this.sharedCache.lRange(key, start, end, callingMethod, requestIdPrefix); + return await this.sharedCache.lRange(key, start, end, callingMethod, requestDetails); } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while getting cache in Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while getting cache in Redis.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } // Fallback to internal cache - const values = (await this.getFromInternalCache(key, callingMethod, requestIdPrefix)) ?? []; + const values = (await this.getFromInternalCache(key, callingMethod, requestDetails)) ?? []; if (!Array.isArray(values)) { throw new Error(`Value at key ${key} is not an array`); } @@ -505,22 +551,27 @@ export class CacheService { * Retrieves all keys matching the given pattern. * @param {string} pattern - The pattern to match keys against. * @param {string} callingMethod - The name of the calling method. - * @param {string} [requestIdPrefix] - A prefix to include in log messages (optional). + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise that resolves with an array of keys that match the pattern. */ - async keys(pattern: string, callingMethod: string, requestIdPrefix: string): Promise { + async keys(pattern: string, callingMethod: string, requestDetails: RequestDetails): Promise { if (this.isSharedCacheEnabled && this.sharedCache instanceof RedisCache) { try { - return await this.sharedCache.keys(pattern, callingMethod, requestIdPrefix); + return await this.sharedCache.keys(pattern, callingMethod, requestDetails); } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( +<<<<<<< HEAD `${requestIdPrefix} Error occurred while getting keys from Redis. Fallback to internal cache. ${redisError}`, +======= + redisError, + `${requestDetails.formattedRequestId} Error occurred while getting keys from Redis.`, +>>>>>>> c7c5c919 (chore: draft changes) ); } } // Fallback to internal cache - return this.internalCache.keys(pattern, callingMethod, requestIdPrefix); + return this.internalCache.keys(pattern, callingMethod, requestDetails); } } diff --git a/packages/relay/src/lib/services/debugService/IDebugService.ts b/packages/relay/src/lib/services/debugService/IDebugService.ts index d93dfb81da..91c9183275 100644 --- a/packages/relay/src/lib/services/debugService/IDebugService.ts +++ b/packages/relay/src/lib/services/debugService/IDebugService.ts @@ -20,14 +20,14 @@ import { ITracerConfig } from '../../types'; import type { TracerType } from '../../constants'; -import { IRequestDetails } from '../../types/IRequestDetails'; +import { RequestDetails } from '../../types/RequestDetails'; export interface IDebugService { debug_traceTransaction: ( transactionIdOrHash: string, tracer: TracerType, tracerConfig: ITracerConfig, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ) => Promise; - resolveAddress: (address: string, requestIdPrefix: string, types?: string[]) => Promise; + resolveAddress: (address: string, requestDetails: RequestDetails, types?: string[]) => Promise; } diff --git a/packages/relay/src/lib/services/debugService/index.ts b/packages/relay/src/lib/services/debugService/index.ts index 360c3f31fd..ec674a7f36 100644 --- a/packages/relay/src/lib/services/debugService/index.ts +++ b/packages/relay/src/lib/services/debugService/index.ts @@ -29,7 +29,7 @@ import { EthImpl } from '../../eth'; import { IOpcodesResponse } from '../../clients/models/IOpcodesResponse'; import { IOpcode } from '../../clients/models/IOpcode'; import { ICallTracerConfig, IOpcodeLoggerConfig, ITracerConfig } from '../../types'; -import { IRequestDetails } from '../../types/IRequestDetails'; +import { RequestDetails } from '../../types/RequestDetails'; /** * Represents a DebugService for tracing and debugging transactions and debugging @@ -89,7 +89,7 @@ export class DebugService implements IDebugService { * @param {string} transactionIdOrHash - The ID or hash of the transaction to be traced. * @param {TracerType} tracer - The type of tracer to use (either 'CallTracer' or 'OpcodeLogger'). * @param {ITracerConfig} tracerConfig - The configuration object for the tracer. - * @param {string} [requestIdPrefix] - An optional request id. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @throws {Error} Throws an error if the specified tracer type is not supported or if an exception occurs during the trace. * @returns {Promise} A Promise that resolves to the result of the trace operation. * @@ -100,16 +100,15 @@ export class DebugService implements IDebugService { transactionIdOrHash: string, tracer: TracerType, tracerConfig: ITracerConfig, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; - this.logger.trace(`${requestIdPrefix} debug_traceTransaction(${transactionIdOrHash})`); + this.logger.trace(`${requestDetails.formattedRequestId} debug_traceTransaction(${transactionIdOrHash})`); try { DebugService.requireDebugAPIEnabled(); if (tracer === TracerType.CallTracer) { - return await this.callTracer(transactionIdOrHash, tracerConfig as ICallTracerConfig, requestIdPrefix); + return await this.callTracer(transactionIdOrHash, tracerConfig as ICallTracerConfig, requestDetails); } else if (tracer === TracerType.OpcodeLogger) { - return await this.callOpcodeLogger(transactionIdOrHash, tracerConfig as IOpcodeLoggerConfig, requestIdPrefix); + return await this.callOpcodeLogger(transactionIdOrHash, tracerConfig as IOpcodeLoggerConfig, requestDetails); } } catch (e) { throw this.common.genericErrorHandler(e); @@ -121,23 +120,23 @@ export class DebugService implements IDebugService { * * @async * @param {any} result - The response from the actions endpoint. - * @param {string} requestIdPrefix - The request prefix id. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise<[] | any>} The formatted actions response in an array. */ - async formatActionsResult(result: any, requestIdPrefix: string): Promise<[] | any> { + async formatActionsResult(result: any, requestDetails: RequestDetails): Promise<[] | any> { return await Promise.all( result.map(async (action, index) => { const { resolvedFrom, resolvedTo } = await this.resolveMultipleAddresses( action.from, action.to, - requestIdPrefix, + requestDetails, ); // The actions endpoint does not return input and output for the calls so we get them from another endpoint // The first one is excluded because we take its input and output from the contracts/results/{transactionIdOrHash} endpoint const contract = index !== 0 && action.call_operation_type === CallType.CREATE - ? await this.mirrorNodeClient.getContract(action.to, requestIdPrefix) + ? await this.mirrorNodeClient.getContract(action.to, requestDetails) : undefined; return { @@ -203,13 +202,13 @@ export class DebugService implements IDebugService { * @async * @param {string} address - The address to be resolved. * @param {[string]} types - The possible types of the address. - * @param {string} requestIdPrefix - The request prefix id. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The address returned as an EVM address. */ async resolveAddress( address: string, - requestIdPrefix: string, - types = [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT], + requestDetails: RequestDetails, + types: string[] = [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT], ): Promise { // if the address is null or undefined we return it as is if (!address) return address; @@ -218,7 +217,7 @@ export class DebugService implements IDebugService { address, types, EthImpl.debugTraceTransaction, - requestIdPrefix, + requestDetails, ); if ( @@ -235,15 +234,15 @@ export class DebugService implements IDebugService { async resolveMultipleAddresses( from: string, to: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise<{ resolvedFrom: string; resolvedTo: string }> { const [resolvedFrom, resolvedTo] = await Promise.all([ - this.resolveAddress(from, requestIdPrefix, [ + this.resolveAddress(from, requestDetails, [ constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT, ]), - this.resolveAddress(to, requestIdPrefix, [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT]), + this.resolveAddress(to, requestDetails, [constants.TYPE_CONTRACT, constants.TYPE_TOKEN, constants.TYPE_ACCOUNT]), ]); return { resolvedFrom, resolvedTo }; @@ -257,13 +256,13 @@ export class DebugService implements IDebugService { * @param {boolean} tracerConfig.enableMemory - Whether to enable memory. * @param {boolean} tracerConfig.disableStack - Whether to disable stack. * @param {boolean} tracerConfig.disableStorage - Whether to disable storage. - * @param {string} requestIdPrefix - The request prefix id. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The formatted response. */ async callOpcodeLogger( transactionIdOrHash: string, tracerConfig: IOpcodeLoggerConfig, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { try { const options = { @@ -273,7 +272,7 @@ export class DebugService implements IDebugService { }; const response = await this.mirrorNodeClient.getContractsResultsOpcodes( transactionIdOrHash, - requestIdPrefix, + requestDetails, options, ); return await this.formatOpcodesResult(response, options); @@ -288,21 +287,25 @@ export class DebugService implements IDebugService { * @async * @param {string} transactionHash - The hash of the transaction to be debugged. * @param {ICallTracerConfig} tracerConfig - The tracer config to be used. - * @param {string} requestIdPrefix - The request prefix id. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} The formatted response. */ - async callTracer(transactionHash: string, tracerConfig: ICallTracerConfig, requestIdPrefix: string): Promise { + async callTracer( + transactionHash: string, + tracerConfig: ICallTracerConfig, + requestDetails: RequestDetails, + ): Promise { try { const [actionsResponse, transactionsResponse] = await Promise.all([ - this.mirrorNodeClient.getContractsResultsActions(transactionHash, requestIdPrefix), - this.mirrorNodeClient.getContractResultWithRetry(transactionHash, requestIdPrefix), + this.mirrorNodeClient.getContractsResultsActions(transactionHash, requestDetails), + this.mirrorNodeClient.getContractResultWithRetry(transactionHash, requestDetails), ]); if (!actionsResponse || !transactionsResponse) { throw predefined.RESOURCE_NOT_FOUND(`Failed to retrieve contract results for transaction ${transactionHash}`); } const { call_type: type } = actionsResponse.actions[0]; - const formattedActions = await this.formatActionsResult(actionsResponse.actions, requestIdPrefix); + const formattedActions = await this.formatActionsResult(actionsResponse.actions, requestDetails); const { from, @@ -316,7 +319,7 @@ export class DebugService implements IDebugService { result, } = transactionsResponse; - const { resolvedFrom, resolvedTo } = await this.resolveMultipleAddresses(from, to, requestIdPrefix); + const { resolvedFrom, resolvedTo } = await this.resolveMultipleAddresses(from, to, requestDetails); const value = amount === 0 ? EthImpl.zeroHex : numberTo0x(amount); const errorResult = result !== constants.SUCCESS ? result : undefined; diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts b/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts index 441a3b6d7a..bd89197f1c 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts @@ -18,6 +18,7 @@ * */ import { Log } from '../../../model'; +import { RequestDetails } from '../../../types/RequestDetails'; export interface ICommonService { blockTagIsLatestOrPending(tag: any): boolean; @@ -26,27 +27,31 @@ export interface ICommonService { params: any, fromBlock: string, toBlock: string, - requestIdPrefix?: string, + requestDetails: RequestDetails, address?: string | string[] | null, ): Promise; getHistoricalBlockResponse( - requestIdPrefix: string, + requestDetails: RequestDetails, blockNumberOrTag?: string | null, returnLatest?: boolean, ): Promise; - getLatestBlockNumber(requestIdPrefix?: string): Promise; + getLatestBlockNumber(requestDetails: RequestDetails): Promise; genericErrorHandler(error: any, logMessage?: string): void; - validateBlockHashAndAddTimestampToParams(params: any, blockHash: string, requestIdPrefix?: string): Promise; + validateBlockHashAndAddTimestampToParams( + params: any, + blockHash: string, + requestDetails: RequestDetails, + ): Promise; addTopicsToParams(params: any, topics: any[] | null): void; - getLogsByAddress(address: string | [string], params: any, requestIdPrefix): Promise; + getLogsByAddress(address: string | [string], params: any, requestDetails: RequestDetails): Promise; - getLogsWithParams(address: string | [string] | null, param, requestIdPrefix: string): Promise; + getLogsWithParams(address: string | [string] | null, params: any, requestDetails: RequestDetails): Promise; getLogs( blockHash: string | null, @@ -54,6 +59,6 @@ export interface ICommonService { toBlock: string | 'latest', address: string | [string] | null, topics: any[] | null, - requestIdPrefix?: string, + requestDetails: RequestDetails, ): Promise; } diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts index c0856fcc42..12bf0c0903 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts @@ -29,6 +29,7 @@ import { MirrorNodeClientError } from '../../../errors/MirrorNodeClientError'; import { Log } from '../../../model'; import * as _ from 'lodash'; import { CacheService } from '../../cacheService/cacheService'; +import { RequestDetails } from '../../../types/RequestDetails'; /** * Create a new Common Service implementation. @@ -102,14 +103,14 @@ export class CommonService implements ICommonService { params: any, fromBlock: string, toBlock: string, - requestIdPrefix: string, + requestDetails: RequestDetails, address?: string | string[] | null, ) { if (this.blockTagIsLatestOrPending(toBlock)) { toBlock = CommonService.blockLatest; } - const latestBlockNumber: string = await this.getLatestBlockNumber(requestIdPrefix); + const latestBlockNumber: string = await this.getLatestBlockNumber(requestDetails); // toBlock is a number and is less than the current block number and fromBlock is not defined if (Number(toBlock) < Number(latestBlockNumber) && !fromBlock) { @@ -124,7 +125,7 @@ export class CommonService implements ICommonService { let toBlockNum; params.timestamp = []; - const fromBlockResponse = await this.getHistoricalBlockResponse(requestIdPrefix, fromBlock, true); + const fromBlockResponse = await this.getHistoricalBlockResponse(requestDetails, fromBlock, true); if (!fromBlockResponse) { return false; } @@ -135,7 +136,7 @@ export class CommonService implements ICommonService { params.timestamp.push(`lte:${fromBlockResponse.timestamp.to}`); } else { fromBlockNum = parseInt(fromBlockResponse.number); - const toBlockResponse = await this.getHistoricalBlockResponse(requestIdPrefix, toBlock, true); + const toBlockResponse = await this.getHistoricalBlockResponse(requestDetails, toBlock, true); if (toBlockResponse != null) { params.timestamp.push(`lte:${toBlockResponse.timestamp.to}`); toBlockNum = parseInt(toBlockResponse.number); @@ -163,11 +164,12 @@ export class CommonService implements ICommonService { * returns the block response * otherwise return undefined. * - * @param blockNumberOrTag + * @param requestDetails + * @param blockNumberOrTagOrHash * @param returnLatest */ public async getHistoricalBlockResponse( - requestIdPrefix: string, + requestDetails: RequestDetails, blockNumberOrTagOrHash?: string | null, returnLatest?: boolean, ): Promise { @@ -177,7 +179,7 @@ export class CommonService implements ICommonService { const blockNumber = Number(blockNumberOrTagOrHash); if (blockNumberOrTagOrHash != null && blockNumberOrTagOrHash.length < 32 && !isNaN(blockNumber)) { - const latestBlockResponse = await this.mirrorNodeClient.getLatestBlock(requestIdPrefix); + const latestBlockResponse = await this.mirrorNodeClient.getLatestBlock(requestDetails); const latestBlock = latestBlockResponse.blocks[0]; if (blockNumber > latestBlock.number + this.maxBlockRange) { return null; @@ -185,39 +187,41 @@ export class CommonService implements ICommonService { } if (blockNumberOrTagOrHash == null || this.blockTagIsLatestOrPending(blockNumberOrTagOrHash)) { - const latestBlockResponse = await this.mirrorNodeClient.getLatestBlock(requestIdPrefix); + const latestBlockResponse = await this.mirrorNodeClient.getLatestBlock(requestDetails); return latestBlockResponse.blocks[0]; } if (blockNumberOrTagOrHash == CommonService.blockEarliest) { - return await this.mirrorNodeClient.getBlock(0, requestIdPrefix); + return await this.mirrorNodeClient.getBlock(0, requestDetails); } if (blockNumberOrTagOrHash.length < 32) { - return await this.mirrorNodeClient.getBlock(Number(blockNumberOrTagOrHash), requestIdPrefix); + return await this.mirrorNodeClient.getBlock(Number(blockNumberOrTagOrHash), requestDetails); } - return await this.mirrorNodeClient.getBlock(blockNumberOrTagOrHash, requestIdPrefix); + return await this.mirrorNodeClient.getBlock(blockNumberOrTagOrHash, requestDetails); } /** * Gets the most recent block number. */ - public async getLatestBlockNumber(requestIdPrefix: string): Promise { + public async getLatestBlockNumber(requestDetails: RequestDetails): Promise { // check for cached value const cacheKey = `${constants.CACHE_KEY.ETH_BLOCK_NUMBER}`; const blockNumberCached = await this.cacheService.getAsync( cacheKey, CommonService.latestBlockNumber, - requestIdPrefix, + requestDetails, ); if (blockNumberCached) { - this.logger.trace(`${requestIdPrefix} returning cached value ${cacheKey}:${JSON.stringify(blockNumberCached)}`); + this.logger.trace( + `${requestDetails.formattedRequestId} returning cached value ${cacheKey}:${JSON.stringify(blockNumberCached)}`, + ); return blockNumberCached; } - const blocksResponse = await this.mirrorNodeClient.getLatestBlock(requestIdPrefix); + const blocksResponse = await this.mirrorNodeClient.getLatestBlock(requestDetails); const blocks = blocksResponse !== null ? blocksResponse.blocks : null; if (Array.isArray(blocks) && blocks.length > 0) { const currentBlock = numberTo0x(blocks[0].number); @@ -226,7 +230,7 @@ export class CommonService implements ICommonService { cacheKey, currentBlock, CommonService.latestBlockNumber, - requestIdPrefix, + requestDetails, this.ethBlockNumberCacheTtlMs, ); @@ -253,9 +257,13 @@ export class CommonService implements ICommonService { throw predefined.INTERNAL_ERROR(error.message.toString()); } - public async validateBlockHashAndAddTimestampToParams(params: any, blockHash: string, requestIdPrefix: string) { + public async validateBlockHashAndAddTimestampToParams( + params: any, + blockHash: string, + requestDetails: RequestDetails, + ) { try { - const block = await this.mirrorNodeClient.getBlock(blockHash, requestIdPrefix); + const block = await this.mirrorNodeClient.getBlock(blockHash, requestDetails); if (block) { params.timestamp = [`gte:${block.timestamp.from}`, `lte:${block.timestamp.to}`]; } else { @@ -282,10 +290,10 @@ export class CommonService implements ICommonService { } } - public async getLogsByAddress(address: string | string[], params: any, requestIdPrefix) { + public async getLogsByAddress(address: string | string[], params: any, requestDetails: RequestDetails) { const addresses = Array.isArray(address) ? address : [address]; const logPromises = addresses.map((addr) => - this.mirrorNodeClient.getContractResultsLogsByAddress(addr, requestIdPrefix, params, undefined), + this.mirrorNodeClient.getContractResultsLogsByAddress(addr, requestDetails, params, undefined), ); const logResults = await Promise.all(logPromises); @@ -297,14 +305,18 @@ export class CommonService implements ICommonService { return logs; } - public async getLogsWithParams(address: string | string[] | null, params, requestIdPrefix: string): Promise { + public async getLogsWithParams( + address: string | string[] | null, + params: any, + requestDetails: RequestDetails, + ): Promise { const EMPTY_RESPONSE = []; let logResults; if (address) { - logResults = await this.getLogsByAddress(address, params, requestIdPrefix); + logResults = await this.getLogsByAddress(address, params, requestDetails); } else { - logResults = await this.mirrorNodeClient.getContractResultsLogs(requestIdPrefix, params, undefined); + logResults = await this.mirrorNodeClient.getContractResultsLogs(requestDetails, params); } if (!logResults) { @@ -337,23 +349,23 @@ export class CommonService implements ICommonService { toBlock: string | 'latest', address: string | string[] | null, topics: any[] | null, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { const EMPTY_RESPONSE = []; const params: any = {}; if (blockHash) { - if (!(await this.validateBlockHashAndAddTimestampToParams(params, blockHash, requestIdPrefix))) { + if (!(await this.validateBlockHashAndAddTimestampToParams(params, blockHash, requestDetails))) { return EMPTY_RESPONSE; } } else if ( - !(await this.validateBlockRangeAndAddTimestampToParams(params, fromBlock, toBlock, requestIdPrefix, address)) + !(await this.validateBlockRangeAndAddTimestampToParams(params, fromBlock, toBlock, requestDetails, address)) ) { return EMPTY_RESPONSE; } this.addTopicsToParams(params, topics); - return this.getLogsWithParams(address, params, requestIdPrefix); + return this.getLogsWithParams(address, params, requestDetails); } } diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts index db3d69b7cd..e13a7acabc 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts @@ -20,7 +20,7 @@ import { JsonRpcError } from '../../../errors/JsonRpcError'; import { Log } from '../../../model'; -import { IRequestDetails } from '../../../types/IRequestDetails'; +import { IRequestDetails } from '../../../types/RequestDetails'; export interface IFilterService { newFilter( diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts index 1db8b9387e..1fd2527125 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts @@ -22,12 +22,12 @@ import { Logger } from 'pino'; import { MirrorNodeClient } from '../../../clients'; import constants from '../../../constants'; import { IFilterService } from './IFilterService'; -import { CommonService } from './../ethCommonService'; +import { CommonService } from '../ethCommonService'; import { generateRandomHex } from '../../../../formatters'; import { JsonRpcError, predefined } from '../../../errors/JsonRpcError'; import { Log } from '../../../model'; import { CacheService } from '../../cacheService/cacheService'; -import { IRequestDetails } from '../../../types/IRequestDetails'; +import { RequestDetails } from '../../../types/RequestDetails'; /** * Create a new Filter Service implementation. @@ -62,7 +62,7 @@ export class FilterService implements IFilterService { public readonly ethGetFilterChanges = 'eth_getFilterChanges'; private readonly common: CommonService; - private readonly supportedTypes; + private readonly supportedTypes: string[]; constructor(mirrorNodeClient: MirrorNodeClient, logger: Logger, cacheService: CacheService, common: CommonService) { this.mirrorNodeClient = mirrorNodeClient; @@ -77,9 +77,9 @@ export class FilterService implements IFilterService { * Creates a new filter with the specified type and parameters * @param type * @param params - * @param requestIdPrefix + * @param requestDetails */ - async createFilter(type: string, params: any, requestIdPrefix: string): Promise { + async createFilter(type: string, params: any, requestDetails: RequestDetails): Promise { const filterId = generateRandomHex(); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; await this.cacheService.set( @@ -90,10 +90,10 @@ export class FilterService implements IFilterService { lastQueried: null, }, this.ethNewFilter, - requestIdPrefix, + requestDetails, constants.FILTER.TTL, ); - this.logger.trace(`${requestIdPrefix} created filter with TYPE=${type}, params: ${params}`); + this.logger.trace(`${requestDetails.formattedRequestId} created filter with TYPE=${type}, params: ${params}`); return filterId; } @@ -112,16 +112,16 @@ export class FilterService implements IFilterService { * @param toBlock * @param address * @param topics - * @param requestIdPrefix + * @param requestDetails */ async newFilter( fromBlock: string = 'latest', toBlock: string = 'latest', - requestDetails: IRequestDetails, + requestDetails: RequestDetails, address?: string, topics?: any[], ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace( `${requestIdPrefix} newFilter(fromBlock=${fromBlock}, toBlock=${toBlock}, address=${address}, topics=${topics})`, ); @@ -129,7 +129,7 @@ export class FilterService implements IFilterService { FilterService.requireFiltersEnabled(); if ( - !(await this.common.validateBlockRangeAndAddTimestampToParams({}, fromBlock, toBlock, requestIdPrefix, address)) + !(await this.common.validateBlockRangeAndAddTimestampToParams({}, fromBlock, toBlock, requestDetails, address)) ) { throw predefined.INVALID_BLOCK_RANGE; } @@ -137,63 +137,62 @@ export class FilterService implements IFilterService { return await this.createFilter( constants.FILTER.TYPE.LOG, { - fromBlock: fromBlock === 'latest' ? await this.common.getLatestBlockNumber(requestIdPrefix) : fromBlock, + fromBlock: fromBlock === 'latest' ? await this.common.getLatestBlockNumber(requestDetails) : fromBlock, toBlock, address, topics, }, - requestIdPrefix, + requestDetails, ); } catch (e) { throw this.common.genericErrorHandler(e); } } - async newBlockFilter(requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + async newBlockFilter(requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} newBlockFilter()`); try { FilterService.requireFiltersEnabled(); return await this.createFilter( constants.FILTER.TYPE.NEW_BLOCK, { - blockAtCreation: await this.common.getLatestBlockNumber(requestIdPrefix), + blockAtCreation: await this.common.getLatestBlockNumber(requestDetails), }, - requestIdPrefix, + requestDetails, ); } catch (e) { throw this.common.genericErrorHandler(e); } } - public async uninstallFilter(filterId: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; + public async uninstallFilter(filterId: string, requestDetails: RequestDetails): Promise { + const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} uninstallFilter(${filterId})`); FilterService.requireFiltersEnabled(); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; - const filter = await this.cacheService.getAsync(cacheKey, this.ethUninstallFilter, requestIdPrefix); + const filter = await this.cacheService.getAsync(cacheKey, this.ethUninstallFilter, requestDetails); if (filter) { - await this.cacheService.delete(cacheKey, this.ethUninstallFilter, requestIdPrefix); + await this.cacheService.delete(cacheKey, this.ethUninstallFilter, requestDetails); return true; } return false; } - public newPendingTransactionFilter(requestDetails: IRequestDetails): JsonRpcError { - this.logger.trace(`${requestDetails.requestIdPrefix} newPendingTransactionFilter()`); + public newPendingTransactionFilter(requestDetails: RequestDetails): JsonRpcError { + this.logger.trace(`${requestDetails.formattedRequestId} newPendingTransactionFilter()`); return predefined.UNSUPPORTED_METHOD; } - public async getFilterLogs(filterId: string, requestDetails: IRequestDetails): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; - this.logger.trace(`${requestIdPrefix} getFilterLogs(${filterId})`); + public async getFilterLogs(filterId: string, requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} getFilterLogs(${filterId})`); FilterService.requireFiltersEnabled(); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; - const filter = await this.cacheService.getAsync(cacheKey, this.ethGetFilterLogs, requestIdPrefix); + const filter = await this.cacheService.getAsync(cacheKey, this.ethGetFilterLogs, requestDetails); if (filter?.type != constants.FILTER.TYPE.LOG) { throw predefined.FILTER_NOT_FOUND; } @@ -204,20 +203,16 @@ export class FilterService implements IFilterService { filter?.params.toBlock, filter?.params.address, filter?.params.topics, - requestIdPrefix, + requestDetails, ); } - public async getFilterChanges( - filterId: string, - requestDetails: IRequestDetails, - ): Promise { - const requestIdPrefix = requestDetails.requestIdPrefix; - this.logger.trace(`${requestIdPrefix} getFilterChanges(${filterId})`); + public async getFilterChanges(filterId: string, requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} getFilterChanges(${filterId})`); FilterService.requireFiltersEnabled(); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; - const filter = await this.cacheService.getAsync(cacheKey, this.ethGetFilterChanges, requestIdPrefix); + const filter = await this.cacheService.getAsync(cacheKey, this.ethGetFilterChanges, requestDetails); if (!filter) { throw predefined.FILTER_NOT_FOUND; @@ -231,7 +226,7 @@ export class FilterService implements IFilterService { filter?.params.toBlock, filter?.params.address, filter?.params.topics, - requestIdPrefix, + requestDetails, ); // get the latest block number and add 1 to exclude current results from the next response because @@ -240,11 +235,11 @@ export class FilterService implements IFilterService { Number( result.length ? result[result.length - 1].blockNumber - : await this.common.getLatestBlockNumber(requestIdPrefix), + : await this.common.getLatestBlockNumber(requestDetails), ) + 1; } else if (filter.type === constants.FILTER.TYPE.NEW_BLOCK) { result = await this.mirrorNodeClient.getBlocks( - requestIdPrefix, + requestDetails, [`gt:${filter.lastQueried || filter.params.blockAtCreation}`], undefined, { @@ -255,7 +250,7 @@ export class FilterService implements IFilterService { latestBlockNumber = Number( result?.blocks?.length ? result.blocks[result.blocks.length - 1].number - : await this.common.getLatestBlockNumber(requestIdPrefix), + : await this.common.getLatestBlockNumber(requestDetails), ); result = result?.blocks?.map((r) => r.hash) || []; @@ -272,7 +267,7 @@ export class FilterService implements IFilterService { lastQueried: latestBlockNumber, }, this.ethGetFilterChanges, - requestIdPrefix, + requestDetails, constants.FILTER.TTL, ); diff --git a/packages/relay/src/lib/services/metricService/metricService.ts b/packages/relay/src/lib/services/metricService/metricService.ts index cdd8764547..def76e4448 100644 --- a/packages/relay/src/lib/services/metricService/metricService.ts +++ b/packages/relay/src/lib/services/metricService/metricService.ts @@ -26,6 +26,7 @@ import { Histogram, Registry } from 'prom-client'; import { MirrorNodeClient, SDKClient } from '../../clients'; import { formatRequestIdMessage } from '../../../formatters'; import { ITransactionRecordMetric, IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../../types'; +import { RequestDetails } from '../../types/RequestDetails'; export default class MetricService { /** @@ -162,7 +163,7 @@ export default class MetricService { gasUsed, interactingEntity, status, - requestId, + requestDetails: requestId, } as IExecuteQueryEventPayload); } @@ -176,7 +177,7 @@ export default class MetricService { gasUsed: 0, interactingEntity, status, - requestId, + requestDetails: requestId, } as IExecuteQueryEventPayload); } } @@ -206,14 +207,14 @@ export default class MetricService { gasUsed, interactingEntity, status, - requestId, + requestDetails, }: IExecuteQueryEventPayload): void => { - const formattedRequestId = formatRequestIdMessage(requestId); + const formattedRequestId = formatRequestIdMessage(requestDetails); this.logger.trace( `${formattedRequestId} Capturing HBAR charged: executionMode=${executionMode} transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, cost=${cost} tinybars`, ); - this.hbarLimiter.addExpense(cost, Date.now(), requestId); + this.hbarLimiter.addExpense(cost, Date.now(), requestDetails); this.captureMetrics(executionMode, txConstructorName, status, cost, gasUsed, callerName, interactingEntity); }; @@ -299,19 +300,18 @@ export default class MetricService { * * @param {string} transactionId - The ID of the transaction for which metrics are being retrieved. * @param {string} callerName - The name of the caller requesting the metrics. - * @param {string} requestId - The request ID for tracing the request flow. * @param {string} txConstructorName - The name of the transaction constructor. * @param {string} operatorAccountId - The account ID of the operator. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - The transaction record metrics or undefined if retrieval fails. */ private async getTransactionRecordMetrics( transactionId: string, callerName: string, - requestId: string, txConstructorName: string, operatorAccountId: string, + requestDetails: RequestDetails, ): Promise { - const formattedRequestId = formatRequestIdMessage(requestId); const defaultToConsensusNode = process.env.GET_RECORD_DEFAULT_TO_CONSENSUS_NODE === 'true'; // retrieve transaction metrics @@ -320,21 +320,24 @@ export default class MetricService { return await this.sdkClient.getTransactionRecordMetrics( transactionId, callerName, - requestId, txConstructorName, operatorAccountId, + requestDetails, ); } else { return await this.mirrorNodeClient.getTransactionRecordMetrics( transactionId, callerName, - requestId, txConstructorName, operatorAccountId, + requestDetails, ); } } catch (error: any) { - this.logger.warn(error, `${formattedRequestId} Could not fetch transaction record: error=${error.message}`); + this.logger.warn( + error, + `${requestDetails.formattedRequestId} Could not fetch transaction record: error=${error.message}`, + ); } } } diff --git a/packages/relay/src/lib/types/IRequestDetails.ts b/packages/relay/src/lib/types/IRequestDetails.ts deleted file mode 100644 index c4f6a9990a..0000000000 --- a/packages/relay/src/lib/types/IRequestDetails.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type IRequestDetails = { - requestIdPrefix: string; - requestIp: string; -}; diff --git a/packages/relay/src/lib/types/RequestDetails.ts b/packages/relay/src/lib/types/RequestDetails.ts new file mode 100644 index 0000000000..7058a3adcc --- /dev/null +++ b/packages/relay/src/lib/types/RequestDetails.ts @@ -0,0 +1,35 @@ +/* + * + * Hedera JSON RPC Relay + * + * Copyright (C) 2022-2024 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 { formatRequestIdMessage } from '../../formatters'; + +export class RequestDetails { + requestId: string; + ipAddress: string; + + constructor(details: { requestId: string; ipAddress: string }) { + this.requestId = details.requestId; + this.ipAddress = details.ipAddress; + } + + get formattedRequestId(): string { + return formatRequestIdMessage(this.requestId); + } +} diff --git a/packages/relay/src/lib/types/events.ts b/packages/relay/src/lib/types/events.ts index 96987ea912..cdf110552b 100644 --- a/packages/relay/src/lib/types/events.ts +++ b/packages/relay/src/lib/types/events.ts @@ -18,13 +18,15 @@ * */ +import { RequestDetails } from './RequestDetails'; + export interface IExecuteTransactionEventPayload { transactionId: string; callerName: string; - requestId: string; txConstructorName: string; operatorAccountId: string; interactingEntity: string; + requestDetails: RequestDetails; } export interface IExecuteQueryEventPayload { @@ -36,5 +38,5 @@ export interface IExecuteQueryEventPayload { gasUsed: number; interactingEntity: string; status: string; - requestId: string; + requestDetails: RequestDetails; } diff --git a/packages/relay/tests/lib/clients/redisCache.spec.ts b/packages/relay/tests/lib/clients/redisCache.spec.ts index 2509997106..2d289dafbc 100644 --- a/packages/relay/tests/lib/clients/redisCache.spec.ts +++ b/packages/relay/tests/lib/clients/redisCache.spec.ts @@ -24,6 +24,7 @@ import chaiAsPromised from 'chai-as-promised'; import { RedisCache } from '../../../src/lib/clients'; import { Registry } from 'prom-client'; import { useInMemoryRedisServer } from '../../helpers'; +import { RequestDetails } from '../../../dist/lib/types'; chai.use(chaiAsPromised); @@ -33,13 +34,19 @@ describe('RedisCache Test Suite', async function () { const logger = pino(); const registry = new Registry(); const callingMethod = 'RedisCacheTest'; - const requestIdPrefix = 'redisCacheTest'; + const requestDetails = new RequestDetails({ requestId: 'localLRUCacheTest', ipAddress: '0.0.0.0' }); + let redisCache: RedisCache; useInMemoryRedisServer(logger, 6379); this.beforeAll(async () => { +<<<<<<< HEAD +======= + redisInMemoryServer = new RedisInMemoryServer(logger.child({ name: `in-memory redis server` }), 6379); + await redisInMemoryServer.start(); +>>>>>>> c7c5c919 (chore: draft changes) redisCache = new RedisCache(logger.child({ name: `cache` }), registry); }); @@ -58,7 +65,7 @@ describe('RedisCache Test Suite', async function () { describe('Get and Set Test Suite', async function () { it('should get null on empty cache', async function () { - const cacheValue = await redisCache.get('test', callingMethod, requestIdPrefix); + const cacheValue = await redisCache.get('test', callingMethod, requestDetails); expect(cacheValue).to.be.null; }); @@ -66,9 +73,9 @@ describe('RedisCache Test Suite', async function () { const key = 'int'; const value = 1; - await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).equal(value); }); @@ -76,9 +83,9 @@ describe('RedisCache Test Suite', async function () { const key = 'boolean'; const value = false; - await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).equal(value); }); @@ -86,9 +93,9 @@ describe('RedisCache Test Suite', async function () { const key = 'array'; const value = ['false']; - await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).deep.equal(value); }); @@ -96,9 +103,9 @@ describe('RedisCache Test Suite', async function () { const key = 'object'; const value = { result: true }; - await redisCache.set(key, value, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).deep.equal(value); }); @@ -107,14 +114,14 @@ describe('RedisCache Test Suite', async function () { const value = 1; const ttl = 500; - await redisCache.set(key, value, callingMethod, requestIdPrefix, ttl); + await redisCache.set(key, value, callingMethod, requestDetails, ttl); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).equal(value); await new Promise((resolve) => setTimeout(resolve, ttl + 100)); - const expiredValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const expiredValue = await redisCache.get(key, callingMethod, requestDetails); expect(expiredValue).to.be.null; }); @@ -123,14 +130,14 @@ describe('RedisCache Test Suite', async function () { const value = 1; const ttl = 1500; - await redisCache.set(key, value, callingMethod, requestIdPrefix, ttl); + await redisCache.set(key, value, callingMethod, requestDetails, ttl); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).equal(value); await new Promise((resolve) => setTimeout(resolve, ttl + 100)); - const expiredValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const expiredValue = await redisCache.get(key, callingMethod, requestDetails); expect(expiredValue).to.be.null; }); }); @@ -145,10 +152,10 @@ describe('RedisCache Test Suite', async function () { object: { result: true }, }; - await redisCache.multiSet(keyValuePairs, callingMethod, requestIdPrefix); + await redisCache.multiSet(keyValuePairs, callingMethod, requestDetails); for (const key in keyValuePairs) { - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).deep.equal(keyValuePairs[key]); } }); @@ -164,10 +171,10 @@ describe('RedisCache Test Suite', async function () { object: { result: true }, }; - await redisCache.pipelineSet(keyValuePairs, callingMethod, requestIdPrefix); + await redisCache.pipelineSet(keyValuePairs, callingMethod, requestDetails); for (const key in keyValuePairs) { - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).deep.equal(keyValuePairs[key]); } }); @@ -181,17 +188,17 @@ describe('RedisCache Test Suite', async function () { object: { result: true }, }; - await redisCache.pipelineSet(keyValuePairs, callingMethod, requestIdPrefix, 500); + await redisCache.pipelineSet(keyValuePairs, callingMethod, requestDetails, 500); for (const key in keyValuePairs) { - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).deep.equal(keyValuePairs[key]); } await new Promise((resolve) => setTimeout(resolve, 500)); for (const key in keyValuePairs) { - const expiredValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const expiredValue = await redisCache.get(key, callingMethod, requestDetails); expect(expiredValue).to.be.null; } }); @@ -202,10 +209,10 @@ describe('RedisCache Test Suite', async function () { const key = 'int'; const value = 1; - await redisCache.set(key, value, callingMethod, requestIdPrefix); - await redisCache.delete(key, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); + await redisCache.delete(key, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).to.be.null; }); @@ -213,10 +220,10 @@ describe('RedisCache Test Suite', async function () { const key = 'boolean'; const value = false; - await redisCache.set(key, value, callingMethod, requestIdPrefix); - await redisCache.delete(key, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); + await redisCache.delete(key, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).to.be.null; }); @@ -224,10 +231,10 @@ describe('RedisCache Test Suite', async function () { const key = 'array'; const value = ['false']; - await redisCache.set(key, value, callingMethod, requestIdPrefix); - await redisCache.delete(key, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); + await redisCache.delete(key, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).to.be.null; }); @@ -235,10 +242,10 @@ describe('RedisCache Test Suite', async function () { const key = 'object'; const value = { result: true }; - await redisCache.set(key, value, callingMethod, requestIdPrefix); - await redisCache.delete(key, callingMethod, requestIdPrefix); + await redisCache.set(key, value, callingMethod, requestDetails); + await redisCache.delete(key, callingMethod, requestDetails); - const cachedValue = await redisCache.get(key, callingMethod, requestIdPrefix); + const cachedValue = await redisCache.get(key, callingMethod, requestDetails); expect(cachedValue).to.be.null; }); }); @@ -248,7 +255,7 @@ describe('RedisCache Test Suite', async function () { const key = 'non-existing'; const amount = 1; - const newValue = await redisCache.incrBy(key, amount, callingMethod, requestIdPrefix); + const newValue = await redisCache.incrBy(key, amount, callingMethod, requestDetails); expect(newValue).equal(amount); }); @@ -257,8 +264,8 @@ describe('RedisCache Test Suite', async function () { const initialValue = 5; const amount = 3; - await redisCache.set(key, initialValue, callingMethod, requestIdPrefix); - const newValue = await redisCache.incrBy(key, amount, callingMethod, requestIdPrefix); + await redisCache.set(key, initialValue, callingMethod, requestDetails); + const newValue = await redisCache.incrBy(key, amount, callingMethod, requestDetails); expect(newValue).equal(initialValue + amount); }); @@ -267,8 +274,8 @@ describe('RedisCache Test Suite', async function () { const initialValue = 5; const amount = -2; - await redisCache.set(key, initialValue, callingMethod, requestIdPrefix); - const newValue = await redisCache.incrBy(key, amount, callingMethod, requestIdPrefix); + await redisCache.set(key, initialValue, callingMethod, requestDetails); + const newValue = await redisCache.incrBy(key, amount, callingMethod, requestDetails); expect(newValue).equal(initialValue + amount); }); }); @@ -278,10 +285,10 @@ describe('RedisCache Test Suite', async function () { const key = 'non-existing-list'; const value = 'item1'; - const length = await redisCache.rPush(key, value, callingMethod, requestIdPrefix); + const length = await redisCache.rPush(key, value, callingMethod, requestDetails); expect(length).equal(1); - const list = await redisCache.lRange(key, 0, -1, callingMethod, requestIdPrefix); + const list = await redisCache.lRange(key, 0, -1, callingMethod, requestDetails); expect(list).deep.equal([value]); }); @@ -290,11 +297,11 @@ describe('RedisCache Test Suite', async function () { const initialList = ['item1']; const newValue = 'item2'; - await redisCache.rPush(key, initialList[0], callingMethod, requestIdPrefix); - const length = await redisCache.rPush(key, newValue, callingMethod, requestIdPrefix); + await redisCache.rPush(key, initialList[0], callingMethod, requestDetails); + const length = await redisCache.rPush(key, newValue, callingMethod, requestDetails); expect(length).equal(2); - const list = await redisCache.lRange(key, 0, -1, callingMethod, requestIdPrefix); + const list = await redisCache.lRange(key, 0, -1, callingMethod, requestDetails); expect(list).deep.equal([...initialList, newValue]); }); }); @@ -305,7 +312,7 @@ describe('RedisCache Test Suite', async function () { const start = 0; const end = 1; - const list = await redisCache.lRange(key, start, end, callingMethod, requestIdPrefix); + const list = await redisCache.lRange(key, start, end, callingMethod, requestDetails); expect(list).deep.equal([]); }); @@ -314,10 +321,10 @@ describe('RedisCache Test Suite', async function () { const list = ['item1', 'item2', 'item3']; for (const item of list) { - await redisCache.rPush(key, item, callingMethod, requestIdPrefix); + await redisCache.rPush(key, item, callingMethod, requestDetails); } - const range = await redisCache.lRange(key, 0, 1, callingMethod, requestIdPrefix); + const range = await redisCache.lRange(key, 0, 1, callingMethod, requestDetails); expect(range).deep.equal(['item1', 'item2']); }); }); @@ -326,17 +333,17 @@ describe('RedisCache Test Suite', async function () { it('should retrieve keys matching a glob-style pattern with *', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await redisCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); + await redisCache.set(keys[i], `value${i}`, callingMethod, requestDetails); } - await expect(redisCache.keys('h*llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); + await expect(redisCache.keys('h*llo', callingMethod, requestDetails)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with ?', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await redisCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); + await redisCache.set(keys[i], `value${i}`, callingMethod, requestDetails); } - await expect(redisCache.keys('h?llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); + await expect(redisCache.keys('h?llo', callingMethod, requestDetails)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with []', async function () { @@ -344,10 +351,10 @@ describe('RedisCache Test Suite', async function () { const key2 = 'hallo'; const pattern = 'h[ae]llo'; - await redisCache.set(key1, 'value1', callingMethod, requestIdPrefix); - await redisCache.set(key2, 'value2', callingMethod, requestIdPrefix); + await redisCache.set(key1, 'value1', callingMethod, requestDetails); + await redisCache.set(key2, 'value2', callingMethod, requestDetails); - const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await redisCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2]); }); @@ -356,10 +363,10 @@ describe('RedisCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[^e]llo'; - await redisCache.set(key1, 'value1', callingMethod, requestIdPrefix); - await redisCache.set(key2, 'value2', callingMethod, requestIdPrefix); + await redisCache.set(key1, 'value1', callingMethod, requestDetails); + await redisCache.set(key2, 'value2', callingMethod, requestDetails); - const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await redisCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2]); }); @@ -368,21 +375,21 @@ describe('RedisCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[a-b]llo'; - await redisCache.set(key1, 'value1', callingMethod, requestIdPrefix); - await redisCache.set(key2, 'value2', callingMethod, requestIdPrefix); + await redisCache.set(key1, 'value1', callingMethod, requestDetails); + await redisCache.set(key2, 'value2', callingMethod, requestDetails); - const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await redisCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2]); }); it('should retrieve keys matching a pattern with escaped special characters', async function () { const keys = ['h*llo', 'h?llo', 'h[llo', 'h]llo']; for (let i = 0; i < keys.length; i++) { - await redisCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); + await redisCache.set(keys[i], `value${i}`, callingMethod, requestDetails); } for (const key of keys) { await expect( - redisCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod, requestIdPrefix), + redisCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod, requestDetails), ).eventually.has.members([key]); } }); @@ -393,11 +400,11 @@ describe('RedisCache Test Suite', async function () { const key3 = 'age'; const pattern = '*'; - await redisCache.set(key1, 'Jack', callingMethod, requestIdPrefix); - await redisCache.set(key2, 'Stuntman', callingMethod, requestIdPrefix); - await redisCache.set(key3, '35', callingMethod, requestIdPrefix); + await redisCache.set(key1, 'Jack', callingMethod, requestDetails); + await redisCache.set(key2, 'Stuntman', callingMethod, requestDetails); + await redisCache.set(key3, '35', callingMethod, requestDetails); - const keys = await redisCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await redisCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2, key3]); }); }); diff --git a/packages/relay/tests/lib/eth/eth_call.spec.ts b/packages/relay/tests/lib/eth/eth_call.spec.ts index 8bdefb54bc..2db0f09f07 100644 --- a/packages/relay/tests/lib/eth/eth_call.spec.ts +++ b/packages/relay/tests/lib/eth/eth_call.spec.ts @@ -56,7 +56,7 @@ import { } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; import { IContractCallRequest, IContractCallResponse } from '../../../src/lib/types/IMirrorNode'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_common.spec.ts b/packages/relay/tests/lib/eth/eth_common.spec.ts index 842b21d3fc..b9d227c9e0 100644 --- a/packages/relay/tests/lib/eth/eth_common.spec.ts +++ b/packages/relay/tests/lib/eth/eth_common.spec.ts @@ -24,7 +24,7 @@ import { Registry } from 'prom-client'; import pino from 'pino'; import chaiAsPromised from 'chai-as-promised'; import { RelayImpl } from '../../../src/lib/relay'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts index d21852904a..a92c8a407e 100644 --- a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts +++ b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts @@ -38,7 +38,7 @@ import { } from './eth-config'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; import { request } from 'http'; dotenv.config({ path: path.resolve(__dirname, '../../test.env') }); diff --git a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts index 1f0adf9cc8..177786cd89 100644 --- a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts +++ b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts @@ -31,7 +31,7 @@ import { predefined } from '../../../src/lib/errors/JsonRpcError'; import RelayAssertions from '../../assertions'; import { generateEthTestEnv } from './eth-helpers'; import { toHex } from '../../helpers'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; import { request } from 'http'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts index 20fa90e735..2a3a692b9d 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts @@ -56,7 +56,7 @@ import { DEFAULT_BLOCK_RECEIPTS_ROOT_HASH, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index ef74c25c52..f1b75132e9 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -73,7 +73,7 @@ import { } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; import { fail } from 'assert'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts index 3757c13d87..719dd17738 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts @@ -33,7 +33,7 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts index d600b145df..751f530bcb 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts @@ -35,7 +35,7 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts index 84ff4bcf7f..4716f28e18 100644 --- a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts @@ -244,7 +244,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { const args = [ CONTRACT_ADDRESS_1, defaultDetailedContractResults.state_changes[0].slot, - requestIdPrefix, + requestDetails, numberTo0x(BLOCK_NUMBER), ]; diff --git a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts index 181d578616..90b4b5c9ff 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts @@ -30,7 +30,7 @@ import { DEFAULT_BLOCK, EMPTY_LOGS_RESPONSE } from './eth-config'; import { defaultErrorMessageHex } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; import { ITransactionReceipt } from '../../../src/lib/types/ITransactionReceipt'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts index 33700c8c53..f8bf6acfbd 100644 --- a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts +++ b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts @@ -31,7 +31,7 @@ import RelayAssertions from '../../assertions'; import { getRequestId, mockData, signTransaction } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; import { SDKClientError } from '../../../src/lib/errors/SDKClientError'; -import { IRequestDetails } from '../../../src/lib/types/IRequestDetails'; +import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/hbarLimiter.spec.ts b/packages/relay/tests/lib/hbarLimiter.spec.ts index 4e02e478ae..7e38b83fd5 100644 --- a/packages/relay/tests/lib/hbarLimiter.spec.ts +++ b/packages/relay/tests/lib/hbarLimiter.spec.ts @@ -23,6 +23,7 @@ import { expect } from 'chai'; import { Registry } from 'prom-client'; import HbarLimit from '../../src/lib/hbarlimiter'; import { estimateFileTransactionsFee, getRequestId, random20BytesAddress } from '../helpers'; +import { RequestDetails } from '../../src/lib/types/RequestDetails'; const registry = new Registry(); const logger = pino(); @@ -42,6 +43,7 @@ describe('HBAR Rate Limiter', async function () { const randomAccountAddress = random20BytesAddress(); const randomWhiteListedAccountAddress = random20BytesAddress(); const fileChunkSize = Number(process.env.FILE_APPEND_CHUNK_SIZE) || 5120; + const requestDetails = new RequestDetails({ requestId: getRequestId(), ipAddress: '0.0.0.0' }); this.beforeEach(() => { currentDateNow = Date.now(); @@ -67,8 +69,9 @@ describe('HBAR Rate Limiter', async function () { 'QUERY', 'eth_call', randomAccountAddress, + requestDetails ); - rateLimiterWithEmptyBudget.addExpense(validTotal, currentDateNow); + rateLimiterWithEmptyBudget.addExpense(validTotal, currentDateNow, requestDetails); expect(isEnabled).to.equal(false); expect(shouldRateLimit).to.equal(false); @@ -82,8 +85,14 @@ describe('HBAR Rate Limiter', async function () { const isEnabled = rateLimiter.isEnabled(); const limiterResetTime = rateLimiter.getResetTime(); const limiterRemainingBudget = rateLimiter.getRemainingBudget(); - const shouldRateLimit = rateLimiter.shouldLimit(currentDateNow, 'QUERY', 'eth_call', randomAccountAddress); - rateLimiter.addExpense(validTotal, currentDateNow); + const shouldRateLimit = rateLimiter.shouldLimit( + currentDateNow, + 'QUERY', + 'eth_call', + randomAccountAddress, + requestDetails, + ); + rateLimiter.addExpense(validTotal, currentDateNow, requestDetails); expect(isEnabled).to.equal(false); expect(shouldRateLimit).to.equal(false); @@ -97,8 +106,8 @@ describe('HBAR Rate Limiter', async function () { const isEnabled = invalidRateLimiter.isEnabled(); const limiterResetTime = invalidRateLimiter.getResetTime(); const limiterRemainingBudget = invalidRateLimiter.getRemainingBudget(); - const shouldRateLimit = invalidRateLimiter.shouldLimit(currentDateNow, 'QUERY', 'eth_call', randomAccountAddress); - invalidRateLimiter.addExpense(validTotal, currentDateNow); + const shouldRateLimit = invalidRateLimiter.shouldLimit(currentDateNow, 'QUERY', 'eth_call', randomAccountAddress, requestDetails); + invalidRateLimiter.addExpense(validTotal, currentDateNow, requestDetails); expect(isEnabled).to.equal(false); expect(shouldRateLimit).to.equal(false); @@ -110,7 +119,13 @@ describe('HBAR Rate Limiter', async function () { const isEnabled = rateLimiter.isEnabled(); const limiterResetTime = rateLimiter.getResetTime(); const limiterRemainingBudget = rateLimiter.getRemainingBudget(); - const shouldRateLimit = rateLimiter.shouldLimit(currentDateNow, 'QUERY', 'eth_call', randomAccountAddress); + const shouldRateLimit = rateLimiter.shouldLimit( + currentDateNow, + 'QUERY', + 'eth_call', + randomAccountAddress, + requestDetails, + ); expect(isEnabled).to.equal(true); expect(shouldRateLimit).to.equal(false); @@ -121,7 +136,7 @@ describe('HBAR Rate Limiter', async function () { it('should not rate limit', async function () { const cost = 10000000; - rateLimiter.addExpense(cost, currentDateNow); + rateLimiter.addExpense(cost, currentDateNow, requestDetails); const isEnabled = rateLimiter.isEnabled(); const limiterResetTime = rateLimiter.getResetTime(); @@ -131,6 +146,7 @@ describe('HBAR Rate Limiter', async function () { 'TRANSACTION', 'eth_sendRawTransaction', randomAccountAddress, + requestDetails, ); expect(isEnabled).to.equal(true); @@ -142,7 +158,7 @@ describe('HBAR Rate Limiter', async function () { it('should rate limit', async function () { const cost = 1000000000; - rateLimiter.addExpense(cost, currentDateNow); + rateLimiter.addExpense(cost, currentDateNow, requestDetails); const isEnabled = rateLimiter.isEnabled(); const limiterResetTime = rateLimiter.getResetTime(); @@ -152,6 +168,7 @@ describe('HBAR Rate Limiter', async function () { 'TRANSACTION', 'eth_sendRawTransaction', randomAccountAddress, + requestDetails, ); expect(isEnabled).to.equal(true); @@ -163,7 +180,7 @@ describe('HBAR Rate Limiter', async function () { it('should reset budget, while checking if we should rate limit', async function () { const cost = 1000000000; - rateLimiter.addExpense(cost, currentDateNow); + rateLimiter.addExpense(cost, currentDateNow, requestDetails); const isEnabled = rateLimiter.isEnabled(); const futureDate = currentDateNow + validDuration * 2; @@ -172,6 +189,7 @@ describe('HBAR Rate Limiter', async function () { 'TRANSACTION', 'eth_sendRawTransaction', randomAccountAddress, + requestDetails, ); const limiterResetTime = rateLimiter.getResetTime(); const limiterRemainingBudget = rateLimiter.getRemainingBudget(); @@ -185,21 +203,23 @@ describe('HBAR Rate Limiter', async function () { it('should reset budget, while adding expense', async function () { const cost = 1000000000; - rateLimiter.addExpense(cost, currentDateNow); + rateLimiter.addExpense(cost, currentDateNow, requestDetails); const shouldRateLimitBefore = rateLimiter.shouldLimit( currentDateNow, 'TRANSACTION', 'eth_sendRawTransaction', randomAccountAddress, + requestDetails, ); const futureDate = currentDateNow + validDuration * 2; - rateLimiter.addExpense(100, futureDate); + rateLimiter.addExpense(100, futureDate, requestDetails); const shouldRateLimitAfter = rateLimiter.shouldLimit( futureDate, 'TRANSACTION', 'eth_sendRawTransaction', randomAccountAddress, + requestDetails, ); const isEnabled = rateLimiter.isEnabled(); @@ -245,7 +265,7 @@ describe('HBAR Rate Limiter', async function () { it('should bypass rate limit if original caller is a white listed account', async function () { // add expense to rate limit throttle - rateLimiter.addExpense(validTotal, currentDateNow); + rateLimiter.addExpense(validTotal, currentDateNow, requestDetails); // should return true as `randomAccountAddress` is not white listed const shouldNOTByPassRateLimit = rateLimiter.shouldLimit( @@ -253,6 +273,7 @@ describe('HBAR Rate Limiter', async function () { 'TRANSACTION', 'eth_sendRawTransaction', randomAccountAddress, + requestDetails, ); // should return false as `randomWhiteListedAccountAddress` is white listed @@ -261,6 +282,7 @@ describe('HBAR Rate Limiter', async function () { 'TRANSACTION', 'eth_sendRawTransaction', randomWhiteListedAccountAddress, + requestDetails, ); expect(shouldByPassRateLimit).to.equal(false); diff --git a/packages/relay/tests/lib/mirrorNodeClient.spec.ts b/packages/relay/tests/lib/mirrorNodeClient.spec.ts index 55607e27d2..0db3de5094 100644 --- a/packages/relay/tests/lib/mirrorNodeClient.spec.ts +++ b/packages/relay/tests/lib/mirrorNodeClient.spec.ts @@ -23,21 +23,21 @@ import dotenv from 'dotenv'; import { expect } from 'chai'; import { Registry } from 'prom-client'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); -import { MirrorNodeClient } from '../../src/lib/clients/mirrorNodeClient'; +import { MirrorNodeClient } from '../../src/lib/clients'; import constants from '../../src/lib/constants'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; -import { getRequestId, mockData, random20BytesAddress } from './../helpers'; +import { getRequestId, mockData, random20BytesAddress } from '../helpers'; const registry = new Registry(); import pino from 'pino'; import { ethers } from 'ethers'; -import { predefined } from '../../src/lib/errors/JsonRpcError'; -import { SDKClientError } from '../../src/lib/errors/SDKClientError'; +import { predefined, MirrorNodeClientError, SDKClientError } from '../../src'; import { CacheService } from '../../src/lib/services/cacheService/cacheService'; -import { MirrorNodeClientError } from '../../src/lib/errors/MirrorNodeClientError'; +import { RequestDetails } from '../../src/lib/types/RequestDetails'; const logger = pino(); const noTransactions = '?transactions=false'; +const requestDetails = new RequestDetails({ requestId: getRequestId(), ipAddress: '0.0.0.0' }); describe('MirrorNodeClient', async function () { this.timeout(20000); @@ -97,7 +97,7 @@ describe('MirrorNodeClient', async function () { error['response'] = 'test error'; await mirrorNodeInstance.handleError(error, CONTRACT_CALL_ENDPOINT, CONTRACT_CALL_ENDPOINT, code, 'POST'); expect.fail('should have thrown an error'); - } catch (e) { + } catch (e: any) { expect(e.message).to.equal('test error'); } }); @@ -107,14 +107,14 @@ describe('MirrorNodeClient', async function () { it('Can extract the account number out of an account pagination next link url', async () => { const accountId = '0.0.123'; const url = `/api/v1/accounts/${accountId}?limit=100×tamp=lt:1682455406.562695326`; - const extractedAccountId = mirrorNodeInstance.extractAccountIdFromUrl(url); + const extractedAccountId = mirrorNodeInstance.extractAccountIdFromUrl(url, requestDetails); expect(extractedAccountId).to.eq(accountId); }); it('Can extract the evm address out of an account pagination next link url', async () => { const evmAddress = '0x583031d1113ad414f02576bd6afa5bbdf935b7d9'; const url = `/api/v1/accounts/${evmAddress}?limit=100×tamp=lt:1682455406.562695326`; - const extractedEvmAddress = mirrorNodeInstance.extractAccountIdFromUrl(url); + const extractedEvmAddress = mirrorNodeInstance.extractAccountIdFromUrl(url, requestDetails); expect(extractedEvmAddress).to.eq(evmAddress); }); @@ -1105,7 +1105,7 @@ describe('MirrorNodeClient', async function () { try { await mirrorNodeInstance.getPaginatedResults('results?page=0', 'results', 'genericResults'); expect.fail('should have thrown an error'); - } catch (e) { + } catch (e: any) { const errorRef = predefined.PAGINATION_MAX(0); // reference error for all properties except message expect(e.message).to.equal( `Exceeded maximum mirror node pagination count: ${constants.MAX_MIRROR_NODE_PAGINATION}`, diff --git a/packages/relay/tests/lib/openrpc.spec.ts b/packages/relay/tests/lib/openrpc.spec.ts index 99b88d3de7..55b5cea106 100644 --- a/packages/relay/tests/lib/openrpc.spec.ts +++ b/packages/relay/tests/lib/openrpc.spec.ts @@ -35,7 +35,7 @@ import { Registry } from 'prom-client'; import { EthImpl } from '../../src/lib/eth'; import { SDKClient } from '../../src/lib/clients'; import { MirrorNodeClient } from '../../src/lib/clients/mirrorNodeClient'; -import type { IRequestDetails } from '../../src/lib/types/IRequestDetails'; +import type { IRequestDetails } from '../../src/lib/types/RequestDetails'; import openRpcSchema from '../../../../docs/openrpc.json'; import { @@ -388,7 +388,7 @@ describe('Open RPC Specification', function () { const response = await ethImpl.getTransactionByBlockHashAndIndex( defaultBlock.hash, numberTo0x(defaultBlock.count), - requestIdPrefix, + requestDetails, ); validateResponseSchema(methodsResponseSchema.eth_getTransactionByBlockHashAndIndex, response); @@ -398,7 +398,7 @@ describe('Open RPC Specification', function () { const response = await ethImpl.getTransactionByBlockNumberAndIndex( numberTo0x(defaultBlock.number), numberTo0x(defaultBlock.count), - requestIdPrefix, + requestDetails, ); validateResponseSchema(methodsResponseSchema.eth_getTransactionByBlockNumberAndIndex, response); diff --git a/packages/relay/tests/lib/sdkClient.spec.ts b/packages/relay/tests/lib/sdkClient.spec.ts index c27a3e8cb6..17f5c04591 100644 --- a/packages/relay/tests/lib/sdkClient.spec.ts +++ b/packages/relay/tests/lib/sdkClient.spec.ts @@ -59,7 +59,7 @@ import { FileDeleteTransaction, TransactionRecordQuery, } from '@hashgraph/sdk'; -import { IRequestDetails } from '../../src/lib/types/IRequestDetails'; +import { RequestDetails } from '../../src/lib/types/RequestDetails'; config({ path: resolve(__dirname, '../test.env') }); const registry = new Registry(); @@ -76,9 +76,8 @@ describe('SdkClient', async function () { let eventEmitter: EventEmitter; let metricService: MetricService; let mirrorNodeClient: MirrorNodeClient; - let transactionService: TransactionService; - let requestDetails: IRequestDetails; + const requestDetails = new RequestDetails({ requestId: 'testId', ipAddress: '0.0.0.0' }); const feeSchedules = { current: { transactionFeeSchedule: [ @@ -97,7 +96,6 @@ describe('SdkClient', async function () { } as unknown as FeeSchedules; before(() => { - requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; const hederaNetwork = process.env.HEDERA_NETWORK!; if (hederaNetwork in constants.CHAIN_IDS) { client = Client.forName(hederaNetwork); @@ -163,7 +161,14 @@ describe('SdkClient', async function () { it('executes the query', async () => { queryStub.returns(successResponse); - let { resp, cost } = await sdkClient.increaseCostAndRetryExecution(contractCallQuery, baseCost, client, 3, 0); + let { resp, cost } = await sdkClient.increaseCostAndRetryExecution( + contractCallQuery, + baseCost, + client, + 3, + 0, + requestDetails, + ); expect(resp).to.eq(successResponse); expect(cost.toTinybars().toNumber()).to.eq(costTinybars); expect(queryStub.callCount).to.eq(1); @@ -175,7 +180,14 @@ describe('SdkClient', async function () { }); queryStub.onCall(1).returns(successResponse); - let { resp, cost } = await sdkClient.increaseCostAndRetryExecution(contractCallQuery, baseCost, client, 3, 0); + let { resp, cost } = await sdkClient.increaseCostAndRetryExecution( + contractCallQuery, + baseCost, + client, + 3, + 0, + requestDetails, + ); expect(resp).to.eq(successResponse); expect(cost.toTinybars().toNumber()).to.eq(costTinybars * constants.QUERY_COST_INCREMENTATION_STEP); expect(queryStub.callCount).to.eq(2); @@ -192,7 +204,14 @@ describe('SdkClient', async function () { queryStub.onCall(2).returns(successResponse); - let { resp, cost } = await sdkClient.increaseCostAndRetryExecution(contractCallQuery, baseCost, client, 3, 0); + let { resp, cost } = await sdkClient.increaseCostAndRetryExecution( + contractCallQuery, + baseCost, + client, + 3, + 0, + requestDetails, + ); expect(resp).to.eq(successResponse); expect(cost.toTinybars().toNumber()).to.eq( Math.floor(costTinybars * Math.pow(constants.QUERY_COST_INCREMENTATION_STEP, 2)), @@ -206,7 +225,7 @@ describe('SdkClient', async function () { status: Status.InsufficientTxFee, }); - await sdkClient.increaseCostAndRetryExecution(contractCallQuery, baseCost, client, 3, 0); + await sdkClient.increaseCostAndRetryExecution(contractCallQuery, baseCost, client, 3, 0, requestDetails); } catch (e: any) { expect(queryStub.callCount).to.eq(4); expect(e.status).to.eq(Status.InsufficientTxFee); @@ -2708,7 +2727,7 @@ describe('SdkClient', async function () { accountId.toString(), ); expect.fail('should have thrown an error'); - } catch (error) { + } catch (error: any) { expect(error.status).to.eq(expectedError.status); expect(error.message).to.eq(expectedError.message); } diff --git a/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts b/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts index 997d174d8f..931e537f0a 100644 --- a/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts +++ b/packages/relay/tests/lib/services/cacheService/cacheService.spec.ts @@ -27,6 +27,7 @@ import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; import * as sinon from 'sinon'; import { useInMemoryRedisServer } from '../../../helpers'; +import { RequestDetails } from '../../../../dist/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); const logger = pino(); @@ -39,7 +40,7 @@ chai.use(chaiAsPromised); describe('CacheService Test Suite', async function () { this.timeout(10000); - const requestIdPrefix = `[Request ID: cacheServiceTest]`; + const requestDetails = new RequestDetails({ requestId: 'cacheServiceTest', ipAddress: '0.0.0.0' }); const describeKeysTestSuite = () => { describe('keys', async function () { it('should retrieve all keys', async function () { @@ -48,9 +49,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); - const keys = await cacheService.keys('*', callingMethod, requestIdPrefix); + const keys = await cacheService.keys('*', callingMethod, requestDetails); expect(keys).to.have.members(Object.keys(entries)); }); @@ -60,9 +61,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); - const keys = await cacheService.keys('key*', callingMethod, requestIdPrefix); + const keys = await cacheService.keys('key*', callingMethod, requestDetails); expect(keys).to.have.members(Object.keys(entries)); }); @@ -72,9 +73,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); - const keys = await cacheService.keys('key?', callingMethod, requestIdPrefix); + const keys = await cacheService.keys('key?', callingMethod, requestDetails); expect(keys).to.have.members(Object.keys(entries)); }); @@ -84,9 +85,9 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); - const keys = await cacheService.keys('key[1-2]', callingMethod, requestIdPrefix); + const keys = await cacheService.keys('key[1-2]', callingMethod, requestDetails); expect(keys).to.have.members(['key1', 'key2']); }); @@ -96,10 +97,10 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); // [^3] should match all keys except key3 - const keys = await cacheService.keys('key[^3]', callingMethod, requestIdPrefix); + const keys = await cacheService.keys('key[^3]', callingMethod, requestDetails); expect(keys).to.have.members(['key1', 'key2']); }); @@ -109,9 +110,9 @@ describe('CacheService Test Suite', async function () { entries['keyb'] = 'value2'; entries['keyc'] = 'value3'; - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); - const keys = await cacheService.keys('key[a-c]', callingMethod, requestIdPrefix); + const keys = await cacheService.keys('key[a-c]', callingMethod, requestDetails); expect(keys).to.have.members(Object.keys(entries)); }); @@ -119,9 +120,9 @@ describe('CacheService Test Suite', async function () { const key = 'h*llo'; const value = 'value'; - await cacheService.set(key, value, callingMethod, requestIdPrefix); + await cacheService.set(key, value, callingMethod, requestDetails); - const keys = await cacheService.keys('h*llo', callingMethod, requestIdPrefix); + const keys = await cacheService.keys('h*llo', callingMethod, requestDetails); expect(keys).to.have.members([key]); }); @@ -132,8 +133,8 @@ describe('CacheService Test Suite', async function () { entries['key3'] = 'value3'; await cacheService.disconnectRedisClient(); - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); - const keys = await cacheService.keys('*', callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); + const keys = await cacheService.keys('*', callingMethod, requestDetails); expect(keys).to.have.members(Object.keys(entries)); }); }); @@ -146,15 +147,15 @@ describe('CacheService Test Suite', async function () { }); this.afterEach(async () => { - await cacheService.clear(requestIdPrefix); + await cacheService.clear(requestDetails); }); it('should be able to set and get from internal cache', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod, requestIdPrefix); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + await cacheService.set(key, value, callingMethod, requestDetails); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).eq(value); }); @@ -163,9 +164,9 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod, requestIdPrefix); - await cacheService.delete(key, callingMethod, requestIdPrefix); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + await cacheService.set(key, value, callingMethod, requestDetails); + await cacheService.delete(key, callingMethod, requestDetails); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).to.be.null; }); @@ -174,8 +175,8 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod, requestIdPrefix); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + await cacheService.set(key, value, callingMethod, requestDetails); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).eq(value); }); @@ -186,10 +187,10 @@ describe('CacheService Test Suite', async function () { entries['key2'] = 'value2'; entries['key3'] = 'value3'; - await cacheService.multiSet(entries, callingMethod, requestIdPrefix); + await cacheService.multiSet(entries, callingMethod, requestDetails); for (const [key, value] of Object.entries(entries)) { - const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const valueFromCache = await cacheService.getAsync(key, callingMethod, requestDetails); expect(valueFromCache).eq(value); } }); @@ -199,8 +200,8 @@ describe('CacheService Test Suite', async function () { const key = 'counter'; const amount = 5; - await cacheService.set(key, 10, callingMethod, requestIdPrefix); - const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); + await cacheService.set(key, 10, callingMethod, requestDetails); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestDetails); expect(newValue).to.equal(15); }); @@ -211,8 +212,8 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const value = 'item'; - await cacheService.rPush(key, value, callingMethod, requestIdPrefix); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + await cacheService.rPush(key, value, callingMethod, requestDetails); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).to.deep.equal([value]); }); @@ -223,8 +224,8 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; - await cacheService.set(key, values, callingMethod, requestIdPrefix); - const range = await cacheService.lRange(key, 0, 1, callingMethod, requestIdPrefix); + await cacheService.set(key, values, callingMethod, requestDetails); + const range = await cacheService.lRange(key, 0, 1, callingMethod, requestDetails); expect(range).to.deep.equal(['item1', 'item2']); }); @@ -233,8 +234,8 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; - await cacheService.set(key, values, callingMethod, requestIdPrefix); - const range = await cacheService.lRange(key, -2, -1, callingMethod, requestIdPrefix); + await cacheService.set(key, values, callingMethod, requestDetails); + const range = await cacheService.lRange(key, -2, -1, callingMethod, requestDetails); expect(range).to.deep.equal(['item2', 'item3']); }); @@ -294,16 +295,16 @@ describe('CacheService Test Suite', async function () { }); this.afterEach(async () => { - await cacheService.clear( requestIdPrefix); + await cacheService.clear(requestDetails); }); it('should be able to set and get from shared cache', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod, requestIdPrefix); + await cacheService.set(key, value, callingMethod, requestDetails); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).eq(value); }); @@ -311,11 +312,11 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod, requestIdPrefix); + await cacheService.set(key, value, callingMethod, requestDetails); - await cacheService.delete(key, callingMethod, requestIdPrefix); + await cacheService.delete(key, callingMethod, requestDetails); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).to.be.null; }); @@ -323,17 +324,17 @@ describe('CacheService Test Suite', async function () { const key = 'string'; const value = 'value'; - await cacheService.set(key, value, callingMethod, requestIdPrefix); + await cacheService.set(key, value, callingMethod, requestDetails); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).eq(value); }); it('should be able to set using multiSet and get them separately using internal cache', async function () { - await cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix); + await cacheService.multiSet(multiSetEntries, callingMethod, requestDetails); for (const [key, value] of Object.entries(multiSetEntries)) { - const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const valueFromCache = await cacheService.getAsync(key, callingMethod, requestDetails); expect(valueFromCache).eq(value); } }); @@ -342,10 +343,10 @@ describe('CacheService Test Suite', async function () { // @ts-ignore cacheService['shouldMultiSet'] = false; - await cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix); + await cacheService.multiSet(multiSetEntries, callingMethod, requestDetails); for (const [key, value] of Object.entries(multiSetEntries)) { - const valueFromCache = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const valueFromCache = await cacheService.getAsync(key, callingMethod, requestDetails); expect(valueFromCache).eq(value); } }); @@ -354,7 +355,7 @@ describe('CacheService Test Suite', async function () { const key = 'string'; await cacheService.disconnectRedisClient(); - const cachedValue = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const cachedValue = await cacheService.getAsync(key, callingMethod, requestDetails); expect(cachedValue).eq(null); }); @@ -364,19 +365,19 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.set(key, value, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.set(key, value, callingMethod, requestDetails)).to.eventually.not.be.rejected; - const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestDetails); expect(internalCacheRes).to.eq(value); }); it('should be able to multiSet to internal cache in case of Redis error', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.multiSet(multiSetEntries, callingMethod, requestDetails)).to.eventually.not.be.rejected; for (const [key, value] of Object.entries(multiSetEntries)) { - const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestDetails); expect(internalCacheRes).to.eq(value); } }); @@ -387,10 +388,10 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.multiSet(multiSetEntries, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.multiSet(multiSetEntries, callingMethod, requestDetails)).to.eventually.not.be.rejected; for (const [key, value] of Object.entries(multiSetEntries)) { - const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestIdPrefix); + const internalCacheRes = await cacheService.getAsync(key, callingMethod, requestDetails); expect(internalCacheRes).to.eq(value); } }); @@ -398,21 +399,21 @@ describe('CacheService Test Suite', async function () { it('should be able to clear from internal cache in case of Redis error', async function () { await cacheService.disconnectRedisClient(); - await expect(cacheService.clear(requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.clear(requestDetails)).to.eventually.not.be.rejected; }); it('should be able to delete from internal cache in case of Redis error', async function () { const key = 'string'; await cacheService.disconnectRedisClient(); - await expect(cacheService.delete(key, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.delete(key, callingMethod, requestDetails)).to.eventually.not.be.rejected; }); it('should be able to set to shared cache', async function () { const key = 'string'; const value = 'value'; - await expect(cacheService.set(key, value, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.set(key, value, callingMethod, requestDetails)).to.eventually.not.be.rejected; }); it('should be able to multiset to shared cache', async function () { @@ -420,13 +421,13 @@ describe('CacheService Test Suite', async function () { items['key1'] = 'value1'; items['key2'] = 'value2'; - await expect(cacheService.multiSet(items, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.multiSet(items, callingMethod, requestDetails)).to.eventually.not.be.rejected; }); it('should be able to delete from shared cache', async function () { const key = 'string'; - await expect(cacheService.delete(key, callingMethod, requestIdPrefix)).to.eventually.not.be.rejected; + await expect(cacheService.delete(key, callingMethod, requestDetails)).to.eventually.not.be.rejected; }); describe('incrBy', async function () { @@ -434,8 +435,8 @@ describe('CacheService Test Suite', async function () { const key = 'counter'; const amount = 5; - await cacheService.set(key, 10, callingMethod, requestIdPrefix); - const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); + await cacheService.set(key, 10, callingMethod, requestDetails); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestDetails); expect(newValue).to.equal(15); }); @@ -444,8 +445,8 @@ describe('CacheService Test Suite', async function () { const key = 'counter'; const amount = 5; - await cacheService.set(key, 10, callingMethod, requestIdPrefix); - const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); + await cacheService.set(key, 10, callingMethod, requestDetails); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestDetails); expect(newValue).to.equal(15); }); @@ -456,7 +457,7 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - const newValue = await cacheService.incrBy(key, amount, callingMethod, requestIdPrefix); + const newValue = await cacheService.incrBy(key, amount, callingMethod, requestDetails); expect(newValue).to.equal(5); }); @@ -467,8 +468,8 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const value = 'item'; - await cacheService.rPush(key, value, callingMethod, requestIdPrefix); - const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod, requestIdPrefix); + await cacheService.rPush(key, value, callingMethod, requestDetails); + const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod, requestDetails); expect(cachedValue).to.deep.equal([value]); }); @@ -479,8 +480,8 @@ describe('CacheService Test Suite', async function () { await cacheService.disconnectRedisClient(); - await cacheService.rPush(key, value, callingMethod, requestIdPrefix); - const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod, requestIdPrefix); + await cacheService.rPush(key, value, callingMethod, requestDetails); + const cachedValue = await cacheService.lRange(key, 0, -1, callingMethod, requestDetails); expect(cachedValue).to.deep.equal([value]); }); @@ -491,10 +492,10 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; for (const item of values) { - await cacheService.rPush(key, item, callingMethod, requestIdPrefix); + await cacheService.rPush(key, item, callingMethod, requestDetails); } - const range = await cacheService.lRange(key, 0, 1, callingMethod, requestIdPrefix); + const range = await cacheService.lRange(key, 0, 1, callingMethod, requestDetails); expect(range).to.deep.equal(['item1', 'item2']); }); @@ -503,10 +504,10 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; for (const item of values) { - await cacheService.rPush(key, item, callingMethod, requestIdPrefix); + await cacheService.rPush(key, item, callingMethod, requestDetails); } - const range = await cacheService.lRange(key, -2, -1, callingMethod, requestIdPrefix); + const range = await cacheService.lRange(key, -2, -1, callingMethod, requestDetails); expect(range).to.deep.equal(['item2', 'item3']); }); @@ -517,10 +518,10 @@ describe('CacheService Test Suite', async function () { const key = 'list'; const values = ['item1', 'item2', 'item3']; for (const item of values) { - await cacheService.rPush(key, item, callingMethod); + await cacheService.rPush(key, item, callingMethod, requestDetails); } - const range = await cacheService.lRange(key, 0, 1, callingMethod, requestIdPrefix); + const range = await cacheService.lRange(key, 0, 1, callingMethod, requestDetails); expect(range).to.deep.equal(['item1', 'item2']); }); diff --git a/packages/relay/tests/lib/services/eth/filter.spec.ts b/packages/relay/tests/lib/services/eth/filter.spec.ts index d27f857af4..7c51b8d69a 100644 --- a/packages/relay/tests/lib/services/eth/filter.spec.ts +++ b/packages/relay/tests/lib/services/eth/filter.spec.ts @@ -33,6 +33,7 @@ import { predefined } from '../../../../src'; import { CacheService } from '../../../../src/lib/services/cacheService/cacheService'; import * as sinon from 'sinon'; import { request } from 'http'; +import { RequestDetails } from '../../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); const logger = pino(); @@ -46,6 +47,7 @@ let cacheService: CacheService; describe('Filter API Test Suite', async function () { this.timeout(10000); + const requestDetails = new RequestDetails({ requestId: getRequestId(), ipAddress: '0.0.0.0' }); const filterObject = { toBlock: 'latest', }; @@ -57,11 +59,10 @@ describe('Filter API Test Suite', async function () { const LATEST_BLOCK_QUERY = 'blocks?limit=1&order=desc'; const BLOCK_BY_NUMBER_QUERY = 'blocks'; let logFilterObject; - let requestIdPrefix; const validateFilterCache = async (filterId, expectedFilterType, expectedParams = {}) => { const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; - const cachedFilter = await cacheService.getAsync(cacheKey, undefined); + const cachedFilter = await cacheService.getAsync(cacheKey, 'validateFilterCache', requestDetails); expect(cachedFilter).to.exist; expect(cachedFilter.type).to.exist; expect(cachedFilter.type).to.eq(expectedFilterType); @@ -73,7 +74,6 @@ describe('Filter API Test Suite', async function () { this.beforeAll(() => { cacheMock = sinon.createSandbox(); - requestIdPrefix = `[Request ID: testId]`; blockFilterObject = { type: constants.FILTER.TYPE.NEW_BLOCK, params: { @@ -93,7 +93,7 @@ describe('Filter API Test Suite', async function () { cacheService = new CacheService(logger.child({ name: `cache` }), registry); // @ts-ignore mirrorNodeInstance = new MirrorNodeClient( - process.env.MIRROR_NODE_URL, + process.env.MIRROR_NODE_URL ?? '', logger.child({ name: `mirror-node` }), registry, cacheService, @@ -112,7 +112,7 @@ describe('Filter API Test Suite', async function () { this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); cacheMock.stub(cacheService, 'set').returns(true); @@ -142,7 +142,7 @@ describe('Filter API Test Suite', async function () { filterService.newFilter, true, filterService, - {}, + [], ); await RelayAssertions.assertRejection( predefined.UNSUPPORTED_METHOD, @@ -163,7 +163,7 @@ describe('Filter API Test Suite', async function () { it('FILTER_API_ENABLED=true', async function () { process.env.FILTER_API_ENABLED = 'true'; restMock.onGet(LATEST_BLOCK_QUERY).reply(200, { blocks: [{ ...defaultBlock }] }); - const filterId = await filterService.newFilter(undefined, undefined, requestIdPrefix); + const filterId = await filterService.newFilter(undefined, undefined, requestDetails); expect(filterId).to.exist; expect(RelayAssertions.validateHash(filterId, 32)).to.eq(true, 'returns valid filterId'); @@ -176,13 +176,13 @@ describe('Filter API Test Suite', async function () { `contracts/results/logs?timestamp=gte:${defaultBlock.timestamp.from}×tamp=lte:${defaultBlock.timestamp.to}&limit=100&order=asc`, ) .reply(200, defaultLogs1); - const filterChanges = await filterService.getFilterChanges(filterId, requestIdPrefix); + const filterChanges = await filterService.getFilterChanges(filterId, requestDetails); expect(filterChanges).to.exist; cacheMock.restore(); cacheMock.stub(cacheService, 'getAsync').withArgs(cacheKey, 'eth_uninstallFilter').returns(logFilterObject); - const isFilterUninstalled = await filterService.uninstallFilter(filterId); + const isFilterUninstalled = await filterService.uninstallFilter(filterId, requestDetails); expect(isFilterUninstalled).to.eq(true, 'executes correctly'); }); @@ -235,29 +235,29 @@ describe('Filter API Test Suite', async function () { it('Returns a valid filterId', async function () { expect( - RelayAssertions.validateHash(await filterService.newFilter(undefined, undefined, requestIdPrefix), 32), + RelayAssertions.validateHash(await filterService.newFilter(undefined, undefined, requestDetails), 32), ).to.eq(true, 'with default param values'); expect( - RelayAssertions.validateHash(await filterService.newFilter(numberHex, undefined, requestIdPrefix), 32), + RelayAssertions.validateHash(await filterService.newFilter(numberHex, undefined, requestDetails), 32), ).to.eq(true, 'with fromBlock'); expect( - RelayAssertions.validateHash(await filterService.newFilter(numberHex, 'latest', requestIdPrefix), 32), + RelayAssertions.validateHash(await filterService.newFilter(numberHex, 'latest', requestDetails), 32), ).to.eq(true, 'with fromBlock, toBlock'); expect( RelayAssertions.validateHash( - await filterService.newFilter(numberHex, 'latest', requestIdPrefix, defaultEvmAddress), + await filterService.newFilter(numberHex, 'latest', requestDetails, defaultEvmAddress), 32, ), ).to.eq(true, 'with fromBlock, toBlock, address'); expect( RelayAssertions.validateHash( - await filterService.newFilter(numberHex, 'latest', requestIdPrefix, defaultEvmAddress, defaultLogTopics), + await filterService.newFilter(numberHex, 'latest', requestDetails, defaultEvmAddress, defaultLogTopics), 32, ), ).to.eq(true, 'with fromBlock, toBlock, address, topics'); expect( RelayAssertions.validateHash( - await filterService.newFilter(numberHex, 'latest', requestIdPrefix, defaultEvmAddress, defaultLogTopics), + await filterService.newFilter(numberHex, 'latest', requestDetails, defaultEvmAddress, defaultLogTopics), 32, ), ).to.eq(true, 'with all parameters'); @@ -267,7 +267,7 @@ describe('Filter API Test Suite', async function () { const filterId = await filterService.newFilter( numberHex, 'latest', - requestIdPrefix, + requestDetails, defaultEvmAddress, defaultLogTopics, ); @@ -308,13 +308,13 @@ describe('Filter API Test Suite', async function () { // block range is valid expect( RelayAssertions.validateHash( - await filterService.newFilter(blockNumberHexes[1400], blockNumberHexes[1500], requestIdPrefix), + await filterService.newFilter(blockNumberHexes[1400], blockNumberHexes[1500], requestDetails), 32, ), ).to.eq(true); expect( RelayAssertions.validateHash( - await filterService.newFilter(blockNumberHexes[1400], 'latest', requestIdPrefix), + await filterService.newFilter(blockNumberHexes[1400], 'latest', requestDetails), 32, ), ).to.eq(true); @@ -327,11 +327,11 @@ describe('Filter API Test Suite', async function () { cacheMock.stub(cacheService, 'getAsync').onFirstCall().returns(filterObject).onSecondCall().returns(undefined); - cacheService.set(cacheKey, filterObject, filterService.ethUninstallFilter, constants.FILTER.TTL, undefined, true); + cacheService.set(cacheKey, filterObject, filterService.ethUninstallFilter, requestDetails, constants.FILTER.TTL); - const result = await filterService.uninstallFilter(existingFilterId); + const result = await filterService.uninstallFilter(existingFilterId, requestDetails); - const isDeleted = (await cacheService.getAsync(cacheKey, filterService.ethUninstallFilter, undefined)) + const isDeleted = (await cacheService.getAsync(cacheKey, filterService.ethUninstallFilter, requestDetails)) ? false : true; expect(result).to.eq(true); @@ -340,7 +340,7 @@ describe('Filter API Test Suite', async function () { it('should return false if filter does not exist, therefore is not deleted', async function () { cacheMock.stub(cacheService, 'getAsync').returns(undefined); - const result = await filterService.uninstallFilter(nonExistingFilterId); + const result = await filterService.uninstallFilter(nonExistingFilterId, requestDetails); expect(result).to.eq(false); }); }); @@ -351,13 +351,11 @@ describe('Filter API Test Suite', async function () { }); it('Returns a valid filterId', async function () { - expect( - RelayAssertions.validateHash(await filterService.newBlockFilter(undefined, undefined, requestIdPrefix), 32), - ).to.eq(true); + expect(RelayAssertions.validateHash(await filterService.newBlockFilter(requestDetails), 32)).to.eq(true); }); it('Creates a filter with type=new_block', async function () { - const filterId = await filterService.newBlockFilter(getRequestId()); + const filterId = await filterService.newBlockFilter(requestDetails); validateFilterCache(filterId, constants.FILTER.TYPE.NEW_BLOCK, { blockAtCreation: toHex(defaultBlock.number), }); @@ -370,7 +368,7 @@ describe('Filter API Test Suite', async function () { const filterIdBlockType = await filterService.createFilter( constants.FILTER.TYPE.NEW_BLOCK, filterObject, - requestIdPrefix, + requestDetails, ); await RelayAssertions.assertRejection( predefined.FILTER_NOT_FOUND, @@ -386,7 +384,7 @@ describe('Filter API Test Suite', async function () { const filterIdBlockType = await filterService.createFilter( constants.FILTER.TYPE.PENDING_TRANSACTION, filterObject, - requestIdPrefix, + requestDetails, ); await RelayAssertions.assertRejection( predefined.FILTER_NOT_FOUND, @@ -419,7 +417,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter('0x1', undefined, requestIdPrefix); + const filterId = await filterService.newFilter('0x1', undefined, requestDetails); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -431,7 +429,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); + const logs = await filterService.getFilterLogs(filterId, requestDetails); expect(logs).to.not.be.empty; logs.every((log) => expect(Number(log.blockNumber)).to.be.greaterThan(1)); @@ -456,7 +454,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter(null, '0x3', requestIdPrefix); + const filterId = await filterService.newFilter(undefined, '0x3', requestDetails); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -469,7 +467,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); + const logs = await filterService.getFilterLogs(filterId, requestDetails); expect(logs).to.not.be.empty; logs.every((log) => expect(Number(log.blockNumber)).to.be.lessThan(3)); @@ -490,7 +488,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter(null, null, requestIdPrefix, defaultEvmAddress); + const filterId = await filterService.newFilter(undefined, undefined, requestDetails, defaultEvmAddress); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock @@ -504,7 +502,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); + const logs = await filterService.getFilterLogs(filterId, requestDetails); expect(logs).to.not.be.empty; logs.every((log) => expect(log.address).to.equal(defaultEvmAddress)); @@ -530,7 +528,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter(null, null, requestIdPrefix, null, customTopic); + const filterId = await filterService.newFilter(null, null, requestDetails, null, customTopic); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -543,7 +541,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterLogs(filterId, requestIdPrefix); + const logs = await filterService.getFilterLogs(filterId, requestDetails); expect(logs).to.not.be.empty; logs.every((log) => expect(log.topics).to.deep.equal(customTopic)); @@ -587,13 +585,12 @@ describe('Filter API Test Suite', async function () { .reply(200, { blocks: [] }); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${existingFilterId}`; - cacheService.set( + await cacheService.set( cacheKey, blockFilterObject, filterService.ethGetFilterChanges, + requestDetails, constants.FILTER.TTL, - undefined, - true, ); cacheMock .stub(cacheService, 'getAsync') @@ -604,7 +601,7 @@ describe('Filter API Test Suite', async function () { .onThirdCall() .returns({ ...blockFilterObject, lastQueried: defaultBlock.number + 4 }); - const result = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); + const result = await filterService.getFilterChanges(existingFilterId, requestDetails); expect(result).to.exist; expect(result.length).to.eq(3, 'returns correct number of blocks'); @@ -612,7 +609,7 @@ describe('Filter API Test Suite', async function () { expect(result[1]).to.eq('0x2'); expect(result[2]).to.eq('0x3'); - const secondResult = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); + const secondResult = await filterService.getFilterChanges(existingFilterId, requestDetails); expect(secondResult).to.exist; expect(secondResult.length).to.eq(0, 'second call returns no block hashes'); }); @@ -628,13 +625,12 @@ describe('Filter API Test Suite', async function () { .reply(200, { blocks: [] }); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${existingFilterId}`; - cacheService.set( + await cacheService.set( cacheKey, blockFilterObject, filterService.ethGetFilterChanges, + requestDetails, constants.FILTER.TTL, - undefined, - true, ); cacheMock .stub(cacheService, 'getAsync') @@ -643,10 +639,10 @@ describe('Filter API Test Suite', async function () { .onSecondCall() .returns({ ...blockFilterObject, lastQueried: defaultBlock.number + 1 }); - const resultCurrentBlock = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); + const resultCurrentBlock = await filterService.getFilterChanges(existingFilterId, requestDetails); expect(resultCurrentBlock).to.not.be.empty; - const resultSameBlock = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); + const resultSameBlock = await filterService.getFilterChanges(existingFilterId, requestDetails); expect(resultSameBlock).to.be.empty; }); @@ -672,7 +668,7 @@ describe('Filter API Test Suite', async function () { .reply(200, filteredLogs); restMock.onGet('blocks/1').reply(200, { ...defaultBlock, block_number: 1 }); - const filterId = await filterService.newFilter('0x1', undefined, requestIdPrefix); + const filterId = await filterService.newFilter('0x1', undefined, requestDetails); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -684,7 +680,7 @@ describe('Filter API Test Suite', async function () { }, }); - const logs = await filterService.getFilterChanges(filterId, requestIdPrefix); + const logs = await filterService.getFilterChanges(filterId, requestDetails); expect(logs).to.not.be.empty; logs.every((log) => expect(Number(log.blockNumber)).to.equal(9)); }); @@ -698,7 +694,7 @@ describe('Filter API Test Suite', async function () { .reply(200, []); restMock.onGet('blocks/1').reply(200, { ...defaultBlock, block_number: 1 }); - const filterId = await filterService.newFilter('0x1', undefined, requestIdPrefix); + const filterId = await filterService.newFilter('0x1', undefined, requestDetails); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -709,7 +705,7 @@ describe('Filter API Test Suite', async function () { fromBlock: 1, }, }); - const logs = await filterService.getFilterChanges(filterId, requestIdPrefix); + const logs = await filterService.getFilterChanges(filterId, requestDetails); expect(logs).to.be.empty; }); @@ -723,7 +719,7 @@ describe('Filter API Test Suite', async function () { cacheService.set(cacheKey, blockFilterObject, filterService.ethGetFilterChanges, constants.FILTER.TTL, undefined); cacheMock.stub(cacheService, 'getAsync').returns(blockFilterObject); - const blocks = await filterService.getFilterChanges(existingFilterId, requestIdPrefix); + const blocks = await filterService.getFilterChanges(existingFilterId, requestDetails); expect(blocks).to.be.empty; }); }); diff --git a/packages/relay/tests/lib/services/metricService/metricService.spec.ts b/packages/relay/tests/lib/services/metricService/metricService.spec.ts index f90d8f96fa..aaa1f0b10f 100644 --- a/packages/relay/tests/lib/services/metricService/metricService.spec.ts +++ b/packages/relay/tests/lib/services/metricService/metricService.spec.ts @@ -322,7 +322,7 @@ describe('Metric Service', function () { gasUsed: mockedGasUsed, interactingEntity: mockedInteractingEntity, status: 'SUCCESS', - requestId: getRequestId(), + requestDetails: getRequestId(), }; it('should execute addExpenseAndCaptureMetrics() to capture metrics in HBAR limiter and metric registry', async () => { const originalBudget = hbarLimiter.getRemainingBudget(); From 68c93b106013a2a18eef0e5510ea22517d947be1 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Thu, 12 Sep 2024 18:23:13 +0300 Subject: [PATCH 24/48] chore: draft changes Signed-off-by: Victor Yanev --- package-lock.json | 14 + package.json | 1 + packages/relay/src/formatters.ts | 2 - packages/relay/src/index.ts | 3 +- packages/relay/src/lib/clients/sdkClient.ts | 23 +- .../ethAddressHbarSpendingPlanRepository.ts | 16 +- .../hbarLimiter/hbarSpendingPlanRepository.ts | 104 ++-- packages/relay/src/lib/eth.ts | 188 +++---- packages/relay/src/lib/poller.ts | 35 +- packages/relay/src/lib/precheck.ts | 81 ++- packages/relay/src/lib/relay.ts | 9 +- .../ethFilterService/IFilterService.ts | 14 +- .../ethService/ethFilterService/index.ts | 4 +- .../hbarLimitService/IHbarLimitService.ts | 4 +- .../lib/services/hbarLimitService/index.ts | 103 ++-- .../services/metricService/metricService.ts | 36 +- .../relay/src/lib/types/RequestDetails.ts | 4 +- .../tests/lib/clients/localLRUCache.spec.ts | 1 - packages/relay/tests/lib/eth/eth_call.spec.ts | 71 ++- .../relay/tests/lib/eth/eth_common.spec.ts | 16 +- .../tests/lib/eth/eth_estimateGas.spec.ts | 13 +- .../tests/lib/eth/eth_feeHistory.spec.ts | 18 +- .../relay/tests/lib/eth/eth_gasPrice.spec.ts | 20 +- .../tests/lib/eth/eth_getBalance.spec.ts | 71 +-- .../tests/lib/eth/eth_getBlockByHash.spec.ts | 19 +- .../lib/eth/eth_getBlockByNumber.spec.ts | 20 +- ...eth_getBlockTransactionCountByHash.spec.ts | 15 +- ...h_getBlockTransactionCountByNumber.spec.ts | 20 +- .../relay/tests/lib/eth/eth_getCode.spec.ts | 15 +- .../relay/tests/lib/eth/eth_getLogs.spec.ts | 54 +- .../tests/lib/eth/eth_getStorageAt.spec.ts | 14 +- ..._getTransactionByBlockHashAndIndex.spec.ts | 24 +- ...etTransactionByBlockNumberAndIndex.spec.ts | 18 +- .../lib/eth/eth_getTransactionByHash.spec.ts | 15 +- .../lib/eth/eth_getTransactionCount.spec.ts | 17 +- .../lib/eth/eth_getTransactionReceipt.spec.ts | 13 +- .../lib/eth/eth_sendRawTransaction.spec.ts | 37 +- .../relay/tests/lib/mirrorNodeClient.spec.ts | 3 +- packages/relay/tests/lib/openrpc.spec.ts | 87 ++-- .../tests/lib/services/eth/filter.spec.ts | 31 +- packages/server/src/koaJsonRpc/index.ts | 15 +- packages/server/src/server.ts | 34 +- packages/server/src/types/types.ts | 4 - .../tests/acceptance/rpc_batch1.spec.ts | 463 +++++++++--------- packages/server/tests/clients/mirrorClient.ts | 6 +- packages/server/tests/helpers/utils.ts | 19 +- packages/ws-server/src/controllers/index.ts | 6 +- packages/ws-server/src/webSocketServer.ts | 9 +- .../ws-server/tests/acceptance/call.spec.ts | 9 +- .../tests/acceptance/estimateGas.spec.ts | 11 +- .../tests/acceptance/getStorageAt.spec.ts | 10 +- 51 files changed, 949 insertions(+), 890 deletions(-) delete mode 100644 packages/server/src/types/types.ts diff --git a/package-lock.json b/package-lock.json index 98bace7110..00ae987ec8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "@types/chai-as-promised": "^7.1.5", "@types/co-body": "6.1.0", "@types/koa-cors": "^0.0.6", + "@types/lodash": "^4.17.7", "@typescript-eslint/eslint-plugin": "^6.5.0", "@typescript-eslint/parser": "^6.5.0", "axios-mock-adapter": "^1.20.0", @@ -5154,6 +5155,13 @@ "@types/node": "*" } }, + "node_modules/@types/lodash": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", @@ -27177,6 +27185,12 @@ "@types/node": "*" } }, + "@types/lodash": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "dev": true + }, "@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", diff --git a/package.json b/package.json index e0e50040d4..e3876d60df 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "@types/chai-as-promised": "^7.1.5", "@types/co-body": "6.1.0", "@types/koa-cors": "^0.0.6", + "@types/lodash": "^4.17.7", "@typescript-eslint/eslint-plugin": "^6.5.0", "@typescript-eslint/parser": "^6.5.0", "axios-mock-adapter": "^1.20.0", diff --git a/packages/relay/src/formatters.ts b/packages/relay/src/formatters.ts index 872787b4e5..3087c9fe5d 100644 --- a/packages/relay/src/formatters.ts +++ b/packages/relay/src/formatters.ts @@ -21,9 +21,7 @@ import crypto from 'crypto'; import constants from './lib/constants'; import { BigNumber as BN } from 'bignumber.js'; -import { TransactionRecord } from '@hashgraph/sdk'; import { BigNumber } from '@hashgraph/sdk/lib/Transfer'; -import { MirrorNodeTransactionRecord } from './lib/types/mirrorNode'; import { Transaction, Transaction1559, Transaction2930 } from './lib/model'; const EMPTY_HEX = '0x'; diff --git a/packages/relay/src/index.ts b/packages/relay/src/index.ts index fb52f3087d..252eaf305b 100644 --- a/packages/relay/src/index.ts +++ b/packages/relay/src/index.ts @@ -27,9 +27,8 @@ import { MirrorNodeClient } from './lib/clients'; import { IFilterService } from './lib/services/ethService/ethFilterService/IFilterService'; import { IDebugService } from './lib/services/debugService/IDebugService'; import { RequestDetails } from './lib/types/RequestDetails'; -import { SDKClientError } from './lib/errors/SDKClientError'; -export { JsonRpcError, predefined, MirrorNodeClientError, WebSocketError, SDKClientError }; +export { JsonRpcError, predefined, MirrorNodeClientError, WebSocketError }; export { RelayImpl } from './lib/relay'; diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index cf52c14a4e..220050a756 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -57,15 +57,14 @@ import { EventEmitter } from 'events'; import HbarLimit from '../hbarlimiter'; import constants from './../constants'; import { BigNumber } from '@hashgraph/sdk/lib/Transfer'; -import { SDKClientError } from './../errors/SDKClientError'; -import { JsonRpcError, predefined } from './../errors/JsonRpcError'; +import { SDKClientError } from '../errors/SDKClientError'; +import { JsonRpcError, predefined } from '../errors/JsonRpcError'; import { CacheService } from '../services/cacheService/cacheService'; import { formatRequestIdMessage, weibarHexToTinyBarInt } from '../../formatters'; import { ITransactionRecordMetric, IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../types'; import { RequestDetails } from '../types/RequestDetails'; const _ = require('lodash'); -const LRU = require('lru-cache'); export class SDKClient { /** @@ -357,12 +356,7 @@ export class SDKClient { const exchangeRates = await this.getExchangeRate(callerName, requestDetails); const tinyBars = this.convertGasPriceToTinyBars(schedule.fees[0].servicedata, exchangeRates); - await this.cacheService.set( - constants.CACHE_KEY.GET_TINYBAR_GAS_FEE, - tinyBars, - callerName, - requestDetails.formattedRequestId, - ); + await this.cacheService.set(constants.CACHE_KEY.GET_TINYBAR_GAS_FEE, tinyBars, callerName, requestDetails); return tinyBars; } } @@ -609,6 +603,7 @@ export class SDKClient { * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A promise resolving to the query response. * @throws {Error} Throws an error if the query fails or if rate limits are exceeded. + * @template T - The type of the query response. */ async executeQuery( query: Query, @@ -683,7 +678,7 @@ export class SDKClient { * @param {Transaction} transaction - The transaction to execute. * @param {string} callerName - The name of the caller requesting the transaction. * @param {string} interactingEntity - The entity interacting with the transaction. - * @param {string} requestId - The ID of the request. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @param {boolean} shouldThrowHbarLimit - Flag to indicate whether to check HBAR limits. * @param {string} originalCallerAddress - The address of the original caller making the request. * @returns {Promise} - A promise that resolves to the transaction response. @@ -770,7 +765,7 @@ export class SDKClient { * @param {FileAppendTransaction} transaction - The batch transaction to execute. * @param {string} callerName - The name of the caller requesting the transaction. * @param {string} interactingEntity - The entity interacting with the transaction. - * @param {string} requestId - The ID of the request. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @param {boolean} shouldThrowHbarLimit - Flag to indicate whether to check HBAR limits. * @param {string} originalCallerAddress - The address of the original caller making the request. * @returns {Promise} - A promise that resolves when the batch execution is complete. @@ -821,7 +816,7 @@ export class SDKClient { this.eventEmitter.emit(constants.EVENTS.EXECUTE_TRANSACTION, { transactionId: transactionResponse.transactionId.toString(), callerName, - requestId: requestDetails.formattedRequestId, + requestDetails, txConstructorName, operatorAccountId: this.clientMain.operatorAccountId!.toString(), interactingEntity, @@ -836,7 +831,7 @@ export class SDKClient { * Creates a file on the Hedera network using the provided call data. * @param {Uint8Array} callData - The data to be written to the file. * @param {Client} client - The Hedera client to use for the transaction. - * @param {string} requestId - The request ID associated with the transaction. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @param {string} callerName - The name of the caller creating the file. * @param {string} interactingEntity - The entity interacting with the transaction. * @param {string} originalCallerAddress - The address of the original caller making the request. @@ -910,7 +905,7 @@ export class SDKClient { * Deletes a file on the Hedera network and verifies its deletion. * * @param {FileId} fileId - The ID of the file to be deleted. - * @param {string} requestId - A unique identifier for the request. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @param {string} callerName - The name of the entity initiating the request. * @param {string} interactingEntity - The name of the interacting entity. * @param {string} originalCallerAddress - The address of the original caller making the request. diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts index faadde0a99..31bd0b6b79 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts @@ -23,6 +23,7 @@ import { Logger } from 'pino'; import { IEthAddressHbarSpendingPlan } from '../../types/hbarLimiter/ethAddressHbarSpendingPlan'; import { EthAddressHbarSpendingPlanNotFoundError } from '../../types/hbarLimiter/errors'; import { EthAddressHbarSpendingPlan } from '../../entities/hbarLimiter/ethAddressHbarSpendingPlan'; +import { RequestDetails } from '../../../types/RequestDetails'; export class EthAddressHbarSpendingPlanRepository { private readonly collectionKey = 'ethAddressHbarSpendingPlan'; @@ -49,11 +50,12 @@ export class EthAddressHbarSpendingPlanRepository { * Finds an {@link EthAddressHbarSpendingPlan} for an ETH address. * * @param {string} ethAddress - The ETH address to search for. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - The associated plan for the ETH address. */ - async findByAddress(ethAddress: string, requestIdPrefix: string): Promise { + async findByAddress(ethAddress: string, requestDetails: RequestDetails): Promise { const key = this.getKey(ethAddress); - const addressPlan = await this.cache.getAsync(key, 'findByAddress', requestIdPrefix); + const addressPlan = await this.cache.getAsync(key, 'findByAddress', requestDetails); if (!addressPlan) { throw new EthAddressHbarSpendingPlanNotFoundError(ethAddress); } @@ -65,11 +67,12 @@ export class EthAddressHbarSpendingPlanRepository { * Saves an {@link EthAddressHbarSpendingPlan} to the cache, linking the plan to the ETH address. * * @param {IEthAddressHbarSpendingPlan} addressPlan - The plan to save. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves when the ETH address is linked to the plan. */ - async save(addressPlan: IEthAddressHbarSpendingPlan, requestIdPrefix: string): Promise { + async save(addressPlan: IEthAddressHbarSpendingPlan, requestDetails: RequestDetails): Promise { const key = this.getKey(addressPlan.ethAddress); - await this.cache.set(key, addressPlan, 'save', requestIdPrefix, this.threeMonthsInMillis); + await this.cache.set(key, addressPlan, 'save', requestDetails, this.threeMonthsInMillis); this.logger.trace(`Saved EthAddressHbarSpendingPlan with address ${addressPlan.ethAddress}`); } @@ -77,11 +80,12 @@ export class EthAddressHbarSpendingPlanRepository { * Deletes an {@link EthAddressHbarSpendingPlan} from the cache, unlinking the plan from the ETH address. * * @param {string} ethAddress - The ETH address to unlink the plan from. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves when the ETH address is unlinked from the plan. */ - async delete(ethAddress: string, requestIdPrefix: string): Promise { + async delete(ethAddress: string, requestDetails: RequestDetails): Promise { const key = this.getKey(ethAddress); - await this.cache.delete(key, 'delete', requestIdPrefix); + await this.cache.delete(key, 'delete', requestDetails); this.logger.trace(`Deleted EthAddressHbarSpendingPlan with address ${ethAddress}`); } diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts index 820ac948f8..9382e1de5a 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts @@ -27,6 +27,7 @@ import { IDetailedHbarSpendingPlan, IHbarSpendingPlan } from '../../types/hbarLi import { HbarSpendingRecord } from '../../entities/hbarLimiter/hbarSpendingRecord'; import { SubscriptionType } from '../../types/hbarLimiter/subscriptionType'; import { HbarSpendingPlan } from '../../entities/hbarLimiter/hbarSpendingPlan'; +import { RequestDetails } from '../../../types/RequestDetails'; export class HbarSpendingPlanRepository { private readonly collectionKey = 'hbarSpendingPlan'; @@ -51,13 +52,14 @@ export class HbarSpendingPlanRepository { } /** - * Gets a hbar spending plan by ID. - * @param id - The ID of the plan to get. - * @returns {Promise} - The hbar spending plan object. + * Gets an HBar spending plan by ID. + * @param {string} id - The ID of the plan to get. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. + * @returns {Promise} - The HBar spending plan object. */ - async findById(id: string, requestIdPrefix: string): Promise { + async findById(id: string, requestDetails: RequestDetails): Promise { const key = this.getKey(id); - const plan = await this.cache.getAsync(key, 'findById', requestIdPrefix); + const plan = await this.cache.getAsync(key, 'findById', requestDetails); if (!plan) { throw new HbarSpendingPlanNotFoundError(id); } @@ -69,25 +71,27 @@ export class HbarSpendingPlanRepository { } /** - * Gets a hbar spending plan by ID with detailed information (spendingHistory and spentToday). - * @param id - The ID of the plan. - * @returns {Promise} - The detailed hbar spending plan object. + * Gets an HBar spending plan by ID with detailed information (spendingHistory and spentToday). + * @param {string} id - The ID of the plan. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. + * @returns {Promise} - The detailed HBar spending plan object. */ - async findByIdWithDetails(id: string, requestIdPrefix: string): Promise { - const plan = await this.findById(id, requestIdPrefix); + async findByIdWithDetails(id: string, requestDetails: RequestDetails): Promise { + const plan = await this.findById(id, requestDetails); return new HbarSpendingPlan({ ...plan, spendingHistory: [], - spentToday: await this.getSpentToday(id, requestIdPrefix), + spentToday: await this.getSpentToday(id, requestDetails), }); } /** - * Creates a new hbar spending plan. - * @param subscriptionType - The subscription type of the plan to create. - * @returns {Promise} - The created hbar spending plan object. + * Creates a new HBar spending plan. + * @param {SubscriptionType} subscriptionType - The subscription type of the plan to create. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. + * @returns {Promise} - The created HBar spending plan object. */ - async create(subscriptionType: SubscriptionType, requestIdPrefix: string): Promise { + async create(subscriptionType: SubscriptionType, requestDetails: RequestDetails): Promise { const plan: IDetailedHbarSpendingPlan = { id: uuidV4(randomBytes(16)), subscriptionType, @@ -98,29 +102,31 @@ export class HbarSpendingPlanRepository { }; this.logger.trace(`Creating HbarSpendingPlan with ID ${plan.id}...`); const key = this.getKey(plan.id); - await this.cache.set(key, plan, 'create', requestIdPrefix, this.threeMonthsInMillis); + await this.cache.set(key, plan, 'create', requestDetails, this.threeMonthsInMillis); return new HbarSpendingPlan(plan); } /** - * Verify that an hbar spending plan exists and is active. - * @param id - The ID of the plan. + * Verify that an HBar spending plan exists and is active. + * @param {string} id - The ID of the plan. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves if the plan exists and is active, or rejects if not. */ - async checkExistsAndActive(id: string, requestIdPrefix: string): Promise { - const plan = await this.findById(id, requestIdPrefix); + async checkExistsAndActive(id: string, requestDetails: RequestDetails): Promise { + const plan = await this.findById(id, requestDetails); if (!plan.active) { throw new HbarSpendingPlanNotActiveError(id); } } /** - * Gets the spending history for a hbar spending plan. - * @param id - The ID of the plan. + * Gets the spending history for an HBar spending plan. + * @param {string} id - The ID of the plan. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves with the spending history. */ - async getSpendingHistory(id: string, requestIdPrefix: string): Promise { - await this.checkExistsAndActive(id, requestIdPrefix); + async getSpendingHistory(id: string, requestDetails: RequestDetails): Promise { + await this.checkExistsAndActive(id, requestDetails); this.logger.trace(`Retrieving spending history for HbarSpendingPlan with ID ${id}...`); const key = this.getSpendingHistoryKey(id); @@ -129,37 +135,39 @@ export class HbarSpendingPlanRepository { 0, -1, 'getSpendingHistory', - requestIdPrefix, + requestDetails, ); return spendingHistory.map((entry) => new HbarSpendingRecord(entry)); } /** * Adds spending to a plan's spending history. - * @param id - The ID of the plan. - * @param amount - The amount to add to the plan's spending. + * @param {string} id - The ID of the plan. + * @param {number} amount - The amount to add to the plan's spending. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves with the new length of the spending history. */ - async addAmountToSpendingHistory(id: string, amount: number, requestIdPrefix: string): Promise { - await this.checkExistsAndActive(id, requestIdPrefix); + async addAmountToSpendingHistory(id: string, amount: number, requestDetails: RequestDetails): Promise { + await this.checkExistsAndActive(id, requestDetails); this.logger.trace(`Adding ${amount} to spending history for HbarSpendingPlan with ID ${id}...`); const key = this.getSpendingHistoryKey(id); const entry: IHbarSpendingRecord = { amount, timestamp: new Date() }; - return this.cache.rPush(key, entry, 'addAmountToSpendingHistory', requestIdPrefix); + return this.cache.rPush(key, entry, 'addAmountToSpendingHistory', requestDetails); } /** - * Gets the amount spent today for an hbar spending plan. - * @param id - The ID of the plan. + * Gets the amount spent today for an HBar spending plan. + * @param {string} id - The ID of the plan. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves with the amount spent today. */ - async getSpentToday(id: string, requestIdPrefix: string): Promise { - await this.checkExistsAndActive(id, requestIdPrefix); + async getSpentToday(id: string, requestDetails: RequestDetails): Promise { + await this.checkExistsAndActive(id, requestDetails); this.logger.trace(`Retrieving spentToday for HbarSpendingPlan with ID ${id}...`); const key = this.getSpentTodayKey(id); - return this.cache.getAsync(key, 'getSpentToday', requestIdPrefix).then((spentToday) => parseInt(spentToday ?? '0')); + return this.cache.getAsync(key, 'getSpentToday', requestDetails).then((spentToday) => parseInt(spentToday ?? '0')); } /** @@ -176,36 +184,38 @@ export class HbarSpendingPlanRepository { /** * Adds an amount to the amount spent today for a plan. - * @param id - The ID of the plan. - * @param amount - The amount to add. + * @param {string} id - The ID of the plan. + * @param {number} amount - The amount to add. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves when the operation is complete. */ - async addAmountToSpentToday(id: string, amount: number, requestIdPrefix: string): Promise { - await this.checkExistsAndActive(id, requestIdPrefix); + async addAmountToSpentToday(id: string, amount: number, requestDetails: RequestDetails): Promise { + await this.checkExistsAndActive(id, requestDetails); const key = this.getSpentTodayKey(id); - if (!(await this.cache.getAsync(key, 'addAmountToSpentToday', requestIdPrefix))) { + if (!(await this.cache.getAsync(key, 'addAmountToSpentToday', requestDetails))) { this.logger.trace(`No spending yet for HbarSpendingPlan with ID ${id}, setting spentToday to ${amount}...`); - await this.cache.set(key, amount, 'addAmountToSpentToday', requestIdPrefix, this.oneDayInMillis); + await this.cache.set(key, amount, 'addAmountToSpentToday', requestDetails, this.oneDayInMillis); } else { this.logger.trace(`Adding ${amount} to spentToday for HbarSpendingPlan with ID ${id}...`); - await this.cache.incrBy(key, amount, 'addAmountToSpentToday', requestIdPrefix); + await this.cache.incrBy(key, amount, 'addAmountToSpentToday', requestDetails); } } /** - * Finds all active hbar spending plans by subscription type. + * Finds all active HBar spending plans by subscription type. * @param {SubscriptionType} subscriptionType - The subscription type to filter by. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves with the active spending plans. */ async findAllActiveBySubscriptionType( subscriptionType: SubscriptionType, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { const callerMethod = this.findAllActiveBySubscriptionType.name; - const keys = await this.cache.keys(`${this.collectionKey}:*`, callerMethod, requestIdPrefix); + const keys = await this.cache.keys(`${this.collectionKey}:*`, callerMethod, requestDetails); const plans = await Promise.all( - keys.map((key) => this.cache.getAsync(key, callerMethod, requestIdPrefix)), + keys.map((key) => this.cache.getAsync(key, callerMethod, requestDetails)), ); return Promise.all( plans @@ -216,7 +226,7 @@ export class HbarSpendingPlanRepository { ...plan, createdAt: new Date(plan.createdAt), spendingHistory: [], - spentToday: await this.getSpentToday(plan.id, requestIdPrefix), + spentToday: await this.getSpentToday(plan.id, requestDetails), }), ), ); diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index c777434377..2cc266b8ca 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -21,13 +21,13 @@ import crypto from 'crypto'; import { Logger } from 'pino'; import { Eth } from '../index'; -import { Utils } from './../utils'; +import { Utils } from '../utils'; import constants from './constants'; import { Precheck } from './precheck'; import { MirrorNodeClient } from './clients'; import { Counter, Registry } from 'prom-client'; import { IAccountInfo } from './types/mirrorNode'; -import { LogsBloomUtils } from './../logsBloomUtils'; +import { LogsBloomUtils } from '../logsBloomUtils'; import { DebugService } from './services/debugService'; import { SDKClientError } from './errors/SDKClientError'; import { Transaction as EthersTransaction } from 'ethers'; @@ -235,17 +235,17 @@ export class EthImpl implements Eth { private readonly ethExecutionsCounter: Counter; /** - * The Common Service implemntation that contains logic shared by other services. + * The Common Service implementation that contains logic shared by other services. */ private readonly common: CommonService; /** - * The Filter Service implemntation that takes care of all filter API operations. + * The Filter Service implementation that takes care of all filter API operations. */ private readonly filterServiceImpl: FilterService; /** - * The Debug Service implemntation that takes care of all filter API operations. + * The Debug Service implementation that takes care of all filter API operations. */ private readonly debugServiceImpl: DebugService; @@ -441,7 +441,7 @@ export class EthImpl implements Eth { rewardPercentiles: Array | null, requestDetails: RequestDetails, ): Promise { - // include newest block number in the total block count + // include the newest block number in the total block count const oldestBlockNumber = Math.max(0, newestBlockNumber - blockCount + 1); const shouldIncludeRewards = Array.isArray(rewardPercentiles) && rewardPercentiles.length > 0; const feeHistory: IFeeHistory = { @@ -697,8 +697,8 @@ export class EthImpl implements Eth { /** * Perform value format precheck before making contract call towards the mirror node - * @param transaction - * @param requestIdPrefix + * @param {IContractCallRequest} transaction the transaction object + * @param {RequestDetails} requestDetails the request details for logging and tracking */ async contractCallFormat(transaction: IContractCallRequest, requestDetails: RequestDetails): Promise { if (transaction.value) { @@ -877,10 +877,10 @@ export class EthImpl implements Eth { /** * Gets the value from a storage position at the given Ethereum address. * - * @param address - * @param slot - * @param blockNumberOrTagOrHash - * @param requestIdPrefix + * @param {string} address The Ethereum address to get the storage value from + * @param {string} slot The storage slot to get the value from + * @param {RequestDetails} requestDetails The request details for logging and tracking + * @param {string | null} blockNumberOrTagOrHash The block number or tag or hash to get the storage value from */ async getStorageAt( address: string, @@ -934,9 +934,9 @@ export class EthImpl implements Eth { * Gets the balance of an account as of the given block from the mirror node. * Current implementation does not yet utilize blockNumber * - * @param account - * @param blockNumberOrTagOrHash - * @param requestIdPrefix + * @param {string} account The account to get the balance from + * @param {string | null} blockNumberOrTagOrHash The block number or tag or hash to get the balance from + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getBalance( account: string, @@ -1101,9 +1101,9 @@ export class EthImpl implements Eth { /** * Gets the smart contract code for the contract at the given Ethereum address. * - * @param address - * @param blockNumber - * @param requestIdPrefix + * @param {string} address The Ethereum address of the contract + * @param {string | null} blockNumber The block number to get the contract code from + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getCode(address: string, blockNumber: string | null, requestDetails: RequestDetails): Promise { const requestIdPrefix = requestDetails.formattedRequestId; @@ -1209,9 +1209,9 @@ export class EthImpl implements Eth { /** * Gets the block with the given hash. * - * @param hash - * @param showDetails - * @param requestIdPrefix + * @param {string} hash the block hash + * @param {boolean} showDetails whether to show the details of the block + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getBlockByHash(hash: string, showDetails: boolean, requestDetails: RequestDetails): Promise { const requestIdPrefix = requestDetails.formattedRequestId; @@ -1231,9 +1231,9 @@ export class EthImpl implements Eth { /** * Gets the block by its block number. - * @param blockNumOrTag Possible values are earliest/pending/latest or hex, and can't be null (validator check). - * @param showDetails - * @param requestIdPrefix + * @param {string} blockNumOrTag Possible values are earliest/pending/latest or hex, and can't be null (validator check). + * @param {boolean} showDetails whether to show the details of the block + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getBlockByNumber( blockNumOrTag: string, @@ -1264,8 +1264,8 @@ export class EthImpl implements Eth { /** * Gets the number of transaction in a block by its block hash. * - * @param hash - * @param requestIdPrefix + * @param {string} hash The block hash + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getBlockTransactionCountByHash(hash: string, requestDetails: RequestDetails): Promise { const requestIdPrefix = requestDetails.formattedRequestId; @@ -1297,8 +1297,8 @@ export class EthImpl implements Eth { /** * Gets the number of transaction in a block by its block number. - * @param blockNumOrTag - * @param requestIdPrefix + * @param {string} blockNumOrTag Possible values are earliest/pending/latest or hex + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getBlockTransactionCountByNumber( blockNumOrTag: string, @@ -1338,9 +1338,9 @@ export class EthImpl implements Eth { /** * Gets the transaction in a block by its block hash and transactions index. * - * @param blockHash - * @param transactionIndex - * @param requestIdPrefix + * @param {string} blockHash The block hash + * @param {string} transactionIndex The transaction index + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getTransactionByBlockHashAndIndex( blockHash: string, @@ -1369,9 +1369,9 @@ export class EthImpl implements Eth { /** * Gets the transaction in a block by its block hash and transactions index. * - * @param blockNumOrTag - * @param transactionIndex - * @param requestIdPrefix + * @param {string} blockNumOrTag Possible values are earliest/pending/latest or hex + * @param {string} transactionIndex The transaction index + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getTransactionByBlockNumberAndIndex( blockNumOrTag: string, @@ -1402,11 +1402,11 @@ export class EthImpl implements Eth { * Gets the number of transactions that have been executed for the given address. * This goes to the consensus nodes to determine the ethereumNonce. * - * Queries mirror node for best effort and fallsback to consensus node for contracts until HIP 729 is implemented. + * Queries mirror node for best effort and falls back to consensus node for contracts until HIP 729 is implemented. * - * @param address - * @param blockNumOrTag - * @param requestIdPrefix + * @param {string} address The account address + * @param {string | null} blockNumOrTag Possible values are earliest/pending/latest or hex + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getTransactionCount( address: string, @@ -1431,7 +1431,7 @@ export class EthImpl implements Eth { return EthImpl.zeroHex; } else if (this.common.blockTagIsLatestOrPending(blockNumOrTag)) { // if latest or pending, get latest ethereumNonce from mirror node account API - nonceCount = await this.getAccountLatestEthereumNonce(address, requestIdPrefix); + nonceCount = await this.getAccountLatestEthereumNonce(address, requestDetails); } else if (blockNumOrTag === EthImpl.blockEarliest) { nonceCount = await this.getAccountNonceForEarliestBlock(requestDetails); } else if (!isNaN(blockNum) && blockNumOrTag.length != EthImpl.blockHashLength && blockNum > 0) { @@ -1444,7 +1444,7 @@ export class EthImpl implements Eth { } } else { // if no block consideration, get latest ethereumNonce from mirror node if account or from consensus node is contract until HIP 729 is implemented - nonceCount = await this.getAccountLatestEthereumNonce(address, requestIdPrefix); + nonceCount = await this.getAccountLatestEthereumNonce(address, requestDetails); } const cacheTtl = @@ -1472,11 +1472,11 @@ export class EthImpl implements Eth { `${requestDetails.formattedRequestId} sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, ); - await this.precheck.sendRawTransactionCheck(parsedTx, networkGasPriceInWeiBars, requestDetails.formattedRequestId); + await this.precheck.sendRawTransactionCheck(parsedTx, networkGasPriceInWeiBars, requestDetails); return parsedTx; } catch (e: any) { this.logger.warn( - `${requestIdPrefix} Error on precheck sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, + `${requestDetails.formattedRequestId} Error on precheck sendRawTransaction(from=${originatingAddress}, to=${interactingEntity}, transaction=${transaction})`, ); throw this.common.genericErrorHandler(e); } @@ -1488,7 +1488,7 @@ export class EthImpl implements Eth { transactionBuffer, txSubmitted, parsedTx, - requestDetails, + requestDetails: RequestDetails, ): Promise { this.logger.error( e, @@ -1551,8 +1551,8 @@ export class EthImpl implements Eth { /** * Submits a transaction to the network for execution. * - * @param transaction - * @param requestId + * @param {string} transaction The raw transaction to submit + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async sendRawTransaction(transaction: string, requestDetails: RequestDetails): Promise { const requestIdPrefix = requestDetails.formattedRequestId; @@ -1632,7 +1632,8 @@ export class EthImpl implements Eth { if (fileId) { this.hapiService .getSDKClient() - .deleteFile(fileId, requestDetails, EthImpl.ethSendRawTransaction, fileId.toString(), originalCallerAddress); + .deleteFile(fileId, requestDetails, EthImpl.ethSendRawTransaction, fileId.toString(), originalCallerAddress) + .then(); } } } @@ -1640,9 +1641,9 @@ export class EthImpl implements Eth { /** * Execute a free contract call query. * - * @param call {IContractCallRequest} The contract call request data. - * @param blockParam either a string (blockNumber or blockTag) or an object (blockHash or blockNumber) - * @param requestIdPrefix optional request ID prefix for logging. + * @param {IContractCallRequest} call The contract call request data. + * @param {string | object | null} blockParam either a string (blockNumber or blockTag) or an object (blockHash or blockNumber) + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async call( call: IContractCallRequest, @@ -1669,7 +1670,7 @@ export class EthImpl implements Eth { await this.performCallChecks(call); // Get a reasonable value for "gas" if it is not specified. - const gas = this.getCappedBlockGasLimit(call.gas?.toString(), requestIdPrefix); + const gas = this.getCappedBlockGasLimit(call.gas?.toString(), requestDetails); await this.contractCallFormat(call, requestDetails); @@ -1709,10 +1710,12 @@ export class EthImpl implements Eth { /** * Gets transactions by block hash or block number and index with resolved EVM addresses - * @param blockParam - * @param transactionIndex - * @param requestIdPrefix - * @returns Promise + * @param {object} blockParam The block parameter + * @param {string} blockParam.title Possible values are 'blockHash' and 'blockNumber' + * @param {string | number} blockParam.value The block hash or block number + * @param {string} transactionIndex + * @param {RequestDetails} requestDetails The request details for logging and tracking + * @returns {Promise} The transaction or null if not found */ private async getTransactionByBlockHashOrBlockNumAndIndex( blockParam: { @@ -1722,7 +1725,6 @@ export class EthImpl implements Eth { transactionIndex: string, requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.formattedRequestId; const contractResults = await this.mirrorNodeClient.getContractResults( requestDetails, { @@ -1734,7 +1736,7 @@ export class EthImpl implements Eth { if (!contractResults[0]) return null; - const resolvedToAddress = await this.resolveEvmAddress(contractResults[0].to, requestIdPrefix); + const resolvedToAddress = await this.resolveEvmAddress(contractResults[0].to, requestDetails); const resolvedFromAddress = await this.resolveEvmAddress(contractResults[0].from, requestDetails, [ constants.TYPE_ACCOUNT, ]); @@ -1767,7 +1769,7 @@ export class EthImpl implements Eth { } // if blockParam is a string, could be a blockNumber or blockTag or blockHash - if (typeof blockParam === 'string' && blockParam.length > 0) { + if (blockParam.length > 0) { // if string is a blockHash, we return its corresponding blockNumber if (EthImpl.isBlockHash(blockParam)) { return await this.getBlockNumberFromHash(blockParam, requestDetails); @@ -1814,7 +1816,7 @@ export class EthImpl implements Eth { ...(block !== null ? { block } : {}), }; - const contractCallResponse = await this.mirrorNodeClient.postContractCall(callData, requestIdPrefix); + const contractCallResponse = await this.mirrorNodeClient.postContractCall(callData, requestDetails); return contractCallResponse?.result ? prepend0x(contractCallResponse.result) : EthImpl.emptyHex; } catch (e: any) { if (e instanceof JsonRpcError) { @@ -1861,9 +1863,9 @@ export class EthImpl implements Eth { /** * Execute a contract call query to the consensus node * - * @param call - * @param gas - * @param requestIdPrefix + * @param call The contract call request data + * @param {number | null} gas The gas to pass for the call + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async callConsensusNode( call: any, @@ -1903,7 +1905,7 @@ export class EthImpl implements Eth { } const cacheKey = `${constants.CACHE_KEY.ETH_CALL}:${call.from || ''}.${call.to}.${data}`; - const cachedResponse = await this.cacheService.getAsync(cacheKey, EthImpl.ethCall, requestDetails.requestIdPrefix); + const cachedResponse = await this.cacheService.getAsync(cacheKey, EthImpl.ethCall, requestDetails); if (cachedResponse != undefined) { this.logger.debug(`${requestIdPrefix} eth_call returned cached response: ${cachedResponse}`); @@ -1984,13 +1986,13 @@ export class EthImpl implements Eth { * Gets a transaction by the provided hash * * @param hash - * @param requestIdPrefix + * @param requestDetails */ async getTransactionByHash(hash: string, requestDetails: RequestDetails): Promise { const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} getTransactionByHash(hash=${hash})`, hash); - const contractResult = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestIdPrefix); + const contractResult = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestDetails); if (contractResult === null || contractResult.hash === undefined) { // handle synthetic transactions const syntheticLogs = await this.common.getLogsWithParams( @@ -2017,7 +2019,7 @@ export class EthImpl implements Eth { } const fromAddress = await this.resolveEvmAddress(contractResult.from, requestDetails, [constants.TYPE_ACCOUNT]); - const toAddress = await this.resolveEvmAddress(contractResult.to, requestIdPrefix); + const toAddress = await this.resolveEvmAddress(contractResult.to, requestDetails); contractResult.chain_id = contractResult.chain_id || this.chain; return formatContractResult({ @@ -2030,8 +2032,8 @@ export class EthImpl implements Eth { /** * Gets a receipt for a transaction that has already executed. * - * @param hash - * @param requestIdPrefix + * @param {string} hash The transaction hash + * @param {RequestDetails} requestDetails The request details for logging and tracking */ async getTransactionReceipt(hash: string, requestDetails: RequestDetails): Promise { const requestIdPrefix = requestDetails.formattedRequestId; @@ -2046,7 +2048,7 @@ export class EthImpl implements Eth { return cachedResponse; } - const receiptResponse = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestIdPrefix); + const receiptResponse = await this.mirrorNodeClient.getContractResultWithRetry(hash, requestDetails); if (receiptResponse === null || receiptResponse.hash === undefined) { // handle synthetic transactions const syntheticLogs = await this.common.getLogsWithParams( @@ -2112,8 +2114,8 @@ export class EthImpl implements Eth { const receipt: ITransactionReceipt = { blockHash: toHash32(receiptResponse.block_hash), blockNumber: numberTo0x(receiptResponse.block_number), - from: await this.resolveEvmAddress(receiptResponse.from, requestIdPrefix), - to: await this.resolveEvmAddress(receiptResponse.to, requestIdPrefix), + from: await this.resolveEvmAddress(receiptResponse.from, requestDetails), + to: await this.resolveEvmAddress(receiptResponse.to, requestDetails), cumulativeGasUsed: numberTo0x(receiptResponse.block_gas_used), gasUsed: nanOrNumberTo0x(receiptResponse.gas_used), contractAddress: receiptResponse.address, @@ -2210,7 +2212,7 @@ export class EthImpl implements Eth { } } - private getCappedBlockGasLimit(gasString: string | undefined, requestIdPrefix: string): number | null { + private getCappedBlockGasLimit(gasString: string | undefined, requestDetails: RequestDetails): number | null { if (!gasString) { // Return null and don't include in the mirror node call, as mirror is doing this estimation on the go. return null; @@ -2221,7 +2223,7 @@ export class EthImpl implements Eth { const gas = Number.parseInt(gasString); if (gas > constants.MAX_GAS_PER_SEC) { this.logger.trace( - `${requestIdPrefix} eth_call gas amount (${gas}) exceeds network limit, capping gas to ${constants.MAX_GAS_PER_SEC}`, + `${requestDetails.formattedRequestId} eth_call gas amount (${gas}) exceeds network limit, capping gas to ${constants.MAX_GAS_PER_SEC}`, ); return constants.MAX_GAS_PER_SEC; } @@ -2264,16 +2266,15 @@ export class EthImpl implements Eth { * Then using the block timerange get all contract results to get transaction details. * If showDetails is set to true subsequently call mirror node for additional transaction details * - * @param blockHashOrNumber - * @param showDetails - * @param requestIdPrefix + * @param {string} blockHashOrNumber The block hash or block number + * @param {boolean} showDetails Whether to show transaction details + * @param {RequestDetails} requestDetails The request details for logging and tracking */ private async getBlock( blockHashOrNumber: string, showDetails: boolean, requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.formattedRequestId; const blockResponse = await this.common.getHistoricalBlockResponse(requestDetails, blockHashOrNumber, true); if (blockResponse == null) return null; @@ -2305,7 +2306,7 @@ export class EthImpl implements Eth { let transactionArray: any[] = []; for (const contractResult of contractResults) { contractResult.from = await this.resolveEvmAddress(contractResult.from, requestDetails, [constants.TYPE_ACCOUNT]); - contractResult.to = await this.resolveEvmAddress(contractResult.to, requestIdPrefix); + contractResult.to = await this.resolveEvmAddress(contractResult.to, requestDetails); contractResult.chain_id = contractResult.chain_id || this.chain; transactionArray.push(showDetails ? formatContractResult(contractResult) : contractResult.hash); @@ -2379,8 +2380,8 @@ export class EthImpl implements Eth { return numberTo0x(block.count); } - private async getAccountLatestEthereumNonce(address: string, requestId: string): Promise { - const accountData = await this.mirrorNodeClient.getAccount(address, requestId); + private async getAccountLatestEthereumNonce(address: string, requestDetails: RequestDetails): Promise { + const accountData = await this.mirrorNodeClient.getAccount(address, requestDetails); if (accountData) { // with HIP 729 ethereum_nonce should always be 0+ and null. Historical contracts may have a null value as the nonce was not tracked, return default EVM compliant 0x1 in this case return accountData.ethereum_nonce !== null ? numberTo0x(accountData.ethereum_nonce) : EthImpl.oneHex; @@ -2393,19 +2394,19 @@ export class EthImpl implements Eth { * Returns the number of transactions sent from an address by searching for the ethereum transaction involving the address * Remove when https://github.com/hashgraph/hedera-mirror-node/issues/5862 is implemented * - * @param address string - * @param blockNumOrHash - * @param requestIdPrefix - * @returns string + * @param {string} address The account address + * @param {string | number} blockNumOrHash The block number or hash + * @param {RequestDetails} requestDetails The request details for logging and tracking + * @returns {Promise} The number of transactions sent from the address */ private async getAcccountNonceFromContractResult( address: string, - blockNumOrHash: any, + blockNumOrHash: string | number, requestDetails: RequestDetails, ): Promise { const requestIdPrefix = requestDetails.formattedRequestId; // get block timestamp for blockNum - const block = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestIdPrefix); // consider caching error responses + const block = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestDetails); // consider caching error responses if (block == null) { throw predefined.UNKNOWN_BLOCK(); } @@ -2438,20 +2439,20 @@ export class EthImpl implements Eth { ); } - const accountResult = await this.mirrorNodeClient.getAccount(transactionResult.from, requestIdPrefix); + const accountResult = await this.mirrorNodeClient.getAccount(transactionResult.from, requestDetails); if (accountResult.evm_address !== address.toLowerCase()) { this.logger.warn( `${requestIdPrefix} eth_transactionCount for a historical block was requested where address: ${address} was not sender: ${transactionResult.address}, returning latest value as best effort.`, ); - return await this.getAccountLatestEthereumNonce(address, requestIdPrefix); + return await this.getAccountLatestEthereumNonce(address, requestDetails); } return numberTo0x(transactionResult.nonce + 1); // nonce is 0 indexed } private async getAccountNonceForEarliestBlock(requestDetails: RequestDetails): Promise { - const block = await this.mirrorNodeClient.getEarliestBlock(requestDetails.formattedRequestId); + const block = await this.mirrorNodeClient.getEarliestBlock(requestDetails); if (block == null) { throw predefined.INTERNAL_ERROR('No network blocks found'); } @@ -2470,28 +2471,27 @@ export class EthImpl implements Eth { blockNumOrHash: number | string, requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = requestDetails.formattedRequestId; let getBlock; - const isParamBlockNum = typeof blockNumOrHash === 'number' ? true : false; + const isParamBlockNum = typeof blockNumOrHash === 'number'; if (isParamBlockNum && (blockNumOrHash as number) < 0) { throw predefined.UNKNOWN_BLOCK(); } if (!isParamBlockNum) { - getBlock = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestIdPrefix); + getBlock = await this.mirrorNodeClient.getBlock(blockNumOrHash, requestDetails); } const blockNum = isParamBlockNum ? blockNumOrHash : getBlock.number; // check if on latest block, if so get latest ethereumNonce from mirror node account API - const blockResponse = await this.mirrorNodeClient.getLatestBlock(requestIdPrefix); // consider caching error responses + const blockResponse = await this.mirrorNodeClient.getLatestBlock(requestDetails); // consider caching error responses if (blockResponse == null || blockResponse.blocks.length === 0) { throw predefined.UNKNOWN_BLOCK(); } if (blockResponse.blocks[0].number - blockNum <= this.maxBlockRange) { - return this.getAccountLatestEthereumNonce(address, requestIdPrefix); + return this.getAccountLatestEthereumNonce(address, requestDetails); } // if valid block number, get block timestamp @@ -2506,7 +2506,7 @@ export class EthImpl implements Eth { topics: any[] | null, requestDetails: RequestDetails, ): Promise { - return this.common.getLogs(blockHash, fromBlock, toBlock, address, topics, requestDetails.formattedRequestId); + return this.common.getLogs(blockHash, fromBlock, toBlock, address, topics, requestDetails); } async maxPriorityFeePerGas(requestDetails: RequestDetails): Promise { diff --git a/packages/relay/src/lib/poller.ts b/packages/relay/src/lib/poller.ts index 7f73957704..61f84c00c2 100644 --- a/packages/relay/src/lib/poller.ts +++ b/packages/relay/src/lib/poller.ts @@ -21,7 +21,7 @@ import { Eth } from '../index'; import { Logger } from 'pino'; import { Registry, Gauge } from 'prom-client'; -import { IRequestDetails } from './types/RequestDetails'; +import { RequestDetails } from './types/RequestDetails'; import { Utils } from '../utils'; export interface Poll { @@ -33,15 +33,15 @@ export interface Poll { const LOGGER_PREFIX = 'Poller:'; export class Poller { - private eth: Eth; - private logger: Logger; + private readonly eth: Eth; + private readonly logger: Logger; private polls: Poll[]; private interval?: NodeJS.Timer; private latestBlock?: string; - private pollingInterval: number; - private newHeadsEnabled: boolean; - private activePollsGauge: Gauge; - private activeNewHeadsPollsGauge: Gauge; + private readonly pollingInterval: number; + private readonly newHeadsEnabled: boolean; + private readonly activePollsGauge: Gauge; + private readonly activeNewHeadsPollsGauge: Gauge; private NEW_HEADS_EVENT = 'newHeads'; @@ -85,18 +85,16 @@ export class Poller { 'latest', filters?.address || null, filters?.topics || null, - { - requestIdPrefix: `[Request ID: ${Utils.generateRequestId()}]`, - requestIp: '', - } as IRequestDetails, + new RequestDetails({ requestId: Utils.generateRequestId(), ipAddress: '' }), ); poll.lastPolled = this.latestBlock; } else if (event === this.NEW_HEADS_EVENT && this.newHeadsEnabled) { - data = await this.eth.getBlockByNumber('latest', filters?.includeTransactions ?? false, { - requestIdPrefix: `[Request ID: ${Utils.generateRequestId()}]`, - requestIp: '0.0.0.0', - } as IRequestDetails); + data = await this.eth.getBlockByNumber( + 'latest', + filters?.includeTransactions ?? false, + new RequestDetails({ requestId: Utils.generateRequestId(), ipAddress: '' }), + ); data.jsonrpc = '2.0'; poll.lastPolled = this.latestBlock; } else { @@ -123,10 +121,9 @@ export class Poller { start() { this.logger.info(`${LOGGER_PREFIX} Starting polling with interval=${this.pollingInterval}`); this.interval = setInterval(async () => { - this.latestBlock = await this.eth.blockNumber({ - requestIdPrefix: `[Request ID: ${Utils.generateRequestId()}]`, - requestIp: '0.0.0.0', - } as IRequestDetails); + this.latestBlock = await this.eth.blockNumber( + new RequestDetails({ requestId: Utils.generateRequestId(), ipAddress: '' }), + ); this.poll(); }, this.pollingInterval); } diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index 28c93b551c..745d093a7a 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -24,7 +24,8 @@ import { EthImpl } from './eth'; import { Logger } from 'pino'; import constants from './constants'; import { ethers, Transaction } from 'ethers'; -import { formatRequestIdMessage, prepend0x } from '../formatters'; +import { prepend0x } from '../formatters'; +import { RequestDetails } from './types/RequestDetails'; /** * Precheck class for handling various prechecks before sending a raw transaction. @@ -69,32 +70,34 @@ export class Precheck { * Sends a raw transaction after performing various prechecks. * @param {ethers.Transaction} parsedTx - The parsed transaction. * @param {number} networkGasPriceInWeiBars - The predefined gas price of the network in weibar. - * @param {string} [requestId] - The request ID. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - async sendRawTransactionCheck(parsedTx: ethers.Transaction, gasPrice: number, requestId: string): Promise { - this.transactionType(parsedTx, requestId); - this.gasLimit(parsedTx, requestId); - const mirrorAccountInfo = await this.verifyAccount(parsedTx, requestId); - this.nonce(parsedTx, mirrorAccountInfo.ethereum_nonce, requestId); - this.chainId(parsedTx, requestId); + async sendRawTransactionCheck( + parsedTx: ethers.Transaction, + networkGasPriceInWeiBars: number, + requestDetails: RequestDetails, + ): Promise { + this.transactionType(parsedTx, requestDetails); + this.gasLimit(parsedTx, requestDetails); + const mirrorAccountInfo = await this.verifyAccount(parsedTx, requestDetails); + this.nonce(parsedTx, mirrorAccountInfo.ethereum_nonce, requestDetails); + this.chainId(parsedTx, requestDetails); this.value(parsedTx); - this.gasPrice(parsedTx, networkGasPriceInWeiBars, requestId); - this.balance(parsedTx, mirrorAccountInfo, requestId); + this.gasPrice(parsedTx, networkGasPriceInWeiBars, requestDetails.formattedRequestId); + this.balance(parsedTx, mirrorAccountInfo, requestDetails); } /** * Verifies the account. * @param {Transaction} tx - The transaction. - * @param {string} [requestId] - The request ID. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A Promise. */ - async verifyAccount(tx: Transaction, requestId: string): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); - // verify account - const accountInfo = await this.mirrorNodeClient.getAccount(tx.from!, requestId); + async verifyAccount(tx: Transaction, requestDetails: RequestDetails): Promise { + const accountInfo = await this.mirrorNodeClient.getAccount(tx.from!, requestDetails); if (accountInfo == null) { this.logger.trace( - `${requestIdPrefix} Failed to retrieve address '${ + `${requestDetails.formattedRequestId} Failed to retrieve address '${ tx.from }' account details from mirror node on verify account precheck for sendRawTransaction(transaction=${JSON.stringify( tx, @@ -110,12 +113,11 @@ export class Precheck { * Checks the nonce of the transaction. * @param {Transaction} tx - The transaction. * @param {number} accountInfoNonce - The nonce of the account. - * @param {string} [requestId] - The request ID. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - nonce(tx: Transaction, accountInfoNonce: number, requestId?: string): void { - const requestIdPrefix = formatRequestIdMessage(requestId); + nonce(tx: Transaction, accountInfoNonce: number, requestDetails: RequestDetails): void { this.logger.trace( - `${requestIdPrefix} Nonce precheck for sendRawTransaction(tx.nonce=${tx.nonce}, accountInfoNonce=${accountInfoNonce})`, + `${requestDetails.formattedRequestId} Nonce precheck for sendRawTransaction(tx.nonce=${tx.nonce}, accountInfoNonce=${accountInfoNonce})`, ); if (accountInfoNonce > tx.nonce) { @@ -126,15 +128,14 @@ export class Precheck { /** * Checks the chain ID of the transaction. * @param {Transaction} tx - The transaction. - * @param {string} [requestId] - The request ID. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - chainId(tx: Transaction, requestId?: string): void { - const requestIdPrefix = formatRequestIdMessage(requestId); + chainId(tx: Transaction, requestDetails: RequestDetails): void { const txChainId = prepend0x(Number(tx.chainId).toString(16)); const passes = this.isLegacyUnprotectedEtx(tx) || txChainId === this.chain; if (!passes) { this.logger.trace( - `${requestIdPrefix} Failed chainId precheck for sendRawTransaction(transaction=%s, chainId=%s)`, + `${requestDetails.formattedRequestId} Failed chainId precheck for sendRawTransaction(transaction=%s, chainId=%s)`, JSON.stringify(tx), txChainId, ); @@ -159,8 +160,7 @@ export class Precheck { * @param {number} networkGasPriceInWeiBars - The predefined gas price of the network in weibar. * @param {string} [requestId] - The request ID. */ - gasPrice(tx: Transaction, networkGasPriceInWeiBars: number, requestId?: string): void { - const requestIdPrefix = formatRequestIdMessage(requestId); + gasPrice(tx: Transaction, networkGasPriceInWeiBars: number, requestDetails: RequestDetails): void { const networkGasPrice = BigInt(networkGasPriceInWeiBars); const txGasPrice = tx.gasPrice || tx.maxFeePerGas! + tx.maxPriorityFeePerGas!; @@ -182,7 +182,7 @@ export class Precheck { } this.logger.trace( - `${requestIdPrefix} Failed gas price precheck for sendRawTransaction(transaction=%s, gasPrice=%s, requiredGasPrice=%s)`, + `${requestDetails.formattedRequestId} Failed gas price precheck for sendRawTransaction(transaction=%s, gasPrice=%s, requiredGasPrice=%s)`, JSON.stringify(tx), txGasPrice, networkGasPrice, @@ -204,10 +204,9 @@ export class Precheck { * Checks the balance of the sender account. * @param {Transaction} tx - The transaction. * @param {any} account - The account information. - * @param {string} [requestId] - The request ID. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - balance(tx: Transaction, account: any, requestId?: string): void { - const requestIdPrefix = formatRequestIdMessage(requestId); + balance(tx: Transaction, account: any, requestDetails: RequestDetails): void { const result = { passes: false, error: predefined.INSUFFICIENT_ACCOUNT_BALANCE, @@ -217,7 +216,9 @@ export class Precheck { if (account == null) { this.logger.trace( - `${requestIdPrefix} Failed to retrieve account details from mirror node on balance precheck for sendRawTransaction(transaction=${JSON.stringify( + `${ + requestDetails.formattedRequestId + } Failed to retrieve account details from mirror node on balance precheck for sendRawTransaction(transaction=${JSON.stringify( tx, )}, totalValue=${txTotalValue})`, ); @@ -230,7 +231,7 @@ export class Precheck { result.passes = tinybars >= txTotalValue; } catch (error: any) { this.logger.trace( - `${requestIdPrefix} Error on balance precheck for sendRawTransaction(transaction=%s, totalValue=%s, error=%s)`, + `${requestDetails.formattedRequestId} Error on balance precheck for sendRawTransaction(transaction=%s, totalValue=%s, error=%s)`, JSON.stringify(tx), txTotalValue, error.message, @@ -245,7 +246,7 @@ export class Precheck { if (!result.passes) { this.logger.trace( - `${requestIdPrefix} Failed balance precheck for sendRawTransaction(transaction=%s, totalValue=%s, accountTinyBarBalance=%s)`, + `${requestDetails.formattedRequestId} Failed balance precheck for sendRawTransaction(transaction=%s, totalValue=%s, accountTinyBarBalance=%s)`, JSON.stringify(tx), txTotalValue, tinybars, @@ -257,10 +258,9 @@ export class Precheck { /** * Checks the gas limit of the transaction. * @param {Transaction} tx - The transaction. - * @param {string} [requestId] - The request ID. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ - gasLimit(tx: Transaction, requestId?: string): void { - const requestIdPrefix = formatRequestIdMessage(requestId); + gasLimit(tx: Transaction, requestDetails: RequestDetails): void { const gasLimit = Number(tx.gasLimit); const failBaseLog = 'Failed gasLimit precheck for sendRawTransaction(transaction=%s).'; @@ -268,7 +268,7 @@ export class Precheck { if (gasLimit > constants.MAX_GAS_PER_SEC) { this.logger.trace( - `${requestIdPrefix} ${failBaseLog} Gas Limit was too high: %s, block gas limit: %s`, + `${requestDetails.formattedRequestId} ${failBaseLog} Gas Limit was too high: %s, block gas limit: %s`, JSON.stringify(tx), gasLimit, constants.MAX_GAS_PER_SEC, @@ -276,7 +276,7 @@ export class Precheck { throw predefined.GAS_LIMIT_TOO_HIGH(gasLimit, constants.MAX_GAS_PER_SEC); } else if (gasLimit < intrinsicGasCost) { this.logger.trace( - `${requestIdPrefix} ${failBaseLog} Gas Limit was too low: %s, intrinsic gas cost: %s`, + `${requestDetails.formattedRequestId} ${failBaseLog} Gas Limit was too low: %s, intrinsic gas cost: %s`, JSON.stringify(tx), gasLimit, intrinsicGasCost, @@ -345,12 +345,11 @@ export class Precheck { } } - transactionType(tx: Transaction, requestId?: string) { + transactionType(tx: Transaction, requestDetails: RequestDetails) { // Blob transactions are not supported as per HIP 866 if (tx.type === 3) { - const requestIdPrefix = formatRequestIdMessage(requestId); this.logger.trace( - `${requestIdPrefix} Transaction with type=${ + `${requestDetails.formattedRequestId} Transaction with type=${ tx.type } is unsupported for sendRawTransaction(transaction=${JSON.stringify(tx)})`, ); diff --git a/packages/relay/src/lib/relay.ts b/packages/relay/src/lib/relay.ts index ff856997b7..2d87cafbe3 100644 --- a/packages/relay/src/lib/relay.ts +++ b/packages/relay/src/lib/relay.ts @@ -39,6 +39,8 @@ import HAPIService from './services/hapiService/hapiService'; import { SubscriptionController } from './subscriptionController'; import MetricService from './services/metricService/metricService'; import { CacheService } from './services/cacheService/cacheService'; +import { RequestDetails } from './types/RequestDetails'; +import { Utils } from '../utils'; export class RelayImpl implements Relay { /** @@ -181,7 +183,7 @@ export class RelayImpl implements Relay { mirrorNodeClient: MirrorNodeClient, logger: Logger, register: Registry, - ) { + ): Gauge { const metricGaugeName = 'rpc_relay_operator_balance'; register.removeSingleMetric(metricGaugeName); return new Gauge({ @@ -193,7 +195,10 @@ export class RelayImpl implements Relay { // Invoked when the registry collects its metrics' values. // Allows for updated account balance tracking try { - const account = await mirrorNodeClient.getAccount(clientMain.operatorAccountId!.toString(), ''); + const account = await mirrorNodeClient.getAccount( + clientMain.operatorAccountId!.toString(), + new RequestDetails({ requestId: Utils.generateRequestId(), ipAddress: '' }), + ); const accountBalance = account.balance?.balance; this.labels({ accountId: clientMain.operatorAccountId?.toString() }).set(accountBalance); } catch (e: any) { diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts index e13a7acabc..e2dc8e3e78 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts @@ -20,24 +20,24 @@ import { JsonRpcError } from '../../../errors/JsonRpcError'; import { Log } from '../../../model'; -import { IRequestDetails } from '../../../types/RequestDetails'; +import { RequestDetails } from '../../../types/RequestDetails'; export interface IFilterService { newFilter( fromBlock: string, toBlock: string, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, address?: string, topics?: any[], ): Promise; - newBlockFilter(requestDetails: IRequestDetails): Promise; + newBlockFilter(requestDetails: RequestDetails): Promise; - uninstallFilter(filterId: string, requestDetails: IRequestDetails): Promise; + uninstallFilter(filterId: string, requestDetails: RequestDetails): Promise; - newPendingTransactionFilter(requestDetails: IRequestDetails): JsonRpcError; + newPendingTransactionFilter(requestDetails: RequestDetails): JsonRpcError; - getFilterLogs(filterId: string, requestDetails: IRequestDetails): Promise; + getFilterLogs(filterId: string, requestDetails: RequestDetails): Promise; - getFilterChanges(filterId: string, requestDetails: IRequestDetails): Promise; + getFilterChanges(filterId: string, requestDetails: RequestDetails): Promise; } diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts index 1fd2527125..f5d842029a 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts @@ -120,7 +120,7 @@ export class FilterService implements IFilterService { requestDetails: RequestDetails, address?: string, topics?: any[], - ): Promise { + ): Promise { const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace( `${requestIdPrefix} newFilter(fromBlock=${fromBlock}, toBlock=${toBlock}, address=${address}, topics=${topics})`, @@ -149,7 +149,7 @@ export class FilterService implements IFilterService { } } - async newBlockFilter(requestDetails: RequestDetails): Promise { + async newBlockFilter(requestDetails: RequestDetails): Promise { const requestIdPrefix = requestDetails.formattedRequestId; this.logger.trace(`${requestIdPrefix} newBlockFilter()`); try { diff --git a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts index 6406c970da..8f22313fc3 100644 --- a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts +++ b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts @@ -18,13 +18,15 @@ * */ +import { RequestDetails } from '../../types/RequestDetails'; + export interface IHbarLimitService { resetLimiter(): Promise; shouldLimit( mode: string, methodName: string, ethAddress: string, - requestId: string, + requestDetails: RequestDetails, ipAddress?: string, estimatedTxFee?: number, ): Promise; diff --git a/packages/relay/src/lib/services/hbarLimitService/index.ts b/packages/relay/src/lib/services/hbarLimitService/index.ts index 92e3dda5b5..d58e298f6a 100644 --- a/packages/relay/src/lib/services/hbarLimitService/index.ts +++ b/packages/relay/src/lib/services/hbarLimitService/index.ts @@ -27,6 +27,7 @@ import { IDetailedHbarSpendingPlan } from '../../db/types/hbarLimiter/hbarSpendi import { HbarSpendingPlanRepository } from '../../db/repositories/hbarLimiter/hbarSpendingPlanRepository'; import { EthAddressHbarSpendingPlanRepository } from '../../db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository'; import { IPAddressHbarSpendingPlanRepository } from '../../db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository'; +import { RequestDetails } from '../../types/RequestDetails'; export class HbarLimitService implements IHbarLimitService { static readonly ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000; @@ -161,20 +162,19 @@ export class HbarLimitService implements IHbarLimitService { * @param {string} methodName - The name of the method being invoked. * @param {string} ethAddress - The eth address to check. * @param {string} [ipAddress] - The ip address to check. - * @param {string} [requestId] - A prefix to include in log messages (optional). * @param {number} [estimatedTxFee] - The total estimated transaction fee, default to 0. + * @param {RequestDetails} requestDetails The request details for logging and tracking. * @returns {Promise} - A promise that resolves with a boolean indicating if the address should be limited. */ async shouldLimit( mode: string, methodName: string, ethAddress: string, - requestId: string, + requestDetails: RequestDetails, ipAddress?: string, estimatedTxFee: number = 0, ): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); - if (await this.isDailyBudgetExceeded(mode, methodName, estimatedTxFee, requestIdPrefix)) { + if (await this.isDailyBudgetExceeded(mode, methodName, estimatedTxFee, requestDetails)) { return true; } if (!ethAddress && !ipAddress) { @@ -182,18 +182,18 @@ export class HbarLimitService implements IHbarLimitService { return false; } const user = `(ethAddress=${ethAddress}, ipAddress=${ipAddress})`; - this.logger.trace(`${requestIdPrefix} Checking if ${user} should be limited...`); - let spendingPlan = await this.getSpendingPlan(ethAddress, requestIdPrefix, ipAddress); + this.logger.trace(`${requestDetails.formattedRequestId} Checking if ${user} should be limited...`); + let spendingPlan = await this.getSpendingPlan(ethAddress, ipAddress, requestDetails); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address - spendingPlan = await this.createBasicSpendingPlan(ethAddress, requestIdPrefix, ipAddress); + spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress, requestDetails); } const dailyLimit = HbarLimitService.DAILY_LIMITS[spendingPlan.subscriptionType]; const exceedsLimit = spendingPlan.spentToday >= dailyLimit || spendingPlan.spentToday + estimatedTxFee > dailyLimit; this.logger.trace( - `${requestIdPrefix} ${user} ${exceedsLimit ? 'should' : 'should not'} be limited: spentToday=${ + `${requestDetails.formattedRequestId} ${user} ${exceedsLimit ? 'should' : 'should not'} be limited, spentToday=${ spendingPlan.spentToday }, estimatedTxFee=${estimatedTxFee}, dailyLimit=${dailyLimit}`, ); @@ -204,25 +204,25 @@ export class HbarLimitService implements IHbarLimitService { * Add expense to the remaining budget. * @param {number} cost - The cost of the expense. * @param {string} ethAddress - The Ethereum address to add the expense to. - * @param {string} [ipAddress] - The optional IP address to add the expense to. - * @param {string} [requestId] - An optional unique request ID for tracking the request. + * @param {string} ipAddress - The optional IP address to add the expense to. + * @param {RequestDetails} requestDetails The request details for logging and tracking. * @returns {Promise} - A promise that resolves when the expense has been added. */ - async addExpense(cost: number, ethAddress: string, requestIdPrefix: string, ipAddress?: string): Promise { + async addExpense(cost: number, ethAddress: string, ipAddress: string, requestDetails: RequestDetails): Promise { if (!ethAddress && !ipAddress) { throw new Error('Cannot add expense without an eth address or ip address'); } - let spendingPlan = await this.getSpendingPlan(ethAddress, requestIdPrefix, ipAddress); + let spendingPlan = await this.getSpendingPlan(ethAddress, ipAddress, requestDetails); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address - spendingPlan = await this.createBasicSpendingPlan(ethAddress, requestIdPrefix, ipAddress); + spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress, requestDetails); } this.logger.trace( - `${requestIdPrefix} Adding expense of ${cost} to spending plan with ID ${spendingPlan.id}, new spentToday=${ - spendingPlan.spentToday + cost - }`, + `${requestDetails.formattedRequestId} Adding expense of ${cost} to spending plan with ID ${ + spendingPlan.id + }, new spentToday=${spendingPlan.spentToday + cost}`, ); // Check if the spending plan is being used for the first time today @@ -230,15 +230,15 @@ export class HbarLimitService implements IHbarLimitService { this.dailyUniqueSpendingPlansCounter[spendingPlan.subscriptionType].inc(1); } - await this.hbarSpendingPlanRepository.addAmountToSpentToday(spendingPlan.id, cost, requestIdPrefix); + await this.hbarSpendingPlanRepository.addAmountToSpentToday(spendingPlan.id, cost, requestDetails); this.remainingBudget -= cost; this.hbarLimitRemainingGauge.set(this.remainingBudget); // Done asynchronously in the background - this.updateAverageDailyUsagePerSubscriptionType(spendingPlan.subscriptionType, requestIdPrefix).then(); + this.updateAverageDailyUsagePerSubscriptionType(spendingPlan.subscriptionType, requestDetails).then(); this.logger.trace( - `${requestIdPrefix} HBAR rate limit expense update: cost=${cost}, remainingBudget=${this.remainingBudget}`, + `${requestDetails.formattedRequestId} HBAR rate limit expense update: cost=${cost}, remainingBudget=${this.remainingBudget}`, ); } @@ -247,7 +247,7 @@ export class HbarLimitService implements IHbarLimitService { * @param {string} mode - The mode of the transaction or request. * @param {string} methodName - The name of the method being invoked. * @param {number} estimatedTxFee - The total estimated transaction fee, default to 0. - * @param {string} [requestIdPrefix] - An optional prefix to include in log messages. + * @param {RequestDetails} requestDetails The request details for logging and tracking * @returns {Promise} - Resolves `true` if the daily budget has been exceeded, otherwise `false`. * @private */ @@ -255,7 +255,7 @@ export class HbarLimitService implements IHbarLimitService { mode: string, methodName: string, estimatedTxFee: number = 0, - requestIdPrefix?: string, + requestDetails: RequestDetails, ): Promise { if (this.shouldResetLimiter()) { await this.resetLimiter(); @@ -263,12 +263,12 @@ export class HbarLimitService implements IHbarLimitService { if (this.remainingBudget <= 0 || this.remainingBudget - estimatedTxFee < 0) { this.hbarLimitCounter.labels(mode, methodName).inc(1); this.logger.warn( - `${requestIdPrefix} HBAR rate limit incoming call: remainingBudget=${this.remainingBudget}, totalBudget=${this.totalBudget}, estimatedTxFee=${estimatedTxFee}, resetTimestamp=${this.reset}`, + `${requestDetails.formattedRequestId} HBAR rate limit incoming call: remainingBudget=${this.remainingBudget}, totalBudget=${this.totalBudget}, resetTimestamp=${this.reset}`, ); return true; } else { this.logger.trace( - `${requestIdPrefix} HBAR rate limit not reached: remainingBudget=${this.remainingBudget}, totalBudget=${this.totalBudget}, estimatedTxFee=${estimatedTxFee} resetTimestamp=${this.reset}.`, + `${requestDetails.formattedRequestId} HBAR rate limit not reached. ${this.remainingBudget} out of ${this.totalBudget} tℏ left in relay budget until ${this.reset}.`, ); return false; } @@ -277,15 +277,16 @@ export class HbarLimitService implements IHbarLimitService { /** * Updates the average daily usage per subscription type. * @param {SubscriptionType} subscriptionType - The subscription type to update the average daily usage for. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @private {Promise} - A promise that resolves when the average daily usage has been updated. */ private async updateAverageDailyUsagePerSubscriptionType( subscriptionType: SubscriptionType, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { const plans = await this.hbarSpendingPlanRepository.findAllActiveBySubscriptionType( subscriptionType, - requestIdPrefix, + requestDetails, ); const totalUsage = plans.reduce((total, plan) => total + plan.spentToday, 0); const averageUsage = Math.round(totalUsage / plans.length); @@ -334,20 +335,24 @@ export class HbarLimitService implements IHbarLimitService { /** * Gets the spending plan for the given eth address or ip address. * @param {string} ethAddress - The eth address to get the spending plan for. - * @param {string} [ipAddress] - The ip address to get the spending plan for. + * @param {string} ipAddress - The ip address to get the spending plan for. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves with the spending plan or null if none exists. * @private */ private async getSpendingPlan( ethAddress: string, - requestIdPrefix: string, - ipAddress?: string, + ipAddress: string, + requestDetails: RequestDetails, ): Promise { if (ethAddress) { try { - return await this.getSpendingPlanByEthAddress(ethAddress, requestIdPrefix); + return await this.getSpendingPlanByEthAddress(ethAddress, requestDetails); } catch (error) { - this.logger.warn(error, `Failed to get spending plan for eth address '${ethAddress}'`); + this.logger.warn( + error, + `${requestDetails.formattedRequestId} Failed to get spending plan for eth address '${ethAddress}'`, + ); } } if (ipAddress) { @@ -363,18 +368,19 @@ export class HbarLimitService implements IHbarLimitService { /** * Gets the spending plan for the given eth address. * @param {string} ethAddress - The eth address to get the spending plan for. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves with the spending plan. * @private */ private async getSpendingPlanByEthAddress( ethAddress: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ): Promise { const ethAddressHbarSpendingPlan = await this.ethAddressHbarSpendingPlanRepository.findByAddress( ethAddress, - requestIdPrefix, + requestDetails, ); - return this.hbarSpendingPlanRepository.findByIdWithDetails(ethAddressHbarSpendingPlan.planId, requestIdPrefix); + return this.hbarSpendingPlanRepository.findByIdWithDetails(ethAddressHbarSpendingPlan.planId, requestDetails); } /** @@ -391,18 +397,20 @@ export class HbarLimitService implements IHbarLimitService { /** * Creates a basic spending plan for the given eth address. * @param {string} ethAddress - The eth address to create the spending plan for. - * @param {string} [ipAddress] - The ip address to create the spending plan for. + * @param {string} ipAddress - The ip address to create the spending plan for. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves with the created spending plan. * @private */ private async createBasicSpendingPlan( ethAddress: string, - requstIdPrefix: string, - ipAddress?: string, + ipAddress: string, + requestDetails: RequestDetails, ): Promise { if (!ethAddress && !ipAddress) { throw new Error('Cannot create a spending plan without an associated eth address or ip address'); } +<<<<<<< HEAD const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC, requstIdPrefix); if (ethAddress) { @@ -412,6 +420,29 @@ export class HbarLimitService implements IHbarLimitService { if (ipAddress) { this.logger.trace(`Linking spending plan with ID ${spendingPlan.id} to ip address ${ipAddress}`); await this.ipAddressHbarSpendingPlanRepository.save({ ipAddress, planId: spendingPlan.id }); +======= +<<<<<<< HEAD +<<<<<<< HEAD + const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC); + +======= + const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC, requstIdPrefix); +>>>>>>> 171fcf4c (Makes requestId required in all methods of cacheService) +======= + const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC, requestDetails); +>>>>>>> ca55f87f (chore: draft changes) + if (ethAddress) { + this.logger.trace( + `${requestDetails.formattedRequestId} Linking spending plan with ID ${spendingPlan.id} to eth address ${ethAddress}`, + ); + await this.ethAddressHbarSpendingPlanRepository.save({ ethAddress, planId: spendingPlan.id }, requestDetails); + } else if (ipAddress) { + this.logger.trace( + `${requestDetails.formattedRequestId} Linking spending plan with ID ${spendingPlan.id} to ip address ${ipAddress}`, + ); + // TODO: Implement this with https://github.com/hashgraph/hedera-json-rpc-relay/issues/2888 + // await this.ipAddressHbarSpendingPlanRepository.save({ ipAddress, planId: spendingPlan.id }); +>>>>>>> 6ec726a8 (chore: draft changes) } return spendingPlan; } diff --git a/packages/relay/src/lib/services/metricService/metricService.ts b/packages/relay/src/lib/services/metricService/metricService.ts index def76e4448..689c04b523 100644 --- a/packages/relay/src/lib/services/metricService/metricService.ts +++ b/packages/relay/src/lib/services/metricService/metricService.ts @@ -24,7 +24,6 @@ import constants from '../../constants'; import HbarLimit from '../../hbarlimiter'; import { Histogram, Registry } from 'prom-client'; import { MirrorNodeClient, SDKClient } from '../../clients'; -import { formatRequestIdMessage } from '../../../formatters'; import { ITransactionRecordMetric, IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../../types'; import { RequestDetails } from '../../types/RequestDetails'; @@ -114,7 +113,7 @@ export default class MetricService { this.consensusNodeClientHistogramGasFee = this.initGasMetric(register); this.eventEmitter.on(constants.EVENTS.EXECUTE_TRANSACTION, (args: IExecuteTransactionEventPayload) => { - this.captureTransactionMetrics(args); + this.captureTransactionMetrics(args).then(); }); this.eventEmitter.on(constants.EVENTS.EXECUTE_QUERY, (args: IExecuteQueryEventPayload) => { @@ -127,28 +126,28 @@ export default class MetricService { * and recording the transaction fees, gas usage, and other relevant metrics. * * @param {IExecuteTransactionEventPayload} payload - The payload object containing transaction details. - * @param {string} payload.requestId - The unique identifier for the request. * @param {string} payload.callerName - The name of the entity calling the transaction. * @param {string} payload.transactionId - The unique identifier for the transaction. * @param {string} payload.txConstructorName - The name of the transaction constructor. * @param {string} payload.operatorAccountId - The account ID of the operator managing the transaction. * @param {string} payload.interactingEntity - The entity interacting with the transaction. + * @param {RequestDetails} payload.requestDetails - The request details for logging and tracking. * @returns {Promise} - A promise that resolves when the transaction metrics have been captured. */ public async captureTransactionMetrics({ - requestId, callerName, transactionId, txConstructorName, operatorAccountId, interactingEntity, + requestDetails, }: IExecuteTransactionEventPayload): Promise { const transactionRecordMetrics = await this.getTransactionRecordMetrics( transactionId, callerName, - requestId, txConstructorName, operatorAccountId, + requestDetails, ); if (transactionRecordMetrics) { @@ -163,7 +162,7 @@ export default class MetricService { gasUsed, interactingEntity, status, - requestDetails: requestId, + requestDetails, } as IExecuteQueryEventPayload); } @@ -177,7 +176,7 @@ export default class MetricService { gasUsed: 0, interactingEntity, status, - requestDetails: requestId, + requestDetails, } as IExecuteQueryEventPayload); } } @@ -195,7 +194,7 @@ export default class MetricService { * @param {number} payload.gasUsed - The amount of gas used during the transaction. * @param {string} payload.interactingEntity - The entity interacting with the transaction. * @param {string} payload.status - The entity interacting with the transaction. - * @param {string} payload.requestId - The unique identifier for the request. + * @param {string} payload.requestDetails - The request details for logging and tracking. * @returns {void} - This method does not return a value. */ public addExpenseAndCaptureMetrics = ({ @@ -209,33 +208,14 @@ export default class MetricService { status, requestDetails, }: IExecuteQueryEventPayload): void => { - const formattedRequestId = formatRequestIdMessage(requestDetails); this.logger.trace( - `${formattedRequestId} Capturing HBAR charged: executionMode=${executionMode} transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, cost=${cost} tinybars`, + `${requestDetails.formattedRequestId} Capturing HBAR charged: executionMode=${executionMode} transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, cost=${cost} tinybars`, ); this.hbarLimiter.addExpense(cost, Date.now(), requestDetails); this.captureMetrics(executionMode, txConstructorName, status, cost, gasUsed, callerName, interactingEntity); }; - /** - * Retrieves the cost metric for consensus node client operations. - * - * @returns {Histogram} - The histogram metric tracking the cost of consensus node client operations. - */ - private getCostMetric(): Histogram { - return this.consensusNodeClientHistogramCost; - } - - /** - * Retrieves the gas fee metric for consensus node client operations. - * - * @returns {Histogram} - The histogram metric tracking the gas fees of consensus node client operations. - */ - private getGasFeeMetric(): Histogram { - return this.consensusNodeClientHistogramGasFee; - } - /** * Initialize consensus node cost metrics * @param {Registry} register diff --git a/packages/relay/src/lib/types/RequestDetails.ts b/packages/relay/src/lib/types/RequestDetails.ts index 7058a3adcc..81899932f6 100644 --- a/packages/relay/src/lib/types/RequestDetails.ts +++ b/packages/relay/src/lib/types/RequestDetails.ts @@ -18,8 +18,6 @@ * */ -import { formatRequestIdMessage } from '../../formatters'; - export class RequestDetails { requestId: string; ipAddress: string; @@ -30,6 +28,6 @@ export class RequestDetails { } get formattedRequestId(): string { - return formatRequestIdMessage(this.requestId); + return `[Request ID: ${this.requestId}]`; } } diff --git a/packages/relay/tests/lib/clients/localLRUCache.spec.ts b/packages/relay/tests/lib/clients/localLRUCache.spec.ts index 97c52d554c..86a711a747 100644 --- a/packages/relay/tests/lib/clients/localLRUCache.spec.ts +++ b/packages/relay/tests/lib/clients/localLRUCache.spec.ts @@ -24,7 +24,6 @@ import { Registry } from 'prom-client'; import pino from 'pino'; import { LocalLRUCache } from '../../../src/lib/clients'; import constants from '../../../src/lib/constants'; -import { IRequestDetails } from '../../../dist/lib/types/IRequestDetails'; const logger = pino(); const registry = new Registry(); diff --git a/packages/relay/tests/lib/eth/eth_call.spec.ts b/packages/relay/tests/lib/eth/eth_call.spec.ts index 2db0f09f07..1508a7a13c 100644 --- a/packages/relay/tests/lib/eth/eth_call.spec.ts +++ b/packages/relay/tests/lib/eth/eth_call.spec.ts @@ -43,7 +43,7 @@ import { ONE_TINYBAR_IN_WEI_HEX, EXAMPLE_CONTRACT_BYTECODE, } from './eth-config'; -import { JsonRpcError, predefined } from '../../../src/lib/errors/JsonRpcError'; +import { JsonRpcError, predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import constants from '../../../src/lib/constants'; import { @@ -55,14 +55,15 @@ import { mockData, } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; -import { IContractCallRequest, IContractCallResponse } from '../../../src/lib/types/IMirrorNode'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { IContractCallRequest, IContractCallResponse } from '../../../src/lib/types'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { ContractFunctionResult } from '@hashgraph/sdk'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; describe('@ethCall Eth Call spec', async function () { @@ -76,16 +77,12 @@ describe('@ethCall Eth Call spec', async function () { gas: MAX_GAS_LIMIT_HEX, }; - let requestDetails: IRequestDetails; - let requestIdPrefix: string; + const requestDetails = new RequestDetails({ requestId: 'eth_callTest', ipAddress: '0.0.0.0' }); - this.beforeEach(() => { + this.beforeEach(async () => { // reset cache and restMock - cacheService.clear(); + await cacheService.clear(requestDetails); restMock.reset(); - - requestIdPrefix = `[Request ID: testId]`; - requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -137,7 +134,7 @@ describe('@ethCall Eth Call spec', async function () { }, 'latest', requestDetails, - (error) => { + (error: any) => { expect(error.message).to.equal( `Invalid Contract Address: ${EthImpl.zeroHex}. Expected length of 42 chars but was 3.`, ); @@ -250,26 +247,26 @@ describe('@ethCall Eth Call spec', async function () { }); describe('eth_call using consensus node', async function () { - let initialEthCallConesneusFF; + let initialEthCallDefaultsToConsensus: string | undefined; before(() => { - initialEthCallConesneusFF = process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE; + initialEthCallDefaultsToConsensus = process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE; process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = 'true'; }); after(() => { - process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallConesneusFF; + process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallDefaultsToConsensus; }); it('eth_call with no gas', async function () { restMock.onGet(`contracts/${ACCOUNT_ADDRESS_1}`).reply(404); restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - sdkClientStub.submitContractCallQueryWithRetry.returns({ + sdkClientStub.submitContractCallQueryWithRetry.resolves({ asBytes: function () { return Uint8Array.of(0); }, - }); + } as unknown as ContractFunctionResult); const result = await ethImpl.call( { @@ -294,11 +291,11 @@ describe('@ethCall Eth Call spec', async function () { it('eth_call with no data', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - sdkClientStub.submitContractCallQueryWithRetry.returns({ + sdkClientStub.submitContractCallQueryWithRetry.resolves({ asBytes: function () { return Uint8Array.of(0); }, - }); + } as unknown as ContractFunctionResult); const result = await ethImpl.call( { @@ -331,11 +328,11 @@ describe('@ethCall Eth Call spec', async function () { }; restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - sdkClientStub.submitContractCallQueryWithRetry.returns({ + sdkClientStub.submitContractCallQueryWithRetry.resolves({ asBytes: function () { return Uint8Array.of(0); }, - }); + } as unknown as ContractFunctionResult); const result = await ethImpl.call(callData, 'latest', requestDetails); expect(result).to.equal('0x00'); @@ -360,11 +357,11 @@ describe('@ethCall Eth Call spec', async function () { it('eth_call with all fields', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - sdkClientStub.submitContractCallQueryWithRetry.returns({ + sdkClientStub.submitContractCallQueryWithRetry.resolves({ asBytes: function () { return Uint8Array.of(0); }, - }); + } as unknown as ContractFunctionResult); const result = await ethImpl.call(ETH_CALL_REQ_ARGS, 'latest', requestDetails); @@ -382,11 +379,11 @@ describe('@ethCall Eth Call spec', async function () { //Return once the value, then it's being fetched from cache. After the loop we reset the sdkClientStub, so that it returns nothing, if we get an error in the next request that means that the cache was cleared. it('eth_call should cache the response for 200ms', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - sdkClientStub.submitContractCallQueryWithRetry.returns({ + sdkClientStub.submitContractCallQueryWithRetry.resolves({ asBytes: function () { return Uint8Array.of(0); }, - }); + } as unknown as ContractFunctionResult); for (let index = 0; index < 3; index++) { const result = await ethImpl.call( @@ -451,7 +448,7 @@ describe('@ethCall Eth Call spec', async function () { it('eth_call throws internal error when consensus node times out and submitContractCallQueryWithRetry returns undefined', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); - sdkClientStub.submitContractCallQueryWithRetry.returns(undefined); + sdkClientStub.submitContractCallQueryWithRetry.resolves(undefined); const result = await ethImpl.call( { @@ -476,7 +473,7 @@ describe('@ethCall Eth Call spec', async function () { gas: 400000, value: null, }; - let initialEthCallConesneusFF; + let initialEthCallConesneusFF: string | undefined; before(() => { initialEthCallConesneusFF = process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE; @@ -646,11 +643,11 @@ describe('@ethCall Eth Call spec', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2); await mockContractCall({ ...callData, block: 'latest' }, false, 501, mockData.notSuported, requestDetails); - sdkClientStub.submitContractCallQueryWithRetry.returns({ + sdkClientStub.submitContractCallQueryWithRetry.resolves({ asBytes: function () { return Uint8Array.of(0); }, - }); + } as unknown as ContractFunctionResult); const result = await ethImpl.call(callData, 'latest', requestDetails); @@ -812,7 +809,7 @@ describe('@ethCall Eth Call spec', async function () { estimate: boolean, statusCode: number, result: IContractCallResponse, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ) { const formattedCallData = { ...callData, estimate }; await ethImpl.contractCallFormat(formattedCallData, requestDetails); @@ -934,7 +931,8 @@ describe('@ethCall Eth Call spec', async function () { }); describe('eth_call using consensus node because of redirect by selector', async function () { - let initialEthCallConesneusFF: any, initialEthCallSelectorsAlwaysToConsensus: any; + let initialForceToConsensusBySelector: string | undefined; + let initialEthCallDefaultsToConsensus: string | undefined; const REDIRECTED_SELECTOR = '0x4d8fdd6d'; const NON_REDIRECTED_SELECTOR = '0xaaaaaaaa'; let callConsensusNodeSpy: sinon.SinonSpy; @@ -942,14 +940,15 @@ describe('@ethCall Eth Call spec', async function () { let sandbox: sinon.SinonSandbox; before(() => { - initialEthCallConesneusFF = process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE; - initialEthCallSelectorsAlwaysToConsensus = process.env.ETH_CALL_CONSENSUS_SELECTORS; + initialForceToConsensusBySelector = process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR; + initialEthCallDefaultsToConsensus = process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE; + process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR = 'true'; process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = 'false'; }); after(() => { - process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallConesneusFF; - process.env.ETH_CALL_CONSENSUS_SELECTORS = initialEthCallSelectorsAlwaysToConsensus; + process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR = initialForceToConsensusBySelector; + process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallDefaultsToConsensus; }); beforeEach(() => { diff --git a/packages/relay/tests/lib/eth/eth_common.spec.ts b/packages/relay/tests/lib/eth/eth_common.spec.ts index b9d227c9e0..a64f360c3d 100644 --- a/packages/relay/tests/lib/eth/eth_common.spec.ts +++ b/packages/relay/tests/lib/eth/eth_common.spec.ts @@ -23,24 +23,20 @@ import { expect, use } from 'chai'; import { Registry } from 'prom-client'; import pino from 'pino'; import chaiAsPromised from 'chai-as-promised'; -import { RelayImpl } from '../../../src/lib/relay'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RelayImpl } from '../../../src'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); describe('@ethCommon', async function () { - let Relay: any; - let requestIdPrefix: string; - let requestDetails: IRequestDetails; + let Relay: RelayImpl; this.timeout(10000); + const requestDetails = new RequestDetails({ requestId: 'eth_commonTest', ipAddress: '0.0.0.0' }); + this.beforeAll(() => { - requestIdPrefix = `[Request ID: eth_common]`; - requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; - const logger = pino(); - const registry = new Registry(); - Relay = new RelayImpl(logger, registry); + Relay = new RelayImpl(pino(), new Registry()); }); describe('@ethCommon', async function () { diff --git a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts index 729b297bb3..4003f3d77c 100644 --- a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts +++ b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts @@ -39,7 +39,7 @@ import { ONE_TINYBAR_IN_WEI_HEX, RECEIVER_ADDRESS, } from './eth-config'; -import { IRequestDetails } from '../../../dist/lib/types/IRequestDetails'; +import { RequestDetails } from '../../../dist/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -53,15 +53,15 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { this.timeout(10000); const { restMock, web3Mock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger, registry } = generateEthTestEnv(); - let requestIdPrefix: string; - let requestDetails: IRequestDetails; + + const requestDetails = new RequestDetails({ requestId: 'eth_estimateGasTest', ipAddress: '0.0.0.0' }); async function mockContractCall( callData: IContractCallRequest, estimate: boolean, statusCode: number, result: IContractCallResponse, - requestDetails: IRequestDetails, + requestDetails: RequestDetails, ) { const formattedData = { ...callData, estimate }; await ethImpl.contractCallFormat(formattedData, requestDetails); @@ -82,11 +82,8 @@ describe('@ethEstimateGas Estimate Gas spec', async function () { this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); - - requestIdPrefix = `[Request ID: testId]`; - requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; sdkClientStub = createStubInstance(SDKClient); getSdkClientStub = stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); ethImplOverridden = new EthImpl(hapiServiceInstance, mirrorNodeInstance, logger, '0x12a', registry, cacheService); diff --git a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts index a92c8a407e..04f29f85be 100644 --- a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts +++ b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts @@ -38,27 +38,25 @@ import { } from './eth-config'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; -import { request } from 'http'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; -let requestDetails: IRequestDetails; describe('@ethFeeHistory using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const requestDetails = new RequestDetails({ requestId: 'eth_feeHistoryTest', ipAddress: '0.0.0.0' }); + this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); - - requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -203,7 +201,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { } this.beforeEach(() => { - sdkClientStub.getTinyBarGasFee.returns(fauxGasTinyBars); + sdkClientStub.getTinyBarGasFee.resolves(fauxGasTinyBars); restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [latestBlock] }); restMock.onGet(`blocks/${latestBlock.number}`).reply(200, latestBlock); restMock.onGet(`network/fees?timestamp=lte:${latestBlock.timestamp.to}`).reply(404, NOT_FOUND_RES); @@ -244,7 +242,7 @@ describe('@ethFeeHistory using MirrorNode', async function () { }); this.beforeEach(function () { - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); restMock.onGet(`network/fees`).reply(200, DEFAULT_NETWORK_FEES); }); diff --git a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts index 177786cd89..9cb8c51cf4 100644 --- a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts +++ b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts @@ -27,31 +27,29 @@ import constants from '../../../src/lib/constants'; import { SDKClient } from '../../../src/lib/clients'; import { numberTo0x } from '../../../dist/formatters'; import { DEFAULT_NETWORK_FEES, NOT_FOUND_RES } from './eth-config'; -import { predefined } from '../../../src/lib/errors/JsonRpcError'; +import { predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import { generateEthTestEnv } from './eth-helpers'; import { toHex } from '../../helpers'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; -import { request } from 'http'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; -let requestDetails: IRequestDetails; describe('@ethGasPrice Gas Price spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const requestDetails = new RequestDetails({ requestId: 'eth_getPriceTest', ipAddress: '0.0.0.0' }); + this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); - - requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -110,7 +108,7 @@ describe('@ethGasPrice Gas Price spec', async function () { const initialGasPrice = await ethImpl.gasPrice(requestDetails); process.env.GAS_PRICE_PERCENTAGE_BUFFER = GAS_PRICE_PERCENTAGE_BUFFER; - await cacheService.clear(); + await cacheService.clear(requestDetails); const gasPriceWithBuffer = await ethImpl.gasPrice(requestDetails); process.env.GAS_PRICE_PERCENTAGE_BUFFER = '0'; @@ -141,7 +139,7 @@ describe('@ethGasPrice Gas Price spec', async function () { it('eth_gasPrice with mirror node return network fees found', async function () { const fauxGasTinyBars = 35_000; const fauxGasWeiBarHex = '0x13e52b9abe000'; - sdkClientStub.getTinyBarGasFee.returns(fauxGasTinyBars); + sdkClientStub.getTinyBarGasFee.resolves(fauxGasTinyBars); const gas = await ethImpl.gasPrice(requestDetails); expect(gas).to.equal(fauxGasWeiBarHex); diff --git a/packages/relay/tests/lib/eth/eth_getBalance.spec.ts b/packages/relay/tests/lib/eth/eth_getBalance.spec.ts index 19dbabb298..66835c4517 100644 --- a/packages/relay/tests/lib/eth/eth_getBalance.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBalance.spec.ts @@ -24,7 +24,7 @@ import sinon from 'sinon'; import chaiAsPromised from 'chai-as-promised'; import { EthImpl } from '../../../src/lib/eth'; -import { buildCryptoTransferTransaction, getRequestId } from '../../helpers'; +import { buildCryptoTransferTransaction } from '../../helpers'; import { SDKClient } from '../../../src/lib/clients'; import { numberTo0x } from '../../../dist/formatters'; import { @@ -44,21 +44,24 @@ import { TINYBAR_TO_WEIBAR_COEF_BIGINT, } from './eth-config'; import { balancesByAccountIdByTimestampURL, generateEthTestEnv } from './eth-helpers'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; describe('@ethGetBalance using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const requestDetails = new RequestDetails({ requestId: 'eth_getBalanceTest', ipAddress: '0.0.0.0' }); + this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); sdkClientStub = sinon.createStubInstance(SDKClient); @@ -78,7 +81,7 @@ describe('@ethGetBalance using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOCK_BLOCK_NUMBER_1000_RES); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(200, MOCK_BALANCE_RES); - const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, requestDetails); expect(resBalance).to.equal(DEF_HEX_BALANCE); }); @@ -86,13 +89,13 @@ describe('@ethGetBalance using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOCK_BLOCK_NUMBER_1000_RES); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(200, MOCK_BALANCE_RES); - const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, requestDetails); expect(resBalance).to.equal(DEF_HEX_BALANCE); // next call should use cache restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(404, {}); - const resBalanceCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, `[Request ID: testId]`); + const resBalanceCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, requestDetails); expect(resBalanceCached).to.equal(resBalance); // Third call should return new number using mirror node @@ -105,9 +108,9 @@ describe('@ethGetBalance using MirrorNode', async function () { }, }); // expire cache, instead of waiting for ttl we clear it to simulate expiry faster. - cacheService.clear(); + await cacheService.clear(requestDetails); - const resBalanceNew = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, getRequestId()); + const resBalanceNew = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, requestDetails); expect(newBalanceHex).to.equal(resBalanceNew); }); @@ -116,7 +119,7 @@ describe('@ethGetBalance using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOCK_BLOCKS_FOR_BALANCE_RES); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(200, MOCK_BALANCE_RES); - const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, requestDetails); expect(resBalance).to.equal(DEF_HEX_BALANCE); }); @@ -128,7 +131,7 @@ describe('@ethGetBalance using MirrorNode', async function () { }); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(200, MOCK_BALANCE_RES); - const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockHash, getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockHash, requestDetails); expect(resBalance).to.equal(DEF_HEX_BALANCE); }); @@ -137,7 +140,7 @@ describe('@ethGetBalance using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOCK_BLOCKS_FOR_BALANCE_RES); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(200, MOCK_BALANCE_RES); - const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, requestDetails); expect(resBalance).to.equal(DEF_HEX_BALANCE); }); @@ -160,7 +163,7 @@ describe('@ethGetBalance using MirrorNode', async function () { ], }); - const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockHash, getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockHash, requestDetails); expect(resBalance).to.equal(DEF_HEX_BALANCE); }); @@ -169,7 +172,7 @@ describe('@ethGetBalance using MirrorNode', async function () { restMock.onGet(`contracts/${CONTRACT_ADDRESS_1}`).reply(200, null); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(404, NOT_FOUND_RES); - const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, requestDetails); expect(resBalance).to.equal(EthImpl.zeroHex); }); @@ -177,11 +180,11 @@ describe('@ethGetBalance using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOCK_BLOCK_NUMBER_1000_RES); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(200, MOCK_BALANCE_RES); - const resNoCache = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, getRequestId()); + const resNoCache = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, requestDetails); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(404, NOT_FOUND_RES); - const resCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, getRequestId()); + const resCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, null, requestDetails); expect(resNoCache).to.equal(DEF_HEX_BALANCE); expect(resCached).to.equal(DEF_HEX_BALANCE); }); @@ -217,11 +220,11 @@ describe('@ethGetBalance using MirrorNode', async function () { }, }); - const resNoCache = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, getRequestId()); + const resNoCache = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, requestDetails); restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(404, NOT_FOUND_RES); - const resCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, getRequestId()); + const resCached = await ethImpl.getBalance(CONTRACT_ADDRESS_1, blockNumber, requestDetails); expect(resNoCache).to.equal(DEF_HEX_BALANCE); expect(resCached).to.equal(DEF_HEX_BALANCE); }); @@ -333,27 +336,27 @@ describe('@ethGetBalance using MirrorNode', async function () { }); it('latest', async () => { - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'latest', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'latest', requestDetails); expect(resBalance).to.equal(hexBalance3); }); it('finalized', async () => { - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'finalized', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'finalized', requestDetails); expect(resBalance).to.equal(hexBalance3); }); it('safe', async () => { - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'safe', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'safe', requestDetails); expect(resBalance).to.equal(hexBalance3); }); it('earliest', async () => { - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'earliest', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'earliest', requestDetails); expect(resBalance).to.equal('0x0'); }); it('pending', async () => { - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'pending', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, 'pending', requestDetails); expect(resBalance).to.equal(hexBalance3); }); @@ -387,7 +390,7 @@ describe('@ethGetBalance using MirrorNode', async function () { }, }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', requestDetails); const historicalBalance = numberTo0x(BigInt(balance3) * TINYBAR_TO_WEIBAR_COEF_BIGINT); expect(resBalance).to.equal(historicalBalance); }); @@ -402,7 +405,7 @@ describe('@ethGetBalance using MirrorNode', async function () { transactions: [], }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', requestDetails); expect(resBalance).to.equal(hexBalance1); }); @@ -433,7 +436,7 @@ describe('@ethGetBalance using MirrorNode', async function () { }, }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', requestDetails); const historicalBalance = numberTo0x(BigInt(balance3 - 175) * TINYBAR_TO_WEIBAR_COEF_BIGINT); expect(resBalance).to.equal(historicalBalance); }); @@ -465,7 +468,7 @@ describe('@ethGetBalance using MirrorNode', async function () { }, }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', requestDetails); const historicalBalance = numberTo0x(BigInt(balance3 + 175) * TINYBAR_TO_WEIBAR_COEF_BIGINT); expect(resBalance).to.equal(historicalBalance); }); @@ -498,7 +501,7 @@ describe('@ethGetBalance using MirrorNode', async function () { }, }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '2', requestDetails); const historicalBalance = numberTo0x(BigInt(balance3 + 65) * TINYBAR_TO_WEIBAR_COEF_BIGINT); expect(resBalance).to.equal(historicalBalance); }); @@ -543,7 +546,7 @@ describe('@ethGetBalance using MirrorNode', async function () { ], }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', requestDetails); const historicalBalance = numberTo0x(BigInt(balance3 - 230) * TINYBAR_TO_WEIBAR_COEF_BIGINT); expect(resBalance).to.equal(historicalBalance); }); @@ -604,7 +607,7 @@ describe('@ethGetBalance using MirrorNode', async function () { blocks: [latestBlock], }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', requestDetails); const historicalBalance = numberTo0x(BigInt(balance3 - 480) * TINYBAR_TO_WEIBAR_COEF_BIGINT); expect(resBalance).to.equal(historicalBalance); }); @@ -664,13 +667,13 @@ describe('@ethGetBalance using MirrorNode', async function () { blocks: [latestBlock], }); - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '1', requestDetails); const historicalBalance = numberTo0x(BigInt(balance3 - 80) * TINYBAR_TO_WEIBAR_COEF_BIGINT); expect(resBalance).to.equal(historicalBalance); }); it('blockNumber is the same as the latest block', async () => { - const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '3', getRequestId()); + const resBalance = await ethImpl.getBalance(CONTRACT_ID_1, '3', requestDetails); expect(resBalance).to.equal(hexBalance3); }); @@ -681,7 +684,7 @@ describe('@ethGetBalance using MirrorNode', async function () { .onGet(balancesByAccountIdByTimestampURL(notFoundEvmAddress, '1651550386.060890949')) .reply(404, NOT_FOUND_RES); - const resBalance = await ethImpl.getBalance(notFoundEvmAddress, '1', getRequestId()); + const resBalance = await ethImpl.getBalance(notFoundEvmAddress, '1', requestDetails); expect(resBalance).to.equal(EthImpl.zeroHex); }); @@ -700,7 +703,7 @@ describe('@ethGetBalance using MirrorNode', async function () { restMock.onGet(`blocks/2`).reply(200, recentBlockWithinLastfifteen); restMock.onGet(`accounts/${notFoundEvmAddress}?limit=100`).reply(404, NOT_FOUND_RES); - const resBalance = await ethImpl.getBalance(notFoundEvmAddress, '2', getRequestId()); + const resBalance = await ethImpl.getBalance(notFoundEvmAddress, '2', requestDetails); expect(resBalance).to.equal(EthImpl.zeroHex); }); }); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts index 2a3a692b9d..874d2a6595 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts @@ -23,7 +23,7 @@ import { expect, use } from 'chai'; import sinon from 'sinon'; import chaiAsPromised from 'chai-as-promised'; -import { predefined } from '../../../src/lib/errors/JsonRpcError'; +import { predefined } from '../../../src'; import { EthImpl } from '../../../src/lib/eth'; import { blockLogsBloom, defaultContractResults, defaultDetailedContractResults } from '../../helpers'; import { SDKClient } from '../../../src/lib/clients'; @@ -56,16 +56,15 @@ import { DEFAULT_BLOCK_RECEIPTS_ROOT_HASH, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; let ethImplLowTransactionCount: EthImpl; -let requestDetails: IRequestDetails; describe('@ethGetBlockByHash using MirrorNode', async function () { this.timeout(10000); @@ -74,12 +73,12 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { const results = defaultContractResults.results; const TOTAL_GAS_USED = numberTo0x(results[0].gas_used + results[1].gas_used); + const requestDetails = new RequestDetails({ requestId: 'eth_getBlockByHashTest', ipAddress: '0.0.0.0' }); + this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); - - requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -254,7 +253,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { }); it('eth_getBlockByHash with block match and contract revert', async function () { - cacheService.clear(); + await cacheService.clear(requestDetails); const randomBlock = { ...DEFAULT_BLOCK, gas_used: 400000, @@ -283,7 +282,7 @@ describe('@ethGetBlockByHash using MirrorNode', async function () { }); it('eth_getBlockByHash with no match', async function () { - cacheService.clear(); + await cacheService.clear(requestDetails); // mirror node request mocks restMock.onGet(`blocks/${BLOCK_HASH}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index f1b75132e9..3f241e7710 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -23,7 +23,7 @@ import { expect, use } from 'chai'; import sinon from 'sinon'; import chaiAsPromised from 'chai-as-promised'; -import { predefined } from '../../../src/lib/errors/JsonRpcError'; +import { predefined } from '../../../src'; import { EthImpl } from '../../../src/lib/eth'; import { blockLogsBloom, defaultContractResults, defaultDetailedContractResults } from '../../helpers'; import { Block, Transaction } from '../../../src/lib/model'; @@ -73,13 +73,13 @@ import { } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; import { fail } from 'assert'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; let ethImplLowTransactionCount: EthImpl; @@ -87,11 +87,11 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger, registry } = generateEthTestEnv(true); - const requestIdPrefix = `[Request ID: eth_getBlockByNumberTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' } as IRequestDetails; const results = defaultContractResults.results; const TOTAL_GAS_USED = numberTo0x(results[0].gas_used + results[1].gas_used); + const requestDetails = new RequestDetails({ requestId: 'eth_getBlockByNumberTest', ipAddress: '0.0.0.0' }); + const veriftAggregatedInfo = (result) => { // verify aggregated info expect(result).to.exist; @@ -109,9 +109,9 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { expect(transactions[1].gas).equal(hashNumber(GAS_USED_2)); } - this.beforeEach(() => { + this.beforeEach(async () => { // reset cache and restMock - cacheService.clear(); + await cacheService.clear(requestDetails); restMock.reset(); restMock.resetHandlers(); @@ -165,7 +165,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { expect(blockNumber2).to.be.eq(blockNumber); // expire cache, instead of waiting for ttl we clear it to simulate expiry faster. - cacheService.clear(); + await cacheService.clear(requestDetails); // Third call should return new number using mirror node const newBlockNumber = 7; restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { @@ -439,7 +439,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { } } - this.beforeEach(() => { + beforeEach(() => { restMock.resetHistory(); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); for (const result of defaultContractResults.results) { diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts index 719dd17738..c6d30ffd26 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts @@ -33,23 +33,26 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; describe('@ethGetBlockTransactionCountByHash using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: eth_getBlockTransactionCountByHashTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' } as IRequestDetails; + + const requestDetails = new RequestDetails({ + requestId: 'eth_getBlockTransactionCountByHashTest', + ipAddress: '0.0.0.0', + }); this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); sdkClientStub = sinon.createStubInstance(SDKClient); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts index 751f530bcb..8a99f4bf36 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts @@ -35,25 +35,27 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: eth_getBlockTransactionCountByNumberTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' } as IRequestDetails; - this.beforeEach(() => { + const requestDetails = new RequestDetails({ + requestId: 'eth_getBlockTransactionCountByNumberTest', + ipAddress: '0.0.0.0', + }); + + this.beforeEach(async () => { // reset cache and restMock - cacheService.clear(); + await cacheService.clear(requestDetails); restMock.reset(); - sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -82,7 +84,7 @@ describe('@ethGetBlockTransactionCountByNumber using MirrorNode', async function }); it('eth_getBlockTransactionCountByNumber with no match', async function () { - cacheService.clear(); + await cacheService.clear(requestDetails); restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(404, NO_SUCH_BLOCK_EXISTS_RES); const result = await ethImpl.getBlockTransactionCountByNumber(BLOCK_NUMBER.toString(), requestDetails); diff --git a/packages/relay/tests/lib/eth/eth_getCode.spec.ts b/packages/relay/tests/lib/eth/eth_getCode.spec.ts index 0836361b26..9cb216644e 100644 --- a/packages/relay/tests/lib/eth/eth_getCode.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getCode.spec.ts @@ -38,12 +38,13 @@ import { } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; import { JsonRpcError, predefined } from '../../../src'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; describe('@ethGetCode using MirrorNode', async function () { @@ -51,12 +52,12 @@ describe('@ethGetCode using MirrorNode', async function () { let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); let validBlockParam = [null, 'earliest', 'latest', 'pending', 'finalized', 'safe', '0x0', '0x369ABF']; let invalidBlockParam = ['hedera', 'ethereum', '0xhbar', '0x369ABF369ABF369ABF369ABF']; - const requestIdPrefix = `[Request ID: eth_getCodeTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; - this.beforeEach(() => { + const requestDetails = new RequestDetails({ requestId: 'eth_getCodeTest', ipAddress: '0.0.0.0' }); + + this.beforeEach(async () => { // reset cache and restMock - cacheService.clear(); + await cacheService.clear(requestDetails); restMock.reset(); sdkClientStub = sinon.createStubInstance(SDKClient); @@ -68,7 +69,7 @@ describe('@ethGetCode using MirrorNode', async function () { restMock.onGet(`accounts/${CONTRACT_ADDRESS_1}?limit=100`).reply(404, null); restMock.onGet(`tokens/0.0.${parseInt(CONTRACT_ADDRESS_1, 16)}`).reply(404, null); restMock.onGet(`contracts/${CONTRACT_ADDRESS_1}`).reply(200, DEFAULT_CONTRACT); - sdkClientStub.getContractByteCode.returns(Buffer.from(DEPLOYED_BYTECODE.replace('0x', ''), 'hex')); + sdkClientStub.getContractByteCode.resolves(Buffer.from(DEPLOYED_BYTECODE.replace('0x', ''), 'hex')); }); this.afterEach(() => { diff --git a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts index ccace7a1b4..7a759187da 100644 --- a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts @@ -58,12 +58,13 @@ import { } from './eth-config'; import { ethers } from 'ethers'; import { generateEthTestEnv } from './eth-helpers'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; describe('@ethGetLogs using MirrorNode', async function () { @@ -81,12 +82,11 @@ describe('@ethGetLogs using MirrorNode', async function () { logs: [DEFAULT_LOGS.logs[0], DEFAULT_LOGS.logs[1]], }; - const requestIdPrefix = `[Request ID: eth_getLogsTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; + const requestDetails = new RequestDetails({ requestId: 'eth_getLogsTest', ipAddress: '0.0.0.0' }); - this.beforeEach(() => { + beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); sdkClientStub = sinon.createStubInstance(SDKClient); @@ -96,13 +96,13 @@ describe('@ethGetLogs using MirrorNode', async function () { process.env.ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE = '1'; }); - this.afterEach(() => { + afterEach(() => { getSdkClientStub.restore(); process.env.ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE = currentMaxBlockRange.toString(); }); describe('timeout', async function () { - this.beforeEach(() => { + beforeEach(() => { restMock.onGet(`blocks/${BLOCK_HASH}`).timeout(); restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, DEFAULT_BLOCKS_RES); restMock.onGet(CONTRACTS_LOGS_WITH_FILTER).timeout(); @@ -110,14 +110,14 @@ describe('@ethGetLogs using MirrorNode', async function () { }); it('BLOCK_HASH filter timeouts and throws the expected error', async () => { - await ethGetLogsFailing(ethImpl, [BLOCK_HASH, null, null, null, null], (error) => { + await ethGetLogsFailing(ethImpl, [BLOCK_HASH, null, null, null, null], (error: any) => { expect(error.statusCode).to.equal(504); expect(error.message).to.eq('timeout of 10000ms exceeded'); }); }); it('address filter timeouts and throws the expected error', async () => { - await ethGetLogsFailing(ethImpl, [null, null, null, CONTRACT_ADDRESS_1, null], (error) => { + await ethGetLogsFailing(ethImpl, [null, null, null, CONTRACT_ADDRESS_1, null], (error: any) => { expect(error.statusCode).to.equal(504); expect(error.message).to.eq('timeout of 10000ms exceeded'); }); @@ -132,8 +132,8 @@ describe('@ethGetLogs using MirrorNode', async function () { let errorReceived = false; try { - await ethImpl.getLogs(null, null, null, null, null, requestDetails); - } catch (error) { + await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails); + } catch (error: any) { errorReceived = true; expect(error.statusCode).to.equal(400); expect(error.message).to.eq('Mocked error'); @@ -157,7 +157,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, { ...DEFAULT_CONTRACT, contract_id: `0.0.105${index}` }); }); - const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails); expect(result).to.exist; expect(result.length).to.eq(4); @@ -182,11 +182,11 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, { ...DEFAULT_CONTRACT, contract_id: `0.0.105${index}` }); }); - const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails); expect(result).to.exist; expect(result.length).to.eq(4); - result.forEach((log, index) => { + result.forEach((log, _index) => { expect(log.transactionIndex).to.be.null; }); }); @@ -230,7 +230,7 @@ describe('@ethGetLogs using MirrorNode', async function () { }); //setting mirror node limit to 2 for this test only process.env['MIRROR_NODE_LIMIT_PARAM'] = '2'; - const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails); //resetting mirror node limit to 100 process.env['MIRROR_NODE_LIMIT_PARAM'] = '100'; expect(result).to.exist; @@ -258,7 +258,7 @@ describe('@ethGetLogs using MirrorNode', async function () { .onGet(`contracts/${filteredLogs.logs[0].address}`) .reply(200, { ...DEFAULT_CONTRACT, evm_address: defaultEvmAddress }); - const result = await ethImpl.getLogs(null, null, null, null, null, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails); expect(result).to.exist; expect(result.length).to.eq(1); @@ -275,7 +275,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, CONTRACT_ADDRESS_1, null, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', CONTRACT_ADDRESS_1, null, requestDetails); expect(result).to.exist; @@ -345,11 +345,11 @@ describe('@ethGetLogs using MirrorNode', async function () { const result = await ethImpl.getLogs( null, - null, - null, + 'latest', + 'latest', [CONTRACT_ADDRESS_1, CONTRACT_ADDRESS_2], null, - requestIdPrefix, + requestDetails, ); expect(result).to.exist; @@ -372,7 +372,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(BLOCK_HASH, null, null, null, null, requestDetails); + const result = await ethImpl.getLogs(BLOCK_HASH, 'latest', 'latest', null, null, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -465,7 +465,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [latestBlock] }); restMock.onGet('blocks/5').reply(200, DEFAULT_BLOCKS_RES); - await ethGetLogsFailing(ethImpl, [null, null, '0x5', null, null], (error) => { + await ethGetLogsFailing(ethImpl, [null, null, '0x5', null, null], (error: any) => { expect(error.code).to.equal(-32011); expect(error.message).to.equal('Provided toBlock parameter without specifying fromBlock'); }); @@ -482,7 +482,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, 'latest', null, null, null, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -508,7 +508,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet('blocks/1').reply(200, fromBlock); restMock.onGet('blocks/1003').reply(200, toBlock); - await ethGetLogsFailing(ethImpl, [null, '0x1', '0x3eb', address, null, requestDetails], (error) => { + await ethGetLogsFailing(ethImpl, [null, '0x1', '0x3eb', address, null, requestDetails], (error: any) => { expect(error.message).to.equal('Exceeded maximum block range: 1000'); }); }); @@ -533,7 +533,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_LOG_TOPICS, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', null, DEFAULT_LOG_TOPICS, requestDetails); expect(result).to.exist; expectLogData1(result[0]); @@ -557,7 +557,7 @@ describe('@ethGetLogs using MirrorNode', async function () { for (const log of filteredLogs.logs) { restMock.onGet(`contracts/${log.address}`).reply(200, DEFAULT_CONTRACT); } - const result = await ethImpl.getLogs(null, null, null, null, DEFAULT_NULL_LOG_TOPICS, requestDetails); + const result = await ethImpl.getLogs(null, 'latest', 'latest', null, DEFAULT_NULL_LOG_TOPICS, requestDetails); expect(result).to.exist; expect(result[0].topics.length).to.eq(DEFAULT_LOGS_4[0].topics.length); diff --git a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts index 4716f28e18..6ef018261e 100644 --- a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts @@ -40,24 +40,24 @@ import { OLDER_BLOCK, BLOCK_HASH, } from './eth-config'; -import { predefined } from '../../../src/lib/errors/JsonRpcError'; +import { predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import { defaultDetailedContractResults } from '../../helpers'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; describe('@ethGetStorageAt eth_getStorageAt spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: eth_getStorageAtTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; + const requestDetails = new RequestDetails({ requestId: 'eth_getStorageAtTest', ipAddress: '0.0.0.0' }); function confirmResult(result: string) { expect(result).to.exist; expect(result).to.not.be.null; @@ -66,7 +66,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); sdkClientStub = sinon.createStubInstance(SDKClient); @@ -219,7 +219,7 @@ describe('@ethGetStorageAt eth_getStorageAt spec', async function () { }); // Block number is a required param, this should not work and should be removed when/if validations are added. - // Instead the relay should return `missing value for required argument error`. + // Instead, the relay should return `missing value for required argument error`. it('eth_getStorageAt with match null block', async function () { // mirror node request mocks restMock diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts index cf468fac44..77b010d530 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts @@ -21,10 +21,10 @@ import path from 'path'; import dotenv from 'dotenv'; import { expect, use } from 'chai'; import sinon from 'sinon'; -import * as _ from 'lodash'; +import _ from 'lodash'; import chaiAsPromised from 'chai-as-promised'; -import { predefined } from '../../../src/lib/errors/JsonRpcError'; +import { predefined } from '../../../src'; import { defaultContractResults, defaultDetailedContractResults } from '../../helpers'; import { Transaction, Transaction1559, Transaction2930 } from '../../../src/lib/model'; import { SDKClient } from '../../../src/lib/clients'; @@ -41,18 +41,15 @@ import { DEFAULT_NETWORK_FEES, EMPTY_RES, NOT_FOUND_RES, - ACCOUNT_ADDRESS_1, - CONTRACT_ADDRESS_2, - CONTRACT_ID_2, } from './eth-config'; import { contractResultsByHashByIndexURL, generateEthTestEnv } from './eth-helpers'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -const requestIdPrefix = `[Request ID: eth_getTransactionByBlockHashAndIndexTest]`; -const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; function verifyAggregatedInfo(result: Transaction | null) { // verify aggregated info @@ -66,11 +63,16 @@ function verifyAggregatedInfo(result: Transaction | null) { describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async function () { this.timeout(10000); - let { restMock, web3Mock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - this.beforeEach(() => { + const requestDetails = new RequestDetails({ + requestId: 'eth_getTransactionByBlockHashAndIndexTest', + ipAddress: '0.0.0.0', + }); + + this.beforeEach(async () => { // reset cache and restMock - cacheService.clear(); + await cacheService.clear(requestDetails); restMock.reset(); sdkClientStub = sinon.createStubInstance(SDKClient); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts index 8735b5e0d9..343673685e 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts @@ -24,7 +24,7 @@ import sinon from 'sinon'; import * as _ from 'lodash'; import chaiAsPromised from 'chai-as-promised'; -import { predefined } from '../../../src/lib/errors/JsonRpcError'; +import { predefined } from '../../../src'; import { defaultContractResults, defaultDetailedContractResults } from '../../helpers'; import { Transaction } from '../../../src/lib/model'; import { SDKClient } from '../../../src/lib/clients'; @@ -43,12 +43,13 @@ import { NOT_FOUND_RES, } from './eth-config'; import { contractResultsByNumberByIndexURL, generateEthTestEnv } from './eth-helpers'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; function verifyAggregatedInfo(result: Transaction | null) { // verify aggregated info @@ -65,13 +66,16 @@ function verifyAggregatedInfo(result: Transaction | null) { describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: eth_getTransactionByBlockNumberAndIndexTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; + + const requestDetails = new RequestDetails({ + requestId: 'eth_getTransactionByBlockNumberAndIndexTest', + ipAddress: '0.0.0.0', + }); + this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); - sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts index 87b8900b5b..8fdb3dbd52 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts @@ -22,11 +22,8 @@ import dotenv from 'dotenv'; import { expect, use } from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import { EthImpl } from '../../../src/lib/eth'; -import { Log, Transaction, Transaction2930, Transaction1559 } from '../../../src/lib/model'; -import constants from '../../../src/lib/constants'; +import { Transaction, Transaction2930, Transaction1559 } from '../../../src/lib/model'; import RelayAssertions from '../../assertions'; -import { nullableNumberTo0x, numberTo0x, toHash32 } from '../../../src/formatters'; import { DEFAULT_DETAILED_CONTRACT_RESULT_BY_HASH_REVERTED, DEFAULT_TRANSACTION, @@ -35,15 +32,15 @@ import { EMPTY_LOGS_RESPONSE, NO_TRANSACTIONS, } from './eth-config'; -import { defaultDetailedContractResultByHash, defaultFromLongZeroAddress, defaultLogs1 } from '../../helpers'; -import { predefined } from '../../../src'; +import { defaultDetailedContractResultByHash, defaultFromLongZeroAddress } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async function () { - let { restMock, ethImpl, cacheService } = generateEthTestEnv(); + let { restMock, ethImpl } = generateEthTestEnv(); const from = '0x00000000000000000000000000000000000003f7'; const evm_address = '0xc37f417fa09933335240fca72dd257bfbde9c275'; const contractResultMock = { @@ -78,8 +75,8 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi v: 1, nonce: 9, }; - const requestIdPrefix = `[Request ID: eth_getTransactionByHashTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; + + const requestDetails = new RequestDetails({ requestId: 'eth_getTransactionByHashTest', ipAddress: '0.0.0.0' }); this.beforeEach(function () { restMock.reset(); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts index b0e9306896..045a790e57 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts @@ -27,24 +27,25 @@ import { EthImpl } from '../../../src/lib/eth'; import constants from '../../../src/lib/constants'; import { SDKClient } from '../../../src/lib/clients'; import { DEFAULT_NETWORK_FEES, NO_TRANSACTIONS } from './eth-config'; -import { predefined } from '../../../src/lib/errors/JsonRpcError'; +import { predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import { defaultDetailedContractResults, defaultEthereumTransactions, mockData } from '../../helpers'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; describe('@ethGetTransactionCount eth_getTransactionCount spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - const requestIdPrefix = `[Request ID: eth_getTransactionCountTest]`; - const requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; + + const requestDetails = new RequestDetails({ requestId: 'eth_getTransactionCountTest', ipAddress: '0.0.0.0' }); const blockNumber = mockData.blocks.blocks[2].number; const blockNumberHex = numberTo0x(blockNumber); const transactionId = '0.0.1078@1686183420.196506746'; @@ -58,8 +59,8 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function const blockPath = `blocks/${blockNumber}`; const latestBlockPath = `blocks?limit=1&order=desc`; - function transactionPath(addresss, num) { - return `accounts/${addresss}?transactiontype=ETHEREUMTRANSACTION×tamp=lte:${mockData.blocks.blocks[2].timestamp.to}&limit=${num}&order=desc`; + function transactionPath(address: string, num: number) { + return `accounts/${address}?transactiontype=ETHEREUMTRANSACTION×tamp=lte:${mockData.blocks.blocks[2].timestamp.to}&limit=${num}&order=desc`; } this.beforeEach(() => { @@ -86,7 +87,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function restMock.resetHandlers(); process.env.ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE = currentMaxBlockRange.toString(); // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); }); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts index 90b4b5c9ff..fc718529db 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts @@ -29,8 +29,7 @@ import RelayAssertions from '../../assertions'; import { DEFAULT_BLOCK, EMPTY_LOGS_RESPONSE } from './eth-config'; import { defaultErrorMessageHex } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; -import { ITransactionReceipt } from '../../../src/lib/types/ITransactionReceipt'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -39,14 +38,12 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func this.timeout(10000); let { restMock, ethImpl, cacheService } = generateEthTestEnv(); let sandbox: sinon.SinonSandbox; - let requestDetails: IRequestDetails; - let requestIdPrefix: string; + + const requestDetails = new RequestDetails({ requestId: 'eth_getTransactionReceiptTest', ipAddress: '0.0.0.0' }); this.beforeAll(() => { // @ts-ignore sandbox = createSandbox(); - requestIdPrefix = `[Request ID: testId]`; - requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; }); const contractEvmAddress = '0xd8db0b1dbf8ba6721ef5256ad5fe07d72d1d04b9'; @@ -146,7 +143,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func this.afterEach(() => { restMock.resetHandlers(); sandbox.restore(); - cacheService.clear(); + cacheService.clear(requestDetails); }); it('returns `null` for non-existent hash', async function () { @@ -338,7 +335,7 @@ describe('@ethGetTransactionReceipt eth_getTransactionReceipt tests', async func type: defaultDetailedContractResultByHash.type, }; - cacheService.set(cacheKey, cacheReceipt, EthImpl.ethGetTransactionReceipt); + await cacheService.set(cacheKey, cacheReceipt, EthImpl.ethGetTransactionReceipt, requestDetails); // w no mirror node requests const receipt = await ethImpl.getTransactionReceipt(defaultTxHash, requestDetails); diff --git a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts index f8bf6acfbd..85f82fa688 100644 --- a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts +++ b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts @@ -22,35 +22,34 @@ import dotenv from 'dotenv'; import { expect, use } from 'chai'; import sinon from 'sinon'; import chaiAsPromised from 'chai-as-promised'; -import { Hbar, HbarUnit, TransactionId } from '@hashgraph/sdk'; +import { Hbar, HbarUnit, TransactionId, TransactionResponse } from '@hashgraph/sdk'; import { SDKClient } from '../../../src/lib/clients'; import { ACCOUNT_ADDRESS_1, DEFAULT_NETWORK_FEES, MAX_GAS_LIMIT_HEX, NO_TRANSACTIONS } from './eth-config'; -import { JsonRpcError, predefined } from '../../../src/lib/errors/JsonRpcError'; +import { JsonRpcError, predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import { getRequestId, mockData, signTransaction } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; import { SDKClientError } from '../../../src/lib/errors/SDKClientError'; -import { IRequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); -let sdkClientStub; -let getSdkClientStub; +let sdkClientStub: sinon.SinonStubbedInstance; +let getSdkClientStub: sinon.SinonStub; let currentMaxBlockRange: number; describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () { this.timeout(10000); let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); - let requestDetails: IRequestDetails; + + const requestDetails = new RequestDetails({ requestId: 'testId', ipAddress: '0.0.0.0' }); this.beforeEach(() => { // reset cache and restMock - cacheService.clear(); + cacheService.clear(requestDetails); restMock.reset(); - - requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; sdkClientStub = sinon.createStubInstance(SDKClient); getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet('network/fees').reply(200, DEFAULT_NETWORK_FEES); @@ -96,7 +95,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () }, }; - this.beforeEach(() => { + beforeEach(() => { sinon.restore(); sdkClientStub = sinon.createStubInstance(SDKClient); sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); @@ -104,7 +103,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () restMock.onGet(networkExchangeRateEndpoint).reply(200, mockedExchangeRate); }); - this.afterEach(() => { + afterEach(() => { sinon.restore(); }); @@ -136,10 +135,10 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () restMock.onGet(contractResultEndpoint).reply(404, mockData.notFound); restMock.onGet(`transactions/${transactionId}?nonce=0`).reply(200, null); - sdkClientStub.submitEthereumTransaction.returns({ + sdkClientStub.submitEthereumTransaction.resolves({ txResponse: { transactionId: '', - }, + } as unknown as TransactionResponse, fileId: null, }); @@ -154,10 +153,10 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () restMock.onGet(contractResultEndpoint).reply(200, { hash: ethereumHash }); - sdkClientStub.submitEthereumTransaction.returns({ + sdkClientStub.submitEthereumTransaction.resolves({ txResponse: { transactionId: '', - }, + } as unknown as TransactionResponse, fileId: null, }); @@ -170,10 +169,10 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () it('should return hash from ContractResult mirror node api', async function () { restMock.onGet(contractResultEndpoint).reply(200, { hash: ethereumHash }); - sdkClientStub.submitEthereumTransaction.returns({ + sdkClientStub.submitEthereumTransaction.resolves({ txResponse: { transactionId: TransactionId.fromString(transactionIdServicesFormat), - }, + } as unknown as TransactionResponse, fileId: null, }); const signed = await signTransaction(transaction); @@ -185,10 +184,10 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () it('should not send second transaction upon succession', async function () { restMock.onGet(contractResultEndpoint).reply(200, { hash: ethereumHash }); - sdkClientStub.submitEthereumTransaction.returns({ + sdkClientStub.submitEthereumTransaction.resolves({ txResponse: { transactionId: TransactionId.fromString(transactionIdServicesFormat), - }, + } as unknown as TransactionResponse, fileId: null, }); diff --git a/packages/relay/tests/lib/mirrorNodeClient.spec.ts b/packages/relay/tests/lib/mirrorNodeClient.spec.ts index 0db3de5094..e3b56c37f4 100644 --- a/packages/relay/tests/lib/mirrorNodeClient.spec.ts +++ b/packages/relay/tests/lib/mirrorNodeClient.spec.ts @@ -32,9 +32,10 @@ const registry = new Registry(); import pino from 'pino'; import { ethers } from 'ethers'; -import { predefined, MirrorNodeClientError, SDKClientError } from '../../src'; +import { predefined, MirrorNodeClientError } from '../../src'; import { CacheService } from '../../src/lib/services/cacheService/cacheService'; import { RequestDetails } from '../../src/lib/types/RequestDetails'; +import { SDKClientError } from '../../src/lib/errors/SDKClientError'; const logger = pino(); const noTransactions = '?transactions=false'; const requestDetails = new RequestDetails({ requestId: getRequestId(), ipAddress: '0.0.0.0' }); diff --git a/packages/relay/tests/lib/openrpc.spec.ts b/packages/relay/tests/lib/openrpc.spec.ts index 55b5cea106..f3180752fe 100644 --- a/packages/relay/tests/lib/openrpc.spec.ts +++ b/packages/relay/tests/lib/openrpc.spec.ts @@ -29,13 +29,13 @@ import axios from 'axios'; import sinon from 'sinon'; import dotenv from 'dotenv'; import MockAdapter from 'axios-mock-adapter'; -import { RelayImpl } from '../../src/lib/relay'; import { Registry } from 'prom-client'; +import { BigNumber } from 'bignumber.js'; +import { RelayImpl } from '../../src'; import { EthImpl } from '../../src/lib/eth'; -import { SDKClient } from '../../src/lib/clients'; -import { MirrorNodeClient } from '../../src/lib/clients/mirrorNodeClient'; -import type { IRequestDetails } from '../../src/lib/types/RequestDetails'; +import { SDKClient, MirrorNodeClient } from '../../src/lib/clients'; +import { RequestDetails } from '../../src/lib/types/RequestDetails'; import openRpcSchema from '../../../../docs/openrpc.json'; import { @@ -64,19 +64,20 @@ import { defaultLogTopics, defaultNetworkFees, defaultTxHash, - getRequestId, signedTransactionHash, } from '../helpers'; import { NOT_FOUND_RES } from './eth/eth-config'; import ClientService from '../../src/lib/services/hapiService/hapiService'; import HbarLimit from '../../src/lib/hbarlimiter'; -import { numberTo0x } from '../../../../packages/relay/src/formatters'; +import { numberTo0x } from '../../src/formatters'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); import constants from '../../src/lib/constants'; import { CacheService } from '../../src/lib/services/cacheService/cacheService'; import EventEmitter from 'events'; +import Long from 'long'; +import { AccountInfo } from '@hashgraph/sdk'; process.env.npm_package_version = 'relay/0.0.1-SNAPSHOT'; @@ -87,7 +88,7 @@ const Relay = new RelayImpl(logger, registry); let mock: MockAdapter; let mirrorNodeInstance: MirrorNodeClient; let clientServiceInstance: ClientService; -let sdkClientStub: any; +let sdkClientStub: sinon.SinonStubbedInstance; const noTransactions = '?transactions=false'; @@ -95,12 +96,10 @@ describe('Open RPC Specification', function () { let rpcDocument: any; let methodsResponseSchema: { [method: string]: any }; let ethImpl: EthImpl; - let requestDetails: IRequestDetails; - let requestIdPrefix: string; + + const requestDetails = new RequestDetails({ requestId: 'testId', ipAddress: '0.0.0.0' }); this.beforeAll(async () => { - requestIdPrefix = `[Request ID: testId]`; - requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; rpcDocument = await parseOpenRPCDocument(JSON.stringify(openRpcSchema)); methodsResponseSchema = rpcDocument.methods.reduce( (res: { [method: string]: any }, method: any) => ({ @@ -211,11 +210,11 @@ describe('Open RPC Specification', function () { mock.onGet(`contracts/${log.address}`).reply(200, defaultContract); } mock.onPost(`contracts/call`, { ...defaultCallData, estimate: false }).reply(200, { result: '0x12' }); - sdkClientStub.getAccountBalanceInWeiBar.returns(1000); - sdkClientStub.getAccountBalanceInTinyBar.returns(100000000000); - sdkClientStub.getContractByteCode.returns(Buffer.from(bytecode.replace('0x', ''), 'hex')); - sdkClientStub.getAccountInfo.returns({ ethereumNonce: '0x1' }); - sdkClientStub.submitEthereumTransaction.returns({}); + sdkClientStub.getAccountBalanceInWeiBar.resolves(BigNumber(1000)); + sdkClientStub.getAccountBalanceInTinyBar.resolves(BigNumber(100000000000)); + sdkClientStub.getContractByteCode.resolves(Buffer.from(bytecode.replace('0x', ''), 'hex')); + sdkClientStub.getAccountInfo.resolves({ ethereumNonce: Long.ONE } as unknown as AccountInfo); + sdkClientStub.submitEthereumTransaction.resolves(); mock.onGet(`accounts/${defaultContractResults.results[0].from}?transactions=false`).reply(200); mock.onGet(`accounts/${defaultContractResults.results[1].from}?transactions=false`).reply(200); mock.onGet(`accounts/${defaultContractResults.results[0].to}?transactions=false`).reply(200); @@ -249,32 +248,32 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_accounts"', function () { - const response = ethImpl.accounts(); + const response = ethImpl.accounts(requestDetails); validateResponseSchema(methodsResponseSchema.eth_accounts, response); }); it('should execute "eth_blockNumber"', async function () { - const response = await ethImpl.blockNumber(requestIdPrefix); + const response = await ethImpl.blockNumber(requestDetails); validateResponseSchema(methodsResponseSchema.eth_blockNumber, response); }); it('should execute "eth_chainId"', function () { - const response = ethImpl.chainId(); + const response = ethImpl.chainId(requestDetails); validateResponseSchema(methodsResponseSchema.eth_chainId, response); }); it('should execute "eth_coinbase"', function () { - const response = ethImpl.coinbase(); + const response = ethImpl.coinbase(requestDetails); validateResponseSchema(methodsResponseSchema.eth_coinbase, response); }); it('should execute "eth_estimateGas"', async function () { mock.onGet(`accounts/undefined${noTransactions}`).reply(404); - const response = await ethImpl.estimateGas({}, null, requestIdPrefix); + const response = await ethImpl.estimateGas({}, null, requestDetails); validateResponseSchema(methodsResponseSchema.eth_estimateGas, response); }); @@ -292,7 +291,7 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_getBalance"', async function () { - const response = await ethImpl.getBalance(contractAddress1, 'latest', getRequestId()); + const response = await ethImpl.getBalance(contractAddress1, 'latest', requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBalance, response); }); @@ -322,19 +321,19 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_getBlockTransactionCountByHash"', async function () { - const response = await ethImpl.getBlockTransactionCountByHash(blockHash); + const response = await ethImpl.getBlockTransactionCountByHash(blockHash, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBlockTransactionCountByHash, response); }); it('should execute "eth_getBlockTransactionCountByNumber" with block tag', async function () { - const response = await ethImpl.getBlockTransactionCountByNumber('latest', requestIdPrefix); + const response = await ethImpl.getBlockTransactionCountByNumber('latest', requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBlockTransactionCountByNumber, response); }); it('should execute "eth_getBlockTransactionCountByNumber" with block number', async function () { - const response = await ethImpl.getBlockTransactionCountByNumber('0x3', requestIdPrefix); + const response = await ethImpl.getBlockTransactionCountByNumber('0x3', requestDetails); validateResponseSchema(methodsResponseSchema.eth_getBlockTransactionCountByNumber, response); }); @@ -354,7 +353,7 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_getLogs" with no filters', async function () { - const response = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails.requestIdPrefix); + const response = await ethImpl.getLogs(null, 'latest', 'latest', null, null, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getLogs, response); }); @@ -379,7 +378,7 @@ describe('Open RPC Specification', function () { mock.onGet(`contracts/${log.address}`).reply(200, defaultContract); } - const response = await ethImpl.getLogs(null, 'latest', 'latest', null, defaultLogTopics, requestDetails.requestIdPrefix); + const response = await ethImpl.getLogs(null, 'latest', 'latest', null, defaultLogTopics, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getLogs, response); }); @@ -405,7 +404,7 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_getTransactionByHash"', async function () { - const response = await ethImpl.getTransactionByHash(defaultTxHash, requestIdPrefix); + const response = await ethImpl.getTransactionByHash(defaultTxHash, requestDetails); validateResponseSchema(methodsResponseSchema.eth_getTransactionByHash, response); }); @@ -415,7 +414,7 @@ describe('Open RPC Specification', function () { .onGet(`accounts/${contractAddress1}${noTransactions}`) .reply(200, { account: contractAddress1, ethereum_nonce: 5 }); mock.onGet(`contracts/${contractAddress1}${noTransactions}`).reply(404); - const response = await ethImpl.getTransactionCount(contractAddress1, 'latest', requestIdPrefix); + const response = await ethImpl.getTransactionCount(contractAddress1, 'latest', requestDetails); validateResponseSchema(methodsResponseSchema.eth_getTransactionCount, response); }); @@ -430,55 +429,55 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_getUncleByBlockHashAndIndex"', async function () { - const response = await ethImpl.getUncleByBlockHashAndIndex(); + const response = await ethImpl.getUncleByBlockHashAndIndex(requestDetails); validateResponseSchema(methodsResponseSchema.eth_getUncleByBlockHashAndIndex, response); }); it('should execute "eth_getUncleByBlockNumberAndIndex"', async function () { - const response = await ethImpl.getUncleByBlockNumberAndIndex(); + const response = await ethImpl.getUncleByBlockNumberAndIndex(requestDetails); validateResponseSchema(methodsResponseSchema.eth_getUncleByBlockNumberAndIndex, response); }); it('should execute "eth_getUncleByBlockNumberAndIndex"', async function () { - const response = await ethImpl.getUncleByBlockNumberAndIndex(); + const response = await ethImpl.getUncleByBlockNumberAndIndex(requestDetails); validateResponseSchema(methodsResponseSchema.eth_getUncleByBlockNumberAndIndex, response); }); it('should execute "eth_getUncleCountByBlockHash"', async function () { - const response = await ethImpl.getUncleCountByBlockHash(); + const response = await ethImpl.getUncleCountByBlockHash(requestDetails); validateResponseSchema(methodsResponseSchema.eth_getUncleCountByBlockHash, response); }); it('should execute "eth_getUncleCountByBlockNumber"', async function () { - const response = await ethImpl.getUncleCountByBlockNumber(); + const response = await ethImpl.getUncleCountByBlockNumber(requestDetails); validateResponseSchema(methodsResponseSchema.eth_getUncleCountByBlockNumber, response); }); it('should execute "eth_getWork"', async function () { - const response = ethImpl.getWork(); + const response = ethImpl.getWork(requestDetails); validateResponseSchema(methodsResponseSchema.eth_getWork, response); }); it('should execute "eth_hashrate"', async function () { - const response = await ethImpl.hashrate(); + const response = await ethImpl.hashrate(requestDetails); validateResponseSchema(methodsResponseSchema.eth_hashrate, response); }); it('should execute "eth_mining"', async function () { - const response = await ethImpl.mining(); + const response = await ethImpl.mining(requestDetails); validateResponseSchema(methodsResponseSchema.eth_mining, response); }); it('should execute "eth_protocolVersion"', async function () { - const response = ethImpl.protocolVersion(); + const response = ethImpl.protocolVersion(requestDetails); validateResponseSchema(methodsResponseSchema.eth_protocolVersion, response); }); @@ -490,37 +489,37 @@ describe('Open RPC Specification', function () { }); it('should execute "eth_sendTransaction"', async function () { - const response = ethImpl.sendTransaction(); + const response = ethImpl.sendTransaction(requestDetails); validateResponseSchema(methodsResponseSchema.eth_sendTransaction, response); }); it('should execute "eth_signTransaction"', async function () { - const response = ethImpl.signTransaction(); + const response = ethImpl.signTransaction(requestDetails); validateResponseSchema(methodsResponseSchema.eth_signTransaction, response); }); it('should execute "eth_sign"', async function () { - const response = ethImpl.sign(); + const response = ethImpl.sign(requestDetails); validateResponseSchema(methodsResponseSchema.eth_sign, response); }); it('should execute "eth_submitHashrate"', async function () { - const response = ethImpl.submitHashrate(); + const response = ethImpl.submitHashrate(requestDetails); validateResponseSchema(methodsResponseSchema.eth_submitHashrate, response); }); it('should execute "eth_submitWork"', async function () { - const response = await ethImpl.submitWork(); + const response = await ethImpl.submitWork(requestDetails); validateResponseSchema(methodsResponseSchema.eth_submitWork, response); }); it('should execute "eth_syncing"', async function () { - const response = await ethImpl.syncing(); + const response = await ethImpl.syncing(requestDetails); validateResponseSchema(methodsResponseSchema.eth_syncing, response); }); diff --git a/packages/relay/tests/lib/services/eth/filter.spec.ts b/packages/relay/tests/lib/services/eth/filter.spec.ts index 7c51b8d69a..616670f6d4 100644 --- a/packages/relay/tests/lib/services/eth/filter.spec.ts +++ b/packages/relay/tests/lib/services/eth/filter.spec.ts @@ -23,7 +23,7 @@ import dotenv from 'dotenv'; import MockAdapter from 'axios-mock-adapter'; import { expect } from 'chai'; import { Registry } from 'prom-client'; -import { MirrorNodeClient } from '../../../../src/lib/clients/mirrorNodeClient'; +import { MirrorNodeClient } from '../../../../src/lib/clients'; import pino from 'pino'; import constants from '../../../../src/lib/constants'; import { FilterService, CommonService } from '../../../../src/lib/services/ethService'; @@ -32,7 +32,6 @@ import RelayAssertions from '../../../assertions'; import { predefined } from '../../../../src'; import { CacheService } from '../../../../src/lib/services/cacheService/cacheService'; import * as sinon from 'sinon'; -import { request } from 'http'; import { RequestDetails } from '../../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); @@ -271,7 +270,7 @@ describe('Filter API Test Suite', async function () { defaultEvmAddress, defaultLogTopics, ); - validateFilterCache(filterId, constants.FILTER.TYPE.LOG, { + await validateFilterCache(filterId, constants.FILTER.TYPE.LOG, { fromBlock: numberHex, toBlock: 'latest', address: defaultEvmAddress, @@ -327,13 +326,17 @@ describe('Filter API Test Suite', async function () { cacheMock.stub(cacheService, 'getAsync').onFirstCall().returns(filterObject).onSecondCall().returns(undefined); - cacheService.set(cacheKey, filterObject, filterService.ethUninstallFilter, requestDetails, constants.FILTER.TTL); + await cacheService.set( + cacheKey, + filterObject, + filterService.ethUninstallFilter, + requestDetails, + constants.FILTER.TTL, + ); const result = await filterService.uninstallFilter(existingFilterId, requestDetails); - const isDeleted = (await cacheService.getAsync(cacheKey, filterService.ethUninstallFilter, requestDetails)) - ? false - : true; + const isDeleted = !(await cacheService.getAsync(cacheKey, filterService.ethUninstallFilter, requestDetails)); expect(result).to.eq(true); expect(isDeleted).to.eq(true); }); @@ -356,7 +359,7 @@ describe('Filter API Test Suite', async function () { it('Creates a filter with type=new_block', async function () { const filterId = await filterService.newBlockFilter(requestDetails); - validateFilterCache(filterId, constants.FILTER.TYPE.NEW_BLOCK, { + await validateFilterCache(filterId, constants.FILTER.TYPE.NEW_BLOCK, { blockAtCreation: toHex(defaultBlock.number), }); }); @@ -528,7 +531,7 @@ describe('Filter API Test Suite', async function () { ) .reply(200, filteredLogs); - const filterId = await filterService.newFilter(null, null, requestDetails, null, customTopic); + const filterId = await filterService.newFilter(undefined, undefined, requestDetails, undefined, customTopic); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; cacheMock .stub(cacheService, 'getAsync') @@ -682,7 +685,7 @@ describe('Filter API Test Suite', async function () { const logs = await filterService.getFilterChanges(filterId, requestDetails); expect(logs).to.not.be.empty; - logs.every((log) => expect(Number(log.blockNumber)).to.equal(9)); + logs.forEach((log) => expect(Number(log.blockNumber)).to.equal(9)); }); it('should return an empty set if there are no logs', async function () { @@ -716,7 +719,13 @@ describe('Filter API Test Suite', async function () { }); const cacheKey = `${constants.CACHE_KEY.FILTERID}_${existingFilterId}`; - cacheService.set(cacheKey, blockFilterObject, filterService.ethGetFilterChanges, constants.FILTER.TTL, undefined); + await cacheService.set( + cacheKey, + blockFilterObject, + filterService.ethGetFilterChanges, + requestDetails, + constants.FILTER.TTL, + ); cacheMock.stub(cacheService, 'getAsync').returns(blockFilterObject); const blocks = await filterService.getFilterChanges(existingFilterId, requestDetails); diff --git a/packages/server/src/koaJsonRpc/index.ts b/packages/server/src/koaJsonRpc/index.ts index 971f09fb55..a7fa402877 100644 --- a/packages/server/src/koaJsonRpc/index.ts +++ b/packages/server/src/koaJsonRpc/index.ts @@ -47,6 +47,7 @@ import { hasOwnProperty, } from './lib/utils'; import { IJsonRpcRequest } from './lib/IJsonRpcRequest'; +import { RequestDetails } from '../../../relay/src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../../../../../.env') }); @@ -72,12 +73,12 @@ export default class KoaJsonRpc { private readonly methodResponseHistogram: Histogram; private requestId: string; - private ipRequest: string; + private requestIpAddress: string; constructor(logger: Logger, register: Registry, opts?: { limit: string | null }) { this.koaApp = new Koa(); this.requestId = ''; - this.ipRequest = ''; + this.requestIpAddress = ''; this.registry = Object.create(null); this.registryTotal = Object.create(null); this.methodConfig = methodConfiguration; @@ -108,7 +109,7 @@ export default class KoaJsonRpc { rpcApp(): (ctx: Koa.Context, _next: Koa.Next) => Promise { return async (ctx: Koa.Context, _next: Koa.Next) => { this.requestId = ctx.state.reqId; - this.ipRequest = ctx.request.ip; + this.requestIpAddress = ctx.request.ip; ctx.set(REQUEST_ID_HEADER_NAME, this.requestId); if (ctx.request.method !== 'POST') { @@ -260,8 +261,12 @@ export default class KoaJsonRpc { return this.requestId; } - getIpRequest(): string { - return this.ipRequest; + getRequestIpAddress(): string { + return this.requestIpAddress; + } + + getRequestDetails(): RequestDetails { + return new RequestDetails({ requestId: this.requestId, ipAddress: this.requestIpAddress }); } hasInvalidRequestId(body: IJsonRpcRequest): boolean { diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index bc47741941..8213da0cab 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -29,7 +29,7 @@ import fs from 'fs'; import { v4 as uuid } from 'uuid'; import { formatRequestIdMessage } from './formatters'; import cors from 'koa-cors'; -import { IRequestDetails } from './types/types'; +import { RequestDetails } from '../../relay/src/lib/types/RequestDetails'; const mainLogger = pino({ name: 'hedera-json-rpc-relay', @@ -115,10 +115,7 @@ app.getKoaApp().use(async (ctx, next) => { app.getKoaApp().use(async (ctx, next) => { if (ctx.url === '/health/readiness') { try { - const result = relay.eth().chainId({ - requestIdPrefix: ctx.state.reqId, - requestIp: ctx.request.ip, - } as IRequestDetails); + const result = relay.eth().chainId(app.getRequestDetails()); if (result.indexOf('0x12') >= 0) { ctx.status = 200; ctx.body = 'OK'; @@ -202,19 +199,18 @@ app.getKoaApp().use(async (ctx, next) => { }); const logAndHandleResponse = async (methodName: string, methodParams: any[], methodFunction: any) => { + const requestDetails = app.getRequestDetails(); logger.debug('Method name: ' + methodName); - const requestId = app.getRequestId(); - logger.debug('Request id' + requestId); - const requestIp = app.getIpRequest(); - logger.debug('Request ip' + requestIp); - const requestIdPrefix = requestId ? formatRequestIdMessage(requestId) : ''; - const requestDetails: IRequestDetails = { requestIdPrefix, requestIp }; + logger.debug('Request id: ' + requestDetails.requestId); + logger.debug('Request ip: ' + requestDetails.ipAddress); try { const methodValidations = Validator.METHODS[methodName]; if (methodValidations) { logger.debug( - `${requestIdPrefix} Validating method parameters for ${methodName}, params: ${JSON.stringify(methodParams)}`, + `${requestDetails.formattedRequestId} Validating method parameters for ${methodName}, params: ${JSON.stringify( + methodParams, + )}`, ); Validator.validateParams(methodParams, methodValidations); } @@ -222,9 +218,9 @@ const logAndHandleResponse = async (methodName: string, methodParams: any[], met if (response instanceof JsonRpcError) { // log error only if it is not a contract revert, otherwise log it as debug if (response.code === predefined.CONTRACT_REVERT().code) { - logger.debug(`${requestIdPrefix} ${response.message}`); + logger.debug(`${requestDetails.formattedRequestId} ${response.message}`); } else { - logger.error(`${requestIdPrefix} ${response.message}`); + logger.error(`${requestDetails.formattedRequestId} ${response.message}`); } return new JsonRpcError( @@ -233,7 +229,7 @@ const logAndHandleResponse = async (methodName: string, methodParams: any[], met message: response.message, data: response.data, }, - requestId, + requestDetails.requestId, ); } return response; @@ -246,17 +242,17 @@ const logAndHandleResponse = async (methodName: string, methodParams: any[], met } else if (e instanceof JsonRpcError) { error = e; } else { - logger.error(`${requestIdPrefix} ${e.message}`); + logger.error(`${requestDetails.formattedRequestId} ${e.message}`); } - logger.error(`${requestIdPrefix} ${error.message}`); + logger.error(`${requestDetails.formattedRequestId} ${error.message}`); return new JsonRpcError( { code: error.code, message: error.message, data: error.data, }, - requestId, + requestDetails.requestId, ); } }; @@ -679,7 +675,7 @@ app.useRpc('eth_maxPriorityFeePerGas', async () => { */ app.useRpc('debug_traceTransaction', async (params: any) => { - return logAndHandleResponse('debug_traceTransaction', params, (requestDetails: IRequestDetails) => { + return logAndHandleResponse('debug_traceTransaction', params, (requestDetails: RequestDetails) => { const transactionIdOrHash = params[0]; let tracer: TracerType = TracerType.OpcodeLogger; let tracerConfig: ITracerConfig = {}; diff --git a/packages/server/src/types/types.ts b/packages/server/src/types/types.ts deleted file mode 100644 index c4f6a9990a..0000000000 --- a/packages/server/src/types/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type IRequestDetails = { - requestIdPrefix: string; - requestIp: string; -}; diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 729d364315..859082c632 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -41,7 +41,9 @@ import RelayCalls from '../../tests/helpers/constants'; // Other imports import { numberTo0x, prepend0x } from '../../../../packages/relay/src/formatters'; import constants from '../../../relay/src/lib/constants'; -import { IRequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/IRequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { JsonRpcError } from '@hashgraph/json-rpc-relay'; + const Address = RelayCalls; describe('@api-batch-1 RPC Server Acceptance Tests', function () { @@ -55,12 +57,10 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // cached entities let parentContractAddress: string; let mirrorContractDetails; - let requestId: string; - let requestIdPrefix: string; let account2Address: string; let expectedGasPrice: string; - let requestDetails: IRequestDetails; + const requestDetails = new RequestDetails({ requestId: 'rpc_batch1Test', ipAddress: '0.0.0.0' }); const CHAIN_ID = process.env.CHAIN_ID || '0x12a'; const INCORRECT_CHAIN_ID = 999; const GAS_PRICE_TOO_LOW = '0x1'; @@ -86,11 +86,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds this.beforeAll(async () => { - requestId = Utils.generateRequestId(); - requestIdPrefix = Utils.formatRequestIdMessage(requestId); - requestDetails = { requestIdPrefix: `${requestIdPrefix}`, requestIp: '0.0.0.0' }; - - expectedGasPrice = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GAS_PRICE, [], requestId); + expectedGasPrice = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GAS_PRICE, [], requestDetails); const initialAccount: AliasAccount = global.accounts[0]; const neededAccounts: number = 3; @@ -100,7 +96,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { initialAccount, neededAccounts, initialBalance, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); @@ -111,7 +107,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { accounts[0].wallet, ); parentContractAddress = parentContract.target as string; - global.logger.trace(`${requestIdPrefix} Deploy parent contract on address ${parentContractAddress}`); + global.logger.trace( + `${requestDetails.formattedRequestId} Deploy parent contract on address ${parentContractAddress}`, + ); await accounts[0].wallet.sendTransaction({ to: parentContractAddress, @@ -122,19 +120,15 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const createChildTx: ethers.ContractTransactionResponse = await parentContract.createChild(1); global.logger.trace( - `${requestIdPrefix} Contract call createChild on parentContract results in tx hash: ${createChildTx.hash}`, + `${requestDetails.formattedRequestId} Contract call createChild on parentContract results in tx hash: ${createChildTx.hash}`, ); // get contract result details - mirrorContractDetails = await mirrorNode.get(`/contracts/results/${createChildTx.hash}`, requestId); + mirrorContractDetails = await mirrorNode.get(`/contracts/results/${createChildTx.hash}`, requestDetails); mirrorContractDetails.from = accounts[0].address; account2Address = accounts[2].address; }); - this.beforeEach(async () => { - requestId = Utils.generateRequestId(); - }); - describe('eth_getLogs', () => { let log0Block, log4Block, contractAddress: string, contractAddress2: string, latestBlock, previousBlock; @@ -152,7 +146,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { contractAddress = logsContract.target.toString(); contractAddress2 = logsContract2.target.toString(); - previousBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestId)); + previousBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); // @ts-ignore await (await logsContract.connect(accounts[1].wallet).log0(1)).wait(); @@ -167,7 +161,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // @ts-ignore await (await logsContract2.connect(accounts[1].wallet).log4(1, 1, 1, 1)).wait(); - latestBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestId)); + latestBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); }); it('@release should deploy a contract', async () => { @@ -180,7 +174,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestIdPrefix, + requestDetails, ); expect(logs.length).to.be.greaterThan(0); @@ -200,7 +194,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { log0Block = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [logs[0].transactionHash], - requestId, + requestDetails, ); const transactionCountLog0Block = await relay.provider.getTransactionCount( log0Block.from, @@ -210,7 +204,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { log4Block = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [logs[logs.length - 1].transactionHash], - requestId, + requestDetails, ); const transactionCountLog4Block = await relay.provider.getTransactionCount( log4Block.from, @@ -239,7 +233,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestId, + requestDetails, ); expect(logs.length).to.be.greaterThan(0); @@ -258,7 +252,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }, ], predefined.MISSING_FROM_BLOCK_PARAM, - requestId, + requestDetails, ); }); @@ -272,7 +266,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestId, + requestDetails, ); expect(logs.length).to.be.greaterThan(0); @@ -294,7 +288,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: contractAddress, }, ], - requestId, + requestDetails, ); expect(logs.length).to.be.greaterThan(0); @@ -316,7 +310,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: contractAddress, }, ], - requestId, + requestDetails, ); expect(logs.length).to.be.greaterThan(0); @@ -337,7 +331,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2, Address.NON_EXISTING_ADDRESS], }, ], - requestId, + requestDetails, ); expect(logs.length).to.be.greaterThan(0); expect(logs.length).to.be.eq(6); @@ -358,7 +352,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestId, + requestDetails, ); expect(logs.length).to.be.greaterThan(0); @@ -376,7 +370,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestId, + requestDetails, ); expect(logs).to.exist; expect(logs.length).to.be.eq(0); @@ -403,7 +397,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { topics: [topic], }, ], - requestId, + requestDetails, ); expect(logsWithTopic.length).to.be.greaterThan(0); @@ -419,7 +413,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { process.env['MIRROR_NODE_LIMIT_PARAM'] = '2'; // calculate blocks behind latest, so we can fetch logs from the past. // if current block is less than 10, we will fetch logs from the beginning otherwise we will fetch logs from 10 blocks behind latest - const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestId)); + const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); let blocksBehindLatest = 0; if (currentBlock > 10) { blocksBehindLatest = currentBlock - 10; @@ -433,7 +427,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestId, + requestDetails, ); expect(logs.length).to.be.greaterThan(2); }); @@ -448,13 +442,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: ethers.ZeroAddress, }, ], - requestId, + requestDetails, ); expect(logs.length).to.eq(0); }); it('should return only logs of non-zero addresses', async () => { - const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestId)); + const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); let blocksBehindLatest = 0; if (currentBlock > 10) { blocksBehindLatest = currentBlock - 10; @@ -468,7 +462,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [ethers.ZeroAddress, contractAddress2], }, ], - requestId, + requestDetails, ); expect(logs.length).to.eq(1); }); @@ -480,14 +474,15 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const mirrorTransactions: any[] = []; before(async () => { - mirrorBlock = (await mirrorNode.get(`/blocks?block.number=${mirrorContractDetails.block_number}`, requestId)) - .blocks[0]; + mirrorBlock = ( + await mirrorNode.get(`/blocks?block.number=${mirrorContractDetails.block_number}`, requestDetails) + ).blocks[0]; const timestampQuery = `timestamp=gte:${mirrorBlock.timestamp.from}×tamp=lte:${mirrorBlock.timestamp.to}`; - mirrorContractResults = (await mirrorNode.get(`/contracts/results?${timestampQuery}`, requestId)).results; + mirrorContractResults = (await mirrorNode.get(`/contracts/results?${timestampQuery}`, requestDetails)).results; for (const res of mirrorContractResults) { mirrorTransactions.push( - await mirrorNode.get(`/contracts/${res.contract_id}/results/${res.timestamp}`, requestId), + await mirrorNode.get(`/contracts/${res.contract_id}/results/${res.timestamp}`, requestDetails), ); } @@ -504,7 +499,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [mirrorBlock.hash.substring(0, 66), false], - requestId, + requestDetails, ); Assertions.block(blockResult, mirrorBlock, mirrorTransactions, expectedGasPrice, false); }); @@ -513,7 +508,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [mirrorBlock.hash.substring(0, 66), true], - requestId, + requestDetails, ); // Remove synthetic transactions blockResult.transactions = blockResult.transactions.filter((transaction) => transaction.value !== '0x1234'); @@ -524,7 +519,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [Address.NON_EXISTING_BLOCK_HASH, false], - requestId, + requestDetails, ); expect(blockResult).to.be.null; }); @@ -533,7 +528,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [Address.NON_EXISTING_BLOCK_HASH, true], - requestId, + requestDetails, ); expect(blockResult).to.be.null; }); @@ -542,7 +537,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [numberTo0x(mirrorBlock.number), false], - requestId, + requestDetails, ); // Remove synthetic transactions blockResult.transactions = blockResult.transactions.filter((transaction) => transaction.value !== '0x1234'); @@ -553,14 +548,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['latest', false], - requestId, + requestDetails, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['latest', false], - requestId, + requestDetails, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -569,14 +564,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['finalized', false], - requestId, + requestDetails, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['finalized', false], - requestId, + requestDetails, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -585,14 +580,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['safe', false], - requestId, + requestDetails, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['safe', false], - requestId, + requestDetails, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -601,14 +596,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['pending', false], - requestId, + requestDetails, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['pending', false], - requestId, + requestDetails, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -617,7 +612,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [numberTo0x(mirrorBlock.number), true], - requestId, + requestDetails, ); // Remove synthetic transactions blockResult.transactions = blockResult.transactions.filter((transaction) => transaction.value !== '0x1234'); @@ -628,7 +623,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [Address.NON_EXISTING_BLOCK_NUMBER, true], - requestId, + requestDetails, ); expect(blockResult).to.be.null; }); @@ -637,7 +632,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [Address.NON_EXISTING_BLOCK_NUMBER, false], - requestId, + requestDetails, ); expect(blockResult).to.be.null; }); @@ -646,7 +641,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER, [numberTo0x(mirrorBlock.number)], - requestId, + requestDetails, ); expect(res).to.be.equal(ethers.toQuantity(mirrorBlock.count)); }); @@ -655,7 +650,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER, [Address.NON_EXISTING_BLOCK_NUMBER], - requestId, + requestDetails, ); expect(res).to.be.null; }); @@ -664,7 +659,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_HASH, [mirrorBlock.hash.substring(0, 66)], - requestId, + requestDetails, ); expect(res).to.be.equal(ethers.toQuantity(mirrorBlock.count)); }); @@ -673,19 +668,19 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_HASH, [Address.NON_EXISTING_BLOCK_HASH], - requestId, + requestDetails, ); expect(res).to.be.null; }); it('should execute "eth_getBlockTransactionCountByNumber"', async function () { it('@release should execute "eth_blockNumber"', async function () { - const mirrorBlocks = await mirrorNode.get(`blocks`, requestId); + const mirrorBlocks = await mirrorNode.get(`blocks`, requestDetails); expect(mirrorBlocks).to.have.property('blocks'); expect(mirrorBlocks.blocks.length).to.gt(0); const mirrorBlockNumber = mirrorBlocks.blocks[0].number; - const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestId); + const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails); const blockNumber = Number(res); expect(blockNumber).to.exist; @@ -733,7 +728,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, [mirrorContractDetails.block_hash.substring(0, 66), numberTo0x(mirrorContractDetails.transaction_index)], - requestId, + requestDetails, ); Assertions.transaction(response, mirrorContractDetails); }); @@ -742,7 +737,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, [Address.NON_EXISTING_BLOCK_HASH, numberTo0x(mirrorContractDetails.transaction_index)], - requestId, + requestDetails, ); expect(response).to.be.null; }); @@ -751,7 +746,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, [mirrorContractDetails.block_hash.substring(0, 66), Address.NON_EXISTING_INDEX], - requestId, + requestDetails, ); expect(response).to.be.null; }); @@ -760,7 +755,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_NUMBER_AND_INDEX, [numberTo0x(mirrorContractDetails.block_number), numberTo0x(mirrorContractDetails.transaction_index)], - requestId, + requestDetails, ); Assertions.transaction(response, mirrorContractDetails); }); @@ -769,7 +764,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_NUMBER_AND_INDEX, [numberTo0x(mirrorContractDetails.block_number), Address.NON_EXISTING_INDEX], - requestId, + requestDetails, ); expect(response).to.be.null; }); @@ -778,7 +773,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_NUMBER_AND_INDEX, [Address.NON_EXISTING_BLOCK_NUMBER, numberTo0x(mirrorContractDetails.transaction_index)], - requestId, + requestDetails, ); expect(response).to.be.null; }); @@ -787,49 +782,53 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), type: 0, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const legacyTxHash = await relay.sendRawTransaction(signedTx, requestId); + const legacyTxHash = await relay.sendRawTransaction(signedTx, requestDetails); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - const mirrorResult = await mirrorNode.get(`/contracts/results/${legacyTxHash}`, requestId); + const mirrorResult = await mirrorNode.get(`/contracts/results/${legacyTxHash}`, requestDetails); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; - const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [legacyTxHash], requestId); - const currentPrice = await relay.gasPrice(requestId); + const res = await relay.call( + RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, + [legacyTxHash], + requestDetails, + ); + const currentPrice = await relay.gasPrice(requestDetails); Assertions.transactionReceipt(res, mirrorResult, currentPrice); }); it('@release-light, @release should execute "eth_getTransactionReceipt" for hash of London transaction', async function () { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxFeePerGas: gasPrice, maxPriorityFeePerGas: gasPrice, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestId, + requestDetails, ); - const currentPrice = await relay.gasPrice(requestId); + const currentPrice = await relay.gasPrice(requestDetails); Assertions.transactionReceipt(res, mirrorResult, currentPrice); }); @@ -838,34 +837,34 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLegacy2930TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestId, + requestDetails, ); - const currentPrice = await relay.gasPrice(requestId); + const currentPrice = await relay.gasPrice(requestDetails); Assertions.transactionReceipt(res, mirrorResult, currentPrice); }); it('@release should fail to execute "eth_getTransactionReceipt" for hash of London transaction', async function () { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxFeePerGas: gasPrice, maxPriorityFeePerGas: gasPrice, }; @@ -875,14 +874,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ signedTx + '11', - requestId, + requestDetails, ]); }); it('@release should return the right "effectiveGasPrice" for SYNTHETIC HTS transaction', async function () { - const tokenId = await servicesNode.createToken(1000, requestId); - await accounts[2].client.associateToken(tokenId, requestId); - const currentPrice = await relay.gasPrice(requestId); + const tokenId = await servicesNode.createToken(1000, requestDetails); + await accounts[2].client.associateToken(tokenId, requestDetails); + const currentPrice = await relay.gasPrice(requestDetails); const transaction = new TransferTransaction() .addTokenTransfer(tokenId, servicesNode._thisAccountId(), -10) .addTokenTransfer(tokenId, accounts[2].accountId, 10) @@ -890,7 +889,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const resp = await transaction.execute(servicesNode.client); await resp.getRecord(servicesNode.client); await Utils.wait(1000); - const logsRes = await mirrorNode.get(`/contracts/results/logs?limit=1`, requestId); + const logsRes = await mirrorNode.get(`/contracts/results/logs?limit=1`, requestDetails); const blockNumber = logsRes.logs[0].block_number; const formattedBlockNumber = prepend0x(blockNumber.toString(16)); const contractId = logsRes.logs[0].contract_id; @@ -900,11 +899,15 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { } // load the block in cache - await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [formattedBlockNumber, true], requestId); + await relay.call( + RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, + [formattedBlockNumber, true], + requestDetails, + ); const receiptFromRelay = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestId, + requestDetails, ); // handle deviation in gas price @@ -913,16 +916,20 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release should return the right "effectiveGasPrice" for SYNTHETIC Contract Call transaction', async function () { - const currentPrice = await relay.gasPrice(requestId); + const currentPrice = await relay.gasPrice(requestDetails); const transactionHash = mirrorContractDetails.hash; const formattedBlockNumber = prepend0x(mirrorContractDetails.block_number.toString(16)); // load the block in cache - await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [formattedBlockNumber, true], requestId); + await relay.call( + RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, + [formattedBlockNumber, true], + requestDetails, + ); const receiptFromRelay = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestId, + requestDetails, ); // handle deviation in gas price @@ -934,7 +941,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [Address.NON_EXISTING_TX_HASH], - requestId, + requestDetails, ); expect(res).to.be.null; }); @@ -943,13 +950,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), chainId: INCORRECT_CHAIN_ID, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.UNSUPPORTED_CHAIN_ID(ethers.toQuantity(INCORRECT_CHAIN_ID), CHAIN_ID); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('should execute "eth_sendRawTransaction" for deterministic deployment transaction', async function () { @@ -958,11 +965,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLegacyTransactionData, value: (10 * ONE_TINYBAR * 10 ** 8).toString(), // 10hbar - the gasPrice to deploy the deterministic proxy contract to: constants.DETERMINISTIC_DEPLOYMENT_SIGNER, - nonce: await relay.getAccountNonce(accounts[0].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[0].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedSendHbarTx = await accounts[0].wallet.signTransaction(sendHbarTx); - await relay.sendRawTransaction(signedSendHbarTx, requestId); + await relay.sendRawTransaction(signedSendHbarTx, requestDetails); await Utils.wait(5000); // wait for signer's account to propagate accross the network const deployerBalance = await global.relay.getBalance(constants.DETERMINISTIC_DEPLOYMENT_SIGNER, 'latest'); expect(deployerBalance).to.not.eq(0); @@ -971,23 +978,26 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // by the DETERMINISTIC_DEPLOYMENT_SIGNER with tx.nonce = 0. With that reason, if the current nonce of the signer // is not 0, it means the DETERMINISTIC_DEPLOYER_TRANSACTION has already been submitted, and the DETERMINISTIC_PROXY_CONTRACT // has already been deployed to the network. Therefore, it only matters to test this flow once. - const signerNonce = await relay.getAccountNonce(constants.DETERMINISTIC_DEPLOYMENT_SIGNER, requestId); + const signerNonce = await relay.getAccountNonce(constants.DETERMINISTIC_DEPLOYMENT_SIGNER, requestDetails); if (signerNonce === 0) { const deployerBalance = await relay.getBalance( constants.DETERMINISTIC_DEPLOYMENT_SIGNER, 'latest', - requestId, + requestDetails, ); expect(deployerBalance).to.not.eq(0); // send transaction to deploy proxy transaction const deterministicDeployTransactionHash = await relay.sendRawTransaction( constants.DETERMINISTIC_DEPLOYER_TRANSACTION, - requestId, + requestDetails, ); - const receipt = await mirrorNode.get(`/contracts/results/${deterministicDeployTransactionHash}`, requestId); + const receipt = await mirrorNode.get( + `/contracts/results/${deterministicDeployTransactionHash}`, + requestDetails, + ); const fromAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.from}`); const toAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.to}`); @@ -997,9 +1007,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { expect(receipt.address).to.eq(constants.DETERMINISTIC_PROXY_CONTRACT); } else { try { - await relay.sendRawTransaction(constants.DETERMINISTIC_DEPLOYER_TRANSACTION, requestId); + await relay.sendRawTransaction(constants.DETERMINISTIC_DEPLOYER_TRANSACTION, requestDetails); expect(true).to.be.false; - } catch (error) { + } catch (error: any) { const expectedNonceTooLowError = predefined.NONCE_TOO_LOW(0, signerNonce); const errObj = JSON.parse(error.info.responseBody).error; expect(errObj.code).to.eq(expectedNonceTooLowError.code); @@ -1009,56 +1019,56 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release-light, @release should execute "eth_sendRawTransaction" for legacy EIP 155 transactions', async function () { - const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); + const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); - const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); + const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); const balanceChange = receiverEndBalance - receiverInitialBalance; expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString()); }); it('should fail "eth_sendRawTransaction" for legacy EIP 155 transactions (with insufficient balance)', async function () { - const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestId); + const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestDetails); const transaction = { ...default155TransactionData, to: parentContractAddress, value: balanceInWeiBars, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.INSUFFICIENT_ACCOUNT_BALANCE; - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('should execute "eth_sendRawTransaction" for legacy transactions (with no chainId i.e. chainId=0x0)', async function () { - const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); + const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); const transaction = { ...defaultLegacyTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); - const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); + const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); const balanceChange = receiverEndBalance - receiverInitialBalance; expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString()); }); @@ -1067,16 +1077,16 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLegacyTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[1].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[1].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[1].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); const transactionResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [transactionHash], - requestId, + requestDetails, ); const result = Object.prototype.hasOwnProperty.call(transactionResult, 'chainId'); @@ -1089,24 +1099,24 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { chainId: Number(CHAIN_ID), gasPrice: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestDetails]); }); it('should not fail "eth_sendRawTransactxion" for Legacy 2930 transactions', async function () { const transaction = { ...defaultLegacy2930TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.exist; expect(info.result).to.equal('SUCCESS'); }); @@ -1116,27 +1126,27 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLegacy2930TransactionData, gasPrice: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestDetails]); }); it('should fail "eth_sendRawTransaction" for Legacy 2930 transactions (with insufficient balance)', async function () { - const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestId); + const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestDetails); const transaction = { ...defaultLegacy2930TransactionData, value: balanceInWeiBars, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), - gasPrice: await relay.gasPrice(requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.INSUFFICIENT_ACCOUNT_BALANCE; - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('should fail "eth_sendRawTransaction" for London transactions (with gas price too low)', async function () { @@ -1145,62 +1155,62 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { maxPriorityFeePerGas: GAS_PRICE_TOO_LOW, maxFeePerGas: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestDetails]); }); it('should fail "eth_sendRawTransaction" for London transactions (with insufficient balance)', async function () { - const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestId); - const gasPrice = await relay.gasPrice(requestId); + const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestDetails); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { ...defaultLondonTransactionData, value: balanceInWeiBars, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.INSUFFICIENT_ACCOUNT_BALANCE; - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('should execute "eth_sendRawTransaction" for London transactions', async function () { - const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); - const gasPrice = await relay.gasPrice(requestId); + const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); - const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); const balanceChange = receiverEndBalance - receiverInitialBalance; expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString()); }); it('should execute "eth_sendRawTransaction" and deploy a large contract', async function () { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, @@ -1208,8 +1218,8 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1220,7 +1230,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // if calldata's size fails into the range of [2568 bytes, 5217 bytes], the request fails and throw // `Null Entity ID` error. This unit test makes sure that with the new fix, requests should work with all case scenarios. it('should execute "eth_sendRawTransaction" and deploy a contract with any arbitrary calldata size', async () => { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const randomBytes = [2566, 2568, 3600, 5217, 7200]; @@ -1228,15 +1238,15 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[0].address, requestId), + nonce: await relay.getAccountNonce(accounts[0].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, data: '0x' + '00'.repeat(bytes), }; const signedTx = await accounts[0].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1246,11 +1256,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should delete the file created while execute "eth_sendRawTransaction" to deploy a large contract', async function () { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, @@ -1258,10 +1268,10 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); await Utils.wait(1000); - const txInfo = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const txInfo = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); const contractResult = await mirrorNode.get(`/contracts/${txInfo.contract_id}`); const fileInfo = await new FileInfoQuery().setFileId(contractResult.file_id).execute(servicesNode.client); @@ -1272,11 +1282,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" and fail when deploying too large contract', async function () { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[1].address, requestId), + nonce: await relay.getAccountNonce(accounts[1].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, @@ -1286,7 +1296,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[1].wallet.signTransaction(transaction); const error = predefined.TRANSACTION_SIZE_TOO_BIG('132320', String(constants.SEND_RAW_TRANSACTION_SIZE_LIMIT)); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('should execute "eth_sendRawTransaction" of type 1 and deploy a real contract', async function () { @@ -1295,12 +1305,12 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLegacy2930TransactionData, value: 0, data: basicContract.bytecode, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1316,12 +1326,12 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLondonTransactionData, value: 0, data: basicContract.bytecode, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('max_fee_per_gas'); @@ -1334,13 +1344,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" and deploy a contract with more than 2 HBAR transaction fee and less than max transaction fee', async function () { - const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId); + const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestDetails); - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: Constants.MAX_GAS_PER_SEC, @@ -1348,9 +1358,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); - const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1364,11 +1374,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" and deploy a contract with more than max transaction fee', async function () { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: Constants.MAX_GAS_PER_SEC, @@ -1377,7 +1387,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.INTERNAL_ERROR(); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestDetails]); }); describe('Prechecks', async function () { @@ -1385,13 +1395,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), chainId: INCORRECT_CHAIN_ID, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.UNSUPPORTED_CHAIN_ID('0x3e7', CHAIN_ID); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('should fail "eth_sendRawTransaction" for EIP155 transaction with not enough gas', async function () { @@ -1399,15 +1409,18 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), gasLimit: gasLimit, - gasPrice: await relay.gasPrice(requestId), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_LIMIT_TOO_LOW(gasLimit, Constants.MAX_GAS_PER_SEC); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ + signedTx, + requestDetails, + ]); }); it('should fail "eth_sendRawTransaction" for EIP155 transaction with a too high gasLimit', async function () { @@ -1415,15 +1428,18 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), gasLimit: gasLimit, - gasPrice: await relay.gasPrice(requestId), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_LIMIT_TOO_HIGH(gasLimit, Constants.MAX_GAS_PER_SEC); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ + signedTx, + requestDetails, + ]); }); it('should fail "eth_sendRawTransaction" for London transaction with not enough gas', async function () { @@ -1431,13 +1447,16 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), gasLimit: gasLimit, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_LIMIT_TOO_LOW(gasLimit, Constants.MAX_GAS_PER_SEC); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ + signedTx, + requestDetails, + ]); }); it('should fail "eth_sendRawTransaction" for London transaction with a too high gasLimit', async function () { @@ -1445,13 +1464,16 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), gasLimit: gasLimit, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_LIMIT_TOO_HIGH(gasLimit, Constants.MAX_GAS_PER_SEC); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ + signedTx, + requestDetails, + ]); }); it('should fail "eth_sendRawTransaction" for legacy EIP 155 transactions (with gas price too low)', async function () { @@ -1459,69 +1481,72 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...default155TransactionData, gasPrice: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ + signedTx, + requestDetails, + ]); }); it('@release fail "eth_getTransactionReceipt" on precheck with wrong nonce error when sending a tx with the same nonce twice', async function () { - const nonce = await relay.getAccountNonce(accounts[2].address, requestId); + const nonce = await relay.getAccountNonce(accounts[2].address, requestDetails); const transaction = { ...default155TransactionData, to: parentContractAddress, nonce: nonce, - maxFeePerGas: await relay.gasPrice(requestId), + maxFeePerGas: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const txHash1 = await relay.sendRawTransaction(signedTx, requestId); - const mirrorResult = await mirrorNode.get(`/contracts/results/${txHash1}`, requestId); + const txHash1 = await relay.sendRawTransaction(signedTx, requestDetails); + const mirrorResult = await mirrorNode.get(`/contracts/results/${txHash1}`, requestDetails); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; - const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [txHash1], requestId); - const currentPrice = await relay.gasPrice(requestId); + const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [txHash1], requestDetails); + const currentPrice = await relay.gasPrice(requestDetails); Assertions.transactionReceipt(res, mirrorResult, currentPrice); const error = predefined.NONCE_TOO_LOW(nonce, nonce + 1); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('@release fail "eth_getTransactionReceipt" on precheck with wrong nonce error when sending a tx with a higher nonce', async function () { - const nonce = await relay.getAccountNonce(accounts[2].address, requestId); + const nonce = await relay.getAccountNonce(accounts[2].address, requestDetails); const transaction = { ...default155TransactionData, to: parentContractAddress, nonce: nonce + 100, - gasPrice: await relay.gasPrice(requestId), + gasPrice: await relay.gasPrice(requestDetails), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.NONCE_TOO_HIGH(nonce + 100, nonce); - await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestId]); + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); it('@release fail "eth_getTransactionReceipt" on submitting with wrong nonce error when sending a tx with the same nonce twice', async function () { - const nonce = await relay.getAccountNonce(accounts[2].address, requestId); + const nonce = await relay.getAccountNonce(accounts[2].address, requestDetails); const transaction1 = { ...default155TransactionData, to: parentContractAddress, nonce: nonce, - maxFeePerGas: await relay.gasPrice(requestId), + maxFeePerGas: await relay.gasPrice(requestDetails), }; const signedTx1 = await accounts[2].wallet.signTransaction(transaction1); await Promise.all([ Promise.allSettled([ - relay.sendRawTransaction(signedTx1, requestId), - relay.sendRawTransaction(signedTx1, requestId), + relay.sendRawTransaction(signedTx1, requestDetails), + relay.sendRawTransaction(signedTx1, requestDetails), ]).then((values) => { const fulfilled = values.find((obj) => obj.status === 'fulfilled'); const rejected = values.find((obj) => obj.status === 'rejected'); @@ -1542,24 +1567,24 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release should execute "eth_getTransactionByHash" for existing transaction', async function () { - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestId), + nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const mirrorTransaction = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const mirrorTransaction = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [transactionHash], - requestId, + requestDetails, ); - const addressResult = await mirrorNode.get(`/accounts/${res.from}`, requestId); + const addressResult = await mirrorNode.get(`/accounts/${res.from}`, requestDetails); mirrorTransaction.from = addressResult.evm_address; Assertions.transaction(res, mirrorTransaction); @@ -1569,7 +1594,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [Address.NON_EXISTING_TX_HASH], - requestId, + requestDetails, ); expect(res).to.be.null; }); diff --git a/packages/server/tests/clients/mirrorClient.ts b/packages/server/tests/clients/mirrorClient.ts index 51565a03a9..2b640d43d8 100644 --- a/packages/server/tests/clients/mirrorClient.ts +++ b/packages/server/tests/clients/mirrorClient.ts @@ -22,6 +22,7 @@ import Axios, { AxiosInstance } from 'axios'; import axiosRetry from 'axios-retry'; import { Logger } from 'pino'; import { Utils } from '../helpers/utils'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; export default class MirrorClient { private readonly logger: Logger; @@ -63,9 +64,8 @@ export default class MirrorClient { this.client = mirrorNodeClient; } - async get(path: string, requestId?: string) { - const requestIdPrefix = Utils.formatRequestIdMessage(requestId); - this.logger.debug(`${requestIdPrefix} [GET] MirrorNode ${path} endpoint`); + async get(path: string, requestDetails: RequestDetails) { + this.logger.debug(`${requestDetails.formattedRequestId} [GET] MirrorNode ${path} endpoint`); return (await this.client.get(path)).data; } } diff --git a/packages/server/tests/helpers/utils.ts b/packages/server/tests/helpers/utils.ts index 9b20e0f9ce..1146bcb11b 100644 --- a/packages/server/tests/helpers/utils.ts +++ b/packages/server/tests/helpers/utils.ts @@ -34,6 +34,7 @@ import { Context } from 'mocha'; import { GitHubClient } from '../clients/githubClient'; import MirrorClient from '../clients/mirrorClient'; import { HeapDifferenceStatistics } from '../types/HeapDifferenceStatistics'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; export class Utils { static readonly HEAP_SIZE_DIFF_MEMORY_LEAK_THRESHOLD: number = 1e6; // 1 MB @@ -257,14 +258,14 @@ export class Utils { * * @param {MirrorClient} mirrorNode The mirror node client. * @param {AliasAccount} creator The creator account for the alias. - * @param {string} requestId The unique identifier for the request. + * @param {string} requestDetails The request details used for logging. * @param {string} balanceInTinyBar The initial balance for the alias account in tiny bars. Defaults to 10 HBAR. * @returns {Promise} A promise resolving to the created alias account. */ static readonly createAliasAccount = async ( mirrorNode: MirrorClient, creator: AliasAccount, - requestId: string, + requestDetails: RequestDetails, balanceInTinyBar: string = '1000000000', //10 HBAR ): Promise => { const signer = creator.wallet; @@ -279,7 +280,7 @@ export class Utils { value: accountBalance, }); - const mirrorNodeAccount = (await mirrorNode.get(`/accounts/${address}`, requestId)).account; + const mirrorNodeAccount = (await mirrorNode.get(`/accounts/${address}`, requestDetails)).account; const accountId = AccountId.fromString(mirrorNodeAccount); const client: ServicesClient = new ServicesClient( process.env.HEDERA_NETWORK!, @@ -306,14 +307,18 @@ export class Utils { initialAccount: AliasAccount, neededAccounts: number, initialAmountInTinyBar: string, - requestId: string, + requestDetails: RequestDetails, ): Promise { - const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const accounts: AliasAccount[] = []; for (let i = 0; i < neededAccounts; i++) { - const account = await Utils.createAliasAccount(mirrorNode, initialAccount, requestId, initialAmountInTinyBar); + const account = await Utils.createAliasAccount( + mirrorNode, + initialAccount, + requestDetails, + initialAmountInTinyBar, + ); global.logger.trace( - `${requestIdPrefix} Create new Eth compatible account w privateKey: ${account.privateKey}, alias: ${account.address} and balance ~${initialAmountInTinyBar} wei`, + `${requestDetails.formattedRequestId} Create new Eth compatible account w privateKey: ${account.privateKey}, alias: ${account.address} and balance ~${initialAmountInTinyBar} wei`, ); accounts.push(account); } diff --git a/packages/ws-server/src/controllers/index.ts b/packages/ws-server/src/controllers/index.ts index 6289c7cffb..b7d02ed7a3 100644 --- a/packages/ws-server/src/controllers/index.ts +++ b/packages/ws-server/src/controllers/index.ts @@ -32,7 +32,7 @@ import { MethodNotFound, IPRateLimitExceeded, } from '@hashgraph/json-rpc-server/dist/koaJsonRpc/lib/RpcError'; -import { IRequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/IRequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; /** * Handles sending requests to a Relay by calling a specified method with given parameters. @@ -59,13 +59,13 @@ const handleSendingRequestsToRelay = async ({ ctx, }): Promise => { logger.trace(`${connectionIdPrefix} ${requestIdPrefix}: Submitting request=${JSON.stringify(request)} to relay.`); - const requestDetails = { requestIdPrefix: requestIdPrefix, requestIp: '' } as IRequestDetails; + const requestDetails = new RequestDetails({ requestId: ctx.req.id, ipAddress: ctx.request.ip }); try { const resolvedParams = resolveParams(method, params); const [service, methodName] = method.split('_'); // Rearrange the parameters for certain methods, since not everywhere requestDetails is last aparameter - const paramRearrangementMap: { [key: string]: (params: any[], requestDetails: IRequestDetails) => any[] } = { + const paramRearrangementMap: { [key: string]: (params: any[], requestDetails: RequestDetails) => any[] } = { estimateGas: (params, requestDetails) => [...params, null, requestDetails], getStorageAt: (params, requestDetails) => [params[0], params[1], requestDetails, params[2]], default: (params, requestDetails) => [...params, requestDetails], diff --git a/packages/ws-server/src/webSocketServer.ts b/packages/ws-server/src/webSocketServer.ts index 47c8da7aa0..768082a963 100644 --- a/packages/ws-server/src/webSocketServer.ts +++ b/packages/ws-server/src/webSocketServer.ts @@ -59,7 +59,7 @@ const wsMetricRegistry = new WsMetricRegistry(register); const pingInterval = Number(process.env.WS_PING_INTERVAL || 100000); const app = websockify(new Koa()); -app.ws.use(async (ctx) => { +app.ws.use(async (ctx: Koa.Context) => { // Increment the total opened connections wsMetricRegistry.getCounter('totalOpenedConnections').inc(); @@ -204,7 +204,7 @@ app.ws.use(async (ctx) => { const httpApp = new KoaJsonRpc(logger, register).getKoaApp(); collectDefaultMetrics({ register, prefix: 'rpc_relay_' }); -httpApp.use(async (ctx, next) => { +httpApp.use(async (ctx: Koa.Context, next: Koa.Next) => { // prometheus metrics exposure if (ctx.url === '/metrics') { ctx.status = 200; @@ -215,10 +215,7 @@ httpApp.use(async (ctx, next) => { } else if (ctx.url === '/health/readiness') { // readiness endpoint try { - const result = relay.eth().chainId({ - requestIdPrefix: ctx.state.reqId, - requestIp: ctx.request.ip, - }); + const result = relay.eth().chainId(httpApp.getRequestDetails()); if (result.includes('0x12')) { ctx.status = 200; ctx.body = 'OK'; diff --git a/packages/ws-server/tests/acceptance/call.spec.ts b/packages/ws-server/tests/acceptance/call.spec.ts index a00ae92d04..108b3737cc 100644 --- a/packages/ws-server/tests/acceptance/call.spec.ts +++ b/packages/ws-server/tests/acceptance/call.spec.ts @@ -25,6 +25,7 @@ import { WsTestConstant, WsTestHelper } from '../helper'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import ERC20MockJson from '@hashgraph/json-rpc-server/tests/contracts/ERC20Mock.json'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; describe('@web-socket-batch-1 eth_call', async function () { const METHOD_NAME = 'eth_call'; @@ -60,14 +61,14 @@ describe('@web-socket-batch-1 eth_call', async function () { // @ts-ignore const { mirrorNode } = global; - let requestId: string, - erc20TokenAddr: string, + let erc20TokenAddr: string, accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider, erc20EtherInterface: ethers.Interface; + const requestDetails = new RequestDetails({ requestId: 'ws_callTest', ipAddress: '0.0.0.0' }); + before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '2500000000'; //25 Hbar @@ -78,7 +79,7 @@ describe('@web-socket-batch-1 eth_call', async function () { initialAccount, neededAccounts, initialAmount, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); diff --git a/packages/ws-server/tests/acceptance/estimateGas.spec.ts b/packages/ws-server/tests/acceptance/estimateGas.spec.ts index 55750ebb69..0eabd53442 100644 --- a/packages/ws-server/tests/acceptance/estimateGas.spec.ts +++ b/packages/ws-server/tests/acceptance/estimateGas.spec.ts @@ -25,6 +25,7 @@ import { WsTestConstant, WsTestHelper } from '../helper'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import basicContractJson from '@hashgraph/json-rpc-server/tests/contracts/Basic.json'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; describe('@web-socket-batch-1 eth_estimateGas', async function () { const METHOD_NAME = 'eth_estimateGas'; @@ -38,16 +39,14 @@ describe('@web-socket-batch-1 eth_estimateGas', async function () { currentPrice: number, expectedGas: number, gasPriceDeviation: number, - ethersWsProvider: WebSocketProvider, - requestId = 'eth_estimateGas'; - let requestDetails; + ethersWsProvider: WebSocketProvider; + + const requestDetails = new RequestDetails({ requestId: 'ws_estimateGasTest', ipAddress: '0.0.0.0' }); before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '2500000000'; //25 Hbar const neededAccounts: number = 1; - requestDetails = { requestIdPrefix: `[Request ID: testId]`, requestIp: '0.0.0.0' }; accounts.push( ...(await Utils.createMultipleAliasAccounts( @@ -55,7 +54,7 @@ describe('@web-socket-batch-1 eth_estimateGas', async function () { initialAccount, neededAccounts, initialAmount, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); diff --git a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts index 25fb863145..bda5ff3dd0 100644 --- a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts +++ b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts @@ -24,7 +24,7 @@ import { ethers, WebSocketProvider } from 'ethers'; import { WsTestConstant, WsTestHelper } from '../helper'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; -import { IRequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/IRequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; describe('@web-socket-batch-2 eth_getStorageAt', async function () { const METHOD_NAME = 'eth_getStorageAt'; @@ -55,12 +55,10 @@ describe('@web-socket-batch-2 eth_getStorageAt', async function () { let params: any[], accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; - let requestId: string; - let requestDetails: IRequestDetails; + + const requestDetails = new RequestDetails({ requestId: 'ws_getStorageAtTest', ipAddress: '0.0.0.0' }); before(async () => { - requestId = `[Request ID: getStorageAtTest]`; - requestDetails = { requestIdPrefix: `${requestId}`, requestIp: '0.0.0.0' }; const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '2500000000'; //25 Hbar @@ -71,7 +69,7 @@ describe('@web-socket-batch-2 eth_getStorageAt', async function () { initialAccount, neededAccounts, initialAmount, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); From 9c842b16097ed9b3bc8d8377916e9120347255c3 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Mon, 16 Sep 2024 11:14:06 +0300 Subject: [PATCH 25/48] chore: fix localLRUCache.spec.ts Signed-off-by: Victor Yanev --- .../tests/lib/clients/localLRUCache.spec.ts | 97 ++++++++++--------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/packages/relay/tests/lib/clients/localLRUCache.spec.ts b/packages/relay/tests/lib/clients/localLRUCache.spec.ts index 86a711a747..f678b8e320 100644 --- a/packages/relay/tests/lib/clients/localLRUCache.spec.ts +++ b/packages/relay/tests/lib/clients/localLRUCache.spec.ts @@ -24,6 +24,7 @@ import { Registry } from 'prom-client'; import pino from 'pino'; import { LocalLRUCache } from '../../../src/lib/clients'; import constants from '../../../src/lib/constants'; +import { RequestDetails } from '../../../src/lib/types/RequestDetails'; const logger = pino(); const registry = new Registry(); @@ -35,10 +36,10 @@ chai.use(chaiAsPromised); describe('LocalLRUCache Test Suite', async function () { this.timeout(10000); - let requestIdPrefix: string; + + const requestDetails = new RequestDetails({ requestId: 'localLRUCacheTest', ipAddress: '0.0.0.0' }); this.beforeAll(() => { - requestIdPrefix = `[Request ID: localLRUCacheTest]`; localLRUCache = new LocalLRUCache(logger.child({ name: `cache` }), registry); }); @@ -48,65 +49,65 @@ describe('LocalLRUCache Test Suite', async function () { describe('verify simple cache', async function () { it('get on empty cache return null', async function () { - const cacheValue = await localLRUCache.get('test', callingMethod, requestIdPrefix); + const cacheValue = await localLRUCache.get('test', callingMethod, requestDetails); expect(cacheValue).to.be.null; }); it('get on valid string cache returns non null', async function () { const key = 'key'; const expectedValue = 'value'; - await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); - const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); + await localLRUCache.set(key, expectedValue, callingMethod, requestDetails); + const cacheValue = await localLRUCache.get(key, callingMethod, requestDetails); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid int cache returns non null', async function () { const key = 'key'; const expectedValue = 1; - await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); - const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); + await localLRUCache.set(key, expectedValue, callingMethod, requestDetails); + const cacheValue = await localLRUCache.get(key, callingMethod, requestDetails); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid false boolean cache returns non null', async function () { const key = 'key'; const expectedValue = false; - await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); - const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); + await localLRUCache.set(key, expectedValue, callingMethod, requestDetails); + const cacheValue = await localLRUCache.get(key, callingMethod, requestDetails); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid true boolean cache returns non null', async function () { const key = 'key'; const expectedValue = true; - await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); - const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); + await localLRUCache.set(key, expectedValue, callingMethod, requestDetails); + const cacheValue = await localLRUCache.get(key, callingMethod, requestDetails); expect(cacheValue).to.be.equal(expectedValue); }); it('get on valid object cache returns non null', async function () { const key = 'key'; const expectedValue = { key: 'value' }; - await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); - const cacheValue = await localLRUCache.get(key, callingMethod, requestIdPrefix); + await localLRUCache.set(key, expectedValue, callingMethod, requestDetails); + const cacheValue = await localLRUCache.get(key, callingMethod, requestDetails); expect(cacheValue).to.be.equal(expectedValue); }); it('delete a valid object', async function () { const key = 'key'; const expectedValue = { key: 'value' }; - await localLRUCache.set(key, expectedValue, callingMethod, requestIdPrefix); - const cacheValueBeforeDelete = await localLRUCache.get(key, callingMethod, requestIdPrefix); - localLRUCache.delete(key, callingMethod, requestIdPrefix); + await localLRUCache.set(key, expectedValue, callingMethod, requestDetails); + const cacheValueBeforeDelete = await localLRUCache.get(key, callingMethod, requestDetails); + await localLRUCache.delete(key, callingMethod, requestDetails); - const cacheValueAfterDelete = await localLRUCache.get(key, callingMethod, requestIdPrefix); + const cacheValueAfterDelete = await localLRUCache.get(key, callingMethod, requestDetails); expect(cacheValueBeforeDelete).to.not.be.null; expect(cacheValueAfterDelete).to.be.null; }); }); describe('verify cache management', async function () { - this.beforeEach(() => { + beforeEach(() => { process.env.CACHE_MAX = constants.CACHE_MAX.toString(); }); @@ -121,12 +122,12 @@ describe('LocalLRUCache Test Suite', async function () { }; Object.entries(keyValuePairs).forEach(([key, value]) => { - customLocalLRUCache.set(key, value, callingMethod, requestIdPrefix); + customLocalLRUCache.set(key, value, callingMethod, requestDetails); }); - const key1 = await customLocalLRUCache.get('key1', callingMethod, requestIdPrefix); - const key2 = await customLocalLRUCache.get('key2', callingMethod, requestIdPrefix); - const key3 = await customLocalLRUCache.get('key3', callingMethod, requestIdPrefix); + const key1 = await customLocalLRUCache.get('key1', callingMethod, requestDetails); + const key2 = await customLocalLRUCache.get('key2', callingMethod, requestDetails); + const key3 = await customLocalLRUCache.get('key3', callingMethod, requestDetails); // expect cache to have capped at max size expect(key1).to.be.null; // key1 should have been evicted expect(key2).to.be.equal(keyValuePairs.key2); @@ -137,20 +138,20 @@ describe('LocalLRUCache Test Suite', async function () { const customLocalLRUCache = new LocalLRUCache(logger.child({ name: `cache` }), registry); const key = 'key'; let valueCount = 0; // keep track of values sets - await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestIdPrefix); - await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestIdPrefix); - await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestIdPrefix); - const cacheValue = await customLocalLRUCache.get(key, callingMethod, requestIdPrefix); - // expect cache to have latest value for key + await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestDetails); + await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestDetails); + await customLocalLRUCache.set(key, ++valueCount, callingMethod, requestDetails); + const cacheValue = await customLocalLRUCache.get(key, callingMethod, requestDetails); + // expect cache to have the latest value for key expect(cacheValue).to.be.equal(valueCount); }); it('verify cache ttl nature', async function () { const customLocalLRUCache = new LocalLRUCache(logger.child({ name: `cache` }), registry); const key = 'key'; - await customLocalLRUCache.set(key, 'value', callingMethod, requestIdPrefix, 100); // set ttl to 1 ms + await customLocalLRUCache.set(key, 'value', callingMethod, requestDetails, 100); // set ttl to 1 ms await new Promise((r) => setTimeout(r, 500)); // wait for ttl to expire - const cacheValue = await customLocalLRUCache.get(key, callingMethod, requestIdPrefix); + const cacheValue = await customLocalLRUCache.get(key, callingMethod, requestDetails); expect(cacheValue).to.be.null; }); }); @@ -159,17 +160,17 @@ describe('LocalLRUCache Test Suite', async function () { it('should retrieve keys matching a glob-style pattern with *', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); + await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestDetails); } - await expect(localLRUCache.keys('h*llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); + await expect(localLRUCache.keys('h*llo', callingMethod, requestDetails)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with ?', async function () { const keys = ['hello', 'hallo', 'hxllo']; for (let i = 0; i < keys.length; i++) { - await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); + await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestDetails); } - await expect(localLRUCache.keys('h?llo', callingMethod, requestIdPrefix)).to.eventually.have.members(keys); + await expect(localLRUCache.keys('h?llo', callingMethod, requestDetails)).to.eventually.have.members(keys); }); it('should retrieve keys matching a glob-style pattern with []', async function () { @@ -177,10 +178,10 @@ describe('LocalLRUCache Test Suite', async function () { const key2 = 'hallo'; const pattern = 'h[ae]llo'; - await localLRUCache.set(key1, 'value1', callingMethod, requestIdPrefix); - await localLRUCache.set(key2, 'value2', callingMethod, requestIdPrefix); + await localLRUCache.set(key1, 'value1', callingMethod, requestDetails); + await localLRUCache.set(key2, 'value2', callingMethod, requestDetails); - const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await localLRUCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2]); }); @@ -189,10 +190,10 @@ describe('LocalLRUCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[^e]llo'; - await localLRUCache.set(key1, 'value1', callingMethod, requestIdPrefix); - await localLRUCache.set(key2, 'value2', callingMethod, requestIdPrefix); + await localLRUCache.set(key1, 'value1', callingMethod, requestDetails); + await localLRUCache.set(key2, 'value2', callingMethod, requestDetails); - const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await localLRUCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2]); }); @@ -201,21 +202,21 @@ describe('LocalLRUCache Test Suite', async function () { const key2 = 'hbllo'; const pattern = 'h[a-b]llo'; - await localLRUCache.set(key1, 'value1', callingMethod, requestIdPrefix); - await localLRUCache.set(key2, 'value2', callingMethod, requestIdPrefix); + await localLRUCache.set(key1, 'value1', callingMethod, requestDetails); + await localLRUCache.set(key2, 'value2', callingMethod, requestDetails); - const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await localLRUCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2]); }); it('should retrieve keys matching a pattern with escaped special characters', async function () { const keys = ['h*llo', 'h?llo', 'h[llo', 'h]llo']; for (let i = 0; i < keys.length; i++) { - await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestIdPrefix); + await localLRUCache.set(keys[i], `value${i}`, callingMethod, requestDetails); } for (const key of keys) { await expect( - localLRUCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod, requestIdPrefix), + localLRUCache.keys(key.replace(/([*?[\]])/g, '\\$1'), callingMethod, requestDetails), ).eventually.has.members([key]); } }); @@ -226,11 +227,11 @@ describe('LocalLRUCache Test Suite', async function () { const key3 = 'age'; const pattern = '*'; - await localLRUCache.set(key1, 'Jack', callingMethod, requestIdPrefix); - await localLRUCache.set(key2, 'Stuntman', callingMethod, requestIdPrefix); - await localLRUCache.set(key3, '35', callingMethod, requestIdPrefix); + await localLRUCache.set(key1, 'Jack', callingMethod, requestDetails); + await localLRUCache.set(key2, 'Stuntman', callingMethod, requestDetails); + await localLRUCache.set(key3, '35', callingMethod, requestDetails); - const keys = await localLRUCache.keys(pattern, callingMethod, requestIdPrefix); + const keys = await localLRUCache.keys(pattern, callingMethod, requestDetails); expect(keys).to.include.members([key1, key2, key3]); }); }); From 975df9021ae6a30d6c3c15d81777a4da8c08b229 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Mon, 16 Sep 2024 11:16:33 +0300 Subject: [PATCH 26/48] chore: fix debug.spec.ts Signed-off-by: Victor Yanev --- .../lib/services/debugService/debug.spec.ts | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/relay/tests/lib/services/debugService/debug.spec.ts b/packages/relay/tests/lib/services/debugService/debug.spec.ts index 6230493457..e5fdf867a4 100644 --- a/packages/relay/tests/lib/services/debugService/debug.spec.ts +++ b/packages/relay/tests/lib/services/debugService/debug.spec.ts @@ -28,13 +28,14 @@ import { MirrorNodeClient } from '../../../../src/lib/clients'; import pino from 'pino'; import { TracerType } from '../../../../src/lib/constants'; import { DebugService } from '../../../../src/lib/services/debugService'; -import { getQueryParams, getRequestId } from '../../../helpers'; +import { getQueryParams } from '../../../helpers'; import RelayAssertions from '../../../assertions'; import { predefined } from '../../../../src'; import { CacheService } from '../../../../src/lib/services/cacheService/cacheService'; import { CommonService } from '../../../../src/lib/services/ethService'; import { IOpcodesResponse } from '../../../../src/lib/clients/models/IOpcodesResponse'; import { strip0x } from '../../../../src/formatters'; +import { RequestDetails } from '../../../../src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); chai.use(chaiAsPromised); @@ -51,6 +52,7 @@ let cacheService: CacheService; describe('Debug API Test Suite', async function () { this.timeout(10000); + const requestDetails = new RequestDetails({ requestId: 'debugTest', ipAddress: '0.0.0.0' }); const transactionHash = '0xb7a433b014684558d4154c73de3ed360bd5867725239938c2143acb7a76bca82'; const nonExistentTransactionHash = '0xb8a433b014684558d4154c73de3ed360bd5867725239938c2143acb7a76bca82'; const contractAddress = '0x0000000000000000000000000000000000000409'; @@ -337,7 +339,7 @@ describe('Debug API Test Suite', async function () { debugService.debug_traceTransaction, true, debugService, - [transactionHash, callTracer, tracerConfigFalse, getRequestId()], + [transactionHash, callTracer, tracerConfigFalse, requestDetails], ); }); @@ -348,7 +350,7 @@ describe('Debug API Test Suite', async function () { transactionHash, callTracer, tracerConfigFalse, - getRequestId(), + requestDetails, ); expect(traceTransaction).to.exist; }); @@ -360,7 +362,7 @@ describe('Debug API Test Suite', async function () { debugService.debug_traceTransaction, true, debugService, - [transactionHash, callTracer, tracerConfigFalse, getRequestId()], + [transactionHash, callTracer, tracerConfigFalse, requestDetails], ); }); }); @@ -398,7 +400,7 @@ describe('Debug API Test Suite', async function () { transactionHash, callTracer, tracerConfigFalse, - getRequestId(), + requestDetails, ); expect(result).to.deep.equal(expectedResult); @@ -420,7 +422,7 @@ describe('Debug API Test Suite', async function () { transactionHash, callTracer, tracerConfigTrue, - getRequestId(), + requestDetails, ); expect(result).to.deep.equal(expectedResult); @@ -467,7 +469,7 @@ describe('Debug API Test Suite', async function () { transactionHash, opcodeLogger, config, - getRequestId(), + requestDetails, ); expect(result).to.deep.equal(expectedResult); @@ -509,7 +511,7 @@ describe('Debug API Test Suite', async function () { nonExistentTransactionHash, callTracer, tracerConfigTrue, - getRequestId(), + requestDetails, ]); }); @@ -526,15 +528,14 @@ describe('Debug API Test Suite', async function () { }); describe('resolveAddress', async function () { - const requestIdPrefix = `[Request ID: testId]`; it('should return null address with invalid parameters in resolveAddress', async function () { - const address = await debugService.resolveAddress(null!, requestIdPrefix); + const address = await debugService.resolveAddress(null!, requestDetails); expect(address).to.be.null; }); it('should return passed address on notFound entity from the mirror node', async function () { restMock.onGet(ACCOUNT_BY_ADDRESS).reply(404, notFound); - const address = await debugService.resolveAddress(accountAddress, requestIdPrefix); + const address = await debugService.resolveAddress(accountAddress, requestDetails); expect(address).to.eq(accountAddress); }); }); From 24e97dde96969cda4dfc47a8b6d4ecfb5517ae1f Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Mon, 16 Sep 2024 11:18:00 +0300 Subject: [PATCH 27/48] chore: fix cacheService.spec.ts Signed-off-by: Victor Yanev --- .../tests/acceptance/cacheService.spec.ts | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/packages/server/tests/acceptance/cacheService.spec.ts b/packages/server/tests/acceptance/cacheService.spec.ts index d5c4d65eda..b37e82b3ee 100644 --- a/packages/server/tests/acceptance/cacheService.spec.ts +++ b/packages/server/tests/acceptance/cacheService.spec.ts @@ -21,6 +21,7 @@ import { expect } from 'chai'; import { CacheService } from '../../../../packages/relay/src/lib/services/cacheService/cacheService'; import { Registry } from 'prom-client'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; const registry = new Registry(); const DATA_LABEL_PREFIX = 'acceptance-test-'; @@ -31,7 +32,9 @@ const CALLING_METHOD = 'AcceptanceTest'; describe('@cache-service Acceptance Tests for shared cache', function () { let cacheService: CacheService; - const requestIdPrefix = `[RequestID: cacheServiceTest}]`; + + const requestDetails = new RequestDetails({ requestId: 'cacheServiceTest', ipAddress: '0.0.0.0' }); + before(async () => { cacheService = new CacheService(global.logger, registry); await new Promise((r) => setTimeout(r, 1000)); @@ -40,22 +43,22 @@ describe('@cache-service Acceptance Tests for shared cache', function () { it('Correctly performs set, get and delete operations', async () => { const dataLabel = `${DATA_LABEL_PREFIX}1`; - await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix, undefined); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestDetails); await new Promise((r) => setTimeout(r, 200)); - const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(cache).to.deep.eq(DATA, 'set method saves to shared cache'); - const cacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const cacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(cacheFromService).to.deep.eq(DATA, 'getAsync method reads correctly from shared cache'); - await cacheService.delete(dataLabel, CALLING_METHOD, requestIdPrefix); + await cacheService.delete(dataLabel, CALLING_METHOD, requestDetails); await new Promise((r) => setTimeout(r, 200)); - const deletedCache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const deletedCache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(deletedCache).to.eq(null, 'the delete method correctly deletes from shared cache'); - const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(deletedCacheFromService).to.eq(null, 'getAsync method cannot read deleted cache'); }); @@ -63,18 +66,18 @@ describe('@cache-service Acceptance Tests for shared cache', function () { const ttl = 1000; const dataLabel = `${DATA_LABEL_PREFIX}2`; - await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix, ttl); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestDetails, ttl); await new Promise((r) => setTimeout(r, 200)); - const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const cache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(cache).to.deep.eq(DATA, 'data is stored with TTL'); await new Promise((r) => setTimeout(r, ttl)); - const expiredCache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const expiredCache = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(expiredCache).to.eq(null, 'cache expires after TTL period'); - const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const deletedCacheFromService = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(deletedCacheFromService).to.eq(null, 'getAsync method cannot read expired cache'); }); @@ -85,10 +88,10 @@ describe('@cache-service Acceptance Tests for shared cache', function () { const serviceWithDisabledRedis = new CacheService(global.logger, registry); await new Promise((r) => setTimeout(r, 1000)); expect(serviceWithDisabledRedis.isRedisEnabled()).to.eq(false, 'redis is disabled'); - await serviceWithDisabledRedis.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); + await serviceWithDisabledRedis.set(dataLabel, DATA, CALLING_METHOD, requestDetails); await new Promise((r) => setTimeout(r, 200)); - const dataInLRU = await serviceWithDisabledRedis.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const dataInLRU = await serviceWithDisabledRedis.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(dataInLRU).to.deep.eq(DATA, 'data is stored in local cache'); process.env.REDIS_ENABLED = 'true'; @@ -97,10 +100,10 @@ describe('@cache-service Acceptance Tests for shared cache', function () { it('Cache set by one instance can be accessed by another', async () => { const dataLabel = `${DATA_LABEL_PREFIX}4`; const otherServiceInstance = new CacheService(global.logger, registry); - await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestDetails); await new Promise((r) => setTimeout(r, 200)); - const cachedData = await otherServiceInstance.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const cachedData = await otherServiceInstance.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(cachedData).to.deep.eq(DATA, 'cached data is read correctly by other service instance'); }); @@ -126,10 +129,10 @@ describe('@cache-service Acceptance Tests for shared cache', function () { }); it('test getAsync operation', async () => { - await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestDetails); await new Promise((r) => setTimeout(r, 200)); - const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(dataInLRU).to.deep.eq(DATA, 'data is stored in local cache'); }); @@ -140,21 +143,21 @@ describe('@cache-service Acceptance Tests for shared cache', function () { string: '5644', }; - await cacheService.multiSet(pairs, CALLING_METHOD, requestIdPrefix); + await cacheService.multiSet(pairs, CALLING_METHOD, requestDetails); await new Promise((r) => setTimeout(r, 200)); for (const key in pairs) { - const cachedValue = await cacheService.getAsync(key, CALLING_METHOD, requestIdPrefix); + const cachedValue = await cacheService.getAsync(key, CALLING_METHOD, requestDetails); expect(cachedValue).deep.equal(pairs[key]); } }); it('test delete operation', async () => { - await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestIdPrefix); + await cacheService.set(dataLabel, DATA, CALLING_METHOD, requestDetails); await new Promise((r) => setTimeout(r, 200)); - await cacheService.delete(dataLabel, CALLING_METHOD, requestIdPrefix); - const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestIdPrefix); + await cacheService.delete(dataLabel, CALLING_METHOD, requestDetails); + const dataInLRU = await cacheService.getAsync(dataLabel, CALLING_METHOD, requestDetails); expect(dataInLRU).to.be.null; }); }); From 531f94cfc865ae6e876a4ccaa21e57937c8f7818 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Mon, 16 Sep 2024 11:21:44 +0300 Subject: [PATCH 28/48] chore: fix hbarLimiter.spec.ts Signed-off-by: Victor Yanev --- .../tests/acceptance/hbarLimiter.spec.ts | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/packages/server/tests/acceptance/hbarLimiter.spec.ts b/packages/server/tests/acceptance/hbarLimiter.spec.ts index 280c6b492c..b282166c9c 100644 --- a/packages/server/tests/acceptance/hbarLimiter.spec.ts +++ b/packages/server/tests/acceptance/hbarLimiter.spec.ts @@ -36,6 +36,9 @@ import parentContractJson from '../contracts/Parent.json'; import EstimateGasContract from '../contracts/EstimateGasContract.json'; import largeContractJson from '../contracts/hbarLimiterContracts/largeSizeContract.json'; import mediumSizeContract from '../contracts/hbarLimiterContracts/mediumSizeContract.json'; +import { resolve } from 'path'; +import { config } from 'dotenv'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; config({ path: resolve(__dirname, '../localAcceptance.env') }); @@ -103,21 +106,21 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { return fileAppendTxFee; }; - const getExpectedCostOfLastLargeTx = async (requestId: string, txData: string) => { + const getExpectedCostOfLastLargeTx = async (txData: string, requestDetails: RequestDetails) => { const ethereumTransaction = ( await mirrorNode.get( `/transactions?transactiontype=ETHEREUMTRANSACTION&order=desc&account.id=${operatorAccount}&limit=1`, - requestId, + requestDetails, ) ).transactions[0]; const ethereumTxFee = sumAccountTransfers(ethereumTransaction.transfers, operatorAccount); - const { fileCreateTxFee, fileCreateTimestamp } = await getExpectedCostOfFileCreateTx(requestId); - const fileAppendTxFee = await getExpectedCostOfFileAppendTx(requestId, fileCreateTimestamp, txData); + const { fileCreateTxFee, fileCreateTimestamp } = await getExpectedCostOfFileCreateTx(requestDetails); + const fileAppendTxFee = await getExpectedCostOfFileAppendTx(requestDetails, fileCreateTimestamp, txData); const fileDeleteTx = ( await mirrorNode.get( `/transactions?transactiontype=FILEDELETE&order=desc&account.id=${operatorAccount}&limit=1`, - requestId, + requestDetails, ) ).transactions[0]; @@ -126,11 +129,11 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { return ethereumTxFee + fileCreateTxFee + fileAppendTxFee + fileDeleteTxFee; }; - const getExpectedCostOfLastSmallTx = async (requestId: string) => { + const getExpectedCostOfLastSmallTx = async (requestDetails: RequestDetails) => { const ethereumTransaction = ( await mirrorNode.get( `/transactions?transactiontype=ETHEREUMTRANSACTION&order=desc&account.id=${operatorAccount}&limit=1`, - requestId, + requestDetails, ) ).transactions[0]; return sumAccountTransfers(ethereumTransaction.transfers, operatorAccount); @@ -149,19 +152,16 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { type: 2, }; - // cached entities - let requestId: string; - let requestIdPrefix: string; + const requestDetails = new RequestDetails({ requestId: 'hbarLimiterTest', ipAddress: '0.0.0.0' }); before(async function () { // Restart the relay to reset the limits await global.restartLocalRelay(); - requestId = Utils.generateRequestId(); - requestIdPrefix = Utils.formatRequestIdMessage(requestId); - - logger.info(`${requestIdPrefix} Creating accounts`); - logger.info(`${requestIdPrefix} HBAR_RATE_LIMIT_TINYBAR: ${process.env.HBAR_RATE_LIMIT_TINYBAR}`); + logger.info(`${requestDetails.formattedRequestId} Creating accounts`); + logger.info( + `${requestDetails.formattedRequestId} HBAR_RATE_LIMIT_TINYBAR: ${process.env.HBAR_RATE_LIMIT_TINYBAR}`, + ); const initialAccount: AliasAccount = global.accounts[0]; @@ -172,15 +172,13 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { initialAccount, neededAccounts, initialBalance, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); }); beforeEach(async function () { - requestId = Utils.generateRequestId(); - requestIdPrefix = Utils.formatRequestIdMessage(requestId); await new Promise((r) => setTimeout(r, 3000)); }); @@ -192,25 +190,27 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { it('should execute "eth_sendRawTransaction" without triggering HBAR rate limit exceeded', async function () { const parentContract = await deployContract(parentContractJson, accounts[0].wallet); const parentContractAddress = parentContract.target as string; - global.logger.trace(`${requestIdPrefix} Deploy parent contract on address ${parentContractAddress}`); + global.logger.trace( + `${requestDetails.formattedRequestId} Deploy parent contract on address ${parentContractAddress}`, + ); - const gasPrice = await relay.gasPrice(requestId); + const gasPrice = await relay.gasPrice(requestDetails); const remainingHbarsBefore = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[1].address, requestId), + nonce: await relay.getAccountNonce(accounts[1].address, requestDetails), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; const signedTx = await accounts[1].wallet.signTransaction(transaction); - await expect(relay.call(testConstants.ETH_ENDPOINTS.ETH_SEND_RAW_TRANSACTION, [signedTx], requestId)).to.be - .fulfilled; + await expect(relay.call(testConstants.ETH_ENDPOINTS.ETH_SEND_RAW_TRANSACTION, [signedTx], requestDetails)).to + .be.fulfilled; const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); - const expectedCost = await getExpectedCostOfLastSmallTx(requestId); + const expectedCost = await getExpectedCostOfLastSmallTx(requestDetails); verifyRemainingLimit(expectedCost, remainingHbarsBefore, remainingHbarsAfter); }); @@ -222,7 +222,10 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { const contract = await deployContract(largeContractJson, accounts[0].wallet); const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); - const expectedCost = await getExpectedCostOfLastLargeTx(requestId, contract.deploymentTransaction()!.data); + const expectedCost = await getExpectedCostOfLastLargeTx( + contract.deploymentTransaction()!.data, + requestDetails, + ); verifyRemainingLimit(expectedCost, remainingHbarsBefore, remainingHbarsAfter); }); @@ -235,7 +238,7 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { await deployContract(EstimateGasContract, accounts[0].wallet); const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); - const expectedCost = await getExpectedCostOfLastSmallTx(requestId); + const expectedCost = await getExpectedCostOfLastSmallTx(requestDetails); verifyRemainingLimit(expectedCost, remainingHbarsBefore, remainingHbarsAfter); }); @@ -247,7 +250,10 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { const contract = await deployContract(mediumSizeContract, accounts[0].wallet); const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); - const expectedCost = await getExpectedCostOfLastLargeTx(requestId, contract.deploymentTransaction()!.data); + const expectedCost = await getExpectedCostOfLastLargeTx( + contract.deploymentTransaction()!.data, + requestDetails, + ); verifyRemainingLimit(expectedCost, remainingHbarsBefore, remainingHbarsAfter); }); @@ -292,18 +298,18 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { const TOLERANCE = 0.02; const remainingHbarsBefore = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); expect(remainingHbarsBefore).to.be.gt(0); - const operatorBalanceBefore = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestId)).balance + const operatorBalanceBefore = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestDetails)).balance .balance; const largeContract = await deployContract(largeContractJson, accounts[0].wallet); - const operatorBalanceAfter = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestId)).balance + const operatorBalanceAfter = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestDetails)).balance .balance; const amountPaidByOperator = operatorBalanceBefore - operatorBalanceAfter; const totalOperatorFees = await getExpectedCostOfLastLargeTx( - requestId, largeContract.deploymentTransaction()!.data, + requestDetails, ); const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); const hbarLimitReducedAmount = remainingHbarsBefore - remainingHbarsAfter; From ee2dc1225e07f6763dc62c91a05ab9ed402075f7 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Mon, 16 Sep 2024 12:52:54 +0300 Subject: [PATCH 29/48] chore: fix build Signed-off-by: Victor Yanev --- packages/relay/src/index.ts | 3 +-- .../src/lib/clients/cache/ICacheClient.ts | 2 +- .../lib/clients/cache/IRedisCacheClient.ts | 2 +- .../src/lib/clients/cache/localLRUCache.ts | 2 +- .../relay/src/lib/clients/cache/redisCache.ts | 2 +- .../relay/src/lib/clients/mirrorNodeClient.ts | 2 +- packages/relay/src/lib/clients/sdkClient.ts | 2 +- .../ethAddressHbarSpendingPlanRepository.ts | 2 +- .../hbarLimiter/hbarSpendingPlanRepository.ts | 2 +- packages/relay/src/lib/eth.ts | 4 +-- packages/relay/src/lib/hbarlimiter/index.ts | 2 +- packages/relay/src/lib/poller.ts | 2 +- packages/relay/src/lib/precheck.ts | 2 +- packages/relay/src/lib/relay.ts | 2 +- .../lib/services/cacheService/cacheService.ts | 2 +- .../services/debugService/IDebugService.ts | 3 +-- .../src/lib/services/debugService/index.ts | 2 +- .../ethCommonService/ICommonService.ts | 2 +- .../ethService/ethCommonService/index.ts | 2 +- .../ethFilterService/IFilterService.ts | 2 +- .../ethService/ethFilterService/index.ts | 2 +- .../hbarLimitService/IHbarLimitService.ts | 2 +- .../services/metricService/metricService.ts | 2 +- packages/relay/src/lib/types/index.ts | 2 ++ .../tests/lib/clients/localLRUCache.spec.ts | 2 +- .../tests/lib/clients/redisCache.spec.ts | 5 ---- packages/relay/tests/lib/eth/eth_call.spec.ts | 3 +-- .../relay/tests/lib/eth/eth_common.spec.ts | 2 +- .../tests/lib/eth/eth_estimateGas.spec.ts | 3 +-- .../tests/lib/eth/eth_feeHistory.spec.ts | 2 +- .../relay/tests/lib/eth/eth_gasPrice.spec.ts | 2 +- .../tests/lib/eth/eth_getBalance.spec.ts | 2 +- .../tests/lib/eth/eth_getBlockByHash.spec.ts | 2 +- .../lib/eth/eth_getBlockByNumber.spec.ts | 2 +- ...eth_getBlockTransactionCountByHash.spec.ts | 2 +- ...h_getBlockTransactionCountByNumber.spec.ts | 2 +- .../relay/tests/lib/eth/eth_getCode.spec.ts | 2 +- .../relay/tests/lib/eth/eth_getLogs.spec.ts | 2 +- .../tests/lib/eth/eth_getStorageAt.spec.ts | 2 +- ..._getTransactionByBlockHashAndIndex.spec.ts | 2 +- ...etTransactionByBlockNumberAndIndex.spec.ts | 2 +- .../lib/eth/eth_getTransactionByHash.spec.ts | 2 +- .../lib/eth/eth_getTransactionCount.spec.ts | 2 +- .../lib/eth/eth_getTransactionReceipt.spec.ts | 2 +- .../lib/eth/eth_sendRawTransaction.spec.ts | 2 +- packages/relay/tests/lib/hbarLimiter.spec.ts | 2 +- .../relay/tests/lib/mirrorNodeClient.spec.ts | 2 +- packages/relay/tests/lib/openrpc.spec.ts | 2 +- packages/relay/tests/lib/sdkClient.spec.ts | 2 +- .../lib/services/debugService/debug.spec.ts | 2 +- .../tests/lib/services/eth/filter.spec.ts | 2 +- packages/server/src/koaJsonRpc/index.ts | 2 +- packages/server/src/server.ts | 3 +-- .../tests/acceptance/cacheService.spec.ts | 2 +- .../tests/acceptance/hbarLimiter.spec.ts | 2 +- .../tests/acceptance/rpc_batch1.spec.ts | 2 +- packages/server/tests/clients/mirrorClient.ts | 2 +- packages/server/tests/helpers/utils.ts | 2 +- .../src/controllers/eth_subscribe.ts | 20 +++++++------- packages/ws-server/src/controllers/index.ts | 26 +++++++++++-------- packages/ws-server/src/utils/validators.ts | 17 ++++++------ packages/ws-server/src/webSocketServer.ts | 14 ++++++---- .../ws-server/tests/acceptance/call.spec.ts | 2 +- .../tests/acceptance/estimateGas.spec.ts | 2 +- .../tests/acceptance/getStorageAt.spec.ts | 2 +- 65 files changed, 105 insertions(+), 104 deletions(-) diff --git a/packages/relay/src/index.ts b/packages/relay/src/index.ts index 252eaf305b..1e16a7db9f 100644 --- a/packages/relay/src/index.ts +++ b/packages/relay/src/index.ts @@ -19,14 +19,13 @@ */ import { Block, Log, Receipt, Transaction } from './lib/model'; -import { IContractCallRequest } from './lib/types'; +import { IContractCallRequest, RequestDetails } from './lib/types'; 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 { IFilterService } from './lib/services/ethService/ethFilterService/IFilterService'; import { IDebugService } from './lib/services/debugService/IDebugService'; -import { RequestDetails } from './lib/types/RequestDetails'; export { JsonRpcError, predefined, MirrorNodeClientError, WebSocketError }; diff --git a/packages/relay/src/lib/clients/cache/ICacheClient.ts b/packages/relay/src/lib/clients/cache/ICacheClient.ts index b4dfd6b576..4ca11b1fa0 100644 --- a/packages/relay/src/lib/clients/cache/ICacheClient.ts +++ b/packages/relay/src/lib/clients/cache/ICacheClient.ts @@ -18,7 +18,7 @@ * */ -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; export interface ICacheClient { keys(pattern: string, callingMethod: string, requestDetails: RequestDetails): Promise; diff --git a/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts b/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts index d72a9eac9b..944b02c60b 100644 --- a/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts +++ b/packages/relay/src/lib/clients/cache/IRedisCacheClient.ts @@ -19,7 +19,7 @@ */ import type { ICacheClient } from './ICacheClient'; -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; export interface IRedisCacheClient extends ICacheClient { disconnect: () => Promise; diff --git a/packages/relay/src/lib/clients/cache/localLRUCache.ts b/packages/relay/src/lib/clients/cache/localLRUCache.ts index 17ebc394ad..c366b8897d 100644 --- a/packages/relay/src/lib/clients/cache/localLRUCache.ts +++ b/packages/relay/src/lib/clients/cache/localLRUCache.ts @@ -23,7 +23,7 @@ import { Gauge, Registry } from 'prom-client'; import { ICacheClient } from './ICacheClient'; import constants from '../../constants'; import LRUCache, { LimitedByCount, LimitedByTTL } from 'lru-cache'; -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; /** * Represents a LocalLRUCache instance that uses an LRU (Least Recently Used) caching strategy diff --git a/packages/relay/src/lib/clients/cache/redisCache.ts b/packages/relay/src/lib/clients/cache/redisCache.ts index 3bd28ff1e5..2c9263d239 100644 --- a/packages/relay/src/lib/clients/cache/redisCache.ts +++ b/packages/relay/src/lib/clients/cache/redisCache.ts @@ -25,7 +25,7 @@ import { Registry } from 'prom-client'; import { RedisCacheError } from '../../errors/RedisCacheError'; import constants from '../../constants'; import { IRedisCacheClient } from './IRedisCacheClient'; -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; /** * A class that provides caching functionality using Redis. diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index daaab4a666..0f9d2f30a1 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -42,8 +42,8 @@ import { IContractLogsResultsParams, MirrorNodeTransactionRecord, IMirrorNodeTransactionRecord, + RequestDetails, } from '../types'; -import { RequestDetails } from '../types/RequestDetails'; type REQUEST_METHODS = 'GET' | 'POST'; diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index 220050a756..6e2c559d16 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -62,7 +62,7 @@ import { JsonRpcError, predefined } from '../errors/JsonRpcError'; import { CacheService } from '../services/cacheService/cacheService'; import { formatRequestIdMessage, weibarHexToTinyBarInt } from '../../formatters'; import { ITransactionRecordMetric, IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../types'; -import { RequestDetails } from '../types/RequestDetails'; +import { RequestDetails } from '../types'; const _ = require('lodash'); diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts index 31bd0b6b79..c7d39bac5e 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.ts @@ -23,7 +23,7 @@ import { Logger } from 'pino'; import { IEthAddressHbarSpendingPlan } from '../../types/hbarLimiter/ethAddressHbarSpendingPlan'; import { EthAddressHbarSpendingPlanNotFoundError } from '../../types/hbarLimiter/errors'; import { EthAddressHbarSpendingPlan } from '../../entities/hbarLimiter/ethAddressHbarSpendingPlan'; -import { RequestDetails } from '../../../types/RequestDetails'; +import { RequestDetails } from '../../../types'; export class EthAddressHbarSpendingPlanRepository { private readonly collectionKey = 'ethAddressHbarSpendingPlan'; diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts index 9382e1de5a..fc2c22016f 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts @@ -27,7 +27,7 @@ import { IDetailedHbarSpendingPlan, IHbarSpendingPlan } from '../../types/hbarLi import { HbarSpendingRecord } from '../../entities/hbarLimiter/hbarSpendingRecord'; import { SubscriptionType } from '../../types/hbarLimiter/subscriptionType'; import { HbarSpendingPlan } from '../../entities/hbarLimiter/hbarSpendingPlan'; -import { RequestDetails } from '../../../types/RequestDetails'; +import { RequestDetails } from '../../../types'; export class HbarSpendingPlanRepository { private readonly collectionKey = 'hbarSpendingPlan'; diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 2cc266b8ca..29da622916 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -41,7 +41,7 @@ import { IDebugService } from './services/debugService/IDebugService'; import { MirrorNodeClientError } from './errors/MirrorNodeClientError'; import { IReceiptRootHash, ReceiptsRootUtils } from '../receiptsRootUtils'; import { IFilterService } from './services/ethService/ethFilterService/IFilterService'; -import { IFeeHistory, IContractCallRequest, IContractCallResponse, ITransactionReceipt } from './types'; +import { IFeeHistory, IContractCallRequest, IContractCallResponse, ITransactionReceipt, RequestDetails } from './types'; import { isHex, toHash32, @@ -59,8 +59,6 @@ import { formatTransactionIdWithoutQueryParams, getFunctionSelector, } from '../formatters'; -import { time } from 'console'; -import { RequestDetails } from './types/RequestDetails'; const _ = require('lodash'); const createHash = require('keccak'); diff --git a/packages/relay/src/lib/hbarlimiter/index.ts b/packages/relay/src/lib/hbarlimiter/index.ts index b7bc9858f8..9b534d366a 100644 --- a/packages/relay/src/lib/hbarlimiter/index.ts +++ b/packages/relay/src/lib/hbarlimiter/index.ts @@ -22,7 +22,7 @@ import { Logger } from 'pino'; import constants from '../constants'; import { Registry, Counter, Gauge } from 'prom-client'; import { formatRequestIdMessage } from '../../formatters'; -import { RequestDetails } from '../types/RequestDetails'; +import { RequestDetails } from '../types'; export default class HbarLimit { private enabled: boolean = false; diff --git a/packages/relay/src/lib/poller.ts b/packages/relay/src/lib/poller.ts index 61f84c00c2..1c5e621a28 100644 --- a/packages/relay/src/lib/poller.ts +++ b/packages/relay/src/lib/poller.ts @@ -21,7 +21,7 @@ import { Eth } from '../index'; import { Logger } from 'pino'; import { Registry, Gauge } from 'prom-client'; -import { RequestDetails } from './types/RequestDetails'; +import { RequestDetails } from './types'; import { Utils } from '../utils'; export interface Poll { diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index 745d093a7a..c81e52d353 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -25,7 +25,7 @@ import { Logger } from 'pino'; import constants from './constants'; import { ethers, Transaction } from 'ethers'; import { prepend0x } from '../formatters'; -import { RequestDetails } from './types/RequestDetails'; +import { RequestDetails } from './types'; /** * Precheck class for handling various prechecks before sending a raw transaction. diff --git a/packages/relay/src/lib/relay.ts b/packages/relay/src/lib/relay.ts index 2d87cafbe3..b366e541c4 100644 --- a/packages/relay/src/lib/relay.ts +++ b/packages/relay/src/lib/relay.ts @@ -39,7 +39,7 @@ import HAPIService from './services/hapiService/hapiService'; import { SubscriptionController } from './subscriptionController'; import MetricService from './services/metricService/metricService'; import { CacheService } from './services/cacheService/cacheService'; -import { RequestDetails } from './types/RequestDetails'; +import { RequestDetails } from './types'; import { Utils } from '../utils'; export class RelayImpl implements Relay { diff --git a/packages/relay/src/lib/services/cacheService/cacheService.ts b/packages/relay/src/lib/services/cacheService/cacheService.ts index e10e53c238..e66b33cbc0 100644 --- a/packages/relay/src/lib/services/cacheService/cacheService.ts +++ b/packages/relay/src/lib/services/cacheService/cacheService.ts @@ -23,7 +23,7 @@ import { Counter, Registry } from 'prom-client'; import { ICacheClient } from '../../clients/cache/ICacheClient'; import { LocalLRUCache, RedisCache } from '../../clients'; import { RedisCacheError } from '../../errors/RedisCacheError'; -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; /** * A service that manages caching using different cache implementations based on configuration. diff --git a/packages/relay/src/lib/services/debugService/IDebugService.ts b/packages/relay/src/lib/services/debugService/IDebugService.ts index 91c9183275..0237eb5bf1 100644 --- a/packages/relay/src/lib/services/debugService/IDebugService.ts +++ b/packages/relay/src/lib/services/debugService/IDebugService.ts @@ -18,9 +18,8 @@ * */ -import { ITracerConfig } from '../../types'; +import { ITracerConfig, RequestDetails } from '../../types'; import type { TracerType } from '../../constants'; -import { RequestDetails } from '../../types/RequestDetails'; export interface IDebugService { debug_traceTransaction: ( diff --git a/packages/relay/src/lib/services/debugService/index.ts b/packages/relay/src/lib/services/debugService/index.ts index ec674a7f36..136cf6382a 100644 --- a/packages/relay/src/lib/services/debugService/index.ts +++ b/packages/relay/src/lib/services/debugService/index.ts @@ -29,7 +29,7 @@ import { EthImpl } from '../../eth'; import { IOpcodesResponse } from '../../clients/models/IOpcodesResponse'; import { IOpcode } from '../../clients/models/IOpcode'; import { ICallTracerConfig, IOpcodeLoggerConfig, ITracerConfig } from '../../types'; -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; /** * Represents a DebugService for tracing and debugging transactions and debugging diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts b/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts index bd89197f1c..f0873fc8e3 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/ICommonService.ts @@ -18,7 +18,7 @@ * */ import { Log } from '../../../model'; -import { RequestDetails } from '../../../types/RequestDetails'; +import { RequestDetails } from '../../../types'; export interface ICommonService { blockTagIsLatestOrPending(tag: any): boolean; diff --git a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts index 12bf0c0903..3e8ff7d084 100644 --- a/packages/relay/src/lib/services/ethService/ethCommonService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethCommonService/index.ts @@ -29,7 +29,7 @@ import { MirrorNodeClientError } from '../../../errors/MirrorNodeClientError'; import { Log } from '../../../model'; import * as _ from 'lodash'; import { CacheService } from '../../cacheService/cacheService'; -import { RequestDetails } from '../../../types/RequestDetails'; +import { RequestDetails } from '../../../types'; /** * Create a new Common Service implementation. diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts index e2dc8e3e78..169d592e73 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/IFilterService.ts @@ -20,7 +20,7 @@ import { JsonRpcError } from '../../../errors/JsonRpcError'; import { Log } from '../../../model'; -import { RequestDetails } from '../../../types/RequestDetails'; +import { RequestDetails } from '../../../types'; export interface IFilterService { newFilter( diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts index f5d842029a..1e4bd60079 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/index.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/index.ts @@ -27,7 +27,7 @@ import { generateRandomHex } from '../../../../formatters'; import { JsonRpcError, predefined } from '../../../errors/JsonRpcError'; import { Log } from '../../../model'; import { CacheService } from '../../cacheService/cacheService'; -import { RequestDetails } from '../../../types/RequestDetails'; +import { RequestDetails } from '../../../types'; /** * Create a new Filter Service implementation. diff --git a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts index 8f22313fc3..f087b28976 100644 --- a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts +++ b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts @@ -18,7 +18,7 @@ * */ -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; export interface IHbarLimitService { resetLimiter(): Promise; diff --git a/packages/relay/src/lib/services/metricService/metricService.ts b/packages/relay/src/lib/services/metricService/metricService.ts index 689c04b523..ff99a1c09c 100644 --- a/packages/relay/src/lib/services/metricService/metricService.ts +++ b/packages/relay/src/lib/services/metricService/metricService.ts @@ -25,7 +25,7 @@ import HbarLimit from '../../hbarlimiter'; import { Histogram, Registry } from 'prom-client'; import { MirrorNodeClient, SDKClient } from '../../clients'; import { ITransactionRecordMetric, IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../../types'; -import { RequestDetails } from '../../types/RequestDetails'; +import { RequestDetails } from '../../types'; export default class MetricService { /** diff --git a/packages/relay/src/lib/types/index.ts b/packages/relay/src/lib/types/index.ts index 267439a689..cf86e73deb 100644 --- a/packages/relay/src/lib/types/index.ts +++ b/packages/relay/src/lib/types/index.ts @@ -38,6 +38,7 @@ import { MirrorNodeTransactionRecord, IMirrorNodeTransactionRecord, } from './mirrorNode'; +import { RequestDetails } from './RequestDetails'; export { ITransfer, @@ -61,4 +62,5 @@ export { MirrorNodeTransactionRecord, IMirrorNodeTransactionRecord, IExecuteTransactionEventPayload, + RequestDetails, }; diff --git a/packages/relay/tests/lib/clients/localLRUCache.spec.ts b/packages/relay/tests/lib/clients/localLRUCache.spec.ts index f678b8e320..f2a27284d0 100644 --- a/packages/relay/tests/lib/clients/localLRUCache.spec.ts +++ b/packages/relay/tests/lib/clients/localLRUCache.spec.ts @@ -24,7 +24,7 @@ import { Registry } from 'prom-client'; import pino from 'pino'; import { LocalLRUCache } from '../../../src/lib/clients'; import constants from '../../../src/lib/constants'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; const logger = pino(); const registry = new Registry(); diff --git a/packages/relay/tests/lib/clients/redisCache.spec.ts b/packages/relay/tests/lib/clients/redisCache.spec.ts index 2d289dafbc..6c6b966a34 100644 --- a/packages/relay/tests/lib/clients/redisCache.spec.ts +++ b/packages/relay/tests/lib/clients/redisCache.spec.ts @@ -42,11 +42,6 @@ describe('RedisCache Test Suite', async function () { useInMemoryRedisServer(logger, 6379); this.beforeAll(async () => { -<<<<<<< HEAD -======= - redisInMemoryServer = new RedisInMemoryServer(logger.child({ name: `in-memory redis server` }), 6379); - await redisInMemoryServer.start(); ->>>>>>> c7c5c919 (chore: draft changes) redisCache = new RedisCache(logger.child({ name: `cache` }), registry); }); diff --git a/packages/relay/tests/lib/eth/eth_call.spec.ts b/packages/relay/tests/lib/eth/eth_call.spec.ts index 1508a7a13c..8b3dd2860a 100644 --- a/packages/relay/tests/lib/eth/eth_call.spec.ts +++ b/packages/relay/tests/lib/eth/eth_call.spec.ts @@ -55,8 +55,7 @@ import { mockData, } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; -import { IContractCallRequest, IContractCallResponse } from '../../../src/lib/types'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { IContractCallRequest, IContractCallResponse, RequestDetails } from '../../../src/lib/types'; import { ContractFunctionResult } from '@hashgraph/sdk'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); diff --git a/packages/relay/tests/lib/eth/eth_common.spec.ts b/packages/relay/tests/lib/eth/eth_common.spec.ts index a64f360c3d..69050d3091 100644 --- a/packages/relay/tests/lib/eth/eth_common.spec.ts +++ b/packages/relay/tests/lib/eth/eth_common.spec.ts @@ -24,7 +24,7 @@ import { Registry } from 'prom-client'; import pino from 'pino'; import chaiAsPromised from 'chai-as-promised'; import { RelayImpl } from '../../../src'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts index 4003f3d77c..bc75a4ba14 100644 --- a/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts +++ b/packages/relay/tests/lib/eth/eth_estimateGas.spec.ts @@ -31,7 +31,7 @@ import { Precheck } from '../../../src/lib/precheck'; import { SDKClient } from '../../../src/lib/clients'; import { numberTo0x } from '../../../src/formatters'; import { createStubInstance, SinonStub, SinonStubbedInstance, stub } from 'sinon'; -import { IContractCallRequest, IContractCallResponse } from '../../../src/lib/types'; +import { IContractCallRequest, IContractCallResponse, RequestDetails } from '../../../src/lib/types'; import { ACCOUNT_ADDRESS_1, DEFAULT_NETWORK_FEES, @@ -39,7 +39,6 @@ import { ONE_TINYBAR_IN_WEI_HEX, RECEIVER_ADDRESS, } from './eth-config'; -import { RequestDetails } from '../../../dist/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts index 04f29f85be..be4b57b667 100644 --- a/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts +++ b/packages/relay/tests/lib/eth/eth_feeHistory.spec.ts @@ -38,7 +38,7 @@ import { } from './eth-config'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts index 9cb8c51cf4..17f836b25a 100644 --- a/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts +++ b/packages/relay/tests/lib/eth/eth_gasPrice.spec.ts @@ -31,7 +31,7 @@ import { predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import { generateEthTestEnv } from './eth-helpers'; import { toHex } from '../../helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBalance.spec.ts b/packages/relay/tests/lib/eth/eth_getBalance.spec.ts index 66835c4517..3af1eb1b5a 100644 --- a/packages/relay/tests/lib/eth/eth_getBalance.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBalance.spec.ts @@ -44,7 +44,7 @@ import { TINYBAR_TO_WEIBAR_COEF_BIGINT, } from './eth-config'; import { balancesByAccountIdByTimestampURL, generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts index 874d2a6595..dcf2eb6074 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByHash.spec.ts @@ -56,7 +56,7 @@ import { DEFAULT_BLOCK_RECEIPTS_ROOT_HASH, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index 3f241e7710..b0a4e1f664 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -73,7 +73,7 @@ import { } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; import { fail } from 'assert'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts index c6d30ffd26..e626de8bbb 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByHash.spec.ts @@ -33,7 +33,7 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts index 8a99f4bf36..27c579b42f 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockTransactionCountByNumber.spec.ts @@ -35,7 +35,7 @@ import { NO_SUCH_BLOCK_EXISTS_RES, } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getCode.spec.ts b/packages/relay/tests/lib/eth/eth_getCode.spec.ts index 9cb216644e..c5cd107218 100644 --- a/packages/relay/tests/lib/eth/eth_getCode.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getCode.spec.ts @@ -38,7 +38,7 @@ import { } from './eth-config'; import { generateEthTestEnv } from './eth-helpers'; import { JsonRpcError, predefined } from '../../../src'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts index 7a759187da..e804483558 100644 --- a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts @@ -58,7 +58,7 @@ import { } from './eth-config'; import { ethers } from 'ethers'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts index 6ef018261e..192429970c 100644 --- a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts @@ -45,7 +45,7 @@ import RelayAssertions from '../../assertions'; import { defaultDetailedContractResults } from '../../helpers'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts index 77b010d530..8c54b989c8 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts @@ -43,7 +43,7 @@ import { NOT_FOUND_RES, } from './eth-config'; import { contractResultsByHashByIndexURL, generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts index 343673685e..9a67f4c57c 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts @@ -43,7 +43,7 @@ import { NOT_FOUND_RES, } from './eth-config'; import { contractResultsByNumberByIndexURL, generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts index 8fdb3dbd52..3b3b93d942 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByHash.spec.ts @@ -34,7 +34,7 @@ import { } from './eth-config'; import { defaultDetailedContractResultByHash, defaultFromLongZeroAddress } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts index 045a790e57..f7ed90e316 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts @@ -32,7 +32,7 @@ import RelayAssertions from '../../assertions'; import { defaultDetailedContractResults, defaultEthereumTransactions, mockData } from '../../helpers'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts index fc718529db..4676593171 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionReceipt.spec.ts @@ -29,7 +29,7 @@ import RelayAssertions from '../../assertions'; import { DEFAULT_BLOCK, EMPTY_LOGS_RESPONSE } from './eth-config'; import { defaultErrorMessageHex } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts index 85f82fa688..6b84daed42 100644 --- a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts +++ b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts @@ -31,7 +31,7 @@ import RelayAssertions from '../../assertions'; import { getRequestId, mockData, signTransaction } from '../../helpers'; import { generateEthTestEnv } from './eth-helpers'; import { SDKClientError } from '../../../src/lib/errors/SDKClientError'; -import { RequestDetails } from '../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); diff --git a/packages/relay/tests/lib/hbarLimiter.spec.ts b/packages/relay/tests/lib/hbarLimiter.spec.ts index 7e38b83fd5..590a28c0ee 100644 --- a/packages/relay/tests/lib/hbarLimiter.spec.ts +++ b/packages/relay/tests/lib/hbarLimiter.spec.ts @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { Registry } from 'prom-client'; import HbarLimit from '../../src/lib/hbarlimiter'; import { estimateFileTransactionsFee, getRequestId, random20BytesAddress } from '../helpers'; -import { RequestDetails } from '../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../src/lib/types'; const registry = new Registry(); const logger = pino(); diff --git a/packages/relay/tests/lib/mirrorNodeClient.spec.ts b/packages/relay/tests/lib/mirrorNodeClient.spec.ts index e3b56c37f4..923d97323e 100644 --- a/packages/relay/tests/lib/mirrorNodeClient.spec.ts +++ b/packages/relay/tests/lib/mirrorNodeClient.spec.ts @@ -34,7 +34,7 @@ import pino from 'pino'; import { ethers } from 'ethers'; import { predefined, MirrorNodeClientError } from '../../src'; import { CacheService } from '../../src/lib/services/cacheService/cacheService'; -import { RequestDetails } from '../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../src/lib/types'; import { SDKClientError } from '../../src/lib/errors/SDKClientError'; const logger = pino(); const noTransactions = '?transactions=false'; diff --git a/packages/relay/tests/lib/openrpc.spec.ts b/packages/relay/tests/lib/openrpc.spec.ts index f3180752fe..b264a40044 100644 --- a/packages/relay/tests/lib/openrpc.spec.ts +++ b/packages/relay/tests/lib/openrpc.spec.ts @@ -35,7 +35,7 @@ import { BigNumber } from 'bignumber.js'; import { RelayImpl } from '../../src'; import { EthImpl } from '../../src/lib/eth'; import { SDKClient, MirrorNodeClient } from '../../src/lib/clients'; -import { RequestDetails } from '../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../src/lib/types'; import openRpcSchema from '../../../../docs/openrpc.json'; import { diff --git a/packages/relay/tests/lib/sdkClient.spec.ts b/packages/relay/tests/lib/sdkClient.spec.ts index 17f5c04591..0c83deb672 100644 --- a/packages/relay/tests/lib/sdkClient.spec.ts +++ b/packages/relay/tests/lib/sdkClient.spec.ts @@ -59,7 +59,7 @@ import { FileDeleteTransaction, TransactionRecordQuery, } from '@hashgraph/sdk'; -import { RequestDetails } from '../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../src/lib/types'; config({ path: resolve(__dirname, '../test.env') }); const registry = new Registry(); diff --git a/packages/relay/tests/lib/services/debugService/debug.spec.ts b/packages/relay/tests/lib/services/debugService/debug.spec.ts index e5fdf867a4..41e7e36294 100644 --- a/packages/relay/tests/lib/services/debugService/debug.spec.ts +++ b/packages/relay/tests/lib/services/debugService/debug.spec.ts @@ -35,7 +35,7 @@ import { CacheService } from '../../../../src/lib/services/cacheService/cacheSer import { CommonService } from '../../../../src/lib/services/ethService'; import { IOpcodesResponse } from '../../../../src/lib/clients/models/IOpcodesResponse'; import { strip0x } from '../../../../src/formatters'; -import { RequestDetails } from '../../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); chai.use(chaiAsPromised); diff --git a/packages/relay/tests/lib/services/eth/filter.spec.ts b/packages/relay/tests/lib/services/eth/filter.spec.ts index 616670f6d4..ec4aebafc6 100644 --- a/packages/relay/tests/lib/services/eth/filter.spec.ts +++ b/packages/relay/tests/lib/services/eth/filter.spec.ts @@ -32,7 +32,7 @@ import RelayAssertions from '../../../assertions'; import { predefined } from '../../../../src'; import { CacheService } from '../../../../src/lib/services/cacheService/cacheService'; import * as sinon from 'sinon'; -import { RequestDetails } from '../../../../src/lib/types/RequestDetails'; +import { RequestDetails } from '../../../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); const logger = pino(); diff --git a/packages/server/src/koaJsonRpc/index.ts b/packages/server/src/koaJsonRpc/index.ts index a7fa402877..c68b01b1cf 100644 --- a/packages/server/src/koaJsonRpc/index.ts +++ b/packages/server/src/koaJsonRpc/index.ts @@ -37,6 +37,7 @@ import { import Koa from 'koa'; import { Histogram, Registry } from 'prom-client'; import { JsonRpcError, predefined } from '@hashgraph/json-rpc-relay'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; import { RpcErrorCodeToStatusMap } from './lib/HttpStatusCodeAndMessage'; import { getBatchRequestsEnabled, @@ -47,7 +48,6 @@ import { hasOwnProperty, } from './lib/utils'; import { IJsonRpcRequest } from './lib/IJsonRpcRequest'; -import { RequestDetails } from '../../../relay/src/lib/types/RequestDetails'; dotenv.config({ path: path.resolve(__dirname, '../../../../../.env') }); diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index 8213da0cab..7ec2272525 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -19,7 +19,7 @@ */ import { JsonRpcError, MirrorNodeClientError, predefined, Relay, RelayImpl } from '@hashgraph/json-rpc-relay'; -import { ITracerConfig } from '@hashgraph/json-rpc-relay/src/lib/types'; +import { ITracerConfig, RequestDetails } from '@hashgraph/json-rpc-relay/src/lib/types'; import { collectDefaultMetrics, Histogram, Registry } from 'prom-client'; import KoaJsonRpc from './koaJsonRpc'; import { TracerType, TYPES, Validator } from './validator'; @@ -29,7 +29,6 @@ import fs from 'fs'; import { v4 as uuid } from 'uuid'; import { formatRequestIdMessage } from './formatters'; import cors from 'koa-cors'; -import { RequestDetails } from '../../relay/src/lib/types/RequestDetails'; const mainLogger = pino({ name: 'hedera-json-rpc-relay', diff --git a/packages/server/tests/acceptance/cacheService.spec.ts b/packages/server/tests/acceptance/cacheService.spec.ts index b37e82b3ee..fb148c59da 100644 --- a/packages/server/tests/acceptance/cacheService.spec.ts +++ b/packages/server/tests/acceptance/cacheService.spec.ts @@ -21,7 +21,7 @@ import { expect } from 'chai'; import { CacheService } from '../../../../packages/relay/src/lib/services/cacheService/cacheService'; import { Registry } from 'prom-client'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; const registry = new Registry(); const DATA_LABEL_PREFIX = 'acceptance-test-'; diff --git a/packages/server/tests/acceptance/hbarLimiter.spec.ts b/packages/server/tests/acceptance/hbarLimiter.spec.ts index b282166c9c..63512117e8 100644 --- a/packages/server/tests/acceptance/hbarLimiter.spec.ts +++ b/packages/server/tests/acceptance/hbarLimiter.spec.ts @@ -38,7 +38,7 @@ import largeContractJson from '../contracts/hbarLimiterContracts/largeSizeContra import mediumSizeContract from '../contracts/hbarLimiterContracts/mediumSizeContract.json'; import { resolve } from 'path'; import { config } from 'dotenv'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; config({ path: resolve(__dirname, '../localAcceptance.env') }); diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 859082c632..e5f415cd5a 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -41,7 +41,7 @@ import RelayCalls from '../../tests/helpers/constants'; // Other imports import { numberTo0x, prepend0x } from '../../../../packages/relay/src/formatters'; import constants from '../../../relay/src/lib/constants'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; import { JsonRpcError } from '@hashgraph/json-rpc-relay'; const Address = RelayCalls; diff --git a/packages/server/tests/clients/mirrorClient.ts b/packages/server/tests/clients/mirrorClient.ts index 2b640d43d8..e4d764da00 100644 --- a/packages/server/tests/clients/mirrorClient.ts +++ b/packages/server/tests/clients/mirrorClient.ts @@ -22,7 +22,7 @@ import Axios, { AxiosInstance } from 'axios'; import axiosRetry from 'axios-retry'; import { Logger } from 'pino'; import { Utils } from '../helpers/utils'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; export default class MirrorClient { private readonly logger: Logger; diff --git a/packages/server/tests/helpers/utils.ts b/packages/server/tests/helpers/utils.ts index 1146bcb11b..7d744849d8 100644 --- a/packages/server/tests/helpers/utils.ts +++ b/packages/server/tests/helpers/utils.ts @@ -34,7 +34,7 @@ import { Context } from 'mocha'; import { GitHubClient } from '../clients/githubClient'; import MirrorClient from '../clients/mirrorClient'; import { HeapDifferenceStatistics } from '../types/HeapDifferenceStatistics'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; export class Utils { static readonly HEAP_SIZE_DIFF_MEMORY_LEAK_THRESHOLD: number = 1e6; // 1 MB diff --git a/packages/ws-server/src/controllers/eth_subscribe.ts b/packages/ws-server/src/controllers/eth_subscribe.ts index 00b6876708..87e0c243b9 100644 --- a/packages/ws-server/src/controllers/eth_subscribe.ts +++ b/packages/ws-server/src/controllers/eth_subscribe.ts @@ -24,6 +24,7 @@ import constants from '@hashgraph/json-rpc-relay/dist/lib/constants'; import { MirrorNodeClient } from '@hashgraph/json-rpc-relay/dist/lib/clients'; import jsonResp from '@hashgraph/json-rpc-server/dist/koaJsonRpc/lib/RpcResponse'; import { constructValidLogSubscriptionFilter, getMultipleAddressesEnabled } from '../utils/utils'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; /** * Subscribes to new block headers (newHeads) events and returns the response and subscription ID. @@ -61,6 +62,7 @@ const subscribeToNewHeads = ( * @param {string} event - The event name to subscribe to (e.g., "newHeads"). * @param {Relay} relay - The relay object used for managing WebSocket subscriptions. * @param {any} logger - The logger object used for logging subscription information. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {{ response: any; subscriptionId: any }} Returns an object containing the response and subscription ID. */ const handleEthSubscribeNewHeads = ( @@ -73,7 +75,7 @@ const handleEthSubscribeNewHeads = ( relay: Relay, logger: any, connectionIdPrefix: string, - requestIdPrefix: string, + requestDetails: RequestDetails, ): { response: any; subscriptionId: any } => { const wsNewHeadsEnabled = typeof process.env.WS_NEW_HEADS_ENABLED !== 'undefined' ? process.env.WS_NEW_HEADS_ENABLED === 'true' : true; @@ -82,7 +84,7 @@ const handleEthSubscribeNewHeads = ( ({ response, subscriptionId } = subscribeToNewHeads(filters, response, subscriptionId, ctx, event, relay, logger)); } else { logger.warn( - `${connectionIdPrefix} ${requestIdPrefix}: Unsupported JSON-RPC method due to the value of environment variable WS_NEW_HEADS_ENABLED`, + `${connectionIdPrefix} ${requestDetails.formattedRequestId}: Unsupported JSON-RPC method due to the value of environment variable WS_NEW_HEADS_ENABLED`, ); response = jsonResp(request.id, predefined.UNSUPPORTED_METHOD, undefined); } @@ -94,7 +96,6 @@ const handleEthSubscribeNewHeads = ( * Validates the subscription parameters, checks if multiple addresses are enabled, * and subscribes to the event or sends an error response accordingly. * @param {any} filters - The filters object specifying criteria for the subscription. - * @param {string} requestIdPrefix - The prefix for the request ID. * @param {any} response - The response object to be sent to the client. * @param {any} request - The request object received from the client. * @param {any} subscriptionId - The ID of the subscription. @@ -102,11 +103,11 @@ const handleEthSubscribeNewHeads = ( * @param {any} event - The event name to subscribe to. * @param {Relay} relay - The relay object used for managing WebSocket subscriptions. * @param {MirrorNodeClient} mirrorNodeClient - The client for interacting with the MirrorNode API. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {{ response: any; subscriptionId: any }} Returns an object containing the response and subscription ID. */ const handleEthSubscribeLogs = async ( filters: any, - requestIdPrefix: string, response: any, request: any, subscriptionId: any, @@ -114,10 +115,11 @@ const handleEthSubscribeLogs = async ( event: any, relay: Relay, mirrorNodeClient: MirrorNodeClient, + requestDetails: RequestDetails, ): Promise<{ response: any; subscriptionId: any }> => { const validFiltersObject = constructValidLogSubscriptionFilter(filters); - await validateSubscribeEthLogsParams(validFiltersObject, requestIdPrefix, mirrorNodeClient); + await validateSubscribeEthLogsParams(validFiltersObject, mirrorNodeClient, requestDetails); if ( !getMultipleAddressesEnabled() && Array.isArray(validFiltersObject['address']) && @@ -140,24 +142,24 @@ const handleEthSubscribeLogs = async ( * @param {object} args - An object containing the function parameters as properties. * @param {any} args.ctx - The context object containing information about the WebSocket connection. * @param {any[]} args.params - The parameters of the method request, expecting an event and filters. - * @param {string} args.requestIdPrefix - The prefix for the request ID. * @param {any} args.request - The request object received from the client. * @param {Relay} args.relay - The relay object for interacting with the Hedera network. * @param {MirrorNodeClient} args.mirrorNodeClient - The mirror node client for handling subscriptions. * @param {ConnectionLimiter} args.limiter - The limiter object for managing connection subscriptions. * @param {any} args.logger - The logger object for logging messages and events. + * @param {RequestDetails} args.requestDetails - The request details for logging and tracking. * @returns {Promise} Returns a promise that resolves with the subscription response. */ export const handleEthSubsribe = async ({ ctx, params, - requestIdPrefix, request, relay, mirrorNodeClient, limiter, logger, connectionIdPrefix, + requestDetails, }): Promise => { const event = params[0]; const filters = params[1]; @@ -168,7 +170,6 @@ export const handleEthSubsribe = async ({ case constants.SUBSCRIBE_EVENTS.LOGS: ({ response, subscriptionId } = await handleEthSubscribeLogs( filters, - requestIdPrefix, response, request, subscriptionId, @@ -176,6 +177,7 @@ export const handleEthSubsribe = async ({ event, relay, mirrorNodeClient, + requestDetails, )); break; @@ -190,7 +192,7 @@ export const handleEthSubsribe = async ({ relay, logger, connectionIdPrefix, - requestIdPrefix, + requestDetails, )); break; case constants.SUBSCRIBE_EVENTS.NEW_PENDING_TRANSACTIONS: diff --git a/packages/ws-server/src/controllers/index.ts b/packages/ws-server/src/controllers/index.ts index b7d02ed7a3..526ad24c6f 100644 --- a/packages/ws-server/src/controllers/index.ts +++ b/packages/ws-server/src/controllers/index.ts @@ -32,7 +32,7 @@ import { MethodNotFound, IPRateLimitExceeded, } from '@hashgraph/json-rpc-server/dist/koaJsonRpc/lib/RpcError'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; /** * Handles sending requests to a Relay by calling a specified method with given parameters. @@ -44,8 +44,8 @@ import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/Request * @param {any} args.params - The parameters for the method call. * @param {Relay} args.relay - The relay object. * @param {any} args.logger - The logger object used for tracing. - * @param {string} args.requestIdPrefix - Prefix for request ID used for logging. * @param {string} args.connectionIdPrefix - Prefix for connection ID used for logging. + * @param {RequestDetails} args.requestDetails - The request details for logging and tracking. * @returns {Promise} A promise that resolves to the result of the request. */ const handleSendingRequestsToRelay = async ({ @@ -54,12 +54,15 @@ const handleSendingRequestsToRelay = async ({ params, relay, logger, - requestIdPrefix, connectionIdPrefix, ctx, + requestDetails, }): Promise => { - logger.trace(`${connectionIdPrefix} ${requestIdPrefix}: Submitting request=${JSON.stringify(request)} to relay.`); - const requestDetails = new RequestDetails({ requestId: ctx.req.id, ipAddress: ctx.request.ip }); + logger.trace( + `${connectionIdPrefix} ${requestDetails.formattedRequestId}: Submitting request=${JSON.stringify( + request, + )} to relay.`, + ); try { const resolvedParams = resolveParams(method, params); const [service, methodName] = method.split('_'); @@ -88,9 +91,9 @@ const handleSendingRequestsToRelay = async ({ if (!txRes) { logger.trace( - `${connectionIdPrefix} ${requestIdPrefix}: Fail to retrieve result for request=${JSON.stringify( - request, - )}. Result=${txRes}`, + `${connectionIdPrefix} ${ + requestDetails.formattedRequestId + }: Fail to retrieve result for request=${JSON.stringify(request)}. Result=${txRes}`, ); } @@ -112,10 +115,10 @@ const handleSendingRequestsToRelay = async ({ * @param {any} logger - The logger object. * @param {any} request - The request object. * @param {ConnectionLimiter} limiter - The connection limiter object. - * @param {string} requestIdPrefix - Prefix for request ID. * @param {string} connectionIdPrefix - Prefix for connection ID. * @param {MirrorNodeClient} mirrorNodeClient - The MirrorNodeClient object. * @param {WsMetricRegistry} wsMetricRegistry - The WsMetricRegistry object. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @returns {Promise} A promise that resolves to the response of the request. */ export const getRequestResult = async ( @@ -124,10 +127,10 @@ export const getRequestResult = async ( logger: any, request: any, limiter: ConnectionLimiter, - requestIdPrefix: string, connectionIdPrefix: string, mirrorNodeClient: MirrorNodeClient, wsMetricRegistry: WsMetricRegistry, + requestDetails: RequestDetails, ): Promise => { // Extract the method and parameters from the received request let { method, params } = request; @@ -140,6 +143,7 @@ export const getRequestResult = async ( wsMetricRegistry.getCounter('methodsCounterByIp').labels(ctx.request.ip, method).inc(); // validate request's jsonrpc object + const requestIdPrefix = requestDetails.formattedRequestId; if (!validateJsonRpcRequest(request, logger, requestIdPrefix, connectionIdPrefix)) { return jsonResp(request.id || null, new InvalidRequest(), undefined); } @@ -188,9 +192,9 @@ export const getRequestResult = async ( request, method, limiter, - requestIdPrefix, mirrorNodeClient, connectionIdPrefix, + requestDetails, }; switch (method) { diff --git a/packages/ws-server/src/utils/validators.ts b/packages/ws-server/src/utils/validators.ts index f157bd2586..3aa6b4492a 100644 --- a/packages/ws-server/src/utils/validators.ts +++ b/packages/ws-server/src/utils/validators.ts @@ -22,25 +22,26 @@ import constants from '@hashgraph/json-rpc-relay/dist/lib/constants'; import { JsonRpcError, predefined } from '@hashgraph/json-rpc-relay'; import { MirrorNodeClient } from '@hashgraph/json-rpc-relay/dist/lib/clients'; import { EthSubscribeLogsParamsObject } from '@hashgraph/json-rpc-server/dist/validator'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; /** * Validates whether the provided address corresponds to a contract or token type. * Throws an error if the address is not a valid contract or token type or does not exist. * @param {string} address - The address to validate. - * @param {string} requestId - The unique identifier for the request. * @param {MirrorNodeClient} mirrorNodeClient - The client for interacting with the MirrorNode API. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. * @throws {JsonRpcError} Throws a JsonRpcError if the address is not a valid contract or token type or does not exist. */ const validateIsContractOrTokenAddress = async ( address: string, - requestId: string, mirrorNodeClient: MirrorNodeClient, + requestDetails: RequestDetails, ) => { const isContractOrToken = await mirrorNodeClient.resolveEntityType( address, [constants.TYPE_CONTRACT, constants.TYPE_TOKEN], constants.METHODS.ETH_SUBSCRIBE, - requestId, + requestDetails, ); if (!isContractOrToken) { throw new JsonRpcError( @@ -48,7 +49,7 @@ const validateIsContractOrTokenAddress = async ( 'filters.address', `${address} is not a valid contract or token type or does not exists`, ), - requestId, + requestDetails.formattedRequestId, ); } }; @@ -56,13 +57,13 @@ const validateIsContractOrTokenAddress = async ( /** * Validates the parameters for subscribing to ETH logs. * @param {any} filters - The filters object containing parameters for subscribing to ETH logs. - * @param {string} requestId - The unique identifier for the request. * @param {MirrorNodeClient} mirrorNodeClient - The client for interacting with the MirrorNode API. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ export const validateSubscribeEthLogsParams = async ( filters: any, - requestId: string, mirrorNodeClient: MirrorNodeClient, + requestDetails: RequestDetails, ) => { // validate address exists and is correct length and type // validate topics if exists and is array and each one is correct length and type @@ -73,10 +74,10 @@ export const validateSubscribeEthLogsParams = async ( if (ethSubscribeLogsParams.object.address) { if (Array.isArray(ethSubscribeLogsParams.object.address)) { for (const address of ethSubscribeLogsParams.object.address) { - await validateIsContractOrTokenAddress(address, requestId, mirrorNodeClient); + await validateIsContractOrTokenAddress(address, mirrorNodeClient, requestDetails); } } else { - await validateIsContractOrTokenAddress(ethSubscribeLogsParams.object.address, requestId, mirrorNodeClient); + await validateIsContractOrTokenAddress(ethSubscribeLogsParams.object.address, mirrorNodeClient, requestDetails); } } }; diff --git a/packages/ws-server/src/webSocketServer.ts b/packages/ws-server/src/webSocketServer.ts index 768082a963..7fd5dc80a1 100644 --- a/packages/ws-server/src/webSocketServer.ts +++ b/packages/ws-server/src/webSocketServer.ts @@ -34,6 +34,7 @@ import KoaJsonRpc from '@hashgraph/json-rpc-server/dist/koaJsonRpc'; import jsonResp from '@hashgraph/json-rpc-server/dist/koaJsonRpc/lib/RpcResponse'; import { JsonRpcError, predefined, type Relay, RelayImpl } from '@hashgraph/json-rpc-relay'; import { getBatchRequestsMaxSize, getWsBatchRequestsEnabled, handleConnectionClose, sendToClient } from './utils/utils'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../../../.env') }); @@ -72,8 +73,10 @@ app.ws.use(async (ctx: Koa.Context) => { ctx.websocket.limiter = limiter; ctx.websocket.wsMetricRegistry = wsMetricRegistry; const connectionIdPrefix = formatIdMessage('Connection ID', ctx.websocket.id); - const requestIdPrefix = formatIdMessage('Request ID', ctx.websocket.requestId); + const requestDetails = new RequestDetails({ requestId: ctx.websocket.requestId, ipAddress: ctx.request.ip }); + const requestIdPrefix = requestDetails.formattedRequestId; logger.info( + // @ts-ignore `${connectionIdPrefix} ${requestIdPrefix} New connection established. Current active connections: ${ctx.app.server._connections}`, ); @@ -153,10 +156,10 @@ app.ws.use(async (ctx: Koa.Context) => { logger, item, limiter, - requestIdPrefix, connectionIdPrefix, mirrorNodeClient, wsMetricRegistry, + requestDetails, ); }); @@ -175,10 +178,10 @@ app.ws.use(async (ctx: Koa.Context) => { logger, request, limiter, - requestIdPrefix, connectionIdPrefix, mirrorNodeClient, wsMetricRegistry, + requestDetails, ); // send to client @@ -201,7 +204,8 @@ app.ws.use(async (ctx: Koa.Context) => { } }); -const httpApp = new KoaJsonRpc(logger, register).getKoaApp(); +const koaJsonRpc = new KoaJsonRpc(logger, register); +const httpApp = koaJsonRpc.getKoaApp(); collectDefaultMetrics({ register, prefix: 'rpc_relay_' }); httpApp.use(async (ctx: Koa.Context, next: Koa.Next) => { @@ -215,7 +219,7 @@ httpApp.use(async (ctx: Koa.Context, next: Koa.Next) => { } else if (ctx.url === '/health/readiness') { // readiness endpoint try { - const result = relay.eth().chainId(httpApp.getRequestDetails()); + const result = relay.eth().chainId(koaJsonRpc.getRequestDetails()); if (result.includes('0x12')) { ctx.status = 200; ctx.body = 'OK'; diff --git a/packages/ws-server/tests/acceptance/call.spec.ts b/packages/ws-server/tests/acceptance/call.spec.ts index 108b3737cc..a1f6a17948 100644 --- a/packages/ws-server/tests/acceptance/call.spec.ts +++ b/packages/ws-server/tests/acceptance/call.spec.ts @@ -25,7 +25,7 @@ import { WsTestConstant, WsTestHelper } from '../helper'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import ERC20MockJson from '@hashgraph/json-rpc-server/tests/contracts/ERC20Mock.json'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-1 eth_call', async function () { const METHOD_NAME = 'eth_call'; diff --git a/packages/ws-server/tests/acceptance/estimateGas.spec.ts b/packages/ws-server/tests/acceptance/estimateGas.spec.ts index 0eabd53442..5da309f6ba 100644 --- a/packages/ws-server/tests/acceptance/estimateGas.spec.ts +++ b/packages/ws-server/tests/acceptance/estimateGas.spec.ts @@ -25,7 +25,7 @@ import { WsTestConstant, WsTestHelper } from '../helper'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import basicContractJson from '@hashgraph/json-rpc-server/tests/contracts/Basic.json'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-1 eth_estimateGas', async function () { const METHOD_NAME = 'eth_estimateGas'; diff --git a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts index bda5ff3dd0..d1aa2fb681 100644 --- a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts +++ b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts @@ -24,7 +24,7 @@ import { ethers, WebSocketProvider } from 'ethers'; import { WsTestConstant, WsTestHelper } from '../helper'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; -import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types/RequestDetails'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-2 eth_getStorageAt', async function () { const METHOD_NAME = 'eth_getStorageAt'; From 0c1a2bc73a2bb63037377b09e760a0ed3eb35b87 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Mon, 16 Sep 2024 13:11:36 +0300 Subject: [PATCH 30/48] chore: fix ethAddressHbarSpendingPlanRepository.spec.ts and hbarSpendingPlanRepository.spec.ts Signed-off-by: Victor Yanev --- ...hAddressHbarSpendingPlanRepository.spec.ts | 26 ++-- .../hbarSpendingPlanRepository.spec.ts | 132 ++++++++++-------- 2 files changed, 87 insertions(+), 71 deletions(-) diff --git a/packages/relay/tests/lib/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.spec.ts b/packages/relay/tests/lib/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.spec.ts index 29d8cffc04..5b128ece92 100644 --- a/packages/relay/tests/lib/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.spec.ts +++ b/packages/relay/tests/lib/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository.spec.ts @@ -28,12 +28,17 @@ import { EthAddressHbarSpendingPlanNotFoundError } from '../../../../src/lib/db/ import { randomBytes, uuidV4 } from 'ethers'; import { Registry } from 'prom-client'; import { useInMemoryRedisServer } from '../../../helpers'; +import { RequestDetails } from '../../../../dist/lib/types'; chai.use(chaiAsPromised); describe('EthAddressHbarSpendingPlanRepository', function () { const logger = pino(); const registry = new Registry(); + const requestDetails = new RequestDetails({ + requestId: 'ethAddressHbarSpendingPlanRepositoryTest', + ipAddress: '0.0.0.0', + }); const tests = (isSharedCacheEnabled: boolean) => { let cacheService: CacheService; @@ -69,15 +74,15 @@ describe('EthAddressHbarSpendingPlanRepository', function () { it('retrieves an address plan by address', async () => { const ethAddress = '0x123'; const addressPlan: IEthAddressHbarSpendingPlan = { ethAddress, planId: uuidV4(randomBytes(16)) }; - await cacheService.set(`${repository['collectionKey']}:${ethAddress}`, addressPlan, 'test'); + await cacheService.set(`${repository['collectionKey']}:${ethAddress}`, addressPlan, 'test', requestDetails); - const result = await repository.findByAddress(ethAddress); + const result = await repository.findByAddress(ethAddress, requestDetails); expect(result).to.deep.equal(addressPlan); }); it('throws an error if address plan is not found', async () => { const ethAddress = '0xnonexistent'; - await expect(repository.findByAddress(ethAddress)).to.be.eventually.rejectedWith( + await expect(repository.findByAddress(ethAddress, requestDetails)).to.be.eventually.rejectedWith( EthAddressHbarSpendingPlanNotFoundError, `EthAddressHbarSpendingPlan with address ${ethAddress} not found`, ); @@ -89,10 +94,11 @@ describe('EthAddressHbarSpendingPlanRepository', function () { const ethAddress = '0x123'; const addressPlan: IEthAddressHbarSpendingPlan = { ethAddress, planId: uuidV4(randomBytes(16)) }; - await repository.save(addressPlan); + await repository.save(addressPlan, requestDetails); const result = await cacheService.getAsync( `${repository['collectionKey']}:${ethAddress}`, 'test', + requestDetails, ); expect(result).to.deep.equal(addressPlan); }); @@ -100,14 +106,15 @@ describe('EthAddressHbarSpendingPlanRepository', function () { it('overwrites an existing address plan', async () => { const ethAddress = '0x123'; const addressPlan: IEthAddressHbarSpendingPlan = { ethAddress, planId: uuidV4(randomBytes(16)) }; - await cacheService.set(`${repository['collectionKey']}:${ethAddress}`, addressPlan, 'test'); + await cacheService.set(`${repository['collectionKey']}:${ethAddress}`, addressPlan, 'test', requestDetails); const newPlanId = uuidV4(randomBytes(16)); const newAddressPlan: IEthAddressHbarSpendingPlan = { ethAddress, planId: newPlanId }; - await repository.save(newAddressPlan); + await repository.save(newAddressPlan, requestDetails); const result = await cacheService.getAsync( `${repository['collectionKey']}:${ethAddress}`, 'test', + requestDetails, ); expect(result).to.deep.equal(newAddressPlan); }); @@ -117,19 +124,20 @@ describe('EthAddressHbarSpendingPlanRepository', function () { it('deletes an address plan successfully', async () => { const ethAddress = '0x123'; const addressPlan: IEthAddressHbarSpendingPlan = { ethAddress, planId: uuidV4(randomBytes(16)) }; - await cacheService.set(`${repository['collectionKey']}:${ethAddress}`, addressPlan, 'test'); + await cacheService.set(`${repository['collectionKey']}:${ethAddress}`, addressPlan, 'test', requestDetails); - await repository.delete(ethAddress); + await repository.delete(ethAddress, requestDetails); const result = await cacheService.getAsync( `${repository['collectionKey']}:${ethAddress}`, 'test', + requestDetails, ); expect(result).to.be.null; }); it('does not throw an error if address plan to delete does not exist', async () => { const ethAddress = '0xnonexistent'; - await expect(repository.delete(ethAddress)).to.be.fulfilled; + await expect(repository.delete(ethAddress, requestDetails)).to.be.fulfilled; }); }); }; diff --git a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts index c10374cfa1..f7df912ea5 100644 --- a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts +++ b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts @@ -39,7 +39,7 @@ chai.use(chaiAsPromised); describe('HbarSpendingPlanRepository', function () { const logger = pino(); const registry = new Registry(); - const requestIdPrefix = `[Request ID: testId]`; + const requestDetails = new RequestDetails({ requestId: 'hbarSpendingPlanRepositoryTest', ipAddress: '0.0.0.0' }); const tests = (isSharedCacheEnabled: boolean) => { let cacheService: CacheService; @@ -66,14 +66,14 @@ describe('HbarSpendingPlanRepository', function () { } afterEach(async () => { - await cacheService.clear(); + await cacheService.clear(requestDetails); }); describe('create', () => { it('creates a plan successfully', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); - await expect(repository.findByIdWithDetails(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal( + const createdPlan = await repository.create(subscriptionType, requestDetails); + await expect(repository.findByIdWithDetails(createdPlan.id, requestDetails)).to.be.eventually.deep.equal( createdPlan, ); }); @@ -81,7 +81,7 @@ describe('HbarSpendingPlanRepository', function () { describe('findById', () => { it('throws an error if plan is not found by ID', async () => { - await expect(repository.findById('non-existent-id', requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(repository.findById('non-existent-id', requestDetails)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID non-existent-id not found`, ); @@ -89,14 +89,14 @@ describe('HbarSpendingPlanRepository', function () { it('returns a plan by ID', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); - await expect(repository.findById(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal(createdPlan); + const createdPlan = await repository.create(subscriptionType, requestDetails); + await expect(repository.findById(createdPlan.id, requestDetails)).to.be.eventually.deep.equal(createdPlan); }); }); describe('findByIdWithDetails', () => { it('throws an error if plan is not found by ID', async () => { - await expect(repository.findByIdWithDetails('non-existent-id', requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(repository.findByIdWithDetails('non-existent-id', requestDetails)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID non-existent-id not found`, ); @@ -104,8 +104,8 @@ describe('HbarSpendingPlanRepository', function () { it('returns a plan by ID', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); - await expect(repository.findByIdWithDetails(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal( + const createdPlan = await repository.create(subscriptionType, requestDetails); + await expect(repository.findByIdWithDetails(createdPlan.id, requestDetails)).to.be.eventually.deep.equal( createdPlan, ); }); @@ -113,7 +113,7 @@ describe('HbarSpendingPlanRepository', function () { describe('getSpendingHistory', () => { it('throws an error if plan not found by ID', async () => { - await expect(repository.getSpendingHistory('non-existent-id', requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(repository.getSpendingHistory('non-existent-id', requestDetails)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID non-existent-id not found`, ); @@ -121,20 +121,20 @@ describe('HbarSpendingPlanRepository', function () { it('returns an empty array if spending history is empty', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); - const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); + const createdPlan = await repository.create(subscriptionType, requestDetails); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestDetails); expect(spendingHistory).to.deep.equal([]); }); it('retrieves spending history for a plan', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); const key = `${repository['collectionKey']}:${createdPlan.id}:spendingHistory`; const hbarSpending = { amount: 100, timestamp: new Date() } as IHbarSpendingRecord; - await cacheService.rPush(key, hbarSpending, 'test'); + await cacheService.rPush(key, hbarSpending, 'test', requestDetails); - const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestDetails); expect(spendingHistory).to.have.lengthOf(1); expect(spendingHistory[0].amount).to.equal(hbarSpending.amount); expect(spendingHistory[0].timestamp).to.be.a('Date'); @@ -144,13 +144,13 @@ describe('HbarSpendingPlanRepository', function () { describe('addAmountToSpendingHistory', () => { it('adds amount to spending history', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); - await expect(repository.getSpendingHistory(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal([]); + const createdPlan = await repository.create(subscriptionType, requestDetails); + await expect(repository.getSpendingHistory(createdPlan.id, requestDetails)).to.be.eventually.deep.equal([]); const amount = 100; - await repository.addAmountToSpendingHistory(createdPlan.id, amount, requestIdPrefix); + await repository.addAmountToSpendingHistory(createdPlan.id, amount, requestDetails); - const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestDetails); expect(spendingHistory).to.have.lengthOf(1); expect(spendingHistory[0].amount).to.equal(amount); expect(spendingHistory[0].timestamp).to.be.a('Date'); @@ -158,15 +158,15 @@ describe('HbarSpendingPlanRepository', function () { it('adds multiple amounts to spending history', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); - await expect(repository.getSpendingHistory(createdPlan.id, requestIdPrefix)).to.be.eventually.deep.equal([]); + const createdPlan = await repository.create(subscriptionType, requestDetails); + await expect(repository.getSpendingHistory(createdPlan.id, requestDetails)).to.be.eventually.deep.equal([]); const amounts = [100, 200, 300]; for (const amount of amounts) { - await repository.addAmountToSpendingHistory(createdPlan.id, amount, requestIdPrefix); + await repository.addAmountToSpendingHistory(createdPlan.id, amount, requestDetails); } - const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestIdPrefix); + const spendingHistory = await repository.getSpendingHistory(createdPlan.id, requestDetails); expect(spendingHistory).to.have.lengthOf(3); expect(spendingHistory.map((entry) => entry.amount)).to.deep.equal(amounts); }); @@ -175,7 +175,7 @@ describe('HbarSpendingPlanRepository', function () { const id = 'non-existent-id'; const amount = 100; - await expect(repository.addAmountToSpendingHistory(id, amount, requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(repository.addAmountToSpendingHistory(id, amount, requestDetails)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID ${id} not found`, ); @@ -202,35 +202,34 @@ describe('HbarSpendingPlanRepository', function () { it('retrieves spent today for a plan', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); const amount = 50; - await repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix); + await repository.addAmountToSpentToday(createdPlan.id, amount, requestDetails); - const spentToday = await repository.getSpentToday(createdPlan.id, requestIdPrefix); + const spentToday = await repository.getSpentToday(createdPlan.id, requestDetails); expect(spentToday).to.equal(amount); }); it('returns 0 if spent today key does not exist', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); - const spentToday = await repository.getSpentToday(createdPlan.id, requestIdPrefix); + const spentToday = await repository.getSpentToday(createdPlan.id, requestDetails); expect(spentToday).to.equal(0); }); it('should expire spent today key at the end of the day', async () => { - const requestIdPrefix = `[Request ID: testId]`; const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); const amount = 50; - await repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix); - await expect(repository.getSpentToday(createdPlan.id, requestIdPrefix)).to.eventually.equal(amount); + await repository.addAmountToSpentToday(createdPlan.id, amount, requestDetails); + await expect(repository.getSpentToday(createdPlan.id, requestDetails)).to.eventually.equal(amount); await new Promise((resolve) => setTimeout(resolve, mockedOneDayInMillis + 100)); - await expect(repository.getSpentToday(createdPlan.id, requestIdPrefix)).to.eventually.equal(0); + await expect(repository.getSpentToday(createdPlan.id, requestDetails)).to.eventually.equal(0); }); }); @@ -260,20 +259,20 @@ describe('HbarSpendingPlanRepository', function () { describe('addAmountToSpentToday', () => { it('adds amount to spent today', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); const amount = 50; - await repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix); + await repository.addAmountToSpentToday(createdPlan.id, amount, requestDetails); - const plan = await repository.findByIdWithDetails(createdPlan.id, requestIdPrefix); + const plan = await repository.findByIdWithDetails(createdPlan.id, requestDetails); expect(plan).to.not.be.null; expect(plan!.spentToday).to.equal(amount); // Add more to spent today const newAmount = 100; - await repository.addAmountToSpentToday(createdPlan.id, newAmount, requestIdPrefix); + await repository.addAmountToSpentToday(createdPlan.id, newAmount, requestDetails); - const updatedPlan = await repository.findByIdWithDetails(createdPlan.id, requestIdPrefix); + const updatedPlan = await repository.findByIdWithDetails(createdPlan.id, requestDetails); expect(updatedPlan).to.not.be.null; expect(updatedPlan!.spentToday).to.equal(amount + newAmount); }); @@ -282,7 +281,7 @@ describe('HbarSpendingPlanRepository', function () { const id = 'non-existent-id'; const amount = 50; - await expect(repository.addAmountToSpentToday(id, amount, requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(repository.addAmountToSpentToday(id, amount, requestDetails)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID ${id} not found`, ); @@ -290,15 +289,15 @@ describe('HbarSpendingPlanRepository', function () { it('throws an error if plan is not active when adding to spent today', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); // Manually set the plan to inactive const key = `${repository['collectionKey']}:${createdPlan.id}`; - await cacheService.set(key, { ...createdPlan, active: false }, 'test'); + await cacheService.set(key, { ...createdPlan, active: false }, 'test', requestDetails); const amount = 50; await expect( - repository.addAmountToSpentToday(createdPlan.id, amount, requestIdPrefix), + repository.addAmountToSpentToday(createdPlan.id, amount, requestDetails), ).to.be.eventually.rejectedWith( HbarSpendingPlanNotActiveError, `HbarSpendingPlan with ID ${createdPlan.id} is not active`, @@ -309,7 +308,7 @@ describe('HbarSpendingPlanRepository', function () { describe('checkExistsAndActive', () => { it('throws error if plan does not exist when checking if exists and active', async () => { const id = 'non-existent-id'; - await expect(repository.checkExistsAndActive(id, requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(repository.checkExistsAndActive(id, requestDetails)).to.be.eventually.rejectedWith( HbarSpendingPlanNotFoundError, `HbarSpendingPlan with ID ${id} not found`, ); @@ -317,13 +316,13 @@ describe('HbarSpendingPlanRepository', function () { it('throws error if plan is not active when checking if exists and active', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); // Manually set the plan to inactive const key = `${repository['collectionKey']}:${createdPlan.id}`; - await cacheService.set(key, { ...createdPlan, active: false }, 'test'); + await cacheService.set(key, { ...createdPlan, active: false }, 'test', requestDetails); - await expect(repository.checkExistsAndActive(createdPlan.id, requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(repository.checkExistsAndActive(createdPlan.id, requestDetails)).to.be.eventually.rejectedWith( HbarSpendingPlanNotActiveError, `HbarSpendingPlan with ID ${createdPlan.id} is not active`, ); @@ -333,47 +332,56 @@ describe('HbarSpendingPlanRepository', function () { describe('findAllActiveBySubscriptionType', () => { it('returns an empty array if no active plans exist for the subscription type', async () => { const subscriptionType = SubscriptionType.BASIC; - const activePlans = await repository.findAllActiveBySubscriptionType(subscriptionType); + const activePlans = await repository.findAllActiveBySubscriptionType(subscriptionType, requestDetails); expect(activePlans).to.deep.equal([]); }); it('returns all active plans for the subscription type', async () => { const subscriptionType = SubscriptionType.BASIC; - const createdPlan1 = await repository.create(subscriptionType); - const createdPlan2 = await repository.create(subscriptionType); + const createdPlan1 = await repository.create(subscriptionType, requestDetails); + const createdPlan2 = await repository.create(subscriptionType, requestDetails); - const activePlans = await repository.findAllActiveBySubscriptionType(subscriptionType); + const activePlans = await repository.findAllActiveBySubscriptionType(subscriptionType, requestDetails); expect(activePlans).to.have.lengthOf(2); expect(activePlans.map((plan) => plan.id)).to.include.members([createdPlan1.id, createdPlan2.id]); }); it('does not return inactive plans for the subscription type', async () => { const subscriptionType = SubscriptionType.BASIC; - const activePlan = await repository.create(subscriptionType); - const inactivePlan = await repository.create(subscriptionType); + const activePlan = await repository.create(subscriptionType, requestDetails); + const inactivePlan = await repository.create(subscriptionType, requestDetails); // Manually set the plan to inactive const key = `${repository['collectionKey']}:${inactivePlan.id}`; - await cacheService.set(key, { ...inactivePlan, active: false }, 'test'); + await cacheService.set(key, { ...inactivePlan, active: false }, 'test', requestDetails); - const activePlans = await repository.findAllActiveBySubscriptionType(subscriptionType); + const activePlans = await repository.findAllActiveBySubscriptionType(subscriptionType, requestDetails); expect(activePlans).to.deep.equal([activePlan]); }); it('returns only active plans for the specified subscription type', async () => { - const basicPlan = await repository.create(SubscriptionType.BASIC); - const extendedPlan = await repository.create(SubscriptionType.EXTENDED); - const privilegedPlan = await repository.create(SubscriptionType.PRIVILEGED); + const basicPlan = await repository.create(SubscriptionType.BASIC, requestDetails); + const extendedPlan = await repository.create(SubscriptionType.EXTENDED, requestDetails); + const privilegedPlan = await repository.create(SubscriptionType.PRIVILEGED, requestDetails); - const activeBasicPlans = await repository.findAllActiveBySubscriptionType(SubscriptionType.BASIC); + const activeBasicPlans = await repository.findAllActiveBySubscriptionType( + SubscriptionType.BASIC, + requestDetails, + ); expect(activeBasicPlans).to.have.lengthOf(1); expect(activeBasicPlans[0].id).to.equal(basicPlan.id); - const activeExtendedPlans = await repository.findAllActiveBySubscriptionType(SubscriptionType.EXTENDED); + const activeExtendedPlans = await repository.findAllActiveBySubscriptionType( + SubscriptionType.EXTENDED, + requestDetails, + ); expect(activeExtendedPlans).to.have.lengthOf(1); expect(activeExtendedPlans[0].id).to.equal(extendedPlan.id); - const activePrivilegedPlans = await repository.findAllActiveBySubscriptionType(SubscriptionType.PRIVILEGED); + const activePrivilegedPlans = await repository.findAllActiveBySubscriptionType( + SubscriptionType.PRIVILEGED, + requestDetails, + ); expect(activePrivilegedPlans).to.have.lengthOf(1); expect(activePrivilegedPlans[0].id).to.equal(privilegedPlan.id); }); From b75e1f71edab7d8ced694040095b93c5343050c3 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Mon, 16 Sep 2024 15:11:01 +0300 Subject: [PATCH 31/48] Fixes acceptance tests using request details Signed-off-by: Konstantina Blazhukova --- .../server/tests/acceptance/equivalence.spec.ts | 11 ++++++++--- packages/server/tests/acceptance/index.spec.ts | 2 +- .../server/tests/acceptance/rpc_batch1.spec.ts | 15 +++++++-------- .../server/tests/acceptance/rpc_batch3.spec.ts | 10 ++++++---- packages/server/tests/clients/mirrorClient.ts | 1 - packages/ws-server/tests/acceptance/index.spec.ts | 4 +++- 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/server/tests/acceptance/equivalence.spec.ts b/packages/server/tests/acceptance/equivalence.spec.ts index 3991c0349c..5908f3946c 100644 --- a/packages/server/tests/acceptance/equivalence.spec.ts +++ b/packages/server/tests/acceptance/equivalence.spec.ts @@ -31,6 +31,7 @@ import pino from 'pino'; import { MirrorNodeClient } from '../../../relay/src/lib/clients'; import { hexToASCII } from '../../../relay/src/formatters'; import { AliasAccount } from '../types/AliasAccount'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; const logger = pino(); enum CallTypes { @@ -76,6 +77,7 @@ describe('Equivalence tests', async function () { const { servicesNode, mirrorNode, relay }: any = global; const servicesClient = servicesNode as ServicesClient; const mirrorNodeClient = mirrorNode as MirrorNodeClient; + const requestDetails = new RequestDetails({ requestId: 'rpc_batch1Test', ipAddress: '0.0.0.0' }); let precheck: Precheck; const SUCCESS = 'SUCCESS'; @@ -185,7 +187,10 @@ describe('Equivalence tests', async function () { equivalenceContractId = equivalenceContractReceipt.contractId.toString(); requestId = Utils.generateRequestId(); - const contractMirror = await mirrorNodeClient.get(`/contracts/${estimatePrecompileSolidityAddress}`, requestId); + const contractMirror = await mirrorNodeClient.get( + `/contracts/${estimatePrecompileSolidityAddress}`, + requestDetails, + ); accounts[0] = await servicesClient.createAccountWithContractIdKey( contractMirror.contract_id, @@ -355,7 +360,7 @@ describe('Equivalence tests', async function () { }; async function getResultByEntityIdAndTxTimestamp(entityId, txTimestamp) { - return await mirrorNode.get(`/contracts/${entityId}/results/${txTimestamp}`); + return await mirrorNode.get(`/contracts/${entityId}/results/${txTimestamp}`, requestDetails); } /** @@ -364,7 +369,7 @@ describe('Equivalence tests', async function () { * @returns list of ContractActions */ async function getContractActions(transactionIdOrHash: string) { - return await mirrorNodeClient.get(`/contracts/results/${transactionIdOrHash}/actions`, Utils.generateRequestId()); + return await mirrorNode.get(`/contracts/results/${transactionIdOrHash}/actions`, requestDetails); } async function createFungibleToken() { diff --git a/packages/server/tests/acceptance/index.spec.ts b/packages/server/tests/acceptance/index.spec.ts index 47468e8923..572152bb31 100644 --- a/packages/server/tests/acceptance/index.spec.ts +++ b/packages/server/tests/acceptance/index.spec.ts @@ -132,7 +132,7 @@ describe('RPC Server Acceptance Tests', function () { ); global.accounts = new Array(initialAccount); - await global.mirrorNode.get(`/accounts/${initialAccount.address}`); + await global.mirrorNode.get(`/accounts/${initialAccount.address}`, Utils.generateRequestId()); }); after(async function () { diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index e5f415cd5a..6112b69b69 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -42,7 +42,6 @@ import RelayCalls from '../../tests/helpers/constants'; import { numberTo0x, prepend0x } from '../../../../packages/relay/src/formatters'; import constants from '../../../relay/src/lib/constants'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; -import { JsonRpcError } from '@hashgraph/json-rpc-relay'; const Address = RelayCalls; @@ -73,9 +72,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { * @param tx: any - supposedly a proper transaction that has `from` and `to` fields * @returns Promise<{from: any|null, to: any|null}> */ - const resolveAccountEvmAddresses = async (tx: any) => { - const fromAccountInfo = await mirrorNode.get(`/accounts/${tx.from}`); - const toAccountInfo = await mirrorNode.get(`/accounts/${tx.to}`); + const resolveAccountEvmAddresses = async (tx: any, requestDetails: RequestDetails) => { + const fromAccountInfo = await mirrorNode.get(`/accounts/${tx.from}`, requestDetails); + const toAccountInfo = await mirrorNode.get(`/accounts/${tx.to}`, requestDetails); return { from: fromAccountInfo?.evm_address ?? tx.from, to: toAccountInfo?.evm_address ?? tx.to, @@ -488,7 +487,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // resolve EVM address for `from` and `to` for (const mirrorTx of mirrorTransactions) { - const resolvedAddresses = await resolveAccountEvmAddresses(mirrorTx); + const resolvedAddresses = await resolveAccountEvmAddresses(mirrorTx, requestDetails); mirrorTx.from = resolvedAddresses.from; mirrorTx.to = resolvedAddresses.to; @@ -998,8 +997,8 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { `/contracts/results/${deterministicDeployTransactionHash}`, requestDetails, ); - const fromAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.from}`); - const toAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.to}`); + const fromAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.from}`, requestDetails); + const toAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.to}`, requestDetails); expect(receipt).to.exist; expect(fromAccountInfo.evm_address).to.eq(constants.DETERMINISTIC_DEPLOYMENT_SIGNER); @@ -1273,7 +1272,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { await Utils.wait(1000); const txInfo = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); - const contractResult = await mirrorNode.get(`/contracts/${txInfo.contract_id}`); + const contractResult = await mirrorNode.get(`/contracts/${txInfo.contract_id}`, requestDetails); const fileInfo = await new FileInfoQuery().setFileId(contractResult.file_id).execute(servicesNode.client); expect(fileInfo).to.exist; expect(fileInfo instanceof FileInfo).to.be.true; diff --git a/packages/server/tests/acceptance/rpc_batch3.spec.ts b/packages/server/tests/acceptance/rpc_batch3.spec.ts index c5de6a340a..9fe325286d 100644 --- a/packages/server/tests/acceptance/rpc_batch3.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch3.spec.ts @@ -52,6 +52,7 @@ import TokenCreateJson from '../contracts/TokenCreateContract.json'; import { EthImpl } from '@hashgraph/json-rpc-relay/src/lib/eth'; import { predefined } from '@hashgraph/json-rpc-relay'; import { TYPES } from '../../src/validator'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; chai.use(chaiExclude); @@ -59,6 +60,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds const accounts: AliasAccount[] = []; + const requestDetails = new RequestDetails({ requestId: 'rpc_batch1Test', ipAddress: '0.0.0.0' }); // @ts-ignore const { servicesNode, mirrorNode, relay } = global; @@ -110,7 +112,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { initialAccount, neededAccounts, initialBalance, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); @@ -1008,7 +1010,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { }); it('should execute "eth_getTransactionCount" for account with non-zero nonce', async function () { - const account = await Utils.createAliasAccount(mirrorNode, accounts[0], requestId); + const account = await Utils.createAliasAccount(mirrorNode, accounts[0], requestDetails); const gasPrice = await relay.gasPrice(requestId); const transaction = { @@ -1245,7 +1247,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const signedTransaction = await accounts[0].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTransaction, requestId); - estimateGasContractAddress = await mirrorNode.get(`/contracts/results/${transactionHash}`); + estimateGasContractAddress = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); }); describe('Positive scenarios', async function () { @@ -2027,7 +2029,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { }); it('Should return a batch of requests', async function () { - const testAccount = await Utils.createAliasAccount(mirrorNode, accounts[0], requestId); + const testAccount = await Utils.createAliasAccount(mirrorNode, accounts[0], requestDetails); { const payload = [ diff --git a/packages/server/tests/clients/mirrorClient.ts b/packages/server/tests/clients/mirrorClient.ts index e4d764da00..a0de83688a 100644 --- a/packages/server/tests/clients/mirrorClient.ts +++ b/packages/server/tests/clients/mirrorClient.ts @@ -21,7 +21,6 @@ import Axios, { AxiosInstance } from 'axios'; import axiosRetry from 'axios-retry'; import { Logger } from 'pino'; -import { Utils } from '../helpers/utils'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; export default class MirrorClient { diff --git a/packages/ws-server/tests/acceptance/index.spec.ts b/packages/ws-server/tests/acceptance/index.spec.ts index 6ece830f78..836d2f5b89 100644 --- a/packages/ws-server/tests/acceptance/index.spec.ts +++ b/packages/ws-server/tests/acceptance/index.spec.ts @@ -35,6 +35,7 @@ import { app as wsApp } from '@hashgraph/json-rpc-ws-server/dist/webSocketServer import ServicesClient from '@hashgraph/json-rpc-server/tests/clients/servicesClient'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../../../.env') }); const testLogger = pino({ @@ -63,6 +64,7 @@ global.relayIsLocal = RELAY_URL === LOCAL_RELAY_URL; describe('RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds + const requestDetails = new RequestDetails({ requestId: 'rpc_batch1Test', ipAddress: '0.0.0.0' }); let relayServer; // Relay Server let socketServer; global.servicesNode = new ServicesClient( @@ -100,7 +102,7 @@ describe('RPC Server Acceptance Tests', function () { ); global.accounts = new Array(initialAccount); - await global.mirrorNode.get(`/accounts/${initialAccount.address}`); + await global.mirrorNode.get(`/accounts/${initialAccount.address}`, requestDetails); }); after(async function () { From ac74abd358e1bea15b1a5ee689448a418f32dd85 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Tue, 17 Sep 2024 11:30:43 +0300 Subject: [PATCH 32/48] Fixes ws-server acceptance tests Signed-off-by: Konstantina Blazhukova --- .../lib/services/cacheService/cacheService.ts | 36 ------------------- .../hbarLimitService/IHbarLimitService.ts | 4 +-- .../lib/services/hbarLimitService/index.ts | 25 ++----------- packages/server/tests/clients/relayClient.ts | 4 +-- .../server/tests/clients/servicesClient.ts | 4 +-- .../tests/acceptance/getBalance.spec.ts | 11 +++--- .../tests/acceptance/getLogs.spec.ts | 12 ++++--- .../acceptance/getTransactionByHash.spec.ts | 20 ++++++----- .../acceptance/getTransactionCount.spec.ts | 19 +++++----- .../acceptance/getTransactionReceipt.spec.ts | 19 +++++----- .../acceptance/sendRawTransaction.spec.ts | 26 ++++++++------ 11 files changed, 72 insertions(+), 108 deletions(-) diff --git a/packages/relay/src/lib/services/cacheService/cacheService.ts b/packages/relay/src/lib/services/cacheService/cacheService.ts index e66b33cbc0..e1a9135403 100644 --- a/packages/relay/src/lib/services/cacheService/cacheService.ts +++ b/packages/relay/src/lib/services/cacheService/cacheService.ts @@ -213,12 +213,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while getting the cache from Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while getting the cache from Redis. Fallback to internal cache.`, ->>>>>>> c7c5c919 (chore: draft changes) ); // fallback to internal cache in case of Redis error @@ -282,12 +278,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while setting the cache to Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while setting the cache to Redis. Fallback to internal cache.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -327,12 +319,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while setting the cache to Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while setting the cache to Redis. Fallback to internal cache.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -362,12 +350,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while deleting cache from Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while deleting cache from Redis.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -391,12 +375,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while clearing Redis cache. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while clearing Redis cache.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -429,12 +409,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while incrementing cache in Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while incrementing cache in Redis.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -472,12 +448,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while pushing cache in Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while pushing cache in Redis.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -526,12 +498,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while getting cache in Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while getting cache in Redis.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } @@ -561,12 +529,8 @@ export class CacheService { } catch (error) { const redisError = new RedisCacheError(error); this.logger.error( -<<<<<<< HEAD - `${requestIdPrefix} Error occurred while getting keys from Redis. Fallback to internal cache. ${redisError}`, -======= redisError, `${requestDetails.formattedRequestId} Error occurred while getting keys from Redis.`, ->>>>>>> c7c5c919 (chore: draft changes) ); } } diff --git a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts index f087b28976..6b5a15f730 100644 --- a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts +++ b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts @@ -27,8 +27,8 @@ export interface IHbarLimitService { methodName: string, ethAddress: string, requestDetails: RequestDetails, - ipAddress?: string, + ipAddress: string, estimatedTxFee?: number, ): Promise; - addExpense(cost: number, ethAddress: string, ipAddress?: string): Promise; + addExpense(cost: number, ethAddress: string, requestDetails: RequestDetails, ipAddress?: string): Promise; } diff --git a/packages/relay/src/lib/services/hbarLimitService/index.ts b/packages/relay/src/lib/services/hbarLimitService/index.ts index d58e298f6a..acfe545f71 100644 --- a/packages/relay/src/lib/services/hbarLimitService/index.ts +++ b/packages/relay/src/lib/services/hbarLimitService/index.ts @@ -21,7 +21,6 @@ import { Logger } from 'pino'; import { Counter, Gauge, Registry } from 'prom-client'; import { IHbarLimitService } from './IHbarLimitService'; -import { formatRequestIdMessage } from '../../../formatters'; import { SubscriptionType } from '../../db/types/hbarLimiter/subscriptionType'; import { IDetailedHbarSpendingPlan } from '../../db/types/hbarLimiter/hbarSpendingPlan'; import { HbarSpendingPlanRepository } from '../../db/repositories/hbarLimiter/hbarSpendingPlanRepository'; @@ -171,7 +170,7 @@ export class HbarLimitService implements IHbarLimitService { methodName: string, ethAddress: string, requestDetails: RequestDetails, - ipAddress?: string, + ipAddress: string, estimatedTxFee: number = 0, ): Promise { if (await this.isDailyBudgetExceeded(mode, methodName, estimatedTxFee, requestDetails)) { @@ -208,7 +207,7 @@ export class HbarLimitService implements IHbarLimitService { * @param {RequestDetails} requestDetails The request details for logging and tracking. * @returns {Promise} - A promise that resolves when the expense has been added. */ - async addExpense(cost: number, ethAddress: string, ipAddress: string, requestDetails: RequestDetails): Promise { + async addExpense(cost: number, ethAddress: string, requestDetails: RequestDetails, ipAddress: string): Promise { if (!ethAddress && !ipAddress) { throw new Error('Cannot add expense without an eth address or ip address'); } @@ -410,27 +409,8 @@ export class HbarLimitService implements IHbarLimitService { if (!ethAddress && !ipAddress) { throw new Error('Cannot create a spending plan without an associated eth address or ip address'); } -<<<<<<< HEAD - const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC, requstIdPrefix); - if (ethAddress) { - this.logger.trace(`Linking spending plan with ID ${spendingPlan.id} to eth address ${ethAddress}`); - await this.ethAddressHbarSpendingPlanRepository.save({ ethAddress, planId: spendingPlan.id }, requstIdPrefix); - } - if (ipAddress) { - this.logger.trace(`Linking spending plan with ID ${spendingPlan.id} to ip address ${ipAddress}`); - await this.ipAddressHbarSpendingPlanRepository.save({ ipAddress, planId: spendingPlan.id }); -======= -<<<<<<< HEAD -<<<<<<< HEAD - const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC); - -======= - const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC, requstIdPrefix); ->>>>>>> 171fcf4c (Makes requestId required in all methods of cacheService) -======= const spendingPlan = await this.hbarSpendingPlanRepository.create(SubscriptionType.BASIC, requestDetails); ->>>>>>> ca55f87f (chore: draft changes) if (ethAddress) { this.logger.trace( `${requestDetails.formattedRequestId} Linking spending plan with ID ${spendingPlan.id} to eth address ${ethAddress}`, @@ -442,7 +422,6 @@ export class HbarLimitService implements IHbarLimitService { ); // TODO: Implement this with https://github.com/hashgraph/hedera-json-rpc-relay/issues/2888 // await this.ipAddressHbarSpendingPlanRepository.save({ ipAddress, planId: spendingPlan.id }); ->>>>>>> 6ec726a8 (chore: draft changes) } return spendingPlan; } diff --git a/packages/server/tests/clients/relayClient.ts b/packages/server/tests/clients/relayClient.ts index 1dd39b3313..06f39fd2f1 100644 --- a/packages/server/tests/clients/relayClient.ts +++ b/packages/server/tests/clients/relayClient.ts @@ -125,7 +125,7 @@ export default class RelayClient { * @param block * @param requestId */ - async getBalance(address, block = 'latest', requestId?: string) { + async getBalance(address, block = 'latest', requestId: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); this.logger.debug(`${requestIdPrefix} [POST] to relay eth_getBalance for address ${address}]`); return this.provider.getBalance(address, block); @@ -136,7 +136,7 @@ export default class RelayClient { * @param requestId * Returns: The nonce of the account with the provided `evmAddress` */ - async getAccountNonce(evmAddress, requestId?: string): Promise { + async getAccountNonce(evmAddress, requestId: string): Promise { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); this.logger.debug(`${requestIdPrefix} [POST] to relay for eth_getTransactionCount for address ${evmAddress}`); const nonce = await this.provider.send('eth_getTransactionCount', [evmAddress, 'latest']); diff --git a/packages/server/tests/clients/servicesClient.ts b/packages/server/tests/clients/servicesClient.ts index 6d56d983fa..2ee4a986df 100644 --- a/packages/server/tests/clients/servicesClient.ts +++ b/packages/server/tests/clients/servicesClient.ts @@ -174,7 +174,7 @@ export default class ServicesClient { return { executedTimestamp, executedTransactionId }; } - async createToken(initialSupply = 1000, requestId?: string) { + async createToken(initialSupply = 1000, requestId: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const symbol = Math.random().toString(36).slice(2, 6).toUpperCase(); this.logger.trace(`${requestIdPrefix} symbol = ${symbol}`); @@ -195,7 +195,7 @@ export default class ServicesClient { return tokenId; } - async associateToken(tokenId, requestId?: string) { + async associateToken(tokenId, requestId: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); await this.executeAndGetTransactionReceipt( await new TokenAssociateTransaction() diff --git a/packages/ws-server/tests/acceptance/getBalance.spec.ts b/packages/ws-server/tests/acceptance/getBalance.spec.ts index d4647306eb..1019b2d733 100644 --- a/packages/ws-server/tests/acceptance/getBalance.spec.ts +++ b/packages/ws-server/tests/acceptance/getBalance.spec.ts @@ -24,6 +24,8 @@ import { ethers, WebSocketProvider } from 'ethers'; import { WsTestConstant, WsTestHelper } from '../helper'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; +import MirrorClient from '@hashgraph/json-rpc-server/tests/clients/mirrorClient'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-1 eth_getBalance', async function () { const METHOD_NAME = 'eth_getBalance'; @@ -38,13 +40,14 @@ describe('@web-socket-batch-1 eth_getBalance', async function () { [WsTestConstant.FAKE_TX_HASH, '0xhbar', 36], ]; // @ts-ignore - const { mirrorNode } = global; + const { mirrorNode }: { mirrorNode: MirrorClient } = global; + const requestId = 'getBalanceTest_ws-server'; + const requestDetails = new RequestDetails({ requestId: requestId, ipAddress: '0.0.0.0' }); + let accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; - let requestId: string; before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '2500000000'; //25 Hbar @@ -55,7 +58,7 @@ describe('@web-socket-batch-1 eth_getBalance', async function () { initialAccount, neededAccounts, initialAmount, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); diff --git a/packages/ws-server/tests/acceptance/getLogs.spec.ts b/packages/ws-server/tests/acceptance/getLogs.spec.ts index fea30b0a0c..1b130edff3 100644 --- a/packages/ws-server/tests/acceptance/getLogs.spec.ts +++ b/packages/ws-server/tests/acceptance/getLogs.spec.ts @@ -24,6 +24,8 @@ import { ethers, WebSocketProvider } from 'ethers'; import { WsTestConstant, WsTestHelper } from '../helper'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; +import MirrorClient from '@hashgraph/json-rpc-server/tests/clients/mirrorClient'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-2 eth_getLogs', async function () { const EXPECTED_VALUE = 7; @@ -77,13 +79,15 @@ describe('@web-socket-batch-2 eth_getLogs', async function () { const SIMPLE_CONTRACT_BYTECODE = '0x6080604052348015600f57600080fd5b507f4e7df42af9a017b7c655a28ef10cbc8f05b2b088f087ee02416cfa1a96ac3be26007604051603e91906091565b60405180910390a160aa565b6000819050919050565b6000819050919050565b6000819050919050565b6000607d6079607584604a565b605e565b6054565b9050919050565b608b816068565b82525050565b600060208201905060a460008301846084565b92915050565b603f8060b76000396000f3fe6080604052600080fdfea264697066735822122084db7fe76bde5c9c041d61bb40294c56dc6d339bdbc8e0cd285fc4008ccefc2c64736f6c63430008180033'; // @ts-ignore - const { mirrorNode } = global; + const { mirrorNode }: { mirrorNode: MirrorClient } = global; + const requestId = 'getLogsTest_ws-server'; + const requestDetails = new RequestDetails({ requestId: requestId, ipAddress: '0.0.0.0' }); + let wsFilterObj: any, accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; - let requestId: string; + before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '2500000000'; //25 Hbar @@ -94,7 +98,7 @@ describe('@web-socket-batch-2 eth_getLogs', async function () { initialAccount, neededAccounts, initialAmount, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); diff --git a/packages/ws-server/tests/acceptance/getTransactionByHash.spec.ts b/packages/ws-server/tests/acceptance/getTransactionByHash.spec.ts index 3e681433df..c3dee35c12 100644 --- a/packages/ws-server/tests/acceptance/getTransactionByHash.spec.ts +++ b/packages/ws-server/tests/acceptance/getTransactionByHash.spec.ts @@ -26,6 +26,9 @@ import { numberTo0x } from '@hashgraph/json-rpc-relay/src/formatters'; import { ONE_TINYBAR_IN_WEI_HEX } from '@hashgraph/json-rpc-relay/tests/lib/eth/eth-config'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; +import MirrorClient from '@hashgraph/json-rpc-server/tests/clients/mirrorClient'; +import RelayClient from '@hashgraph/json-rpc-server/tests/clients/relayClient'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-2 eth_getTransactionByHash', async function () { const METHOD_NAME = 'eth_getTransactionByHash'; @@ -45,15 +48,16 @@ describe('@web-socket-batch-2 eth_getTransactionByHash', async function () { ]; // @ts-ignore - const { mirrorNode, relay, initialBalance } = global; + const { mirrorNode, relay, initialBalance }: { mirrorNode: MirrorClient; relay: RelayClient } = global; + const requestId = 'getTransactionByHash_ws-server'; + const requestDetails = new RequestDetails({ requestId: requestId, ipAddress: '0.0.0.0' }); + let txHash: string, expectedTxReceipt: any, accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; - let requestId: string; before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const neededAccounts: number = 2; @@ -63,7 +67,7 @@ describe('@web-socket-batch-2 eth_getTransactionByHash', async function () { initialAccount, neededAccounts, initialBalance, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); @@ -73,12 +77,12 @@ describe('@web-socket-batch-2 eth_getTransactionByHash', async function () { gasLimit: numberTo0x(30000), chainId: Number(CHAIN_ID), to: accounts[1].address, - nonce: await relay.getAccountNonce(accounts[0].address), - maxFeePerGas: await relay.gasPrice(), + nonce: await relay.getAccountNonce(accounts[0].address, requestId), + maxFeePerGas: await relay.gasPrice(requestId), }; const signedTx = await accounts[0].wallet.signTransaction(tx); - txHash = await relay.sendRawTransaction(signedTx); - expectedTxReceipt = await mirrorNode.get(`/contracts/results/${txHash}`); + txHash = await relay.sendRawTransaction(signedTx, requestId); + expectedTxReceipt = await mirrorNode.get(`/contracts/results/${txHash}`, requestDetails); }); beforeEach(async () => { diff --git a/packages/ws-server/tests/acceptance/getTransactionCount.spec.ts b/packages/ws-server/tests/acceptance/getTransactionCount.spec.ts index ac74249c2a..80e16363d1 100644 --- a/packages/ws-server/tests/acceptance/getTransactionCount.spec.ts +++ b/packages/ws-server/tests/acceptance/getTransactionCount.spec.ts @@ -25,6 +25,9 @@ import { WsTestConstant, WsTestHelper } from '../helper'; import { numberTo0x } from '@hashgraph/json-rpc-relay/src/formatters'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; +import MirrorClient from '@hashgraph/json-rpc-server/tests/clients/mirrorClient'; +import RelayClient from '@hashgraph/json-rpc-server/tests/clients/relayClient'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@release @web-socket-batch-2 eth_getTransactionCount', async function () { const METHOD_NAME = 'eth_getTransactionCount'; @@ -32,14 +35,14 @@ describe('@release @web-socket-batch-2 eth_getTransactionCount', async function const ONE_TINYBAR = Utils.add0xPrefix(Utils.toHex(ethers.parseUnits('1', 10))); // @ts-ignore - const { mirrorNode, relay } = global; + const { mirrorNode, relay }: { mirrorNode: MirrorClient; relay: RelayClient } = global; + const requestId = 'getTransactionCount_ws-server'; + const requestDetails = new RequestDetails({ requestId: requestId, ipAddress: '0.0.0.0' }); - let requestId: string, - accounts: AliasAccount[] = [], + let accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '100000000'; //1 Hbar @@ -50,7 +53,7 @@ describe('@release @web-socket-batch-2 eth_getTransactionCount', async function initialAccount, neededAccounts, initialAmount, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); @@ -85,7 +88,7 @@ describe('@release @web-socket-batch-2 eth_getTransactionCount', async function 'latest', ]); WsTestHelper.assertJsonRpcObject(beforeSendRawTransactionCountResponse); - const transactionCountBefore = await relay.getAccountNonce(accounts[0].address); + const transactionCountBefore = await relay.getAccountNonce(accounts[0].address, requestId); expect(Number(beforeSendRawTransactionCountResponse.result)).to.eq(transactionCountBefore); const transaction = { @@ -94,7 +97,7 @@ describe('@release @web-socket-batch-2 eth_getTransactionCount', async function chainId: Number(CHAIN_ID), to: accounts[1].address, maxFeePerGas: defaultGasPrice, - nonce: await relay.getAccountNonce(accounts[0].address), + nonce: await relay.getAccountNonce(accounts[0].address, requestId), }; const signedTx = await accounts[0].wallet.signTransaction(transaction); // @notice submit a transaction to increase transaction count @@ -105,7 +108,7 @@ describe('@release @web-socket-batch-2 eth_getTransactionCount', async function 'latest', ]); WsTestHelper.assertJsonRpcObject(afterSendRawTransactionCountResponse); - const transactionCountAfter = await relay.getAccountNonce(accounts[0].address); + const transactionCountAfter = await relay.getAccountNonce(accounts[0].address, requestId); expect(Number(afterSendRawTransactionCountResponse.result)).to.eq(transactionCountAfter); }); }); diff --git a/packages/ws-server/tests/acceptance/getTransactionReceipt.spec.ts b/packages/ws-server/tests/acceptance/getTransactionReceipt.spec.ts index 273512c5d9..12bed02289 100644 --- a/packages/ws-server/tests/acceptance/getTransactionReceipt.spec.ts +++ b/packages/ws-server/tests/acceptance/getTransactionReceipt.spec.ts @@ -26,6 +26,9 @@ import { numberTo0x } from '@hashgraph/json-rpc-relay/src/formatters'; import { ONE_TINYBAR_IN_WEI_HEX } from '@hashgraph/json-rpc-relay/tests/lib/eth/eth-config'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; +import MirrorClient from '@hashgraph/json-rpc-server/tests/clients/mirrorClient'; +import RelayClient from '@hashgraph/json-rpc-server/tests/clients/relayClient'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-2 eth_getTransactionReceipt', async function () { const METHOD_NAME = 'eth_getTransactionReceipt'; @@ -45,16 +48,16 @@ describe('@web-socket-batch-2 eth_getTransactionReceipt', async function () { ]; // @ts-ignore - const { mirrorNode, relay, initialBalance } = global; + const { mirrorNode, relay, initialBalance }: { mirrorNode: MirrorClient; relay: RelayClient } = global; + const requestId = 'getTransactionReceiptTest_ws-server'; + const requestDetails = new RequestDetails({ requestId: requestId, ipAddress: '0.0.0.0' }); let txHash: string, expectedTxReceipt: any, accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; - let requestId: string; before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const neededAccounts: number = 3; @@ -64,7 +67,7 @@ describe('@web-socket-batch-2 eth_getTransactionReceipt', async function () { initialAccount, neededAccounts, initialBalance, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); @@ -74,13 +77,13 @@ describe('@web-socket-batch-2 eth_getTransactionReceipt', async function () { gasLimit: numberTo0x(30000), chainId: Number(CHAIN_ID), to: accounts[1].address, - nonce: await relay.getAccountNonce(accounts[0].address), - maxFeePerGas: await relay.gasPrice(), + nonce: await relay.getAccountNonce(accounts[0].address, requestId), + maxFeePerGas: await relay.gasPrice(requestId), }; const signedTx = await accounts[0].wallet.signTransaction(tx); - txHash = await relay.sendRawTransaction(signedTx); - expectedTxReceipt = await mirrorNode.get(`/contracts/results/${txHash}`); + txHash = await relay.sendRawTransaction(signedTx, requestId); + expectedTxReceipt = await mirrorNode.get(`/contracts/results/${txHash}`, requestDetails); }); beforeEach(async () => { diff --git a/packages/ws-server/tests/acceptance/sendRawTransaction.spec.ts b/packages/ws-server/tests/acceptance/sendRawTransaction.spec.ts index 61f7588234..9d46bd5e6b 100644 --- a/packages/ws-server/tests/acceptance/sendRawTransaction.spec.ts +++ b/packages/ws-server/tests/acceptance/sendRawTransaction.spec.ts @@ -28,6 +28,9 @@ import { numberTo0x } from '@hashgraph/json-rpc-relay/src/formatters'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import { ONE_TINYBAR_IN_WEI_HEX } from '@hashgraph/json-rpc-relay/tests/lib/eth/eth-config'; +import MirrorClient from '@hashgraph/json-rpc-server/tests/clients/mirrorClient'; +import RelayClient from '@hashgraph/json-rpc-server/tests/clients/relayClient'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; describe('@web-socket-batch-2 eth_sendRawTransaction', async function () { const METHOD_NAME = 'eth_sendRawTransaction'; @@ -47,16 +50,17 @@ describe('@web-socket-batch-2 eth_sendRawTransaction', async function () { ]; // @ts-ignore - const { mirrorNode, relay } = global; + const { mirrorNode, relay }: { mirrorNode: MirrorClient; relay: RelayClient } = global; const initialBalance = '5000000000'; // 50hbar + const requestId = 'sendRawTransactionTest_ws-server'; + const requestDetails = new RequestDetails({ requestId: requestId, ipAddress: '0.0.0.0' }); let tx: any, sendHbarToProxyContractDeployerTx: any, accounts: AliasAccount[] = [], ethersWsProvider: WebSocketProvider; - let requestId: string; + before(async () => { - requestId = Utils.generateRequestId(); const initialAccount: AliasAccount = global.accounts[0]; const neededAccounts: number = 3; @@ -66,7 +70,7 @@ describe('@web-socket-batch-2 eth_sendRawTransaction', async function () { initialAccount, neededAccounts, initialBalance, - requestId, + requestDetails, )), ); global.accounts.push(...accounts); @@ -76,7 +80,7 @@ describe('@web-socket-batch-2 eth_sendRawTransaction', async function () { gasLimit: numberTo0x(30000), chainId: Number(CHAIN_ID), to: accounts[2].address, - maxFeePerGas: await relay.gasPrice(), + maxFeePerGas: await relay.gasPrice(requestId), }; sendHbarToProxyContractDeployerTx = { @@ -110,15 +114,15 @@ describe('@web-socket-batch-2 eth_sendRawTransaction', async function () { } it(`@release Should execute eth_sendRawTransaction on Standard Web Socket and handle valid requests correctly`, async () => { - tx.nonce = await relay.getAccountNonce(accounts[0].address); + tx.nonce = await relay.getAccountNonce(accounts[0].address, requestId); const signedTx = await accounts[0].wallet.signTransaction(tx); const response = await WsTestHelper.sendRequestToStandardWebSocket(METHOD_NAME, [signedTx], 1000); WsTestHelper.assertJsonRpcObject(response); const txHash = response.result; - const txReceipt = await mirrorNode.get(`/contracts/results/${txHash}`); - const fromAccountInfo = await mirrorNode.get(`/accounts/${txReceipt.from}`); + const txReceipt = await mirrorNode.get(`/contracts/results/${txHash}`, requestDetails); + const fromAccountInfo = await mirrorNode.get(`/accounts/${txReceipt.from}`, requestDetails); expect(txReceipt.to).to.eq(accounts[2].address.toLowerCase()); expect(fromAccountInfo.evm_address).to.eq(accounts[0].address.toLowerCase()); @@ -178,13 +182,13 @@ describe('@web-socket-batch-2 eth_sendRawTransaction', async function () { } it(`@release Should execute eth_sendRawTransaction on Ethers Web Socket Provider and handle valid requests correctly`, async () => { - tx.nonce = await relay.getAccountNonce(accounts[1].address); + tx.nonce = await relay.getAccountNonce(accounts[1].address, requestId); const signedTx = await accounts[1].wallet.signTransaction(tx); // const signedTx = await accounts[0].wallet.signTransaction(tx); const txHash = await ethersWsProvider.send(METHOD_NAME, [signedTx]); - const txReceipt = await mirrorNode.get(`/contracts/results/${txHash}`); - const fromAccountInfo = await mirrorNode.get(`/accounts/${txReceipt.from}`); + const txReceipt = await mirrorNode.get(`/contracts/results/${txHash}`, requestDetails); + const fromAccountInfo = await mirrorNode.get(`/accounts/${txReceipt.from}`, requestDetails); expect(txReceipt.to).to.eq(accounts[2].address.toLowerCase()); expect(fromAccountInfo.evm_address).to.eq(accounts[1].address.toLowerCase()); From c8f042d83f7cf16796cd31a926318a4dbecf8cb3 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Tue, 17 Sep 2024 15:13:23 +0300 Subject: [PATCH 33/48] Adds better typing in accpetance tests as well as fixing them Signed-off-by: Konstantina Blazhukova --- .../server/tests/acceptance/erc20.spec.ts | 6 +- .../acceptance/estimateGasPrecompile.spec.ts | 11 +- .../tests/acceptance/hbarLimiter.spec.ts | 25 +- .../tests/acceptance/htsPrecompile_v1.spec.ts | 11 +- .../tests/acceptance/rateLimiter.spec.ts | 3 +- .../tests/acceptance/rpc_batch1.spec.ts | 352 +++++++++--------- .../tests/acceptance/rpc_batch2.spec.ts | 37 +- .../tests/acceptance/rpc_batch3.spec.ts | 28 +- packages/server/tests/helpers/utils.ts | 4 +- .../tests/acceptance/getStorageAt.spec.ts | 1 - .../acceptance/subscribeNewHeads.spec.ts | 5 +- 11 files changed, 279 insertions(+), 204 deletions(-) diff --git a/packages/server/tests/acceptance/erc20.spec.ts b/packages/server/tests/acceptance/erc20.spec.ts index be6a043b8c..cecf90580b 100644 --- a/packages/server/tests/acceptance/erc20.spec.ts +++ b/packages/server/tests/acceptance/erc20.spec.ts @@ -32,6 +32,8 @@ import { EthImpl } from '@hashgraph/json-rpc-relay/src/lib/eth'; // Constants from local resources import Constants from '../../../server/tests/helpers/constants'; +import ServicesClient from '../clients/servicesClient'; +import RelayClient from '../clients/relayClient'; chai.use(solidity); @@ -42,7 +44,9 @@ const extractRevertReason = (errorReason: string) => { describe('@erc20 Acceptance Tests', async function () { this.timeout(240 * 1000); // 240 seconds - const { servicesNode, relay }: any = global; + + // @ts-ignore + const { servicesNode, relay }: { servicesNode: ServicesClient; relay: RelayClient } = global; // cached entities const accounts: AliasAccount[] = []; diff --git a/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts b/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts index 508bfc3007..494d2e6be4 100644 --- a/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts +++ b/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts @@ -37,6 +37,9 @@ import RelayCalls from '../../../../packages/server/tests/helpers/constants'; // Other imports import { numberTo0x } from '../../../../packages/relay/src/formatters'; +import RelayClient from '../clients/relayClient'; +import ServicesClient from '../clients/servicesClient'; +import MirrorClient from '../clients/mirrorClient'; describe('EstimatePrecompileContract tests', function () { const signers: AliasAccount[] = []; @@ -72,7 +75,13 @@ describe('EstimatePrecompileContract tests', function () { const usdFee1 = 1; const usdFee2 = 2; const accounts: AliasAccount[] = []; - const { servicesNode, mirrorNode, relay }: any = global; + + // @ts-ignore + const { + servicesNode, + mirrorNode, + relay, + }: { servicesNode: ServicesClient; mirrorNode: MirrorClient; relay: RelayClient } = global; async function createFungibleToken() { estimateContract = new ethers.Contract( diff --git a/packages/server/tests/acceptance/hbarLimiter.spec.ts b/packages/server/tests/acceptance/hbarLimiter.spec.ts index 63512117e8..d36276ea55 100644 --- a/packages/server/tests/acceptance/hbarLimiter.spec.ts +++ b/packages/server/tests/acceptance/hbarLimiter.spec.ts @@ -39,14 +39,25 @@ import mediumSizeContract from '../contracts/hbarLimiterContracts/mediumSizeCont import { resolve } from 'path'; import { config } from 'dotenv'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; +import MirrorClient from '../clients/mirrorClient'; +import RelayClient from '../clients/relayClient'; config({ path: resolve(__dirname, '../localAcceptance.env') }); describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { // @ts-ignore - const { mirrorNode, relay, logger, initialBalance, metrics, relayIsLocal } = global; + const { + mirrorNode, + relay, + logger, + initialBalance, + metrics, + relayIsLocal, + }: { mirrorNode: MirrorClient; relay: RelayClient } = global; const operatorAccount = process.env.OPERATOR_ID_MAIN; const fileAppendChunkSize = Number(process.env.FILE_APPEND_CHUNK_SIZE) || 5120; + const requestId = 'hbarLimiterTest'; + const requestDetails = new RequestDetails({ requestId: requestId, ipAddress: '0.0.0.0' }); // The following tests exhaust the hbar limit, so they should only be run against a local relay if (relayIsLocal) { @@ -152,8 +163,6 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { type: 2, }; - const requestDetails = new RequestDetails({ requestId: 'hbarLimiterTest', ipAddress: '0.0.0.0' }); - before(async function () { // Restart the relay to reset the limits await global.restartLocalRelay(); @@ -194,20 +203,20 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { `${requestDetails.formattedRequestId} Deploy parent contract on address ${parentContractAddress}`, ); - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const remainingHbarsBefore = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[1].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[1].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; const signedTx = await accounts[1].wallet.signTransaction(transaction); - await expect(relay.call(testConstants.ETH_ENDPOINTS.ETH_SEND_RAW_TRANSACTION, [signedTx], requestDetails)).to - .be.fulfilled; + await expect(relay.call(testConstants.ETH_ENDPOINTS.ETH_SEND_RAW_TRANSACTION, [signedTx], requestId)).to.be + .fulfilled; const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); const expectedCost = await getExpectedCostOfLastSmallTx(requestDetails); @@ -341,7 +350,7 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { process.env.HBAR_RATE_LIMIT_PREEMPTIVE_CHECK = 'false'; const remainingHbarsBefore = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); - let lastRemainingHbars = remainingHbarsBefore; + const lastRemainingHbars = remainingHbarsBefore; expect(remainingHbarsBefore).to.be.gt(0); try { for (let i = 0; i < 50; i++) { diff --git a/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts b/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts index d5676af6d7..bbb33aab48 100644 --- a/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts +++ b/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts @@ -30,12 +30,21 @@ import { AliasAccount } from '../types/AliasAccount'; import { ethers } from 'ethers'; import BaseHTSJson from '../contracts/contracts_v1/BaseHTS.json'; import { Utils } from '../helpers/utils'; +import ServicesClient from '../clients/servicesClient'; +import RelayClient from '../clients/relayClient'; +import MirrorClient from '../clients/mirrorClient'; chai.use(solidity); describe('@htsprecompilev1 HTS Precompile V1 Acceptance Tests', async function () { this.timeout(240 * 1000); // 240 seconds - const { servicesNode, relay, mirrorNode }: any = global; + + // @ts-ignore + const { + servicesNode, + relay, + mirrorNode, + }: { servicesNode: ServicesClient; relay: RelayClient; mirrorNode: MirrorClient } = global; const TX_SUCCESS_CODE = BigInt(22); diff --git a/packages/server/tests/acceptance/rateLimiter.spec.ts b/packages/server/tests/acceptance/rateLimiter.spec.ts index 62ff5521d0..a6ed98df71 100644 --- a/packages/server/tests/acceptance/rateLimiter.spec.ts +++ b/packages/server/tests/acceptance/rateLimiter.spec.ts @@ -22,12 +22,13 @@ import Assertions from '../helpers/assertions'; import testConstants from '../../tests/helpers/constants'; import relayConstants from '../../../../packages/relay/src/lib/constants'; +import RelayClient from '../clients/relayClient'; describe('@ratelimiter Rate Limiters Acceptance Tests', function () { this.timeout(480 * 1000); // 480 seconds // @ts-ignore - const { relay } = global; + const { relay }: { relay: RelayClient } = global; // cached entities let requestId: string; diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 6112b69b69..70ce240c89 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -42,6 +42,9 @@ import RelayCalls from '../../tests/helpers/constants'; import { numberTo0x, prepend0x } from '../../../../packages/relay/src/formatters'; import constants from '../../../relay/src/lib/constants'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; +import RelayClient from '../clients/relayClient'; +import ServicesClient from '../clients/servicesClient'; +import MirrorClient from '../clients/mirrorClient'; const Address = RelayCalls; @@ -51,7 +54,12 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const accounts: AliasAccount[] = []; // @ts-ignore - const { servicesNode, mirrorNode, relay, initialBalance } = global; + const { + servicesNode, + mirrorNode, + relay, + initialBalance, + }: { servicesNode: ServicesClient; mirrorNode: MirrorClient; relay: RelayClient } = global; // cached entities let parentContractAddress: string; @@ -59,6 +67,8 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { let account2Address: string; let expectedGasPrice: string; + const requestId = 'rpc_batch1Test'; + const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const requestDetails = new RequestDetails({ requestId: 'rpc_batch1Test', ipAddress: '0.0.0.0' }); const CHAIN_ID = process.env.CHAIN_ID || '0x12a'; const INCORRECT_CHAIN_ID = 999; @@ -85,7 +95,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds this.beforeAll(async () => { - expectedGasPrice = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GAS_PRICE, [], requestDetails); + expectedGasPrice = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GAS_PRICE, [], requestIdPrefix); const initialAccount: AliasAccount = global.accounts[0]; const neededAccounts: number = 3; @@ -145,7 +155,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { contractAddress = logsContract.target.toString(); contractAddress2 = logsContract2.target.toString(); - previousBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); + previousBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestIdPrefix)); // @ts-ignore await (await logsContract.connect(accounts[1].wallet).log0(1)).wait(); @@ -160,7 +170,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // @ts-ignore await (await logsContract2.connect(accounts[1].wallet).log4(1, 1, 1, 1)).wait(); - latestBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); + latestBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestIdPrefix)); }); it('@release should deploy a contract', async () => { @@ -173,7 +183,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); @@ -193,7 +203,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { log0Block = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [logs[0].transactionHash], - requestDetails, + requestIdPrefix, ); const transactionCountLog0Block = await relay.provider.getTransactionCount( log0Block.from, @@ -203,7 +213,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { log4Block = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [logs[logs.length - 1].transactionHash], - requestDetails, + requestIdPrefix, ); const transactionCountLog4Block = await relay.provider.getTransactionCount( log4Block.from, @@ -232,7 +242,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); @@ -251,7 +261,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }, ], predefined.MISSING_FROM_BLOCK_PARAM, - requestDetails, + requestIdPrefix, ); }); @@ -265,7 +275,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); @@ -287,7 +297,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: contractAddress, }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); @@ -309,7 +319,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: contractAddress, }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); @@ -330,7 +340,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2, Address.NON_EXISTING_ADDRESS], }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); expect(logs.length).to.be.eq(6); @@ -351,7 +361,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(0); @@ -369,20 +379,24 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestDetails, + requestIdPrefix, ); expect(logs).to.exist; expect(logs.length).to.be.eq(0); }); it('should be able to use `topics` param', async () => { - const logs = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_LOGS, [ - { - fromBlock: log0Block.blockNumber, - toBlock: log4Block.blockNumber, - address: [contractAddress, contractAddress2], - }, - ]); + const logs = await relay.call( + RelayCalls.ETH_ENDPOINTS.ETH_GET_LOGS, + [ + { + fromBlock: log0Block.blockNumber, + toBlock: log4Block.blockNumber, + address: [contractAddress, contractAddress2], + }, + ], + requestIdPrefix, + ); expect(logs.length).to.be.greaterThan(0); //using second log in array, because the first doesn't contain any topics const topic = logs[1].topics[0]; @@ -396,7 +410,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { topics: [topic], }, ], - requestDetails, + requestIdPrefix, ); expect(logsWithTopic.length).to.be.greaterThan(0); @@ -412,7 +426,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { process.env['MIRROR_NODE_LIMIT_PARAM'] = '2'; // calculate blocks behind latest, so we can fetch logs from the past. // if current block is less than 10, we will fetch logs from the beginning otherwise we will fetch logs from 10 blocks behind latest - const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); + const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestIdPrefix)); let blocksBehindLatest = 0; if (currentBlock > 10) { blocksBehindLatest = currentBlock - 10; @@ -426,7 +440,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [contractAddress, contractAddress2], }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.be.greaterThan(2); }); @@ -441,13 +455,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: ethers.ZeroAddress, }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.eq(0); }); it('should return only logs of non-zero addresses', async () => { - const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails)); + const currentBlock = Number(await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestIdPrefix)); let blocksBehindLatest = 0; if (currentBlock > 10) { blocksBehindLatest = currentBlock - 10; @@ -461,7 +475,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { address: [ethers.ZeroAddress, contractAddress2], }, ], - requestDetails, + requestIdPrefix, ); expect(logs.length).to.eq(1); }); @@ -498,7 +512,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [mirrorBlock.hash.substring(0, 66), false], - requestDetails, + requestIdPrefix, ); Assertions.block(blockResult, mirrorBlock, mirrorTransactions, expectedGasPrice, false); }); @@ -507,7 +521,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [mirrorBlock.hash.substring(0, 66), true], - requestDetails, + requestIdPrefix, ); // Remove synthetic transactions blockResult.transactions = blockResult.transactions.filter((transaction) => transaction.value !== '0x1234'); @@ -518,7 +532,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [Address.NON_EXISTING_BLOCK_HASH, false], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.be.null; }); @@ -527,7 +541,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_HASH, [Address.NON_EXISTING_BLOCK_HASH, true], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.be.null; }); @@ -536,7 +550,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [numberTo0x(mirrorBlock.number), false], - requestDetails, + requestIdPrefix, ); // Remove synthetic transactions blockResult.transactions = blockResult.transactions.filter((transaction) => transaction.value !== '0x1234'); @@ -547,14 +561,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['latest', false], - requestDetails, + requestIdPrefix, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['latest', false], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -563,14 +577,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['finalized', false], - requestDetails, + requestIdPrefix, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['finalized', false], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -579,14 +593,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['safe', false], - requestDetails, + requestIdPrefix, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['safe', false], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -595,14 +609,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['pending', false], - requestDetails, + requestIdPrefix, ); await Utils.wait(1000); const blockResult2 = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, ['pending', false], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.not.deep.equal(blockResult2); }); @@ -611,7 +625,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [numberTo0x(mirrorBlock.number), true], - requestDetails, + requestIdPrefix, ); // Remove synthetic transactions blockResult.transactions = blockResult.transactions.filter((transaction) => transaction.value !== '0x1234'); @@ -622,7 +636,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [Address.NON_EXISTING_BLOCK_NUMBER, true], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.be.null; }); @@ -631,7 +645,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const blockResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [Address.NON_EXISTING_BLOCK_NUMBER, false], - requestDetails, + requestIdPrefix, ); expect(blockResult).to.be.null; }); @@ -640,7 +654,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER, [numberTo0x(mirrorBlock.number)], - requestDetails, + requestIdPrefix, ); expect(res).to.be.equal(ethers.toQuantity(mirrorBlock.count)); }); @@ -649,7 +663,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER, [Address.NON_EXISTING_BLOCK_NUMBER], - requestDetails, + requestIdPrefix, ); expect(res).to.be.null; }); @@ -658,7 +672,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_HASH, [mirrorBlock.hash.substring(0, 66)], - requestDetails, + requestIdPrefix, ); expect(res).to.be.equal(ethers.toQuantity(mirrorBlock.count)); }); @@ -667,7 +681,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_TRANSACTION_COUNT_BY_HASH, [Address.NON_EXISTING_BLOCK_HASH], - requestDetails, + requestIdPrefix, ); expect(res).to.be.null; }); @@ -679,7 +693,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { expect(mirrorBlocks.blocks.length).to.gt(0); const mirrorBlockNumber = mirrorBlocks.blocks[0].number; - const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestDetails); + const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_BLOCK_NUMBER, [], requestIdPrefix); const blockNumber = Number(res); expect(blockNumber).to.exist; @@ -727,7 +741,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, [mirrorContractDetails.block_hash.substring(0, 66), numberTo0x(mirrorContractDetails.transaction_index)], - requestDetails, + requestIdPrefix, ); Assertions.transaction(response, mirrorContractDetails); }); @@ -736,7 +750,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, [Address.NON_EXISTING_BLOCK_HASH, numberTo0x(mirrorContractDetails.transaction_index)], - requestDetails, + requestIdPrefix, ); expect(response).to.be.null; }); @@ -745,7 +759,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, [mirrorContractDetails.block_hash.substring(0, 66), Address.NON_EXISTING_INDEX], - requestDetails, + requestIdPrefix, ); expect(response).to.be.null; }); @@ -754,7 +768,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_NUMBER_AND_INDEX, [numberTo0x(mirrorContractDetails.block_number), numberTo0x(mirrorContractDetails.transaction_index)], - requestDetails, + requestIdPrefix, ); Assertions.transaction(response, mirrorContractDetails); }); @@ -763,7 +777,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_NUMBER_AND_INDEX, [numberTo0x(mirrorContractDetails.block_number), Address.NON_EXISTING_INDEX], - requestDetails, + requestIdPrefix, ); expect(response).to.be.null; }); @@ -772,7 +786,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const response = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_BLOCK_NUMBER_AND_INDEX, [Address.NON_EXISTING_BLOCK_NUMBER, numberTo0x(mirrorContractDetails.transaction_index)], - requestDetails, + requestIdPrefix, ); expect(response).to.be.null; }); @@ -781,13 +795,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), + gasPrice: await relay.gasPrice(requestId), type: 0, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const legacyTxHash = await relay.sendRawTransaction(signedTx, requestDetails); + const legacyTxHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry const mirrorResult = await mirrorNode.get(`/contracts/results/${legacyTxHash}`, requestDetails); @@ -797,9 +811,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [legacyTxHash], - requestDetails, + requestIdPrefix, ); - const currentPrice = await relay.gasPrice(requestDetails); + const currentPrice = await relay.gasPrice(requestId); Assertions.transactionReceipt(res, mirrorResult, currentPrice); }); @@ -809,13 +823,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxFeePerGas: gasPrice, maxPriorityFeePerGas: gasPrice, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); @@ -825,9 +839,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestDetails, + requestIdPrefix, ); - const currentPrice = await relay.gasPrice(requestDetails); + const currentPrice = await relay.gasPrice(requestId); Assertions.transactionReceipt(res, mirrorResult, currentPrice); }); @@ -836,12 +850,12 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLegacy2930TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); @@ -851,19 +865,19 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestDetails, + requestIdPrefix, ); - const currentPrice = await relay.gasPrice(requestDetails); + const currentPrice = await relay.gasPrice(requestId); Assertions.transactionReceipt(res, mirrorResult, currentPrice); }); it('@release should fail to execute "eth_getTransactionReceipt" for hash of London transaction', async function () { - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxFeePerGas: gasPrice, maxPriorityFeePerGas: gasPrice, }; @@ -878,9 +892,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release should return the right "effectiveGasPrice" for SYNTHETIC HTS transaction', async function () { - const tokenId = await servicesNode.createToken(1000, requestDetails); - await accounts[2].client.associateToken(tokenId, requestDetails); - const currentPrice = await relay.gasPrice(requestDetails); + const tokenId = await servicesNode.createToken(1000, requestId); + await accounts[2].client.associateToken(tokenId, requestId); + const currentPrice = await relay.gasPrice(requestId); const transaction = new TransferTransaction() .addTokenTransfer(tokenId, servicesNode._thisAccountId(), -10) .addTokenTransfer(tokenId, accounts[2].accountId, 10) @@ -901,12 +915,12 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [formattedBlockNumber, true], - requestDetails, + requestIdPrefix, ); const receiptFromRelay = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestDetails, + requestIdPrefix, ); // handle deviation in gas price @@ -915,7 +929,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release should return the right "effectiveGasPrice" for SYNTHETIC Contract Call transaction', async function () { - const currentPrice = await relay.gasPrice(requestDetails); + const currentPrice = await relay.gasPrice(requestId); const transactionHash = mirrorContractDetails.hash; const formattedBlockNumber = prepend0x(mirrorContractDetails.block_number.toString(16)); @@ -923,12 +937,12 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_BLOCK_BY_NUMBER, [formattedBlockNumber, true], - requestDetails, + requestIdPrefix, ); const receiptFromRelay = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [transactionHash], - requestDetails, + requestIdPrefix, ); // handle deviation in gas price @@ -940,7 +954,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [Address.NON_EXISTING_TX_HASH], - requestDetails, + requestIdPrefix, ); expect(res).to.be.null; }); @@ -949,7 +963,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), chainId: INCORRECT_CHAIN_ID, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); @@ -964,11 +978,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLegacyTransactionData, value: (10 * ONE_TINYBAR * 10 ** 8).toString(), // 10hbar - the gasPrice to deploy the deterministic proxy contract to: constants.DETERMINISTIC_DEPLOYMENT_SIGNER, - nonce: await relay.getAccountNonce(accounts[0].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[0].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedSendHbarTx = await accounts[0].wallet.signTransaction(sendHbarTx); - await relay.sendRawTransaction(signedSendHbarTx, requestDetails); + await relay.sendRawTransaction(signedSendHbarTx, requestId); await Utils.wait(5000); // wait for signer's account to propagate accross the network const deployerBalance = await global.relay.getBalance(constants.DETERMINISTIC_DEPLOYMENT_SIGNER, 'latest'); expect(deployerBalance).to.not.eq(0); @@ -977,20 +991,20 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // by the DETERMINISTIC_DEPLOYMENT_SIGNER with tx.nonce = 0. With that reason, if the current nonce of the signer // is not 0, it means the DETERMINISTIC_DEPLOYER_TRANSACTION has already been submitted, and the DETERMINISTIC_PROXY_CONTRACT // has already been deployed to the network. Therefore, it only matters to test this flow once. - const signerNonce = await relay.getAccountNonce(constants.DETERMINISTIC_DEPLOYMENT_SIGNER, requestDetails); + const signerNonce = await relay.getAccountNonce(constants.DETERMINISTIC_DEPLOYMENT_SIGNER, requestId); if (signerNonce === 0) { const deployerBalance = await relay.getBalance( constants.DETERMINISTIC_DEPLOYMENT_SIGNER, 'latest', - requestDetails, + requestId, ); expect(deployerBalance).to.not.eq(0); // send transaction to deploy proxy transaction const deterministicDeployTransactionHash = await relay.sendRawTransaction( constants.DETERMINISTIC_DEPLOYER_TRANSACTION, - requestDetails, + requestId, ); const receipt = await mirrorNode.get( @@ -1006,7 +1020,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { expect(receipt.address).to.eq(constants.DETERMINISTIC_PROXY_CONTRACT); } else { try { - await relay.sendRawTransaction(constants.DETERMINISTIC_DEPLOYER_TRANSACTION, requestDetails); + await relay.sendRawTransaction(constants.DETERMINISTIC_DEPLOYER_TRANSACTION, requestId); expect(true).to.be.false; } catch (error: any) { const expectedNonceTooLowError = predefined.NONCE_TOO_LOW(0, signerNonce); @@ -1022,29 +1036,29 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); - const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); + const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); const balanceChange = receiverEndBalance - receiverInitialBalance; expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString()); }); it('should fail "eth_sendRawTransaction" for legacy EIP 155 transactions (with insufficient balance)', async function () { - const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestDetails); + const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestId); const transaction = { ...default155TransactionData, to: parentContractAddress, value: balanceInWeiBars, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.INSUFFICIENT_ACCOUNT_BALANCE; @@ -1053,21 +1067,21 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" for legacy transactions (with no chainId i.e. chainId=0x0)', async function () { - const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); + const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); const transaction = { ...defaultLegacyTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); - const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); + const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); const balanceChange = receiverEndBalance - receiverInitialBalance; expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString()); }); @@ -1076,16 +1090,16 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLegacyTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[1].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[1].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[1].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const transactionResult = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [transactionHash], - requestDetails, + requestIdPrefix, ); const result = Object.prototype.hasOwnProperty.call(transactionResult, 'chainId'); @@ -1098,7 +1112,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { chainId: Number(CHAIN_ID), gasPrice: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); @@ -1110,11 +1124,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLegacy2930TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.exist; expect(info.result).to.equal('SUCCESS'); @@ -1125,7 +1139,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLegacy2930TransactionData, gasPrice: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); @@ -1134,13 +1148,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should fail "eth_sendRawTransaction" for Legacy 2930 transactions (with insufficient balance)', async function () { - const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestDetails); + const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestId); const transaction = { ...defaultLegacy2930TransactionData, value: balanceInWeiBars, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), - gasPrice: await relay.gasPrice(requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.INSUFFICIENT_ACCOUNT_BALANCE; @@ -1154,7 +1168,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { maxPriorityFeePerGas: GAS_PRICE_TOO_LOW, maxFeePerGas: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); @@ -1163,14 +1177,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should fail "eth_sendRawTransaction" for London transactions (with insufficient balance)', async function () { - const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestDetails); - const gasPrice = await relay.gasPrice(requestDetails); + const balanceInWeiBars = await relay.getBalance(account2Address, 'latest', requestId); + const gasPrice = await relay.gasPrice(requestId); const transaction = { ...defaultLondonTransactionData, value: balanceInWeiBars, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; @@ -1181,35 +1195,35 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" for London transactions', async function () { - const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); - const gasPrice = await relay.gasPrice(requestDetails); + const receiverInitialBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); + const gasPrice = await relay.gasPrice(requestId); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); - const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestDetails); + const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); const balanceChange = receiverEndBalance - receiverInitialBalance; expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString()); }); it('should execute "eth_sendRawTransaction" and deploy a large contract', async function () { - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, @@ -1217,7 +1231,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; @@ -1229,7 +1243,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // if calldata's size fails into the range of [2568 bytes, 5217 bytes], the request fails and throw // `Null Entity ID` error. This unit test makes sure that with the new fix, requests should work with all case scenarios. it('should execute "eth_sendRawTransaction" and deploy a contract with any arbitrary calldata size', async () => { - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const randomBytes = [2566, 2568, 3600, 5217, 7200]; @@ -1237,14 +1251,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[0].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[0].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, data: '0x' + '00'.repeat(bytes), }; const signedTx = await accounts[0].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; @@ -1255,11 +1269,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should delete the file created while execute "eth_sendRawTransaction" to deploy a large contract', async function () { - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, @@ -1267,7 +1281,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); await Utils.wait(1000); const txInfo = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); @@ -1281,11 +1295,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" and fail when deploying too large contract', async function () { - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[1].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[1].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: defaultGasLimit, @@ -1304,11 +1318,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLegacy2930TransactionData, value: 0, data: basicContract.bytecode, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; @@ -1325,11 +1339,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...defaultLondonTransactionData, value: 0, data: basicContract.bytecode, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; @@ -1343,13 +1357,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" and deploy a contract with more than 2 HBAR transaction fee and less than max transaction fee', async function () { - const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestDetails); + const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId); - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: Constants.MAX_GAS_PER_SEC, @@ -1357,9 +1371,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); - const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestDetails); + const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1373,11 +1387,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('should execute "eth_sendRawTransaction" and deploy a contract with more than max transaction fee', async function () { - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const transaction = { type: 2, chainId: Number(CHAIN_ID), - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, gasLimit: Constants.MAX_GAS_PER_SEC, @@ -1394,7 +1408,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), chainId: INCORRECT_CHAIN_ID, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); @@ -1408,9 +1422,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), gasLimit: gasLimit, - gasPrice: await relay.gasPrice(requestDetails), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); @@ -1427,9 +1441,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...default155TransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), gasLimit: gasLimit, - gasPrice: await relay.gasPrice(requestDetails), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); @@ -1446,7 +1460,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), gasLimit: gasLimit, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); @@ -1463,7 +1477,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), gasLimit: gasLimit, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); @@ -1480,7 +1494,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { ...default155TransactionData, gasPrice: GAS_PRICE_TOO_LOW, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const error = predefined.GAS_PRICE_TOO_LOW(GAS_PRICE_TOO_LOW, GAS_PRICE_REF); @@ -1492,22 +1506,26 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release fail "eth_getTransactionReceipt" on precheck with wrong nonce error when sending a tx with the same nonce twice', async function () { - const nonce = await relay.getAccountNonce(accounts[2].address, requestDetails); + const nonce = await relay.getAccountNonce(accounts[2].address, requestId); const transaction = { ...default155TransactionData, to: parentContractAddress, nonce: nonce, - maxFeePerGas: await relay.gasPrice(requestDetails), + maxFeePerGas: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const txHash1 = await relay.sendRawTransaction(signedTx, requestDetails); + const txHash1 = await relay.sendRawTransaction(signedTx, requestId); const mirrorResult = await mirrorNode.get(`/contracts/results/${txHash1}`, requestDetails); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; - const res = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [txHash1], requestDetails); - const currentPrice = await relay.gasPrice(requestDetails); + const res = await relay.call( + RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, + [txHash1], + requestIdPrefix, + ); + const currentPrice = await relay.gasPrice(requestId); Assertions.transactionReceipt(res, mirrorResult, currentPrice); const error = predefined.NONCE_TOO_LOW(nonce, nonce + 1); @@ -1515,13 +1533,13 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release fail "eth_getTransactionReceipt" on precheck with wrong nonce error when sending a tx with a higher nonce', async function () { - const nonce = await relay.getAccountNonce(accounts[2].address, requestDetails); + const nonce = await relay.getAccountNonce(accounts[2].address, requestId); const transaction = { ...default155TransactionData, to: parentContractAddress, nonce: nonce + 100, - gasPrice: await relay.gasPrice(requestDetails), + gasPrice: await relay.gasPrice(requestId), }; const signedTx = await accounts[2].wallet.signTransaction(transaction); @@ -1531,21 +1549,21 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release fail "eth_getTransactionReceipt" on submitting with wrong nonce error when sending a tx with the same nonce twice', async function () { - const nonce = await relay.getAccountNonce(accounts[2].address, requestDetails); + const nonce = await relay.getAccountNonce(accounts[2].address, requestId); const transaction1 = { ...default155TransactionData, to: parentContractAddress, nonce: nonce, - maxFeePerGas: await relay.gasPrice(requestDetails), + maxFeePerGas: await relay.gasPrice(requestId), }; const signedTx1 = await accounts[2].wallet.signTransaction(transaction1); await Promise.all([ Promise.allSettled([ - relay.sendRawTransaction(signedTx1, requestDetails), - relay.sendRawTransaction(signedTx1, requestDetails), + relay.sendRawTransaction(signedTx1, requestId), + relay.sendRawTransaction(signedTx1, requestId), ]).then((values) => { const fulfilled = values.find((obj) => obj.status === 'fulfilled'); const rejected = values.find((obj) => obj.status === 'rejected'); @@ -1566,22 +1584,22 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }); it('@release should execute "eth_getTransactionByHash" for existing transaction', async function () { - const gasPrice = await relay.gasPrice(requestDetails); + const gasPrice = await relay.gasPrice(requestId); const transaction = { ...defaultLondonTransactionData, to: parentContractAddress, - nonce: await relay.getAccountNonce(accounts[2].address, requestDetails), + nonce: await relay.getAccountNonce(accounts[2].address, requestId), maxPriorityFeePerGas: gasPrice, maxFeePerGas: gasPrice, }; const signedTx = await accounts[2].wallet.signTransaction(transaction); - const transactionHash = await relay.sendRawTransaction(signedTx, requestDetails); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); const mirrorTransaction = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [transactionHash], - requestDetails, + requestIdPrefix, ); const addressResult = await mirrorNode.get(`/accounts/${res.from}`, requestDetails); mirrorTransaction.from = addressResult.evm_address; @@ -1593,7 +1611,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [Address.NON_EXISTING_TX_HASH], - requestDetails, + requestIdPrefix, ); expect(res).to.be.null; }); diff --git a/packages/server/tests/acceptance/rpc_batch2.spec.ts b/packages/server/tests/acceptance/rpc_batch2.spec.ts index c848789fc6..789873231d 100644 --- a/packages/server/tests/acceptance/rpc_batch2.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch2.spec.ts @@ -43,6 +43,9 @@ import RelayCalls from '../../tests/helpers/constants'; import Helper from '../../tests/helpers/constants'; import Address from '../../tests/helpers/constants'; import constants from '../../tests/helpers/constants'; +import RelayClient from '../clients/relayClient'; +import ServicesClient from '../clients/servicesClient'; +import MirrorClient from '../clients/mirrorClient'; describe('@api-batch-2 RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds @@ -50,7 +53,13 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { const accounts: AliasAccount[] = []; // @ts-ignore - const { servicesNode, mirrorNode, relay, logger, initialBalance } = global; + const { + servicesNode, + mirrorNode, + relay, + logger, + initialBalance, + }: { servicesNode: ServicesClient; mirrorNode: MirrorClient; relay: RelayClient } = global; // cached entities let tokenId; @@ -84,7 +93,11 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { const signedTx = await accounts.wallet.signTransaction(transaction); const txHash = await relay.sendRawTransaction(signedTx, requestId); await mirrorNode.get(`/contracts/results/${txHash}`, requestId); - await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [txHash]); + await relay.call( + RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, + [txHash], + Utils.formatRequestIdMessage(requestId), + ); await new Promise((r) => setTimeout(r, 2000)); }; @@ -546,7 +559,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { requestId, ); const acc3Nonce = await relay.getAccountNonce(accounts[3].address); - const gasPrice = await relay.gasPrice(); + const gasPrice = await relay.gasPrice(requestId); const transaction = { value: ONE_TINYBAR, @@ -831,7 +844,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { ); expect(beginStorageVal).to.eq(BEGIN_EXPECTED_STORAGE_VAL); - const gasPrice = await relay.gasPrice(); + const gasPrice = await relay.gasPrice(requestId); const transaction = { value: 0, gasLimit: 50000, @@ -925,7 +938,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { ); expect(beginStorageVal).to.eq(BEGIN_EXPECTED_STORAGE_VAL); - const gasPrice = await relay.gasPrice(); + const gasPrice = await relay.gasPrice(requestId); const transaction = { value: 0, gasLimit: 50000, @@ -956,7 +969,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { it('should execute "eth_getStorageAt" request to get current state changes with passing specific block', async function () { const EXPECTED_STORAGE_VAL = '0x0000000000000000000000000000000000000000000000000000000000000008'; - const gasPrice = await relay.gasPrice(); + const gasPrice = await relay.gasPrice(requestId); const transaction = { value: 0, gasLimit: 50000, @@ -1002,7 +1015,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { it('should execute "eth_getStorageAt" request to get current state changes with passing specific block hash', async function () { const EXPECTED_STORAGE_VAL = '0x0000000000000000000000000000000000000000000000000000000000000008'; - const gasPrice = await relay.gasPrice(); + const gasPrice = await relay.gasPrice(requestId); const transaction = { value: 0, gasLimit: 50000, @@ -1157,7 +1170,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { const getTxData = async (hash) => { const txByHash = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [hash], requestId); const receipt = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, [hash], requestId); - let mirrorResult = await mirrorNode.get(`/contracts/results/${hash}`, requestId); + const mirrorResult = await mirrorNode.get(`/contracts/results/${hash}`, requestId); return { txByHash, receipt, mirrorResult }; }; @@ -1170,7 +1183,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { await tx.wait(); - let { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); + const { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); mirrorResult.from = accounts[0].wallet.address; mirrorResult.to = accounts[1].wallet.address; @@ -1195,7 +1208,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { await tx.wait(); - let { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); + const { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); mirrorResult.from = accounts[0].wallet.address; mirrorResult.to = relayContract.target; @@ -1219,7 +1232,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { await tx.wait(); - let { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); + const { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); mirrorResult.from = accounts[0].wallet.address; mirrorResult.to = parentContractLongZeroAddress; @@ -1240,7 +1253,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { await tx.wait(); - let { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); + const { txByHash, receipt, mirrorResult } = await getTxData(tx.hash); mirrorResult.from = accounts[0].wallet.address; diff --git a/packages/server/tests/acceptance/rpc_batch3.spec.ts b/packages/server/tests/acceptance/rpc_batch3.spec.ts index 9fe325286d..a0577fd5f6 100644 --- a/packages/server/tests/acceptance/rpc_batch3.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch3.spec.ts @@ -53,6 +53,10 @@ import { EthImpl } from '@hashgraph/json-rpc-relay/src/lib/eth'; import { predefined } from '@hashgraph/json-rpc-relay'; import { TYPES } from '../../src/validator'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; +import RelayClient from '../clients/relayClient'; +import ServicesClient from '../clients/servicesClient'; +import MirrorClient from '../clients/mirrorClient'; +import { request } from 'http'; chai.use(chaiExclude); @@ -63,7 +67,11 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const requestDetails = new RequestDetails({ requestId: 'rpc_batch1Test', ipAddress: '0.0.0.0' }); // @ts-ignore - const { servicesNode, mirrorNode, relay } = global; + const { + servicesNode, + mirrorNode, + relay, + }: { servicesNode: ServicesClient; mirrorNode: MirrorClient; relay: RelayClient } = global; let mirrorPrimaryAccount: ethers.Wallet; let mirrorSecondaryAccount: ethers.Wallet; @@ -276,7 +284,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { // get block hash before deployment const blockNumber = deploymentBlockNumber - 1; - const nextBlockHash = (await mirrorNode.get(`/blocks/${blockNumber}`, requestId)).hash; + const nextBlockHash = (await mirrorNode.get(`/blocks/${blockNumber}`, requestDetails)).hash; const truncatedHash = nextBlockHash.slice(0, 66); const res = await relay.call( @@ -404,7 +412,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { callerContractJson.bytecode, activeAccount.wallet, ); - const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestId); + const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestDetails); const callerContractId = ContractId.fromString(callerMirror.contract_id); callerAddress = `0x${callerContractId.toSolidityAddress()}`; @@ -428,7 +436,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { relay, )) as ethers.Contract; // Wait for creation to propagate - const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestId); + const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestDetails); callerAddress = callerMirror.evm_address; defaultCallData = { from: activeAccount.address, @@ -586,7 +594,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const activeAccount = accounts[1]; const callerContract = await Utils.deployContractWithEthers([], callerContractJson, activeAccount.wallet, relay); // Wait for creation to propagate - const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestId); + const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestDetails); const callerAddress = callerMirror.evm_address; const defaultCallData = { from: activeAccount.address, @@ -677,7 +685,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Wait until receipt is available in mirror node - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); const receipt = await relay.call( RelayCall.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, @@ -866,7 +874,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { ); // get contract details - const mirrorContract = await mirrorNode.get(`/contracts/${deployerContractAddress}`, requestId); + const mirrorContract = await mirrorNode.get(`/contracts/${deployerContractAddress}`, requestDetails); contractId = ContractId.fromString(mirrorContract.contract_id); primaryAccountNonce = await relay.call( @@ -985,7 +993,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { [signedTxHollowAccountCreation], requestId, ); - await mirrorNode.get(`/contracts/results/${txHashHAC}`, requestId); + await mirrorNode.get(`/contracts/results/${txHashHAC}`, requestDetails); const signTxFromHollowAccount = await hollowAccount.signTransaction({ ...defaultTransaction, @@ -999,7 +1007,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { [signTxFromHollowAccount], requestId, ); - await mirrorNode.get(`/contracts/results/${txHashHA}`, requestId); + await mirrorNode.get(`/contracts/results/${txHashHA}`, requestDetails); const resAfterCreation = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_COUNT, @@ -1025,7 +1033,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_COUNT, diff --git a/packages/server/tests/helpers/utils.ts b/packages/server/tests/helpers/utils.ts index 7d744849d8..09ba5a98d7 100644 --- a/packages/server/tests/helpers/utils.ts +++ b/packages/server/tests/helpers/utils.ts @@ -35,6 +35,7 @@ import { GitHubClient } from '../clients/githubClient'; import MirrorClient from '../clients/mirrorClient'; import { HeapDifferenceStatistics } from '../types/HeapDifferenceStatistics'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; +import { Relay } from '@hashgraph/json-rpc-relay'; export class Utils { static readonly HEAP_SIZE_DIFF_MEMORY_LEAK_THRESHOLD: number = 1e6; // 1 MB @@ -180,9 +181,10 @@ export class Utils { }; static gasOptions = async (requestId, gasLimit = 1_500_000) => { + const relay: RelayClient = global.relay; return { gasLimit: gasLimit, - gasPrice: await global.relay.gasPrice(requestId), + gasPrice: await relay.gasPrice(requestId), }; }; diff --git a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts index d1aa2fb681..dddcb0255e 100644 --- a/packages/ws-server/tests/acceptance/getStorageAt.spec.ts +++ b/packages/ws-server/tests/acceptance/getStorageAt.spec.ts @@ -37,7 +37,6 @@ describe('@web-socket-batch-2 eth_getStorageAt', async function () { [WsTestConstant.FAKE_TX_HASH, ''], [WsTestConstant.FAKE_TX_HASH, 36, 'latest'], [WsTestConstant.FAKE_TX_HASH, '0xhbar', 'latest'], - [WsTestConstant.FAKE_TX_HASH, '0x0', 'latest'], ]; // @notice: The simple contract artifacts (ABI & bytecode) below simply has one state at position 0, which will be assigned to the number `7` within the consutrctor after deployment diff --git a/packages/ws-server/tests/acceptance/subscribeNewHeads.spec.ts b/packages/ws-server/tests/acceptance/subscribeNewHeads.spec.ts index 5fc05c2862..8f4db50ab0 100644 --- a/packages/ws-server/tests/acceptance/subscribeNewHeads.spec.ts +++ b/packages/ws-server/tests/acceptance/subscribeNewHeads.spec.ts @@ -27,6 +27,8 @@ import { predefined } from '@hashgraph/json-rpc-relay'; import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import Assertions from '@hashgraph/json-rpc-server/tests/helpers/assertions'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; +import MirrorClient from '@hashgraph/json-rpc-server/tests/clients/mirrorClient'; +import RelayClient from '@hashgraph/json-rpc-server/tests/clients/relayClient'; chai.use(solidity); const WS_RELAY_URL = `${process.env.WS_RELAY_URL}`; @@ -103,7 +105,8 @@ describe('@web-socket-batch-3 eth_subscribe newHeads', async function () { before(async () => { // @ts-ignore - const { socketServer, mirrorNode, relay } = global; + const { socketServer, mirrorNode, relay }: { socketServer: any; mirrorNode: MirrorClient; relay: RelayClient } = + global; mirrorNodeServer = mirrorNode; rpcServer = relay; wsServer = socketServer; From d2f99c7780990628b8f01ba5efc355181e73baaf Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Tue, 17 Sep 2024 16:52:17 +0300 Subject: [PATCH 34/48] temporary fix Signed-off-by: Konstantina Blazhukova --- packages/relay/src/lib/eth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 29da622916..43a6e21143 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -549,7 +549,7 @@ export class EthImpl implements Eth { * `CHAIN_ID`. */ chainId(requestDetails: RequestDetails): string { - this.logger.trace(`${requestDetails.formattedRequestId} chainId()`); + //this.logger.trace(`${requestDetails.formattedRequestId} chainId()`); return this.chain; } From e48d7ec205a6e29eeaf8f47409f5e7003a8c34c2 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Wed, 18 Sep 2024 13:21:02 +0300 Subject: [PATCH 35/48] fix: build error Signed-off-by: Victor Yanev --- .../repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts index f7df912ea5..b7716f58f9 100644 --- a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts +++ b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts @@ -33,6 +33,7 @@ import { IHbarSpendingRecord } from '../../../../src/lib/db/types/hbarLimiter/hb import { SubscriptionType } from '../../../../src/lib/db/types/hbarLimiter/subscriptionType'; import { IDetailedHbarSpendingPlan } from '../../../../src/lib/db/types/hbarLimiter/hbarSpendingPlan'; import { useInMemoryRedisServer } from '../../../helpers'; +import { RequestDetails } from '../../../../src/lib/types'; chai.use(chaiAsPromised); From ef6e2c07350db8c8beaee2342262d4fd6bb4d971 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Wed, 18 Sep 2024 15:26:10 +0300 Subject: [PATCH 36/48] fix: ws errors Signed-off-by: Victor Yanev --- packages/relay/tests/lib/sdkClient.spec.ts | 6 +- .../server/tests/acceptance/erc20.spec.ts | 8 +- .../acceptance/estimateGasContract.spec.ts | 2 +- .../acceptance/estimateGasPrecompile.spec.ts | 2 +- .../tests/acceptance/hbarLimiter.spec.ts | 27 +- .../htsPrecompile/precompileCalls.spec.ts | 4 +- .../tests/acceptance/htsPrecompile_v1.spec.ts | 25 +- .../server/tests/acceptance/index.spec.ts | 10 +- .../tests/acceptance/rpc_batch1.spec.ts | 75 +++--- .../tests/acceptance/rpc_batch2.spec.ts | 11 +- .../tests/acceptance/rpc_batch3.spec.ts | 28 +- .../tests/acceptance/serverConfig.spec.ts | 2 +- packages/server/tests/clients/mirrorClient.ts | 6 +- packages/server/tests/clients/relayClient.ts | 32 +-- .../server/tests/clients/servicesClient.ts | 248 ++++++++---------- packages/server/tests/helpers/utils.ts | 84 +++--- .../ws-server/tests/acceptance/index.spec.ts | 9 +- 17 files changed, 294 insertions(+), 285 deletions(-) diff --git a/packages/relay/tests/lib/sdkClient.spec.ts b/packages/relay/tests/lib/sdkClient.spec.ts index 0c83deb672..aa33d12ed4 100644 --- a/packages/relay/tests/lib/sdkClient.spec.ts +++ b/packages/relay/tests/lib/sdkClient.spec.ts @@ -2266,12 +2266,10 @@ describe('SdkClient', async function () { const mockedConstructorName = 'constructor_name'; const mockedInteractingEntity = 'interacting_entity'; - let requestId: string; let hbarLimitMock: sinon.SinonMock; let sdkClientMock: sinon.SinonMock; beforeEach(() => { - requestId = uuid(); hbarLimitMock = sinon.mock(hbarLimiter); sdkClientMock = sinon.mock(sdkClient); mock = new MockAdapter(instance); @@ -2703,9 +2701,9 @@ describe('SdkClient', async function () { const transactionRecordMetrics = await sdkClient.getTransactionRecordMetrics( transactionId.toString(), mockedCallerName, - requestId, mockedConstructorName, accountId.toString(), + requestDetails, ); expect(transactionRecordStub.called).to.be.true; @@ -2722,9 +2720,9 @@ describe('SdkClient', async function () { await sdkClient.getTransactionRecordMetrics( transactionId.toString(), mockedCallerName, - requestId, mockedConstructorName, accountId.toString(), + requestDetails, ); expect.fail('should have thrown an error'); } catch (error: any) { diff --git a/packages/server/tests/acceptance/erc20.spec.ts b/packages/server/tests/acceptance/erc20.spec.ts index cecf90580b..4cd322d9de 100644 --- a/packages/server/tests/acceptance/erc20.spec.ts +++ b/packages/server/tests/acceptance/erc20.spec.ts @@ -289,7 +289,7 @@ describe('@erc20 Acceptance Tests', async function () { await contract .connect(tokenOwnerWallet) .approve(spender, initialSupply, await Utils.gasOptions(requestId)); - await contract.transfer(to, 1, await Utils.gasOptions(1_500_000)); + await contract.transfer(to, 1, await Utils.gasOptions(requestId)); // 5 seconds sleep to propagate the changes to mirror node await new Promise((r) => setTimeout(r, 5000)); }); @@ -351,7 +351,7 @@ describe('@erc20 Acceptance Tests', async function () { }); beforeEach('reducing balance', async function () { - await contract.transfer(to, 2, await Utils.gasOptions(1_500_000)); + await contract.transfer(to, 2, await Utils.gasOptions(requestId)); }); it('reverts', async function () { @@ -378,9 +378,7 @@ describe('@erc20 Acceptance Tests', async function () { amount = initialSupply; to = ethers.ZeroAddress; tokenOwnerWallet = accounts[2].wallet; - await contract - .connect(tokenOwnerWallet) - .approve(spender, amount, await Utils.gasOptions(requestId, 1_500_000)); + await contract.connect(tokenOwnerWallet).approve(spender, amount, await Utils.gasOptions(requestId)); }); it('reverts', async function () { diff --git a/packages/server/tests/acceptance/estimateGasContract.spec.ts b/packages/server/tests/acceptance/estimateGasContract.spec.ts index 848df84caa..20d38b7a5b 100644 --- a/packages/server/tests/acceptance/estimateGasContract.spec.ts +++ b/packages/server/tests/acceptance/estimateGasContract.spec.ts @@ -168,7 +168,7 @@ describe('EstimateGasContract tests', function () { const estimateGasResponse = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_ESTIMATE_GAS, [ { data: '0x0ec1551d', - to: Utils.add0xPrefix(contract.target), + to: Utils.add0xPrefix(contract.target as string), from: randomAddress, }, ]); diff --git a/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts b/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts index 494d2e6be4..828743b179 100644 --- a/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts +++ b/packages/server/tests/acceptance/estimateGasPrecompile.spec.ts @@ -2378,7 +2378,7 @@ describe('EstimatePrecompileContract tests', function () { let estimateGasResponse; try { estimateGasResponse = await relay.call(RelayCalls.ETH_ENDPOINTS.ETH_ESTIMATE_GAS, [tx]); - } catch (e) { + } catch (e: any) { expect(e.code).to.eq(errorMessage); failed = true; } diff --git a/packages/server/tests/acceptance/hbarLimiter.spec.ts b/packages/server/tests/acceptance/hbarLimiter.spec.ts index d36276ea55..357eb0a700 100644 --- a/packages/server/tests/acceptance/hbarLimiter.spec.ts +++ b/packages/server/tests/acceptance/hbarLimiter.spec.ts @@ -41,6 +41,8 @@ import { config } from 'dotenv'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; import MirrorClient from '../clients/mirrorClient'; import RelayClient from '../clients/relayClient'; +import { Logger } from 'pino'; +import MetricsClient from '../clients/metricsClient'; config({ path: resolve(__dirname, '../localAcceptance.env') }); @@ -53,7 +55,14 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { initialBalance, metrics, relayIsLocal, - }: { mirrorNode: MirrorClient; relay: RelayClient } = global; + }: { + mirrorNode: MirrorClient; + relay: RelayClient; + logger: Logger; + initialBalance: string; + metrics: MetricsClient; + relayIsLocal: boolean; + } = global; const operatorAccount = process.env.OPERATOR_ID_MAIN; const fileAppendChunkSize = Number(process.env.FILE_APPEND_CHUNK_SIZE) || 5120; const requestId = 'hbarLimiterTest'; @@ -121,7 +130,7 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { const ethereumTransaction = ( await mirrorNode.get( `/transactions?transactiontype=ETHEREUMTRANSACTION&order=desc&account.id=${operatorAccount}&limit=1`, - requestDetails, + requestId, ) ).transactions[0]; const ethereumTxFee = sumAccountTransfers(ethereumTransaction.transfers, operatorAccount); @@ -131,7 +140,7 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { const fileDeleteTx = ( await mirrorNode.get( `/transactions?transactiontype=FILEDELETE&order=desc&account.id=${operatorAccount}&limit=1`, - requestDetails, + requestId, ) ).transactions[0]; @@ -140,11 +149,11 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { return ethereumTxFee + fileCreateTxFee + fileAppendTxFee + fileDeleteTxFee; }; - const getExpectedCostOfLastSmallTx = async (requestDetails: RequestDetails) => { + const getExpectedCostOfLastSmallTx = async (requestId: string) => { const ethereumTransaction = ( await mirrorNode.get( `/transactions?transactiontype=ETHEREUMTRANSACTION&order=desc&account.id=${operatorAccount}&limit=1`, - requestDetails, + requestId, ) ).transactions[0]; return sumAccountTransfers(ethereumTransaction.transfers, operatorAccount); @@ -219,7 +228,7 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { .fulfilled; const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); - const expectedCost = await getExpectedCostOfLastSmallTx(requestDetails); + const expectedCost = await getExpectedCostOfLastSmallTx(requestId); verifyRemainingLimit(expectedCost, remainingHbarsBefore, remainingHbarsAfter); }); @@ -247,7 +256,7 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { await deployContract(EstimateGasContract, accounts[0].wallet); const remainingHbarsAfter = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); - const expectedCost = await getExpectedCostOfLastSmallTx(requestDetails); + const expectedCost = await getExpectedCostOfLastSmallTx(requestId); verifyRemainingLimit(expectedCost, remainingHbarsBefore, remainingHbarsAfter); }); @@ -307,11 +316,11 @@ describe('@hbarlimiter HBAR Limiter Acceptance Tests', function () { const TOLERANCE = 0.02; const remainingHbarsBefore = Number(await metrics.get(testConstants.METRICS.REMAINING_HBAR_LIMIT)); expect(remainingHbarsBefore).to.be.gt(0); - const operatorBalanceBefore = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestDetails)).balance + const operatorBalanceBefore = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestId)).balance .balance; const largeContract = await deployContract(largeContractJson, accounts[0].wallet); - const operatorBalanceAfter = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestDetails)).balance + const operatorBalanceAfter = (await mirrorNode.get(`/accounts/${operatorAccount}`, requestId)).balance .balance; const amountPaidByOperator = operatorBalanceBefore - operatorBalanceAfter; diff --git a/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts b/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts index 5e7cb79676..f89a03c653 100644 --- a/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts +++ b/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts @@ -391,7 +391,7 @@ describe('@precompile-calls Tests for eth_call with HTS', async function () { expect(customFees.fixedFees).to.exist; expect(customFees.fixedFees.length).to.eq(1); expect(customFees.fixedFees[0].amount).to.exist; - expect(customFees.fixedFees[0].amount.toString()).to.eq(Hbar.from(1).toTinybars().toString()); + expect(customFees.fixedFees[0].amount.toString()).to.eq(Hbar.fromTinybars(1).toString()); expect(customFees.fixedFees[0].tokenId).to.eq(ZERO_HEX); expect(customFees.fixedFees[0].feeCollector).to.exist; expect(customFees.fixedFees[0].feeCollector.toLowerCase()).to.eq(accounts[0].address.toLowerCase()); @@ -473,7 +473,7 @@ describe('@precompile-calls Tests for eth_call with HTS', async function () { expect(customFees.fixedFees.length).to.eq(2); expect(customFees.fixedFees[0].amount).to.exist; - expect(customFees.fixedFees[0].amount.toString()).to.eq(Hbar.from(1).toTinybars().toString()); + expect(customFees.fixedFees[0].amount.toString()).to.eq(Hbar.fromTinybars(1).toString()); expect(customFees.fixedFees[0].tokenId).to.eq(ZERO_HEX); expect(customFees.fixedFees[0].feeCollector).to.exist; expect(customFees.fixedFees[0].feeCollector.toLowerCase()).to.eq(accounts[0].address.toLowerCase()); diff --git a/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts b/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts index bbb33aab48..7a53850269 100644 --- a/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts +++ b/packages/server/tests/acceptance/htsPrecompile_v1.spec.ts @@ -33,6 +33,7 @@ import { Utils } from '../helpers/utils'; import ServicesClient from '../clients/servicesClient'; import RelayClient from '../clients/relayClient'; import MirrorClient from '../clients/mirrorClient'; +import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; chai.use(solidity); @@ -46,6 +47,8 @@ describe('@htsprecompilev1 HTS Precompile V1 Acceptance Tests', async function ( mirrorNode, }: { servicesNode: ServicesClient; relay: RelayClient; mirrorNode: MirrorClient } = global; + const requestDetails = new RequestDetails({ requestId: 'htsPrecompile_v1Test', ipAddress: '0.0.0.0' }); + const TX_SUCCESS_CODE = BigInt(22); const accounts: AliasAccount[] = []; @@ -57,36 +60,38 @@ describe('@htsprecompilev1 HTS Precompile V1 Acceptance Tests', async function ( let baseHTSContractReceiverWalletFirst; let baseHTSContractReceiverWalletSecond; let HTSTokenWithCustomFeesContractAddress; - let requestId; this.beforeAll(async () => { - requestId = Utils.generateRequestId(); - const initialAccount: AliasAccount = global.accounts[0]; const initialAmount: string = '5000000000'; //50 Hbar - const contractDeployer = await Utils.createAliasAccount(mirrorNode, initialAccount, requestId, initialAmount); + const contractDeployer = await Utils.createAliasAccount( + mirrorNode, + initialAccount, + requestDetails.requestId, + initialAmount, + ); const BaseHTSContract = await Utils.deployContract(BaseHTSJson.abi, BaseHTSJson.bytecode, contractDeployer.wallet); BaseHTSContractAddress = BaseHTSContract.target; - const contractMirror = await mirrorNode.get(`/contracts/${BaseHTSContractAddress}`, requestId); + const contractMirror = await mirrorNode.get(`/contracts/${BaseHTSContractAddress}`, requestDetails.requestId); accounts[0] = await servicesNode.createAccountWithContractIdKey( contractMirror.contract_id, 70, relay.provider, - requestId, + requestDetails.requestId, ); accounts[1] = await servicesNode.createAccountWithContractIdKey( contractMirror.contract_id, 25, relay.provider, - requestId, + requestDetails.requestId, ); accounts[2] = await servicesNode.createAccountWithContractIdKey( contractMirror.contract_id, 25, relay.provider, - requestId, + requestDetails.requestId, ); // allow mirror node a 2 full record stream write windows (2 sec) and a buffer to persist setup details @@ -99,10 +104,6 @@ describe('@htsprecompilev1 HTS Precompile V1 Acceptance Tests', async function ( baseHTSContractReceiverWalletSecond = baseHTSContract.connect(accounts[2].wallet); }); - this.beforeEach(async () => { - requestId = Utils.generateRequestId(); - }); - async function createHTSToken() { const baseHTSContract = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[0].wallet); const tx = await baseHTSContract.createFungibleTokenPublic(accounts[0].wallet.address, { diff --git a/packages/server/tests/acceptance/index.spec.ts b/packages/server/tests/acceptance/index.spec.ts index 572152bb31..fa184a2ecd 100644 --- a/packages/server/tests/acceptance/index.spec.ts +++ b/packages/server/tests/acceptance/index.spec.ts @@ -48,6 +48,7 @@ import constants from '@hashgraph/json-rpc-relay/dist/lib/constants'; import { Utils } from '../helpers/utils'; import { AliasAccount } from '../types/AliasAccount'; import { setServerTimeout } from '../../src/koaJsonRpc/lib/utils'; +import { Server, IncomingMessage, ServerResponse } from 'http'; chai.use(chaiAsPromised); dotenv.config({ path: path.resolve(__dirname, '../../../.env') }); @@ -79,8 +80,6 @@ global.relayIsLocal = RELAY_URL === LOCAL_RELAY_URL; describe('RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds - let relayServer; // Relay Server - let socketServer; global.servicesNode = new ServicesClient( NETWORK, OPERATOR_ID, @@ -90,8 +89,6 @@ describe('RPC Server Acceptance Tests', function () { global.mirrorNode = new MirrorClient(MIRROR_NODE_URL, logger.child({ name: `mirror-node-test-client` })); global.metrics = new MetricsClient(RELAY_URL, logger.child({ name: `metrics-test-client` })); global.relay = new RelayClient(RELAY_URL, logger.child({ name: `relay-test-client` })); - global.relayServer = relayServer; - global.socketServer = socketServer; global.logger = logger; global.initialBalance = INITIAL_BALANCE; @@ -193,6 +190,8 @@ describe('RPC Server Acceptance Tests', function () { function stopRelay() { //stop relay logger.info('Stop relay'); + + const relayServer: Server = global.relayServer; if (relayServer !== undefined) { relayServer.close(); } @@ -206,7 +205,8 @@ describe('RPC Server Acceptance Tests', function () { // start local relay, relay instance in local should not be running logger.info(`Start relay on port ${constants.RELAY_PORT}`); - relayServer = app.listen({ port: constants.RELAY_PORT }); + const relayServer = app.listen({ port: constants.RELAY_PORT }); + global.relayServer = relayServer; setServerTimeout(relayServer); if (process.env.TEST_WS_SERVER === 'true') { diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 70ce240c89..bbc4be2e51 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -23,7 +23,7 @@ import { expect } from 'chai'; import { ethers } from 'ethers'; import { AliasAccount } from '../types/AliasAccount'; import { Utils } from '../helpers/utils'; -import { FileInfo, FileInfoQuery, TransferTransaction } from '@hashgraph/sdk'; +import { FileInfo, FileInfoQuery, Hbar, TransferTransaction } from '@hashgraph/sdk'; // Assertions from local resources import Assertions from '../helpers/assertions'; @@ -59,7 +59,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { mirrorNode, relay, initialBalance, - }: { servicesNode: ServicesClient; mirrorNode: MirrorClient; relay: RelayClient } = global; + }: { servicesNode: ServicesClient; mirrorNode: MirrorClient; relay: RelayClient; initialBalance: string } = global; // cached entities let parentContractAddress: string; @@ -75,16 +75,17 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const GAS_PRICE_TOO_LOW = '0x1'; const GAS_PRICE_REF = '0x123456'; const ONE_TINYBAR = Utils.add0xPrefix(Utils.toHex(Constants.TINYBAR_TO_WEIBAR_COEF)); + const TEN_HBAR = Utils.add0xPrefix(new Hbar(10).toTinybars().mul(Constants.TINYBAR_TO_WEIBAR_COEF).toString(16)); const sendRawTransaction = relay.sendRawTransaction; /** * resolves long zero addresses to EVM addresses by querying mirror node - * @param tx: any - supposedly a proper transaction that has `from` and `to` fields + * @param tx - supposedly a proper transaction that has `from` and `to` fields * @returns Promise<{from: any|null, to: any|null}> */ - const resolveAccountEvmAddresses = async (tx: any, requestDetails: RequestDetails) => { - const fromAccountInfo = await mirrorNode.get(`/accounts/${tx.from}`, requestDetails); - const toAccountInfo = await mirrorNode.get(`/accounts/${tx.to}`, requestDetails); + const resolveAccountEvmAddresses = async (tx: any) => { + const fromAccountInfo = await mirrorNode.get(`/accounts/${tx.from}`, requestId); + const toAccountInfo = await mirrorNode.get(`/accounts/${tx.to}`, requestId); return { from: fromAccountInfo?.evm_address ?? tx.from, to: toAccountInfo?.evm_address ?? tx.to, @@ -132,7 +133,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { `${requestDetails.formattedRequestId} Contract call createChild on parentContract results in tx hash: ${createChildTx.hash}`, ); // get contract result details - mirrorContractDetails = await mirrorNode.get(`/contracts/results/${createChildTx.hash}`, requestDetails); + mirrorContractDetails = await mirrorNode.get(`/contracts/results/${createChildTx.hash}`, requestId); mirrorContractDetails.from = accounts[0].address; account2Address = accounts[2].address; @@ -487,21 +488,20 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const mirrorTransactions: any[] = []; before(async () => { - mirrorBlock = ( - await mirrorNode.get(`/blocks?block.number=${mirrorContractDetails.block_number}`, requestDetails) - ).blocks[0]; + mirrorBlock = (await mirrorNode.get(`/blocks?block.number=${mirrorContractDetails.block_number}`, requestId)) + .blocks[0]; const timestampQuery = `timestamp=gte:${mirrorBlock.timestamp.from}×tamp=lte:${mirrorBlock.timestamp.to}`; - mirrorContractResults = (await mirrorNode.get(`/contracts/results?${timestampQuery}`, requestDetails)).results; + mirrorContractResults = (await mirrorNode.get(`/contracts/results?${timestampQuery}`, requestId)).results; for (const res of mirrorContractResults) { mirrorTransactions.push( - await mirrorNode.get(`/contracts/${res.contract_id}/results/${res.timestamp}`, requestDetails), + await mirrorNode.get(`/contracts/${res.contract_id}/results/${res.timestamp}`, requestId), ); } // resolve EVM address for `from` and `to` for (const mirrorTx of mirrorTransactions) { - const resolvedAddresses = await resolveAccountEvmAddresses(mirrorTx, requestDetails); + const resolvedAddresses = await resolveAccountEvmAddresses(mirrorTx); mirrorTx.from = resolvedAddresses.from; mirrorTx.to = resolvedAddresses.to; @@ -688,7 +688,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { it('should execute "eth_getBlockTransactionCountByNumber"', async function () { it('@release should execute "eth_blockNumber"', async function () { - const mirrorBlocks = await mirrorNode.get(`blocks`, requestDetails); + const mirrorBlocks = await mirrorNode.get(`blocks`, requestId); expect(mirrorBlocks).to.have.property('blocks'); expect(mirrorBlocks.blocks.length).to.gt(0); const mirrorBlockNumber = mirrorBlocks.blocks[0].number; @@ -804,7 +804,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const legacyTxHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - const mirrorResult = await mirrorNode.get(`/contracts/results/${legacyTxHash}`, requestDetails); + const mirrorResult = await mirrorNode.get(`/contracts/results/${legacyTxHash}`, requestId); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; @@ -832,7 +832,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; @@ -858,7 +858,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const mirrorResult = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; @@ -902,7 +902,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const resp = await transaction.execute(servicesNode.client); await resp.getRecord(servicesNode.client); await Utils.wait(1000); - const logsRes = await mirrorNode.get(`/contracts/results/logs?limit=1`, requestDetails); + const logsRes = await mirrorNode.get(`/contracts/results/logs?limit=1`, requestId); const blockNumber = logsRes.logs[0].block_number; const formattedBlockNumber = prepend0x(blockNumber.toString(16)); const contractId = logsRes.logs[0].contract_id; @@ -976,7 +976,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // send gas money to the proxy deployer const sendHbarTx = { ...defaultLegacyTransactionData, - value: (10 * ONE_TINYBAR * 10 ** 8).toString(), // 10hbar - the gasPrice to deploy the deterministic proxy contract + value: TEN_HBAR, // 10hbar - the gasPrice to deploy the deterministic proxy contract to: constants.DETERMINISTIC_DEPLOYMENT_SIGNER, nonce: await relay.getAccountNonce(accounts[0].address, requestId), gasPrice: await relay.gasPrice(requestId), @@ -1007,12 +1007,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { requestId, ); - const receipt = await mirrorNode.get( - `/contracts/results/${deterministicDeployTransactionHash}`, - requestDetails, - ); - const fromAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.from}`, requestDetails); - const toAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.to}`, requestDetails); + const receipt = await mirrorNode.get(`/contracts/results/${deterministicDeployTransactionHash}`, requestId); + const fromAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.from}`, requestId); + const toAccountInfo = await global.mirrorNode.get(`/accounts/${receipt.to}`, requestId); expect(receipt).to.exist; expect(fromAccountInfo.evm_address).to.eq(constants.DETERMINISTIC_DEPLOYMENT_SIGNER); @@ -1044,7 +1041,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); const balanceChange = receiverEndBalance - receiverInitialBalance; @@ -1079,7 +1076,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); const balanceChange = receiverEndBalance - receiverInitialBalance; @@ -1129,7 +1126,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); expect(info).to.exist; expect(info.result).to.equal('SUCCESS'); }); @@ -1212,7 +1209,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { // Wait for the transaction to be processed and imported in the mirror node with axios-retry await Utils.wait(5000); - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); const receiverEndBalance = await relay.getBalance(parentContractAddress, 'latest', requestId); const balanceChange = receiverEndBalance - receiverInitialBalance; expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString()); @@ -1232,7 +1229,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[2].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1259,7 +1256,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[0].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1284,9 +1281,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const transactionHash = await relay.sendRawTransaction(signedTx, requestId); await Utils.wait(1000); - const txInfo = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const txInfo = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); - const contractResult = await mirrorNode.get(`/contracts/${txInfo.contract_id}`, requestDetails); + const contractResult = await mirrorNode.get(`/contracts/${txInfo.contract_id}`, requestId); const fileInfo = await new FileInfoQuery().setFileId(contractResult.file_id).execute(servicesNode.client); expect(fileInfo).to.exist; expect(fileInfo instanceof FileInfo).to.be.true; @@ -1323,7 +1320,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[2].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('created_contract_ids'); @@ -1344,7 +1341,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[2].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; expect(info).to.have.property('max_fee_per_gas'); @@ -1372,7 +1369,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[2].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId); expect(info).to.have.property('contract_id'); expect(info.contract_id).to.not.be.null; @@ -1516,7 +1513,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[2].wallet.signTransaction(transaction); const txHash1 = await relay.sendRawTransaction(signedTx, requestId); - const mirrorResult = await mirrorNode.get(`/contracts/results/${txHash1}`, requestDetails); + const mirrorResult = await mirrorNode.get(`/contracts/results/${txHash1}`, requestId); mirrorResult.from = accounts[2].wallet.address; mirrorResult.to = parentContractAddress; @@ -1594,14 +1591,14 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[2].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTx, requestId); - const mirrorTransaction = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + const mirrorTransaction = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH, [transactionHash], requestIdPrefix, ); - const addressResult = await mirrorNode.get(`/accounts/${res.from}`, requestDetails); + const addressResult = await mirrorNode.get(`/accounts/${res.from}`, requestId); mirrorTransaction.from = addressResult.evm_address; Assertions.transaction(res, mirrorTransaction); diff --git a/packages/server/tests/acceptance/rpc_batch2.spec.ts b/packages/server/tests/acceptance/rpc_batch2.spec.ts index 789873231d..6024db73c0 100644 --- a/packages/server/tests/acceptance/rpc_batch2.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch2.spec.ts @@ -46,6 +46,7 @@ import constants from '../../tests/helpers/constants'; import RelayClient from '../clients/relayClient'; import ServicesClient from '../clients/servicesClient'; import MirrorClient from '../clients/mirrorClient'; +import { Logger } from 'pino'; describe('@api-batch-2 RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds @@ -59,7 +60,13 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { relay, logger, initialBalance, - }: { servicesNode: ServicesClient; mirrorNode: MirrorClient; relay: RelayClient } = global; + }: { + servicesNode: ServicesClient; + mirrorNode: MirrorClient; + relay: RelayClient; + logger: Logger; + initialBalance: string; + } = global; // cached entities let tokenId; @@ -739,7 +746,7 @@ describe('@api-batch-2 RPC Server Acceptance Tests', function () { async function createNftHTSToken(account) { const mainContract = new ethers.Contract(mainContractAddress, TokenCreateJson.abi, accounts[0].wallet); const tx = await mainContract.createNonFungibleTokenPublic(account.wallet.address, { - value: 30000000000000000000n, + value: BigInt('30000000000000000000'), ...Helper.GAS.LIMIT_5_000_000, }); const { tokenAddress } = (await tx.wait()).logs.filter( diff --git a/packages/server/tests/acceptance/rpc_batch3.spec.ts b/packages/server/tests/acceptance/rpc_batch3.spec.ts index a0577fd5f6..5bff80a411 100644 --- a/packages/server/tests/acceptance/rpc_batch3.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch3.spec.ts @@ -46,7 +46,6 @@ import DeployerContractJson from '../contracts/Deployer.json'; import HederaTokenServiceImplJson from '../contracts/HederaTokenServiceImpl.json'; import EstimateGasContract from '../contracts/EstimateGasContract.json'; import HRC719ContractJson from '../contracts/HRC719Contract.json'; -import TokenCreateJson from '../contracts/TokenCreateContract.json'; // Helper functions/constants from local resources import { EthImpl } from '@hashgraph/json-rpc-relay/src/lib/eth'; @@ -56,7 +55,6 @@ import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; import RelayClient from '../clients/relayClient'; import ServicesClient from '../clients/servicesClient'; import MirrorClient from '../clients/mirrorClient'; -import { request } from 'http'; chai.use(chaiExclude); @@ -284,7 +282,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { // get block hash before deployment const blockNumber = deploymentBlockNumber - 1; - const nextBlockHash = (await mirrorNode.get(`/blocks/${blockNumber}`, requestDetails)).hash; + const nextBlockHash = (await mirrorNode.get(`/blocks/${blockNumber}`, requestId)).hash; const truncatedHash = nextBlockHash.slice(0, 66); const res = await relay.call( @@ -412,7 +410,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { callerContractJson.bytecode, activeAccount.wallet, ); - const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestDetails); + const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestId); const callerContractId = ContractId.fromString(callerMirror.contract_id); callerAddress = `0x${callerContractId.toSolidityAddress()}`; @@ -436,7 +434,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { relay, )) as ethers.Contract; // Wait for creation to propagate - const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestDetails); + const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestId); callerAddress = callerMirror.evm_address; defaultCallData = { from: activeAccount.address, @@ -594,7 +592,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const activeAccount = accounts[1]; const callerContract = await Utils.deployContractWithEthers([], callerContractJson, activeAccount.wallet, relay); // Wait for creation to propagate - const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestDetails); + const callerMirror = await mirrorNode.get(`/contracts/${callerContract.target}`, requestId); const callerAddress = callerMirror.evm_address; const defaultCallData = { from: activeAccount.address, @@ -685,7 +683,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Wait until receipt is available in mirror node - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); const receipt = await relay.call( RelayCall.ETH_ENDPOINTS.ETH_GET_TRANSACTION_RECEIPT, @@ -767,7 +765,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { adminPrivateKey: accounts[1].privateKey, }); - tokenAddress = Utils.idToEvmAddress(htsResult.receipt.tokenId.toString()); + tokenAddress = Utils.idToEvmAddress(htsResult.receipt.tokenId!.toString()); // Deploy a contract implementing HederaTokenService const HederaTokenServiceImplFactory = new ethers.ContractFactory( @@ -874,7 +872,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { ); // get contract details - const mirrorContract = await mirrorNode.get(`/contracts/${deployerContractAddress}`, requestDetails); + const mirrorContract = await mirrorNode.get(`/contracts/${deployerContractAddress}`, requestId); contractId = ContractId.fromString(mirrorContract.contract_id); primaryAccountNonce = await relay.call( @@ -993,7 +991,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { [signedTxHollowAccountCreation], requestId, ); - await mirrorNode.get(`/contracts/results/${txHashHAC}`, requestDetails); + await mirrorNode.get(`/contracts/results/${txHashHAC}`, requestId); const signTxFromHollowAccount = await hollowAccount.signTransaction({ ...defaultTransaction, @@ -1007,7 +1005,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { [signTxFromHollowAccount], requestId, ); - await mirrorNode.get(`/contracts/results/${txHashHA}`, requestDetails); + await mirrorNode.get(`/contracts/results/${txHashHA}`, requestId); const resAfterCreation = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_COUNT, @@ -1018,7 +1016,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { }); it('should execute "eth_getTransactionCount" for account with non-zero nonce', async function () { - const account = await Utils.createAliasAccount(mirrorNode, accounts[0], requestDetails); + const account = await Utils.createAliasAccount(mirrorNode, accounts[0], requestId); const gasPrice = await relay.gasPrice(requestId); const transaction = { @@ -1033,7 +1031,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const transactionHash = await relay.sendRawTransaction(signedTx, requestId); // Since the transactionId is not available in this context // Wait for the transaction to be processed and imported in the mirror node with axios-retry - await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); const res = await relay.call( RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_COUNT, @@ -1255,7 +1253,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { const signedTransaction = await accounts[0].wallet.signTransaction(transaction); const transactionHash = await relay.sendRawTransaction(signedTransaction, requestId); - estimateGasContractAddress = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestDetails); + estimateGasContractAddress = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); }); describe('Positive scenarios', async function () { @@ -2037,7 +2035,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () { }); it('Should return a batch of requests', async function () { - const testAccount = await Utils.createAliasAccount(mirrorNode, accounts[0], requestDetails); + const testAccount = await Utils.createAliasAccount(mirrorNode, accounts[0], requestId); { const payload = [ diff --git a/packages/server/tests/acceptance/serverConfig.spec.ts b/packages/server/tests/acceptance/serverConfig.spec.ts index e46d2e0ae1..3edc034b42 100644 --- a/packages/server/tests/acceptance/serverConfig.spec.ts +++ b/packages/server/tests/acceptance/serverConfig.spec.ts @@ -32,7 +32,7 @@ describe('@server-config Server Configuration Options Coverage', function () { try { await Utils.sendJsonRpcRequestWithDelay(host, port, method, params, requestTimeoutMs + 1000); throw new Error('Request did not timeout as expected'); // Force the test to fail if the request does not time out - } catch (err) { + } catch (err: any) { expect(err.code).to.equal('ECONNRESET'); expect(err.message).to.equal('socket hang up'); } diff --git a/packages/server/tests/clients/mirrorClient.ts b/packages/server/tests/clients/mirrorClient.ts index a0de83688a..f0aebccd2d 100644 --- a/packages/server/tests/clients/mirrorClient.ts +++ b/packages/server/tests/clients/mirrorClient.ts @@ -22,6 +22,7 @@ import Axios, { AxiosInstance } from 'axios'; import axiosRetry from 'axios-retry'; import { Logger } from 'pino'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; +import { Utils } from '../helpers/utils'; export default class MirrorClient { private readonly logger: Logger; @@ -63,8 +64,9 @@ export default class MirrorClient { this.client = mirrorNodeClient; } - async get(path: string, requestDetails: RequestDetails) { - this.logger.debug(`${requestDetails.formattedRequestId} [GET] MirrorNode ${path} endpoint`); + async get(path: string, requestId?: string) { + const requestIdPrefix = Utils.formatRequestIdMessage(requestId); + this.logger.debug(`${requestIdPrefix} [GET] MirrorNode ${path} endpoint`); return (await this.client.get(path)).data; } } diff --git a/packages/server/tests/clients/relayClient.ts b/packages/server/tests/clients/relayClient.ts index 06f39fd2f1..7b3bbbb6fe 100644 --- a/packages/server/tests/clients/relayClient.ts +++ b/packages/server/tests/clients/relayClient.ts @@ -18,14 +18,14 @@ * */ -import { ethers } from 'ethers'; +import { BlockTag, ethers } from 'ethers'; import { Logger } from 'pino'; import Assertions from '../helpers/assertions'; -import { predefined } from '../../../relay/src/lib/errors/JsonRpcError'; +import { predefined } from '@hashgraph/json-rpc-relay'; import { Utils } from '../helpers/utils'; export default class RelayClient { - private readonly provider: ethers.JsonRpcProvider; + readonly provider: ethers.JsonRpcProvider; private readonly logger: Logger; constructor(relayUrl: string, logger: Logger) { @@ -40,7 +40,8 @@ export default class RelayClient { * @param params * @param requestId */ - async call(methodName: string, params: any[], requestIdPrefix: string) { + async call(methodName: string, params: any[], requestId?: string) { + const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const result = await this.provider.send(methodName, params); this.logger.trace( `${requestIdPrefix} [POST] to relay '${methodName}' with params [${JSON.stringify( @@ -59,7 +60,7 @@ export default class RelayClient { * @param payload * @returns */ - async callBatch(payload: { id: string; method: string; params: any[] }[]) { + async callBatch(payload: { id: number; method: string; params: any[] }[]) { const request = this.provider._getConnection(); request.setHeader('content-type', 'application/json'); request.body = JSON.stringify(payload.map((r) => ({ ...r, jsonrpc: '2.0' }))); @@ -73,17 +74,18 @@ export default class RelayClient { * Calls the specified methodName with the provided params and asserts that it fails * @param methodName * @param params + * @param expectedRpcError * @param requestId */ async callFailing( methodName: string, params: any[], expectedRpcError = predefined.INTERNAL_ERROR(), - requestId: string, + requestId?: string, ) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); try { - const res = await this.call(methodName, params, requestIdPrefix); + const res = await this.call(methodName, params, requestId); this.logger.trace( `${requestIdPrefix} [POST] to relay '${methodName}' with params [${params}] returned ${JSON.stringify(res)}`, ); @@ -109,10 +111,9 @@ export default class RelayClient { * @param params * @param requestId */ - async callUnsupported(methodName: string, params: any[], requestId: string) { + async callUnsupported(methodName: string, params: any[], requestId?: string) { try { - const requestIdPrefix = Utils.formatRequestIdMessage(requestId); - await this.call(methodName, params, requestIdPrefix); + await this.call(methodName, params, requestId); Assertions.expectedError(); } catch (e: any) { Assertions.unsupportedResponse(e?.response?.bodyJson); @@ -125,7 +126,7 @@ export default class RelayClient { * @param block * @param requestId */ - async getBalance(address, block = 'latest', requestId: string) { + async getBalance(address: ethers.AddressLike, block: BlockTag = 'latest', requestId?: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); this.logger.debug(`${requestIdPrefix} [POST] to relay eth_getBalance for address ${address}]`); return this.provider.getBalance(address, block); @@ -136,7 +137,7 @@ export default class RelayClient { * @param requestId * Returns: The nonce of the account with the provided `evmAddress` */ - async getAccountNonce(evmAddress, requestId: string): Promise { + async getAccountNonce(evmAddress: string, requestId?: string): Promise { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); this.logger.debug(`${requestIdPrefix} [POST] to relay for eth_getTransactionCount for address ${evmAddress}`); const nonce = await this.provider.send('eth_getTransactionCount', [evmAddress, 'latest']); @@ -150,7 +151,7 @@ export default class RelayClient { * @param signedTx * @param requestId */ - async sendRawTransaction(signedTx, requestId: string): Promise { + async sendRawTransaction(signedTx, requestId?: string): Promise { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); this.logger.debug(`${requestIdPrefix} [POST] to relay for eth_sendRawTransaction`); return this.provider.send('eth_sendRawTransaction', [signedTx]); @@ -161,8 +162,7 @@ export default class RelayClient { * * Returns the result of eth_gasPrice as a Number. */ - async gasPrice(requestId: string): Promise { - const requestIdPrefix = Utils.formatRequestIdMessage(requestId); - return Number(await this.call('eth_gasPrice', [], requestIdPrefix)); + async gasPrice(requestId?: string): Promise { + return Number(await this.call('eth_gasPrice', [], requestId)); } } diff --git a/packages/server/tests/clients/servicesClient.ts b/packages/server/tests/clients/servicesClient.ts index 2ee4a986df..88767f2648 100644 --- a/packages/server/tests/clients/servicesClient.ts +++ b/packages/server/tests/clients/servicesClient.ts @@ -24,13 +24,10 @@ import { AccountId, AccountInfoQuery, Client, - ContractCreateTransaction, ContractExecuteTransaction, ContractFunctionParameters, ContractId, - FileCreateTransaction, Hbar, - Key, KeyList, PrivateKey, Query, @@ -43,7 +40,6 @@ import { FileUpdateTransaction, TransactionId, AccountAllowanceApproveTransaction, - AccountBalance, FileContentsQuery, TokenType, TokenSupplyType, @@ -53,19 +49,46 @@ import { CustomFractionalFee, CustomRoyaltyFee, EvmAddress, + CustomFee, + TokenId, + Key, } from '@hashgraph/sdk'; import { Logger } from 'pino'; -import { ethers } from 'ethers'; +import { ethers, JsonRpcProvider } from 'ethers'; import { Utils } from '../helpers/utils'; import { AliasAccount } from '../types/AliasAccount'; import { Utils as relayUtils } from '@hashgraph/json-rpc-relay/dist/utils'; +import { Long } from 'long'; const supportedEnvs = ['previewnet', 'testnet', 'mainnet']; +type CreateHTSParams = { + tokenName: string; + symbol: string; + treasuryAccountId: string; + initialSupply: number; + adminPrivateKey: PrivateKey; + kyc?: Key; + freeze?: Key; + customHbarFees?: number; + customTokenFees?: number; + customRoyaltyFees?: number; + customFractionalFees?: number; +}; + +type CreateNFTParams = { + tokenName: string; + symbol: string; + treasuryAccountId: string; + maxSupply: number; + adminPrivateKey: PrivateKey; + customRoyaltyFees?: number; +}; + export default class ServicesClient { static TINYBAR_TO_WEIBAR_COEF = 10_000_000_000; - private readonly DEFAULT_KEY = new Key(); + private readonly DEFAULT_KEY = PrivateKey.generateECDSA(); private readonly logger: Logger; private readonly network: string; @@ -89,7 +112,12 @@ export default class ServicesClient { return this.logger; } - async createInitialAliasAccount(providerUrl, chainId, requestId, initialBalance = 2000): Promise { + async createInitialAliasAccount( + providerUrl: string, + chainId: ethers.BigNumberish, + requestId?: string, + initialBalance: number = 2000, + ): Promise { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const privateKey = PrivateKey.generateECDSA(); const wallet = new ethers.Wallet( @@ -114,7 +142,7 @@ export default class ServicesClient { const accountId = receipt?.transfers[1].accountId!; accountId.evmAddress = EvmAddress.fromString(address); - const aliasAccount: AliasAccount = { + return { alias: accountId, accountId, address, @@ -123,11 +151,9 @@ export default class ServicesClient { wallet, keyList: KeyList.from([privateKey]), }; - - return aliasAccount; } - async executeQuery(query: Query, requestId?: string) { + async executeQuery(query: Query, requestId?: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); try { this.logger.info(`${requestIdPrefix} Execute ${query.constructor.name} query`); @@ -174,7 +200,7 @@ export default class ServicesClient { return { executedTimestamp, executedTransactionId }; } - async createToken(initialSupply = 1000, requestId: string) { + async createToken(initialSupply: number = 1000, requestId?: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const symbol = Math.random().toString(36).slice(2, 6).toUpperCase(); this.logger.trace(`${requestIdPrefix} symbol = ${symbol}`); @@ -192,13 +218,13 @@ export default class ServicesClient { this.logger.trace(`${requestIdPrefix} get token id from receipt`); const tokenId = resp?.tokenId; this.logger.info(`${requestIdPrefix} token id = ${tokenId?.toString()}`); - return tokenId; + return tokenId!; } - async associateToken(tokenId, requestId: string) { + async associateToken(tokenId: string | TokenId, requestId?: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); await this.executeAndGetTransactionReceipt( - await new TokenAssociateTransaction() + new TokenAssociateTransaction() .setAccountId(this._thisAccountId()) .setTokenIds([tokenId]) .setTransactionMemo('Relay test token association'), @@ -210,7 +236,7 @@ export default class ServicesClient { ); } - async transferToken(tokenId, recipient: AccountId, amount = 10, requestId?: string) { + async transferToken(tokenId: string | TokenId, recipient: AccountId, amount = 10, requestId?: string) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const receipt = await this.executeAndGetTransactionReceipt( new TransferTransaction() @@ -227,54 +253,17 @@ export default class ServicesClient { const balances = await this.executeQuery(new AccountBalanceQuery().setAccountId(recipient), requestId); this.logger.debug( - `${requestIdPrefix} Token balances for ${recipient.toString()} are ${balances.tokens.toString().toString()}`, + `${requestIdPrefix} Token balances for ${recipient.toString()} are ${balances?.tokens?.toString()}`, ); return receipt; } - async createParentContract(contractJson, requestId?: string) { - const requestIdPrefix = Utils.formatRequestIdMessage(requestId); - const contractByteCode = contractJson.deployedBytecode.replace('0x', ''); - - const fileReceipt = await this.executeAndGetTransactionReceipt( - new FileCreateTransaction() - .setKeys([this.client.operatorPublicKey || this.DEFAULT_KEY]) - .setContents(contractByteCode) - .setTransactionMemo('Relay test file create'), - requestId, - ); - - // Fetch the receipt for transaction that created the file - // The file ID is located on the transaction receipt - const fileId = fileReceipt?.fileId; - this.logger.info(`${requestIdPrefix} contract bytecode file: ${fileId?.toString()}`); - - // Create the contract - const contractReceipt = await this.executeAndGetTransactionReceipt( - new ContractCreateTransaction() - .setConstructorParameters(new ContractFunctionParameters()) - .setGas(75000) - .setInitialBalance(1) - .setBytecodeFileId(fileId || '') - .setAdminKey(this.client.operatorPublicKey || this.DEFAULT_KEY) - .setTransactionMemo('Relay test contract create'), - requestId, - ); - - // The contract ID is located on the transaction receipt - const contractId = contractReceipt?.contractId; - - this.logger.info(`${requestIdPrefix} new contract ID: ${contractId?.toString()}`); - - return contractId; - } - async executeContractCall( - contractId, + contractId: string | ContractId, functionName: string, params: ContractFunctionParameters, - gasLimit = 75000, + gasLimit: number | Long = 75000, requestId?: string, ) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); @@ -297,7 +286,7 @@ export default class ServicesClient { } async executeContractCallWithAmount( - contractId, + contractId: string | ContractId, functionName: string, params: ContractFunctionParameters, gasLimit = 500_000, @@ -316,7 +305,7 @@ export default class ServicesClient { if (amount > 0) { tx.setPayableAmount(Hbar.fromTinybars(amount)); } - let contractExecTransactionResponse; + let contractExecTransactionResponse: TransactionResponse; try { contractExecTransactionResponse = await this.executeTransaction(tx, requestId); @@ -333,20 +322,18 @@ export default class ServicesClient { } async getAliasAccountInfo( - accountId, + accountId: AccountId, privateKey: PrivateKey, - provider = null, + provider: JsonRpcProvider | null = null, requestId?: string, - keyList?: null | KeyList, + keyList?: KeyList, ): Promise { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); - //@ts-ignore - const balance = await this.executeQuery(new AccountBalanceQuery().setAccountId(accountId), requestId); + const balance = (await this.executeQuery(new AccountBalanceQuery().setAccountId(accountId), requestId))!; this.logger.info(`${requestIdPrefix} Balance of the new account: ${balance.toString()}`); - //@ts-ignore - const accountInfo = await this.executeQuery(new AccountInfoQuery().setAccountId(accountId), requestId); + const accountInfo = (await this.executeQuery(new AccountInfoQuery().setAccountId(accountId), requestId))!; this.logger.info( `${requestIdPrefix} New account Info - accountId: ${accountInfo.accountId.toString()}, evmAddress: ${ accountInfo.contractAccountId @@ -359,39 +346,40 @@ export default class ServicesClient { this.logger.child({ name: `services-client` }), ); - let wallet; + let wallet: ethers.Wallet; if (provider) { wallet = new ethers.Wallet(privateKey.toStringRaw(), provider); } else { wallet = new ethers.Wallet(privateKey.toStringRaw()); } - const account: AliasAccount = { + return { alias: accountId, accountId: accountInfo.accountId, - address: Utils.add0xPrefix(accountInfo.contractAccountId), + address: Utils.add0xPrefix(accountInfo.contractAccountId!), client: servicesClient, privateKey, wallet, keyList, }; - - return account; } // Creates an account that has 2 keys - ECDSA and a contractId. This is required for calling contract methods that create HTS tokens. // The contractId should be the id of the contract. // The account should be created after the contract has been deployed. async createAccountWithContractIdKey( - contractIdString: string, + contractId: string | ContractId, initialBalance = 10, - provider = null, + provider: JsonRpcProvider | null = null, requestId?: string, ) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const privateKey = PrivateKey.generateECDSA(); const publicKey = privateKey.publicKey; - const contractId = ContractId.fromString(contractIdString); + + if (typeof contractId === 'string') { + contractId = ContractId.fromString(contractId); + } const keys = [publicKey, contractId]; @@ -399,25 +387,28 @@ export default class ServicesClient { const keyList = new KeyList(keys, 1); this.logger.trace( - `${requestIdPrefix} Create new Eth compatible account w ContractId key: ${contractIdString}, privateKey: ${privateKey}, alias: ${publicKey.toEvmAddress()} and balance ~${initialBalance} hb`, + `${requestIdPrefix} Create new Eth compatible account w ContractId key: ${contractId}, privateKey: ${privateKey}, alias: ${publicKey.toEvmAddress()} and balance ~${initialBalance} hb`, ); - const accountCreateTx = await ( - await new AccountCreateTransaction() - .setInitialBalance(new Hbar(initialBalance)) - .setKey(keyList) - .setAlias(publicKey.toEvmAddress()) - .freezeWith(this.client) - ).sign(privateKey); + const accountCreateTx = await new AccountCreateTransaction() + .setInitialBalance(new Hbar(initialBalance)) + .setKey(keyList) + .setAlias(publicKey.toEvmAddress()) + .freezeWith(this.client) + .sign(privateKey); const txResult = await accountCreateTx.execute(this.client); const receipt = await txResult.getReceipt(this.client); - const accountId = receipt.accountId; + const accountId = receipt.accountId!; return this.getAliasAccountInfo(accountId, privateKey, provider, requestId, keyList); } - async createAliasAccount(initialBalance = 10, provider = null, requestId?: string): Promise { + async createAliasAccount( + initialBalance = 10, + provider: JsonRpcProvider | null = null, + requestId?: string, + ): Promise { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const privateKey = PrivateKey.generateECDSA(); const publicKey = privateKey.publicKey; @@ -442,7 +433,7 @@ export default class ServicesClient { } async deployContract( - contract, + contract: { bytecode: string | Uint8Array }, gas = 100_000, constructorParameters: Uint8Array = new Uint8Array(), initialBalance = 0, @@ -485,41 +476,23 @@ export default class ServicesClient { this.logger.info(`${requestIdPrefix} File ${fileId} updated with status: ${receipt.status.toString()}`); } - async getAccountBalance(account: string | AccountId, requestId?: string): Promise { - const accountId = typeof account === 'string' ? AccountId.fromString(account) : account; - return this.executeQuery(new AccountBalanceQuery().setAccountId(accountId), requestId); - } - - async getAccountBalanceInWeiBars(account: string | AccountId, requestId?: string) { - const balance = await this.getAccountBalance(account, requestId); - - return BigInt(balance.hbars.toTinybars().toString()) * BigInt(ServicesClient.TINYBAR_TO_WEIBAR_COEF); - } - getClient() { - let network = this.network; try { - network = JSON.parse(this.network); + const network = JSON.parse(this.network); + return Client.forNetwork(network); } catch (e) { // network config is a string and not a valid JSON + return Client.forName(this.network); } - - return Client.forNetwork(network); } async createHTS( - args = { + args: CreateHTSParams = { tokenName: 'Default Name', symbol: 'HTS', treasuryAccountId: '0.0.2', initialSupply: 5000, adminPrivateKey: this.DEFAULT_KEY, - kyc: null, - freeze: null, - customHbarFees: false, - customTokenFees: false, - customRoyaltyFees: false, - customFractionalFees: false, }, ) { const {} = args; @@ -549,11 +522,11 @@ export default class ServicesClient { transaction.setFreezeKey(args.freeze); } - const customFees = []; + const customFees: CustomFee[] = []; if (args.customHbarFees) { customFees.push( new CustomFixedFee() - .setHbarAmount(Hbar.from(args.customHbarFees)) + .setHbarAmount(Hbar.fromTinybars(args.customHbarFees)) .setFeeCollectorAccountId(AccountId.fromString(args.treasuryAccountId)), ); } @@ -579,7 +552,7 @@ export default class ServicesClient { transaction.setCustomFees(customFees); } - const tokenCreate = await (await transaction).execute(htsClient); + const tokenCreate = await transaction.execute(htsClient); const receipt = await tokenCreate.getReceipt(this.client); this.logger.info(`Created HTS token ${receipt.tokenId?.toString()}`); @@ -590,13 +563,12 @@ export default class ServicesClient { } async createNFT( - args = { + args: CreateNFTParams = { tokenName: 'Default Name', symbol: 'HTS', treasuryAccountId: '0.0.2', maxSupply: 5000, adminPrivateKey: this.DEFAULT_KEY, - customRoyaltyFees: false, }, ) { const {} = args; @@ -627,7 +599,7 @@ export default class ServicesClient { ]); } - let nftCreate = await (await transaction).execute(htsClient); + let nftCreate = await transaction.execute(htsClient); const receipt = await nftCreate.getReceipt(this.client); this.logger.info(`Created NFT token ${receipt.tokenId?.toString()}`); @@ -649,9 +621,10 @@ export default class ServicesClient { htsClient.setOperator(AccountId.fromString(args.treasuryAccountId), args.adminPrivateKey); // Mint new NFT - let mintTx = await ( - await new TokenMintTransaction().setTokenId(args.tokenId).setMetadata([Buffer.from(args.metadata)]) - ).execute(htsClient); + let mintTx = await new TokenMintTransaction() + .setTokenId(args.tokenId) + .setMetadata([Buffer.from(args.metadata)]) + .execute(htsClient); const receipt = await mintTx.getReceipt(this.client); return { @@ -672,9 +645,10 @@ export default class ServicesClient { htsClient.setOperator(AccountId.fromString(args.treasuryAccountId), args.adminPrivateKey); //Enable KYC flag on account and freeze the transaction for manual signing - const transaction = await ( - await new TokenGrantKycTransaction().setAccountId(args.accountId).setTokenId(args.tokenId) - ).execute(htsClient); + const transaction = await new TokenGrantKycTransaction() + .setAccountId(args.accountId) + .setTokenId(args.tokenId) + .execute(htsClient); //Request the receipt of the transaction const receipt = await transaction.getReceipt(htsClient); @@ -685,7 +659,13 @@ export default class ServicesClient { }; } - async associateHTSToken(accountId, tokenId, privateKey, htsClient, requestId?: string) { + async associateHTSToken( + accountId: string | AccountId, + tokenId: string | TokenId, + privateKey: PrivateKey, + htsClient: Client, + requestId?: string, + ) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const tokenAssociate = await ( await new TokenAssociateTransaction() @@ -699,7 +679,12 @@ export default class ServicesClient { this.logger.info(`${requestIdPrefix} HTS Token ${tokenId} associated to : ${accountId}`); } - async approveHTSToken(spenderId, tokenId, htsClient, requestId?: string) { + async approveHTSToken( + spenderId: string | AccountId, + tokenId: string | TokenId, + htsClient: Client, + requestId?: string, + ) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); const amount = 10000; const tokenApprove = await new AccountAllowanceApproveTransaction() @@ -710,14 +695,19 @@ export default class ServicesClient { this.logger.info(`${requestIdPrefix} ${amount} of HTS Token ${tokenId} can be spent by ${spenderId}`); } - async transferHTSToken(accountId, tokenId, amount, fromId = this.client.operatorAccountId, requestId?: string) { + async transferHTSToken( + accountId: string | AccountId, + tokenId: string | TokenId, + amount: number | Long, + fromId: string | AccountId = this.client.operatorAccountId!, + requestId?: string, + ) { const requestIdPrefix = Utils.formatRequestIdMessage(requestId); try { - const tokenTransfer = await ( - await new TransferTransaction() - .addTokenTransfer(tokenId, fromId, -amount) - .addTokenTransfer(tokenId, accountId, amount) - ).execute(this.client); + const tokenTransfer = await new TransferTransaction() + .addTokenTransfer(tokenId, fromId, -amount) + .addTokenTransfer(tokenId, accountId, amount) + .execute(this.client); const rec = await tokenTransfer.getReceipt(this.client); this.logger.info(`${requestIdPrefix} ${amount} of HTS Token ${tokenId} can be spent by ${accountId}`); @@ -726,10 +716,4 @@ export default class ServicesClient { this.logger.error(e, `${requestIdPrefix} TransferTransaction failed`); } } - - async getAccountNonce(accountId) { - const query = new AccountInfoQuery().setAccountId(accountId); - const accountInfo = await query.execute(this.client); - return accountInfo.ethereumNonce; - } } diff --git a/packages/server/tests/helpers/utils.ts b/packages/server/tests/helpers/utils.ts index 09ba5a98d7..755b41368b 100644 --- a/packages/server/tests/helpers/utils.ts +++ b/packages/server/tests/helpers/utils.ts @@ -35,7 +35,6 @@ import { GitHubClient } from '../clients/githubClient'; import MirrorClient from '../clients/mirrorClient'; import { HeapDifferenceStatistics } from '../types/HeapDifferenceStatistics'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; -import { Relay } from '@hashgraph/json-rpc-relay'; export class Utils { static readonly HEAP_SIZE_DIFF_MEMORY_LEAK_THRESHOLD: number = 1e6; // 1 MB @@ -45,11 +44,11 @@ export class Utils { /** * Converts a number to its hexadecimal representation. * - * @param {number} num The number to convert to hexadecimal. + * @param {number | bigint | string} num The number to convert to hexadecimal. * @returns {string} The hexadecimal representation of the number. */ - static toHex = (num) => { - return parseInt(num).toString(16); + static toHex = (num: number | bigint | string): string => { + return Number(num).toString(16); }; /** @@ -58,7 +57,7 @@ export class Utils { * @param {string} id The Hedera account ID to convert. * @returns {string} The EVM compatible address. */ - static idToEvmAddress = (id): string => { + static idToEvmAddress = (id: string): string => { Assertions.assertId(id); const [shard, realm, num] = id.split('.'); @@ -73,10 +72,10 @@ export class Utils { /** * Converts a value from tinybars to weibars. * - * @param {number} value The value in tinybars to convert. - * @returns {ethers.BigNumber} The value converted to weibars. + * @param {number | bigint | string} value The value in tinybars to convert. + * @returns {bigint} The value converted to weibars. */ - static tinyBarsToWeibars = (value) => { + static tinyBarsToWeibars = (value: number | bigint | string): bigint => { return ethers.parseUnits(Number(value).toString(), 10); }; @@ -86,7 +85,7 @@ export class Utils { * @param {number} length The length of the random string to generate. * @returns {string} The generated random string. */ - static randomString(length) { + static randomString(length: number): string { let result = ''; const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; for (let i = 0; i < length; i++) { @@ -111,21 +110,38 @@ export class Utils { return requestId ? `[Request ID: ${requestId}]` : ''; }; - static deployContractWithEthers = async (constructorArgs: any[] = [], contractJson, wallet, relay) => { + static deployContractWithEthers = async ( + constructorArgs: any[] = [], + contractJson: { abi: ethers.InterfaceAbi | ethers.Interface; bytecode: ethers.BytesLike | { object: string } }, + wallet: ethers.Wallet, + relay: RelayClient, + ) => { const factory = new ethers.ContractFactory(contractJson.abi, contractJson.bytecode, wallet); let contract = await factory.deploy(...constructorArgs); await contract.waitForDeployment(); // re-init the contract with the deployed address - const receipt = await relay.provider.getTransactionReceipt(contract.deploymentTransaction()?.hash); - contract = new ethers.Contract(receipt.to, contractJson.abi, wallet); + const receipt = await relay.provider.getTransactionReceipt(contract.deploymentTransaction()!.hash); - return contract; + let contractAddress: string | ethers.Addressable; + if (receipt?.to) { + // long-zero address + contractAddress = receipt.to; + } else { + // evm address + contractAddress = contract.target; + } + + return new ethers.Contract(contractAddress, contractJson.abi, wallet); }; // The main difference between this and deployContractWithEthers is that this does not re-init the contract with the deployed address // and that results in the contract address coming in EVM Format instead of LongZero format - static deployContractWithEthersV2 = async (constructorArgs: any[] = [], contractJson, wallet) => { + static deployContractWithEthersV2 = async ( + constructorArgs: any[] = [], + contractJson: { abi: ethers.Interface | ethers.InterfaceAbi; bytecode: ethers.BytesLike | { object: string } }, + wallet: ethers.Wallet, + ) => { const factory = new ethers.ContractFactory(contractJson.abi, contractJson.bytecode, wallet); const contract = await factory.deploy(...constructorArgs); await contract.waitForDeployment(); @@ -134,15 +150,15 @@ export class Utils { }; static createHTS = async ( - tokenName, - symbol, - adminAccount, - initialSupply, - abi, - associatedAccounts, - owner, - servicesNode, - requestId, + tokenName: string, + symbol: string, + adminAccount: AliasAccount, + initialSupply: number, + abi: ethers.InterfaceAbi | ethers.Interface, + associatedAccounts: AliasAccount[], + owner: AliasAccount, + servicesNode: ServicesClient, + requestId?: string, ) => { const htsResult = await servicesNode.createHTS({ tokenName, @@ -156,31 +172,31 @@ export class Utils { for (const account of associatedAccounts) { await servicesNode.associateHTSToken( account.accountId, - htsResult.receipt.tokenId, + htsResult.receipt.tokenId!, account.privateKey, htsResult.client, requestId, ); - await servicesNode.approveHTSToken(account.accountId, htsResult.receipt.tokenId, htsResult.client, requestId); + await servicesNode.approveHTSToken(account.accountId, htsResult.receipt.tokenId!, htsResult.client, requestId); } // Setup initial balance of token owner account await servicesNode.transferHTSToken( owner.accountId, - htsResult.receipt.tokenId, + htsResult.receipt.tokenId!, initialSupply, - htsResult.client, + htsResult.client.operatorAccountId!, requestId, ); - const evmAddress = Utils.idToEvmAddress(htsResult.receipt.tokenId.toString()); + const evmAddress = Utils.idToEvmAddress(htsResult.receipt.tokenId!.toString()); return new ethers.Contract(evmAddress, abi, owner.wallet); }; - static add0xPrefix = (num) => { + static add0xPrefix = (num: string) => { return num.startsWith('0x') ? num : '0x' + num; }; - static gasOptions = async (requestId, gasLimit = 1_500_000) => { + static gasOptions = async (requestId: string, gasLimit = 1_500_000) => { const relay: RelayClient = global.relay; return { gasLimit: gasLimit, @@ -260,14 +276,14 @@ export class Utils { * * @param {MirrorClient} mirrorNode The mirror node client. * @param {AliasAccount} creator The creator account for the alias. - * @param {string} requestDetails The request details used for logging. + * @param {string} requestId The unique identifier for the request. * @param {string} balanceInTinyBar The initial balance for the alias account in tiny bars. Defaults to 10 HBAR. * @returns {Promise} A promise resolving to the created alias account. */ static readonly createAliasAccount = async ( mirrorNode: MirrorClient, creator: AliasAccount, - requestDetails: RequestDetails, + requestId: string, balanceInTinyBar: string = '1000000000', //10 HBAR ): Promise => { const signer = creator.wallet; @@ -282,7 +298,7 @@ export class Utils { value: accountBalance, }); - const mirrorNodeAccount = (await mirrorNode.get(`/accounts/${address}`, requestDetails)).account; + const mirrorNodeAccount = (await mirrorNode.get(`/accounts/${address}`, requestId)).account; const accountId = AccountId.fromString(mirrorNodeAccount); const client: ServicesClient = new ServicesClient( process.env.HEDERA_NETWORK!, @@ -316,7 +332,7 @@ export class Utils { const account = await Utils.createAliasAccount( mirrorNode, initialAccount, - requestDetails, + requestDetails.requestId, initialAmountInTinyBar, ); global.logger.trace( diff --git a/packages/ws-server/tests/acceptance/index.spec.ts b/packages/ws-server/tests/acceptance/index.spec.ts index 836d2f5b89..b35a9be4c0 100644 --- a/packages/ws-server/tests/acceptance/index.spec.ts +++ b/packages/ws-server/tests/acceptance/index.spec.ts @@ -36,6 +36,7 @@ import ServicesClient from '@hashgraph/json-rpc-server/tests/clients/servicesCli import { Utils } from '@hashgraph/json-rpc-server/tests/helpers/utils'; import { AliasAccount } from '@hashgraph/json-rpc-server/tests/types/AliasAccount'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; +import { Server } from 'node:http'; dotenv.config({ path: path.resolve(__dirname, '../../../.env') }); const testLogger = pino({ @@ -65,8 +66,6 @@ describe('RPC Server Acceptance Tests', function () { this.timeout(240 * 1000); // 240 seconds const requestDetails = new RequestDetails({ requestId: 'rpc_batch1Test', ipAddress: '0.0.0.0' }); - let relayServer; // Relay Server - let socketServer; global.servicesNode = new ServicesClient( NETWORK, OPERATOR_ID, @@ -75,8 +74,6 @@ describe('RPC Server Acceptance Tests', function () { ); global.mirrorNode = new MirrorClient(MIRROR_NODE_URL, logger.child({ name: `mirror-node-test-client` })); global.relay = new RelayClient(RELAY_URL, logger.child({ name: `relay-test-client` })); - global.relayServer = relayServer; - global.socketServer = socketServer; global.logger = logger; before(async () => { @@ -141,10 +138,12 @@ describe('RPC Server Acceptance Tests', function () { //stop relay logger.info('Stop relay'); + const relayServer: Server = global.relayServer; if (relayServer !== undefined) { relayServer.close(); } + const socketServer: Server = global.socketServer; if (process.env.TEST_WS_SERVER === 'true' && socketServer !== undefined) { socketServer.close(); } @@ -172,7 +171,7 @@ describe('RPC Server Acceptance Tests', function () { // start local relay, relay instance in local should not be running logger.info(`Start relay on port ${constants.RELAY_PORT}`); - relayServer = app.listen({ port: constants.RELAY_PORT }); + const relayServer = app.listen({ port: constants.RELAY_PORT }); if (process.env.TEST_WS_SERVER === 'true') { logger.info(`Start ws-server on port ${constants.WEB_SOCKET_PORT}`); From 6ee4195a32664ff52eee8ccd21ee38ff8b86e1f7 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Wed, 18 Sep 2024 16:19:10 +0300 Subject: [PATCH 37/48] fix: metricService.spec.ts Signed-off-by: Victor Yanev --- .../metricService/metricService.spec.ts | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/relay/tests/lib/services/metricService/metricService.spec.ts b/packages/relay/tests/lib/services/metricService/metricService.spec.ts index aaa1f0b10f..2334dc0d5a 100644 --- a/packages/relay/tests/lib/services/metricService/metricService.spec.ts +++ b/packages/relay/tests/lib/services/metricService/metricService.spec.ts @@ -31,11 +31,12 @@ import { Utils } from '../../../../src/utils'; import constants from '../../../../src/lib/constants'; import HbarLimit from '../../../../src/lib/hbarlimiter'; import { MirrorNodeClient, SDKClient } from '../../../../src/lib/clients'; -import { calculateTxRecordChargeAmount, getRequestId } from '../../../helpers'; +import { calculateTxRecordChargeAmount } from '../../../helpers'; import MetricService from '../../../../src/lib/services/metricService/metricService'; import { CacheService } from '../../../../src/lib/services/cacheService/cacheService'; -import { IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../../../../src/lib/types/events'; +import { IExecuteQueryEventPayload, IExecuteTransactionEventPayload } from '../../../../src/lib/types'; import { Hbar, Long, Status, Client, AccountId, TransactionRecord, TransactionRecordQuery } from '@hashgraph/sdk'; +import { RequestDetails } from '../../../../src/lib/types'; config({ path: resolve(__dirname, '../../../test.env') }); const registry = new Registry(); @@ -50,6 +51,7 @@ describe('Metric Service', function () { let metricService: MetricService; let mirrorNodeClient: MirrorNodeClient; + const requestDetails = new RequestDetails({ requestId: 'metricServiceTest', ipAddress: '0.0.0.0' }); const mockedTxFee = 36900000; const operatorAccountId = `0.0.1022`; const mockedCallerName = 'caller_name'; @@ -157,10 +159,10 @@ describe('Metric Service', function () { const mockedExecuteTransactionEventPayload: IExecuteTransactionEventPayload = { transactionId: mockedTransactionId, callerName: mockedCallerName, - requestId: getRequestId(), txConstructorName: mockedConstructorName, operatorAccountId, interactingEntity: mockedInteractingEntity, + requestDetails, }; it('Should execute captureTransactionMetrics() by retrieving transaction record from MIRROR NODE client', async () => { @@ -178,14 +180,14 @@ describe('Metric Service', function () { expect(originalBudget - updatedBudget).to.eq(mockedTxFee); // validate cost metrics - // @ts-ignore - const costMetricObject = (await metricService.getCostMetric().get()).values.find( + const costMetricObject = (await metricService['consensusNodeClientHistogramCost'].get()).values.find( (metric) => metric.metricName === metricHistogramCostSumTitle, - )!; - expect(costMetricObject.metricName).to.eq(metricHistogramCostSumTitle); - expect(costMetricObject.labels.caller).to.eq(mockedCallerName); - expect(costMetricObject.labels.interactingEntity).to.eq(mockedInteractingEntity); - expect(costMetricObject.value).to.eq(mockedTxFee); + ); + expect(costMetricObject).to.not.be.undefined; + expect(costMetricObject!.metricName).to.eq(metricHistogramCostSumTitle); + expect(costMetricObject!.labels.caller).to.eq(mockedCallerName); + expect(costMetricObject!.labels.interactingEntity).to.eq(mockedInteractingEntity); + expect(costMetricObject!.value).to.eq(mockedTxFee); }); it('Should execute captureTransactionMetrics() by retrieving transaction record from CONSENSUS NODE client', async () => { @@ -209,7 +211,7 @@ describe('Metric Service', function () { // validate cost metric // @ts-ignore - const metricObjects = await metricService.getCostMetric().get(); + const metricObjects = await metricService['consensusNodeClientHistogramCost'].get(); const txRecordFeeMetricObject = metricObjects.values.find((metric) => { return ( metric.labels.mode === constants.EXECUTION_MODE.RECORD && metric.metricName === metricHistogramCostSumTitle @@ -234,7 +236,7 @@ describe('Metric Service', function () { // validate gas metric // @ts-ignore - const gasMetricObject = (await metricService.getGasFeeMetric().get()).values.find( + const gasMetricObject = (await metricService['consensusNodeClientHistogramGasFee'].get()).values.find( (metric) => metric.metricName === metricHistogramGasFeeSumTitle, )!; @@ -273,7 +275,7 @@ describe('Metric Service', function () { // validate cost metric // @ts-ignore - const metricObjects = await metricService.getCostMetric().get(); + const metricObjects = await metricService['consensusNodeClientHistogramCost'].get(); const txRecordFeeMetricObject = metricObjects.values.find((metric) => { return ( metric.labels.mode === constants.EXECUTION_MODE.RECORD && metric.metricName === metricHistogramCostSumTitle @@ -298,7 +300,7 @@ describe('Metric Service', function () { // validate gas metric // @ts-ignore - const gasMetricObject = (await metricService.getGasFeeMetric().get()).values.find( + const gasMetricObject = (await metricService['consensusNodeClientHistogramGasFee'].get()).values.find( (metric) => metric.metricName === metricHistogramGasFeeSumTitle, )!; @@ -322,7 +324,7 @@ describe('Metric Service', function () { gasUsed: mockedGasUsed, interactingEntity: mockedInteractingEntity, status: 'SUCCESS', - requestDetails: getRequestId(), + requestDetails, }; it('should execute addExpenseAndCaptureMetrics() to capture metrics in HBAR limiter and metric registry', async () => { const originalBudget = hbarLimiter.getRemainingBudget(); @@ -336,7 +338,7 @@ describe('Metric Service', function () { // validate cost metrics // @ts-ignore - const costMetricObject = (await metricService.getCostMetric().get()).values.find( + const costMetricObject = (await metricService['consensusNodeClientHistogramCost'].get()).values.find( (metric) => metric.metricName === metricHistogramCostSumTitle, )!; expect(costMetricObject.metricName).to.eq(metricHistogramCostSumTitle); @@ -346,7 +348,7 @@ describe('Metric Service', function () { // validate gas metric // @ts-ignore - const gasMetricObject = (await metricService.getGasFeeMetric().get()).values.find( + const gasMetricObject = (await metricService['consensusNodeClientHistogramGasFee'].get()).values.find( (metric) => metric.metricName === metricHistogramGasFeeSumTitle, )!; @@ -373,7 +375,7 @@ describe('Metric Service', function () { // validate cost metrics // @ts-ignore - const costMetricObject = (await metricService.getCostMetric().get()).values.find( + const costMetricObject = (await metricService['consensusNodeClientHistogramCost'].get()).values.find( (metric) => metric.metricName === metricHistogramCostSumTitle, )!; expect(costMetricObject.metricName).to.eq(metricHistogramCostSumTitle); @@ -383,7 +385,7 @@ describe('Metric Service', function () { // validate gas metric // @ts-ignore - const gasMetricObject = (await metricService.getGasFeeMetric().get()).values.find( + const gasMetricObject = (await metricService['consensusNodeClientHistogramGasFee'].get()).values.find( (metric) => metric.metricName === metricHistogramGasFeeSumTitle, )!; From 34be5aedec36951ab51b9bc6295e55f0ae142273 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Wed, 18 Sep 2024 16:39:24 +0300 Subject: [PATCH 38/48] fix: mirrorNodeClient Signed-off-by: Victor Yanev --- .../relay/src/lib/clients/mirrorNodeClient.ts | 12 +- packages/relay/src/lib/eth.ts | 16 +- .../src/lib/services/debugService/index.ts | 2 +- .../relay/tests/lib/mirrorNodeClient.spec.ts | 275 +++++++++++------- 4 files changed, 188 insertions(+), 117 deletions(-) diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index 0f9d2f30a1..fdef1c5e9a 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -464,8 +464,8 @@ export class MirrorNodeClient { public async getAccountLatestEthereumTransactionsByTimestamp( idOrAliasOrEvmAddress: string, timestampTo: string, - numberOfTransactions: number = 1, requestDetails: RequestDetails, + numberOfTransactions: number = 1, ) { const queryParamObject = {}; this.setQueryParam( @@ -1040,7 +1040,7 @@ export class MirrorNodeClient { ); } - public async getTransactionById(transactionId: string, nonce: number | undefined, requestDetails: RequestDetails) { + public async getTransactionById(transactionId: string, requestDetails: RequestDetails, nonce?: number) { const formattedId = formatTransactionId(transactionId); if (formattedId == null) { return formattedId; @@ -1072,7 +1072,7 @@ export class MirrorNodeClient { if (e instanceof SDKClientError && e.isContractRevertExecuted()) { const transactionId = e.message.match(constants.TRANSACTION_ID_REGEX); if (transactionId) { - const tx = await this.getTransactionById(transactionId[0], undefined, requestDetails); + const tx = await this.getTransactionById(transactionId[0], requestDetails); if (tx === null) { this.logger.error(`${requestDetails.formattedRequestId} Transaction failed with null result`); @@ -1148,9 +1148,9 @@ export class MirrorNodeClient { */ public async resolveEntityType( entityIdentifier: string, - searchableTypes: any[] = [constants.TYPE_CONTRACT, constants.TYPE_ACCOUNT, constants.TYPE_TOKEN], callerName: string, requestDetails: RequestDetails, + searchableTypes: any[] = [constants.TYPE_CONTRACT, constants.TYPE_ACCOUNT, constants.TYPE_TOKEN], retries?: number, ) { const cachedLabel = `${constants.CACHE_KEY.RESOLVE_ENTITY_TYPE}_${entityIdentifier}`; @@ -1263,7 +1263,7 @@ export class MirrorNodeClient { let result; for (let i = 0; i < repeatCount; i++) { try { - result = await this[methodName](...args, requestDetails); + result = await this[methodName](...args); } catch (e: any) { // note: for some methods, it will throw 404 not found error as the record is not yet recorded in mirror-node // if error is 404, `result` would be assigned as null for it to not break out the loop. @@ -1320,7 +1320,7 @@ export class MirrorNodeClient { const transactionRecords = await this.repeatedRequest( this.getTransactionById.name, - [transactionId, 0], + [transactionId, requestDetails, 0], this.MIRROR_NODE_REQUEST_RETRY_COUNT, requestDetails, ); diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 43a6e21143..0bc4347437 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -1132,12 +1132,10 @@ export class EthImpl implements Eth { } try { - const result = await this.mirrorNodeClient.resolveEntityType( - address, - [constants.TYPE_CONTRACT, constants.TYPE_TOKEN], - EthImpl.ethGetCode, - requestDetails, - ); + const result = await this.mirrorNodeClient.resolveEntityType(address, EthImpl.ethGetCode, requestDetails, [ + constants.TYPE_CONTRACT, + constants.TYPE_TOKEN, + ]); if (result) { if (result?.type === constants.TYPE_TOKEN) { this.logger.trace(`${requestIdPrefix} Token redirect case, return redirectBytecode`); @@ -1595,7 +1593,7 @@ export class EthImpl implements Eth { const contractResult = await this.mirrorNodeClient.repeatedRequest( this.mirrorNodeClient.getContractResult.name, - [formattedId], + [formattedId, requestDetails], this.mirrorNodeClient.getMirrorNodeRequestRetryCount(), requestDetails, ); @@ -1963,9 +1961,9 @@ export class EthImpl implements Eth { const entity = await this.mirrorNodeClient.resolveEntityType( address, - searchableTypes, EthImpl.ethGetCode, requestDetails, + searchableTypes, 0, ); let resolvedAddress = address; @@ -2413,8 +2411,8 @@ export class EthImpl implements Eth { const ethereumTransactions = await this.mirrorNodeClient.getAccountLatestEthereumTransactionsByTimestamp( address, block.timestamp.to, - 2, requestDetails, + 2, ); if (ethereumTransactions == null || ethereumTransactions.transactions.length === 0) { return EthImpl.zeroHex; diff --git a/packages/relay/src/lib/services/debugService/index.ts b/packages/relay/src/lib/services/debugService/index.ts index 136cf6382a..6a57d47bbf 100644 --- a/packages/relay/src/lib/services/debugService/index.ts +++ b/packages/relay/src/lib/services/debugService/index.ts @@ -215,9 +215,9 @@ export class DebugService implements IDebugService { const entity = await this.mirrorNodeClient.resolveEntityType( address, - types, EthImpl.debugTraceTransaction, requestDetails, + types, ); if ( diff --git a/packages/relay/tests/lib/mirrorNodeClient.spec.ts b/packages/relay/tests/lib/mirrorNodeClient.spec.ts index 923d97323e..f016084f4e 100644 --- a/packages/relay/tests/lib/mirrorNodeClient.spec.ts +++ b/packages/relay/tests/lib/mirrorNodeClient.spec.ts @@ -25,17 +25,20 @@ import { Registry } from 'prom-client'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); import { MirrorNodeClient } from '../../src/lib/clients'; import constants from '../../src/lib/constants'; -import axios from 'axios'; +import axios, { AxiosInstance } from 'axios'; import MockAdapter from 'axios-mock-adapter'; import { getRequestId, mockData, random20BytesAddress } from '../helpers'; + const registry = new Registry(); import pino from 'pino'; import { ethers } from 'ethers'; import { predefined, MirrorNodeClientError } from '../../src'; import { CacheService } from '../../src/lib/services/cacheService/cacheService'; -import { RequestDetails } from '../../src/lib/types'; +import { MirrorNodeTransactionRecord, RequestDetails } from '../../src/lib/types'; import { SDKClientError } from '../../src/lib/errors/SDKClientError'; +import { BigNumber } from 'bignumber.js'; + const logger = pino(); const noTransactions = '?transactions=false'; const requestDetails = new RequestDetails({ requestId: getRequestId(), ipAddress: '0.0.0.0' }); @@ -43,7 +46,7 @@ const requestDetails = new RequestDetails({ requestId: getRequestId(), ipAddress describe('MirrorNodeClient', async function () { this.timeout(20000); - let instance, mock, mirrorNodeInstance, cacheService; + let instance: AxiosInstance, mock: MockAdapter, mirrorNodeInstance: MirrorNodeClient, cacheService: CacheService; before(() => { // mock axios @@ -67,7 +70,7 @@ describe('MirrorNodeClient', async function () { beforeEach(() => { mock = new MockAdapter(instance); - mirrorNodeInstance.cacheService.clear(); + cacheService.clear(requestDetails); }); describe('handleError', async () => { @@ -80,12 +83,13 @@ describe('MirrorNodeClient', async function () { let error = new Error('test error'); error['response'] = 'test error'; - const result = await mirrorNodeInstance.handleError( + const result = mirrorNodeInstance.handleError( error, CONTRACT_CALL_ENDPOINT, CONTRACT_CALL_ENDPOINT, code, 'POST', + requestDetails, ); expect(result).to.equal(null); }); @@ -96,7 +100,14 @@ describe('MirrorNodeClient', async function () { try { let error = new Error('test error'); error['response'] = 'test error'; - await mirrorNodeInstance.handleError(error, CONTRACT_CALL_ENDPOINT, CONTRACT_CALL_ENDPOINT, code, 'POST'); + mirrorNodeInstance.handleError( + error, + CONTRACT_CALL_ENDPOINT, + CONTRACT_CALL_ENDPOINT, + code, + 'POST', + requestDetails, + ); expect.fail('should have thrown an error'); } catch (e: any) { expect(e.message).to.equal('test error'); @@ -121,7 +132,7 @@ describe('MirrorNodeClient', async function () { it('it should have a `request` method ', async () => { expect(mirrorNodeInstance).to.exist; - expect(mirrorNodeInstance.request).to.exist; + expect(mirrorNodeInstance['request']).to.exist; }); it('`restUrl` is exposed and correct', async () => { @@ -138,14 +149,14 @@ describe('MirrorNodeClient', async function () { it('Can extract the account number out of an account pagination next link url', async () => { const accountId = '0.0.123'; const url = `/api/v1/accounts/${accountId}?limit=100×tamp=lt:1682455406.562695326`; - const extractedAccountId = mirrorNodeInstance.extractAccountIdFromUrl(url); + const extractedAccountId = mirrorNodeInstance.extractAccountIdFromUrl(url, requestDetails); expect(extractedAccountId).to.eq(accountId); }); it('Can extract the evm address out of an account pagination next link url', async () => { const evmAddress = '0x583031d1113ad414f02576bd6afa5bbdf935b7d9'; const url = `/api/v1/accounts/${evmAddress}?limit=100×tamp=lt:1682455406.562695326`; - const extractedEvmAddress = mirrorNodeInstance.extractAccountIdFromUrl(url); + const extractedEvmAddress = mirrorNodeInstance.extractAccountIdFromUrl(url, requestDetails); expect(extractedEvmAddress).to.eq(evmAddress); }); @@ -228,7 +239,7 @@ describe('MirrorNodeClient', async function () { }, }); - const result = await mirrorNodeInstance.get('accounts'); + const result = await mirrorNodeInstance.get('accounts', 'accounts', requestDetails); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.exist; @@ -248,7 +259,7 @@ describe('MirrorNodeClient', async function () { }; mock.onPost('contracts/call', { foo: 'bar' }).reply(200, mockResult); - const result = await mirrorNodeInstance.post('contracts/call', { foo: 'bar' }); + const result = await mirrorNodeInstance.post('contracts/call', { foo: 'bar' }, 'contracts/call', requestDetails); expect(result).to.exist; expect(result.result).to.exist; expect(result.result).to.eq(mockResult.result); @@ -256,7 +267,7 @@ describe('MirrorNodeClient', async function () { it('call to non-existing REST route returns 404', async () => { try { - expect(await mirrorNodeInstance.get('non-existing-route')).to.throw(); + expect(await mirrorNodeInstance.get('non-existing-route', 'non-existing-route', requestDetails)).to.throw; } catch (err: any) { expect(err.statusCode).to.eq(404); } @@ -275,7 +286,7 @@ describe('MirrorNodeClient', async function () { }, }); - const result = await mirrorNodeInstance.getAccount(alias); + const result = await mirrorNodeInstance.getAccount(alias, requestDetails); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -300,7 +311,7 @@ describe('MirrorNodeClient', async function () { }, }); - const result = await mirrorNodeInstance.getBlock(hash); + const result = await mirrorNodeInstance.getBlock(hash, requestDetails); expect(result).to.exist; expect(result.count).equal(3); expect(result.number).equal(77); @@ -323,7 +334,7 @@ describe('MirrorNodeClient', async function () { }, }); - const result = await mirrorNodeInstance.getBlock(number); + const result = await mirrorNodeInstance.getBlock(number, requestDetails); expect(result).to.exist; expect(result.count).equal(3); expect(result.number).equal(77); @@ -348,7 +359,7 @@ describe('MirrorNodeClient', async function () { .onGet(`blocks?block.number=${number}&limit=100&order=asc`) .reply(200, { blocks: [block], links: { next: null } }); - const result = await mirrorNodeInstance.getBlocks(`[Request ID: testId]`, number); + const result = await mirrorNodeInstance.getBlocks(requestDetails, number); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -364,7 +375,7 @@ describe('MirrorNodeClient', async function () { .onGet(`blocks?timestamp=${timestamp}&limit=100&order=asc`) .reply(200, { blocks: [block], links: { next: null } }); - const result = await mirrorNodeInstance.getBlocks(`[Request ID: testId]`, undefined, timestamp); + const result = await mirrorNodeInstance.getBlocks(requestDetails, undefined, timestamp); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -376,21 +387,21 @@ describe('MirrorNodeClient', async function () { it('`getContract`', async () => { mock.onGet(`contracts/${mockData.contractEvmAddress}`).reply(200, mockData.contract); - const result = await mirrorNodeInstance.getContract(mockData.contractEvmAddress); + const result = await mirrorNodeInstance.getContract(mockData.contractEvmAddress, requestDetails); expect(result).to.exist; expect(result.contract_id).equal('0.0.2000'); }); it('`getContract` not found', async () => { mock.onGet(`contracts/${mockData.contractEvmAddress}`).reply(404, mockData.notFound); - const result = await mirrorNodeInstance.getContract(mockData.contractEvmAddress); + const result = await mirrorNodeInstance.getContract(mockData.contractEvmAddress, requestDetails); expect(result).to.be.null; }); it('`getAccount`', async () => { mock.onGet(`accounts/${mockData.accountEvmAddress}${noTransactions}`).reply(200, mockData.account); - const result = await mirrorNodeInstance.getAccount(mockData.accountEvmAddress); + const result = await mirrorNodeInstance.getAccount(mockData.accountEvmAddress, requestDetails); expect(result).to.exist; expect(result.account).equal('0.0.1014'); }); @@ -399,7 +410,7 @@ describe('MirrorNodeClient', async function () { const evmAddress = '0x00000000000000000000000000000000000003f6'; mock.onGet(`accounts/${evmAddress}${noTransactions}`).reply(404, mockData.notFound); - const result = await mirrorNodeInstance.getAccount(evmAddress); + const result = await mirrorNodeInstance.getAccount(evmAddress, requestDetails); expect(result).to.be.null; }); @@ -408,7 +419,7 @@ describe('MirrorNodeClient', async function () { mock.onGet(`accounts/${evmAddress}${noTransactions}`).reply(500, { error: 'unexpected error' }); let errorRaised = false; try { - await mirrorNodeInstance.getAccount(evmAddress); + await mirrorNodeInstance.getAccount(evmAddress, requestDetails); } catch (error: any) { errorRaised = true; expect(error.message).to.equal(`Request failed with status code 500`); @@ -421,7 +432,7 @@ describe('MirrorNodeClient', async function () { mock.onGet(`accounts/${invalidAddress}${noTransactions}`).reply(400); let errorRaised = false; try { - await mirrorNodeInstance.getAccount(invalidAddress); + await mirrorNodeInstance.getAccount(invalidAddress, requestDetails); } catch (error: any) { errorRaised = true; expect(error.message).to.equal(`Request failed with status code 400`); @@ -432,7 +443,7 @@ describe('MirrorNodeClient', async function () { it('`getTokenById`', async () => { mock.onGet(`tokens/${mockData.tokenId}`).reply(200, mockData.token); - const result = await mirrorNodeInstance.getTokenById(mockData.tokenId); + const result = await mirrorNodeInstance.getTokenById(mockData.tokenId, requestDetails); expect(result).to.exist; expect(result.token_id).equal('0.0.13312'); }); @@ -441,7 +452,7 @@ describe('MirrorNodeClient', async function () { const tokenId = '0.0.132'; mock.onGet(`accounts/${tokenId}${noTransactions}`).reply(404, mockData.notFound); - const result = await mirrorNodeInstance.getTokenById(tokenId); + const result = await mirrorNodeInstance.getTokenById(tokenId, requestDetails); expect(result).to.be.null; }); @@ -520,7 +531,7 @@ describe('MirrorNodeClient', async function () { const transactionId = '0.0.10-167654-000123456'; mock.onGet(`contracts/results/${transactionId}`).reply(200, detailedContractResult); - const result = await mirrorNodeInstance.getContractResult(transactionId); + const result = await mirrorNodeInstance.getContractResult(transactionId, requestDetails); expect(result).to.exist; expect(result.contract_id).equal(detailedContractResult.contract_id); expect(result.to).equal(detailedContractResult.to); @@ -531,7 +542,7 @@ describe('MirrorNodeClient', async function () { const hash = '0x4a563af33c4871b51a8b108aa2fe1dd5280a30dfb7236170ae5e5e7957eb6391'; mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); - const result = await mirrorNodeInstance.getContractResult(hash); + const result = await mirrorNodeInstance.getContractResult(hash, requestDetails); expect(result).to.exist; expect(result.contract_id).equal(detailedContractResult.contract_id); expect(result.to).equal(detailedContractResult.to); @@ -541,10 +552,10 @@ describe('MirrorNodeClient', async function () { it('`getContractResults` by hash using cache', async () => { const hash = '0x07cad7b827375d10d73af57b6a3e84353645fdb1305ea58ff52dda53ec640533'; mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); - const resultBeforeCached = await mirrorNodeInstance.getContractResult(hash); + const resultBeforeCached = await mirrorNodeInstance.getContractResult(hash, requestDetails); mock.onGet(`contracts/results/${hash}`).reply(400, null); - const resultAfterCached = await mirrorNodeInstance.getContractResult(hash); + const resultAfterCached = await mirrorNodeInstance.getContractResult(hash, requestDetails); expect(resultBeforeCached).to.eq(resultAfterCached); }); @@ -553,7 +564,7 @@ describe('MirrorNodeClient', async function () { const hash = '0x4a563af33c4871b51a8b108aa2fe1dd5280a30dfb7236170ae5e5e7957eb6399'; mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); - const result = await mirrorNodeInstance.getContractResultWithRetry(hash); + const result = await mirrorNodeInstance.getContractResultWithRetry(hash, requestDetails); expect(result).to.exist; expect(result.contract_id).equal(detailedContractResult.contract_id); expect(result.to).equal(detailedContractResult.to); @@ -567,7 +578,7 @@ describe('MirrorNodeClient', async function () { mock.onGet(`contracts/results/${hash}`).replyOnce(200, { ...detailedContractResult, transaction_index: undefined }); mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); - const result = await mirrorNodeInstance.getContractResultWithRetry(hash); + const result = await mirrorNodeInstance.getContractResultWithRetry(hash, requestDetails); expect(result).to.exist; expect(result.contract_id).equal(detailedContractResult.contract_id); expect(result.to).equal(detailedContractResult.to); @@ -583,7 +594,7 @@ describe('MirrorNodeClient', async function () { .replyOnce(200, { ...detailedContractResult, transaction_index: undefined, block_number: undefined }); mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); - const result = await mirrorNodeInstance.getContractResultWithRetry(hash); + const result = await mirrorNodeInstance.getContractResultWithRetry(hash, requestDetails); expect(result).to.exist; expect(result.contract_id).equal(detailedContractResult.contract_id); expect(result.to).equal(detailedContractResult.to); @@ -598,7 +609,7 @@ describe('MirrorNodeClient', async function () { mock.onGet(`contracts/results/${hash}`).replyOnce(200, { ...detailedContractResult, block_number: undefined }); mock.onGet(`contracts/results/${hash}`).reply(200, detailedContractResult); - const result = await mirrorNodeInstance.getContractResultWithRetry(hash); + const result = await mirrorNodeInstance.getContractResultWithRetry(hash, requestDetails); expect(result).to.exist; expect(result.contract_id).equal(detailedContractResult.contract_id); expect(result.to).equal(detailedContractResult.to); @@ -612,7 +623,7 @@ describe('MirrorNodeClient', async function () { .onGet(`contracts/results?limit=100&order=asc`) .reply(200, { results: [detailedContractResult], links: { next: null } }); - const result = await mirrorNodeInstance.getContractResults(); + const result = await mirrorNodeInstance.getContractResults(requestDetails); expect(result).to.exist; expect(result.links).to.not.exist; expect(result.length).to.gt(0); @@ -631,8 +642,8 @@ describe('MirrorNodeClient', async function () { error_message: null, from: '0x0000000000000000000000000000000000001f41', function_parameters: '0x0707', - gas_limit: 9223372036854775807, - gas_used: 9223372036854775806, + gas_limit: BigNumber('9223372036854775807'), + gas_used: BigNumber('9223372036854775806'), timestamp: '987654.000123456', to: '0x0000000000000000000000000000000000001389', }; @@ -642,7 +653,7 @@ describe('MirrorNodeClient', async function () { .onGet(`contracts/${contractId}/results?limit=100&order=asc`) .reply(200, { results: [contractResult], links: { next: null } }); - const result = await mirrorNodeInstance.getContractResultsByAddress(contractId); + const result = await mirrorNodeInstance.getContractResultsByAddress(contractId, requestDetails); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -659,7 +670,7 @@ describe('MirrorNodeClient', async function () { .onGet(`contracts/${address}/results?limit=100&order=asc`) .reply(200, { results: [contractResult], links: { next: null } }); - const result = await mirrorNodeInstance.getContractResultsByAddress(address); + const result = await mirrorNodeInstance.getContractResultsByAddress(address, requestDetails); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -676,7 +687,7 @@ describe('MirrorNodeClient', async function () { .onGet(`contracts/${address}/results?limit=1&order=desc`) .reply(200, { results: [contractResult], links: { next: null } }); - const result = await mirrorNodeInstance.getLatestContractResultsByAddress(address, undefined, 1); + const result = await mirrorNodeInstance.getLatestContractResultsByAddress(address, undefined, 1, requestDetails); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -693,7 +704,12 @@ describe('MirrorNodeClient', async function () { .onGet(`contracts/${address}/results?timestamp=lte:987654.000123456&limit=2&order=desc`) .reply(200, { results: [contractResult], links: { next: null } }); - const result = await mirrorNodeInstance.getLatestContractResultsByAddress(address, '987654.000123456', 2); + const result = await mirrorNodeInstance.getLatestContractResultsByAddress( + address, + '987654.000123456', + 2, + requestDetails, + ); expect(result).to.exist; expect(result.links).to.exist; expect(result.links.next).to.equal(null); @@ -717,7 +733,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(); + const results = await mirrorNodeInstance.getContractResultsLogs(requestDetails); expect(results).to.exist; expect(results.length).to.gt(0); const firstResult = results[0]; @@ -729,7 +745,7 @@ describe('MirrorNodeClient', async function () { it('`getContractResultsLogsByAddress` ', async () => { mock.onGet(`contracts/${log.address}/results/logs?limit=100&order=asc`).reply(200, { logs: [log] }); - const results = await mirrorNodeInstance.getContractResultsLogsByAddress(log.address); + const results = await mirrorNodeInstance.getContractResultsLogsByAddress(log.address, requestDetails); expect(results).to.exist; expect(results.length).to.gt(0); const firstResult = results[0]; @@ -738,7 +754,7 @@ describe('MirrorNodeClient', async function () { expect(firstResult.index).equal(log.index); }); it('`getContractResultsLogsByAddress` with ZeroAddress ', async () => { - const results = await mirrorNodeInstance.getContractResultsLogsByAddress(ethers.ZeroAddress); + const results = await mirrorNodeInstance.getContractResultsLogsByAddress(ethers.ZeroAddress, requestDetails); expect(results).to.exist; expect(results.length).to.eq(0); expect(results).to.deep.equal([]); @@ -753,6 +769,7 @@ describe('MirrorNodeClient', async function () { const result = await mirrorNodeInstance.getContractStateByAddressAndSlot( contractAddress, defaultCurrentContractState.state[0].slot, + requestDetails, ); expect(result).to.exist; @@ -771,6 +788,7 @@ describe('MirrorNodeClient', async function () { await mirrorNodeInstance.getContractStateByAddressAndSlot( contractAddress + '1', defaultCurrentContractState.state[0].slot, + requestDetails, ), ).to.throw(); } catch (error) { @@ -789,6 +807,7 @@ describe('MirrorNodeClient', async function () { await mirrorNodeInstance.getContractStateByAddressAndSlot( contractAddress, defaultCurrentContractState.state[0].slot + '1', + requestDetails, ), ).to.throw(); } catch (error) { @@ -801,7 +820,7 @@ describe('MirrorNodeClient', async function () { const incorrectAddress = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ed'; try { - expect(await mirrorNodeInstance.getContractResultsLogsByAddress(incorrectAddress)).to.throw(); + expect(await mirrorNodeInstance.getContractResultsLogsByAddress(incorrectAddress, requestDetails)).to.throw; } catch (err: any) { expect(err).to.exist; } @@ -810,7 +829,7 @@ describe('MirrorNodeClient', async function () { it('`getBlocks` by number', async () => { mock.onGet(`blocks?limit=1&order=desc`).reply(200, block); - const result = await mirrorNodeInstance.getLatestBlock(); + const result = await mirrorNodeInstance.getLatestBlock(requestDetails); expect(result).to.exist; expect(result.count).equal(block.count); expect(result.number).equal(block.number); @@ -824,7 +843,7 @@ describe('MirrorNodeClient', async function () { }); for (let i = 0; i < 3; i++) { - const result = await mirrorNodeInstance.getBlock(hash); + const result = await mirrorNodeInstance.getBlock(hash, requestDetails); expect(result).to.exist; expect(result.hash).equal(hash); expect(result.number).equal(77); @@ -848,7 +867,7 @@ describe('MirrorNodeClient', async function () { mock.onGet(`network/exchangerate`).reply(200, exchangerate); - const result = await mirrorNodeInstance.getNetworkExchangeRate(getRequestId()); + const result = await mirrorNodeInstance.getNetworkExchangeRate(requestDetails); expect(result).to.exist; expect(result.current_rate).to.exist; expect(result.next_rate).to.exist; @@ -865,13 +884,17 @@ describe('MirrorNodeClient', async function () { mock.onGet(`accounts/${mockData.contractEvmAddress}${noTransactions}`).reply(200, mockData.account); mock.onGet(`tokens/${mockData.contractEvmAddress}`).reply(404, mockData.notFound); - const entityType = await mirrorNodeInstance.resolveEntityType(mockData.contractEvmAddress); + const entityType = await mirrorNodeInstance.resolveEntityType( + mockData.contractEvmAddress, + 'mirrorNodeClientTest', + requestDetails, + ); expect(entityType).to.exist; expect(entityType).to.have.property('type'); expect(entityType).to.have.property('entity'); - expect(entityType.type).to.eq('contract'); - expect(entityType.entity).to.have.property('contract_id'); - expect(entityType.entity.contract_id).to.eq(mockData.contract.contract_id); + expect(entityType!.type).to.eq('contract'); + expect(entityType!.entity).to.have.property('contract_id'); + expect(entityType!.entity.contract_id).to.eq(mockData.contract.contract_id); }); it('returns `account` when CONTRACTS and TOKENS endpoint returns 404 and ACCOUNTS endpoint returns a result', async () => { @@ -879,13 +902,17 @@ describe('MirrorNodeClient', async function () { mock.onGet(`accounts/${mockData.accountEvmAddress}${noTransactions}`).reply(200, mockData.account); mock.onGet(`tokens/${mockData.tokenId}`).reply(404, mockData.notFound); - const entityType = await mirrorNodeInstance.resolveEntityType(mockData.accountEvmAddress); + const entityType = await mirrorNodeInstance.resolveEntityType( + mockData.accountEvmAddress, + 'mirrorNodeClientTest', + requestDetails, + ); expect(entityType).to.exist; expect(entityType).to.have.property('type'); expect(entityType).to.have.property('entity'); - expect(entityType.type).to.eq('account'); - expect(entityType.entity).to.have.property('account'); - expect(entityType.entity.account).to.eq(mockData.account.account); + expect(entityType!.type).to.eq('account'); + expect(entityType!.entity).to.have.property('account'); + expect(entityType!.entity.account).to.eq(mockData.account.account); }); it('returns `token` when CONTRACTS and ACCOUNTS endpoints returns 404 and TOKEN endpoint returns a result', async () => { @@ -893,12 +920,16 @@ describe('MirrorNodeClient', async function () { mock.onGet(`accounts/${notFoundAddress}${noTransactions}`).reply(404, mockData.notFound); mock.onGet(`tokens/${mockData.tokenId}`).reply(200, mockData.token); - const entityType = await mirrorNodeInstance.resolveEntityType(mockData.tokenLongZero); + const entityType = await mirrorNodeInstance.resolveEntityType( + mockData.tokenLongZero, + 'mirrorNodeClientTest', + requestDetails, + ); expect(entityType).to.exist; expect(entityType).to.have.property('type'); expect(entityType).to.have.property('entity'); - expect(entityType.type).to.eq('token'); - expect(entityType.entity.token_id).to.eq(mockData.tokenId); + expect(entityType!.type).to.eq('token'); + expect(entityType!.entity.token_id).to.eq(mockData.tokenId); }); it('returns null when CONTRACTS and ACCOUNTS endpoints return 404', async () => { @@ -906,7 +937,11 @@ describe('MirrorNodeClient', async function () { mock.onGet(`accounts/${notFoundAddress}${noTransactions}`).reply(404, mockData.notFound); mock.onGet(`tokens/${notFoundAddress}`).reply(404, mockData.notFound); - const entityType = await mirrorNodeInstance.resolveEntityType(notFoundAddress); + const entityType = await mirrorNodeInstance.resolveEntityType( + notFoundAddress, + 'mirrorNodeClientTest', + requestDetails, + ); expect(entityType).to.be.null; }); @@ -914,31 +949,35 @@ describe('MirrorNodeClient', async function () { mock.onGet(`contracts/${mockData.tokenId}`).reply(404, mockData.notFound); mock.onGet(`tokens/${mockData.tokenId}`).reply(200, mockData.token); - const entityType = await mirrorNodeInstance.resolveEntityType(mockData.tokenLongZero, [ - constants.TYPE_CONTRACT, - constants.TYPE_TOKEN, - ]); + const entityType = await mirrorNodeInstance.resolveEntityType( + mockData.tokenLongZero, + 'mirrorNodeClientTest', + requestDetails, + [constants.TYPE_CONTRACT, constants.TYPE_TOKEN], + ); expect(entityType).to.exist; expect(entityType).to.have.property('type'); expect(entityType).to.have.property('entity'); - expect(entityType.type).to.eq('token'); - expect(entityType.entity.token_id).to.eq(mockData.tokenId); + expect(entityType!.type).to.eq('token'); + expect(entityType!.entity.token_id).to.eq(mockData.tokenId); }); it('does not call mirror node tokens API when token is not long zero type', async () => { mock.onGet(`contracts/${mockData.contractEvmAddress}`).reply(200, mockData.contract); mock.onGet(`tokens/${mockData.tokenId}`).reply(404, mockData.notFound); - const entityType = await mirrorNodeInstance.resolveEntityType(mockData.contractEvmAddress, [ - constants.TYPE_CONTRACT, - constants.TYPE_TOKEN, - ]); + const entityType = await mirrorNodeInstance.resolveEntityType( + mockData.contractEvmAddress, + 'mirrorNodeClientTest', + requestDetails, + [constants.TYPE_CONTRACT, constants.TYPE_TOKEN], + ); expect(entityType).to.exist; expect(entityType).to.have.property('type'); expect(entityType).to.have.property('entity'); - expect(entityType.type).to.eq('contract'); - expect(entityType.entity).to.have.property('contract_id'); - expect(entityType.entity.contract_id).to.eq(mockData.contract.contract_id); + expect(entityType!.type).to.eq('contract'); + expect(entityType!.entity).to.have.property('contract_id'); + expect(entityType!.entity.contract_id).to.eq(mockData.contract.contract_id); }); }); @@ -995,7 +1034,7 @@ describe('MirrorNodeClient', async function () { it('should be able to fetch transaction by transaction id', async () => { mock.onGet(`transactions/${defaultTransactionIdFormatted}`).reply(200, defaultTransaction); - const transaction = await mirrorNodeInstance.getTransactionById(defaultTransactionId); + const transaction = await mirrorNodeInstance.getTransactionById(defaultTransactionId, requestDetails); expect(transaction).to.exist; expect(transaction.transactions.length).to.equal(defaultTransaction.transactions.length); }); @@ -1004,7 +1043,7 @@ describe('MirrorNodeClient', async function () { mock .onGet(`transactions/${defaultTransactionIdFormatted}?nonce=1`) .reply(200, defaultTransaction.transactions[1]); - const transaction = await mirrorNodeInstance.getTransactionById(defaultTransactionId, 1); + const transaction = await mirrorNodeInstance.getTransactionById(defaultTransactionId, requestDetails, 1); expect(transaction).to.exist; expect(transaction.transaction_id).to.equal(defaultTransaction.transactions[1].transaction_id); expect(transaction.result).to.equal(defaultTransaction.transactions[1].result); @@ -1012,7 +1051,7 @@ describe('MirrorNodeClient', async function () { it('should fail to fetch transaction by wrong transaction id', async () => { mock.onGet(`transactions/${invalidTransactionId}`).reply(404, mockData.notFound); - const transaction = await mirrorNodeInstance.getTransactionById(invalidTransactionId); + const transaction = await mirrorNodeInstance.getTransactionById(invalidTransactionId, requestDetails); expect(transaction).to.be.null; }); @@ -1023,7 +1062,7 @@ describe('MirrorNodeClient', async function () { }); mock.onGet(`transactions/${transactionId}`).reply(200, null); - const result = await mirrorNodeInstance.getContractRevertReasonFromTransaction(error, getRequestId()); + const result = await mirrorNodeInstance.getContractRevertReasonFromTransaction(error, requestDetails); expect(result).to.be.null; }); @@ -1034,7 +1073,7 @@ describe('MirrorNodeClient', async function () { }); mock.onGet(`transactions/${transactionId}`).reply(200, []); - const result = await mirrorNodeInstance.getContractRevertReasonFromTransaction(error, getRequestId()); + const result = await mirrorNodeInstance.getContractRevertReasonFromTransaction(error, requestDetails); expect(result).to.be.null; }); @@ -1045,7 +1084,7 @@ describe('MirrorNodeClient', async function () { }); mock.onGet(`transactions/${transactionId}`).reply(200, defaultTransaction); - const result = await mirrorNodeInstance.getContractRevertReasonFromTransaction(error, getRequestId()); + const result = await mirrorNodeInstance.getContractRevertReasonFromTransaction(error, requestDetails); expect(result).to.eq('INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE'); }); }); @@ -1082,7 +1121,12 @@ describe('MirrorNodeClient', async function () { }, }); - const results = await mirrorNodeInstance.getPaginatedResults('results', 'results', 'genericResults'); + const results = await mirrorNodeInstance.getPaginatedResults( + 'results', + 'results', + 'genericResults', + requestDetails, + ); expect(results).to.exist; expect(results).to.deep.equal(mockedResults); @@ -1092,7 +1136,12 @@ describe('MirrorNodeClient', async function () { const pages = 5; const mockedResults = mockPages(pages); - const results = await mirrorNodeInstance.getPaginatedResults('results?page=0', 'results', 'genericResults'); + const results = await mirrorNodeInstance.getPaginatedResults( + 'results?page=0', + 'results', + 'genericResults', + requestDetails, + ); expect(results).to.exist; expect(results.length).to.eq(pages); @@ -1104,7 +1153,7 @@ describe('MirrorNodeClient', async function () { mockPages(pages); try { - await mirrorNodeInstance.getPaginatedResults('results?page=0', 'results', 'genericResults'); + await mirrorNodeInstance.getPaginatedResults('results?page=0', 'results', 'genericResults', requestDetails); expect.fail('should have thrown an error'); } catch (e: any) { const errorRef = predefined.PAGINATION_MAX(0); // reference error for all properties except message @@ -1122,7 +1171,11 @@ describe('MirrorNodeClient', async function () { it('if the method returns an immediate result it is called only once', async () => { mock.onGet(uri).reply(200, mockData.account); - const result = await mirrorNodeInstance.repeatedRequest('getAccount', [mockData.accountEvmAddress], 3); + const result = await mirrorNodeInstance.repeatedRequest( + 'getAccount', + [mockData.accountEvmAddress, requestDetails], + 3, + ); expect(result).to.exist; expect(result.account).equal('0.0.1014'); @@ -1133,7 +1186,11 @@ describe('MirrorNodeClient', async function () { // Return data on the second call mock.onGet(uri).replyOnce(404, mockData.notFound).onGet(uri).reply(200, mockData.account); - const result = await mirrorNodeInstance.repeatedRequest('getAccount', [mockData.accountEvmAddress], 3); + const result = await mirrorNodeInstance.repeatedRequest( + 'getAccount', + [mockData.accountEvmAddress, requestDetails], + 3, + ); expect(result).to.exist; expect(result.account).equal('0.0.1014'); @@ -1141,7 +1198,11 @@ describe('MirrorNodeClient', async function () { }); it('method is repeated the specified number of times if no result is found', async () => { - const result = await mirrorNodeInstance.repeatedRequest('getAccount', [mockData.accountEvmAddress], 3); + const result = await mirrorNodeInstance.repeatedRequest( + 'getAccount', + [mockData.accountEvmAddress, requestDetails], + 3, + ); expect(result).to.be.null; expect(mock.history.get.length).to.eq(3); // is called three times }); @@ -1158,7 +1219,11 @@ describe('MirrorNodeClient', async function () { .onGet(uri) .reply(200, mockData.account); - const result = await mirrorNodeInstance.repeatedRequest('getAccount', [mockData.accountEvmAddress], 3); + const result = await mirrorNodeInstance.repeatedRequest( + 'getAccount', + [mockData.accountEvmAddress, requestDetails], + 3, + ); expect(result).to.be.null; expect(mock.history.get.length).to.eq(3); // is called three times }); @@ -1197,9 +1262,9 @@ describe('MirrorNodeClient', async function () { const transactionRecordMetrics = await mirrorNodeInstance.getTransactionRecordMetrics( mockedTransactionId, mockedCallerName, - getRequestId(), mockedConstructorName, operatorAcocuntId, + requestDetails, ); expect(transactionRecordMetrics.transactionFee).to.eq(mockedTxFee); @@ -1212,9 +1277,9 @@ describe('MirrorNodeClient', async function () { await mirrorNodeInstance.getTransactionRecordMetrics( mockedTransactionId, mockedCallerName, - getRequestId(), mockedConstructorName, operatorAcocuntId, + requestDetails, ); expect.fail('should have thrown an error'); @@ -1267,7 +1332,7 @@ describe('MirrorNodeClient', async function () { }; const transactionFee = mirrorNodeInstance.getTransferAmountSumForAccount( - mockedMirrorNodeTransactionRecord.transactions[0], + mockedMirrorNodeTransactionRecord.transactions[0] as MirrorNodeTransactionRecord, accountIdA, ); expect(transactionFee).to.eq(expectedTxFeeForAccountIdA); @@ -1329,6 +1394,7 @@ describe('MirrorNodeClient', async function () { const transactions = await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp( evmAddress, timestamp, + requestDetails, ); expect(transactions).to.be.null; }); @@ -1338,6 +1404,7 @@ describe('MirrorNodeClient', async function () { const transactions = await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp( evmAddress, timestamp, + requestDetails, ); expect(transactions).to.exist; expect(transactions.transactions.length).to.equal(0); @@ -1348,6 +1415,7 @@ describe('MirrorNodeClient', async function () { const transactions = await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp( evmAddress, timestamp, + requestDetails, ); expect(transactions).to.exist; expect(transactions.transactions.length).to.equal(1); @@ -1358,6 +1426,7 @@ describe('MirrorNodeClient', async function () { const transactions = await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp( evmAddress, timestamp, + requestDetails, 2, ); expect(transactions).to.exist; @@ -1369,7 +1438,7 @@ describe('MirrorNodeClient', async function () { mock.onGet(transactionPath(address, 1)).reply(500, { error: 'unexpected error' }); let errorRaised = false; try { - await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp(address, timestamp); + await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp(address, timestamp, requestDetails); } catch (error: any) { errorRaised = true; expect(error.message).to.equal(`Request failed with status code 500`); @@ -1382,7 +1451,11 @@ describe('MirrorNodeClient', async function () { mock.onGet(transactionPath(invalidAddress, 1)).reply(400, null); let errorRaised = false; try { - await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp(invalidAddress, timestamp); + await mirrorNodeInstance.getAccountLatestEthereumTransactionsByTimestamp( + invalidAddress, + timestamp, + requestDetails, + ); } catch (error: any) { errorRaised = true; expect(error.message).to.equal(`Request failed with status code 400`); @@ -1397,24 +1470,24 @@ describe('MirrorNodeClient', async function () { it('should return false for contract for non existing contract', async () => { mock.onGet(contractPath).reply(404, mockData.notFound); - const isValid = await mirrorNodeInstance.isValidContract(evmAddress); + const isValid = await mirrorNodeInstance.isValidContract(evmAddress, requestDetails); expect(isValid).to.be.false; }); it('should return valid for contract for existing contract', async () => { mock.onGet(contractPath).reply(200, mockData.contract); - const isValid = await mirrorNodeInstance.isValidContract(evmAddress); + const isValid = await mirrorNodeInstance.isValidContract(evmAddress, requestDetails); expect(isValid).to.be.true; }); it('should return valid for contract from cache on additional calls', async () => { mock.onGet(contractPath).reply(200, mockData.contract); - let isValid = await mirrorNodeInstance.isValidContract(evmAddress); + let isValid = await mirrorNodeInstance.isValidContract(evmAddress, requestDetails); expect(isValid).to.be.true; // verify that the cache is used mock.onGet(contractPath).reply(404, mockData.notFound); - isValid = await mirrorNodeInstance.isValidContract(evmAddress); + isValid = await mirrorNodeInstance.isValidContract(evmAddress, requestDetails); expect(isValid).to.be.true; }); }); @@ -1425,20 +1498,20 @@ describe('MirrorNodeClient', async function () { it('should fail to fetch contract for non existing contract', async () => { mock.onGet(contractPath).reply(404, mockData.notFound); - const id = await mirrorNodeInstance.getContractId(evmAddress); + const id = await mirrorNodeInstance.getContractId(evmAddress, requestDetails); expect(id).to.not.exist; }); it('should fetch id for existing contract', async () => { mock.onGet(contractPath).reply(200, mockData.contract); - const id = await mirrorNodeInstance.getContractId(evmAddress); + const id = await mirrorNodeInstance.getContractId(evmAddress, requestDetails); expect(id).to.exist; expect(id).to.be.equal(mockData.contract.contract_id); }); it('should fetch contract for existing contract from cache on additional calls', async () => { mock.onGet(contractPath).reply(200, mockData.contract); - let id = await mirrorNodeInstance.getContractId(evmAddress); + let id = await mirrorNodeInstance.getContractId(evmAddress, requestDetails); expect(id).to.exist; expect(id).to.be.equal(mockData.contract.contract_id); @@ -1454,26 +1527,26 @@ describe('MirrorNodeClient', async function () { it('should fail to fetch blocks for empty network', async () => { mock.onGet(blockPath).reply(404, mockData.notFound); - const earlierBlock = await mirrorNodeInstance.getEarliestBlock(); + const earlierBlock = await mirrorNodeInstance.getEarliestBlock(requestDetails); expect(earlierBlock).to.not.exist; }); it('should fetch block for existing valid network', async () => { mock.onGet(blockPath).reply(200, { blocks: [mockData.blocks.blocks[0]] }); - const earlierBlock = await mirrorNodeInstance.getEarliestBlock(); + const earlierBlock = await mirrorNodeInstance.getEarliestBlock(requestDetails); expect(earlierBlock).to.exist; expect(earlierBlock.name).to.be.equal(mockData.blocks.blocks[0].name); }); it('should fetch block for valid network from cache on additional calls', async () => { mock.onGet(blockPath).reply(200, { blocks: [mockData.blocks.blocks[0]] }); - let earlierBlock = await mirrorNodeInstance.getEarliestBlock(); + let earlierBlock = await mirrorNodeInstance.getEarliestBlock(requestDetails); expect(earlierBlock).to.exist; expect(earlierBlock.name).to.be.equal(mockData.blocks.blocks[0].name); // verify that the cache is used mock.onGet(blockPath).reply(404, mockData.notFound); - earlierBlock = await mirrorNodeInstance.getEarliestBlock(); + earlierBlock = await mirrorNodeInstance.getEarliestBlock(requestDetails); expect(earlierBlock).to.exist; expect(earlierBlock.name).to.be.equal(mockData.blocks.blocks[0].name); }); From 88f85ce7e00fdd131fdd4f198892e82f8f98fe21 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Wed, 18 Sep 2024 16:40:47 +0300 Subject: [PATCH 39/48] fix: validators.ts Signed-off-by: Victor Yanev --- packages/ws-server/src/utils/validators.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ws-server/src/utils/validators.ts b/packages/ws-server/src/utils/validators.ts index 3aa6b4492a..154bd956da 100644 --- a/packages/ws-server/src/utils/validators.ts +++ b/packages/ws-server/src/utils/validators.ts @@ -39,9 +39,9 @@ const validateIsContractOrTokenAddress = async ( ) => { const isContractOrToken = await mirrorNodeClient.resolveEntityType( address, - [constants.TYPE_CONTRACT, constants.TYPE_TOKEN], constants.METHODS.ETH_SUBSCRIBE, requestDetails, + [constants.TYPE_CONTRACT, constants.TYPE_TOKEN], ); if (!isContractOrToken) { throw new JsonRpcError( From 90ad401e265b6c03de95e73fc1b36e7001831637 Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Wed, 18 Sep 2024 16:43:47 +0300 Subject: [PATCH 40/48] fix: hapiService.spec.ts Signed-off-by: Victor Yanev --- packages/relay/tests/lib/hapiService.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/relay/tests/lib/hapiService.spec.ts b/packages/relay/tests/lib/hapiService.spec.ts index 1aeed76d36..856d26d04e 100644 --- a/packages/relay/tests/lib/hapiService.spec.ts +++ b/packages/relay/tests/lib/hapiService.spec.ts @@ -29,6 +29,7 @@ import { SDKClient } from '../../src/lib/clients'; import HbarLimit from '../../src/lib/hbarlimiter'; import HAPIService from '../../src/lib/services/hapiService/hapiService'; import { CacheService } from '../../src/lib/services/cacheService/cacheService'; +import { RequestDetails } from '../../src/lib/types'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); @@ -43,6 +44,7 @@ describe('HAPI Service', async function () { let hapiService: HAPIService; const errorStatus = 50; + const requestDetails = new RequestDetails({ requestId: 'hapiService.spec.ts', ipAddress: '0.0.0.0' }); this.beforeAll(() => { const duration: number = 60000; @@ -147,7 +149,7 @@ describe('HAPI Service', async function () { const oldClientInstance = hapiService.getMainClientInstance(); const oldSDKInstance = hapiService.getSDKClient(); - hbarLimiter.addExpense(costAmount, Date.now()); + hbarLimiter.addExpense(costAmount, Date.now(), requestDetails); hapiService.decrementErrorCounter(errorStatus); const newSDKInstance = hapiService.getSDKClient(); From 42ed1a8e71a5196563772faacc9dc8ffbbcdefdc Mon Sep 17 00:00:00 2001 From: Victor Yanev Date: Wed, 18 Sep 2024 16:52:43 +0300 Subject: [PATCH 41/48] fix: precheck.spec.ts and hbarSpendingPlanRepository.spec.ts Signed-off-by: Victor Yanev --- packages/relay/tests/lib/precheck.spec.ts | 51 ++++++++++--------- .../hbarSpendingPlanRepository.spec.ts | 12 ++--- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/packages/relay/tests/lib/precheck.spec.ts b/packages/relay/tests/lib/precheck.spec.ts index 16b6a477d2..f316531c22 100644 --- a/packages/relay/tests/lib/precheck.spec.ts +++ b/packages/relay/tests/lib/precheck.spec.ts @@ -34,12 +34,14 @@ import constants from '../../src/lib/constants'; import { JsonRpcError, predefined } from '../../src'; import { CacheService } from '../../src/lib/services/cacheService/cacheService'; import { ONE_TINYBAR_IN_WEI_HEX } from './eth/eth-config'; +import { RequestDetails } from '../../src/lib/types'; const logger = pino(); const limitOrderPostFix = '?order=desc&limit=1'; const transactionsPostFix = '?transactions=false'; describe('Precheck', async function () { + const requestDetails = new RequestDetails({ requestId: 'precheckTest', ipAddress: '0.0.0.0' }); const txWithMatchingChainId = '0x02f87482012a0485a7a358200085a7a3582000832dc6c09400000000000000000000000000000000000003f78502540be40080c001a006f4cd8e6f84b76a05a5c1542a08682c928108ef7163d9c1bf1f3b636b1cd1fba032097cbf2dda17a2dcc40f62c97964d9d930cdce2e8a9df9a8ba023cda28e4ad'; const parsedTxWithMatchingChainId = ethers.Transaction.from(txWithMatchingChainId); @@ -141,7 +143,7 @@ describe('Precheck', async function () { describe('chainId', async function () { it('should pass for matching chainId', async function () { try { - precheck.chainId(parsedTxWithMatchingChainId); + precheck.chainId(parsedTxWithMatchingChainId, requestDetails); } catch (e: any) { expect(e).to.not.exist; } @@ -149,7 +151,7 @@ describe('Precheck', async function () { it('should pass when chainId=0x0', async function () { try { - precheck.chainId(parsedtxWithChainId0x0); + precheck.chainId(parsedtxWithChainId0x0, requestDetails); } catch (e: any) { expect(e).to.not.exist; } @@ -157,7 +159,7 @@ describe('Precheck', async function () { it('should not pass for non-matching chainId', async function () { try { - precheck.chainId(parsedTxWithNonMatchingChainId); + precheck.chainId(parsedTxWithNonMatchingChainId, requestDetails); expectedError(); } catch (e: any) { expect(e).to.exist; @@ -191,7 +193,7 @@ describe('Precheck', async function () { ? `Transaction gas limit '${gasLimit}' exceeds max gas per sec limit '${constants.MAX_GAS_PER_SEC}'` : `Transaction gas limit provided '${gasLimit}' is insufficient of intrinsic gas required `; try { - await precheck.gasLimit(parsedTx); + await precheck.gasLimit(parsedTx, requestDetails); expectedError(); } catch (e: any) { console.log(e); @@ -214,7 +216,7 @@ describe('Precheck', async function () { const parsedTx = ethers.Transaction.from(signed); try { - await precheck.gasLimit(parsedTx); + precheck.gasLimit(parsedTx, requestDetails); } catch (e: any) { expect(e).to.not.exist; } @@ -243,12 +245,12 @@ describe('Precheck', async function () { }); it('should pass for gas price gt to required gas price', async function () { - const result = precheck.gasPrice(parsedTxWithMatchingChainId, 10); + const result = precheck.gasPrice(parsedTxWithMatchingChainId, 10, requestDetails); expect(result).to.not.exist; }); it('should pass for gas price equal to required gas price', async function () { - const result = precheck.gasPrice(parsedTxWithMatchingChainId, defaultGasPrice); + const result = precheck.gasPrice(parsedTxWithMatchingChainId, defaultGasPrice, requestDetails); expect(result).to.not.exist; }); @@ -273,6 +275,7 @@ describe('Precheck', async function () { const result = precheck.gasPrice( parsedDeterministicDeploymentTransaction, 100 * constants.TINYBAR_TO_WEIBAR_COEF, + requestDetails, ); expect(result).to.not.exist; }); @@ -280,7 +283,7 @@ describe('Precheck', async function () { it('should not pass for gas price not enough', async function () { const minGasPrice = 1000 * constants.TINYBAR_TO_WEIBAR_COEF; try { - precheck.gasPrice(parsedTxWithMatchingChainId, minGasPrice); + precheck.gasPrice(parsedTxWithMatchingChainId, minGasPrice, requestDetails); expectedError(); } catch (e: any) { expect(e).to.exist; @@ -292,7 +295,7 @@ describe('Precheck', async function () { it('should pass for gas price not enough but within buffer', async function () { const adjustedGasPrice = parsedTxGasPrice + Number(constants.GAS_PRICE_TINY_BAR_BUFFER); - precheck.gasPrice(parsedTxWithMatchingChainId, adjustedGasPrice); + precheck.gasPrice(parsedTxWithMatchingChainId, adjustedGasPrice, requestDetails); }); }); @@ -312,7 +315,7 @@ describe('Precheck', async function () { }; try { - await precheck.balance(parsedTransaction, account); + precheck.balance(parsedTransaction, account, requestDetails); expectedError(); } catch (e: any) { expect(e).to.exist; @@ -325,7 +328,7 @@ describe('Precheck', async function () { const account = null; try { - await precheck.balance(parsedTransaction, account); + precheck.balance(parsedTransaction, account, requestDetails); expectedError(); } catch (e: any) { expect(e).to.exist; @@ -342,7 +345,7 @@ describe('Precheck', async function () { }, }; - const result = await precheck.balance(parsedTransaction, account); + const result = precheck.balance(parsedTransaction, account, requestDetails); expect(result).to.not.exist; }); @@ -354,7 +357,7 @@ describe('Precheck', async function () { }, }; - const result = await precheck.balance(parsedTransaction, account); + const result = precheck.balance(parsedTransaction, account, requestDetails); expect(result).to.not.exist; }); @@ -366,7 +369,7 @@ describe('Precheck', async function () { }, }; - const result = await precheck.balance(parsedTransaction, account); + const result = precheck.balance(parsedTransaction, account, requestDetails); expect(result).to.not.exist; }); @@ -378,7 +381,7 @@ describe('Precheck', async function () { }, }; - const result = await precheck.balance(parsedTransaction, account); + const result = precheck.balance(parsedTransaction, account, requestDetails); expect(result).to.not.exist; }); @@ -390,7 +393,7 @@ describe('Precheck', async function () { }, }; - const result = await precheck.balance(parsedTransaction, account); + const result = precheck.balance(parsedTransaction, account, requestDetails); expect(result).to.not.exist; }); }); @@ -412,7 +415,7 @@ describe('Precheck', async function () { mock.onGet(`accounts/${parsedTx.from}${limitOrderPostFix}`).reply(200, mirrorAccount); try { - await precheck.nonce(parsedTx, mirrorAccount.ethereum_nonce); + precheck.nonce(parsedTx, mirrorAccount.ethereum_nonce, requestDetails); expectedError(); } catch (e: any) { expect(e).to.eql(predefined.NONCE_TOO_LOW(parsedTx.nonce, mirrorAccount.ethereum_nonce)); @@ -429,7 +432,7 @@ describe('Precheck', async function () { mock.onGet(`accounts/${parsedTx.from}${limitOrderPostFix}`).reply(200, mirrorAccount); - await precheck.nonce(parsedTx, mirrorAccount.ethereum_nonce); + precheck.nonce(parsedTx, mirrorAccount.ethereum_nonce, requestDetails); }); }); @@ -450,9 +453,8 @@ describe('Precheck', async function () { it(`should fail for missing account`, async function () { mock.onGet(`accounts/${parsedTx.from}${transactionsPostFix}`).reply(404, mockData.notFound); - const requestId = `eth_precheckTest`; try { - await precheck.verifyAccount(parsedTx, requestId); + await precheck.verifyAccount(parsedTx, requestDetails); expectedError(); } catch (e: any) { expect(e).to.exist; @@ -463,8 +465,7 @@ describe('Precheck', async function () { it(`should not fail for matched account`, async function () { mock.onGet(`accounts/${parsedTx.from}${transactionsPostFix}`).reply(200, mirrorAccount); - const requestId = `eth_precheckTest`; - const account = await precheck.verifyAccount(parsedTx, requestId); + const account = await precheck.verifyAccount(parsedTx, requestDetails); expect(account.ethereum_nonce).to.eq(defaultNonce); }); @@ -574,7 +575,7 @@ describe('Precheck', async function () { it('should accept legacy transactions', async () => { const signedLegacy = await signTransaction(defaultTx); - expect(precheck.transactionType(ethers.Transaction.from(signedLegacy))).not.to.throw; + expect(() => precheck.transactionType(ethers.Transaction.from(signedLegacy), requestDetails)).not.to.throw; }); it('should accept London transactions', async () => { @@ -584,7 +585,7 @@ describe('Precheck', async function () { maxPriorityFeePerGas: defaultGasPrice, maxFeePerGas: defaultGasPrice, }); - expect(precheck.transactionType(ethers.Transaction.from(signedLondon))).not.to.throw; + expect(() => precheck.transactionType(ethers.Transaction.from(signedLondon), requestDetails)).not.to.throw; }); it('should reject Cancun transactions', async () => { @@ -596,7 +597,7 @@ describe('Precheck', async function () { maxFeePerBlobGas: defaultGasPrice, blobVersionedHashes: [blobVersionedHash], }); - precheck.transactionType(ethers.Transaction.from(signedCancun)); + precheck.transactionType(ethers.Transaction.from(signedCancun), requestDetails); } catch (e) { error = e; } diff --git a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts index b7716f58f9..3daa0883a0 100644 --- a/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts +++ b/packages/relay/tests/lib/repositories/hbarLimiter/hbarSpendingPlanRepository.spec.ts @@ -238,22 +238,22 @@ describe('HbarSpendingPlanRepository', function () { it('resets all spent today entries', async () => { const plans: IDetailedHbarSpendingPlan[] = []; for (const subscriptionType of Object.values(SubscriptionType)) { - const createdPlan = await repository.create(subscriptionType); + const createdPlan = await repository.create(subscriptionType, requestDetails); plans.push(createdPlan); const amount = 50 * plans.length; - await repository.addAmountToSpentToday(createdPlan.id, amount); - await expect(repository.getSpentToday(createdPlan.id)).to.eventually.equal(amount); + await repository.addAmountToSpentToday(createdPlan.id, amount, requestDetails); + await expect(repository.getSpentToday(createdPlan.id, requestDetails)).to.eventually.equal(amount); } - await repository.resetAllSpentTodayEntries(); + await repository.resetAllSpentTodayEntries(requestDetails); for (const plan of plans) { - await expect(repository.getSpentToday(plan.id)).to.eventually.equal(0); + await expect(repository.getSpentToday(plan.id, requestDetails)).to.eventually.equal(0); } }); it('does not throw an error if no spent today keys exist', async () => { - await expect(repository.resetAllSpentTodayEntries()).to.not.be.rejected; + await expect(repository.resetAllSpentTodayEntries(requestDetails)).to.not.be.rejected; }); }); From e787c324a0f74ba2dc07737220c87bf1f6672ad7 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 19 Sep 2024 14:32:15 +0300 Subject: [PATCH 42/48] fixes hbar calculation in rpc batch1 test Signed-off-by: Konstantina Blazhukova --- packages/server/tests/acceptance/rpc_batch1.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index bbc4be2e51..833128fc0b 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -75,7 +75,9 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const GAS_PRICE_TOO_LOW = '0x1'; const GAS_PRICE_REF = '0x123456'; const ONE_TINYBAR = Utils.add0xPrefix(Utils.toHex(Constants.TINYBAR_TO_WEIBAR_COEF)); - const TEN_HBAR = Utils.add0xPrefix(new Hbar(10).toTinybars().mul(Constants.TINYBAR_TO_WEIBAR_COEF).toString(16)); + const TEN_HBAR = Utils.add0xPrefix( + (BigInt(new Hbar(10).toTinybars().toString()) * BigInt(Constants.TINYBAR_TO_WEIBAR_COEF)).toString(16), + ); const sendRawTransaction = relay.sendRawTransaction; /** From 2ebff411d608fc9f7744287e8ecfbb3dc688a260 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 19 Sep 2024 15:36:27 +0300 Subject: [PATCH 43/48] Fixes precompile test Signed-off-by: Konstantina Blazhukova --- .../tests/acceptance/htsPrecompile/precompileCalls.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts b/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts index f89a03c653..60e217b7a6 100644 --- a/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts +++ b/packages/server/tests/acceptance/htsPrecompile/precompileCalls.spec.ts @@ -391,7 +391,7 @@ describe('@precompile-calls Tests for eth_call with HTS', async function () { expect(customFees.fixedFees).to.exist; expect(customFees.fixedFees.length).to.eq(1); expect(customFees.fixedFees[0].amount).to.exist; - expect(customFees.fixedFees[0].amount.toString()).to.eq(Hbar.fromTinybars(1).toString()); + expect(customFees.fixedFees[0].amount.toString()).to.eq('1'); expect(customFees.fixedFees[0].tokenId).to.eq(ZERO_HEX); expect(customFees.fixedFees[0].feeCollector).to.exist; expect(customFees.fixedFees[0].feeCollector.toLowerCase()).to.eq(accounts[0].address.toLowerCase()); From 66aeeb6503b482380c49588866649cbecf9fba85 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 19 Sep 2024 16:08:57 +0300 Subject: [PATCH 44/48] Fixes unit tests after adding requestDetails as required Signed-off-by: Konstantina Blazhukova --- .../lib/eth/eth_getBlockByNumber.spec.ts | 28 ++++++++++++++++--- .../relay/tests/lib/eth/eth_getLogs.spec.ts | 18 +++++++++--- .../tests/lib/eth/eth_getStorageAt.spec.ts | 13 +++++++-- ..._getTransactionByBlockHashAndIndex.spec.ts | 15 ++++++++-- ...etTransactionByBlockNumberAndIndex.spec.ts | 15 ++++++++-- .../lib/eth/eth_getTransactionCount.spec.ts | 27 ++++++++++++------ .../tests/lib/services/eth/filter.spec.ts | 21 +++++++------- 7 files changed, 102 insertions(+), 35 deletions(-) diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index b0a4e1f664..4b29f5272a 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -23,11 +23,11 @@ import { expect, use } from 'chai'; import sinon from 'sinon'; import chaiAsPromised from 'chai-as-promised'; -import { predefined } from '../../../src'; +import { Eth, predefined } from '../../../src'; import { EthImpl } from '../../../src/lib/eth'; import { blockLogsBloom, defaultContractResults, defaultDetailedContractResults } from '../../helpers'; import { Block, Transaction } from '../../../src/lib/model'; -import { SDKClient } from '../../../src/lib/clients'; +import { MirrorNodeClient, SDKClient } from '../../../src/lib/clients'; import RelayAssertions from '../../assertions'; import constants from '../../../src/lib/constants'; import { hashNumber, numberTo0x } from '../../../dist/formatters'; @@ -74,6 +74,10 @@ import { import { generateEthTestEnv } from './eth-helpers'; import { fail } from 'assert'; import { RequestDetails } from '../../../src/lib/types'; +import MockAdapter from 'axios-mock-adapter'; +import HAPIService from '../../../src/lib/services/hapiService/hapiService'; +import { CacheService } from '../../../src/lib/services/cacheService/cacheService'; +import { Registry } from 'prom-client'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -85,8 +89,23 @@ let ethImplLowTransactionCount: EthImpl; describe('@ethGetBlockByNumber using MirrorNode', async function () { this.timeout(10000); - let { restMock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger, registry } = - generateEthTestEnv(true); + const { + restMock, + hapiServiceInstance, + ethImpl, + cacheService, + mirrorNodeInstance, + logger, + registry, + }: { + restMock: MockAdapter; + hapiServiceInstance: HAPIService; + ethImpl: Eth; + cacheService: CacheService; + mirrorNodeInstance: MirrorNodeClient; + logger: any; + registry: Registry; + } = generateEthTestEnv(true); const results = defaultContractResults.results; const TOTAL_GAS_USED = numberTo0x(results[0].gas_used + results[1].gas_used); @@ -204,6 +223,7 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { ethImpl.blockNumber, true, ethImpl, + [requestDetails], ); }); diff --git a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts index e804483558..d2cd1e264c 100644 --- a/packages/relay/tests/lib/eth/eth_getLogs.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getLogs.spec.ts @@ -59,6 +59,10 @@ import { import { ethers } from 'ethers'; import { generateEthTestEnv } from './eth-helpers'; import { RequestDetails } from '../../../src/lib/types'; +import MockAdapter from 'axios-mock-adapter'; +import HAPIService from '../../../src/lib/services/hapiService/hapiService'; +import { Eth } from '../../../src'; +import { CacheService } from '../../../src/lib/services/cacheService/cacheService'; dotenv.config({ path: path.resolve(__dirname, '../../test.env') }); use(chaiAsPromised); @@ -77,7 +81,13 @@ describe('@ethGetLogs using MirrorNode', async function () { to: '1651560395.060890949', }, }; - let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const { + restMock, + hapiServiceInstance, + ethImpl, + cacheService, + }: { restMock: MockAdapter; hapiServiceInstance: HAPIService; ethImpl: Eth; cacheService: CacheService } = + generateEthTestEnv(); const filteredLogs = { logs: [DEFAULT_LOGS.logs[0], DEFAULT_LOGS.logs[1]], }; @@ -110,14 +120,14 @@ describe('@ethGetLogs using MirrorNode', async function () { }); it('BLOCK_HASH filter timeouts and throws the expected error', async () => { - await ethGetLogsFailing(ethImpl, [BLOCK_HASH, null, null, null, null], (error: any) => { + await ethGetLogsFailing(ethImpl, [BLOCK_HASH, null, null, null, null, requestDetails], (error: any) => { expect(error.statusCode).to.equal(504); expect(error.message).to.eq('timeout of 10000ms exceeded'); }); }); it('address filter timeouts and throws the expected error', async () => { - await ethGetLogsFailing(ethImpl, [null, null, null, CONTRACT_ADDRESS_1, null], (error: any) => { + await ethGetLogsFailing(ethImpl, [null, null, null, CONTRACT_ADDRESS_1, null, requestDetails], (error: any) => { expect(error.statusCode).to.equal(504); expect(error.message).to.eq('timeout of 10000ms exceeded'); }); @@ -465,7 +475,7 @@ describe('@ethGetLogs using MirrorNode', async function () { restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, { blocks: [latestBlock] }); restMock.onGet('blocks/5').reply(200, DEFAULT_BLOCKS_RES); - await ethGetLogsFailing(ethImpl, [null, null, '0x5', null, null], (error: any) => { + await ethGetLogsFailing(ethImpl, [null, null, '0x5', null, null, requestDetails], (error: any) => { expect(error.code).to.equal(-32011); expect(error.message).to.equal('Provided toBlock parameter without specifying fromBlock'); }); diff --git a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts index 192429970c..4b5d5033b3 100644 --- a/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getStorageAt.spec.ts @@ -40,12 +40,15 @@ import { OLDER_BLOCK, BLOCK_HASH, } from './eth-config'; -import { predefined } from '../../../src'; +import { Eth, predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import { defaultDetailedContractResults } from '../../helpers'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; import { RequestDetails } from '../../../src/lib/types'; +import MockAdapter from 'axios-mock-adapter'; +import HAPIService from '../../../src/lib/services/hapiService/hapiService'; +import { CacheService } from '../../../src/lib/services/cacheService/cacheService'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -56,7 +59,13 @@ let currentMaxBlockRange: number; describe('@ethGetStorageAt eth_getStorageAt spec', async function () { this.timeout(10000); - let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const { + restMock, + hapiServiceInstance, + ethImpl, + cacheService, + }: { restMock: MockAdapter; hapiServiceInstance: HAPIService; ethImpl: Eth; cacheService: CacheService } = + generateEthTestEnv(); const requestDetails = new RequestDetails({ requestId: 'eth_getStorageAtTest', ipAddress: '0.0.0.0' }); function confirmResult(result: string) { expect(result).to.exist; diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts index 8c54b989c8..cfb59c429f 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockHashAndIndex.spec.ts @@ -24,7 +24,7 @@ import sinon from 'sinon'; import _ from 'lodash'; import chaiAsPromised from 'chai-as-promised'; -import { predefined } from '../../../src'; +import { Eth, predefined } from '../../../src'; import { defaultContractResults, defaultDetailedContractResults } from '../../helpers'; import { Transaction, Transaction1559, Transaction2930 } from '../../../src/lib/model'; import { SDKClient } from '../../../src/lib/clients'; @@ -44,6 +44,9 @@ import { } from './eth-config'; import { contractResultsByHashByIndexURL, generateEthTestEnv } from './eth-helpers'; import { RequestDetails } from '../../../src/lib/types'; +import MockAdapter from 'axios-mock-adapter'; +import HAPIService from '../../../src/lib/services/hapiService/hapiService'; +import { CacheService } from '../../../src/lib/services/cacheService/cacheService'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -63,7 +66,13 @@ function verifyAggregatedInfo(result: Transaction | null) { describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async function () { this.timeout(10000); - let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const { + restMock, + hapiServiceInstance, + ethImpl, + cacheService, + }: { restMock: MockAdapter; hapiServiceInstance: HAPIService; ethImpl: Eth; cacheService: CacheService } = + generateEthTestEnv(); const requestDetails = new RequestDetails({ requestId: 'eth_getTransactionByBlockHashAndIndexTest', @@ -125,7 +134,7 @@ describe('@ethGetTransactionByBlockHashAndIndex using MirrorNode', async functio .onGet(contractResultsByHashByIndexURL(randomBlock.hash, randomBlock.count)) .reply(200, defaultContractResultsWithNullableFrom); - const args = [randomBlock.hash, numberTo0x(randomBlock.count)]; + const args = [randomBlock.hash, numberTo0x(randomBlock.count), requestDetails]; const errMessage = "Cannot read properties of null (reading 'substring')"; await RelayAssertions.assertRejection( diff --git a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts index 9a67f4c57c..82c274e719 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionByBlockNumberAndIndex.spec.ts @@ -24,7 +24,7 @@ import sinon from 'sinon'; import * as _ from 'lodash'; import chaiAsPromised from 'chai-as-promised'; -import { predefined } from '../../../src'; +import { Eth, predefined } from '../../../src'; import { defaultContractResults, defaultDetailedContractResults } from '../../helpers'; import { Transaction } from '../../../src/lib/model'; import { SDKClient } from '../../../src/lib/clients'; @@ -44,6 +44,9 @@ import { } from './eth-config'; import { contractResultsByNumberByIndexURL, generateEthTestEnv } from './eth-helpers'; import { RequestDetails } from '../../../src/lib/types'; +import MockAdapter from 'axios-mock-adapter'; +import HAPIService from '../../../src/lib/services/hapiService/hapiService'; +import { CacheService } from '../../../src/lib/services/cacheService/cacheService'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -65,7 +68,13 @@ function verifyAggregatedInfo(result: Transaction | null) { describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async function () { this.timeout(10000); - let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const { + restMock, + hapiServiceInstance, + ethImpl, + cacheService, + }: { restMock: MockAdapter; hapiServiceInstance: HAPIService; ethImpl: Eth; cacheService: CacheService } = + generateEthTestEnv(); const requestDetails = new RequestDetails({ requestId: 'eth_getTransactionByBlockNumberAndIndexTest', @@ -164,7 +173,7 @@ describe('@ethGetTransactionByBlockNumberAndIndex using MirrorNode', async funct .onGet(contractResultsByNumberByIndexURL(randomBlock.number, randomBlock.count)) .reply(200, defaultContractResultsWithNullableFrom); - const args = [numberTo0x(randomBlock.number), numberTo0x(randomBlock.count)]; + const args = [numberTo0x(randomBlock.number), numberTo0x(randomBlock.count), requestDetails]; const errMessage = "Cannot read properties of null (reading 'substring')"; await RelayAssertions.assertRejection( diff --git a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts index f7ed90e316..8beeda137a 100644 --- a/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts @@ -27,12 +27,15 @@ import { EthImpl } from '../../../src/lib/eth'; import constants from '../../../src/lib/constants'; import { SDKClient } from '../../../src/lib/clients'; import { DEFAULT_NETWORK_FEES, NO_TRANSACTIONS } from './eth-config'; -import { predefined } from '../../../src'; +import { Eth, predefined } from '../../../src'; import RelayAssertions from '../../assertions'; import { defaultDetailedContractResults, defaultEthereumTransactions, mockData } from '../../helpers'; import { numberTo0x } from '../../../src/formatters'; import { generateEthTestEnv } from './eth-helpers'; import { RequestDetails } from '../../../src/lib/types'; +import MockAdapter from 'axios-mock-adapter'; +import HAPIService from '../../../src/lib/services/hapiService/hapiService'; +import { CacheService } from '../../../src/lib/services/cacheService/cacheService'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); use(chaiAsPromised); @@ -43,7 +46,13 @@ let currentMaxBlockRange: number; describe('@ethGetTransactionCount eth_getTransactionCount spec', async function () { this.timeout(10000); - let { restMock, hapiServiceInstance, ethImpl, cacheService } = generateEthTestEnv(); + const { + restMock, + hapiServiceInstance, + ethImpl, + cacheService, + }: { restMock: MockAdapter; hapiServiceInstance: HAPIService; ethImpl: Eth; cacheService: CacheService } = + generateEthTestEnv(); const requestDetails = new RequestDetails({ requestId: 'eth_getTransactionCountTest', ipAddress: '0.0.0.0' }); const blockNumber = mockData.blocks.blocks[2].number; @@ -163,7 +172,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should throw error for earliest block with invalid block', async () => { restMock.onGet(earliestBlockPath).reply(200, { blocks: [] }); - const args = [MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest]; + const args = [MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest, requestDetails]; await RelayAssertions.assertRejection( predefined.INTERNAL_ERROR('No network blocks found'), @@ -177,7 +186,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should throw error for earliest block with non 0 or 1 block', async () => { restMock.onGet(earliestBlockPath).reply(200, { blocks: [mockData.blocks.blocks[2]] }); - const args = [MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest]; + const args = [MOCK_ACCOUNT_ADDR, EthImpl.blockEarliest, requestDetails]; const errMessage = `Partial mirror node encountered, earliest block number is ${mockData.blocks.blocks[2].number}`; @@ -210,7 +219,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function it('should throw error for account historical numerical block tag with missing block', async () => { restMock.onGet(blockPath).reply(404, mockData.notFound); - const args = [MOCK_ACCOUNT_ADDR, blockNumberHex]; + const args = [MOCK_ACCOUNT_ADDR, blockNumberHex, requestDetails]; await RelayAssertions.assertRejection(predefined.UNKNOWN_BLOCK(), ethImpl.getTransactionCount, true, ethImpl, args); }); @@ -219,7 +228,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function restMock.onGet(blockPath).reply(404, mockData.notFound); restMock.onGet(latestBlockPath).reply(404, mockData.notFound); - const args = [MOCK_ACCOUNT_ADDR, blockNumberHex]; + const args = [MOCK_ACCOUNT_ADDR, blockNumberHex, requestDetails]; await RelayAssertions.assertRejection(predefined.UNKNOWN_BLOCK(), ethImpl.getTransactionCount, true, ethImpl, args); }); @@ -262,7 +271,7 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function .reply(200, { transactions: [{ transaction_id: transactionId }, {}] }); restMock.onGet(contractResultsPath).reply(404, mockData.notFound); - const args = [MOCK_ACCOUNT_ADDR, blockNumberHex]; + const args = [MOCK_ACCOUNT_ADDR, blockNumberHex, requestDetails]; const errMessage = `Failed to retrieve contract results for transaction ${transactionId}`; await RelayAssertions.assertRejection( @@ -301,13 +310,13 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function }); it('should throw for -1 invalid block tag', async () => { - const args = [MOCK_ACCOUNT_ADDR, '-1']; + const args = [MOCK_ACCOUNT_ADDR, '-1', requestDetails]; await RelayAssertions.assertRejection(predefined.UNKNOWN_BLOCK(), ethImpl.getTransactionCount, true, ethImpl, args); }); it('should throw for invalid block tag', async () => { - const args = [MOCK_ACCOUNT_ADDR, 'notablock']; + const args = [MOCK_ACCOUNT_ADDR, 'notablock', requestDetails]; await RelayAssertions.assertRejection(predefined.UNKNOWN_BLOCK(), ethImpl.getTransactionCount, true, ethImpl, args); }); diff --git a/packages/relay/tests/lib/services/eth/filter.spec.ts b/packages/relay/tests/lib/services/eth/filter.spec.ts index ec4aebafc6..97e8f559f0 100644 --- a/packages/relay/tests/lib/services/eth/filter.spec.ts +++ b/packages/relay/tests/lib/services/eth/filter.spec.ts @@ -141,21 +141,21 @@ describe('Filter API Test Suite', async function () { filterService.newFilter, true, filterService, - [], + [requestDetails], ); await RelayAssertions.assertRejection( predefined.UNSUPPORTED_METHOD, filterService.uninstallFilter, true, filterService, - [existingFilterId], + [existingFilterId, requestDetails], ); await RelayAssertions.assertRejection( predefined.UNSUPPORTED_METHOD, filterService.getFilterChanges, true, filterService, - [existingFilterId], + [existingFilterId, requestDetails], ); }); @@ -273,6 +273,7 @@ describe('Filter API Test Suite', async function () { await validateFilterCache(filterId, constants.FILTER.TYPE.LOG, { fromBlock: numberHex, toBlock: 'latest', + requestDetails: requestDetails, address: defaultEvmAddress, topics: defaultLogTopics, }); @@ -285,14 +286,14 @@ describe('Filter API Test Suite', async function () { filterService.newFilter, true, filterService, - [blockNumberHexes[1500], blockNumberHexes[1400]], + [blockNumberHexes[1500], blockNumberHexes[1400], requestDetails], ); await RelayAssertions.assertRejection( predefined.INVALID_BLOCK_RANGE, filterService.newFilter, true, filterService, - ['latest', blockNumberHexes[1400]], + ['latest', blockNumberHexes[1400], requestDetails], ); // block range is too large @@ -301,7 +302,7 @@ describe('Filter API Test Suite', async function () { filterService.newFilter, true, filterService, - [blockNumberHexes[5], blockNumberHexes[2000]], + [blockNumberHexes[5], blockNumberHexes[2000], requestDetails], ); // block range is valid @@ -378,7 +379,7 @@ describe('Filter API Test Suite', async function () { filterService.getFilterLogs, true, filterService, - [filterIdBlockType], + [filterIdBlockType, requestDetails], ); }); @@ -394,7 +395,7 @@ describe('Filter API Test Suite', async function () { filterService.getFilterLogs, true, filterService, - [filterIdBlockType], + [filterIdBlockType, requestDetails], ); }); @@ -559,7 +560,7 @@ describe('Filter API Test Suite', async function () { filterService.getFilterChanges, true, filterService, - [nonExistingFilterId], + [nonExistingFilterId, requestDetails], ); }); @@ -570,7 +571,7 @@ describe('Filter API Test Suite', async function () { filterService.getFilterChanges, true, filterService, - [nonExistingFilterId], + [nonExistingFilterId, requestDetails], ); }); From 5b795b74017b20f30713e0597f5bb97063a5bf3f Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Thu, 19 Sep 2024 23:29:11 +0300 Subject: [PATCH 45/48] Fixes failing tests in filter accetance test Signed-off-by: Konstantina Blazhukova --- .../relay/tests/lib/services/eth/filter.spec.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/relay/tests/lib/services/eth/filter.spec.ts b/packages/relay/tests/lib/services/eth/filter.spec.ts index 97e8f559f0..d8d294a12f 100644 --- a/packages/relay/tests/lib/services/eth/filter.spec.ts +++ b/packages/relay/tests/lib/services/eth/filter.spec.ts @@ -27,12 +27,13 @@ import { MirrorNodeClient } from '../../../../src/lib/clients'; import pino from 'pino'; import constants from '../../../../src/lib/constants'; import { FilterService, CommonService } from '../../../../src/lib/services/ethService'; -import { defaultEvmAddress, getRequestId, toHex, defaultBlock, defaultLogTopics, defaultLogs1 } from '../../../helpers'; +import { defaultEvmAddress, toHex, defaultBlock, defaultLogTopics, defaultLogs1 } from '../../../helpers'; import RelayAssertions from '../../../assertions'; import { predefined } from '../../../../src'; import { CacheService } from '../../../../src/lib/services/cacheService/cacheService'; import * as sinon from 'sinon'; import { RequestDetails } from '../../../../src/lib/types'; +import { v4 as uuid } from 'uuid'; dotenv.config({ path: path.resolve(__dirname, '../test.env') }); const logger = pino(); @@ -46,7 +47,7 @@ let cacheService: CacheService; describe('Filter API Test Suite', async function () { this.timeout(10000); - const requestDetails = new RequestDetails({ requestId: getRequestId(), ipAddress: '0.0.0.0' }); + const requestDetails = new RequestDetails({ requestId: uuid(), ipAddress: '0.0.0.0' }); const filterObject = { toBlock: 'latest', }; @@ -141,7 +142,7 @@ describe('Filter API Test Suite', async function () { filterService.newFilter, true, filterService, - [requestDetails], + [undefined, undefined, requestDetails], ); await RelayAssertions.assertRejection( predefined.UNSUPPORTED_METHOD, @@ -192,21 +193,21 @@ describe('Filter API Test Suite', async function () { filterService.newFilter, true, filterService, - [], + [undefined, undefined, requestDetails], ); await RelayAssertions.assertRejection( predefined.UNSUPPORTED_METHOD, filterService.uninstallFilter, true, filterService, - [existingFilterId], + [existingFilterId, requestDetails], ); await RelayAssertions.assertRejection( predefined.UNSUPPORTED_METHOD, filterService.getFilterChanges, true, filterService, - [existingFilterId], + [existingFilterId, requestDetails], ); }); }); From 633e385887dcfb6587fb057c90298fceca6b9cbd Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Fri, 20 Sep 2024 14:37:30 +0300 Subject: [PATCH 46/48] Fixes build after main merge Signed-off-by: Konstantina Blazhukova --- .../hbarLimiter/hbarSpendingPlanRepository.ts | 6 ++--- .../ipAddressHbarSpendingPlanRepository.ts | 13 +++++----- packages/relay/src/lib/eth.ts | 19 +++++++------- packages/relay/src/lib/hbarlimiter/index.ts | 10 +++----- packages/relay/src/lib/precheck.ts | 2 +- .../hbarLimitService/IHbarLimitService.ts | 2 +- .../lib/services/hbarLimitService/index.ts | 25 +++++++++++-------- 7 files changed, 41 insertions(+), 36 deletions(-) diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts index fc2c22016f..13a9a46160 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts @@ -174,11 +174,11 @@ export class HbarSpendingPlanRepository { * Resets the amount spent today for all hbar spending plans. * @returns {Promise} - A promise that resolves when the operation is complete. */ - async resetAllSpentTodayEntries(): Promise { + async resetAllSpentTodayEntries(requestDetails: RequestDetails): Promise { this.logger.trace('Resetting the spentToday entries for all HbarSpendingPlans...'); const callerMethod = this.resetAllSpentTodayEntries.name; - const keys = await this.cache.keys(`${this.collectionKey}:*:spentToday`, callerMethod); - await Promise.all(keys.map((key) => this.cache.delete(key, callerMethod))); + const keys = await this.cache.keys(`${this.collectionKey}:*:spentToday`, callerMethod, requestDetails); + await Promise.all(keys.map((key) => this.cache.delete(key, callerMethod, requestDetails))); this.logger.trace(`Successfully reset ${keys.length} spentToday entries for HbarSpendingPlans.`); } diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts index 564cd301bf..044a99eb3d 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts @@ -23,6 +23,7 @@ import { Logger } from 'pino'; import { IIPAddressHbarSpendingPlan } from '../../types/hbarLimiter/ipAddressHbarSpendingPlan'; import { IPAddressHbarSpendingPlanNotFoundError } from '../../types/hbarLimiter/errors'; import { IPAddressHbarSpendingPlan } from '../../entities/hbarLimiter/ipAddressHbarSpendingPlan'; +import { RequestDetails } from '../../../types'; export class IPAddressHbarSpendingPlanRepository { private readonly collectionKey = 'ipAddressHbarSpendingPlan'; @@ -51,9 +52,9 @@ export class IPAddressHbarSpendingPlanRepository { * @param {string} ipAddress - The IP address to search for. * @returns {Promise} - The associated plan for the IP address. */ - async findByAddress(ipAddress: string): Promise { + async findByAddress(ipAddress: string, requestDetails: RequestDetails): Promise { const key = this.getKey(ipAddress); - const addressPlan = await this.cache.getAsync(key, 'findByAddress'); + const addressPlan = await this.cache.getAsync(key, 'findByAddress', requestDetails); if (!addressPlan) { throw new IPAddressHbarSpendingPlanNotFoundError(ipAddress); } @@ -67,9 +68,9 @@ export class IPAddressHbarSpendingPlanRepository { * @param {IIPAddressHbarSpendingPlan} addressPlan - The plan to save. * @returns {Promise} - A promise that resolves when the IP address is linked to the plan. */ - async save(addressPlan: IIPAddressHbarSpendingPlan): Promise { + async save(addressPlan: IIPAddressHbarSpendingPlan, requestDetails: RequestDetails): Promise { const key = this.getKey(addressPlan.ipAddress); - await this.cache.set(key, addressPlan, 'save', this.threeMonthsInMillis); + await this.cache.set(key, addressPlan, 'save', requestDetails, this.threeMonthsInMillis); this.logger.trace(`Saved IPAddressHbarSpendingPlan with address ${addressPlan.ipAddress}`); } @@ -79,9 +80,9 @@ export class IPAddressHbarSpendingPlanRepository { * @param {string} ipAddress - The IP address to unlink the plan from. * @returns {Promise} - A promise that resolves when the IP address is unlinked from the plan. */ - async delete(ipAddress: string): Promise { + async delete(ipAddress: string, requestDetails: RequestDetails): Promise { const key = this.getKey(ipAddress); - await this.cache.delete(key, 'delete'); + await this.cache.delete(key, 'delete', requestDetails); this.logger.trace(`Deleted IPAddressHbarSpendingPlan with address ${ipAddress}`); } diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 0bc4347437..6a286ff026 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -488,7 +488,9 @@ export class EthImpl implements Eth { } if (_.isNil(networkFees)) { - this.logger.debug(`${requestDetails.formattedRequestId} Mirror Node returned no network fees. Fallback to consensus node.`); + this.logger.debug( + `${requestDetails.formattedRequestId} Mirror Node returned no network fees. Fallback to consensus node.`, + ); networkFees = { fees: [ { @@ -549,7 +551,7 @@ export class EthImpl implements Eth { * `CHAIN_ID`. */ chainId(requestDetails: RequestDetails): string { - //this.logger.trace(`${requestDetails.formattedRequestId} chainId()`); + this.logger.trace(`${requestDetails.formattedRequestId} chainId()`); return this.chain; } @@ -1575,8 +1577,8 @@ export class EthImpl implements Eth { requestDetails, originalCallerAddress, networkGasPriceInWeiBars, - await this.getCurrentNetworkExchangeRateInCents(requestDetails.requestIdPrefix), - requestDetails.requestIdPrefix + await this.getCurrentNetworkExchangeRateInCents(requestDetails), + requestDetails.formattedRequestId, ); txSubmitted = true; @@ -2543,17 +2545,16 @@ export class EthImpl implements Eth { * @param {string} requestId - The unique identifier for the request. * @returns {Promise} - A promise that resolves to the current exchange rate in cents. */ - private async getCurrentNetworkExchangeRateInCents(requestId: string): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); + private async getCurrentNetworkExchangeRateInCents(requestDetails: RequestDetails): Promise { const cacheKey = constants.CACHE_KEY.CURRENT_NETWORK_EXCHANGE_RATE; const callingMethod = this.getCurrentNetworkExchangeRateInCents.name; const cacheTTL = 15 * 60 * 1000; // 15 minutes - let currentNetworkExchangeRate = await this.cacheService.getAsync(cacheKey, callingMethod, requestIdPrefix); + let currentNetworkExchangeRate = await this.cacheService.getAsync(cacheKey, callingMethod, requestDetails); if (!currentNetworkExchangeRate) { - currentNetworkExchangeRate = (await this.mirrorNodeClient.getNetworkExchangeRate(requestId)).current_rate; - await this.cacheService.set(cacheKey, currentNetworkExchangeRate, callingMethod, cacheTTL, requestIdPrefix); + currentNetworkExchangeRate = (await this.mirrorNodeClient.getNetworkExchangeRate(requestDetails)).current_rate; + await this.cacheService.set(cacheKey, currentNetworkExchangeRate, callingMethod, requestDetails, cacheTTL); } const exchangeRateInCents = currentNetworkExchangeRate.cent_equivalent / currentNetworkExchangeRate.hbar_equivalent; diff --git a/packages/relay/src/lib/hbarlimiter/index.ts b/packages/relay/src/lib/hbarlimiter/index.ts index 9b534d366a..2b25a657f5 100644 --- a/packages/relay/src/lib/hbarlimiter/index.ts +++ b/packages/relay/src/lib/hbarlimiter/index.ts @@ -139,13 +139,11 @@ export default class HbarLimit { callDataSize: number, fileChunkSize: number, currentNetworkExchangeRateInCents: number, - requestId: string, + requestDetails: RequestDetails, ): boolean { - const requestIdPrefix = formatRequestIdMessage(requestId); - if (this.isAccountWhiteListed(originalCallerAddress)) { this.logger.trace( - `${requestIdPrefix} Request bypasses the preemptive limit check - the caller is a whitelisted account: originalCallerAddress=${originalCallerAddress}`, + `${requestDetails.formattedRequestId} Request bypasses the preemptive limit check - the caller is a whitelisted account: originalCallerAddress=${originalCallerAddress}`, ); return false; } @@ -158,13 +156,13 @@ export default class HbarLimit { if (this.remainingBudget - estimatedTxFee < 0) { this.logger.warn( - `${requestIdPrefix} Request fails the preemptive limit check - the remaining HBAR budget was not enough to accommodate the estimated transaction fee: remainingBudget=${this.remainingBudget}, total=${this.total}, resetTimestamp=${this.reset}, callDataSize=${callDataSize}, estimatedTxFee=${estimatedTxFee}, exchangeRateInCents=${currentNetworkExchangeRateInCents}`, + `${requestDetails.formattedRequestId} Request fails the preemptive limit check - the remaining HBAR budget was not enough to accommodate the estimated transaction fee: remainingBudget=${this.remainingBudget}, total=${this.total}, resetTimestamp=${this.reset}, callDataSize=${callDataSize}, estimatedTxFee=${estimatedTxFee}, exchangeRateInCents=${currentNetworkExchangeRateInCents}`, ); return true; } this.logger.trace( - `${requestIdPrefix} Request passes the preemptive limit check - the remaining HBAR budget is enough to accommodate the estimated transaction fee: remainingBudget=${this.remainingBudget}, total=${this.total}, resetTimestamp=${this.reset}, callDataSize=${callDataSize}, estimatedTxFee=${estimatedTxFee}, exchangeRateInCents=${currentNetworkExchangeRateInCents}`, + `${requestDetails.formattedRequestId} Request passes the preemptive limit check - the remaining HBAR budget is enough to accommodate the estimated transaction fee: remainingBudget=${this.remainingBudget}, total=${this.total}, resetTimestamp=${this.reset}, callDataSize=${callDataSize}, estimatedTxFee=${estimatedTxFee}, exchangeRateInCents=${currentNetworkExchangeRateInCents}`, ); return false; } diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index c81e52d353..f44c1d3d51 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -83,7 +83,7 @@ export class Precheck { this.nonce(parsedTx, mirrorAccountInfo.ethereum_nonce, requestDetails); this.chainId(parsedTx, requestDetails); this.value(parsedTx); - this.gasPrice(parsedTx, networkGasPriceInWeiBars, requestDetails.formattedRequestId); + this.gasPrice(parsedTx, networkGasPriceInWeiBars, requestDetails); this.balance(parsedTx, mirrorAccountInfo, requestDetails); } diff --git a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts index 6b5a15f730..60d2b7e6d2 100644 --- a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts +++ b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts @@ -21,7 +21,7 @@ import { RequestDetails } from '../../types'; export interface IHbarLimitService { - resetLimiter(): Promise; + resetLimiter(requestDetails: RequestDetails): Promise; shouldLimit( mode: string, methodName: string, diff --git a/packages/relay/src/lib/services/hbarLimitService/index.ts b/packages/relay/src/lib/services/hbarLimitService/index.ts index acfe545f71..0e4813473d 100644 --- a/packages/relay/src/lib/services/hbarLimitService/index.ts +++ b/packages/relay/src/lib/services/hbarLimitService/index.ts @@ -143,15 +143,14 @@ export class HbarLimitService implements IHbarLimitService { * @param {string} [requestId] - An optional unique request ID for tracking the request. * @returns {Promise} - A promise that resolves when the operation is complete. */ - async resetLimiter(requestId?: string): Promise { - const requestIdPrefix = formatRequestIdMessage(requestId); - this.logger.trace(`${requestIdPrefix} Resetting HBAR rate limiter...`); - await this.hbarSpendingPlanRepository.resetAllSpentTodayEntries(); + async resetLimiter(requestDetails: RequestDetails): Promise { + this.logger.trace(`${requestDetails.formattedRequestId} Resetting HBAR rate limiter...`); + await this.hbarSpendingPlanRepository.resetAllSpentTodayEntries(requestDetails); this.resetBudget(); this.resetMetrics(); this.reset = this.getResetTimestamp(); this.logger.trace( - `${requestIdPrefix} HBAR Rate Limit reset: remainingBudget=${this.remainingBudget}, newResetTimestamp=${this.reset}`, + `${requestDetails.formattedRequestId} HBAR Rate Limit reset: remainingBudget=${this.remainingBudget}, newResetTimestamp=${this.reset}`, ); } @@ -257,7 +256,7 @@ export class HbarLimitService implements IHbarLimitService { requestDetails: RequestDetails, ): Promise { if (this.shouldResetLimiter()) { - await this.resetLimiter(); + await this.resetLimiter(requestDetails); } if (this.remainingBudget <= 0 || this.remainingBudget - estimatedTxFee < 0) { this.hbarLimitCounter.labels(mode, methodName).inc(1); @@ -356,7 +355,7 @@ export class HbarLimitService implements IHbarLimitService { } if (ipAddress) { try { - return await this.getSpendingPlanByIPAddress(ipAddress); + return await this.getSpendingPlanByIPAddress(ipAddress, requestDetails); } catch (error) { this.logger.warn(error, `Failed to get spending plan for IP address '${ipAddress}'`); } @@ -388,9 +387,15 @@ export class HbarLimitService implements IHbarLimitService { * @returns {Promise} - A promise that resolves with the spending plan. * @private */ - private async getSpendingPlanByIPAddress(ipAddress: string): Promise { - const ipAddressHbarSpendingPlan = await this.ipAddressHbarSpendingPlanRepository.findByAddress(ipAddress); - return this.hbarSpendingPlanRepository.findByIdWithDetails(ipAddressHbarSpendingPlan.planId); + private async getSpendingPlanByIPAddress( + ipAddress: string, + requestDetails: RequestDetails, + ): Promise { + const ipAddressHbarSpendingPlan = await this.ipAddressHbarSpendingPlanRepository.findByAddress( + ipAddress, + requestDetails, + ); + return this.hbarSpendingPlanRepository.findByIdWithDetails(ipAddressHbarSpendingPlan.planId, requestDetails); } /** From b8b06826cd8507c5ea2c36c64953d7f1ce4ffe9e Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Fri, 20 Sep 2024 18:34:21 +0300 Subject: [PATCH 47/48] merge main and fix tests Signed-off-by: Konstantina Blazhukova --- packages/relay/src/lib/clients/sdkClient.ts | 1 - packages/relay/src/lib/eth.ts | 1 - .../hbarLimitService/IHbarLimitService.ts | 1 - .../lib/services/hbarLimitService/index.ts | 31 +++-- packages/relay/tests/lib/hbarLimiter.spec.ts | 18 ++- ...pAddressHbarSpendingPlanRepository.spec.ts | 23 ++-- packages/relay/tests/lib/sdkClient.spec.ts | 6 +- .../tests/lib/services/eth/filter.spec.ts | 2 +- .../hbarLimitService/hbarLimitService.spec.ts | 123 +++++++++--------- 9 files changed, 103 insertions(+), 103 deletions(-) diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index 6e2c559d16..dd4f714a9e 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -404,7 +404,6 @@ export class SDKClient { originalCallerAddress: string, networkGasPriceInWeiBars: number, currentNetworkExchangeRateInCents: number, - requestId: string, ): Promise<{ txResponse: TransactionResponse; fileId: FileId | null }> { const ethereumTransactionData: EthereumTransactionData = EthereumTransactionData.fromBytes(transactionBuffer); const ethereumTransaction = new EthereumTransaction(); diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 6a286ff026..82bd77ef7e 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -1578,7 +1578,6 @@ export class EthImpl implements Eth { originalCallerAddress, networkGasPriceInWeiBars, await this.getCurrentNetworkExchangeRateInCents(requestDetails), - requestDetails.formattedRequestId, ); txSubmitted = true; diff --git a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts index 60d2b7e6d2..b8f1f49fe1 100644 --- a/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts +++ b/packages/relay/src/lib/services/hbarLimitService/IHbarLimitService.ts @@ -27,7 +27,6 @@ export interface IHbarLimitService { methodName: string, ethAddress: string, requestDetails: RequestDetails, - ipAddress: string, estimatedTxFee?: number, ): Promise; addExpense(cost: number, ethAddress: string, requestDetails: RequestDetails, ipAddress?: string): Promise; diff --git a/packages/relay/src/lib/services/hbarLimitService/index.ts b/packages/relay/src/lib/services/hbarLimitService/index.ts index 0e4813473d..dd4280b97a 100644 --- a/packages/relay/src/lib/services/hbarLimitService/index.ts +++ b/packages/relay/src/lib/services/hbarLimitService/index.ts @@ -169,9 +169,9 @@ export class HbarLimitService implements IHbarLimitService { methodName: string, ethAddress: string, requestDetails: RequestDetails, - ipAddress: string, estimatedTxFee: number = 0, ): Promise { + const ipAddress = requestDetails.ipAddress; if (await this.isDailyBudgetExceeded(mode, methodName, estimatedTxFee, requestDetails)) { return true; } @@ -181,10 +181,10 @@ export class HbarLimitService implements IHbarLimitService { } const user = `(ethAddress=${ethAddress}, ipAddress=${ipAddress})`; this.logger.trace(`${requestDetails.formattedRequestId} Checking if ${user} should be limited...`); - let spendingPlan = await this.getSpendingPlan(ethAddress, ipAddress, requestDetails); + let spendingPlan = await this.getSpendingPlan(ethAddress, requestDetails); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address - spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress, requestDetails); + spendingPlan = await this.createBasicSpendingPlan(ethAddress, requestDetails); } const dailyLimit = HbarLimitService.DAILY_LIMITS[spendingPlan.subscriptionType]; @@ -206,15 +206,16 @@ export class HbarLimitService implements IHbarLimitService { * @param {RequestDetails} requestDetails The request details for logging and tracking. * @returns {Promise} - A promise that resolves when the expense has been added. */ - async addExpense(cost: number, ethAddress: string, requestDetails: RequestDetails, ipAddress: string): Promise { + async addExpense(cost: number, ethAddress: string, requestDetails: RequestDetails): Promise { + const ipAddress = requestDetails.ipAddress; if (!ethAddress && !ipAddress) { throw new Error('Cannot add expense without an eth address or ip address'); } - let spendingPlan = await this.getSpendingPlan(ethAddress, ipAddress, requestDetails); + let spendingPlan = await this.getSpendingPlan(ethAddress, requestDetails); if (!spendingPlan) { // Create a basic spending plan if none exists for the eth address or ip address - spendingPlan = await this.createBasicSpendingPlan(ethAddress, ipAddress, requestDetails); + spendingPlan = await this.createBasicSpendingPlan(ethAddress, requestDetails); } this.logger.trace( @@ -340,9 +341,9 @@ export class HbarLimitService implements IHbarLimitService { */ private async getSpendingPlan( ethAddress: string, - ipAddress: string, requestDetails: RequestDetails, ): Promise { + const ipAddress = requestDetails.ipAddress; if (ethAddress) { try { return await this.getSpendingPlanByEthAddress(ethAddress, requestDetails); @@ -355,7 +356,7 @@ export class HbarLimitService implements IHbarLimitService { } if (ipAddress) { try { - return await this.getSpendingPlanByIPAddress(ipAddress, requestDetails); + return await this.getSpendingPlanByIPAddress(requestDetails); } catch (error) { this.logger.warn(error, `Failed to get spending plan for IP address '${ipAddress}'`); } @@ -387,10 +388,8 @@ export class HbarLimitService implements IHbarLimitService { * @returns {Promise} - A promise that resolves with the spending plan. * @private */ - private async getSpendingPlanByIPAddress( - ipAddress: string, - requestDetails: RequestDetails, - ): Promise { + private async getSpendingPlanByIPAddress(requestDetails: RequestDetails): Promise { + const ipAddress = requestDetails.ipAddress; const ipAddressHbarSpendingPlan = await this.ipAddressHbarSpendingPlanRepository.findByAddress( ipAddress, requestDetails, @@ -408,9 +407,9 @@ export class HbarLimitService implements IHbarLimitService { */ private async createBasicSpendingPlan( ethAddress: string, - ipAddress: string, requestDetails: RequestDetails, ): Promise { + const ipAddress = requestDetails.ipAddress; if (!ethAddress && !ipAddress) { throw new Error('Cannot create a spending plan without an associated eth address or ip address'); } @@ -421,12 +420,12 @@ export class HbarLimitService implements IHbarLimitService { `${requestDetails.formattedRequestId} Linking spending plan with ID ${spendingPlan.id} to eth address ${ethAddress}`, ); await this.ethAddressHbarSpendingPlanRepository.save({ ethAddress, planId: spendingPlan.id }, requestDetails); - } else if (ipAddress) { + } + if (ipAddress) { this.logger.trace( `${requestDetails.formattedRequestId} Linking spending plan with ID ${spendingPlan.id} to ip address ${ipAddress}`, ); - // TODO: Implement this with https://github.com/hashgraph/hedera-json-rpc-relay/issues/2888 - // await this.ipAddressHbarSpendingPlanRepository.save({ ipAddress, planId: spendingPlan.id }); + await this.ipAddressHbarSpendingPlanRepository.save({ ipAddress, planId: spendingPlan.id }, requestDetails); } return spendingPlan; } diff --git a/packages/relay/tests/lib/hbarLimiter.spec.ts b/packages/relay/tests/lib/hbarLimiter.spec.ts index 590a28c0ee..2d1e45f35c 100644 --- a/packages/relay/tests/lib/hbarLimiter.spec.ts +++ b/packages/relay/tests/lib/hbarLimiter.spec.ts @@ -69,7 +69,7 @@ describe('HBAR Rate Limiter', async function () { 'QUERY', 'eth_call', randomAccountAddress, - requestDetails + requestDetails, ); rateLimiterWithEmptyBudget.addExpense(validTotal, currentDateNow, requestDetails); @@ -106,7 +106,13 @@ describe('HBAR Rate Limiter', async function () { const isEnabled = invalidRateLimiter.isEnabled(); const limiterResetTime = invalidRateLimiter.getResetTime(); const limiterRemainingBudget = invalidRateLimiter.getRemainingBudget(); - const shouldRateLimit = invalidRateLimiter.shouldLimit(currentDateNow, 'QUERY', 'eth_call', randomAccountAddress, requestDetails); + const shouldRateLimit = invalidRateLimiter.shouldLimit( + currentDateNow, + 'QUERY', + 'eth_call', + randomAccountAddress, + requestDetails, + ); invalidRateLimiter.addExpense(validTotal, currentDateNow, requestDetails); expect(isEnabled).to.equal(false); @@ -239,7 +245,7 @@ describe('HBAR Rate Limiter', async function () { callDataSize, fileChunkSize, mockedExchangeRateInCents, - getRequestId(), + requestDetails, ); expect(result).to.be.true; }); @@ -250,7 +256,7 @@ describe('HBAR Rate Limiter', async function () { callDataSize, fileChunkSize, mockedExchangeRateInCents, - getRequestId(), + requestDetails, ); expect(result).to.be.false; }); @@ -295,7 +301,7 @@ describe('HBAR Rate Limiter', async function () { callDataSize, fileChunkSize, mockedExchangeRateInCents, - getRequestId(), + requestDetails, ); expect(result).to.be.false; }); @@ -306,7 +312,7 @@ describe('HBAR Rate Limiter', async function () { callDataSize, fileChunkSize, mockedExchangeRateInCents, - getRequestId(), + requestDetails, ); expect(result).to.be.true; }); diff --git a/packages/relay/tests/lib/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.spec.ts b/packages/relay/tests/lib/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.spec.ts index 2debf7cee8..d3a63da701 100644 --- a/packages/relay/tests/lib/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.spec.ts +++ b/packages/relay/tests/lib/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.spec.ts @@ -28,12 +28,14 @@ import { IPAddressHbarSpendingPlanNotFoundError } from '../../../../src/lib/db/t import { randomBytes, uuidV4 } from 'ethers'; import { Registry } from 'prom-client'; import { useInMemoryRedisServer } from '../../../helpers'; +import { RequestDetails } from '../../../../src/lib/types'; chai.use(chaiAsPromised); describe('IPAddressHbarSpendingPlanRepository', function () { const logger = pino(); const registry = new Registry(); + const requestDetails = new RequestDetails({ requestId: 'testId', ipAddress: '0.0.0.0' }); const tests = (isSharedCacheEnabled: boolean) => { let cacheService: CacheService; @@ -60,14 +62,14 @@ describe('IPAddressHbarSpendingPlanRepository', function () { describe('findByAddress', () => { it('retrieves an address plan by ip', async () => { const addressPlan: IIPAddressHbarSpendingPlan = { ipAddress, planId: uuidV4(randomBytes(16)) }; - await cacheService.set(`${repository['collectionKey']}:${ipAddress}`, addressPlan, 'test'); + await cacheService.set(`${repository['collectionKey']}:${ipAddress}`, addressPlan, 'test', requestDetails); - const result = await repository.findByAddress(ipAddress); + const result = await repository.findByAddress(ipAddress, requestDetails); expect(result).to.deep.equal(addressPlan); }); it('throws an error if address plan is not found', async () => { - await expect(repository.findByAddress(nonExistingIpAddress)).to.be.eventually.rejectedWith( + await expect(repository.findByAddress(nonExistingIpAddress, requestDetails)).to.be.eventually.rejectedWith( IPAddressHbarSpendingPlanNotFoundError, `IPAddressHbarSpendingPlan with address ${nonExistingIpAddress} not found`, ); @@ -78,24 +80,26 @@ describe('IPAddressHbarSpendingPlanRepository', function () { it('saves an address plan successfully', async () => { const addressPlan: IIPAddressHbarSpendingPlan = { ipAddress, planId: uuidV4(randomBytes(16)) }; - await repository.save(addressPlan); + await repository.save(addressPlan, requestDetails); const result = await cacheService.getAsync( `${repository['collectionKey']}:${ipAddress}`, 'test', + requestDetails, ); expect(result).to.deep.equal(addressPlan); }); it('overwrites an existing address plan', async () => { const addressPlan: IIPAddressHbarSpendingPlan = { ipAddress, planId: uuidV4(randomBytes(16)) }; - await cacheService.set(`${repository['collectionKey']}:${ipAddress}`, addressPlan, 'test'); + await cacheService.set(`${repository['collectionKey']}:${ipAddress}`, addressPlan, 'test', requestDetails); const newPlanId = uuidV4(randomBytes(16)); const newAddressPlan: IIPAddressHbarSpendingPlan = { ipAddress, planId: newPlanId }; - await repository.save(newAddressPlan); + await repository.save(newAddressPlan, requestDetails); const result = await cacheService.getAsync( `${repository['collectionKey']}:${ipAddress}`, 'test', + requestDetails, ); expect(result).to.deep.equal(newAddressPlan); }); @@ -104,18 +108,19 @@ describe('IPAddressHbarSpendingPlanRepository', function () { describe('delete', () => { it('deletes an address plan successfully', async () => { const addressPlan: IIPAddressHbarSpendingPlan = { ipAddress, planId: uuidV4(randomBytes(16)) }; - await cacheService.set(`${repository['collectionKey']}:${ipAddress}`, addressPlan, 'test'); + await cacheService.set(`${repository['collectionKey']}:${ipAddress}`, addressPlan, 'test', requestDetails); - await repository.delete(ipAddress); + await repository.delete(ipAddress, requestDetails); const result = await cacheService.getAsync( `${repository['collectionKey']}:${ipAddress}`, 'test', + requestDetails, ); expect(result).to.be.null; }); it('does not throw an error if address plan to delete does not exist', async () => { - await expect(repository.delete(nonExistingIpAddress)).to.be.fulfilled; + await expect(repository.delete(nonExistingIpAddress, requestDetails)).to.be.fulfilled; }); }); }; diff --git a/packages/relay/tests/lib/sdkClient.spec.ts b/packages/relay/tests/lib/sdkClient.spec.ts index aa33d12ed4..5aac26123b 100644 --- a/packages/relay/tests/lib/sdkClient.spec.ts +++ b/packages/relay/tests/lib/sdkClient.spec.ts @@ -25,7 +25,6 @@ import { resolve } from 'path'; import * as sinon from 'sinon'; import { config } from 'dotenv'; import { Context } from 'mocha'; -import { v4 as uuid } from 'uuid'; import EventEmitter from 'events'; import { Registry } from 'prom-client'; import { Utils } from '../../src/utils'; @@ -2304,7 +2303,6 @@ describe('SdkClient', async function () { randomAccountAddress, mockedNetworkGasPrice, mockedExchangeRateIncents, - requestDetails.requestIdPrefix, ); expect.fail(`Expected an error but nothing was thrown`); } catch (error: any) { @@ -2364,7 +2362,6 @@ describe('SdkClient', async function () { randomAccountAddress, mockedNetworkGasPrice, mockedExchangeRateIncents, - requestDetails.requestIdPrefix, ); expect(queryStub.called).to.be.true; @@ -2490,8 +2487,9 @@ describe('SdkClient', async function () { await sdkClient.submitEthereumTransaction( transactionBuffer, mockedCallerName, - requestId, + requestDetails, randomAccountAddress, + mockedNetworkGasPrice, mockedExchangeRateIncents, ); expect.fail(`Expected an error but nothing was thrown`); diff --git a/packages/relay/tests/lib/services/eth/filter.spec.ts b/packages/relay/tests/lib/services/eth/filter.spec.ts index d8d294a12f..bf09d6658a 100644 --- a/packages/relay/tests/lib/services/eth/filter.spec.ts +++ b/packages/relay/tests/lib/services/eth/filter.spec.ts @@ -62,7 +62,7 @@ describe('Filter API Test Suite', async function () { const validateFilterCache = async (filterId, expectedFilterType, expectedParams = {}) => { const cacheKey = `${constants.CACHE_KEY.FILTERID}_${filterId}`; - const cachedFilter = await cacheService.getAsync(cacheKey, 'validateFilterCache', requestDetails); + const cachedFilter = await cacheService.getAsync(cacheKey, undefined, requestDetails); expect(cachedFilter).to.exist; expect(cachedFilter.type).to.exist; expect(cachedFilter.type).to.eq(expectedFilterType); diff --git a/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts b/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts index 72c405bc3f..8cdd4be158 100644 --- a/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts +++ b/packages/relay/tests/lib/services/hbarLimitService/hbarLimitService.spec.ts @@ -38,6 +38,7 @@ import { EthAddressHbarSpendingPlanNotFoundError, IPAddressHbarSpendingPlanNotFoundError, } from '../../../../src/lib/db/types/hbarLimiter/errors'; +import { RequestDetails } from '../../../../src/lib/types'; chai.use(chaiAsPromised); @@ -53,7 +54,8 @@ describe('HbarLimitService', function () { const mockRequestId = getRequestId(); const mockPlanId = uuidV4(randomBytes(16)); - const requestIdPrefix = `[Request ID: testId]`; + const requestDetails = new RequestDetails({ requestId: 'hbarLimterTest', ipAddress: mockIpAddress }); + let hbarLimitService: HbarLimitService; let hbarSpendingPlanRepositoryStub: sinon.SinonStubbedInstance; let ethAddressHbarSpendingPlanRepositoryStub: sinon.SinonStubbedInstance; @@ -114,7 +116,7 @@ describe('HbarLimitService', function () { }); it('should reset the spentToday field of all spending plans', async function () { - await hbarLimitService.resetLimiter(); + await hbarLimitService.resetLimiter(requestDetails); expect(hbarSpendingPlanRepositoryStub.resetAllSpentTodayEntries.called).to.be.true; }); @@ -122,27 +124,27 @@ describe('HbarLimitService', function () { // @ts-ignore hbarLimitService.remainingBudget = 1000; const setSpy = sinon.spy(hbarLimitService['hbarLimitRemainingGauge'], 'set'); - await hbarLimitService.resetLimiter(); + await hbarLimitService.resetLimiter(requestDetails); expect(hbarLimitService['remainingBudget']).to.equal(totalBudget); expect(setSpy.calledOnceWith(totalBudget)).to.be.true; }); it('should reset the daily unique spending plans counter', async function () { const spies = createSpiesForMetricsReset('dailyUniqueSpendingPlansCounter'); - await hbarLimitService.resetLimiter(); + await hbarLimitService.resetLimiter(requestDetails); spies.forEach((spy) => sinon.assert.calledOnce(spy)); }); it('should reset the average daily spending plan usages gauge', async function () { const spies = createSpiesForMetricsReset('averageDailySpendingPlanUsagesGauge'); - await hbarLimitService.resetLimiter(); + await hbarLimitService.resetLimiter(requestDetails); spies.forEach((spy) => sinon.assert.calledOnce(spy)); }); it('should set the reset date to the next day at midnight', async function () { const tomorrow = new Date(Date.now() + HbarLimitService.ONE_DAY_IN_MILLIS); const expectedResetDate = new Date(tomorrow.setHours(0, 0, 0, 0)); - await hbarLimitService.resetLimiter(); + await hbarLimitService.resetLimiter(requestDetails); expect(hbarLimitService['reset']).to.deep.equal(expectedResetDate); }); }); @@ -152,7 +154,7 @@ describe('HbarLimitService', function () { it('should return true if the total daily budget is exceeded', async function () { // @ts-ignore hbarLimitService.remainingBudget = 0; - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestIdPrefix); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestDetails); expect(result).to.be.true; }); @@ -163,8 +165,7 @@ describe('HbarLimitService', function () { mode, methodName, mockEthAddress, - mockRequestId, - mockIpAddress, + requestDetails, mockEstimatedTxFee, ); expect(result).to.be.true; @@ -177,7 +178,7 @@ describe('HbarLimitService', function () { hbarSpendingPlanRepositoryStub.create.resolves(newSpendingPlan); ethAddressHbarSpendingPlanRepositoryStub.save.resolves(); - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestDetails); expect(result).to.be.false; expect(hbarSpendingPlanRepositoryStub.create.calledOnce).to.be.true; @@ -190,8 +191,9 @@ describe('HbarLimitService', function () { ).to.be.true; }); - it('should return false if ethAddress is null or empty', async function () { - const result = await hbarLimitService.shouldLimit(mode, methodName, ''); + it('should return false if ethAddress and ipAddress is empty string', async function () { + const requestDetails = new RequestDetails({ requestId: 'hbarLimterTest', ipAddress: '' }); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.false; }); @@ -203,7 +205,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestDetails); expect(result).to.be.true; }); @@ -216,7 +218,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestDetails); expect(result).to.be.false; }); @@ -229,7 +231,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestDetails); expect(result).to.be.true; }); @@ -249,8 +251,7 @@ describe('HbarLimitService', function () { mode, methodName, mockEthAddress, - mockRequestId, - mockIpAddress, + requestDetails, mockEstimatedTxFee, ); @@ -268,7 +269,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestDetails); expect(result).to.be.false; }); @@ -284,7 +285,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, mockEthAddress, requestDetails); expect(result).to.be.false; }); @@ -294,21 +295,14 @@ describe('HbarLimitService', function () { it('should return true if the total daily budget is exceeded', async function () { // @ts-ignore hbarLimitService.remainingBudget = 0; - const result = await hbarLimitService.shouldLimit(mode, methodName, '', mockIpAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.true; }); it('should return true when remainingBudget < estimatedTxFee ', async function () { // @ts-ignore hbarLimitService.remainingBudget = mockEstimatedTxFee - 1; - const result = await hbarLimitService.shouldLimit( - mode, - methodName, - '', - mockRequestId, - mockIpAddress, - mockEstimatedTxFee, - ); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails, mockEstimatedTxFee); expect(result).to.be.true; }); @@ -319,7 +313,8 @@ describe('HbarLimitService', function () { hbarSpendingPlanRepositoryStub.create.resolves(spendingPlan); ipAddressHbarSpendingPlanRepositoryStub.save.resolves(); - const result = await hbarLimitService.shouldLimit(mode, methodName, '', mockIpAddress); + const requestDetails = new RequestDetails({ requestId: 'hbarLimterTest', ipAddress: mockIpAddress }); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.false; expect(hbarSpendingPlanRepositoryStub.create.calledOnce).to.be.true; @@ -333,7 +328,8 @@ describe('HbarLimitService', function () { }); it('should return false if ipAddress is null or empty', async function () { - const result = await hbarLimitService.shouldLimit(mode, methodName, '', ''); + const requestDetails = new RequestDetails({ requestId: 'hbarLimterTest', ipAddress: '' }); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.false; }); @@ -345,7 +341,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, '', mockIpAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.true; }); @@ -358,7 +354,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, '', mockIpAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.false; }); @@ -371,7 +367,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, '', mockIpAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.true; }); @@ -387,14 +383,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit( - mode, - methodName, - '', - mockRequestId, - mockIpAddress, - mockEstimatedTxFee, - ); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails, mockEstimatedTxFee); expect(result).to.be.true; }); @@ -410,7 +399,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, '', mockIpAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.false; }); @@ -426,7 +415,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService.shouldLimit(mode, methodName, '', mockIpAddress); + const result = await hbarLimitService.shouldLimit(mode, methodName, '', requestDetails); expect(result).to.be.false; }); @@ -435,14 +424,15 @@ describe('HbarLimitService', function () { describe('getSpendingPlan', function () { it(`should return null if neither ethAddress nor ipAddress is provided`, async function () { - const ipAddresses = ['', null, undefined]; - const ethAddresses = ['', null, undefined]; + const ipAddresses = ['']; + const ethAddresses = ['']; const testCases = ethAddresses.flatMap((ethAddress) => ipAddresses.map((ipAddress) => ({ ethAddress, ipAddress })), ); for (const { ethAddress, ipAddress } of testCases) { // @ts-ignore - const result = await hbarLimitService['getSpendingPlan'](ethAddress, ipAddress); + const requestDetails = new RequestDetails({ requestId: 'hbarLimterTest', ipAddress: ipAddress }); + const result = await hbarLimitService['getSpendingPlan'](ethAddress, requestDetails); expect(result).to.be.null; } }); @@ -455,7 +445,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService['getSpendingPlan'](mockEthAddress, requestIdPrefix); + const result = await hbarLimitService['getSpendingPlan'](mockEthAddress, requestDetails); expect(result).to.deep.equal(spendingPlan); }); @@ -468,7 +458,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService['getSpendingPlan']('', mockIpAddress); + const result = await hbarLimitService['getSpendingPlan']('', requestDetails); expect(result).to.deep.equal(spendingPlan); }); @@ -477,7 +467,7 @@ describe('HbarLimitService', function () { const error = new EthAddressHbarSpendingPlanNotFoundError(mockEthAddress); ethAddressHbarSpendingPlanRepositoryStub.findByAddress.rejects(error); - const result = await hbarLimitService['getSpendingPlan'](mockEthAddress, requestIdPrefix); + const result = await hbarLimitService['getSpendingPlan'](mockEthAddress, requestDetails); expect(result).to.be.null; }); @@ -486,7 +476,7 @@ describe('HbarLimitService', function () { const error = new IPAddressHbarSpendingPlanNotFoundError(mockIpAddress); ipAddressHbarSpendingPlanRepositoryStub.findByAddress.rejects(error); - const result = await hbarLimitService['getSpendingPlan']('', mockIpAddress); + const result = await hbarLimitService['getSpendingPlan']('', requestDetails); expect(result).to.be.null; }); @@ -494,7 +484,7 @@ describe('HbarLimitService', function () { describe('getSpendingPlanByEthAddress', function () { const testGetSpendingPlanByEthAddressError = async (error: Error, errorClass: any) => { - const result = hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress, requestIdPrefix); + const result = hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress, requestDetails); await expect(result).to.be.eventually.rejectedWith(errorClass, error.message); }; @@ -532,7 +522,7 @@ describe('HbarLimitService', function () { }); hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(spendingPlan); - const result = await hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress, requestIdPrefix); + const result = await hbarLimitService['getSpendingPlanByEthAddress'](mockEthAddress, requestDetails); expect(result).to.deep.equal(spendingPlan); }); @@ -540,11 +530,13 @@ describe('HbarLimitService', function () { describe('createBasicSpendingPlan', function () { const testCreateBasicSpendingPlan = async (ethAddress: string, ipAddress?: string) => { + const requestDetails = new RequestDetails({ requestId: 'hbarLimterTest', ipAddress: ipAddress ? ipAddress : '' }); + console.log('requestDetails', requestDetails); const newSpendingPlan = createSpendingPlan(mockPlanId); hbarSpendingPlanRepositoryStub.create.resolves(newSpendingPlan); ethAddressHbarSpendingPlanRepositoryStub.save.resolves(); - const result = await hbarLimitService['createBasicSpendingPlan'](ethAddress, ipAddress); + const result = await hbarLimitService['createBasicSpendingPlan'](ethAddress, requestDetails); expect(result).to.deep.equal(newSpendingPlan); expect(hbarSpendingPlanRepositoryStub.create.calledOnce).to.be.true; @@ -613,7 +605,7 @@ describe('HbarLimitService', function () { 'updateAverageDailyUsagePerSubscriptionType', ); - await hbarLimitService.addExpense(expense, ethAddress, requestIdPrefix, ipAddress); + await hbarLimitService.addExpense(expense, ethAddress, requestDetails); expect(hbarSpendingPlanRepositoryStub.addAmountToSpentToday.calledOnceWith(mockPlanId, expense)).to.be.true; // @ts-ignore @@ -629,17 +621,18 @@ describe('HbarLimitService', function () { sinon.assert.calledOnceWithExactly(incDailyUniqueSpendingPlansCounterSpy, 1); }; - it('should throw an error if neither ethAddress nor ipAddress is provided', async function () { - const ipAddresses = ['', null, undefined]; - const ethAddresses = ['', null, undefined]; + it('should throw an error if empty ethAddress or ipAddress is provided', async function () { + const ipAddresses = ['']; + const ethAddresses = ['']; const testCases = ethAddresses.flatMap((ethAddress) => ipAddresses.map((ipAddress) => ({ ethAddress, ipAddress })), ); for (const { ethAddress, ipAddress } of testCases) { + const requestDetails = new RequestDetails({ requestId: 'hbarLimterTest', ipAddress: ipAddress }); // @ts-ignore - await expect( - hbarLimitService.addExpense(100, ethAddress, requestIdPrefix, ipAddress), - ).to.be.eventually.rejectedWith('Cannot add expense without an eth address or ip address'); + await expect(hbarLimitService.addExpense(100, ethAddress, requestDetails)).to.be.eventually.rejectedWith( + 'Cannot add expense without an eth address or ip address', + ); } }); @@ -651,7 +644,7 @@ describe('HbarLimitService', function () { ); ethAddressHbarSpendingPlanRepositoryStub.save.resolves(); - await hbarLimitService.addExpense(100, mockEthAddress, requestIdPrefix); + await hbarLimitService.addExpense(100, mockEthAddress, requestDetails); expect(hbarSpendingPlanRepositoryStub.create.calledOnce).to.be.true; expect(ethAddressHbarSpendingPlanRepositoryStub.save.calledOnce).to.be.true; @@ -677,7 +670,7 @@ describe('HbarLimitService', function () { hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(createSpendingPlan(mockPlanId)); hbarSpendingPlanRepositoryStub.addAmountToSpentToday.rejects(new Error('Failed to add expense')); - await expect(hbarLimitService.addExpense(100, mockEthAddress, requestIdPrefix)).to.be.eventually.rejectedWith( + await expect(hbarLimitService.addExpense(100, mockEthAddress, requestDetails)).to.be.eventually.rejectedWith( 'Failed to add expense', ); }); @@ -687,7 +680,9 @@ describe('HbarLimitService', function () { const testIsDailyBudgetExceeded = async (remainingBudget: number, expected: boolean) => { // @ts-ignore hbarLimitService.remainingBudget = remainingBudget; - await expect(hbarLimitService['isDailyBudgetExceeded'](mode, methodName)).to.eventually.equal(expected); + await expect( + hbarLimitService['isDailyBudgetExceeded'](mode, methodName, undefined, requestDetails), + ).to.eventually.equal(expected); }; it('should return true when the remaining budget is zero', async function () { @@ -706,7 +701,7 @@ describe('HbarLimitService', function () { hbarSpendingPlanRepositoryStub.findByIdWithDetails.resolves(createSpendingPlan(mockPlanId)); hbarSpendingPlanRepositoryStub.addAmountToSpentToday.rejects(new Error('Failed to add expense')); - await expect(hbarLimitService.addExpense(100, mockEthAddress)).to.be.eventually.rejectedWith( + await expect(hbarLimitService.addExpense(100, mockEthAddress, requestDetails)).to.be.eventually.rejectedWith( 'Failed to add expense', ); }); From c7e1ea1c353741c48a3a9ab13d83f8e51494bd42 Mon Sep 17 00:00:00 2001 From: Konstantina Blazhukova Date: Fri, 20 Sep 2024 19:09:44 +0300 Subject: [PATCH 48/48] Addresses PR comments Signed-off-by: Konstantina Blazhukova --- packages/relay/src/lib/env.txt | 150 --------------------------------- packages/server/src/server.ts | 3 - 2 files changed, 153 deletions(-) delete mode 100644 packages/relay/src/lib/env.txt diff --git a/packages/relay/src/lib/env.txt b/packages/relay/src/lib/env.txt deleted file mode 100644 index d6eea35a1f..0000000000 --- a/packages/relay/src/lib/env.txt +++ /dev/null @@ -1,150 +0,0 @@ -apiVersion: v1 -data: - BATCH_REQUESTS_ENABLED: "true" - CACHE_MAX: "4000" - CHAIN_ID: "295" - CONSENSUS_MAX_EXECUTION_TIME: "15000" - CONTRACT_CALL_GAS_LIMIT: "50000000" - CONTRACT_QUERY_TIMEOUT_RETRIES: "3" - DEFAULT_RATE_LIMIT: "200" - DEV_MODE: "false" - ETH_CALL_CACHE_TTL: "200" - ETH_CALL_DEFAULT_TO_CONSENSUS_NODE: "false" - ETH_CALL_MAX_REQUEST_PER_SDK_INSTANCE: "20" - ETH_GET_LOGS_BLOCK_RANGE_LIMIT: "1000" - ETH_POPULATE_SYNTHETIC_CONTRACT_RESULTS: "true" - FILE_APPEND_MAX_CHUNKS: "26" - HAPI_CLIENT_DURATION_RESET: "3.6e+06" - HAPI_CLIENT_ERROR_RESET: '[50]' - HAPI_CLIENT_TRANSACTION_RESET: "50" - HBAR_RATE_LIMIT_DURATION: "120000" - HBAR_RATE_LIMIT_PREEMTIVE_CHECK: "true" - HBAR_RATE_LIMIT_TINYBAR: "277777777" - HEDERA_NETWORK: '{"3.130.52.236:50211":"0.0.4"}' - HOT_FIX_FILE_APPEND_FEE: "120000000" - HOT_FIX_FILE_CREATE_FEE: "100000000" - INPUT_SIZE_LIMIT: "1" - LIMIT_DURATION: "60000" - LOG_LEVEL: trace - MIRROR_NODE_CONTRACT_RESULTS_LOGS_PG_MAX: "200" - MIRROR_NODE_GET_CONTRACT_RESULTS_RETRIES: "10" - MIRROR_NODE_HTTP_KEEP_ALIVE: "true" - MIRROR_NODE_LIMIT_PARAM: "100" - MIRROR_NODE_RETRIES: "0" - MIRROR_NODE_RETRY_DELAY: "2000" - MIRROR_NODE_TIMEOUT: "30000" - MIRROR_NODE_URL: https://mainnet-public.mirrornode.hedera.com - RATE_LIMIT_DISABLED: "false" - REDIS_ENABLED: "true" - REDIS_URL: redis://10.171.140.116:6379 - SDK_REQUEST_TIMEOUT: "15000" - SERVER_PORT: "7546" - SUBSCRIPTIONS_ENABLED: "false" - TIER_1_RATE_LIMIT: "100" - TIER_2_RATE_LIMIT: "200" - TIER_3_RATE_LIMIT: "400" - WEB_SOCKET_PORT: "8546" -kind: ConfigMap -metadata: - annotations: - meta.helm.sh/release-name: mainnet-hashio - meta.helm.sh/release-namespace: mainnet - creationTimestamp: "2023-03-01T16:40:18Z" - labels: - app: mainnet-hashio - app.kubernetes.io/instance: mainnet-hashio - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: mainnet-hashio - app.kubernetes.io/version: 0.26.0-SNAPSHOT - helm.sh/chart: hedera-json-rpc-relay-0.26.0-SNAPSHOT - managedFields: - - apiVersion: v1 - fieldsType: FieldsV1 - fieldsV1: - f:data: - .: {} - f:CHAIN_ID: {} - f:CONTRACT_QUERY_TIMEOUT_RETRIES: {} - f:DEFAULT_RATE_LIMIT: {} - f:DEV_MODE: {} - f:ETH_CALL_CACHE_TTL: {} - f:ETH_GET_LOGS_BLOCK_RANGE_LIMIT: {} - f:HAPI_CLIENT_DURATION_RESET: {} - f:HAPI_CLIENT_TRANSACTION_RESET: {} - f:INPUT_SIZE_LIMIT: {} - f:LIMIT_DURATION: {} - f:MIRROR_NODE_LIMIT_PARAM: {} - f:MIRROR_NODE_URL: {} - f:RATE_LIMIT_DISABLED: {} - f:SERVER_PORT: {} - f:SUBSCRIPTIONS_ENABLED: {} - f:TIER_1_RATE_LIMIT: {} - f:TIER_2_RATE_LIMIT: {} - f:TIER_3_RATE_LIMIT: {} - f:WEB_SOCKET_PORT: {} - f:metadata: - f:annotations: - .: {} - f:meta.helm.sh/release-name: {} - f:meta.helm.sh/release-namespace: {} - f:labels: - .: {} - f:app: {} - f:app.kubernetes.io/instance: {} - f:app.kubernetes.io/managed-by: {} - f:app.kubernetes.io/name: {} - f:app.kubernetes.io/version: {} - f:helm.sh/chart: {} - manager: helm - operation: Update - time: "2023-07-13T17:15:56Z" - - apiVersion: v1 - fieldsType: FieldsV1 - fieldsV1: - f:data: - f:HEDERA_NETWORK: {} - f:REDIS_URL: {} - manager: kubectl-edit - operation: Update - time: "2024-03-11T18:34:36Z" - - apiVersion: v1 - fieldsType: FieldsV1 - fieldsV1: - f:data: - f:BATCH_REQUESTS_ENABLED: {} - f:CACHE_MAX: {} - f:CONSENSUS_MAX_EXECUTION_TIME: {} - f:CONTRACT_CALL_GAS_LIMIT: {} - f:ETH_CALL_DEFAULT_TO_CONSENSUS_NODE: {} - f:ETH_CALL_MAX_REQUEST_PER_SDK_INSTANCE: {} - f:ETH_POPULATE_SYNTHETIC_CONTRACT_RESULTS: {} - f:FILE_APPEND_MAX_CHUNKS: {} - f:HAPI_CLIENT_ERROR_RESET: {} - f:LOG_LEVEL: {} - f:MIRROR_NODE_CONTRACT_RESULTS_LOGS_PG_MAX: {} - f:MIRROR_NODE_GET_CONTRACT_RESULTS_RETRIES: {} - f:MIRROR_NODE_HTTP_KEEP_ALIVE: {} - f:MIRROR_NODE_RETRIES: {} - f:MIRROR_NODE_RETRY_DELAY: {} - f:MIRROR_NODE_TIMEOUT: {} - f:REDIS_ENABLED: {} - f:SDK_REQUEST_TIMEOUT: {} - manager: GoogleCloudConsole - operation: Update - time: "2024-05-17T15:54:57Z" - - apiVersion: v1 - fieldsType: FieldsV1 - fieldsV1: - f:data: - f:HBAR_RATE_LIMIT_DURATION: {} - f:HBAR_RATE_LIMIT_PREEMTIVE_CHECK: {} - f:HBAR_RATE_LIMIT_TINYBAR: {} - f:HOT_FIX_FILE_APPEND_FEE: {} - f:HOT_FIX_FILE_CREATE_FEE: {} - manager: unknown - operation: Update - time: "2024-08-13T15:41:32Z" - name: mainnet-hashio - namespace: mainnet - resourceVersion: "578640270" - uid: 2465adbe-72e0-4504-85ea-ca36c790b142 diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index 7ec2272525..db557c0613 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -199,9 +199,6 @@ app.getKoaApp().use(async (ctx, next) => { const logAndHandleResponse = async (methodName: string, methodParams: any[], methodFunction: any) => { const requestDetails = app.getRequestDetails(); - logger.debug('Method name: ' + methodName); - logger.debug('Request id: ' + requestDetails.requestId); - logger.debug('Request ip: ' + requestDetails.ipAddress); try { const methodValidations = Validator.METHODS[methodName];