Skip to content

Commit e8f72ae

Browse files
committed
reverts getCode refactor
Signed-off-by: Konstantina Blazhukova <konstantina.blajukova@gmail.com>
1 parent 7c68a42 commit e8f72ae

File tree

1 file changed

+6
-263
lines changed

1 file changed

+6
-263
lines changed

packages/relay/src/lib/services/contractService/ContractService.ts

Lines changed: 6 additions & 263 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
import { disassemble } from '@ethersproject/asm';
33
import { ConfigService } from '@hashgraph/json-rpc-config-service/dist/services';
4-
import { PrecheckStatusError } from '@hashgraph/sdk';
54
import crypto from 'crypto';
65
import { Logger } from 'pino';
76

@@ -19,16 +18,9 @@ import constants from '../../constants';
1918
import { JsonRpcError, predefined } from '../../errors/JsonRpcError';
2019
import { MirrorNodeClientError } from '../../errors/MirrorNodeClientError';
2120
import { SDKClientError } from '../../errors/SDKClientError';
22-
import { EthImpl } from '../../eth';
2321
import { Log } from '../../model';
2422
import { Precheck } from '../../precheck';
25-
import {
26-
IContractCallRequest,
27-
IContractCallResponse,
28-
IContractResult,
29-
IGetLogsParams,
30-
RequestDetails,
31-
} from '../../types';
23+
import { IContractCallRequest, IContractCallResponse, IGetLogsParams, RequestDetails } from '../../types';
3224
import { CommonService } from '..';
3325
import { CacheService } from '../cacheService/cacheService';
3426
import { ICommonService } from '../ethService/ethCommonService/ICommonService';
@@ -260,26 +252,26 @@ export class ContractService implements IContractService {
260252
if (!blockInfo || parseFloat(result.entity?.created_timestamp) > parseFloat(blockInfo.timestamp.to)) {
261253
return constants.EMPTY_HEX;
262254
}
263-
if (result?.type === constants.TYPE_TOKEN) {
255+
if (result.type === constants.TYPE_TOKEN) {
264256
if (this.logger.isLevelEnabled('trace')) {
265257
this.logger.trace(`${requestIdPrefix} Token redirect case, return redirectBytecode`);
266258
}
267259
return CommonService.redirectBytecodeAddressReplace(address);
268-
} else if (result?.type === constants.TYPE_CONTRACT) {
269-
if (result?.entity.runtime_bytecode !== constants.EMPTY_HEX) {
260+
} else if (result.type === constants.TYPE_CONTRACT) {
261+
if (result.entity.runtime_bytecode !== constants.EMPTY_HEX) {
270262
const prohibitedOpcodes = ['CALLCODE', 'DELEGATECALL', 'SELFDESTRUCT', 'SUICIDE'];
271263
const opcodes = disassemble(result?.entity.runtime_bytecode);
272264
const hasProhibitedOpcode =
273265
opcodes.filter((opcode) => prohibitedOpcodes.indexOf(opcode.opcode.mnemonic) > -1).length > 0;
274266
if (!hasProhibitedOpcode) {
275267
await this.cacheService.set(
276268
cachedLabel,
277-
result?.entity.runtime_bytecode,
269+
result.entity.runtime_bytecode,
278270
constants.ETH_GET_CODE,
279271
requestDetails,
280272
);
281273
}
282-
return result?.entity.runtime_bytecode;
274+
return result.entity.runtime_bytecode;
283275
}
284276
}
285277
}
@@ -665,37 +657,6 @@ export class ContractService implements IContractService {
665657

666658
return gas;
667659
}
668-
/**
669-
* Attempts to get code from cache and mirror node.
670-
*
671-
* @param {string} address - The contract address
672-
* @param {string | null} blockNumber - Block number or tag
673-
* @param {RequestDetails} requestDetails - The request details
674-
* @returns {Promise<string | null>} The contract code if found, null otherwise
675-
* @private
676-
*/
677-
private async getCodeWithCache(
678-
address: string,
679-
blockNumber: string | null,
680-
requestDetails: RequestDetails,
681-
): Promise<string | null> {
682-
const cachedLabel = `getCode.${address}.${blockNumber}`;
683-
const cachedResponse: string | undefined = await this.cacheService.getAsync(
684-
cachedLabel,
685-
constants.ETH_GET_CODE,
686-
requestDetails,
687-
);
688-
if (cachedResponse != undefined) {
689-
return cachedResponse;
690-
}
691-
692-
const mirrorNodeResult = await this.tryGetCodeFromMirrorNode(address, blockNumber, cachedLabel, requestDetails);
693-
if (mirrorNodeResult) {
694-
return mirrorNodeResult;
695-
}
696-
697-
return null;
698-
}
699660

700661
/**
701662
* Handles errors from consensus node calls.
@@ -718,63 +679,6 @@ export class ContractService implements IContractService {
718679
}
719680
return predefined.INTERNAL_ERROR(e.message.toString());
720681
}
721-
722-
/**
723-
* Processes and caches contract bytecode if it doesn't contain prohibited opcodes.
724-
*
725-
* @param {IContractResult} result - The contract result containing bytecode
726-
* @param {string} cachedLabel - The cache key to store the bytecode
727-
* @param {RequestDetails} requestDetails - The request details for logging and tracking
728-
* @returns {Promise<string | null>} The runtime bytecode if valid, null otherwise
729-
* @private
730-
*/
731-
private async handleContractBytecode(
732-
result: IContractResult,
733-
cachedLabel: string,
734-
requestDetails: RequestDetails,
735-
): Promise<string | null> {
736-
if (result?.entity.runtime_bytecode !== constants.EMPTY_HEX) {
737-
if (!this.hasProhibitedOpcodes(result.entity.runtime_bytecode)) {
738-
await this.cacheService.set(
739-
cachedLabel,
740-
result.entity.runtime_bytecode,
741-
constants.ETH_GET_CODE,
742-
requestDetails,
743-
);
744-
return result.entity.runtime_bytecode;
745-
}
746-
}
747-
return constants.EMPTY_HEX;
748-
}
749-
750-
/**
751-
* Handles errors that occur during getCode operations.
752-
*
753-
* @param {any} e - The error to handle
754-
* @param {string} address - The contract address
755-
* @param {string | null} blockNumber - The block number or tag
756-
* @param {string} requestIdPrefix - The request ID prefix for logging
757-
* @returns {string | never} The error response or throws if unhandled
758-
* @private
759-
*/
760-
private handleGetCodeError(
761-
e: any,
762-
address: string,
763-
blockNumber: string | null,
764-
requestIdPrefix: string,
765-
): string | never {
766-
if (e instanceof SDKClientError) {
767-
return this.handleSDKClientError(e, address, blockNumber, requestIdPrefix);
768-
}
769-
770-
if (e instanceof PrecheckStatusError) {
771-
return this.handlePrecheckStatusError(e, address, blockNumber, requestIdPrefix);
772-
}
773-
774-
this.logger.error(e, `${requestIdPrefix} Error raised during getCode for address ${address}`);
775-
throw e;
776-
}
777-
778682
/**
779683
* Handles specific mirror node client errors.
780684
*
@@ -839,127 +743,6 @@ export class ContractService implements IContractService {
839743
return predefined.INTERNAL_ERROR(e.message.toString());
840744
}
841745

842-
/**
843-
* Handles precheck status errors during contract operations.
844-
*
845-
* @param {PrecheckStatusError} e - The precheck status error
846-
* @param {string} address - The contract address
847-
* @param {string | null} blockNumber - The block number or tag
848-
* @param {string} requestIdPrefix - The request ID prefix for logging
849-
* @returns {string | never} The empty hex string for known errors or throws
850-
* @private
851-
*/
852-
private handlePrecheckStatusError(
853-
e: PrecheckStatusError,
854-
address: string,
855-
blockNumber: string | null,
856-
requestIdPrefix: string,
857-
): string | never {
858-
if (
859-
e.status._code === constants.PRECHECK_STATUS_ERROR_STATUS_CODES.INVALID_CONTRACT_ID ||
860-
e.status._code === constants.PRECHECK_STATUS_ERROR_STATUS_CODES.CONTRACT_DELETED
861-
) {
862-
if (this.logger.isLevelEnabled('debug')) {
863-
this.logger.debug(
864-
`${requestIdPrefix} Unable to find code for contract ${address} in block "${blockNumber}", returning 0x0, err code: ${e.status._code}`,
865-
);
866-
}
867-
return constants.EMPTY_HEX;
868-
}
869-
870-
this.hapiService.decrementErrorCounter(e.status._code);
871-
this.logger.error(
872-
e,
873-
`${requestIdPrefix} Error raised during getCode for address ${address}, err code: ${e.status._code}`,
874-
);
875-
throw e;
876-
}
877-
878-
/**
879-
* Handles SDK client errors during contract operations.
880-
*
881-
* @param {SDKClientError} e - The SDK client error
882-
* @param {string} address - The contract address
883-
* @param {string | null} blockNumber - The block number or tag
884-
* @param {string} requestIdPrefix - The request ID prefix for logging
885-
* @returns {string | never} The empty hex string for known errors or throws
886-
* @private
887-
*/
888-
private handleSDKClientError(
889-
e: SDKClientError,
890-
address: string,
891-
blockNumber: string | null,
892-
requestIdPrefix: string,
893-
): string | never {
894-
if (e.isInvalidContractId() || e.isContractDeleted()) {
895-
if (this.logger.isLevelEnabled('debug')) {
896-
this.logger.debug(
897-
`${requestIdPrefix} Unable to find code for contract ${address} in block "${blockNumber}", returning 0x0, err code: ${e.statusCode}`,
898-
);
899-
}
900-
return constants.EMPTY_HEX;
901-
}
902-
903-
this.hapiService.decrementErrorCounter(e.statusCode);
904-
this.logger.error(
905-
e,
906-
`${requestIdPrefix} Error raised during getCode for address ${address}, err code: ${e.statusCode}`,
907-
);
908-
throw e;
909-
}
910-
911-
/**
912-
* Handles token redirect cases by generating appropriate bytecode.
913-
*
914-
* @param {string} address - The token address
915-
* @param {string} requestIdPrefix - The request ID prefix for logging
916-
* @returns {string} The redirect bytecode for the token
917-
* @private
918-
*/
919-
private handleTokenRedirect(address: string, requestIdPrefix: string): string {
920-
const redirectBytecodePostfix =
921-
'600052366000602037600080366018016008845af43d806000803e8160008114605857816000f35b816000fdfea2646970667358221220d8378feed472ba49a0005514ef7087017f707b45fb9bf56bb81bb93ff19a238b64736f6c634300080b0033';
922-
const redirectBytecodePrefix = '6080604052348015600f57600080fd5b506000610167905077618dc65e';
923-
924-
if (this.logger.isLevelEnabled('trace')) {
925-
this.logger.trace(`${requestIdPrefix} Token redirect case, return redirectBytecode`);
926-
}
927-
return `${redirectBytecodePrefix}${address.slice(2)}${redirectBytecodePostfix}`;
928-
}
929-
930-
/**
931-
* Checks if the provided bytecode contains any prohibited EVM opcodes.
932-
*
933-
* @param {string} bytecode - The bytecode to check
934-
* @returns {boolean} True if prohibited opcodes are found, false otherwise
935-
* @private
936-
*/
937-
private hasProhibitedOpcodes(bytecode: string): boolean {
938-
const prohibitedOpcodes = ['CALLCODE', 'DELEGATECALL', 'SELFDESTRUCT', 'SUICIDE'];
939-
const opcodes = disassemble(bytecode);
940-
return opcodes.filter((opcode) => prohibitedOpcodes.indexOf(opcode.opcode.mnemonic) > -1).length > 0;
941-
}
942-
943-
/**
944-
* Checks if the address is the HTS precompile address.
945-
*
946-
* @param {string} address - The address to check
947-
* @param {string} requestIdPrefix - The request ID prefix for logging
948-
* @returns {boolean} True if address is HTS precompile
949-
* @private
950-
*/
951-
private isHTSPrecompile(address: string, requestIdPrefix: string): boolean {
952-
if (address === constants.HTS_ADDRESS) {
953-
if (this.logger.isLevelEnabled('trace')) {
954-
this.logger.trace(
955-
`${requestIdPrefix} HTS precompile case, return ${constants.INVALID_EVM_INSTRUCTION} for byte code`,
956-
);
957-
}
958-
return true;
959-
}
960-
return false;
961-
}
962-
963746
/**
964747
* Fallback calculations for the amount of gas to be used for a transaction.
965748
* This method is used when the mirror node fails to return a gas estimate.
@@ -1113,46 +896,6 @@ export class ContractService implements IContractService {
1113896
return cachedResponse === null ? undefined : cachedResponse;
1114897
}
1115898

1116-
/**
1117-
* Attempts to retrieve contract code from the mirror node.
1118-
*
1119-
* @param {string} address - The contract address
1120-
* @param {string | null} blockNumber - The block number or tag
1121-
* @param {string} cachedLabel - The cache key for storing results
1122-
* @param {RequestDetails} requestDetails - The request details for logging and tracking
1123-
* @returns {Promise<string | null>} The contract code if found, null otherwise
1124-
* @private
1125-
*/
1126-
private async tryGetCodeFromMirrorNode(
1127-
address: string,
1128-
blockNumber: string | null,
1129-
cachedLabel: string,
1130-
requestDetails: RequestDetails,
1131-
): Promise<string | null> {
1132-
const result = await this.mirrorNodeClient.resolveEntityType(address, constants.ETH_GET_CODE, requestDetails, [
1133-
constants.TYPE_CONTRACT,
1134-
constants.TYPE_TOKEN,
1135-
]);
1136-
1137-
if (!result) return null;
1138-
1139-
// Check if contract was created after the requested block
1140-
const blockInfo = await this.common.getHistoricalBlockResponse(requestDetails, blockNumber, true);
1141-
if (!blockInfo || parseFloat(result.entity?.created_timestamp) > parseFloat(blockInfo.timestamp.to)) {
1142-
return constants.EMPTY_HEX;
1143-
}
1144-
1145-
if (result.type === constants.TYPE_TOKEN) {
1146-
return this.handleTokenRedirect(address, requestDetails.formattedRequestId);
1147-
}
1148-
1149-
if (result.type === constants.TYPE_CONTRACT) {
1150-
return await this.handleContractBytecode(result, cachedLabel, requestDetails);
1151-
}
1152-
1153-
return constants.EMPTY_HEX;
1154-
}
1155-
1156899
/**
1157900
* Validates the from and to addresses in the call request.
1158901
*

0 commit comments

Comments
 (0)