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: blocked gateway cctx for high-gas deposit #3106

Merged
merged 12 commits into from
Nov 8, 2024
Merged

Conversation

lumtis
Copy link
Member

@lumtis lumtis commented Nov 6, 2024

Description

  • Add a gas limit for omnichain calls with gateway workflow
  • Add TestDepositAndCallOutOfGasName test to check CCTX revert if the omnichain call is out of gas

Check the change:
if the value is set back to nil in https://github.com/zeta-chain/node/pull/3106/files#diff-27b3a64d8d9957b22a3aaec6fe8679ed046033e5de6437afe7b46c7efca3c7b7R19 then the TestDepositAndCallOutOfGasName will fail because inbound doesn't get observed

Summary by CodeRabbit

  • New Features

    • Added whitelisting capability for SPL tokens on Solana.
    • Introduced a function in the TestGasConsumer contract for enhanced gas consumption testing.
  • Bug Fixes

    • Resolved an issue preventing blocked cross-chain transactions during "out of gas" errors.
  • Tests

    • New end-to-end tests for concurrent withdrawal, deposit, and gas exhaustion scenarios.
  • Improvements

    • Enhanced build reproducibility for release commands.
    • Implemented a defined gas limit for Ethereum transaction calls.

@lumtis lumtis added the V2_TESTS Run make start-v2-test label Nov 6, 2024
Copy link
Contributor

coderabbitai bot commented Nov 6, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces several enhancements and fixes across the ZetaChain node, including a new feature for whitelisting SPL tokens on Solana, improvements in build reproducibility, and the addition of concurrent withdrawal and deposit tests for the TON blockchain. A critical fix prevents blocked cross-chain transactions during "out of gas" errors. New smart contract functionalities and corresponding test cases have also been implemented, enhancing the overall robustness and functionality of the platform.

Changes

File Path Change Summary
changelog.md Updated to include new features, tests, fixes, and refactoring; added whitelisting for SPL tokens; improved build reproducibility; added tests for TON; fixed CCTX issues.
cmd/zetae2e/local/v2.go Added new test case e2etests.TestDepositAndCallOutOfGasName for gas token workflow revert cases.
e2e/contracts/testgasconsumer/TestGasConsumer.abi Added function onCall with parameters for context and token management.
e2e/contracts/testgasconsumer/TestGasConsumer.go Introduced Go bindings for TestGasConsumer contract, including various structs and methods for interaction.
e2e/contracts/testgasconsumer/TestGasConsumer.json Added ABI for onCall function with structured input parameters.
e2e/contracts/testgasconsumer/TestGasConsumer.sol Added Solidity contract TestGasConsumer with functionality for simulating high gas consumption.
e2e/contracts/testgasconsumer/bindings.go Introduced Go generate directives for compiling the Solidity contract and generating ABI and binary files.
e2e/e2etests/e2etests.go Added end-to-end test case TestDepositAndCallOutOfGasName for gas exhaustion scenarios.
e2e/e2etests/test_deposit_and_call_out_of_gas.go Implemented TestDepositAndCallOutOfGas to validate deposit and call operations under gas limits.
x/fungible/keeper/v2_evm.go Introduced gatewayGasLimit variable for defined gas limits in Ethereum transaction calls.

Possibly related PRs

Suggested labels

nosec, E2E, PERFORMANCE_TESTS

Suggested reviewers

  • fbac
  • kingpinXD
  • ws4charlie
  • brewmaster012
  • swift1337
  • skosito

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 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.

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.

Copy link

codecov bot commented Nov 6, 2024

Codecov Report

Attention: Patch coverage is 40.00000% with 3 lines in your changes missing coverage. Please review.

Project coverage is 63.29%. Comparing base (0e86494) to head (eb9c292).
Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
x/fungible/keeper/v2_evm.go 40.00% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #3106   +/-   ##
========================================
  Coverage    63.29%   63.29%           
