Skip to content

feat: support query gas limit flag #368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

thomas-nguy
Copy link
Contributor

@thomas-nguy thomas-nguy commented Jul 29, 2025

Description

This PR enforces a max gas cap when calling the endpoint eth_call or eth_estimateGas

Currently, an attacker can bypass the gas cap by querying directly at the cosmos level and specifying a very large gas cap

If done in a malicious way, an attacker could use a high GasCap to execute an infinite loop function, potentially impacting node performance & crashing the node

Step to reproduce

Deploy

// SPDX-License-Identifier: MIT
pragma solidity =0.8.6;

contract InfiniteLoop {
    uint256 public count;

    constructor() {
        count = 0;
    }

    function infiniteLoop() public {
        while (true) {
            count++;
            // This will cause an out-of-gas error if called
            // in a transaction, but will not revert the contract.
            // It will just keep incrementing `count`.
        }
    } 

    function getCount() public view returns (uint256) {
        return count;
    }
}

Call

curl http://localhost:1317/cosmos/evm/vm/v1/eth_call\?args\=eyJmcm9tIjogIjB4QzZGZTVEMzM2MTVhMUM1MmMwODAxOGM0N0U4QmM1MzY0NkEwRTEwMSIsICJ0byI6ICIweDNENjQxYTI3OTE1MzNCNEEwMDAwMzQ1ZUE4ZDUwOWQwMUUxZWMzMDEiLCJkYXRhIjogIjB4MWRiZjM1M2QifQ==\&gas_cap\=18446744073709551615
The base64 decoded value of args is {"from": "0xC6Fe5D33615a1C52c08018c47E8Bc53646A0E101", "to": "0x3D641a2791533B4A0000345eA8d509d01E1ec301","data": "0x1dbf353d"} where from is the address of user1 , to is the address of deployed contract and data is the signature of infiniteLoop() function.
Change the to address to the address of the deployed smart contract during testing if it changes in your setup.

This PR remediates it by setting a global query gas limit

Closes: #372


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • tackled an existing issue or discussed with a team member
  • left instructions on how to review the changes
  • targeted the main branch

Reviewers Checklist

All items are required.
Please add a note if the item is not applicable
and please add your handle next to the items reviewed
if you only reviewed selected items.

I have...

  • added a relevant changelog entry to the Unreleased section in CHANGELOG.md
  • confirmed all author checklist items have been addressed
  • confirmed that this PR does not change production code
  • reviewed content
  • tested instructions (if applicable)
  • confirmed all CI checks have passed

@thomas-nguy thomas-nguy requested review from a team as code owners July 29, 2025 00:44
@@ -482,6 +482,7 @@ func NewExampleApp(
&app.ConsensusParamsKeeper,
&app.Erc20Keeper,
tracer,
cast.ToUint64(appOpts.Get(server.FlagQueryGasLimit)),
Copy link
Contributor

@technicallyty technicallyty Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this flag is meant to control the cosmos SDK query gas limit. im not sure if it makes sense to use it in this way.

imo it makes more sense to set the value like this:

root.go

baseapp.SetQueryGasLimit(cast.ToUint64(appOpts.Get(sdkserver.FlagQueryGasLimit))),

this will make the SDK set a gas limit in context during query executions. then we can update the keeper calls to respect the value set here: https://github.com/cosmos/cosmos-sdk/blob/553f8955c3214c21c2755811aae5a8f3e021f0f8/baseapp/abci.go#L1282-L1286


keep in mind, this would enforce a query gas limit for ALL gRPC queries. if we want a separate gas limit (i.e. no gas limit for SDK queries, but one for EVM), i suggest we create a separate flag.

Copy link
Contributor Author

@thomas-nguy thomas-nguy Aug 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we want a separate gas limit (i.e. no gas limit for SDK queries, but one for EVM), i suggest we create a separate flag.

Do we want to support such use case? The FlagQueryGasLimit is meant to set a max gas limit for all Rest/Grpc queries, intended to prevent DOS attack
My original thought is that the x/evm module rpcs is a subset of those queries (as they all endup calling cosmos level rest/grpc) and need to follow the same limitation. Adding an extra flag may bring an additional layer of complexity, and confuse users.

I can do the change if it is really needed though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main reason i would think to separate them is because im unsure of the relation between eth gas units and SDK gas units. i know eth gas costs are quite calculated and well thought out, whereas the SDK's feels more arbitrarily chosen.

any thoughts here? @aljo242? i know youve mentioned we dont want to have too many ways to configure things these days, so maybe lets just go with a catch-all flag

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to put it under the one flag

@thomas-nguy thomas-nguy force-pushed the thomas/max-gas-query branch from 0c54a5c to 17f1ec1 Compare August 12, 2025 07:54
@thomas-nguy
Copy link
Contributor Author

thomas-nguy commented Aug 12, 2025

@technicallyty I have set the query gas limit in the baseapp by default as well for the other msgs but unfortunately that alone won't fix the issue because it does not apply to the debug_* context.

We may to dig deeper but the cosmos gasmeter mechanism seems to be ignored during the vm execution or at least is handled differently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: eth_call can be called with a very large gas limit and impact node performance
3 participants