@@ -11,6 +11,7 @@ import { numberTo0x } from '../../../src/formatters';
1111import { SDKClient } from '../../../src/lib/clients' ;
1212import constants from '../../../src/lib/constants' ;
1313import { predefined } from '../../../src/lib/errors/JsonRpcError' ;
14+ import { MirrorNodeClientError } from '../../../src/lib/errors/MirrorNodeClientError' ;
1415import { EthImpl } from '../../../src/lib/eth' ;
1516import { IContractCallRequest , IContractCallResponse , RequestDetails } from '../../../src/lib/types' ;
1617import { overrideEnvsInMochaDescribe } from '../../helpers' ;
@@ -29,6 +30,7 @@ let sdkClientStub: SinonStubbedInstance<SDKClient>;
2930let getSdkClientStub : SinonStub < [ ] , SDKClient > ;
3031let ethImplOverridden : Eth ;
3132const gasTxBaseCost = numberTo0x ( constants . TX_BASE_COST ) ;
33+
3234describe ( '@ethEstimateGas Estimate Gas spec' , async function ( ) {
3335 this . timeout ( 10000 ) ;
3436 const { restMock, web3Mock, hapiServiceInstance, ethImpl, cacheService, mirrorNodeInstance, logger } =
@@ -92,28 +94,28 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
9294
9395 describe ( 'eth_estimateGas with contract call' , async function ( ) { } ) ;
9496
95- it ( 'should eth_estimateGas with transaction.data null throws COULD_NOT_ESTIMATE_GAS_PRICE error' , async function ( ) {
97+ it ( 'should eth_estimateGas with transaction.data null throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 ' , async function ( ) {
9698 const callData : IContractCallRequest = {
9799 from : '0x05fba803be258049a27b820088bab1cad2058871' ,
98100 value : '0x0' ,
99101 gasPrice : '0x0' ,
100102 data : null ,
101103 } ;
102- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
104+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
103105
104106 await expect ( ethImpl . estimateGas ( callData , null , requestDetails ) ) . to . be . rejectedWith (
105107 JsonRpcError ,
106108 gasPriceErrorMessage ,
107109 ) ;
108110 } ) ;
109111
110- it ( 'should eth_estimateGas to mirror node for contract call returns 501 throws COULD_NOT_ESTIMATE_GAS_PRICE error' , async function ( ) {
112+ it ( 'should eth_estimateGas to mirror node for contract call returns 400 throws COULD_NOT_ESTIMATE_GAS_PRICE error' , async function ( ) {
111113 const callData : IContractCallRequest = {
112114 data : '0x608060405234801561001057600080fd5b506040516107893803806107898339818101604052810190610032919061015a565b806000908051906020019061004892919061004f565b50506102f6565b82805461005b90610224565b90600052602060002090601f01602090048101928261007d57600085556100c4565b82601f1061009657805160ff19168380011785556100c4565b828001600101855582156100c4579182015b828111156100c35782518255916020019190600101906100a8565b5b5090506100d191906100d5565b5090565b5b808211156100ee5760008160009055506001016100d6565b5090565b6000610105610100846101c0565b61019b565b90508281526020810184848401111561011d57600080fd5b6101288482856101f1565b509392505050565b600082601f83011261014157600080fd5b81516101518482602086016100f2565b91505092915050565b60006020828403121561016c57600080fd5b600082015167ffffffffffffffff81111561018657600080fd5b61019284828501610130565b91505092915050565b60006101a56101b6565b90506101b18282610256565b919050565b6000604051905090565b600067ffffffffffffffff8211156101db576101da6102b6565b5b6101e4826102e5565b9050602081019050919050565b60005b8381101561020f5780820151818401526020810190506101f4565b8381111561021e576000848401525b50505050565b6000600282049050600182168061023c57607f821691505b602082108114156102505761024f610287565b5b50919050565b61025f826102e5565b810181811067ffffffffffffffff8211171561027e5761027d6102b6565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b610484806103056000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610057575b600080fd5b6100556004803603810190610050919061022c565b610075565b005b61005f61008f565b60405161006c91906102a6565b60405180910390f35b806000908051906020019061008b929190610121565b5050565b60606000805461009e9061037c565b80601f01602080910402602001604051908101604052809291908181526020018280546100ca9061037c565b80156101175780601f106100ec57610100808354040283529160200191610117565b820191906000526020600020905b8154815290600101906020018083116100fa57829003601f168201915b5050505050905090565b82805461012d9061037c565b90600052602060002090601f01602090048101928261014f5760008555610196565b82601f1061016857805160ff1916838001178555610196565b82800160010185558215610196579182015b8281111561019557825182559160200191906001019061017a565b5b5090506101a391906101a7565b5090565b5b808211156101c05760008160009055506001016101a8565b5090565b60006101d76101d2846102ed565b6102c8565b9050828152602081018484840111156101ef57600080fd5b6101fa84828561033a565b509392505050565b600082601f83011261021357600080fd5b81356102238482602086016101c4565b91505092915050565b60006020828403121561023e57600080fd5b600082013567ffffffffffffffff81111561025857600080fd5b61026484828501610202565b91505092915050565b60006102788261031e565b6102828185610329565b9350610292818560208601610349565b61029b8161043d565b840191505092915050565b600060208201905081810360008301526102c0818461026d565b905092915050565b60006102d26102e3565b90506102de82826103ae565b919050565b6000604051905090565b600067ffffffffffffffff8211156103085761030761040e565b5b6103118261043d565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b8381101561036757808201518184015260208101905061034c565b83811115610376576000848401525b50505050565b6000600282049050600182168061039457607f821691505b602082108114156103a8576103a76103df565b5b50919050565b6103b78261043d565b810181811067ffffffffffffffff821117156103d6576103d561040e565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fea264697066735822122070d157c4efbb3fba4a1bde43cbba5b92b69f2fc455a650c0dfb61e9ed3d4bd6364736f6c634300080400330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b696e697469616c5f6d7367000000000000000000000000000000000000000000' ,
113115 from : '0x81cb089c285e5ee3a7353704fb114955037443af' ,
114116 to : RECEIVER_ADDRESS ,
115117 } ;
116- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
118+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
117119
118120 await expect ( ethImpl . estimateGas ( callData , null , requestDetails ) ) . to . be . rejectedWith (
119121 JsonRpcError ,
@@ -144,26 +146,26 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
144146 expect ( ( gas as string ) . toLowerCase ( ) ) . to . equal ( numberTo0x ( constants . TX_DEFAULT_GAS_DEFAULT ) . toLowerCase ( ) ) ;
145147 } ) ;
146148
147- it ( 'should eth_estimateGas for contract deploy throws COULD_NOT_ESTIMATE_GAS_PRICE error on 501 ' , async function ( ) {
149+ it ( 'should eth_estimateGas for contract deploy throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 ' , async function ( ) {
148150 const callData : IContractCallRequest = {
149151 data : '0x01' ,
150152 } ;
151- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
153+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
152154
153155 await expect ( ethImpl . estimateGas ( { data : '0x01' } , null , requestDetails ) ) . to . be . rejectedWith (
154156 JsonRpcError ,
155157 gasPriceErrorMessage ,
156158 ) ;
157159 } ) ;
158160
159- it ( 'should eth_estimateGas to mirror node for transfer throws COULD_NOT_ESTIMATE_GAS_PRICE error on 501 ' , async function ( ) {
161+ it ( 'should eth_estimateGas to mirror node for transfer throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 ' , async function ( ) {
160162 const callData : IContractCallRequest = {
161- data : '0x' ,
162163 from : '0x81cb089c285e5ee3a7353704fb114955037443af' ,
163164 to : RECEIVER_ADDRESS ,
164165 value : '0x2540BE400' ,
166+ // data: '0x',
165167 } ;
166- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
168+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
167169 restMock
168170 . onGet ( `accounts/${ RECEIVER_ADDRESS } ${ NO_TRANSACTIONS } ` )
169171 . reply ( 200 , JSON . stringify ( { address : RECEIVER_ADDRESS } ) ) ;
@@ -174,13 +176,13 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
174176 ) ;
175177 } ) ;
176178
177- it ( 'should eth_estimateGas to mirror node for transfer without value throws COULD_NOT_ESTIMATE_GAS_PRICE error on 501 ' , async function ( ) {
179+ it ( 'should eth_estimateGas to mirror node for transfer without value throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 ' , async function ( ) {
178180 const callData : IContractCallRequest = {
179- data : '0x' ,
180181 from : '0x81cb089c285e5ee3a7353704fb114955037443af' ,
181182 to : RECEIVER_ADDRESS ,
183+ // data: '0x',
182184 } ;
183- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
185+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
184186 restMock . onGet ( `accounts/${ RECEIVER_ADDRESS } ${ NO_TRANSACTIONS } ` ) . reply ( 200 , { address : RECEIVER_ADDRESS } ) ;
185187
186188 await expect ( ethImpl . estimateGas ( callData , null , requestDetails ) ) . to . be . rejectedWith (
@@ -304,12 +306,12 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
304306 expect ( ( gas as string ) . toLowerCase ( ) ) . to . equal ( numberTo0x ( gasEstimation ) . toLowerCase ( ) ) ;
305307 } ) ;
306308
307- it ( 'should eth_estimateGas transfer with invalid value throws COULD_NOT_ESTIMATE_GAS_PRICE error' , async function ( ) {
309+ it ( 'should eth_estimateGas transfer with invalid value throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 ' , async function ( ) {
308310 const callData : IContractCallRequest = {
309311 to : RECEIVER_ADDRESS ,
310312 value : - 100_000_000_000 , //in tinybars
311313 } ;
312- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
314+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
313315 restMock
314316 . onGet ( `accounts/${ RECEIVER_ADDRESS } ${ NO_TRANSACTIONS } ` )
315317 . reply ( 200 , JSON . stringify ( { address : RECEIVER_ADDRESS } ) ) ;
@@ -326,9 +328,9 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
326328 ) . to . be . rejectedWith ( JsonRpcError , gasPriceErrorMessage ) ;
327329 } ) ;
328330
329- it ( 'should eth_estimateGas empty call throws COULD_NOT_ESTIMATE_GAS_PRICE error on 501 ' , async function ( ) {
331+ it ( 'should eth_estimateGas empty call throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 ' , async function ( ) {
330332 const callData : IContractCallRequest = { } ;
331- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
333+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
332334
333335 await expect ( ethImpl . estimateGas ( { } , null , requestDetails ) ) . to . be . rejectedWith ( JsonRpcError , gasPriceErrorMessage ) ;
334336 } ) ;
@@ -341,26 +343,26 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
341343 expect ( gas ) . to . equal ( numberTo0x ( defaultGasOverride ) ) ;
342344 } ) ;
343345
344- it ( 'should eth_estimateGas empty input throws COULD_NOT_ESTIMATE_GAS_PRICE error on 501 ' , async function ( ) {
346+ it ( 'should eth_estimateGas empty input throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 ' , async function ( ) {
345347 const callData : IContractCallRequest = {
346348 data : '' ,
347349 estimate : true ,
348350 } ;
349- const contractsCallResponse : IContractCallResponse = { errorMessage : '' , statusCode : 501 } ;
351+ const contractsCallResponse : IContractCallResponse = { errorMessage : '' , statusCode : 400 } ;
350352
351- await mockContractCall ( callData , true , 501 , contractsCallResponse , requestDetails ) ;
353+ await mockContractCall ( callData , true , 400 , contractsCallResponse , requestDetails ) ;
352354
353355 await expect ( ethImpl . estimateGas ( { data : '' } , null , requestDetails ) ) . to . be . rejectedWith (
354356 JsonRpcError ,
355357 gasPriceErrorMessage ,
356358 ) ;
357359 } ) ;
358360
359- it ( 'should eth_estimateGas empty input throws COULD_NOT_ESTIMATE_GAS_PRICE error on 501 with overridden default gas' , async function ( ) {
361+ it ( 'should eth_estimateGas empty input throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 with overridden default gas' , async function ( ) {
360362 const callData : IContractCallRequest = {
361363 data : '' ,
362364 } ;
363- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
365+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
364366
365367 await expect ( ethImplOverridden . estimateGas ( { data : '' } , null , requestDetails ) ) . to . be . rejectedWith (
366368 JsonRpcError ,
@@ -389,13 +391,13 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
389391 expect ( gas ) . to . equal ( gasTxBaseCost ) ;
390392 } ) ;
391393
392- it ( 'should eth_estimateGas zero input throws COULD_NOT_ESTIMATE_GAS_PRICE error on 501 with overridden default gas' , async function ( ) {
394+ it ( 'should eth_estimateGas zero input throws COULD_NOT_ESTIMATE_GAS_PRICE error on 400 with overridden default gas' , async function ( ) {
393395 const callData : IContractCallRequest = {
394- data : '0x ' ,
396+ gas : '0x0 ' ,
395397 } ;
396- await mockContractCall ( callData , true , 501 , { errorMessage : '' , statusCode : 501 } , requestDetails ) ;
398+ await mockContractCall ( callData , true , 400 , { errorMessage : '' , statusCode : 400 } , requestDetails ) ;
397399
398- await expect ( ethImplOverridden . estimateGas ( { data : '0x' } , null , requestDetails ) ) . to . be . rejectedWith (
400+ await expect ( ethImplOverridden . estimateGas ( callData , null , requestDetails ) ) . to . be . rejectedWith (
399401 JsonRpcError ,
400402 gasPriceErrorMessage ,
401403 ) ;
@@ -517,11 +519,16 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
517519 } ) ;
518520 } ) ;
519521
520- it ( 'should eth_estimateGas handles a 501 unimplemented response from the mirror node correctly by throwing COULD_NOT_ESTIMATE_GAS_PRICE error' , async function ( ) {
522+ it ( 'should eth_estimateGas handles a 400 response from the mirror node correctly by throwing COULD_NOT_ESTIMATE_GAS_PRICE error' , async function ( ) {
523+ const callData : IContractCallRequest = {
524+ from : '0x05fba803be258049a27b820088bab1cad2058871' ,
525+ value : '0x1' ,
526+ gasPrice : '0x0' ,
527+ } ;
521528 await mockContractCall (
522- transaction ,
529+ callData ,
523530 true ,
524- 501 ,
531+ 400 ,
525532 {
526533 _status : {
527534 messages : [
@@ -536,9 +543,10 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
536543 requestDetails ,
537544 ) ;
538545
539- await expect (
540- ethImpl . estimateGas ( { ...transaction , data : '0x' , value : '0x1' } , id , requestDetails ) ,
541- ) . to . be . rejectedWith ( JsonRpcError , gasPriceErrorMessage ) ;
546+ await expect ( ethImpl . estimateGas ( callData , null , requestDetails ) ) . to . be . rejectedWith (
547+ JsonRpcError ,
548+ gasPriceErrorMessage ,
549+ ) ;
542550 } ) ;
543551
544552 it ( 'should should perform estimateGas precheck' , async function ( ) {
@@ -606,4 +614,32 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
606614 expect ( transaction . gasPrice ) . to . eq ( 1000000 ) ;
607615 expect ( transaction . gas ) . to . eq ( 14250000 ) ;
608616 } ) ;
617+
618+ describe ( 'eth_estimateGas with mirror node 5xx server errors' , function ( ) {
619+ const serverErrorStatusCodes = [ 500 , 501 , 502 , 503 , 504 ] ;
620+
621+ serverErrorStatusCodes . forEach ( ( statusCode ) => {
622+ it ( `should throw MirrorNodeClientError when mirror node returns ${ statusCode } status code` , async function ( ) {
623+ const callData : IContractCallRequest = {
624+ from : '0x05fba803be258049a27b820088bab1cad2058871' ,
625+ to : RECEIVER_ADDRESS ,
626+ } ;
627+
628+ await mockContractCall (
629+ callData ,
630+ true ,
631+ statusCode ,
632+ { errorMessage : `Server error ${ statusCode } ` , statusCode } ,
633+ requestDetails ,
634+ ) ;
635+
636+ await expect ( ethImpl . estimateGas ( callData , null , requestDetails ) )
637+ . to . be . rejectedWith ( MirrorNodeClientError )
638+ . and . eventually . satisfy ( ( error : MirrorNodeClientError ) => {
639+ expect ( error . statusCode ) . to . equal ( statusCode ) ;
640+ return true ;
641+ } ) ;
642+ } ) ;
643+ } ) ;
644+ } ) ;
609645} ) ;
0 commit comments