Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ Unless you need to set a non-default value, it is recommended to only populate o
| `CLIENT_TRANSPORT_SECURITY` | "false" | Flag to enable or disable TLS for both networks. |
| `CONSENSUS_MAX_EXECUTION_TIME` | "15000" | Maximum time in ms the SDK will wait when submitting a transaction/query before throwing a TIMEOUT error. |
| `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. |
| `CONTRACT_CODE_SIZE_LIMIT` | 24576 | Maximum contract code size in bytes (24KB by default) allowed for contract deployment transactions. This limit is enforced during transaction validation to prevent excessive gas consumption from oversized contracts. |
| `CONTRACT_QUERY_TIMEOUT_RETRIES` | "3" | Maximum retries for failed contract call query with timeout exceeded error |
| `DEBUG_API_ENABLED` | "false" | Enables all debug related methods: `debug_traceTransaction` |
| `DEFAULT_RATE_LIMIT` | "200" | default fallback rate limit, if no other is configured. |
Expand Down
6 changes: 0 additions & 6 deletions packages/config-service/src/services/globalConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,6 @@ const _CONFIG = {
required: false,
defaultValue: 50_000_000,
},
CONTRACT_CODE_SIZE_LIMIT: {
envName: 'CONTRACT_CODE_SIZE_LIMIT',
type: 'number',
required: false,
defaultValue: 24576, // 24KB
},
CONTRACT_QUERY_TIMEOUT_RETRIES: {
envName: 'CONTRACT_QUERY_TIMEOUT_RETRIES',
type: 'number',
Expand Down
6 changes: 2 additions & 4 deletions packages/relay/src/lib/clients/mirrorNodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1555,7 +1555,6 @@ export class MirrorNodeClient {
* Retrieves and processes transaction record metrics from the mirror node based on the provided transaction ID.
*
* @param {string} transactionId - The ID of the transaction for which the record is being retrieved.
* @param {string} callerName - The name of the caller requesting the transaction record.
* @param {string} txConstructorName - The name of the transaction constructor associated with the transaction.
* @param {string} operatorAccountId - The account ID of the operator, used to calculate transaction fees.
* @param {RequestDetails} requestDetails - The request details for logging and tracking.
Expand All @@ -1564,7 +1563,6 @@ export class MirrorNodeClient {
*/
public async getTransactionRecordMetrics(
transactionId: string,
callerName: string,
txConstructorName: string,
operatorAccountId: string,
requestDetails: RequestDetails,
Expand All @@ -1573,7 +1571,7 @@ export class MirrorNodeClient {

if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`${formattedRequestId} Get transaction record via mirror node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`,
`${formattedRequestId} Get transaction record via mirror node: transactionId=${transactionId}, txConstructorName=${txConstructorName}`,
);
}

Expand All @@ -1591,7 +1589,7 @@ export class MirrorNodeClient {
);

if (!transactionRecords) {
const notFoundMessage = `No transaction record retrieved: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}.`;
const notFoundMessage = `No transaction record retrieved: transactionId=${transactionId}, txConstructorName=${txConstructorName}.`;
throw new MirrorNodeClientError({ message: notFoundMessage }, MirrorNodeClientError.statusCodes.NOT_FOUND);
}

Expand Down
11 changes: 2 additions & 9 deletions packages/relay/src/lib/clients/sdkClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,8 @@ export class SDKClient {
executionMode: constants.EXECUTION_MODE.QUERY,
transactionId: query.paymentTransactionId?.toString(),
txConstructorName: queryConstructorName,
callerName,
cost: queryCost,
gasUsed: 0,
interactingEntity,
status,
requestDetails,
originalCallerAddress,
Expand Down Expand Up @@ -487,11 +485,9 @@ export class SDKClient {
if (transactionId?.length) {
this.eventEmitter.emit(constants.EVENTS.EXECUTE_TRANSACTION, {
transactionId,
callerName,
requestDetails,
txConstructorName,
operatorAccountId: this.clientMain.operatorAccountId!.toString(),
interactingEntity,
originalCallerAddress,
} as IExecuteTransactionEventPayload);
}
Expand Down Expand Up @@ -558,11 +554,9 @@ export class SDKClient {
if (transactionResponse.transactionId) {
this.eventEmitter.emit(constants.EVENTS.EXECUTE_TRANSACTION, {
transactionId: transactionResponse.transactionId.toString(),
callerName,
requestDetails,
txConstructorName,
operatorAccountId: this.clientMain.operatorAccountId!.toString(),
interactingEntity,
originalCallerAddress,
} as IExecuteTransactionEventPayload);
}
Expand Down Expand Up @@ -736,7 +730,6 @@ export class SDKClient {
*/
public async getTransactionRecordMetrics(
transactionId: string,
callerName: string,
txConstructorName: string,
operatorAccountId: string,
requestDetails: RequestDetails,
Expand All @@ -747,7 +740,7 @@ export class SDKClient {
try {
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`${requestDetails.formattedRequestId} Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}`,
`${requestDetails.formattedRequestId} Get transaction record via consensus node: transactionId=${transactionId}, txConstructorName=${txConstructorName}`,
);
}

Expand All @@ -769,7 +762,7 @@ export class SDKClient {
const sdkClientError = new SDKClientError(e, e.message);
this.logger.warn(
e,
`${requestDetails.formattedRequestId} Error raised during TransactionRecordQuery: transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, recordStatus=${sdkClientError.status} (${sdkClientError.status._code}), cost=${transactionFee}, gasUsed=${gasUsed}`,
`${requestDetails.formattedRequestId} Error raised during TransactionRecordQuery: transactionId=${transactionId}, txConstructorName=${txConstructorName}, recordStatus=${sdkClientError.status} (${sdkClientError.status._code}), cost=${transactionFee}, gasUsed=${gasUsed}`,
);
throw sdkClientError;
}
Expand Down
1 change: 0 additions & 1 deletion packages/relay/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ export default {

MAX_TRANSACTION_FEE_THRESHOLD: ConfigService.get('MAX_TRANSACTION_FEE_THRESHOLD'),
SEND_RAW_TRANSACTION_SIZE_LIMIT: ConfigService.get('SEND_RAW_TRANSACTION_SIZE_LIMIT'),
CONTRACT_CODE_SIZE_LIMIT: ConfigService.get('CONTRACT_CODE_SIZE_LIMIT'),
CALL_DATA_SIZE_LIMIT: ConfigService.get('CALL_DATA_SIZE_LIMIT'),

INVALID_EVM_INSTRUCTION: '0xfe',
Expand Down
5 changes: 0 additions & 5 deletions packages/relay/src/lib/errors/JsonRpcError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,6 @@ export const predefined = {
code: -32201,
message: `Oversized data: call data size ${actualSize}, call data size limit ${expectedSize}`,
}),
CONTRACT_CODE_SIZE_LIMIT_EXCEEDED: (actualSize: number, expectedSize: number) =>
new JsonRpcError({
code: -32201,
message: `Oversized data: contract code size ${actualSize}, contract code size limit ${expectedSize}`,
}),
BATCH_REQUESTS_DISABLED: new JsonRpcError({
code: -32202,
message: 'Batch requests are disabled',
Expand Down
18 changes: 0 additions & 18 deletions packages/relay/src/lib/precheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export class Precheck {
networkGasPriceInWeiBars: number,
requestDetails: RequestDetails,
): Promise<void> {
this.contractCodeSize(parsedTx);
this.callDataSize(parsedTx);
this.transactionSize(parsedTx);
this.transactionType(parsedTx, requestDetails);
Expand Down Expand Up @@ -383,21 +382,4 @@ export class Precheck {
}
}
}

/**
* Validates that the contract code size is within the allowed limit.
* This check is only performed for contract creation transactions (where tx.to is null).
* This limits contract code size to prevent excessive gas consumption.
*
* @param {Transaction} tx - The transaction to validate.
* @throws {JsonRpcError} If the contract code size exceeds the configured limit.
*/
contractCodeSize(tx: Transaction): void {
if (!tx.to) {
const contractCodeSize = tx.data.replace('0x', '').length / 2;
if (contractCodeSize > constants.CONTRACT_CODE_SIZE_LIMIT) {
throw predefined.CONTRACT_CODE_SIZE_LIMIT_EXCEEDED(contractCodeSize, constants.CONTRACT_CODE_SIZE_LIMIT);
}
}
}
}
39 changes: 7 additions & 32 deletions packages/relay/src/lib/services/metricService/metricService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,14 @@ export default class MetricService {
* @returns {Promise<void>} - A promise that resolves when the transaction metrics have been captured.
*/
public async captureTransactionMetrics({
callerName,
transactionId,
txConstructorName,
operatorAccountId,
interactingEntity,
requestDetails,
originalCallerAddress,
}: IExecuteTransactionEventPayload): Promise<void> {
const transactionRecordMetrics = await this.getTransactionRecordMetrics(
transactionId,
callerName,
txConstructorName,
operatorAccountId,
requestDetails,
Expand All @@ -159,10 +156,8 @@ export default class MetricService {
executionMode: constants.EXECUTION_MODE.TRANSACTION,
transactionId,
txConstructorName,
callerName,
cost: transactionFee,
gasUsed,
interactingEntity,
status,
requestDetails,
originalCallerAddress,
Expand All @@ -174,10 +169,8 @@ export default class MetricService {
executionMode: constants.EXECUTION_MODE.RECORD,
transactionId,
txConstructorName,
callerName,
cost: txRecordChargeAmount,
gasUsed: 0,
interactingEntity,
status,
requestDetails,
originalCallerAddress,
Expand All @@ -193,10 +186,8 @@ export default class MetricService {
* @param {string} payload.executionMode - The mode of the execution (TRANSACTION, QUERY, RECORD).
* @param {string} payload.transactionId - The unique identifier for the transaction.
* @param {string} payload.txConstructorName - The name of the transaction constructor.
* @param {string} payload.callerName - The name of the entity calling the transaction.
* @param {number} payload.cost - The cost of the transaction in tinybars.
* @param {number} payload.gasUsed - The amount of gas used during the transaction.
* @param {string} payload.interactingEntity - The entity interacting with the transaction.
* @param {string} payload.status - The entity interacting with the transaction.
* @param {string} payload.requestDetails - The request details for logging and tracking.
* @param {string | undefined} payload.originalCallerAddress - The address of the original caller making the request.
Expand All @@ -206,22 +197,20 @@ export default class MetricService {
executionMode,
transactionId,
txConstructorName,
callerName,
cost,
gasUsed,
interactingEntity,
status,
requestDetails,
originalCallerAddress,
}: IExecuteQueryEventPayload): Promise<void> => {
if (this.logger.isLevelEnabled('debug')) {
this.logger.debug(
`${requestDetails.formattedRequestId} Capturing transaction fee charged to operator: executionMode=${executionMode} transactionId=${transactionId}, txConstructorName=${txConstructorName}, callerName=${callerName}, cost=${cost} tinybars`,
`${requestDetails.formattedRequestId} Capturing transaction fee charged to operator: executionMode=${executionMode} transactionId=${transactionId}, txConstructorName=${txConstructorName}, cost=${cost} tinybars`,
);
}

await this.hbarLimitService.addExpense(cost, originalCallerAddress ?? '', requestDetails);
this.captureMetrics(executionMode, txConstructorName, status, cost, gasUsed, callerName, interactingEntity);
this.captureMetrics(executionMode, txConstructorName, status, cost, gasUsed);
};

/**
Expand All @@ -235,7 +224,7 @@ export default class MetricService {
return new Histogram({
name: metricHistogramCost,
help: 'Relay consensusnode mode type status cost histogram',
labelNames: ['mode', 'type', 'status', 'caller', 'interactingEntity'],
labelNames: ['mode', 'type', 'status'],
registers: [register],
});
}
Expand All @@ -251,7 +240,7 @@ export default class MetricService {
return new Histogram({
name: metricHistogramGasFee,
help: 'Relay consensusnode mode type status gas fee histogram',
labelNames: ['mode', 'type', 'status', 'caller', 'interactingEntity'],
labelNames: ['mode', 'type', 'status'],
registers: [register],
});
}
Expand All @@ -275,21 +264,11 @@ export default class MetricService {
* @param {string} status - The status of the transaction.
* @param {number} cost - The cost of the transaction in tinybars.
* @param {number} gas - The gas used by the transaction.
* @param {string} caller - The name of the caller executing the transaction.
* @param {string} interactingEntity - The entity interacting with the transaction.
* @returns {void}
*/
private captureMetrics = (
mode: string,
type: string,
status: string,
cost: number,
gas: number,
caller: string,
interactingEntity: string,
): void => {
this.consensusNodeClientHistogramCost.labels(mode, type, status, caller, interactingEntity).observe(cost);
this.consensusNodeClientHistogramGasFee.labels(mode, type, status, caller, interactingEntity).observe(gas);
private captureMetrics = (mode: string, type: string, status: string, cost: number, gas: number): void => {
this.consensusNodeClientHistogramCost.labels(mode, type, status).observe(cost);
this.consensusNodeClientHistogramGasFee.labels(mode, type, status).observe(gas);
};

/**
Expand All @@ -298,15 +277,13 @@ export default class MetricService {
* consensus node via the SDK client or from the mirror node.
*
* @param {string} transactionId - The ID of the transaction for which metrics are being retrieved.
* @param {string} callerName - The name of the caller requesting the metrics.
* @param {string} txConstructorName - The name of the transaction constructor.
* @param {string} operatorAccountId - The account ID of the operator.
* @param {RequestDetails} requestDetails - The request details for logging and tracking.
* @returns {Promise<ITransactionRecordMetric | undefined>} - The transaction record metrics or undefined if retrieval fails.
*/
private async getTransactionRecordMetrics(
transactionId: string,
callerName: string,
txConstructorName: string,
operatorAccountId: string,
requestDetails: RequestDetails,
Expand All @@ -318,15 +295,13 @@ export default class MetricService {
if (defaultToConsensusNode) {
return await this.sdkClient.getTransactionRecordMetrics(
transactionId,
callerName,
txConstructorName,
operatorAccountId,
requestDetails,
);
} else {
return await this.mirrorNodeClient.getTransactionRecordMetrics(
transactionId,
callerName,
txConstructorName,
operatorAccountId,
requestDetails,
Expand Down
2 changes: 0 additions & 2 deletions packages/relay/src/lib/types/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ export interface IExecuteQueryEventPayload {
executionMode: string;
transactionId: string;
txConstructorName: string;
callerName: string;
cost: number;
gasUsed: number;
interactingEntity: string;
status: string;
requestDetails: RequestDetails;
originalCallerAddress: string | undefined;
Expand Down
4 changes: 1 addition & 3 deletions packages/relay/tests/lib/mirrorNodeClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,6 @@ describe('MirrorNodeClient', async function () {

const transactionRecordMetrics = await mirrorNodeInstance.getTransactionRecordMetrics(
mockedTransactionId,
mockedCallerName,
mockedConstructorName,
operatorAcocuntId,
requestDetails,
Expand All @@ -1482,15 +1481,14 @@ describe('MirrorNodeClient', async function () {
try {
await mirrorNodeInstance.getTransactionRecordMetrics(
mockedTransactionId,
mockedCallerName,
mockedConstructorName,
operatorAcocuntId,
requestDetails,
);

expect.fail('should have thrown an error');
} catch (error) {
const notFoundMessage = `No transaction record retrieved: transactionId=${mockedTransactionId}, txConstructorName=${mockedConstructorName}, callerName=${mockedCallerName}.`;
const notFoundMessage = `No transaction record retrieved: transactionId=${mockedTransactionId}, txConstructorName=${mockedConstructorName}.`;
const expectedError = new MirrorNodeClientError(
{ message: notFoundMessage },
MirrorNodeClientError.statusCodes.NOT_FOUND,
Expand Down
Loading
Loading