@@ -161,24 +161,26 @@ export class ContractService implements IContractService {
161161 try {
162162 const response = await this . estimateGasFromMirrorNode ( transaction , requestDetails ) ;
163163
164- if ( response ?. result ) {
165- this . logger . info ( `Returning gas: %s` , response . result ) ;
166- return prepend0x ( trimPrecedingZeros ( response . result ) ) ;
167- } else {
168- this . logger . error ( `No gas estimate returned from mirror-node: %s` , JSON . stringify ( response ) ) ;
169- return this . predefinedGasForTransaction ( transaction , requestDetails ) ;
164+ if ( ! response ?. result ) {
165+ if ( this . logger . isLevelEnabled ( 'debug' ) ) {
166+ this . logger . debug ( `No gas estimate returned from mirror-node: ${ JSON . stringify ( response ) } ` ) ;
167+ }
168+ return predefined . INTERNAL_ERROR ( 'Fail to retrieve gas estimate' ) ;
170169 }
170+
171+ return prepend0x ( trimPrecedingZeros ( response . result ) ) ;
171172 } catch ( e : any ) {
172- this . logger . error ( `Error raised while fetching estimateGas from mirror-node: %s` , JSON . stringify ( e ) ) ;
173- // in case of contract revert, we don't want to return a predefined gas but the actual error with the reason
174- if (
175- ConfigService . get ( 'ESTIMATE_GAS_THROWS' ) &&
176- e instanceof MirrorNodeClientError &&
177- e . isContractRevertOpcodeExecuted ( )
178- ) {
179- return predefined . CONTRACT_REVERT ( e . detail ?? e . message , e . data ) ;
173+ if ( e instanceof MirrorNodeClientError ) {
174+ if ( e . isContractRevert ( ) ) {
175+ throw predefined . CONTRACT_REVERT ( e . detail || e . message , e . data ) ;
176+ } else if ( e . statusCode === 400 ) {
177+ throw predefined . COULD_NOT_SIMULATE_TRANSACTION ( e . detail || e . message ) ;
178+ }
180179 }
181- return this . predefinedGasForTransaction ( transaction , requestDetails , e ) ;
180+
181+ // for any other error or Mirror Node upstream server errors (429, 500, 502, 503, 504, etc.),
182+ // preserve the original error and re-throw to the upper layer for further handling logic
183+ throw e ;
182184 }
183185 }
184186
@@ -503,16 +505,14 @@ export class ContractService implements IContractService {
503505 return constants . EMPTY_HEX ;
504506 }
505507
506- if ( e . isContractReverted ( ) ) {
507- this . logger . trace (
508- `mirror node eth_call request encountered contract revert. message: %s, details: %s, data: %s` ,
509- e . message ,
510- e . detail ,
511- e . data ,
512- ) ;
513- return predefined . CONTRACT_REVERT ( e . detail || e . message , e . data ) ;
508+ if ( e . isContractRevert ( ) ) {
509+ throw predefined . CONTRACT_REVERT ( e . detail || e . message , e . data ) ;
510+ } else if ( e . statusCode === 400 ) {
511+ throw predefined . COULD_NOT_SIMULATE_TRANSACTION ( e . detail || e . message ) ;
514512 }
515- // 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
513+
514+ // for any other error or Mirror Node upstream server errors (429, 500, 502, 503, 504, etc.),
515+ // preserve the original error and re-throw to the upper layer for further handling logic
516516 throw e ;
517517 }
518518
@@ -536,68 +536,6 @@ export class ContractService implements IContractService {
536536 return predefined . INTERNAL_ERROR ( e . message . toString ( ) ) ;
537537 }
538538
539- /**
540- * Fallback calculations for the amount of gas to be used for a transaction.
541- * This method is used when the mirror node fails to return a gas estimate.
542- *
543- * @param {IContractCallRequest } transaction The transaction data for the contract call.
544- * @param {RequestDetails } requestDetails The request details for logging and tracking.
545- * @param error (Optional) received error from the mirror-node contract call request.
546- * @returns {Promise<string | JsonRpcError> } the calculated gas cost for the transaction
547- */
548- private async predefinedGasForTransaction (
549- transaction : IContractCallRequest ,
550- requestDetails : RequestDetails ,
551- error ?: any ,
552- ) : Promise < string | JsonRpcError > {
553- const isSimpleTransfer = ! ! transaction ?. to && ( ! transaction . data || transaction . data === '0x' ) ;
554- const isContractCall =
555- ! ! transaction ?. to && transaction ?. data && transaction . data . length >= constants . FUNCTION_SELECTOR_CHAR_LENGTH ;
556- const isContractCreate = ! transaction ?. to && transaction ?. data && transaction . data !== '0x' ;
557- const contractCallAverageGas = numberTo0x ( constants . TX_CONTRACT_CALL_AVERAGE_GAS ) ;
558- const gasTxBaseCost = numberTo0x ( constants . TX_BASE_COST ) ;
559-
560- if ( isSimpleTransfer ) {
561- // Handle Simple Transaction and Hollow Account creation
562- const isZeroOrHigher = Number ( transaction . value ) >= 0 ;
563- if ( ! isZeroOrHigher ) {
564- return predefined . INVALID_PARAMETER (
565- 0 ,
566- `Invalid 'value' field in transaction param. Value must be greater than or equal to 0` ,
567- ) ;
568- }
569- // when account exists return default base gas
570- if ( await this . common . getAccount ( transaction . to ! , requestDetails ) ) {
571- this . logger . warn ( `Returning predefined gas for simple transfer: ${ gasTxBaseCost } ` ) ;
572- return gasTxBaseCost ;
573- }
574- const minGasTxHollowAccountCreation = numberTo0x ( constants . MIN_TX_HOLLOW_ACCOUNT_CREATION_GAS ) ;
575- // otherwise, return the minimum amount of gas for hollow account creation
576- this . logger . warn ( `Returning predefined gas for hollow account creation: ${ minGasTxHollowAccountCreation } ` ) ;
577- return minGasTxHollowAccountCreation ;
578- } else if ( isContractCreate ) {
579- // The size limit of the encoded contract posted to the mirror node can
580- // cause contract deployment transactions to fail with a 400 response code.
581- // The contract is actually deployed on the consensus node, so the contract will work.
582- // In these cases, we don't want to return a CONTRACT_REVERT error.
583- if (
584- ConfigService . get ( 'ESTIMATE_GAS_THROWS' ) &&
585- error ?. isContractReverted ( ) &&
586- error ?. message !== MirrorNodeClientError . messages . INVALID_HEX
587- ) {
588- return predefined . CONTRACT_REVERT ( error . detail , error . data ) ;
589- }
590- this . logger . warn ( `Returning predefined gas for contract creation: %s` , gasTxBaseCost ) ;
591- return numberTo0x ( Precheck . transactionIntrinsicGasCost ( transaction . data ! ) ) ;
592- } else if ( isContractCall ) {
593- this . logger . warn ( `Returning predefined gas for contract call: %s` , contractCallAverageGas ) ;
594- return contractCallAverageGas ;
595- } else {
596- this . logger . warn ( `Returning predefined gas for unknown transaction: %s` , this . defaultGas ) ;
597- return this . defaultGas ;
598- }
599- }
600-
601539 /**
602540 * Prepares the call data for mirror node request.
603541 *
0 commit comments