hardhat icon indicating copy to clipboard operation
hardhat copied to clipboard

Unhelpful error when making a deployment on Kovan that exceeds the contract size

Open fvictorio opened this issue 4 years ago • 7 comments

If you deploy a contract that exceeds the size limit on kovan, you get an error like this (happens both with ethers and with hardhat-truffle5):

ProviderError: The execution failed due to an exception.

But if you log the jsonRpcResponse in internal/core/providers/http.ts, the response has a little more information:

{ jsonrpc: '2.0',
  id: 5,
  error:
   { code: -32016,
     data: 'Out of gas',
     message: 'The execution failed due to an exception.' } }

Notice that we aren't using the data field.

This doesn't happen with Rinkeby, where a ProviderError: max code size exceeded is shown, but that's because the jsonRpcResponse is:

{ jsonrpc: '2.0',
  id: 5,
  error: { code: -32000, message: 'max code size exceeded' } }

fvictorio avatar Feb 03 '21 14:02 fvictorio

@fvictorio If I may ask a stupid question, what are you doing to log jsonRpcResponse in internal/core/providers/http.ts? I'm trying to debug the same vague error by inserting console.log()s into my node_modules/hardhat/src/internal/core/providers/http.ts and then running my hardhat task from the command line (npx hardhat fund-link --contract 0xbEc059609c0307392ad836d5bA049b1c35B90E53 --network kovan), but am failing to get any output

sloreti avatar May 30 '21 22:05 sloreti

Uhm, I don't remember exactly what I did, but I guess it was just adding a log below this line:

    const jsonRpcResponse = await this._fetchJsonRpcResponse(jsonRpcRequest);

I don't remember if I used JSON.stringify, but from the output I shared it seems like I didn't.

fvictorio avatar May 31 '21 10:05 fvictorio

Don't know if @sloreti managed to log the response error, but I tried adding a log right below that line, like you're mentioning, @fvictorio , and got no response either.

I actually added several logs throughout the entire body of request(), but got nothing:

const jsonRpcResponse = await this._fetchJsonRpcResponse(jsonRpcRequest);
      console.log('jsonRpcResponse: ', jsonRpcResponse);    //----> no behaviour
    if (isErrorResponse(jsonRpcResponse)) {
      console.log('jsonRpcResponse: ', jsonRpcResponse);   //----> no behaviour
      error.message = jsonRpcResponse.error.message;
      error.code = jsonRpcResponse.error.code;
      error.data = jsonRpcResponse.error.data;
      // eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
      console.log('error: ', error);   //----> no behaviour
      throw error;
    }
    

trojanMcAfee avatar Oct 11 '21 10:10 trojanMcAfee

This is the error btw:

const error = new ProviderError("HttpProviderError", -1);
                  ^
ProviderError: The execution failed due to an exception.
    at HttpProvider.request (xxxxxxx/node_modules/hardhat/src/internal/core/providers/http.ts:49:19)
    

trojanMcAfee avatar Oct 11 '21 10:10 trojanMcAfee

I am also having an abstract error 'Uncaught ProviderError: The execution failed due to an exception.' response when trying to call a contract in FUSE network that had a 'Ownable: caller is not the owner' error.

Using seth from https://dapp.tools/ , at least when trying to send a transaction, I can get the transaction hash, and search for it on the network.

Maybe hardhat could follow this direction also, or even include the revert reason, as you can see in this lib.

henry-hz avatar Mar 28 '22 09:03 henry-hz

I hit this problem as well, not on Kovan but on Goerli and Rinkeby as well. And yes it turned out the bytecode size of my contract was larger than 24576 bytes, found it only via truffle run contract-size as below. Wish hardhat can also print the error message more intiitively.

Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.

iwashu0 avatar Sep 10 '22 11:09 iwashu0

Note for ourselves.

The problem is here:

https://github.com/NomicFoundation/hardhat/blob/a4987a46adfd88e85e654cd0b635c768e055c56a/packages/hardhat-core/src/internal/core/providers/http.ts#L76-L92

When you modify the message of an error, the stack property is not re-computed. Since we then use that property for the inspect function of CustomError, the printed error doesn't include the remote message.

The simplest solution is to create the error within the if. This means that (as the comment explains) some stack frames might get lost, but that's way better than swallowing the error message from the node.

fvictorio avatar Sep 20 '22 21:09 fvictorio

Don't know if @sloreti managed to log the response error, but I tried adding a log right below that line, like you're mentioning, @fvictorio , and got no response either.

I actually added several logs throughout the entire body of request(), but got nothing:

const jsonRpcResponse = await this._fetchJsonRpcResponse(jsonRpcRequest);
      console.log('jsonRpcResponse: ', jsonRpcResponse);    //----> no behaviour
    if (isErrorResponse(jsonRpcResponse)) {
      console.log('jsonRpcResponse: ', jsonRpcResponse);   //----> no behaviour
      error.message = jsonRpcResponse.error.message;
      error.code = jsonRpcResponse.error.code;
      error.data = jsonRpcResponse.error.data;
      // eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
      console.log('error: ', error);   //----> no behaviour
      throw error;
    }
    

With regards to where to stick the console.log, you tried in the wrong block section (76->92). I needs to go in the line 47 -> 60 block which starts with async request(args) rather than the sendBatch(batch) block:

Like so:

    async request(args) {
        // We create the error here to capture the stack traces at this point,
        // the async call that follows would probably loose of the stack trace
        const error = new errors_2.ProviderError("HttpProviderError", -1);
        const jsonRpcRequest = this._getJsonRpcRequest(args.method, args.params);
        const jsonRpcResponse = await this._fetchJsonRpcResponse(jsonRpcRequest);
        if (isErrorResponse(jsonRpcResponse)) {
            error.message = jsonRpcResponse.error.message;
            error.code = jsonRpcResponse.error.code;
            error.data = jsonRpcResponse.error.data;
            // eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
            console.log('jsonRpcResponse: ', jsonRpcResponse);    // <----- INSERT HERE
            throw error;
        }

When I place it here, I get the following output to console:

jsonRpcResponse:  {
  jsonrpc: '2.0',
  id: 20,
  error: { code: -32000, message: 'exceeds block gas limit' }
}
ProviderError: HttpProviderError
    at HttpProvider.request . . .

psipherious avatar Oct 07 '22 18:10 psipherious

Closing in favor of https://github.com/NomicFoundation/hardhat/issues/3581

fvictorio avatar Jan 13 '23 23:01 fvictorio