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

fix(evm): consume gas in CallContractWithInput #2180

Merged
merged 10 commits into from
Jan 28, 2025
Merged

Conversation

k-yang
Copy link
Member

@k-yang k-yang commented Jan 27, 2025

Purpose / Abstract

Ensures consistent gas consumption in all areas of the EVM codebase by applying gas consumption at the CallContractWithInput layer.

@k-yang k-yang marked this pull request as ready for review January 27, 2025 16:50
@k-yang k-yang requested a review from a team as a code owner January 27, 2025 16:50
Copy link
Contributor

coderabbitai bot commented Jan 27, 2025

Warning

Rate limit exceeded

@k-yang has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 26 minutes and 54 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 52f3293 and a55e5b2.

📒 Files selected for processing (1)
  • x/evm/keeper/gas_fees.go (1 hunks)
📝 Walkthrough

Walkthrough

This pull request introduces changes to gas consumption across the Nibiru EVM codebase. The modifications primarily focus on consistently applying gas consumption at various points in the EVM execution flow, such as during contract calls, Ethereum transactions, and token operations. The changes ensure that gas is properly tracked and consumed across different methods in the keeper and precompile packages, with updates to error handling and code clarity.

Changes

File Change Summary
CHANGELOG.md Added new entry documenting gas consumption fix across EVM codebase
x/evm/keeper/call_contract.go Added gas consumption after applying Ethereum message and improved error handling
x/evm/keeper/erc20.go Updated variable naming from res to evmResp in contract call methods
x/evm/keeper/funtoken_from_coin.go Removed gas consumption logic in contract deployment method
x/evm/keeper/msg_server.go Added gas consumption after executing Ethereum transaction and updated variable naming
x/evm/precompile/funtoken.go Simplified error handling in sendToBank method
x/evm/keeper/gas_fees.go Updated refund logic with new parameters for gas refund calculations
x/evm/keeper/keeper.go Improved error handling in HandleOutOfGasPanic function
x/evm/keeper/funtoken_from_coin_test.go Enhanced test suite with gas meter management and assertions for gas consumption
x/evm/keeper/funtoken_from_erc20_test.go Updated test cases to track gas consumption during ERC20 interactions
x/evm/keeper/grpc_query.go Removed fullRefundLeftoverGas parameter from method calls for simplification
x/evm/precompile/funtoken_test.go Refactored logging and response handling in test suite for clarity

Sequence Diagram

sequenceDiagram
    participant Client
    participant EVMKeeper
    participant GasMeter
    participant ContractExecution

    Client->>EVMKeeper: Call Contract/Execute Tx
    EVMKeeper->>ContractExecution: Process Transaction
    ContractExecution-->>EVMKeeper: Return Response (evmResp)
    EVMKeeper->>GasMeter: ConsumeGas(evmResp.GasUsed)
    EVMKeeper-->>Client: Return Result
Loading

Possibly related PRs

Suggested labels

x: evm, P: Urgent / High prio

Poem

