From 8e2783bf647c92a0ceea9d8f896c52b22d95e626 Mon Sep 17 00:00:00 2001 From: nikolay Date: Wed, 30 Oct 2024 14:46:46 +0200 Subject: [PATCH 1/6] chore: add excluded transaction statuses array Signed-off-by: nikolay --- docs/configuration.md | 123 +++++++++--------- .../src/services/globalConfig.ts | 6 + packages/relay/src/lib/eth.ts | 12 +- packages/relay/src/utils.ts | 18 +++ .../lib/eth/eth_getBlockByNumber.spec.ts | 56 ++++---- packages/relay/tests/lib/utils.spec.ts | 34 ++++- 6 files changed, 150 insertions(+), 99 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index d516ce06a0..d88817bd4e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -49,67 +49,68 @@ Unless you need to set a non-default value, it is recommended to only populate o The following table lists the available properties along with their default values for the [Relay package](/packages/relay/). Unless you need to set a non-default value, it is recommended to only populate overridden properties in the custom `.env`. -| Name | Default | Description | -|---------------------------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `CACHE_MAX` | "1000" | The maximum number (or size) of items that remain in the cache (assuming no TTL pruning or explicit deletions). | -| `CACHE_TTL` | "3_600_000" | Max time to live in ms, for items before they are considered stale. Default is one hour in milliseconds | -| `CLIENT_TRANSPORT_SECURITY` | "false" | Flag to enable or disable TLS for both networks. | -| `CONTRACT_CALL_GAS_LIMIT` | "50_000_000" | Maximum gas limit applied to eth_call endpoint networks, the Relay will accept up to 50M but keep it capped at 15M for the actual call. | -| `CONSENSUS_MAX_EXECUTION_TIME` | "15000" | Maximum time in ms the SDK will wait when submitting a transaction/query before throwing a TIMEOUT error. | -| `DEFAULT_RATE_LIMIT` | "200" | default fallback rate limit, if no other is configured. | -| `ETH_CALL_CACHE_TTL` | "200" | Maximum time in ms to cache an eth_call response. | -| `ETH_BLOCK_NUMBER_CACHE_TTL_MS` | "1000" | Time in ms to cache response from mirror node | -| `ETH_GET_BALANCE_CACHE_TTL_MS` | "1000" | Time in ms to cache balance returned | -| `ETH_GET_BLOCK_BY_RESULTS_BATCH_SIZE` | "25" | The number of contract results to request from the Mirror Node per batch durin an eth_getBlockByHash or eth_getBlockByNumber call | -| `ETH_GET_GAS_PRICE_CACHE_TTL_MS` | "1_800_000" | Time in ms to cache ethGasPrice returned | -| `ETH_CALL_DEFAULT_TO_CONSENSUS_NODE` | "false" | Flag to set if eth_call logic should first query the mirror node. | -| `ETH_CALL_CONSENSUS_SELECTORS` | [""] | A comma-separated list of special transaction selectors that should always be routed to the Consensus node. | -| `ETH_GET_LOGS_BLOCK_RANGE_LIMIT` | "1000" | The maximum block number range to consider during an eth_getLogs call. | -| `ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE` | "1000" | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | -| `FEE_HISTORY_MAX_RESULTS` | "10" | The maximum number of results to returns as part of `eth_feeHistory`. | -| `ETH_FEE_HISTORY_FIXED` | "true" | Flag to set if eth_feeHistory should return a fixed fee for the set of results. | -| `GAS_PRICE_PERCENTAGE_BUFFER` | "0" | The additional buffer that adds a percentage on top of the calculated network gasPrice. This may be used by operators to reduce the chances of `INSUFFICIENT_TX_FEE` errors experienced by users caused by minor fluctuations in the exchange rate. | -| `GAS_PRICE_TINY_BAR_BUFFER` | "10000000000" | The additional buffer range to allow during a relay precheck of gas price. This supports slight fluctuations in network gasprice calculations. | -| `HBAR_RATE_LIMIT_DURATION` | "86400000" | HBAR budget limit duration. This creates a timestamp, which resets all limits, when it's reached. Defaults to 1 day. | -| `HBAR_RATE_LIMIT_TINYBAR` | "800000000000" | Total HBAR budget (in tinybars). Defaults to 8000 HBARs. | -| `HBAR_RATE_LIMIT_BASIC` | "1120000000" | Individual limit (in tinybars) for spending plans with a BASIC tier. Defaults to 11.2 HBARs. | -| `HBAR_RATE_LIMIT_EXTENDED` | "3200000000" | Individual limit (in tinybars) for spending plans with a EXTENDED tier. Defaults to 32 HBARs. | -| `HBAR_RATE_LIMIT_PRIVILEGED` | "8000000000" | Individual limit (in tinybars) for spending plans with a PRIVILEGED tier. Defaults to 80 HBARs. | -| `HBAR_SPENDING_PLANS_CONFIG_FILE` | "spendingPlansConfig.json" | The name of the JSON file containing the pre-configured spending plans for supported projects and partner projects. | -| `HAPI_CLIENT_DURATION_RESET` | "3600000" | Time until client reinitialization. (ms) | -| `HAPI_CLIENT_ERROR_RESET` | [21, 50] | Array of status codes, which when encountered will trigger a reinitialization. Status codes are availble [here](https://github.com/hashgraph/hedera-protobufs/blob/main/services/response_code.proto). | -| `HAPI_CLIENT_TRANSACTION_RESET` | "50" | Number of transaction executions, until client reinitialization. | -| `TEST_INITIAL_ACCOUNT_STARTING_BALANCE` | "2000" | The number of HBars to allocate to the initial account in acceptance test runs. This account is responsible for the gas payment of tests within the suite run session and needs to be adequately funded. | -| `LIMIT_DURATION` | "60000" | The maximum duration in ms applied to IP-method based rate limits. | -| `MIRROR_NODE_CONTRACT_RESULTS_PG_MAX` | "25" | The maximum number of pages to be requested for contract results from the mirror node. | -| `MIRROR_NODE_CONTRACT_RESULTS_LOGS_PG_MAX` | "200" | The maximum number of pages to be requested for contract results logs from the mirror node. (each page will contain a max of 100 results) | -| `MIRROR_NODE_LIMIT_PARAM` | "100" | The mirror node custom limit value to be set on GET requests. This optimizes the flow to reduce the number of calls made to the mirror node by setting a limit larger than it's default limit. | -| `MIRROR_NODE_RETRIES` | "0" | The maximum number of retries on a GET request to the mirror node when an acceptable error code is returned. | -| `MIRROR_NODE_RETRY_CODES` | "[]" | The acceptable error codes to retry on a request to the mirror node. If more than 1 error is defined value should be like ie: [400,404,500] | -| `MIRROR_NODE_RETRY_DELAY` | "2000" | The delay in ms between retry requests. | -| `MIRROR_NODE_RETRIES_DEVMODE` | "5" | The maximum number of retries on a GET request to the mirror node when an acceptable error code is returned in dev mode. | -| `MIRROR_NODE_RETRY_DELAY_DEVMODE` | "200" | The delay in ms between retry requests in dev mode. | -| `MIRROR_NODE_URL` | "" | The Mirror Node API endpoint. Official endpoints are Previewnet (https://previewnet.mirrornode.hedera.com), Testnet (https://testnet.mirrornode.hedera.com), Mainnet (https://mainnet-public.mirrornode.hedera.com). See [Mirror Node REST API](https://docs.hedera.com/hedera/sdks-and-apis/rest-api) | -| `MIRROR_NODE_URL_HEADER_X_API_KEY` | "" | Authentication for a `MIRROR_NODE_URL` that requires authentication via the `x-api-key` header. | -| `MIRROR_NODE_REQUEST_RETRY_COUNT` | "10" | Maximun amount of retries to repeat on `GetContractResults` `contracts/results/)` requests when fetching contract results after eth_sendRawTransaction submission. \*Note that this in addition and multiplies the configured Axios retries values. | -| `MIRROR_NODE_AGENT_CACHEABLE_DNS` | "true" | Flag to set if the mirror node agent should cacheable DNS lookups, using better-lookup library. | -| `SDK_REQUEST_TIMEOUT` | "10000" | The complete timeout for running the SDK `execute()` method. This controls the GRPC channel timeout config when querying with network nodes. | -| `CONTRACT_QUERY_TIMEOUT_RETRIES` | "3" | Maximum retries for failed contract call query with timeout exceeded error | -| `TIER_1_RATE_LIMIT` | "100" | Maximum restrictive request count limit used for expensive endpoints rate limiting. | -| `TIER_2_RATE_LIMIT` | "800" | Maximum moderate request count limit used for non expensive endpoints. | -| `TIER_3_RATE_LIMIT` | "1600" | Maximum relaxed request count limit used for static return endpoints. | -| `TX_DEFAULT_GAS` | "400000" | Default gas for transactions that do not specify gas. | -| `FILE_APPEND_MAX_CHUNKS` | "20" | Default maximum number of chunks for the `HAPI` `FileAppendTransaction` to use during contract creation submissions to consensus nodes as part of `eth_sendRawTransactionsaction`. | -| `FILE_APPEND_CHUNK_SIZE=5120` | "5120" | Size in bytes of file chunks for the `HAPI` `FileAppendTransaction` to use during contract creation submissions to consensus nodes as part of `eth_sendRawTransactionsaction`. | -| `FILTER_API_ENABLED` | "false" | Enables all filter related methods: `eth_newFilter`, `eth_uninstallFilter`, `eth_getFilterChanges`, `eth_getFilterLogs`, `eth_newBlockFilter` | -| `DEBUG_API_ENABLED` | "false" | Enables all debug related methods: `debug_traceTransaction` | -| `REDIS_ENABLED` | "true" | Enable usage of Redis as shared cache | -| `REDIS_URL` | "redis://127.0.0.1:6379" | Sets the url for the Redis shared cache | -| `MULTI_SET` | "true" | Switch between different implementation of setting multiple K/V pairs in the shared cache. True is mSet, false is pipeline | -| `REDIS_RECONNECT_DELAY_MS` | "1000" | Sets the delay between reconnect retries from the Redis client in ms | -| `SEND_RAW_TRANSACTION_SIZE_LIMIT` | "131072" | Sets the limit of the transaction size the relay accepts on eth_sendRawTransaction | -| `GET_RECORD_DEFAULT_TO_CONSENSUS_NODE` | "false" | Flag to set if get transaction record logic should first query the mirror node (false) or consensus node via the SDK (true). | -| `HBAR_RATE_LIMIT_WHITELIST` | [""] | An array of EVM addresses that are allowed to bypass the HBAR rate limits | +| Name | Default | Description | +|---------------------------------------------|---------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `CACHE_MAX` | "1000" | The maximum number (or size) of items that remain in the cache (assuming no TTL pruning or explicit deletions). | +| `CACHE_TTL` | "3_600_000" | Max time to live in ms, for items before they are considered stale. Default is one hour in milliseconds | +| `CLIENT_TRANSPORT_SECURITY` | "false" | Flag to enable or disable TLS for both networks. | +| `CONTRACT_CALL_GAS_LIMIT` | "50_000_000" | Maximum gas limit applied to eth_call endpoint networks, the Relay will accept up to 50M but keep it capped at 15M for the actual call. | +| `CONSENSUS_MAX_EXECUTION_TIME` | "15000" | Maximum time in ms the SDK will wait when submitting a transaction/query before throwing a TIMEOUT error. | +| `DEFAULT_RATE_LIMIT` | "200" | default fallback rate limit, if no other is configured. | +| `ETH_CALL_CACHE_TTL` | "200" | Maximum time in ms to cache an eth_call response. | +| `ETH_BLOCK_NUMBER_CACHE_TTL_MS` | "1000" | Time in ms to cache response from mirror node | +| `ETH_GET_BALANCE_CACHE_TTL_MS` | "1000" | Time in ms to cache balance returned | +| `ETH_GET_BLOCK_BY_RESULTS_BATCH_SIZE` | "25" | The number of contract results to request from the Mirror Node per batch durin an eth_getBlockByHash or eth_getBlockByNumber call | +| `ETH_GET_GAS_PRICE_CACHE_TTL_MS` | "1_800_000" | Time in ms to cache ethGasPrice returned | +| `ETH_CALL_DEFAULT_TO_CONSENSUS_NODE` | "false" | Flag to set if eth_call logic should first query the mirror node. | +| `ETH_CALL_CONSENSUS_SELECTORS` | [""] | A comma-separated list of special transaction selectors that should always be routed to the Consensus node. | +| `ETH_GET_LOGS_BLOCK_RANGE_LIMIT` | "1000" | The maximum block number range to consider during an eth_getLogs call. | +| `ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE` | "1000" | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | +| `EXCLUDED_TRANSACTION_STATUSES` | ["WRONG_NONCE", "INVALID_ACCOUNT_ID"] | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | +| `FEE_HISTORY_MAX_RESULTS` | "10" | The maximum number of results to returns as part of `eth_feeHistory`. | +| `ETH_FEE_HISTORY_FIXED` | "true" | Flag to set if eth_feeHistory should return a fixed fee for the set of results. | +| `GAS_PRICE_PERCENTAGE_BUFFER` | "0" | The additional buffer that adds a percentage on top of the calculated network gasPrice. This may be used by operators to reduce the chances of `INSUFFICIENT_TX_FEE` errors experienced by users caused by minor fluctuations in the exchange rate. | +| `GAS_PRICE_TINY_BAR_BUFFER` | "10000000000" | The additional buffer range to allow during a relay precheck of gas price. This supports slight fluctuations in network gasprice calculations. | +| `HBAR_RATE_LIMIT_DURATION` | "86400000" | HBAR budget limit duration. This creates a timestamp, which resets all limits, when it's reached. Defaults to 1 day. | +| `HBAR_RATE_LIMIT_TINYBAR` | "800000000000" | Total HBAR budget (in tinybars). Defaults to 8000 HBARs. | +| `HBAR_RATE_LIMIT_BASIC` | "1120000000" | Individual limit (in tinybars) for spending plans with a BASIC tier. Defaults to 11.2 HBARs. | +| `HBAR_RATE_LIMIT_EXTENDED` | "3200000000" | Individual limit (in tinybars) for spending plans with a EXTENDED tier. Defaults to 32 HBARs. | +| `HBAR_RATE_LIMIT_PRIVILEGED` | "8000000000" | Individual limit (in tinybars) for spending plans with a PRIVILEGED tier. Defaults to 80 HBARs. | +| `HBAR_SPENDING_PLANS_CONFIG_FILE` | "spendingPlansConfig.json" | The name of the JSON file containing the pre-configured spending plans for supported projects and partner projects. | +| `HAPI_CLIENT_DURATION_RESET` | "3600000" | Time until client reinitialization. (ms) | +| `HAPI_CLIENT_ERROR_RESET` | [21, 50] | Array of status codes, which when encountered will trigger a reinitialization. Status codes are availble [here](https://github.com/hashgraph/hedera-protobufs/blob/main/services/response_code.proto). | +| `HAPI_CLIENT_TRANSACTION_RESET` | "50" | Number of transaction executions, until client reinitialization. | +| `TEST_INITIAL_ACCOUNT_STARTING_BALANCE` | "2000" | The number of HBars to allocate to the initial account in acceptance test runs. This account is responsible for the gas payment of tests within the suite run session and needs to be adequately funded. | +| `LIMIT_DURATION` | "60000" | The maximum duration in ms applied to IP-method based rate limits. | +| `MIRROR_NODE_CONTRACT_RESULTS_PG_MAX` | "25" | The maximum number of pages to be requested for contract results from the mirror node. | +| `MIRROR_NODE_CONTRACT_RESULTS_LOGS_PG_MAX` | "200" | The maximum number of pages to be requested for contract results logs from the mirror node. (each page will contain a max of 100 results) | +| `MIRROR_NODE_LIMIT_PARAM` | "100" | The mirror node custom limit value to be set on GET requests. This optimizes the flow to reduce the number of calls made to the mirror node by setting a limit larger than it's default limit. | +| `MIRROR_NODE_RETRIES` | "0" | The maximum number of retries on a GET request to the mirror node when an acceptable error code is returned. | +| `MIRROR_NODE_RETRY_CODES` | "[]" | The acceptable error codes to retry on a request to the mirror node. If more than 1 error is defined value should be like ie: [400,404,500] | +| `MIRROR_NODE_RETRY_DELAY` | "2000" | The delay in ms between retry requests. | +| `MIRROR_NODE_RETRIES_DEVMODE` | "5" | The maximum number of retries on a GET request to the mirror node when an acceptable error code is returned in dev mode. | +| `MIRROR_NODE_RETRY_DELAY_DEVMODE` | "200" | The delay in ms between retry requests in dev mode. | +| `MIRROR_NODE_URL` | "" | The Mirror Node API endpoint. Official endpoints are Previewnet (https://previewnet.mirrornode.hedera.com), Testnet (https://testnet.mirrornode.hedera.com), Mainnet (https://mainnet-public.mirrornode.hedera.com). See [Mirror Node REST API](https://docs.hedera.com/hedera/sdks-and-apis/rest-api) | +| `MIRROR_NODE_URL_HEADER_X_API_KEY` | "" | Authentication for a `MIRROR_NODE_URL` that requires authentication via the `x-api-key` header. | +| `MIRROR_NODE_REQUEST_RETRY_COUNT` | "10" | Maximun amount of retries to repeat on `GetContractResults` `contracts/results/)` requests when fetching contract results after eth_sendRawTransaction submission. \*Note that this in addition and multiplies the configured Axios retries values. | +| `MIRROR_NODE_AGENT_CACHEABLE_DNS` | "true" | Flag to set if the mirror node agent should cacheable DNS lookups, using better-lookup library. | +| `SDK_REQUEST_TIMEOUT` | "10000" | The complete timeout for running the SDK `execute()` method. This controls the GRPC channel timeout config when querying with network nodes. | +| `CONTRACT_QUERY_TIMEOUT_RETRIES` | "3" | Maximum retries for failed contract call query with timeout exceeded error | +| `TIER_1_RATE_LIMIT` | "100" | Maximum restrictive request count limit used for expensive endpoints rate limiting. | +| `TIER_2_RATE_LIMIT` | "800" | Maximum moderate request count limit used for non expensive endpoints. | +| `TIER_3_RATE_LIMIT` | "1600" | Maximum relaxed request count limit used for static return endpoints. | +| `TX_DEFAULT_GAS` | "400000" | Default gas for transactions that do not specify gas. | +| `FILE_APPEND_MAX_CHUNKS` | "20" | Default maximum number of chunks for the `HAPI` `FileAppendTransaction` to use during contract creation submissions to consensus nodes as part of `eth_sendRawTransactionsaction`. | +| `FILE_APPEND_CHUNK_SIZE=5120` | "5120" | Size in bytes of file chunks for the `HAPI` `FileAppendTransaction` to use during contract creation submissions to consensus nodes as part of `eth_sendRawTransactionsaction`. | +| `FILTER_API_ENABLED` | "false" | Enables all filter related methods: `eth_newFilter`, `eth_uninstallFilter`, `eth_getFilterChanges`, `eth_getFilterLogs`, `eth_newBlockFilter` | +| `DEBUG_API_ENABLED` | "false" | Enables all debug related methods: `debug_traceTransaction` | +| `REDIS_ENABLED` | "true" | Enable usage of Redis as shared cache | +| `REDIS_URL` | "redis://127.0.0.1:6379" | Sets the url for the Redis shared cache | +| `MULTI_SET` | "true" | Switch between different implementation of setting multiple K/V pairs in the shared cache. True is mSet, false is pipeline | +| `REDIS_RECONNECT_DELAY_MS` | "1000" | Sets the delay between reconnect retries from the Redis client in ms | +| `SEND_RAW_TRANSACTION_SIZE_LIMIT` | "131072" | Sets the limit of the transaction size the relay accepts on eth_sendRawTransaction | +| `GET_RECORD_DEFAULT_TO_CONSENSUS_NODE` | "false" | Flag to set if get transaction record logic should first query the mirror node (false) or consensus node via the SDK (true). | +| `HBAR_RATE_LIMIT_WHITELIST` | [""] | An array of EVM addresses that are allowed to bypass the HBAR rate limits | ## WS-Server diff --git a/packages/config-service/src/services/globalConfig.ts b/packages/config-service/src/services/globalConfig.ts index cd5dc1f4e4..13d62b6ab9 100644 --- a/packages/config-service/src/services/globalConfig.ts +++ b/packages/config-service/src/services/globalConfig.ts @@ -183,6 +183,12 @@ export class GlobalConfig { required: false, defaultValue: null, }, + EXCLUDED_TRANSACTION_STATUSES: { + envName: 'EXCLUDED_TRANSACTION_STATUSES', + type: 'string', + required: false, + defaultValue: '["WRONG_NONCE", "INVALID_ACCOUNT_ID"]', + }, FEE_HISTORY_MAX_RESULTS: { envName: 'FEE_HISTORY_MAX_RESULTS', type: 'number', diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 936680c297..21c50515f0 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -2298,18 +2298,12 @@ export class EthImpl implements Eth { throw predefined.MAX_BLOCK_SIZE(blockResponse.count); } - const isWrongNonce = (contractResult: { result: string; error_message: any }) => { - return ( - contractResult.result === constants.TRANSACTION_RESULT_STATUS.WRONG_NONCE || - hexToASCII(strip0x(contractResult.error_message ?? '')) === constants.TRANSACTION_RESULT_STATUS.WRONG_NONCE - ); - }; - // prepare transactionArray let transactionArray: any[] = []; for (const contractResult of contractResults) { - if (isWrongNonce(contractResult)) { - // skip wrong nonce transactions as they are not valid transactions which should be included in the block + // 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)) { continue; } contractResult.from = await this.resolveEvmAddress(contractResult.from, requestDetails, [constants.TYPE_ACCOUNT]); diff --git a/packages/relay/src/utils.ts b/packages/relay/src/utils.ts index 993f6ca8b0..c95347c644 100644 --- a/packages/relay/src/utils.ts +++ b/packages/relay/src/utils.ts @@ -22,6 +22,7 @@ import { PrivateKey } from '@hashgraph/sdk'; import constants from './lib/constants'; import { ConfigService } from '@hashgraph/json-rpc-config-service/dist/services'; import crypto from 'crypto'; +import { hexToASCII, strip0x } from './formatters'; export class Utils { public static readonly IP_ADDRESS_REGEX = /\b((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}\b/g; @@ -107,4 +108,21 @@ export class Utils { return estimatedTxFee; } + + /** + * Check whether the transaction has reverted by a hedera-specific validation before the actual evm execution + * @param contractResult + * @returns {boolean} + */ + public static isRevertedDueToHederaSpecificValidation(contractResult: { + result: string; + error_message: any; + }): boolean { + // @ts-ignore + const statuses = JSON.parse(ConfigService.get('EXCLUDED_TRANSACTION_STATUSES')); + return ( + statuses.indexOf(contractResult.result) > -1 || + statuses.indexOf(hexToASCII(strip0x(contractResult.error_message ?? ''))) > -1 + ); + } } diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index 25a8e28334..e81001456c 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -568,34 +568,36 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { }); [false, true].forEach((showDetails) => { - it(`eth_getBlockByNumber should skip wrong nonce transactions when showDetails = ${showDetails}`, async () => { - // mirror node request mocks - restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); - restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOST_RECENT_BLOCK); - restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, { - results: [ - ...defaultContractResults.results, - { ...defaultContractResults.results[0], result: 'WRONG_NONCE' }, - { ...defaultContractResults.results[0], error_message: prepend0x(ASCIIToHex('WRONG_NONCE')) }, - ], + ['WRONG_NONCE', 'INVALID_ACCOUNT_ID'].forEach((status) => { + it(`eth_getBlockByNumber should skip ${status} transactions when showDetails = ${showDetails}`, async () => { + // mirror node request mocks + restMock.onGet(`blocks/${BLOCK_NUMBER}`).reply(200, DEFAULT_BLOCK); + restMock.onGet(BLOCKS_LIMIT_ORDER_URL).reply(200, MOST_RECENT_BLOCK); + restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, { + results: [ + ...defaultContractResults.results, + { ...defaultContractResults.results[0], result: status }, + { ...defaultContractResults.results[0], error_message: prepend0x(ASCIIToHex(status)) }, + ], + }); + restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); + + const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), showDetails, requestDetails); + + RelayAssertions.assertBlock( + result, + { + hash: BLOCK_HASH_TRIMMED, + gasUsed: TOTAL_GAS_USED, + number: BLOCK_NUMBER_HEX, + parentHash: BLOCK_HASH_PREV_TRIMMED, + timestamp: BLOCK_TIMESTAMP_HEX, + transactions: [CONTRACT_HASH_1, CONTRACT_HASH_2], // should not include the transaction with wrong nonce + receiptsRoot: DEFAULT_BLOCK_RECEIPTS_ROOT_HASH, + }, + showDetails, + ); }); - restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); - - const result = await ethImpl.getBlockByNumber(numberTo0x(BLOCK_NUMBER), showDetails, requestDetails); - - RelayAssertions.assertBlock( - result, - { - hash: BLOCK_HASH_TRIMMED, - gasUsed: TOTAL_GAS_USED, - number: BLOCK_NUMBER_HEX, - parentHash: BLOCK_HASH_PREV_TRIMMED, - timestamp: BLOCK_TIMESTAMP_HEX, - transactions: [CONTRACT_HASH_1, CONTRACT_HASH_2], // should not include the transaction with wrong nonce - receiptsRoot: DEFAULT_BLOCK_RECEIPTS_ROOT_HASH, - }, - showDetails, - ); }); }); }); diff --git a/packages/relay/tests/lib/utils.spec.ts b/packages/relay/tests/lib/utils.spec.ts index 2aad74fc7e..264ffb7f3f 100644 --- a/packages/relay/tests/lib/utils.spec.ts +++ b/packages/relay/tests/lib/utils.spec.ts @@ -21,9 +21,9 @@ import { expect } from 'chai'; import { Utils } from '../../src/utils'; import constants from '../../src/lib/constants'; -import { overrideEnvsInMochaDescribe } from '../helpers'; -import { estimateFileTransactionsFee } from '../helpers'; +import { estimateFileTransactionsFee, overrideEnvsInMochaDescribe } from '../helpers'; import { ConfigService } from '@hashgraph/json-rpc-config-service/dist/services'; +import { ASCIIToHex, prepend0x } from '../../src/formatters'; describe('Utils', () => { describe('addPercentageBufferToGasPrice', () => { @@ -63,4 +63,34 @@ describe('Utils', () => { expect(result).to.eq(expectedResult); }); }); + + describe('isRevertedDueToHederaSpecificValidation', () => { + it('should not exclude transaction with status SUCCESS', () => { + expect(Utils.isRevertedDueToHederaSpecificValidation({ result: 'SUCCESS', error_message: null })).to.be.false; + }); + + it('should not exclude evm reverted transaction', () => { + expect( + Utils.isRevertedDueToHederaSpecificValidation({ + result: 'CONTRACT_REVERT_EXECUTED', + error_message: 'Error', + }), + ).to.be.false; + }); + + // @ts-ignore + JSON.parse(ConfigService.get('EXCLUDED_TRANSACTION_STATUSES')).forEach((status) => { + it(`should exclude transaction with result ${status}`, () => { + expect(Utils.isRevertedDueToHederaSpecificValidation({ result: status, error_message: null })).to.be.true; + }); + it(`should exclude transaction with error_message ${status}`, () => { + expect( + Utils.isRevertedDueToHederaSpecificValidation({ + result: '', + error_message: prepend0x(ASCIIToHex(status)), + }), + ).to.be.true; + }); + }); + }); }); From d51906635d7caa3b6dc4a5b8df67e259e5c2faa8 Mon Sep 17 00:00:00 2001 From: nikolay Date: Wed, 30 Oct 2024 17:33:33 +0200 Subject: [PATCH 2/6] chore: resolve comments Signed-off-by: nikolay --- docs/configuration.md | 2 +- packages/config-service/src/services/globalConfig.ts | 4 ++-- packages/relay/src/lib/eth.ts | 2 -- packages/relay/src/utils.ts | 6 +++--- packages/relay/tests/lib/utils.spec.ts | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index d88817bd4e..d6cceaeaf9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -66,7 +66,7 @@ Unless you need to set a non-default value, it is recommended to only populate o | `ETH_CALL_CONSENSUS_SELECTORS` | [""] | A comma-separated list of special transaction selectors that should always be routed to the Consensus node. | | `ETH_GET_LOGS_BLOCK_RANGE_LIMIT` | "1000" | The maximum block number range to consider during an eth_getLogs call. | | `ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE` | "1000" | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | -| `EXCLUDED_TRANSACTION_STATUSES` | ["WRONG_NONCE", "INVALID_ACCOUNT_ID"] | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | +| `HEDERA_SPECIFIC_REVERT_STATUSES` | ["WRONG_NONCE", "INVALID_ACCOUNT_ID"] | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | | `FEE_HISTORY_MAX_RESULTS` | "10" | The maximum number of results to returns as part of `eth_feeHistory`. | | `ETH_FEE_HISTORY_FIXED` | "true" | Flag to set if eth_feeHistory should return a fixed fee for the set of results. | | `GAS_PRICE_PERCENTAGE_BUFFER` | "0" | The additional buffer that adds a percentage on top of the calculated network gasPrice. This may be used by operators to reduce the chances of `INSUFFICIENT_TX_FEE` errors experienced by users caused by minor fluctuations in the exchange rate. | diff --git a/packages/config-service/src/services/globalConfig.ts b/packages/config-service/src/services/globalConfig.ts index 13d62b6ab9..da3ceced10 100644 --- a/packages/config-service/src/services/globalConfig.ts +++ b/packages/config-service/src/services/globalConfig.ts @@ -183,8 +183,8 @@ export class GlobalConfig { required: false, defaultValue: null, }, - EXCLUDED_TRANSACTION_STATUSES: { - envName: 'EXCLUDED_TRANSACTION_STATUSES', + HEDERA_SPECIFIC_REVERT_STATUSES: { + envName: 'HEDERA_SPECIFIC_REVERT_STATUSES', type: 'string', required: false, defaultValue: '["WRONG_NONCE", "INVALID_ACCOUNT_ID"]', diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index 21c50515f0..f1fc63215b 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -48,7 +48,6 @@ import { formatContractResult, formatTransactionIdWithoutQueryParams, getFunctionSelector, - hexToASCII, isHex, isValidEthereumAddress, nanOrNumberTo0x, @@ -56,7 +55,6 @@ import { numberTo0x, parseNumericEnvVar, prepend0x, - strip0x, toHash32, trimPrecedingZeros, weibarHexToTinyBarInt, diff --git a/packages/relay/src/utils.ts b/packages/relay/src/utils.ts index c95347c644..80bf6f857d 100644 --- a/packages/relay/src/utils.ts +++ b/packages/relay/src/utils.ts @@ -119,10 +119,10 @@ export class Utils { error_message: any; }): boolean { // @ts-ignore - const statuses = JSON.parse(ConfigService.get('EXCLUDED_TRANSACTION_STATUSES')); + const statuses = JSON.parse(ConfigService.get('HEDERA_SPECIFIC_REVERT_STATUSES')); return ( - statuses.indexOf(contractResult.result) > -1 || - statuses.indexOf(hexToASCII(strip0x(contractResult.error_message ?? ''))) > -1 + statuses.includes(contractResult.result) || + statuses.includes(hexToASCII(strip0x(contractResult.error_message ?? ''))) ); } } diff --git a/packages/relay/tests/lib/utils.spec.ts b/packages/relay/tests/lib/utils.spec.ts index 264ffb7f3f..f87e1317b4 100644 --- a/packages/relay/tests/lib/utils.spec.ts +++ b/packages/relay/tests/lib/utils.spec.ts @@ -79,7 +79,7 @@ describe('Utils', () => { }); // @ts-ignore - JSON.parse(ConfigService.get('EXCLUDED_TRANSACTION_STATUSES')).forEach((status) => { + JSON.parse(ConfigService.get('HEDERA_SPECIFIC_REVERT_STATUSES')).forEach((status) => { it(`should exclude transaction with result ${status}`, () => { expect(Utils.isRevertedDueToHederaSpecificValidation({ result: status, error_message: null })).to.be.true; }); From 31e6e997803cca5c45c11fa414cdc0fc8aeb8c5c Mon Sep 17 00:00:00 2001 From: nikolay Date: Thu, 31 Oct 2024 10:55:45 +0200 Subject: [PATCH 3/6] chore: resolve comments Signed-off-by: nikolay --- docs/configuration.md | 2 +- packages/relay/src/lib/eth.ts | 3 +++ .../tests/lib/eth/eth_getBlockByNumber.spec.ts | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index d6cceaeaf9..186df55cfd 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -66,7 +66,7 @@ Unless you need to set a non-default value, it is recommended to only populate o | `ETH_CALL_CONSENSUS_SELECTORS` | [""] | A comma-separated list of special transaction selectors that should always be routed to the Consensus node. | | `ETH_GET_LOGS_BLOCK_RANGE_LIMIT` | "1000" | The maximum block number range to consider during an eth_getLogs call. | | `ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE` | "1000" | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | -| `HEDERA_SPECIFIC_REVERT_STATUSES` | ["WRONG_NONCE", "INVALID_ACCOUNT_ID"] | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | +| `HEDERA_SPECIFIC_REVERT_STATUSES` | ["WRONG_NONCE", "INVALID_ACCOUNT_ID"] | A list of specific transaction statuses where each one identifies that the transaction hadn't been executed in the evm but it had reached the services. | | `FEE_HISTORY_MAX_RESULTS` | "10" | The maximum number of results to returns as part of `eth_feeHistory`. | | `ETH_FEE_HISTORY_FIXED` | "true" | Flag to set if eth_feeHistory should return a fixed fee for the set of results. | | `GAS_PRICE_PERCENTAGE_BUFFER` | "0" | The additional buffer that adds a percentage on top of the calculated network gasPrice. This may be used by operators to reduce the chances of `INSUFFICIENT_TX_FEE` errors experienced by users caused by minor fluctuations in the exchange rate. | diff --git a/packages/relay/src/lib/eth.ts b/packages/relay/src/lib/eth.ts index f1fc63215b..e59df09a86 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -2302,6 +2302,9 @@ export class EthImpl implements Eth { // 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)) { + this.logger.debug( + `Transaction with hash ${contractResult.hash} is skipped due to hedera-specific validation failure`, + ); continue; } contractResult.from = await this.resolveEvmAddress(contractResult.from, requestDetails, [constants.TYPE_ACCOUNT]); diff --git a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts index e81001456c..3b3309f773 100644 --- a/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts +++ b/packages/relay/tests/lib/eth/eth_getBlockByNumber.spec.ts @@ -576,8 +576,16 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { restMock.onGet(CONTRACT_RESULTS_WITH_FILTER_URL).reply(200, { results: [ ...defaultContractResults.results, - { ...defaultContractResults.results[0], result: status }, - { ...defaultContractResults.results[0], error_message: prepend0x(ASCIIToHex(status)) }, + { + ...defaultContractResults.results[0], + result: status, + hash: '0xf84b9a38205131431901ca6a945046369f5be81bb579167458d4992427d03bb1', + }, + { + ...defaultContractResults.results[0], + error_message: prepend0x(ASCIIToHex(status)), + hash: '0x9c8d9d99e033c56bec1669a0ea68887b7df69ec1bac55899150b6ed5bc3f4b79', + }, ], }); restMock.onGet(CONTRACT_RESULTS_LOGS_WITH_FILTER_URL).reply(200, DEFAULT_ETH_GET_BLOCK_BY_LOGS); @@ -592,7 +600,8 @@ describe('@ethGetBlockByNumber using MirrorNode', async function () { number: BLOCK_NUMBER_HEX, parentHash: BLOCK_HASH_PREV_TRIMMED, timestamp: BLOCK_TIMESTAMP_HEX, - transactions: [CONTRACT_HASH_1, CONTRACT_HASH_2], // should not include the transaction with wrong nonce + // should not include the transaction with wrong nonce or invalid account id + transactions: [CONTRACT_HASH_1, CONTRACT_HASH_2], receiptsRoot: DEFAULT_BLOCK_RECEIPTS_ROOT_HASH, }, showDetails, From d8b48fb6bc22aa34304b89a4eeecbe421f509fc7 Mon Sep 17 00:00:00 2001 From: nikolay Date: Thu, 31 Oct 2024 18:49:23 +0200 Subject: [PATCH 4/6] chore: resolve comments Signed-off-by: nikolay --- 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 e59df09a86..a44bd7ee93 100644 --- a/packages/relay/src/lib/eth.ts +++ b/packages/relay/src/lib/eth.ts @@ -2303,7 +2303,7 @@ export class EthImpl implements Eth { // if a transaction has reverted there, we should not include that tx in the block response if (Utils.isRevertedDueToHederaSpecificValidation(contractResult)) { this.logger.debug( - `Transaction with hash ${contractResult.hash} is skipped due to hedera-specific validation failure`, + `${requestDetails.formattedRequestId} Transaction with hash ${contractResult.hash} is skipped due to hedera-specific validation failure (${contractResult.result})`, ); continue; } From 72036b46f369c57eb2064596d6fc3dfc7de12f3f Mon Sep 17 00:00:00 2001 From: nikolay Date: Fri, 1 Nov 2024 08:23:26 +0200 Subject: [PATCH 5/6] chore: pull main Signed-off-by: nikolay --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 186df55cfd..8721968a74 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -76,7 +76,7 @@ Unless you need to set a non-default value, it is recommended to only populate o | `HBAR_RATE_LIMIT_BASIC` | "1120000000" | Individual limit (in tinybars) for spending plans with a BASIC tier. Defaults to 11.2 HBARs. | | `HBAR_RATE_LIMIT_EXTENDED` | "3200000000" | Individual limit (in tinybars) for spending plans with a EXTENDED tier. Defaults to 32 HBARs. | | `HBAR_RATE_LIMIT_PRIVILEGED` | "8000000000" | Individual limit (in tinybars) for spending plans with a PRIVILEGED tier. Defaults to 80 HBARs. | -| `HBAR_SPENDING_PLANS_CONFIG_FILE` | "spendingPlansConfig.json" | The name of the JSON file containing the pre-configured spending plans for supported projects and partner projects. | +| `HBAR_SPENDING_PLANS_CONFIG` | "spendingPlansConfig.json" | The environment variable that either points to a file containing the spending plans, or the JSON content defining the spending plans. | | `HAPI_CLIENT_DURATION_RESET` | "3600000" | Time until client reinitialization. (ms) | | `HAPI_CLIENT_ERROR_RESET` | [21, 50] | Array of status codes, which when encountered will trigger a reinitialization. Status codes are availble [here](https://github.com/hashgraph/hedera-protobufs/blob/main/services/response_code.proto). | | `HAPI_CLIENT_TRANSACTION_RESET` | "50" | Number of transaction executions, until client reinitialization. | From a41beb1b21229da0e81cf7e55a4ae677705eca29 Mon Sep 17 00:00:00 2001 From: nikolay Date: Tue, 5 Nov 2024 08:49:45 +0200 Subject: [PATCH 6/6] chore: alphabet order Signed-off-by: nikolay --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 309ca22ce5..befe1130f2 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -66,7 +66,6 @@ Unless you need to set a non-default value, it is recommended to only populate o | `ETH_CALL_CONSENSUS_SELECTORS` | [""] | A comma-separated list of special transaction selectors that should always be routed to the Consensus node. | | `ETH_GET_LOGS_BLOCK_RANGE_LIMIT` | "1000" | The maximum block number range to consider during an eth_getLogs call. | | `ETH_GET_TRANSACTION_COUNT_MAX_BLOCK_RANGE` | "1000" | The maximum number of transactions to return when running eth_getBlockByHash or eth_getBlockByNumber with transaction objects set to true call. | -| `HEDERA_SPECIFIC_REVERT_STATUSES` | ["WRONG_NONCE", "INVALID_ACCOUNT_ID"] | A list of specific transaction statuses where each one identifies that the transaction hadn't been executed in the evm but it had reached the services. | | `FEE_HISTORY_MAX_RESULTS` | "10" | The maximum number of results to returns as part of `eth_feeHistory`. | | `ETH_FEE_HISTORY_FIXED` | "true" | Flag to set if eth_feeHistory should return a fixed fee for the set of results. | | `GAS_PRICE_PERCENTAGE_BUFFER` | "0" | The additional buffer that adds a percentage on top of the calculated network gasPrice. This may be used by operators to reduce the chances of `INSUFFICIENT_TX_FEE` errors experienced by users caused by minor fluctuations in the exchange rate. | @@ -77,6 +76,7 @@ Unless you need to set a non-default value, it is recommended to only populate o | `HBAR_RATE_LIMIT_EXTENDED` | "3200000000" | Individual limit (in tinybars) for spending plans with a EXTENDED tier. Defaults to 32 HBARs. | | `HBAR_RATE_LIMIT_PRIVILEGED` | "8000000000" | Individual limit (in tinybars) for spending plans with a PRIVILEGED tier. Defaults to 80 HBARs. | | `HBAR_SPENDING_PLANS_CONFIG` | "spendingPlansConfig.json" | The environment variable that either points to a file containing the spending plans, or the JSON content defining the spending plans. | +| `HEDERA_SPECIFIC_REVERT_STATUSES` | ["WRONG_NONCE", "INVALID_ACCOUNT_ID"] | A list of specific transaction statuses where each one identifies that the transaction hadn't been executed in the evm but it had reached the services. | | `HAPI_CLIENT_DURATION_RESET` | "3600000" | Time until client reinitialization. (ms) | | `HAPI_CLIENT_ERROR_RESET` | [21, 50] | Array of status codes, which when encountered will trigger a reinitialization. Status codes are availble [here](https://github.com/hashgraph/hedera-protobufs/blob/main/services/response_code.proto). | | `HAPI_CLIENT_TRANSACTION_RESET` | "50" | Number of transaction executions, until client reinitialization. |