========================================
  Files          422      422           
  Lines        29959    29959           
========================================
  Hits         18962    18962           
  Misses       10157    10157           
  Partials       840      840           
Files with missing lines Coverage Δ
x/fungible/keeper/v2_evm.go 24.46% <40.00%> (ø)

@lumtis
Copy link
Member Author

lumtis commented Nov 6, 2024

Removing #3084 as attached PR as it will not fully address the problem

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: 3

🧹 Outside diff range and nitpick comments (9)
e2e/contracts/testgasconsumer/TestGasConsumer.abi (1)

1-47: Consider adding events for better test observability.

While the current ABI is functional, adding events to track function execution would enhance debugging capabilities during gas consumption tests. This would make it easier to verify the exact point of gas exhaustion.

Consider adding an event like:

event GasConsumed(
    bytes origin,
    address sender,
    uint256 chainID,
    address zrc20,
    uint256 amount,
    uint256 gasUsed
);
e2e/contracts/testgasconsumer/TestGasConsumer.sol (1)

9-13: Consider adding context validation.

While the zContext struct is well-defined, the contract should validate the context parameters in the onCall function to ensure they meet expected criteria (non-zero address for sender, valid chainID range).

 function onCall(
     zContext calldata _context,
     address _zrc20,
     uint256 _amount,
     bytes calldata _message
 ) external {
+    require(_context.sender != address(0), "Invalid sender address");
+    require(_context.chainID > 0, "Invalid chain ID");
+    require(_context.origin.length > 0, "Invalid origin");
     consumeGas();
 }
e2e/e2etests/test_deposit_and_call_out_of_gas.go (4)

3-13: Consider grouping imports for better organization.

The imports could be organized into three distinct groups:

  1. Standard library imports
  2. External dependencies
  3. Internal packages
 import (
+	// Standard library
 	"math/big"
 
+	// External dependencies
 	"github.com/stretchr/testify/require"
 	"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol"
 
+	// Internal packages
 	"github.com/zeta-chain/node/e2e/contracts/testgasconsumer"
 	"github.com/zeta-chain/node/e2e/runner"
 	"github.com/zeta-chain/node/e2e/utils"
 	crosschaintypes "github.com/zeta-chain/node/x/crosschain/types"
 )

15-15: Enhance function documentation for better clarity.

Consider adding more detailed documentation following Go's documentation conventions:

-// TestDepositAndCallOutOfGas tests that a deposit and call that consumer all gas will revert
+// TestDepositAndCallOutOfGas verifies that a deposit and call operation reverts when gas is exhausted.
+// It deploys a gas consumer contract and attempts to perform a deposit with a zero gas limit.
+// The test expects the cross-chain transaction to be marked as reverted.
+//
+// Args:
+//   - r: E2E test runner instance
+//   - args: Test arguments where args[0] is the deposit amount in base units

17-20: Improve argument validation and error messaging.

The argument validation could be more explicit and user-friendly:

-	require.Len(r, args, 1)
+	require.Len(r, args, 1, "TestDepositAndCallOutOfGas requires exactly 1 argument: deposit amount")
 
 	amount, ok := big.NewInt(0).SetString(args[0], 10)
-	require.True(r, ok, "Invalid amount specified for TestV2ETHDepositAndCall")
+	require.True(r, ok, "Invalid deposit amount: %s. Must be a valid decimal number", args[0])

16-38: Consider adding test cleanup.

The test should clean up resources after completion:

Consider adding a cleanup function or using t.Cleanup() to ensure the deployed contract and any other resources are properly cleaned up after the test completes, especially if this test is part of a larger test suite.

Example cleanup pattern:

defer func() {
    // Add cleanup logic here
    // For example, you might want to:
    // 1. Log final contract state
    // 2. Verify no lingering transactions
    // 3. Clean up any test data
}()
e2e/contracts/testgasconsumer/TestGasConsumer.json (1)

6-26: Consider adding validation for the zContext structure.

