diff --git a/docs/configuration.md b/docs/configuration.md index e966d4f6ee..4046634a38 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -87,6 +87,7 @@ Unless you need to set a non-default value, it is recommended to only populate o | `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. | | `MULTI_SET` | "false" | Switch between different implementation of setting multiple K/V pairs in the shared cache. True is mSet, false is pipeline | +| `OPCODELOGGER_ENABLED` | "true" | Whether the `opcodeLogger` tracer is enabled for a call to `debug_traceTransaction`. This setting should match the value `hiero.mirror.web3.opcode.tracer.enabled` in the Mirror Node used. See [HIP-801](https://hips.hedera.com/hip/hip-801) for more information. | | `JUMBO_TX_ENABLED` | "true" | Controls how large transactions are handled during `eth_sendRawTransaction`. When set to `true`, transactions up to 128KB can be sent directly to consensus nodes without using Hedera File Service (HFS), as long as contract bytecode doesn't exceed 24KB. When set to `false`, all transactions containing contract deployments use the traditional HFS approach. This feature leverages the increased transaction size limit to simplify processing of standard Ethereum transactions. | | `IP_RATE_LIMIT_STORE` | null | Specifies the rate limit store to use for IP-based rate limiting: valid values are "LRU", "REDIS", with the possibility to be extended with a custom implementation (see [Store Selection](rate-limiting.md#store-selection)). If unset, falls back to Redis when `REDIS_ENABLED=true`, otherwise uses in-memory LRU. | | `REDIS_ENABLED` | "true" | Enable usage of Redis as shared cache | diff --git a/packages/config-service/src/services/globalConfig.ts b/packages/config-service/src/services/globalConfig.ts index c3dc0cb894..44de98580c 100644 --- a/packages/config-service/src/services/globalConfig.ts +++ b/packages/config-service/src/services/globalConfig.ts @@ -593,6 +593,12 @@ const _CONFIG = { required: true, defaultValue: null, }, + OPCODELOGGER_ENABLED: { + envName: 'OPCODELOGGER_ENABLED', + type: 'boolean', + required: false, + defaultValue: true, + }, OPERATOR_ID_ETH_SENDRAWTRANSACTION: { envName: 'OPERATOR_ID_ETH_SENDRAWTRANSACTION', type: 'string', diff --git a/packages/relay/src/lib/debug.ts b/packages/relay/src/lib/debug.ts index 6f8006711a..c741e352b6 100644 --- a/packages/relay/src/lib/debug.ts +++ b/packages/relay/src/lib/debug.ts @@ -133,6 +133,10 @@ export class DebugImpl implements Debug { if (tracer === TracerType.CallTracer) { return await this.callTracer(transactionIdOrHash, tracerConfig as ICallTracerConfig, requestDetails); } + + if (!ConfigService.get('OPCODELOGGER_ENABLED')) { + throw predefined.UNSUPPORTED_METHOD; + } return await this.callOpcodeLogger(transactionIdOrHash, tracerConfig as IOpcodeLoggerConfig, requestDetails); } catch (e) { throw this.common.genericErrorHandler(e); diff --git a/packages/relay/tests/lib/debug.spec.ts b/packages/relay/tests/lib/debug.spec.ts index b4513807cc..5c5dd990b6 100644 --- a/packages/relay/tests/lib/debug.spec.ts +++ b/packages/relay/tests/lib/debug.spec.ts @@ -34,7 +34,6 @@ let restMock: MockAdapter; let web3Mock: MockAdapter; let mirrorNodeInstance: MirrorNodeClient; let debugService: DebugImpl; -let hapiServiceInstance: HAPIService; describe('Debug API Test Suite', async function () { this.timeout(10000); @@ -61,7 +60,6 @@ describe('Debug API Test Suite', async function () { const CONTRACT_BY_ADDRESS2 = `contracts/${contractAddress2}`; const CONTRACTS_RESULTS_BY_NON_EXISTENT_HASH = `contracts/results/${nonExistentTransactionHash}`; const CONTRACT_RESULTS_BY_ACTIONS_NON_EXISTENT_HASH = `contracts/results/${nonExistentTransactionHash}/actions`; - const BLOCKS_ENDPOINT = 'blocks'; const opcodeLoggerConfigs = [ { @@ -276,7 +274,7 @@ describe('Debug API Test Suite', async function () { register, duration, ); - hapiServiceInstance = new HAPIService(logger, registry, eventEmitter, hbarLimitService); + new HAPIService(logger, registry, eventEmitter, hbarLimitService); restMock = new MockAdapter(mirrorNodeInstance.getMirrorNodeRestInstance(), { onNoMatch: 'throwException' }); @@ -439,6 +437,18 @@ describe('Debug API Test Suite', async function () { }); describe('opcodeLogger', async function () { + withOverriddenEnvsInMochaTest({ OPCODELOGGER_ENABLED: false }, () => { + it('should throw UNSUPPORTED_METHOD', async function () { + await RelayAssertions.assertRejection( + predefined.UNSUPPORTED_METHOD, + debugService.traceTransaction, + true, + debugService, + [transactionHash, callTracer, tracerConfigFalse, requestDetails], + ); + }); + }); + for (const config of opcodeLoggerConfigs) { const opcodeLoggerParams = Object.keys(config) .map((key) => `${key}=${config[key]}`)