🐰 Hop, hop, through the EVM's maze,
Gas meters dancing in digital haze,
Consuming bytes with calculated grace,
Each transaction finds its rightful place,
A rabbit's code, precise and bright! 🔥


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@k-yang k-yang marked this pull request as draft January 27, 2025 17:35
@k-yang k-yang marked this pull request as ready for review January 27, 2025 20:54
@@ -39,7 +39,7 @@ func (k Keeper) CallContractWithInput(
) (evmResp *evm.MsgEthereumTxResponse, err error) {
// This is a `defer` pattern to add behavior that runs in the case that the
// error is non-nil, creating a concise way to add extra information.
defer HandleOutOfGasPanic(&err, "CallContractError")
defer HandleOutOfGasPanic(&err, "CallContractError")()
Copy link
Member Author

Choose a reason for hiding this comment

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

missing parentheses was causing issues with catching OOG errors lol

@@ -63,9 +63,11 @@ func (k Keeper) CallContractWithInput(
evmResp, err = k.ApplyEvmMsg(
ctx, evmMsg, evmObj, evm.NewNoOpTracer(), commit, txConfig.TxHash, true,
)
if evmResp != nil {
ctx.GasMeter().ConsumeGas(evmResp.GasUsed, "CallContractWithInput")
Copy link
Member Author

Choose a reason for hiding this comment

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

We should always consume gas after ApplyEvmMsg(), before returning away from CallContractWithInput(), or else we lose the opportunity to apply the EvmResp.GasUsed variable.

@@ -196,7 +196,7 @@ func (e erc20Calls) loadERC20String(
if err != nil {
return out, err
}
res, err := e.Keeper.CallContractWithInput(
evmResp, err := e.Keeper.CallContractWithInput(
Copy link
Member Author

Choose a reason for hiding this comment

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

just a minor rename

@@ -114,7 +114,5 @@ func (k *Keeper) deployERC20ForBankCoin(
return gethcommon.Address{}, errors.Wrap(err, "failed to commit stateDB")
}

ctx.GasMeter().ConsumeGas(evmResp.GasUsed, "deploy erc20 funtoken contract")
Copy link
Member Author

Choose a reason for hiding this comment

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

We no longer need to consume gas here since we consume it at a lower level in CallContractWithInput().

// gas limit) if the `ApplyEvmMsg` call originated from a state transition
// where the chain set the gas limit and not an end-user.
func GasToRefund(availableRefundAmount, gasUsed uint64, fullRefundLeftoverGas bool) uint64 {
refundQuotient := params.RefundQuotientEIP3529
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved all the 1/5 calculations here.

*err = vm.ErrOutOfGas
default:
panic(r)
}
}
if err != nil && format != "" {
if *err != nil && format != "" {
Copy link
Member Author

Choose a reason for hiding this comment

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

Need to check *err != nil, not err != nil because err is a pointer value.

// "vm.Tracer".
leftoverGas = msg.Gas() - gasUsed
// The dirty states in `StateDB` is either committed or discarded after return
if commit {
Copy link
Member Author

Choose a reason for hiding this comment

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

I moved the StateDB.Commit() to after the gas calculations so we have accurate gas accounting prior to commit and return.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
x/evm/keeper/gas_fees.go (2)

78-85: Clarify mismatch between doc comments and boolean parameter

The comments describe refund scenarios for "user" vs. "internal (funtoken)" messages, while the function relies on the fullRefundLeftoverGas boolean. Consider refining the doc comments or the parameter name to better reflect the decision logic (e.g., isInternalMsg), ensuring readers understand how these scenarios map to true or false.


86-90: Consolidate or reorganize verbose documentation

Lines 86–90 extensively outline EIP-3529 refunds, leftover gas, and internal calls. While helpful, consider merging some commentary to avoid redundancy, keeping the doc block concise while still conveying the key reasoning.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1cb2068 and be10743.

📒 Files selected for processing (5)
  • x/evm/keeper/call_contract.go (2 hunks)
  • x/evm/keeper/gas_fees.go (1 hunks)
  • x/evm/keeper/keeper.go (1 hunks)
  • x/evm/keeper/msg_server.go (4 hunks)
  • x/evm/precompile/funtoken.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • x/evm/precompile/funtoken.go
  • x/evm/keeper/call_contract.go
  • x/evm/keeper/msg_server.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-tests
🔇 Additional comments (2)
x/evm/keeper/gas_fees.go (2)

92-94: Confirm constraints on fullRefundLeftoverGas usage

Allowing a refundQuotient = 1 effectively refunds all leftover gas. Validate that no external user code path can accidentally set fullRefundLeftoverGas = true, potentially enabling a full refund scenario that defeats gas constraints.


96-100: Validate integer division and overflow conditions

Using refundAmount := gasUsed / refundQuotient inherently truncates any fractional result. Ensure this behavior is intentional and optimal for your business logic. Also confirm that availableRefundAmount is large enough to avoid overflow or unexpected capping in edge cases.

x/evm/keeper/keeper.go Outdated Show resolved Hide resolved
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

codecov bot commented Jan 28, 2025

Codecov Report

Attention: Patch coverage is 85.07463% with 10 lines in your changes missing coverage. Please review.

Project coverage is 65.00%. Comparing base (bc29b88) to head (a55e5b2).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
x/evm/keeper/msg_server.go 82.05% 4 Missing and 3 partials ⚠️
x/evm/precompile/funtoken.go 25.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2180      +/-   ##
==========================================
+ Coverage   64.86%   65.00%   +0.13%     
==========================================
  Files         277      277              
  Lines       22367    22349      -18     
==========================================
+ Hits        14508    14527      +19     
+ Misses       6869     6832      -37     
  Partials      990      990              
Files with missing lines Coverage Δ
x/evm/keeper/call_contract.go 94.23% <100.00%> (+0.23%) ⬆️
x/evm/keeper/erc20.go 74.02% <100.00%> (+1.94%) ⬆️
x/evm/keeper/funtoken_from_coin.go 81.48% <100.00%> (-0.45%) ⬇️
x/evm/keeper/gas_fees.go 65.38% <100.00%> (ø)
x/evm/keeper/grpc_query.go 82.33% <100.00%> (ø)
x/evm/keeper/keeper.go 85.36% <100.00%> (+21.08%) ⬆️
x/evm/precompile/funtoken.go 53.18% <25.00%> (+0.21%) ⬆️
x/evm/keeper/msg_server.go 77.07% <82.05%> (-0.28%) ⬇️

... and 1 file with indirect coverage changes

@k-yang k-yang marked this pull request as draft January 28, 2025 15:49
@k-yang k-yang marked this pull request as ready for review January 28, 2025 17:37
@k-yang k-yang requested a review from onikonychev January 28, 2025 18:31
@k-yang k-yang merged commit 1ddbc2a into main Jan 28, 2025
15 checks passed
@k-yang k-yang deleted the fix/evm/consume-evm-gas branch January 28, 2025 19:10
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.

2 participants