Skip to content
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

Gas limit estimation is broken by [email protected] #160

Open
nksazonov opened this issue Mar 12, 2024 · 2 comments
Open

Gas limit estimation is broken by [email protected] #160

nksazonov opened this issue Mar 12, 2024 · 2 comments
Assignees

Comments

@nksazonov
Copy link

Description

We are running Alto in a container locally alongside geth node as an infra for our AA tests. After switching to newer versions of go-ethereum, we have noticed that Alto is failing to estimate the callGasLimit properly.

To Reproduce

Steps to reproduce the behavior:

  1. Start up geth locally
  2. Deploy infra contracts (EntryPoint, SW, SW Factory etc)
  3. Start Alto locally, supplying the EntryPoint and other necessary info
  4. All eth_estimateUserOperationGas calls result in callGasLimit estimated to 9000, which leads to OOG errors in userop execution.

Expected behavior

Alto estimates callGasLimit correctly, so that userop is executed successfuly.

Versions

  • OS: macOS v14.1.2
  • Alto: v1.0.1, with balanceOverride = false
  • Go-ethereum: 1.13.14
  • Geth node: without eth_call overrides support

Reason

We have found that a magic number 9000 is used when estimated callGasLimit is lower than 9000. Given our geth and Alto settings, Alto uses viem to call EntryPoint.simulateHandleOp, which does NOT set gasPrice, feePerGas and priorityFeePerGas to eth_call call.

[email protected] introduced a change to block.basefee logic in the vm in the eth_call, eth_estimateGas etc. contexts: if gasPrice is not specified, then block.basefee returns 0. This is very important for the Alto Bundler, because its gas estimation depends on EntryPoint.simulateHandleOp, which uses block.basefee.

Currently, without specifying gasPrice when calling EntryPoint.simulateHandleOp, it returns paid equal to gasUsed * maxPriorityFeePerGas (without adding block.baseFee), which results in callGasLimit calculated to ~-1500000.

Fix

As specified in the go-ethereum PR, specifying gasPrice in eth_call is sufficient. Indeed, after changing

const errorResult = await entryPointContract.simulate
    .simulateHandleOp(
        [
            userOperation,
            "0x0000000000000000000000000000000000000000",
            "0x"
        ],
        {
            account: this.utilityWallet
        }
    )

in packages/rpc/src/validation/validator.ts to

const errorResult = await entryPointContract.simulate
    .simulateHandleOp(
        [
            userOperation,
            "0x0000000000000000000000000000000000000000",
            "0x"
        ],
        {
            account: this.utilityWallet,
            gasPrice: userOperation.maxFeePerGas,
            feePerGas: userOperation.maxFeePerGas,
            priorityFeePerGas: userOperation.maxPriorityFeePerGas,
        }
    )

Alto's gas limit estimation works as expected.

We hope you can incorporate this fix, as we use Alto heavily in our workflow.

@kristofgazso
Copy link
Contributor

Thanks for this! Would you be able to try with the main branch?

@nksazonov
Copy link
Author

It works!
Strange, I have checked the code in main branch before opening the issue, and as I have not found the explicit fix, I have not run the Bundler.
Could you point out to why it works now, please? :)

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

No branches or pull requests

3 participants