The context structure contains critical cross-chain information. Ensure that:

  1. The origin bytes field has a maximum length constraint
  2. The chainID is validated against supported chains

Consider implementing these validations in the contract constructor or a separate validation function to maintain gas efficiency.

x/fungible/keeper/v2_evm.go (1)

18-20: Consider making the gas limit configurable

While 1M gas is a reasonable baseline, hardcoding this value as a package-level variable might limit flexibility. Consider:

  1. Making it configurable through chain parameters
  2. Adding documentation about the gas limit choice
-// gatewayGasLimit is the gas limit for the gateway functions
-var gatewayGasLimit = big.NewInt(1_000_000)
+// DefaultGatewayGasLimit is the default gas limit for gateway functions
+var DefaultGatewayGasLimit = big.NewInt(1_000_000)
+
+// GetGatewayGasLimit returns the current gas limit for gateway functions
+func (k Keeper) GetGatewayGasLimit(ctx sdk.Context) *big.Int {
+    // TODO: Implement chain parameter lookup with fallback to default
+    return DefaultGatewayGasLimit
+}
e2e/e2etests/e2etests.go (1)

900-907: Consider enhancing test description and adding gas limit parameter.

The test case implementation looks good, but consider these improvements:

  1. The description could be more specific about the expected behavior when gas is exhausted
  2. Consider adding a gas limit parameter to explicitly control the gas threshold for testing different scenarios

Apply this diff to enhance the test definition:

 runner.NewE2ETest(
   TestDepositAndCallOutOfGasName,
-  "deposit Ether into ZEVM and call a contract that runs out of gas",
+  "deposit Ether into ZEVM and verify CCTX reversion when contract call exhausts gas",
   []runner.ArgDefinition{
     {Description: "amount in wei", DefaultValue: "10000000000000000"},
+    {Description: "gas limit", DefaultValue: "100000"},
   },
   TestDepositAndCallOutOfGas,
 ),
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9cf3635 and 973261f.

