@@ -167,24 +167,26 @@ export class ContractService implements IContractService {
167167 try {
168168 const response = await this . estimateGasFromMirrorNode ( transaction , requestDetails ) ;
169169
170- if ( response ?. result ) {
171- this . logger . info ( `Returning gas: ${ response . result } ` ) ;
172- return prepend0x ( trimPrecedingZeros ( response . result ) ) ;
173- } else {
174- this . logger . error ( `No gas estimate returned from mirror-node: ${ JSON . stringify ( response ) } ` ) ;
175- return this . predefinedGasForTransaction ( transaction , requestDetails ) ;
170+ if ( ! response ?. result ) {
171+ if ( this . logger . isLevelEnabled ( 'debug' ) ) {
172+ this . logger . debug ( `No gas estimate returned from mirror-node: ${ JSON . stringify ( response ) } ` ) ;
173+ }
174+ return predefined . INTERNAL_ERROR ( 'Fail to retrieve gas estimate' ) ;
176175 }
176+
177+ return prepend0x ( trimPrecedingZeros ( response . result ) ) ;
177178 } catch ( e : any ) {
178- this . logger . error ( `Error raised while fetching estimateGas from mirror-node: ${ JSON . stringify ( e ) } ` ) ;
179- // in case of contract revert, we don't want to return a predefined gas but the actual error with the reason
180- if (
181- ConfigService . get ( 'ESTIMATE_GAS_THROWS' ) &&
182- e instanceof MirrorNodeClientError &&
183- e . isContractRevertOpcodeExecuted ( )
184- ) {
185- return predefined . CONTRACT_REVERT ( e . detail ?? e . message , e . data ) ;
179+ if ( e instanceof MirrorNodeClientError ) {
180+ if ( e . isContractRevert ( ) ) {
181+ throw predefined . CONTRACT_REVERT ( e . detail || e . message , e . data ) ;
182+ } else if ( e . statusCode === 400 ) {
183+ throw predefined . COULD_NOT_SIMULATE_TRANSACTION ( e . detail || e . message ) ;
184+ }
186185 }
187- return this . predefinedGasForTransaction ( transaction , requestDetails , e ) ;
186+
187+ // for any other error or Mirror Node upstream server errors (429, 500, 502, 503, 504, etc.),
188+ // preserve the original error and re-throw to the upper layer for further handling logic
189+ throw e ;
188190 }
189191 }
190192
@@ -523,15 +525,14 @@ export class ContractService implements IContractService {
523525 return constants . EMPTY_HEX ;
524526 }
525527
526- if ( e . isContractReverted ( ) ) {
527- if ( this . logger . isLevelEnabled ( 'trace' ) ) {
528- this . logger . trace (
529- `mirror node eth_call request encountered contract revert. message: ${ e . message } , details: ${ e . detail } , data: ${ e . data } ` ,
530- ) ;
531- }
532- return predefined . CONTRACT_REVERT ( e . detail || e . message , e . data ) ;
528+ if ( e . isContractRevert ( ) ) {
529+ throw predefined . CONTRACT_REVERT ( e . detail || e . message , e . data ) ;
530+ } else if ( e . statusCode === 400 ) {
531+ throw predefined . COULD_NOT_SIMULATE_TRANSACTION ( e . detail || e . message ) ;
533532 }
534- // 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
533+
534+ // for any other error or Mirror Node upstream server errors (429, 500, 502, 503, 504, etc.),
535+ // preserve the original error and re-throw to the upper layer for further handling logic
535536 throw e ;
536537 }
537538
@@ -555,68 +556,6 @@ export class ContractService implements IContractService {
555556 return predefined . INTERNAL_ERROR ( e . message . toString ( ) ) ;
556557 }
557558
558- /**
559- * Fallback calculations for the amount of gas to be used for a transaction.
560- * This method is used when the mirror node fails to return a gas estimate.
561- *
562- * @param {IContractCallRequest } transaction The transaction data for the contract call.
563- * @param {RequestDetails } requestDetails The request details for logging and tracking.
564- * @param error (Optional) received error from the mirror-node contract call request.
565- * @returns {Promise<string | JsonRpcError> } the calculated gas cost for the transaction
566- */
567- private async predefinedGasForTransaction (
568- transaction : IContractCallRequest ,
569- requestDetails : RequestDetails ,
570- error ?: any ,
571- ) : Promise < string | JsonRpcError > {
572- const isSimpleTransfer = ! ! transaction ?. to && ( ! transaction . data || transaction . data === '0x' ) ;
573- const isContractCall =
574- ! ! transaction ?. to && transaction ?. data && transaction . data . length >= constants . FUNCTION_SELECTOR_CHAR_LENGTH ;
575- const isContractCreate = ! transaction ?. to && transaction ?. data && transaction . data !== '0x' ;
576- const contractCallAverageGas = numberTo0x ( constants . TX_CONTRACT_CALL_AVERAGE_GAS ) ;
577- const gasTxBaseCost = numberTo0x ( constants . TX_BASE_COST ) ;
578-
579- if ( isSimpleTransfer ) {
580- // Handle Simple Transaction and Hollow Account creation
581- const isZeroOrHigher = Number ( transaction . value ) >= 0 ;
582- if ( ! isZeroOrHigher ) {
583- return predefined . INVALID_PARAMETER (
584- 0 ,
585- `Invalid 'value' field in transaction param. Value must be greater than or equal to 0` ,
586- ) ;
587- }
588- // when account exists return default base gas
589- if ( await this . common . getAccount ( transaction . to ! , requestDetails ) ) {
590- this . logger . warn ( `Returning predefined gas for simple transfer: ${ gasTxBaseCost } ` ) ;
591- return gasTxBaseCost ;
592- }
593- const minGasTxHollowAccountCreation = numberTo0x ( constants . MIN_TX_HOLLOW_ACCOUNT_CREATION_GAS ) ;
594- // otherwise, return the minimum amount of gas for hollow account creation
595- this . logger . warn ( `Returning predefined gas for hollow account creation: ${ minGasTxHollowAccountCreation } ` ) ;
596- return minGasTxHollowAccountCreation ;
597- } else if ( isContractCreate ) {
598- // The size limit of the encoded contract posted to the mirror node can
599- // cause contract deployment transactions to fail with a 400 response code.
600- // The contract is actually deployed on the consensus node, so the contract will work.
601- // In these cases, we don't want to return a CONTRACT_REVERT error.
602- if (
603- ConfigService . get ( 'ESTIMATE_GAS_THROWS' ) &&
604- error ?. isContractReverted ( ) &&
605- error ?. message !== MirrorNodeClientError . messages . INVALID_HEX
606- ) {
607- return predefined . CONTRACT_REVERT ( error . detail , error . data ) ;
608- }
609- this . logger . warn ( `Returning predefined gas for contract creation: ${ gasTxBaseCost } ` ) ;
610- return numberTo0x ( Precheck . transactionIntrinsicGasCost ( transaction . data ! ) ) ;
611- } else if ( isContractCall ) {
612- this . logger . warn ( `Returning predefined gas for contract call: ${ contractCallAverageGas } ` ) ;
613- return contractCallAverageGas ;
614- } else {
615- this . logger . warn ( `Returning predefined gas for unknown transaction: ${ this . defaultGas } ` ) ;
616- return this . defaultGas ;
617- }
618- }
619-
620559 /**
621560 * Prepares the call data for mirror node request.
622561 *
0 commit comments