From aaecccb641526dc55904590aee9b34d2e2c99651 Mon Sep 17 00:00:00 2001 From: nikolay Date: Thu, 4 Dec 2025 12:30:18 +0200 Subject: [PATCH] chore: fix eslint Signed-off-by: nikolay --- .../src/lib/clients/cache/localLRUCache.ts | 24 +++--- .../relay/src/lib/clients/cache/redisCache.ts | 50 ++++++----- .../relay/src/lib/clients/mirrorNodeClient.ts | 85 ++++++++++-------- packages/relay/src/lib/clients/sdkClient.ts | 84 +++++++++++------- .../config/hbarSpendingPlanConfigService.ts | 34 +++++--- .../evmAddressHbarSpendingPlanRepository.ts | 27 +++--- .../hbarLimiter/hbarSpendingPlanRepository.ts | 34 ++------ .../ipAddressHbarSpendingPlanRepository.ts | 12 +-- packages/relay/src/lib/debug.ts | 15 ++-- .../src/lib/dispatcher/rpcMethodDispatcher.ts | 10 +-- packages/relay/src/lib/eth.ts | 86 +++++-------------- packages/relay/src/lib/relay.ts | 6 +- .../accountService/AccountService.ts | 25 +++--- .../ethService/blockService/BlockService.ts | 50 +++++------ .../contractService/ContractService.ts | 85 +++++++++--------- .../ethFilterService/FilterService.ts | 2 +- .../ethService/feeService/FeeService.ts | 20 ++--- .../rateLimiterService/RedisRateLimitStore.ts | 15 ++-- .../hbarSpendingPlanConfigService.spec.ts | 8 +- packages/relay/tests/lib/relay.spec.ts | 8 +- packages/relay/tests/lib/sdkClient.spec.ts | 14 +-- .../RedisRateLimitStore.spec.ts | 8 +- .../src/metrics/connectionLimiter.ts | 16 ++-- .../src/service/subscriptionService.ts | 38 ++++---- .../tests/unit/connectionLimiter.spec.ts | 16 +++- .../tests/unit/subscriptionService.spec.ts | 19 ++-- 26 files changed, 399 insertions(+), 392 deletions(-) diff --git a/packages/relay/src/lib/clients/cache/localLRUCache.ts b/packages/relay/src/lib/clients/cache/localLRUCache.ts index 63cf309b49..d20355f1f8 100644 --- a/packages/relay/src/lib/clients/cache/localLRUCache.ts +++ b/packages/relay/src/lib/clients/cache/localLRUCache.ts @@ -121,10 +121,10 @@ export class LocalLRUCache implements ICacheClient { const cache = this.getCacheInstance(key); const value = cache.get(prefixedKey); if (value !== undefined) { - const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, ''); - const censoredValue = JSON.stringify(value).replace(/"ipAddress":"[^"]+"/, '"ipAddress":""'); if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Returning cached value ${censoredKey}:${censoredValue} on ${callingMethod} call`); + const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, ''); + const censoredValue = JSON.stringify(value).replace(/"ipAddress":"[^"]+"/, '"ipAddress":""'); + this.logger.trace('Returning cached value %s:%s on %s call', censoredKey, censoredValue, callingMethod); } return value; } @@ -142,9 +142,8 @@ export class LocalLRUCache implements ICacheClient { const prefixedKey = this.prefixKey(key); const cache = this.getCacheInstance(key); const remainingTtl = cache.getRemainingTTL(prefixedKey); // in milliseconds - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`returning remaining TTL ${key}:${remainingTtl} on ${callingMethod} call`); - } + this.logger.trace(`returning remaining TTL %s:%s on %s call`, key, remainingTtl, callingMethod); + return remainingTtl; } @@ -171,7 +170,7 @@ export class LocalLRUCache implements ICacheClient { const message = `Caching ${censoredKey}:${censoredValue} on ${callingMethod} for ${ resolvedTtl > 0 ? `${resolvedTtl} ms` : 'indefinite time' }`; - this.logger.trace(`${message} (cache size: ${this.cache.size}, max: ${this.options.max})`); + this.logger.trace(`%s (cache size: %s, max: %s)`, message, this.cache.size, this.options.max); } } @@ -212,9 +211,9 @@ export class LocalLRUCache implements ICacheClient { */ public async delete(key: string, callingMethod: string): Promise { const prefixedKey = this.prefixKey(key); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`delete cache for ${key} on ${callingMethod} call`); - } + + this.logger.trace(`delete cache for %s on %s call`, key, callingMethod); + const cache = this.getCacheInstance(key); cache.delete(prefixedKey); } @@ -273,9 +272,8 @@ export class LocalLRUCache implements ICacheClient { const matchingKeys = keys.filter((key) => regex.test(key)); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`retrieving keys matching ${pattern} on ${callingMethod} call`); - } + this.logger.trace(`retrieving keys matching %s on %s call`, pattern, callingMethod); + // Remove the prefix from the returned keys return matchingKeys.map((key) => key.substring(LocalLRUCache.CACHE_KEY_PREFIX.length)); } diff --git a/packages/relay/src/lib/clients/cache/redisCache.ts b/packages/relay/src/lib/clients/cache/redisCache.ts index 7238343cb0..d3fd71ee5c 100644 --- a/packages/relay/src/lib/clients/cache/redisCache.ts +++ b/packages/relay/src/lib/clients/cache/redisCache.ts @@ -86,7 +86,7 @@ export class RedisCache implements IRedisCacheClient { if (this.logger.isLevelEnabled('trace')) { const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, ''); const censoredValue = result.replace(/"ipAddress":"[^"]+"/, '"ipAddress":""'); - this.logger.trace(`Returning cached value ${censoredKey}:${censoredValue} on ${callingMethod} call`); + this.logger.trace(`Returning cached value %s:%s on %s call`, censoredKey, censoredValue, callingMethod); } // TODO: add metrics return JSON.parse(result); @@ -113,13 +113,13 @@ export class RedisCache implements IRedisCacheClient { await this.client.set(prefixedKey, serializedValue); } - const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, ''); - const censoredValue = serializedValue.replace(/"ipAddress":"[^"]+"/, '"ipAddress":""'); - const message = `Caching ${censoredKey}:${censoredValue} on ${callingMethod} for ${ - resolvedTtl > 0 ? `${resolvedTtl} ms` : 'indefinite time' - }`; if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`${message}`); + const censoredKey = key.replace(Utils.IP_ADDRESS_REGEX, ''); + const censoredValue = serializedValue.replace(/"ipAddress":"[^"]+"/, '"ipAddress":""'); + const message = `Caching ${censoredKey}:${censoredValue} on ${callingMethod} for ${ + resolvedTtl > 0 ? `${resolvedTtl} ms` : 'indefinite time' + }`; + this.logger.trace(`%s`, message); } // TODO: add metrics } @@ -143,9 +143,12 @@ export class RedisCache implements IRedisCacheClient { await this.client.mSet(serializedKeyValuePairs); // Log the operation - const entriesLength = Object.keys(keyValuePairs).length; if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`); + this.logger.trace( + `caching multiple keys via %s, total keys: %s`, + callingMethod, + Object.keys(keyValuePairs).length, + ); } } @@ -171,10 +174,13 @@ export class RedisCache implements IRedisCacheClient { // Execute pipeline operation await pipeline.execAsPipeline(); + // Log the operation if (this.logger.isLevelEnabled('trace')) { - // Log the operation - const entriesLength = Object.keys(keyValuePairs).length; - this.logger.trace(`caching multiple keys via ${callingMethod}, total keys: ${entriesLength}`); + this.logger.trace( + `caching multiple keys via %s, total keys: %s`, + callingMethod, + Object.keys(keyValuePairs).length, + ); } } @@ -188,9 +194,7 @@ export class RedisCache implements IRedisCacheClient { async delete(key: string, callingMethod: string): Promise { const prefixedKey = this.prefixKey(key); await this.client.del(prefixedKey); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`delete cache for ${key} on ${callingMethod} call`); - } + this.logger.trace(`delete cache for %s on %s call`, key, callingMethod); // TODO: add metrics } @@ -205,9 +209,7 @@ export class RedisCache implements IRedisCacheClient { async incrBy(key: string, amount: number, callingMethod: string): Promise { const prefixedKey = this.prefixKey(key); const result = await this.client.incrBy(prefixedKey, amount); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`incrementing ${key} by ${amount} on ${callingMethod} call`); - } + this.logger.trace(`incrementing %s by %s on %s call`, key, amount, callingMethod); return result; } @@ -223,9 +225,7 @@ export class RedisCache implements IRedisCacheClient { async lRange(key: string, start: number, end: number, callingMethod: string): Promise { const prefixedKey = this.prefixKey(key); const result = await this.client.lRange(prefixedKey, start, end); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`retrieving range [${start}:${end}] from ${key} on ${callingMethod} call`); - } + this.logger.trace(`retrieving range [%s:%s] from %s on %s call`, start, end, key, callingMethod); return result.map((item) => JSON.parse(item)); } @@ -242,7 +242,7 @@ export class RedisCache implements IRedisCacheClient { const serializedValue = JSON.stringify(value); const result = await this.client.rPush(prefixedKey, serializedValue); if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`pushing ${serializedValue} to ${key} on ${callingMethod} call`); + this.logger.trace(`pushing %s to %s on %s call`, serializedValue, key, callingMethod); } return result; } @@ -256,9 +256,7 @@ export class RedisCache implements IRedisCacheClient { async keys(pattern: string, callingMethod: string): Promise { const prefixedPattern = this.prefixKey(pattern); const result = await this.client.keys(prefixedPattern); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`retrieving keys matching ${pattern} on ${callingMethod} call`); - } + this.logger.trace(`retrieving keys matching %s on %s call`, pattern, callingMethod); // Remove the prefix from the returned keys return result.map((key) => key.substring(RedisCache.CACHE_KEY_PREFIX.length)); } @@ -283,7 +281,7 @@ export class RedisCache implements IRedisCacheClient { await pipeline.exec(); if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Cleared ${keysToDelete.length} cache keys`); + this.logger.trace(`Cleared %s cache keys`, keysToDelete.length); } } } diff --git a/packages/relay/src/lib/clients/mirrorNodeClient.ts b/packages/relay/src/lib/clients/mirrorNodeClient.ts index 1fad449d85..36da45e1bb 100644 --- a/packages/relay/src/lib/clients/mirrorNodeClient.ts +++ b/packages/relay/src/lib/clients/mirrorNodeClient.ts @@ -225,7 +225,7 @@ export class MirrorNodeClient { retryDelay: (retryCount, error) => { const delay = mirrorNodeRetryDelay * retryCount; if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Retry delay ${delay} ms on '${error?.request?.path}'`); + this.logger.trace(`Retry delay %s ms on '%s'`, delay, error?.request?.path); } return delay; }, @@ -290,7 +290,9 @@ export class MirrorNodeClient { }); this.logger.info( - `Mirror Node client successfully configured to REST url: ${this.restUrl} and Web3 url: ${this.web3Url} `, + `Mirror Node client successfully configured to REST url: %s and Web3 url: %s `, + this.restUrl, + this.web3Url, ); this.cacheService = cacheService; @@ -377,7 +379,7 @@ export class MirrorNodeClient { try { return JSONBigInt.parse(data); } catch (error) { - this.logger.warn(`Failed to parse response data from Mirror Node: ${error}`); + this.logger.warn(`Failed to parse response data from Mirror Node: %s`, error); } } @@ -394,9 +396,12 @@ export class MirrorNodeClient { const ms = Date.now() - start; if (this.logger.isLevelEnabled('debug')) { this.logger.debug( - `Successfully received response from mirror node server: method=${method}, path=${path}, status=${ - response.status - }, duration:${ms}ms, data:${JSON.stringify(response.data)}`, + `Successfully received response from mirror node server: method=%s, path=%s, status=%s, duration:%sms, data:%s`, + method, + path, + response.status, + ms, + JSON.stringify(response.data), ); } this.mirrorResponseHistogram.labels(pathLabel, response.status?.toString()).observe(ms); @@ -451,11 +456,12 @@ export class MirrorNodeClient { const acceptedErrorResponses = MirrorNodeClient.acceptedErrorStatusesResponsePerRequestPathMap.get(pathLabel); if (error.response && acceptedErrorResponses?.includes(effectiveStatusCode)) { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `An accepted error occurred while communicating with the mirror node server: method=${method}, path=${path}, status=${effectiveStatusCode}`, - ); - } + this.logger.debug( + `An accepted error occurred while communicating with the mirror node server: method=%s, path=%s, status=%s}`, + method, + path, + effectiveStatusCode, + ); return null; } @@ -463,15 +469,22 @@ export class MirrorNodeClient { if (pathLabel === MirrorNodeClient.CONTRACT_CALL_ENDPOINT && effectiveStatusCode === 400) { if (this.logger.isLevelEnabled('debug')) { this.logger.debug( - `[${method}] ${path} Contract Revert: ( StatusCode: '${effectiveStatusCode}', StatusText: '${ - error.response.statusText - }', Detail: '${JSON.stringify(error.response.detail)}',Data: '${JSON.stringify(error.response.data)}')`, + `[%s] %s Contract Revert: ( StatusCode: '%s', StatusText: '%s', Detail: '%s',Data: '%s')`, + method, + path, + effectiveStatusCode, + error.response.statusText, + JSON.stringify(error.response.detail), + JSON.stringify(error.response.data), ); } } else { this.logger.error( new Error(error.message), - `Error encountered while communicating with the mirror node server: method=${method}, path=${path}, status=${effectiveStatusCode}`, + `Error encountered while communicating with the mirror node server: method=%s, path=%s, status=%s`, + method, + path, + effectiveStatusCode, ); } @@ -497,7 +510,7 @@ export class MirrorNodeClient { if (page === pageMax) { // max page reached if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Max page reached ${pageMax} with ${results.length} results`); + this.logger.trace(`Max page reached %s with %s results`, pageMax, results.length); } throw predefined.PAGINATION_MAX(pageMax); } @@ -575,7 +588,7 @@ export class MirrorNodeClient { const match = url.match(regex); const accountId = match ? match[1] : null; if (!accountId) { - this.logger.error(`Unable to extract evm address from url ${url}`); + this.logger.error(`Unable to extract evm address from url %s`, url); } return String(accountId); } else { @@ -583,7 +596,7 @@ export class MirrorNodeClient { const match = url.match(MirrorNodeClient.EVM_ADDRESS_REGEX); const accountId = match ? match[1] : null; if (!accountId) { - this.logger.error(`Unable to extract account ID from url ${url}`); + this.logger.error(`Unable to extract account ID from url %s`, url); } return String(accountId); } @@ -802,9 +815,9 @@ export class MirrorNodeClient { // Found immature record, log the info, set flag and exit record traversal if (this.logger.isLevelEnabled('debug')) { this.logger.debug( - `Contract result contains nullable transaction_index or block_number, or block_hash is an empty hex (0x): contract_result=${JSON.stringify( - contractObject, - )}. ${!isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``}`, + `Contract result contains nullable transaction_index or block_number, or block_hash is an empty hex (0x): contract_result=%s. %s}`, + JSON.stringify(contractObject), + !isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``, ); } @@ -991,9 +1004,9 @@ export class MirrorNodeClient { // Found immature record, log the info, set flag and exit record traversal if (this.logger.isLevelEnabled('debug')) { this.logger.debug( - `Contract result log contains nullable transaction_index, block_number, index, or block_hash is an empty hex (0x): log=${JSON.stringify( - log, - )}. ${!isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``}`, + `Contract result log contains nullable transaction_index, block_number, index, or block_hash is an empty hex (0x): log=%s. %s`, + JSON.stringify(log), + !isLastAttempt ? `Retrying after a delay of ${mirrorNodeRetryDelay} ms.` : ``, ); } @@ -1484,7 +1497,9 @@ export class MirrorNodeClient { } else { this.logger.warn( e, - `Error raised during polling mirror node for updated records: method=${methodName}, args=${args}`, + `Error raised during polling mirror node for updated records: method=%s, args=%s`, + methodName, + args, ); } } @@ -1495,9 +1510,12 @@ export class MirrorNodeClient { if (this.logger.isLevelEnabled('debug')) { this.logger.debug( - `Repeating request ${methodName} with args ${JSON.stringify( - args, - )} retry count ${i} of ${repeatCount}. Waiting ${this.MIRROR_NODE_RETRY_DELAY} ms before repeating request`, + `Repeating request %s with args %s retry count %s of %s. Waiting %s ms before repeating request`, + methodName, + JSON.stringify(args), + i, + repeatCount, + this.MIRROR_NODE_RETRY_DELAY, ); } @@ -1523,12 +1541,11 @@ export class MirrorNodeClient { operatorAccountId: string, requestDetails: RequestDetails, ): Promise { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Get transaction record via mirror node: transactionId=${transactionId}, txConstructorName=${txConstructorName}`, - ); - } - + this.logger.debug( + `Get transaction record via mirror node: transactionId=%s, txConstructorName=%s`, + transactionId, + txConstructorName, + ); // Create a modified copy of requestDetails const modifiedRequestDetails = new RequestDetails({ requestId: requestDetails.requestId, diff --git a/packages/relay/src/lib/clients/sdkClient.ts b/packages/relay/src/lib/clients/sdkClient.ts index c6410f0ece..9bbe1bbd87 100644 --- a/packages/relay/src/lib/clients/sdkClient.ts +++ b/packages/relay/src/lib/clients/sdkClient.ts @@ -223,14 +223,17 @@ export class SDKClient { let queryCost: number | undefined = undefined; let status: string = ''; - this.logger.info(`Execute ${queryConstructorName} query.`); + this.logger.info(`Execute %s query.`, queryConstructorName); try { queryResponse = await query.execute(this.clientMain); queryCost = query._queryPayment?.toTinybars().toNumber(); status = Status.Success.toString(); this.logger.info( - `Successfully execute ${queryConstructorName} query: callerName=${callerName}, cost=${queryCost} tinybars`, + `Successfully execute %s query: callerName=%s, cost=%s tinybars`, + queryConstructorName, + callerName, + queryCost, ); return queryResponse; } catch (e: any) { @@ -243,11 +246,14 @@ export class SDKClient { throw predefined.REQUEST_TIMEOUT; } - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Fail to execute ${queryConstructorName} callerName=${callerName}, status=${sdkClientError.status}(${sdkClientError.status._code}), cost=${queryCost} tinybars`, - ); - } + this.logger.debug( + `Fail to execute %s callerName=%s, status=%s(%s), cost=%s tinybars`, + queryConstructorName, + callerName, + sdkClientError.status, + sdkClientError.status._code, + queryCost, + ); throw sdkClientError; } finally { @@ -306,7 +312,7 @@ export class SDKClient { } try { - this.logger.info(`Execute ${txConstructorName} transaction`); + this.logger.info(`Execute %s transaction`, txConstructorName); transactionResponse = await transaction.execute(this.clientMain); transactionId = transactionResponse.transactionId.toString(); @@ -315,13 +321,21 @@ export class SDKClient { const transactionReceipt = await transactionResponse.getReceipt(this.clientMain); this.logger.info( - `Successfully execute ${txConstructorName} transaction: transactionId=${transactionResponse.transactionId}, callerName=${callerName}, status=${transactionReceipt.status}(${transactionReceipt.status._code})`, + `Successfully execute %s transaction: transactionId=%s, callerName=%s, status=%s(%s)`, + txConstructorName, + transactionResponse.transactionId, + callerName, + transactionReceipt.status, + transactionReceipt.status._code, ); return transactionResponse; } catch (e: any) { this.logger.warn( e, - `Transaction failed while executing transaction via the SDK: transactionId=${transaction.transactionId}, callerName=${callerName}, txConstructorName=${txConstructorName}`, + `Transaction failed while executing transaction via the SDK: transactionId=%s, callerName=%s, txConstructorName=%s`, + transaction.transactionId, + callerName, + txConstructorName, ); if (e instanceof JsonRpcError) { @@ -397,17 +411,27 @@ export class SDKClient { } try { - this.logger.info(`Execute ${txConstructorName} transaction`); + this.logger.info(`Execute %s transaction`, txConstructorName); transactionResponses = await transaction.executeAll(this.clientMain); this.logger.info( - `Successfully execute all ${transactionResponses.length} ${txConstructorName} transactions: callerName=${callerName}, status=${Status.Success}(${Status.Success._code})`, + `Successfully execute all %s %s transactions: callerName=%s, status=%s(%s)`, + transactionResponses.length, + txConstructorName, + callerName, + Status.Success, + Status.Success._code, ); } catch (e: any) { const sdkClientError = new SDKClientError(e, e.message, undefined, e.nodeAccountId); - this.logger.warn( - `Fail to executeAll for ${txConstructorName} transaction: transactionId=${transaction.transactionId}, callerName=${callerName}, transactionType=${txConstructorName}, status=${sdkClientError.status}(${sdkClientError.status._code})`, + `Fail to executeAll for %s transaction: transactionId=%s, callerName=%s, transactionType=%s, status=%s(%s)`, + txConstructorName, + transaction.transactionId, + callerName, + txConstructorName, + sdkClientError.status, + sdkClientError.status._code, ); throw sdkClientError; } finally { @@ -498,12 +522,10 @@ export class SDKClient { ); if (fileInfo.size.isZero()) { - this.logger.warn(`File ${fileId} is empty.`); + this.logger.warn(`File %s is empty.`, fileId); throw new SDKClientError({}, 'Created file is empty.'); } - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Created file with fileId: ${fileId} and file size ${fileInfo.size}`); - } + this.logger.trace(`Created file with fileId: %s and file size %s`, fileId, fileInfo.size); } return fileId; @@ -541,14 +563,12 @@ export class SDKClient { ); if (fileInfo.isDeleted) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Deleted file with fileId: ${fileId}`); - } + this.logger.trace(`Deleted file with fileId: %s`, fileId); } else { - this.logger.warn(`Fail to delete file with fileId: ${fileId} `); + this.logger.warn(`Fail to delete file with fileId: %s`, fileId); } } catch (error: any) { - this.logger.warn(`${error['message']} `); + this.logger.warn(`%s`, error['message']); } } @@ -570,11 +590,11 @@ export class SDKClient { let transactionFee: number = 0; let txRecordChargeAmount: number = 0; try { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}`, - ); - } + this.logger.debug( + `Get transaction record via consensus node: transactionId=%s, txConstructorName=%s`, + transactionId, + txConstructorName, + ); const transactionRecord = await new TransactionRecordQuery() .setTransactionId(transactionId) @@ -594,7 +614,13 @@ export class SDKClient { const sdkClientError = new SDKClientError(e, e.message); this.logger.warn( e, - `Error raised during TransactionRecordQuery: transactionId=${transactionId}, txConstructorName=${txConstructorName}, recordStatus=${sdkClientError.status} (${sdkClientError.status._code}), cost=${transactionFee}, gasUsed=${gasUsed}`, + `Error raised during TransactionRecordQuery: transactionId=%s, txConstructorName=%s, recordStatus=%s (%s), cost=%s, gasUsed=%s`, + transactionId, + txConstructorName, + sdkClientError.status, + sdkClientError.status._code, + transactionFee, + gasUsed, ); throw sdkClientError; } diff --git a/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts b/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts index ca471d22c5..8af70ab0e4 100644 --- a/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts +++ b/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts @@ -178,7 +178,8 @@ export class HbarSpendingPlanConfigService { const plansToDelete = existingPlans.filter((plan) => !spendingPlanConfigs.some((spc) => spc.id === plan.id)); for (const { id } of plansToDelete) { this.logger.info( - `Deleting HBAR spending plan with ID "${id}", as it is no longer in the spending plan configuration...`, + `Deleting HBAR spending plan with ID "%s", as it is no longer in the spending plan configuration...`, + id, ); await this.hbarSpendingPlanRepository.delete(id); await this.evmAddressHbarSpendingPlanRepository.deleteAllByPlanId(id, 'populatePreconfiguredSpendingPlans'); @@ -202,7 +203,10 @@ export class HbarSpendingPlanConfigService { for (const { id, name, subscriptionTier } of plansToAdd) { await this.hbarSpendingPlanRepository.create(subscriptionTier, this.TTL, id); this.logger.info( - `Created HBAR spending plan "${name}" with ID "${id}" and subscriptionTier "${subscriptionTier}"`, + `Created HBAR spending plan "%s" with ID "%s" and subscriptionTier "%s"`, + name, + id, + subscriptionTier, ); } return plansToAdd.length; @@ -217,11 +221,11 @@ export class HbarSpendingPlanConfigService { */ private async updatePlanAssociations(spendingPlanConfigs: SpendingPlanConfig[]): Promise { for (const planConfig of spendingPlanConfigs) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace( - `Updating associations for HBAR spending plan '${planConfig.name}' with ID ${planConfig.id}...`, - ); - } + this.logger.trace( + `Updating associations for HBAR spending plan '%s' with ID %s...`, + planConfig.name, + planConfig.id, + ); await this.deleteObsoleteEvmAddressAssociations(planConfig); await this.deleteObsoleteIpAddressAssociations(planConfig); await this.updateEvmAddressAssociations(planConfig); @@ -248,7 +252,9 @@ export class HbarSpendingPlanConfigService { addressesToDelete.map(async (evmAddress) => { await this.evmAddressHbarSpendingPlanRepository.delete(evmAddress); this.logger.info( - `Removed association between EVM address ${evmAddress} and HBAR spending plan '${planConfig.name}'`, + `Removed association between EVM address %s and HBAR spending plan '%s'`, + evmAddress, + planConfig.name, ); }), ); @@ -258,7 +264,7 @@ export class HbarSpendingPlanConfigService { await Promise.all( addressesToAdd.map(async (evmAddress) => { await this.evmAddressHbarSpendingPlanRepository.save({ evmAddress, planId: planConfig.id }, this.TTL); - this.logger.info(`Associated HBAR spending plan '${planConfig.name}' with EVM address ${evmAddress}`); + this.logger.info(`Associated HBAR spending plan '%s' with EVM address %s`, planConfig.name, evmAddress); }), ); } @@ -279,7 +285,7 @@ export class HbarSpendingPlanConfigService { await Promise.all( addressesToDelete.map(async (ipAddress) => { await this.ipAddressHbarSpendingPlanRepository.delete(ipAddress); - this.logger.info(`Removed association between IP address and HBAR spending plan '${planConfig.name}'`); + this.logger.info(`Removed association between IP address and HBAR spending plan '%s'`, planConfig.name); }), ); @@ -287,7 +293,7 @@ export class HbarSpendingPlanConfigService { await Promise.all( addressesToAdd.map(async (ipAddress) => { await this.ipAddressHbarSpendingPlanRepository.save({ ipAddress, planId: planConfig.id }, this.TTL); - this.logger.info(`Associated HBAR spending plan '${planConfig.name}' with IP address`); + this.logger.info(`Associated HBAR spending plan '%s' with IP address`, planConfig.name); }), ); } @@ -307,7 +313,9 @@ export class HbarSpendingPlanConfigService { const evmAddressPlan = await this.evmAddressHbarSpendingPlanRepository.findByAddress(evmAddress); if (evmAddressPlan.planId !== planConfig.id) { this.logger.info( - `Deleting association between EVM address ${evmAddress} and HBAR spending plan '${planConfig.name}'`, + `Deleting association between EVM address %s and HBAR spending plan '%s'`, + evmAddress, + planConfig.name, ); await this.evmAddressHbarSpendingPlanRepository.delete(evmAddress); } @@ -329,7 +337,7 @@ export class HbarSpendingPlanConfigService { if (exists) { const ipAddressPlan = await this.ipAddressHbarSpendingPlanRepository.findByAddress(ipAddress); if (ipAddressPlan.planId !== planConfig.id) { - this.logger.info(`Deleting association between IP address and HBAR spending plan '${planConfig.name}'`); + this.logger.info(`Deleting association between IP address and HBAR spending plan '%s'`, planConfig.name); await this.ipAddressHbarSpendingPlanRepository.delete(ipAddress); } } diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/evmAddressHbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/evmAddressHbarSpendingPlanRepository.ts index 5fee2d106d..2c981f3931 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/evmAddressHbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/evmAddressHbarSpendingPlanRepository.ts @@ -69,9 +69,7 @@ export class EvmAddressHbarSpendingPlanRepository { for (const key of keys) { const addressPlan = await this.cache.getAsync(key, callingMethod); if (addressPlan?.planId === planId) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Removing EVM address ${addressPlan.evmAddress} from HbarSpendingPlan with ID ${planId}`); - } + this.logger.trace(`Removing EVM address %s from HbarSpendingPlan with ID %s`, addressPlan.evmAddress, planId); await this.cache.delete(key, callingMethod); } } @@ -89,11 +87,12 @@ export class EvmAddressHbarSpendingPlanRepository { if (!addressPlan) { throw new EvmAddressHbarSpendingPlanNotFoundError(evmAddress); } - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Retrieved link between EVM address ${evmAddress} and HbarSpendingPlan with ID ${addressPlan.planId}`, - ); - } + this.logger.debug( + `Retrieved link between EVM address %s and HbarSpendingPlan with ID %s`, + evmAddress, + addressPlan.planId, + ); + return new EvmAddressHbarSpendingPlan(addressPlan); } @@ -107,11 +106,11 @@ export class EvmAddressHbarSpendingPlanRepository { async save(addressPlan: IEvmAddressHbarSpendingPlan, ttl: number): Promise { const key = this.getKey(addressPlan.evmAddress); await this.cache.set(key, addressPlan, 'save', ttl); - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Linked EVM address ${addressPlan.evmAddress} to HbarSpendingPlan with ID ${addressPlan.planId}`, - ); - } + this.logger.debug( + `Linked EVM address %s to HbarSpendingPlan with ID %s`, + addressPlan.evmAddress, + addressPlan.planId, + ); } /** @@ -128,7 +127,7 @@ export class EvmAddressHbarSpendingPlanRepository { ? `Removed EVM address ${evmAddress} from HbarSpendingPlan with ID ${evmAddressPlan.planId}` : `Trying to remove EVM address ${evmAddress}, which is not linked to a spending plan`; if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`${errorMessage}`); + this.logger.trace(`%s`, errorMessage); } } diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts index ed12b49ef1..f1da7ecaca 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/hbarSpendingPlanRepository.ts @@ -42,9 +42,7 @@ export class HbarSpendingPlanRepository { if (!plan) { throw new HbarSpendingPlanNotFoundError(id); } - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`Retrieved subscription with ID ${id}`); - } + this.logger.debug(`Retrieved subscription with ID %s`, id); return { ...plan, createdAt: new Date(plan.createdAt), @@ -81,18 +79,14 @@ export class HbarSpendingPlanRepository { spendingHistory: [], amountSpent: 0, }; - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`Creating HbarSpendingPlan with ID ${plan.id}...`); - } + this.logger.debug(`Creating HbarSpendingPlan with ID %s...`, plan.id); const key = this.getKey(plan.id); await this.cache.set(key, plan, 'create', ttl); return new HbarSpendingPlan(plan); } async delete(id: string): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Deleting HbarSpendingPlan with ID ${id}...`); - } + this.logger.trace(`Deleting HbarSpendingPlan with ID %s...`, id); const key = this.getKey(id); await this.cache.delete(key, 'delete'); } @@ -117,9 +111,7 @@ export class HbarSpendingPlanRepository { async getSpendingHistory(id: string): Promise { await this.checkExistsAndActive(id); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Retrieving spending history for HbarSpendingPlan with ID ${id}...`); - } + this.logger.trace(`Retrieving spending history for HbarSpendingPlan with ID %s...`, id); const key = this.getSpendingHistoryKey(id); const spendingHistory = await this.cache.lRange(key, 0, -1, 'getSpendingHistory'); return spendingHistory.map((entry) => new HbarSpendingRecord(entry)); @@ -134,9 +126,7 @@ export class HbarSpendingPlanRepository { async addAmountToSpendingHistory(id: string, amount: number): Promise { await this.checkExistsAndActive(id); - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Adding ${amount} to spending history for HbarSpendingPlan with ID ${id}...`); - } + this.logger.trace(`Adding %s to spending history for HbarSpendingPlan with ID %s...`, amount, id); const key = this.getSpendingHistoryKey(id); const entry: IHbarSpendingRecord = { amount, timestamp: new Date() }; return this.cache.rPush(key, entry, 'addAmountToSpendingHistory'); @@ -150,9 +140,7 @@ export class HbarSpendingPlanRepository { async getAmountSpent(id: string): Promise { await this.checkExistsAndActive(id); - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`Retrieving amountSpent for HbarSpendingPlan with ID ${id}...`); - } + this.logger.debug(`Retrieving amountSpent for HbarSpendingPlan with ID %s...`, id); const key = this.getAmountSpentKey(id); return this.cache.getAsync(key, 'getAmountSpent').then((amountSpent) => parseInt(amountSpent ?? '0')); } @@ -169,7 +157,7 @@ export class HbarSpendingPlanRepository { const keys = await this.cache.keys(this.getAmountSpentKey('*'), callerMethod); await Promise.all(keys.map((key) => this.cache.delete(key, callerMethod))); if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Successfully reset ${keys.length} "amountSpent" entries for HbarSpendingPlans.`); + this.logger.trace(`Successfully reset %s "amountSpent" entries for HbarSpendingPlans.`, keys.length); } } @@ -185,14 +173,10 @@ export class HbarSpendingPlanRepository { const key = this.getAmountSpentKey(id); if (!(await this.cache.getAsync(key, 'addToAmountSpent'))) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`No spending yet for HbarSpendingPlan with ID ${id}, setting amountSpent to ${amount}...`); - } + this.logger.trace(`No spending yet for HbarSpendingPlan with ID %s, setting amountSpent to %s...`, id, amount); await this.cache.set(key, amount, 'addToAmountSpent', ttl); } else { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`Adding ${amount} to amountSpent for HbarSpendingPlan with ID ${id}...`); - } + this.logger.debug(`Adding %s to amountSpent for HbarSpendingPlan with ID %s...`, amount, id); await this.cache.incrBy(key, amount, 'addToAmountSpent'); } } diff --git a/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts b/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts index f1b973a908..fb6234b6f4 100644 --- a/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts +++ b/packages/relay/src/lib/db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository.ts @@ -69,9 +69,7 @@ export class IPAddressHbarSpendingPlanRepository { for (const key of keys) { const addressPlan = await this.cache.getAsync(key, callingMethod); if (addressPlan?.planId === planId) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Removing IP address from HbarSpendingPlan with ID ${planId}`); - } + this.logger.trace(`Removing IP address from HbarSpendingPlan with ID %s`, planId); await this.cache.delete(key, callingMethod); } } @@ -89,9 +87,7 @@ export class IPAddressHbarSpendingPlanRepository { if (!addressPlan) { throw new IPAddressHbarSpendingPlanNotFoundError(ipAddress); } - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Retrieved link between IP address and HbarSpendingPlan with ID ${addressPlan.planId}`); - } + this.logger.trace(`Retrieved link between IP address and HbarSpendingPlan with ID %s`, addressPlan.planId); return new IPAddressHbarSpendingPlan(addressPlan); } @@ -105,7 +101,7 @@ export class IPAddressHbarSpendingPlanRepository { async save(addressPlan: IIPAddressHbarSpendingPlan, ttl: number): Promise { const key = this.getKey(addressPlan.ipAddress); await this.cache.set(key, addressPlan, 'save', ttl); - this.logger.trace(`Linked new IP address to HbarSpendingPlan with ID ${addressPlan.planId}`); + this.logger.trace(`Linked new IP address to HbarSpendingPlan with ID %s`, addressPlan.planId); } /** @@ -122,7 +118,7 @@ export class IPAddressHbarSpendingPlanRepository { ? `Removed IP address from HbarSpendingPlan with ID ${ipAddressSpendingPlan.planId}` : `Trying to remove an IP address, which is not linked to a spending plan`; if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`${errorMessage}`); + this.logger.trace(`%s`, errorMessage); } } diff --git a/packages/relay/src/lib/debug.ts b/packages/relay/src/lib/debug.ts index d063b09beb..848629ad74 100644 --- a/packages/relay/src/lib/debug.ts +++ b/packages/relay/src/lib/debug.ts @@ -115,9 +115,7 @@ export class DebugImpl implements Debug { tracerObject: TransactionTracerConfig, requestDetails: RequestDetails, ): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`traceTransaction(${transactionIdOrHash})`); - } + this.logger.trace(`traceTransaction(%s)`, transactionIdOrHash); //we use a wrapper since we accept a transaction where a second param with tracer/tracerConfig may not be provided //and we will still default to opcodeLogger @@ -200,7 +198,11 @@ export class DebugImpl implements Debug { requestDetails: RequestDetails, ): Promise { if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`traceBlockByNumber(blockNumber=${blockNumber}, tracerObject=${JSON.stringify(tracerObject)})`); + this.logger.trace( + `traceBlockByNumber(blockNumber=%s, tracerObject=%s)`, + blockNumber, + JSON.stringify(tracerObject), + ); } try { @@ -625,7 +627,10 @@ export class DebugImpl implements Debug { } } catch (error) { this.logger.error( - `Error processing entity ${accountEntity.address} for transaction ${transactionHash}: ${error}`, + `Error processing entity %s for transaction %s: %s`, + accountEntity.address, + transactionHash, + error, ); } }), diff --git a/packages/relay/src/lib/dispatcher/rpcMethodDispatcher.ts b/packages/relay/src/lib/dispatcher/rpcMethodDispatcher.ts index 514be8d028..68c4846118 100644 --- a/packages/relay/src/lib/dispatcher/rpcMethodDispatcher.ts +++ b/packages/relay/src/lib/dispatcher/rpcMethodDispatcher.ts @@ -79,9 +79,7 @@ export class RpcMethodDispatcher { const operationHandler = this.methodRegistry.get(rpcMethodName); if (!operationHandler) { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`RPC method not found in registry: rpcMethodName=${rpcMethodName}`); - } + this.logger.debug(`RPC method not found in registry: rpcMethodName=%s`, rpcMethodName); throw this.throwUnregisteredRpcMethods(rpcMethodName); } @@ -92,7 +90,9 @@ export class RpcMethodDispatcher { if (methodParamSchemas) { if (this.logger.isLevelEnabled('info')) { this.logger.info( - `Validating method parameters for ${rpcMethodName}, params: ${JSON.stringify(rpcMethodParams)}`, + `Validating method parameters for %s, params: %s`, + rpcMethodName, + JSON.stringify(rpcMethodParams), ); } validateParams(rpcMethodParams, methodParamSchemas); @@ -152,7 +152,7 @@ export class RpcMethodDispatcher { */ private handleRpcMethodError(error: any, rpcMethodName: string): JsonRpcError { const errorMessage = error?.message?.toString() || 'Unknown error'; - this.logger.error(`Error executing method: rpcMethodName=${rpcMethodName}, error=${errorMessage}`); + this.logger.error(`Error executing method: rpcMethodName=%s, error=%s`, rpcMethodName, errorMessage); // If error is already a JsonRpcError, use it directly if (error instanceof JsonRpcError) { diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 53e13cc66f..a5e3b313b8 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -216,9 +216,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) async blockNumber(requestDetails: RequestDetails): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`blockNumber()`); - } + this.logger.trace(`blockNumber()`); return await this.common.getLatestBlockNumber(requestDetails); } @@ -235,9 +233,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) chainId(): string { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`chainId()`); - } + this.logger.trace(`chainId()`); return this.chain; } @@ -305,9 +301,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) async mining(): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('mining()'); - } + this.logger.trace('mining()'); return false; } @@ -328,7 +322,7 @@ export class EthImpl implements Eth { }) async newFilter(params: INewFilterParams, requestDetails: RequestDetails): Promise { if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`newFilter(params=${JSON.stringify(params)})`); + this.logger.trace(`newFilter(params=%s)`, JSON.stringify(params)); } return this.filterService.newFilter(params, requestDetails); } @@ -348,9 +342,7 @@ export class EthImpl implements Eth { 0: { type: 'hex', required: true }, }) async getFilterLogs(filterId: string, requestDetails: RequestDetails): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getFilterLogs(${filterId})`); - } + this.logger.trace(`getFilterLogs(%s)`, filterId); return this.filterService.getFilterLogs(filterId, requestDetails); } @@ -369,9 +361,7 @@ export class EthImpl implements Eth { 0: { type: 'hex', required: true }, }) async getFilterChanges(filterId: string, requestDetails: RequestDetails): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getFilterChanges(${filterId})`); - } + this.logger.trace(`getFilterChanges(%s)`, filterId); return this.filterService.getFilterChanges(filterId, requestDetails); } @@ -387,9 +377,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) async newBlockFilter(requestDetails: RequestDetails): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('newBlockFilter()'); - } + this.logger.trace('newBlockFilter()'); return this.filterService.newBlockFilter(requestDetails); } @@ -407,9 +395,7 @@ export class EthImpl implements Eth { 0: { type: 'hex', required: true }, }) async uninstallFilter(filterId: string): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`uninstallFilter(${filterId})`); - } + this.logger.trace(`uninstallFilter(%s)`, filterId); return this.filterService.uninstallFilter(filterId); } @@ -425,9 +411,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) newPendingTransactionFilter(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('newPendingTransactionFilter()'); - } + this.logger.trace('newPendingTransactionFilter()'); return predefined.UNSUPPORTED_METHOD; } @@ -437,9 +421,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) async submitWork(): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('submitWork()'); - } + this.logger.trace('submitWork()'); return false; } @@ -449,9 +431,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) async syncing(): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('syncing()'); - } + this.logger.trace('syncing()'); return false; } @@ -533,9 +513,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) async hashrate(): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('hashrate()'); - } + this.logger.trace('hashrate()'); return constants.ZERO_HEX; } @@ -550,9 +528,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) getWork(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('getWork()'); - } + this.logger.trace('getWork()'); return predefined.UNSUPPORTED_METHOD; } @@ -567,9 +543,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) submitHashrate(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('submitHashrate()'); - } + this.logger.trace('submitHashrate()'); return predefined.UNSUPPORTED_METHOD; } @@ -626,9 +600,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) protocolVersion(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('protocolVersion()'); - } + this.logger.trace('protocolVersion()'); return predefined.UNSUPPORTED_METHOD; } @@ -643,9 +615,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) coinbase(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('coinbase()'); - } + this.logger.trace('coinbase()'); return predefined.UNSUPPORTED_METHOD; } @@ -660,9 +630,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) simulateV1(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('simulateV1()'); - } + this.logger.trace('simulateV1()'); return predefined.UNSUPPORTED_METHOD; } @@ -677,9 +645,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) blobBaseFee(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('blobBaseFee()'); - } + this.logger.trace('blobBaseFee()'); return predefined.UNSUPPORTED_METHOD; } @@ -993,9 +959,7 @@ export class EthImpl implements Eth { ); // log request info and increment metrics counter const callDataSize = callData ? callData.length : 0; - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`call data size: ${callDataSize}`); - } + this.logger.trace(`call data size: %s`, callDataSize); this.eventEmitter.emit('eth_execution', { method: constants.ETH_CALL, @@ -1102,9 +1066,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) async maxPriorityFeePerGas(): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('maxPriorityFeePerGas()'); - } + this.logger.trace('maxPriorityFeePerGas()'); return constants.ZERO_HEX; } @@ -1143,9 +1105,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) getProof(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('getProof()'); - } + this.logger.trace('getProof()'); return predefined.UNSUPPORTED_METHOD; } @@ -1161,9 +1121,7 @@ export class EthImpl implements Eth { @rpcMethod @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY) createAccessList(): JsonRpcError { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('createAccessList()'); - } + this.logger.trace('createAccessList()'); return predefined.UNSUPPORTED_METHOD; } } diff --git a/packages/relay/src/lib/relay.ts b/packages/relay/src/lib/relay.ts index edc61ddd09..ed5edb2bc8 100644 --- a/packages/relay/src/lib/relay.ts +++ b/packages/relay/src/lib/relay.ts @@ -173,10 +173,10 @@ export class Relay { .populatePreconfiguredSpendingPlans() .then((plansUpdated) => { if (plansUpdated > 0) { - this.logger.info('Pre-configured spending plans populated successfully'); + this.logger.info(`Pre-configured spending plans populated successfully`); } }) - .catch((e) => this.logger.warn(`Failed to load pre-configured spending plans: ${e.message}`)); + .catch((e) => this.logger.warn(`Failed to load pre-configured spending plans: %s`, e.message)); } /** @@ -411,7 +411,7 @@ export class Relay { if (balance === BigInt(0)) { throw new Error(`Operator account '${operator}' has no balance`); } else { - this.logger.info(`Operator account '${operator}' has balance: ${balance}`); + this.logger.info(`Operator account '%s' has balance: %s`, operator, balance); } } diff --git a/packages/relay/src/lib/services/ethService/accountService/AccountService.ts b/packages/relay/src/lib/services/ethService/accountService/AccountService.ts index f60445809c..a78bf80077 100644 --- a/packages/relay/src/lib/services/ethService/accountService/AccountService.ts +++ b/packages/relay/src/lib/services/ethService/accountService/AccountService.ts @@ -112,9 +112,7 @@ export class AccountService implements IAccountService { blockNumberOrTagOrHash: string, requestDetails: RequestDetails, ): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getBalance(account=${account}, blockNumberOrTag=${blockNumberOrTagOrHash})`); - } + this.logger.trace(`getBalance(account=%s, blockNumberOrTag=%s)`, account, blockNumberOrTagOrHash); let latestBlock: LatestBlockNumberTimestamp | null | undefined; // this check is required, because some tools like Metamask pass for parameter latest block, with a number (ex 0x30ea) @@ -162,9 +160,10 @@ export class AccountService implements IAccountService { if (!balanceFound) { if (this.logger.isLevelEnabled('debug')) { this.logger.debug( - `Unable to find account ${account} in block ${JSON.stringify( - blockNumber, - )}(${blockNumberOrTagOrHash}), returning 0x0 balance`, + `Unable to find account %s in block %s (%s), returning 0x0 balance`, + account, + JSON.stringify(blockNumber), + blockNumberOrTagOrHash, ); } return constants.ZERO_HEX; @@ -190,7 +189,7 @@ export class AccountService implements IAccountService { if (blockNumberCached) { if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`returning cached value ${cacheKey}:${JSON.stringify(blockNumberCached)}`); + this.logger.trace(`returning cached value %s:%s`, cacheKey, JSON.stringify(blockNumberCached)); } latestBlock = { blockNumber: blockNumberCached, timeStampTo: '0' }; } else { @@ -312,9 +311,7 @@ export class AccountService implements IAccountService { blockNumOrTag: string, requestDetails: RequestDetails, ): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getTransactionCount(address=${address}, blockNumOrTag=${blockNumOrTag})`); - } + this.logger.trace(`getTransactionCount(address=%s, blockNumOrTag=%s)`, address, blockNumOrTag); const blockNum = Number(blockNumOrTag); if (blockNum === 0 || blockNum === 1) { @@ -345,9 +342,7 @@ export class AccountService implements IAccountService { caller: string, requestDetails: RequestDetails, ): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`blockNumber()`); - } + this.logger.trace(`blockNumber()`); const cacheKey = `${constants.CACHE_KEY.ETH_BLOCK_NUMBER}`; @@ -492,7 +487,9 @@ export class AccountService implements IAccountService { if (accountResult.evm_address !== address.toLowerCase()) { this.logger.warn( - `eth_transactionCount for a historical block was requested where address: ${address} was not sender: ${transactionResult.address}, returning latest value as best effort.`, + `eth_transactionCount for a historical block was requested where address: %s was not sender: %s, returning latest value as best effort.`, + address, + transactionResult.address, ); return await this.getAccountLatestEthereumNonce(address, requestDetails); } diff --git a/packages/relay/src/lib/services/ethService/blockService/BlockService.ts b/packages/relay/src/lib/services/ethService/blockService/BlockService.ts index b320ee94fb..223e66af30 100644 --- a/packages/relay/src/lib/services/ethService/blockService/BlockService.ts +++ b/packages/relay/src/lib/services/ethService/blockService/BlockService.ts @@ -84,7 +84,7 @@ export class BlockService implements IBlockService { showDetails: boolean, requestDetails: RequestDetails, ): Promise { - this.logger.trace(`getBlockByHash(hash=${hash}, showDetails=${showDetails})`); + this.logger.trace(`getBlockByHash(hash=%s, showDetails=%s)`, hash, showDetails); return this.getBlock(hash, showDetails, requestDetails).catch((e: any) => { throw this.common.genericErrorHandler(e, `Failed to retrieve block for hash ${hash}`); @@ -104,7 +104,7 @@ export class BlockService implements IBlockService { showDetails: boolean, requestDetails: RequestDetails, ): Promise { - this.logger.trace(`getBlockByNumber(blockNumber=${blockNumber}, showDetails=${showDetails})`); + this.logger.trace(`getBlockByNumber(blockNumber=%s, showDetails=%s)`, blockNumber, showDetails); return this.getBlock(blockNumber, showDetails, requestDetails).catch((e: any) => { throw this.common.genericErrorHandler(e, `Failed to retrieve block for blockNumber ${blockNumber}`); @@ -123,7 +123,7 @@ export class BlockService implements IBlockService { requestDetails: RequestDetails, ): Promise { if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getBlockReceipt(${JSON.stringify(blockHashOrBlockNumber)})`); + this.logger.trace(`getBlockReceipt(%s)`, JSON.stringify(blockHashOrBlockNumber)); } const block = await this.common.getHistoricalBlockResponse(requestDetails, blockHashOrBlockNumber); @@ -157,11 +157,11 @@ export class BlockService implements IBlockService { const receiptPromises = contractResults.map(async (contractResult) => { if (Utils.isRevertedDueToHederaSpecificValidation(contractResult)) { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Transaction with hash ${contractResult.hash} is skipped due to hedera-specific validation failure (${contractResult.result})`, - ); - } + this.logger.debug( + `Transaction with hash %s is skipped due to hedera-specific validation failure (%s)`, + contractResult.hash, + contractResult.result, + ); return null; } @@ -208,7 +208,7 @@ export class BlockService implements IBlockService { * @returns {Promise} The transaction count */ async getBlockTransactionCountByHash(hash: string, requestDetails: RequestDetails): Promise { - this.logger.trace(`getBlockTransactionCountByHash(hash=${hash}, showDetails=%o)`); + this.logger.trace(`getBlockTransactionCountByHash(hash=%s)`, hash); try { const block = await this.mirrorNodeClient.getBlock(hash, requestDetails); @@ -229,7 +229,7 @@ export class BlockService implements IBlockService { requestDetails: RequestDetails, ): Promise { if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getBlockTransactionCountByNumber(blockNum=${blockNumOrTag}, showDetails=%o)`); + this.logger.trace(`getBlockTransactionCountByNumber(blockNum=%s)`, blockNumOrTag); } const blockNum = await this.common.translateBlockTag(blockNumOrTag, requestDetails); @@ -249,9 +249,7 @@ export class BlockService implements IBlockService { * @returns null as Hedera does not support uncle blocks */ getUncleByBlockHashAndIndex(blockHash: string, index: string): null { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getUncleByBlockHashAndIndex(blockHash=${blockHash}, index=${index})`); - } + this.logger.trace(`getUncleByBlockHashAndIndex(blockHash=%s, index=%s)`, blockHash, index); return null; } @@ -263,9 +261,7 @@ export class BlockService implements IBlockService { * @returns null as Hedera does not support uncle blocks */ getUncleByBlockNumberAndIndex(blockNumOrTag: string, index: string): null { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getUncleByBlockNumberAndIndex(blockNumOrTag=${blockNumOrTag}, index=${index})`); - } + this.logger.trace(`getUncleByBlockNumberAndIndex(blockNumOrTag=%s, index=%s)`, blockNumOrTag, index); return null; } @@ -276,9 +272,7 @@ export class BlockService implements IBlockService { * @returns '0x0' as Hedera does not support uncle blocks */ getUncleCountByBlockHash(blockHash: string): string { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getUncleCountByBlockHash(blockHash=${blockHash})`); - } + this.logger.trace(`getUncleCountByBlockHash(blockHash=%s)`, blockHash); return constants.ZERO_HEX; } @@ -289,9 +283,7 @@ export class BlockService implements IBlockService { * @returns '0x0' as Hedera does not support uncle blocks */ getUncleCountByBlockNumber(blockNumOrTag: string): string { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getUncleCountByBlockNumber(blockNumOrTag=${blockNumOrTag})`); - } + this.logger.trace(`getUncleCountByBlockNumber(blockNumOrTag=%s)`, blockNumOrTag); return constants.ZERO_HEX; } @@ -429,9 +421,7 @@ export class BlockService implements IBlockService { }); } - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Synthetic transaction hashes will be populated in the block response`); - } + this.logger.trace(`Synthetic transaction hashes will be populated in the block response`); transactionsArray = _.uniqWith(transactionsArray as string[], _.isEqual); return transactionsArray; @@ -454,11 +444,11 @@ export class BlockService implements IBlockService { // there are several hedera-specific validations that occur right before entering the evm // if a transaction has reverted there, we should not include that tx in the block response if (Utils.isRevertedDueToHederaSpecificValidation(contractResult)) { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Transaction with hash ${contractResult.hash} is skipped due to hedera-specific validation failure (${contractResult.result})`, - ); - } + this.logger.debug( + `Transaction with hash %s is skipped due to hedera-specific validation failure (%s)`, + contractResult.hash, + contractResult.result, + ); continue; } diff --git a/packages/relay/src/lib/services/ethService/contractService/ContractService.ts b/packages/relay/src/lib/services/ethService/contractService/ContractService.ts index 578690af6e..8916df9d24 100644 --- a/packages/relay/src/lib/services/ethService/contractService/ContractService.ts +++ b/packages/relay/src/lib/services/ethService/contractService/ContractService.ts @@ -100,9 +100,7 @@ export class ContractService implements IContractService { * @returns An empty array of addresses */ public accounts(): [] { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`accounts()`); - } + this.logger.trace(`accounts()`); return []; } @@ -130,7 +128,7 @@ export class ContractService implements IContractService { const result = await this.callMirrorNode(call, gas, call.value, blockNumberOrTag, requestDetails); if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`eth_call response: ${JSON.stringify(result)}`); + this.logger.debug(`eth_call response: %s`, JSON.stringify(result)); } return result; @@ -161,21 +159,21 @@ export class ContractService implements IContractService { requestDetails: RequestDetails, ): Promise { if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`estimateGas(transaction=${JSON.stringify(transaction)}, blockParam=${blockParam})`); + this.logger.trace(`estimateGas(transaction=%s, blockParam=%s)`, JSON.stringify(transaction), blockParam); } try { const response = await this.estimateGasFromMirrorNode(transaction, requestDetails); if (response?.result) { - this.logger.info(`Returning gas: ${response.result}`); + this.logger.info(`Returning gas: %s`, response.result); return prepend0x(trimPrecedingZeros(response.result)); } else { - this.logger.error(`No gas estimate returned from mirror-node: ${JSON.stringify(response)}`); + this.logger.error(`No gas estimate returned from mirror-node: %s`, JSON.stringify(response)); return this.predefinedGasForTransaction(transaction, requestDetails); } } catch (e: any) { - this.logger.error(`Error raised while fetching estimateGas from mirror-node: ${JSON.stringify(e)}`); + this.logger.error(`Error raised while fetching estimateGas from mirror-node: %s`, JSON.stringify(e)); // in case of contract revert, we don't want to return a predefined gas but the actual error with the reason if ( ConfigService.get('ESTIMATE_GAS_THROWS') && @@ -202,16 +200,12 @@ export class ContractService implements IContractService { `The value passed is not a valid blockHash/blockNumber/blockTag value: ${blockNumber}`, ); } - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`getCode(address=${address}, blockNumber=${blockNumber})`); - } + this.logger.trace(`getCode(address=%s, blockNumber=%s)`, address, blockNumber); // check for static precompile cases first before consulting nodes // this also account for environments where system entities were not yet exposed to the mirror node if (address === constants.HTS_ADDRESS) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`HTS precompile case, return ${constants.INVALID_EVM_INSTRUCTION} for byte code`); - } + this.logger.trace(`HTS precompile case, return %s for byte code`, constants.INVALID_EVM_INSTRUCTION); return constants.INVALID_EVM_INSTRUCTION; } @@ -226,9 +220,7 @@ export class ContractService implements IContractService { return constants.EMPTY_HEX; } if (result.type === constants.TYPE_TOKEN) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`Token redirect case, return redirectBytecode`); - } + this.logger.trace(`Token redirect case, return redirectBytecode`); return CommonService.redirectBytecodeAddressReplace(address); } else if (result.type === constants.TYPE_CONTRACT) { if (result.entity.runtime_bytecode !== constants.EMPTY_HEX) { @@ -237,14 +229,15 @@ export class ContractService implements IContractService { } } - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`Address ${address} is not a contract nor an HTS token, returning empty hex`); - } + this.logger.debug(`Address %s is not a contract nor an HTS token, returning empty hex`, address); return constants.EMPTY_HEX; } catch (error: any) { this.logger.error( - `Error raised during getCode: address=${address}, blockNumber=${blockNumber}, error=${error.message}`, + `Error raised during getCode: address=%s, blockNumber=%s, error=%s`, + address, + blockNumber, + error.message, ); throw error; } @@ -283,11 +276,12 @@ export class ContractService implements IContractService { blockNumberOrTagOrHash: string, requestDetails: RequestDetails, ): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace( - `getStorageAt(address=${address}, slot=${slot}, blockNumberOrOrHashTag=${blockNumberOrTagOrHash})`, - ); - } + this.logger.trace( + `getStorageAt(address=%s, slot=%s, blockNumberOrOrHashTag=%s)`, + address, + slot, + blockNumberOrTagOrHash, + ); let result = constants.ZERO_HEX_32_BYTE; // if contract or slot not found then return 32 byte 0 @@ -336,14 +330,14 @@ export class ContractService implements IContractService { ): Promise { try { if (this.logger.isLevelEnabled('debug')) { - this.logger.debug({ - msg: `Making eth_call on contract ${call.to} with gas ${gas} and call data "${call.data}" from "${call.from}" at blockBlockNumberOrTag: "${block}" using mirror-node.`, - to: call.to, + this.logger.debug( + `Making eth_call on contract %s with gas %s and call data "%s" from "%s" at blockBlockNumberOrTag: "%s" using mirror-node.`, + call.to, gas, - data: call.data, - from: call.from, + call.data, + call.from, block, - }); + ); } const callData = this.prepareMirrorNodeCallData(call, gas, value, block); return await this.executeMirrorNodeCall(callData, requestDetails); @@ -500,11 +494,11 @@ export class ContractService implements IContractService { // With values over the gas limit, the call will fail with BUSY error so we cap it at 15_000_000 const gas = Number.parseInt(gasString); if (gas > constants.MAX_GAS_PER_SEC) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace( - `eth_call gas amount (${gas}) exceeds network limit, capping gas to ${constants.MAX_GAS_PER_SEC}`, - ); - } + this.logger.trace( + `eth_call gas amount (%s) exceeds network limit, capping gas to %s`, + gas, + constants.MAX_GAS_PER_SEC, + ); return constants.MAX_GAS_PER_SEC; } @@ -524,11 +518,12 @@ export class ContractService implements IContractService { } if (e.isContractReverted()) { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace( - `mirror node eth_call request encountered contract revert. message: ${e.message}, details: ${e.detail}, data: ${e.data}`, - ); - } + this.logger.trace( + `mirror node eth_call request encountered contract revert. message: %s, details: %s, data: %s`, + e.message, + e.detail, + e.data, + ); return predefined.CONTRACT_REVERT(e.detail || e.message, e.data); } // for any other Mirror Node upstream server errors (429, 500, 502, 503, 504, etc.), preserve the original error and re-throw to the upper layer @@ -606,13 +601,13 @@ export class ContractService implements IContractService { ) { return predefined.CONTRACT_REVERT(error.detail, error.data); } - this.logger.warn(`Returning predefined gas for contract creation: ${gasTxBaseCost}`); + this.logger.warn(`Returning predefined gas for contract creation: %s`, gasTxBaseCost); return numberTo0x(Precheck.transactionIntrinsicGasCost(transaction.data!)); } else if (isContractCall) { - this.logger.warn(`Returning predefined gas for contract call: ${contractCallAverageGas}`); + this.logger.warn(`Returning predefined gas for contract call: %s`, contractCallAverageGas); return contractCallAverageGas; } else { - this.logger.warn(`Returning predefined gas for unknown transaction: ${this.defaultGas}`); + this.logger.warn(`Returning predefined gas for unknown transaction: %s`, this.defaultGas); return this.defaultGas; } } diff --git a/packages/relay/src/lib/services/ethService/ethFilterService/FilterService.ts b/packages/relay/src/lib/services/ethService/ethFilterService/FilterService.ts index 6071a375d2..5f47694286 100644 --- a/packages/relay/src/lib/services/ethService/ethFilterService/FilterService.ts +++ b/packages/relay/src/lib/services/ethService/ethFilterService/FilterService.ts @@ -110,7 +110,7 @@ export class FilterService implements IFilterService { await this.updateFilterCache(filterId, type, params, null, this.ethNewFilter); if (this.logger.isLevelEnabled('trace')) { - this.logger.trace(`created filter with TYPE=${type}, params: ${JSON.stringify(params)}`); + this.logger.trace(`created filter with TYPE=%s, params: %s`, type, JSON.stringify(params)); } return filterId; } diff --git a/packages/relay/src/lib/services/ethService/feeService/FeeService.ts b/packages/relay/src/lib/services/ethService/feeService/FeeService.ts index b626fe2742..3fe4f633f1 100644 --- a/packages/relay/src/lib/services/ethService/feeService/FeeService.ts +++ b/packages/relay/src/lib/services/ethService/feeService/FeeService.ts @@ -67,12 +67,12 @@ export class FeeService implements IFeeService { : Number(ConfigService.get('FEE_HISTORY_MAX_RESULTS')); const maxRewardPercentilesSize = constants.FEE_HISTORY_REWARD_PERCENTILES_MAX_SIZE; - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace( - `feeHistory(blockCount=${blockCount}, newestBlock=${newestBlock}, rewardPercentiles=${rewardPercentiles})`, - ); - } - + this.logger.trace( + `feeHistory(blockCount=%s, newestBlock=%s, rewardPercentiles=%s)`, + blockCount, + newestBlock, + rewardPercentiles, + ); if (rewardPercentiles && rewardPercentiles.length > maxRewardPercentilesSize) { throw predefined.INVALID_PARAMETER( 2, @@ -139,9 +139,7 @@ export class FeeService implements IFeeService { * @param requestDetails */ public async maxPriorityFeePerGas(): Promise { - if (this.logger.isLevelEnabled('trace')) { - this.logger.trace('maxPriorityFeePerGas()'); - } + this.logger.trace('maxPriorityFeePerGas()'); return constants.ZERO_HEX; } @@ -243,7 +241,9 @@ export class FeeService implements IFeeService { } catch (error) { this.logger.warn( error, - `Fee history cannot retrieve block or fee. Returning ${fee} fee for block ${blockNumber}`, + `Fee history cannot retrieve block or fee. Returning %s fee for block %s`, + fee, + blockNumber, ); } diff --git a/packages/relay/src/lib/services/rateLimiterService/RedisRateLimitStore.ts b/packages/relay/src/lib/services/rateLimiterService/RedisRateLimitStore.ts index f7cdab2085..5e08fc3347 100644 --- a/packages/relay/src/lib/services/rateLimiterService/RedisRateLimitStore.ts +++ b/packages/relay/src/lib/services/rateLimiterService/RedisRateLimitStore.ts @@ -59,7 +59,7 @@ export class RedisRateLimitStore implements RateLimitStore { socket: { reconnectStrategy: (retries: number) => { const delay = retries * reconnectDelay; - this.logger.warn(`Rate limiter Redis reconnection attempt #${retries}. Delay: ${delay}ms`); + this.logger.warn(`Rate limiter Redis reconnection attempt #%s. Delay: %sms`, retries, delay); return delay; }, }, @@ -87,9 +87,9 @@ export class RedisRateLimitStore implements RateLimitStore { this.connected = Promise.resolve(false); const redisError = new RedisCacheError(error); if (redisError.isSocketClosed()) { - this.logger.error(`Rate limiter Redis error when closing socket: ${redisError.message}`); + this.logger.error(`Rate limiter Redis error when closing socket: %s`, redisError.message); } else { - this.logger.error(`Rate limiter Redis error: ${redisError.fullError}`); + this.logger.error(`Rate limiter Redis error: %s`, redisError.fullError); } }); } @@ -129,10 +129,13 @@ export class RedisRateLimitStore implements RateLimitStore { } const errorMessage = error instanceof Error ? error.message : String(error); - this.logger.error({ - msg: `Rate limit store operation failed for IP address method for method ${key.method}. Error: ${errorMessage}. Allowing request to proceed (fail-open behavior).`, + + this.logger.error( error, - }); + `Rate limit store operation failed for IP address method for method %s. Error: %s. Allowing request to proceed (fail-open behavior).`, + key.method, + errorMessage, + ); // Fail open: allow the request to proceed if rate limiting fails return false; diff --git a/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts b/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts index 440db1610e..f3f456a235 100644 --- a/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts +++ b/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts @@ -445,7 +445,10 @@ describe('HbarSpendingPlanConfigService', function () { sinon.assert.calledWith(hbarSpendingPlanRepositorySpy.create, subscriptionTier, neverExpireTtl, id); sinon.assert.calledWith( loggerSpy.info, - `Created HBAR spending plan "${name}" with ID "${id}" and subscriptionTier "${subscriptionTier}"`, + `Created HBAR spending plan "%s" with ID "%s" and subscriptionTier "%s"`, + name, + id, + subscriptionTier, ); }); @@ -534,7 +537,8 @@ describe('HbarSpendingPlanConfigService', function () { sinon.assert.calledWith(hbarSpendingPlanRepositorySpy.delete, id); sinon.assert.calledWith( loggerSpy.info, - `Deleting HBAR spending plan with ID "${id}", as it is no longer in the spending plan configuration...`, + `Deleting HBAR spending plan with ID "%s", as it is no longer in the spending plan configuration...`, + id, ); sinon.assert.calledWithMatch(evmAddressHbarSpendingPlanRepositorySpy.deleteAllByPlanId, id); sinon.assert.calledWithMatch(ipAddressHbarSpendingPlanRepositorySpy.deleteAllByPlanId, id); diff --git a/packages/relay/tests/lib/relay.spec.ts b/packages/relay/tests/lib/relay.spec.ts index e4149cf08e..380f785c3f 100644 --- a/packages/relay/tests/lib/relay.spec.ts +++ b/packages/relay/tests/lib/relay.spec.ts @@ -100,8 +100,12 @@ describe('Relay', () => { expect(populatePreconfiguredSpendingPlansSpy.calledOnce).to.be.true; await expect(populatePreconfiguredSpendingPlansSpy.returnValues[0]).not.to.be.rejected; - const message = `Failed to load pre-configured spending plans: File error: Unexpected token 'i', "invalid JSON" is not valid JSON`; - expect(loggerSpy.warn.calledWith(message)).to.be.true; + expect( + loggerSpy.warn.calledWith( + 'Failed to load pre-configured spending plans: %s', + `File error: Unexpected token 'i', "invalid JSON" is not valid JSON`, + ), + ).to.be.true; }); }); }); diff --git a/packages/relay/tests/lib/sdkClient.spec.ts b/packages/relay/tests/lib/sdkClient.spec.ts index b82781391c..995c30988c 100644 --- a/packages/relay/tests/lib/sdkClient.spec.ts +++ b/packages/relay/tests/lib/sdkClient.spec.ts @@ -14,8 +14,6 @@ import { FileId, FileInfoQuery, Hbar, - Logger as HederaLogger, - LogLevel, Query, Status, TransactionId, @@ -1248,7 +1246,8 @@ describe('SdkClient', async function () { ).to.be.true; expect(loggerTraceStub.calledOnce).to.be.true; - expect(loggerTraceStub.firstCall.args[0]).to.include(`Deleted file with fileId: ${fileId}`); + expect(loggerTraceStub.firstCall.args[0]).to.include(`Deleted file with fileId: %s`); + expect(loggerTraceStub.firstCall.args[1]).to.equal(fileId); expect(loggerWarnStub.called).to.be.false; }); @@ -1263,7 +1262,8 @@ describe('SdkClient', async function () { // Assert - Verify warning is logged when file is not deleted expect(loggerWarnStub.calledOnce, 'logger.warn should be called when deletion fails').to.be.true; - expect(loggerWarnStub.firstCall.args[0]).to.include(`Fail to delete file with fileId: ${fileId}`); + expect(loggerWarnStub.firstCall.args[0]).to.include(`Fail to delete file with fileId: %s`); + expect(loggerWarnStub.firstCall.args[1]).to.equal(fileId); expect(loggerTraceStub.called, 'logger.trace should not be called on failure').to.be.false; }); @@ -1279,7 +1279,8 @@ describe('SdkClient', async function () { expect(executeTransactionStub.calledOnce, 'executeTransaction should be called once').to.be.true; expect(executeQueryStub.called, 'executeQuery should not be called when transaction fails').to.be.false; expect(loggerWarnStub.calledOnce, 'logger.warn should be called for error').to.be.true; - expect(loggerWarnStub.firstCall.args[0]).to.include(errorMessage); + expect(loggerWarnStub.firstCall.args[0]).to.include('%s'); + expect(loggerWarnStub.firstCall.args[1]).to.equal(errorMessage); }); it('should handle errors during file info query', async () => { @@ -1295,7 +1296,8 @@ describe('SdkClient', async function () { expect(executeTransactionStub.calledOnce, 'executeTransaction should be called').to.be.true; expect(executeQueryStub.calledOnce, 'executeQuery should be called').to.be.true; expect(loggerWarnStub.calledOnce, 'logger.warn should be called for query error').to.be.true; - expect(loggerWarnStub.firstCall.args[0]).to.include('Query execution failed'); + expect(loggerWarnStub.firstCall.args[0]).to.include('%s'); + expect(loggerWarnStub.firstCall.args[1]).to.equal('Query execution failed'); }); it('should configure FileDeleteTransaction correctly', async () => { diff --git a/packages/relay/tests/lib/services/rateLimiterService/RedisRateLimitStore.spec.ts b/packages/relay/tests/lib/services/rateLimiterService/RedisRateLimitStore.spec.ts index 96a4f1ce75..6fb1cbe19d 100644 --- a/packages/relay/tests/lib/services/rateLimiterService/RedisRateLimitStore.spec.ts +++ b/packages/relay/tests/lib/services/rateLimiterService/RedisRateLimitStore.spec.ts @@ -119,7 +119,7 @@ describe('RedisRateLimitStore Test Suite', function () { const reconnectDelay = config.socket.reconnectStrategy(3); expect(reconnectDelay).to.equal(3000); // 3 retries * 1000ms delay expect(loggerWarnSpy.calledOnce).to.be.true; - expect(loggerWarnSpy.calledWith('Rate limiter Redis reconnection attempt #3. Delay: 3000ms')).to.be.true; + expect(loggerWarnSpy.calledWith('Rate limiter Redis reconnection attempt #%s. Delay: %sms')).to.be.true; }); it('should handle Redis ready event', async () => { @@ -179,7 +179,8 @@ describe('RedisRateLimitStore Test Suite', function () { expect(await store.isConnected()).to.be.false; expect(loggerErrorSpy.calledOnce).to.be.true; const logCall = loggerErrorSpy.getCall(0); - expect(logCall.args[0]).to.equal('Rate limiter Redis error: RedisCacheError: Socket closed'); + expect(logCall.args[0]).to.equal('Rate limiter Redis error: %s'); + expect(logCall.args[1]).to.equal(redisCacheError); }); it('should handle Redis error event with non-socket error', async () => { @@ -204,7 +205,8 @@ describe('RedisRateLimitStore Test Suite', function () { expect(await store.isConnected()).to.be.false; expect(loggerErrorSpy.calledOnce).to.be.true; - expect(loggerErrorSpy.getCall(0).args[0]).to.equal('Rate limiter Redis error: Full Redis error message'); + expect(loggerErrorSpy.getCall(0).args[0]).to.equal('Rate limiter Redis error: %s'); + expect(loggerErrorSpy.getCall(0).args[1]).to.equal(mockRedisCacheError.fullError); redisCacheErrorStub.restore(); }); diff --git a/packages/ws-server/src/metrics/connectionLimiter.ts b/packages/ws-server/src/metrics/connectionLimiter.ts index 3c70ddeccf..31e01ed7a5 100644 --- a/packages/ws-server/src/metrics/connectionLimiter.ts +++ b/packages/ws-server/src/metrics/connectionLimiter.ts @@ -106,7 +106,9 @@ export default class ConnectionLimiter { const MAX_CONNECTION_LIMIT = ConfigService.get('WS_CONNECTION_LIMIT'); if (this.connectedClients > MAX_CONNECTION_LIMIT) { this.logger.info( - `Closing connection ${ctx.websocket.id} due to exceeded maximum connections (max_con=${MAX_CONNECTION_LIMIT})`, + `Closing connection %s due to exceeded maximum connections (max_con=%s)`, + ctx.websocket.id, + MAX_CONNECTION_LIMIT, ); this.connectionLimitCounter.inc(); ctx.websocket.send( @@ -132,7 +134,11 @@ export default class ConnectionLimiter { const MAX_CONNECTION_LIMIT_PER_IP = ConfigService.get('WS_CONNECTION_LIMIT_PER_IP'); if (this.clientIps[ip] && this.clientIps[ip] > MAX_CONNECTION_LIMIT_PER_IP) { this.logger.info( - `Closing connection ${ctx.websocket.id} due to exceeded maximum connections from a single IP: address ${ip} - ${this.clientIps[ip]} connections. (max_con=${MAX_CONNECTION_LIMIT_PER_IP})`, + `Closing connection %s due to exceeded maximum connections from a single IP: address %s - %s connections. (max_con=%s)`, + ctx.websocket.id, + ip, + this.clientIps[ip], + MAX_CONNECTION_LIMIT_PER_IP, ); this.ipConnectionLimitCounter.labels(ip).inc(); ctx.websocket.send( @@ -175,9 +181,7 @@ export default class ConnectionLimiter { websocket.inactivityTTL = setTimeout(() => { if (websocket.readyState !== 3) { // 3 = CLOSED, Avoid closing already closed connections - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`Closing connection ${websocket.id} due to reaching TTL (${maxInactivityTTL}ms)`); - } + this.logger.debug(`Closing connection %s due to reaching TTL (%sms)`, websocket.id, maxInactivityTTL); try { this.inactivityTTLCounter.inc(); websocket.send( @@ -196,7 +200,7 @@ export default class ConnectionLimiter { ); websocket.close(TTL_EXPIRED.code, TTL_EXPIRED.message); } catch (e) { - this.logger.error(`${websocket.id}: ${e}`); + this.logger.error(`%s: %s`, websocket.id, e); } } }, maxInactivityTTL); diff --git a/packages/ws-server/src/service/subscriptionService.ts b/packages/ws-server/src/service/subscriptionService.ts index fd472b93d7..d5143c280e 100644 --- a/packages/ws-server/src/service/subscriptionService.ts +++ b/packages/ws-server/src/service/subscriptionService.ts @@ -71,6 +71,7 @@ export class SubscriptionService { return generateRandomHex(); } + // eslint-disable-next-line @typescript-eslint/no-empty-object-type public subscribe(connection, event: string, filters?: {}) { let tag: any = { event }; if (filters && Object.keys(filters).length) { @@ -87,16 +88,14 @@ export class SubscriptionService { // Check if the connection is already subscribed to this event const existingSub = this.subscriptions[tag].find((sub) => sub.connection.id === connection.id); if (existingSub) { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`Connection ${connection.id}: Attempting to subscribe to ${tag}; already subscribed`); - } + this.logger.debug(`Connection %s: Attempting to subscribe to %s; already subscribed`, connection.id, tag); return existingSub.subscriptionId; } } const subId = this.generateId(); - this.logger.info(`Connection ${connection.id}: created subscription ${subId}, listening for ${tag}`); + this.logger.info(`Connection %s: created subscription %s, listening for %s`, connection.id, subId, tag); this.subscriptions[tag].push({ subscriptionId: subId, @@ -113,9 +112,9 @@ export class SubscriptionService { const { id } = connection; if (subId) { - this.logger.info(`Connection ${id}: Unsubscribing from ${subId}`); + this.logger.info(`Connection %s: Unsubscribing from %s`, id, subId); } else { - this.logger.info(`Connection ${id}: Unsubscribing from all subscriptions`); + this.logger.info(`Connection %s: Unsubscribing from all subscriptions`, id); } let subCount = 0; @@ -123,11 +122,12 @@ export class SubscriptionService { this.subscriptions[tag] = subs.filter((sub) => { const match = sub.connection.id === id && (!subId || subId === sub.subscriptionId); if (match) { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Connection ${sub.connection.id}. Unsubscribing subId: ${sub.subscriptionId}; tag: ${tag}`, - ); - } + this.logger.debug( + `Connection %s. Unsubscribing subId: %s; tag: %s`, + sub.connection.id, + sub.subscriptionId, + tag, + ); sub.endTimer(); subCount++; } @@ -136,9 +136,7 @@ export class SubscriptionService { }); if (!this.subscriptions[tag].length) { - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug(`No subscribers for ${tag}. Removing from list.`); - } + this.logger.debug(`No subscribers for %s. Removing from list.`, tag); delete this.subscriptions[tag]; this.pollerService.remove(tag); } @@ -159,11 +157,13 @@ export class SubscriptionService { // If the hash exists in the cache then the data has recently been sent to the subscriber if (!this.cache.get(hash)) { this.cache.set(hash, true); - if (this.logger.isLevelEnabled('debug')) { - this.logger.debug( - `Sending data from tag: ${tag} to subscriptionId: ${sub.subscriptionId}, connectionId: ${sub.connection.id}, data: ${subscriptionData}`, - ); - } + this.logger.debug( + `Sending data from tag: %s to subscriptionId: %s, connectionId: %s, data: %s`, + tag, + sub.subscriptionId, + sub.connection.id, + subscriptionData, + ); this.resultsSentToSubscribersCounter.labels('sub.subscriptionId', tag).inc(); sub.connection.send( JSON.stringify({ diff --git a/packages/ws-server/tests/unit/connectionLimiter.spec.ts b/packages/ws-server/tests/unit/connectionLimiter.spec.ts index d6d86cb206..c9fe68d5c2 100644 --- a/packages/ws-server/tests/unit/connectionLimiter.spec.ts +++ b/packages/ws-server/tests/unit/connectionLimiter.spec.ts @@ -20,8 +20,8 @@ function createMockContext({ ip?: string; ipCounted?: boolean; subscriptions?: number; -} = {}): MockContext { - const websocket: MockWebsocket = { +} = {}): any { + const websocket: any = { id: 'test-connection-id', send: sinon.stub(), close: sinon.stub(), @@ -86,7 +86,9 @@ describe('Connection Limiter', function () { sinon.assert.calledWith( mockLogger.info, - 'Closing connection test-connection-id due to exceeded maximum connections (max_con=100)', + 'Closing connection %s due to exceeded maximum connections (max_con=%s)', + 'test-connection-id', + 100, ); sinon.assert.calledWith( @@ -122,7 +124,11 @@ describe('Connection Limiter', function () { sinon.assert.calledWith( mockLogger.info, - 'Closing connection test-connection-id due to exceeded maximum connections from a single IP: address 127.0.0.1 - 11 connections. (max_con=10)', + 'Closing connection %s due to exceeded maximum connections from a single IP: address %s - %s connections. (max_con=%s)', + 'test-connection-id', + '127.0.0.1', + 11, + 10, ); sinon.assert.calledWith( @@ -206,6 +212,7 @@ describe('Connection Limiter', function () { const methodName = 'eth_getBalance'; const requestDetails = { requestId: 'test-request' }; const expectedLimit = 50; + // eslint-disable-next-line no-import-assign methodConfigModule.methodConfiguration = { eth_getBalance: { total: 50 }, }; @@ -223,6 +230,7 @@ describe('Connection Limiter', function () { const methodName = 'eth_getLogs'; const requestDetails = { requestId: 'test-request' }; const expectedLimit = 25; + // eslint-disable-next-line no-import-assign methodConfigModule.methodConfiguration = { eth_getLogs: { total: 25 }, }; diff --git a/packages/ws-server/tests/unit/subscriptionService.spec.ts b/packages/ws-server/tests/unit/subscriptionService.spec.ts index cafbf5016e..a7afb44540 100644 --- a/packages/ws-server/tests/unit/subscriptionService.spec.ts +++ b/packages/ws-server/tests/unit/subscriptionService.spec.ts @@ -174,17 +174,23 @@ describe('subscriptionService', async function () { const count = subscriptionService.unsubscribe(wsConnection); expect(count).to.be.eq(2); - expect(loggerInfoSpy.calledWith(`Connection ${wsConnection.id}: Unsubscribing from all subscriptions`)).to.be.eq( + expect(loggerInfoSpy.calledWith(`Connection %s: Unsubscribing from all subscriptions`, wsConnection.id)).to.be.eq( true, ); expect( loggerDebugSpy.calledWith( - `Connection ${wsConnection.id}. Unsubscribing subId: ${subId}; tag: ${JSON.stringify(tag1)}`, + `Connection %s. Unsubscribing subId: %s; tag: %s`, + wsConnection.id, + subId, + JSON.stringify(tag1), ), ).to.be.eq(true); expect( loggerDebugSpy.calledWith( - `Connection ${wsConnection.id}. Unsubscribing subId: ${subId2}; tag: ${JSON.stringify(tag2)}`, + `Connection %s. Unsubscribing subId: %s; tag: %s`, + wsConnection.id, + subId2, + JSON.stringify(tag2), ), ).to.be.eq(true); }); @@ -205,10 +211,13 @@ describe('subscriptionService', async function () { const count = subscriptionService.unsubscribe(wsConnection, subId2); expect(count).to.be.eq(1); - expect(loggerInfoSpy.calledWith(`Connection ${wsConnection.id}: Unsubscribing from ${subId2}`)).to.be.eq(true); + expect(loggerInfoSpy.calledWith(`Connection %s: Unsubscribing from %s`), wsConnection.id, subId2).to.be.eq(true); expect( loggerDebugSpy.calledWith( - `Connection ${wsConnection.id}. Unsubscribing subId: ${subId2}; tag: ${JSON.stringify(tag2)}`, + `Connection %s. Unsubscribing subId: %s; tag: %s`, + wsConnection.id, + subId2, + JSON.stringify(tag2), ), ).to.be.eq(true); });