⛔ Files ignored due to path filters (1)
  • e2e/contracts/testgasconsumer/TestGasConsumer.bin is excluded by !**/*.bin
📒 Files selected for processing (10)
  • changelog.md (1 hunks)
  • cmd/zetae2e/local/v2.go (1 hunks)
  • e2e/contracts/testgasconsumer/TestGasConsumer.abi (1 hunks)
  • e2e/contracts/testgasconsumer/TestGasConsumer.go (1 hunks)
  • e2e/contracts/testgasconsumer/TestGasConsumer.json (1 hunks)
  • e2e/contracts/testgasconsumer/TestGasConsumer.sol (1 hunks)
  • e2e/contracts/testgasconsumer/bindings.go (1 hunks)
  • e2e/e2etests/e2etests.go (2 hunks)
  • e2e/e2etests/test_deposit_and_call_out_of_gas.go (1 hunks)
  • x/fungible/keeper/v2_evm.go (6 hunks)
✅ Files skipped from review due to trivial changes (2)
  • e2e/contracts/testgasconsumer/TestGasConsumer.go
  • e2e/contracts/testgasconsumer/bindings.go
🧰 Additional context used
📓 Path-based instructions (4)
cmd/zetae2e/local/v2.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

e2e/e2etests/e2etests.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

e2e/e2etests/test_deposit_and_call_out_of_gas.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/fungible/keeper/v2_evm.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

🪛 GitHub Check: codecov/patch
x/fungible/keeper/v2_evm.go

[warning] 139-139: x/fungible/keeper/v2_evm.go#L139
Added line #L139 was not covered by tests


[warning] 185-185: x/fungible/keeper/v2_evm.go#L185
Added line #L185 was not covered by tests


[warning] 237-237: x/fungible/keeper/v2_evm.go#L237
Added line #L237 was not covered by tests

🔇 Additional comments (13)
e2e/contracts/testgasconsumer/TestGasConsumer.abi (1)

1-47: ABI structure is well-designed for gas consumption testing.

The ABI definition is clean and well-structured, with appropriate parameter types for cross-chain token transfers. The context struct provides essential chain data, and the nonpayable modifier is correctly applied.

e2e/contracts/testgasconsumer/TestGasConsumer.sol (2)

1-8: LGTM! Good choice of Solidity version.

The contract uses Solidity 0.8.26 which includes important security features like overflow checks and improved error handling. The storage variable is correctly scoped as private.


27-41: ⚠️ Potential issue

Critical: Improve gas consumption reliability and safety.

Several concerns with the current implementation:

  1. Magic numbers should be declared as constants
  2. Gas estimates may vary across EVM implementations
  3. No emergency stop mechanism
  4. Potential for DOS if gas estimates are incorrect

Consider this safer implementation:

 contract TestGasConsumer {
+    uint256 private constant TARGET_GAS = 5000000;
+    uint256 private constant STORAGE_WRITE_GAS = 20000;
+    bool private stopped;
+
+    modifier notStopped() {
+        require(!stopped, "Contract is stopped");
+        _;
+    }
+
+    function emergencyStop() external {
+        stopped = true;
+    }
+
     function consumeGas() internal {
-        uint256 targetGas = 5000000;
-        uint256 storageWriteGasCost = 20000;
-        uint256 iterations = targetGas / storageWriteGasCost;
+        uint256 iterations = TARGET_GAS / STORAGE_WRITE_GAS;
+        require(iterations > 0, "Invalid gas calculation");
+        require(iterations < 1000, "Too many iterations");

         for (uint256 i = 0; i < iterations; i++) {
+            require(gasleft() > STORAGE_WRITE_GAS, "Insufficient gas");
             storageArray.push(i);
         }

         delete storageArray;
     }
 }

Let's verify the gas consumption estimates:

e2e/contracts/testgasconsumer/TestGasConsumer.json (3)

43-46: Review nonpayable modifier usage.

The nonpayable modifier is appropriate here as this function handles token transfers through _zrc20 parameter rather than native currency. This prevents accidental value transfers through the function call.


49-49: Verify the deployed bytecode matches the source.

The binary appears to be valid EVM bytecode. Ensure it matches the source code compilation with optimization settings appropriate for a gas-intensive contract.

#!/bin/bash
# Look for contract deployment tests
rg -A 5 "TestGasConsumer.*Deploy" "test/"

# Search for optimization settings in hardhat config
rg "solidity.*optimizer" -A 5

3-47: Verify gas consumption patterns in the onCall function implementation.

The ABI definition suggests this contract is designed to consume gas during cross-chain operations. Given the PR's objective to implement gas limits for omnichain calls, ensure that:

  1. The contract's gas consumption is predictable and bounded
  2. The function reverts cleanly when gas limits are exceeded
✅ Verification successful

Gas consumption implementation is well-designed and predictable

The contract implementation shows a deliberate and controlled gas consumption pattern:

  • Uses a fixed target gas consumption of 5M gas
  • Calculates iterations based on known storage operation costs (20K gas)
  • Includes cleanup to prevent state bloat
  • Has corresponding e2e test for out-of-gas scenarios

The ABI definition correctly reflects this implementation with appropriate parameter types and nonpayable modifier. The gas consumption is predictable and bounded, making it suitable for testing gas limit implementations in omnichain calls.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for gas-related operations in the contract implementation
ast-grep --pattern 'function onCall($$$) {
  $$$
  gasleft()
  $$$
}'

# Look for gas consumption tests
rg -l "TestDepositAndCallOutOfGasName" "test/"

Length of output: 289


Script:

#!/bin/bash
# Look for the actual contract implementation
fd -e sol TestGasConsumer

# Search for gas-related test files
fd -e sol -e js -e ts test.*gas

# Look for the contract source to analyze gas consumption
rg -A 10 "contract TestGasConsumer" 

Length of output: 999


Script:

#!/bin/bash
# Get the full implementation of TestGasConsumer contract
cat e2e/contracts/testgasconsumer/TestGasConsumer.sol

# Look for test files that might be using this contract
rg -l "TestGasConsumer" e2e/

Length of output: 1474

cmd/zetae2e/local/v2.go (3)

58-58: LGTM: Test case addition aligns with PR objectives.

The addition of TestDepositAndCallOutOfGasName to the eth-revert test group is appropriate for validating gas limit behavior in omnichain calls.


Line range hint 89-91: Verify if the TODO is still relevant.

The TODO comment references issue #2554 regarding breaking down this routine. Given the new gas-related test cases being added, it might be worth reassessing if this refactoring should be prioritized to improve test organization.

✅ Verification successful

Based on the GitHub issue response, I can generate the final response since the issue #2554 is marked as "CLOSED" and its content clearly shows it was about implementing V2 contract E2E tests with specific test cases for gas and ERC20 operations.

The TODO comment can be removed as the referenced issue #2554 is now closed

The issue has been addressed with the implementation of V2 contract E2E tests, including comprehensive test cases for gas operations, ERC20 transactions, and cross-VM calls. The original refactoring task has been completed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the referenced issue is still open and relevant
gh issue view 2554 --json state,title,body

Length of output: 1170


56-59: Verify test dependencies for the new gas test.

The new test is added after other revert-related tests. Let's verify if there are any specific dependencies or required test ordering.

✅ Verification successful

Let me gather more information about the test implementation to understand its dependencies better.


Test ordering is appropriate with no specific dependencies

The test is correctly placed as it belongs to the revert-related test group. After reviewing the implementation:

  • It's a standalone test that deploys its own contract (TestGasConsumer)
  • Uses common test utilities and runner methods
  • Doesn't depend on state from other tests
  • Appropriately tests the revert scenario with gas exhaustion
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any dependencies or setup requirements in the test implementation
rg -A 5 "TestDepositAndCallOutOfGas" 

Length of output: 2227


Script:

#!/bin/bash
# Check the implementation details of the test
cat e2e/e2etests/test_deposit_and_call_out_of_gas.go

Length of output: 1361

x/fungible/keeper/v2_evm.go (2)

Line range hint 18-237: Verify gas limit behavior across different networks

The implementation of a fixed gas limit needs verification across different network conditions and transaction types.

Consider:

  1. Monitoring and adjusting the gas limit based on network conditions
  2. Implementing circuit breakers for high gas situations
  3. Adding metrics collection for gas usage patterns

Would you like assistance in implementing any of these suggestions?


39-39: Add test coverage for gateway gas limit changes

The gas limit implementation lacks test coverage for several gateway contract calls. Consider adding test cases that verify:

  1. Gas limit is properly enforced
  2. Contract calls fail gracefully when gas limit is exceeded
  3. Different gas consumption scenarios

Also applies to: 89-89, 139-139, 185-185, 237-237

e2e/e2etests/e2etests.go (1)

152-152: LGTM: Test name follows naming convention.

The constant name TestDepositAndCallOutOfGasName follows the established pattern and clearly indicates its purpose.

changelog.md (1)

13-15: LGTM! The changelog entry is well-structured and informative.

The entry properly documents the fix for blocked CCTX during omnichain calls with out-of-gas conditions, aligning with the PR objectives.

e2e/e2etests/test_deposit_and_call_out_of_gas.go Outdated Show resolved Hide resolved
Co-authored-by: Dmitry S <11892559+swift1337@users.noreply.github.com>
@lumtis lumtis added this pull request to the merge queue Nov 8, 2024
Merged via the queue into develop with commit b5985bc Nov 8, 2024
40 of 41 checks passed
@lumtis lumtis deleted the gas-limit-gateway branch November 8, 2024 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking:cli V2_TESTS Run make start-v2-test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make TestDappV2 consume more gas
3 participants