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

refactor(bridgecall): token conversion logic #717

Merged
merged 2 commits into from
Oct 8, 2024

Conversation

zakir-code
Copy link
Contributor

@zakir-code zakir-code commented Oct 8, 2024

Summary by CodeRabbit

  • New Features

    • Enhanced token pair management with the ability to deploy upgradable tokens.
    • Introduced methods for handling bridge calls and refunds more effectively.
    • Added functionality to convert tokens to ERC20 addresses.
  • Bug Fixes

    • Improved error handling for token deployments and bridge call processes.
  • Tests

    • Refactored test suite for the BridgeCallHandler to improve clarity and organization.
    • Introduced new initialization methods for better test data setup.

Copy link

coderabbitai bot commented Oct 8, 2024

Walkthrough

The pull request introduces significant modifications across several files in the codebase, primarily focusing on enhancing the handling of token pairs and bridge calls. Key changes include updates to method signatures, the introduction of new methods for better error handling, and restructuring of test cases for improved clarity. The AddTokenPair method in the helpers package now returns a token address, while the BridgeCallHandler and related methods in the keeper package have been refined for better functionality and error management. Additionally, the test suite has been restructured to support these changes.

Changes

File Change Summary
testutil/helpers/suite.go - Added imports for strings and authtypes packages.
- Updated AddTokenPair to return common.Address and modified its logic for deploying upgradable tokens.
x/crosschain/keeper/bridge_call_in.go - Added import for context.
- Updated BridgeCallHandler to check for module accounts.
- Replaced BridgeCallTransferAndCallEvm with BridgeCallEvm with new parameters.
- Introduced BridgeTokenToERC20 and BridgeCallFailedRefund methods.
x/crosschain/keeper/bridge_call_in_test.go - Refactored tests for BridgeCallHandler with new naming conventions and structured test cases.
- Added BridgeCallClaimInitialize for setting up bridge call claims.

Possibly related PRs

🐇 In the meadow, where tokens play,
A new method shines bright today.
With bridges built and calls refined,
Upgradable tokens, well-defined.
So hop along, let’s test and cheer,
For clearer paths and less to fear! 🌼


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.

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.

Copy link

@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: 6

🧹 Outside diff range and nitpick comments (4)
x/crosschain/keeper/bridge_call_in_test.go (3)

25-52: Explicitly set CallContract in test cases for clarity

In the test cases, the CallContract field is not set, so it defaults to false. To improve clarity and avoid potential confusion in the future, consider explicitly setting CallContract in each test case.


19-19: Ensure consistent receiver names and types across test functions

The test functions use different receiver names and types:

  • (suite *KeeperTestSuite) in TestBridgeCallHandler and BridgeCallClaimInitialize
  • (s *KeeperMockSuite) in Test_CoinsToBridgeCallTokens and MockBridgeCallToken

For consistency and better readability, consider using the same receiver name and struct type across all test functions, unless there is a specific reason for the difference.

Also applies to: 95-129


74-94: Consider renaming BridgeCallClaimInitialize to InitializeBridgeCallClaim for better readability

Renaming the function to InitializeBridgeCallClaim aligns with Go naming conventions by starting with an action verb, improving code readability.

Apply this diff to rename the function:

-func (suite *KeeperTestSuite) BridgeCallClaimInitialize(msg types.MsgBridgeCallClaim, tokenIsNativeCoin []bool) (baseDenoms, bridgeDenoms []string, erc20Addrs []common.Address) {
+func (suite *KeeperTestSuite) InitializeBridgeCallClaim(msg types.MsgBridgeCallClaim, tokenIsNativeCoin []bool) (baseDenoms, bridgeDenoms []string, erc20Addrs []common.Address) {

And update the function call accordingly:

-_, _, erc20Addrs := suite.BridgeCallClaimInitialize(tc.Msg, tc.TokenIsNativeCoin)
+_, _, erc20Addrs := suite.InitializeBridgeCallClaim(tc.Msg, tc.TokenIsNativeCoin)
x/crosschain/keeper/bridge_call_in.go (1)

81-81: Address the TODO comment regarding coin conversion

There's a TODO comment: // todo replace convert coin, return token pair. This indicates that the current implementation is a placeholder. Please consider completing this task to improve the code's functionality and maintainability.

Would you like assistance in implementing the replacement of ConvertCoin with a method that returns the token pair? I can help draft the code or open a new GitHub issue to track this task.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between fff9cc0 and 94c7f1b.

📒 Files selected for processing (4)
  • testutil/helpers/suite.go (3 hunks)
  • x/crosschain/keeper/bridge_call_in.go (3 hunks)
  • x/crosschain/keeper/bridge_call_in_test.go (2 hunks)
  • x/crosschain/keeper/keeper.go (0 hunks)
💤 Files with no reviewable changes (1)
  • x/crosschain/keeper/keeper.go
🧰 Additional context used
🔇 Additional comments (1)
testutil/helpers/suite.go (1)

216-216: Confirm use of strings.ToUpper(denom)

In the function call to DeployUpgradableToken, denom is converted to uppercase using strings.ToUpper(denom). Ensure this is intentional, as changing the case of denom may lead to inconsistencies if the original case is significant elsewhere in the codebase or in external systems.

Run the following script to verify how denom is used elsewhere and whether case sensitivity matters:

#!/bin/bash
# Description: Check usage of `denom` and its case sensitivity in the codebase.

# Find all occurrences of `denom` variable.
rg --type go '\bdenom\b'

# Check if `denom` is used in a case-sensitive context.

x/crosschain/keeper/bridge_call_in_test.go Outdated Show resolved Hide resolved
x/crosschain/keeper/bridge_call_in.go Outdated Show resolved Hide resolved
x/crosschain/keeper/bridge_call_in.go Show resolved Hide resolved
x/crosschain/keeper/bridge_call_in.go Show resolved Hide resolved
testutil/helpers/suite.go Outdated Show resolved Hide resolved
testutil/helpers/suite.go Show resolved Hide resolved
Copy link

@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

🧹 Outside diff range and nitpick comments (7)
x/crosschain/keeper/bridge_call_in_test.go (2)

55-70: Improved test execution and error handling

The changes to the test execution loop are well-structured and improve the overall quality of the tests:

  1. Using suite.Run for each test case enhances isolation and reporting.
  2. The introduction of BridgeCallClaimInitialize improves modularity in test setup.
  3. The simplified error checking makes the tests more concise and readable.

Consider adding more descriptive error messages to the suite.Require().Error(err) check. This can help in quickly identifying which specific assertion failed when a test case doesn't succeed. For example:

suite.Require().Error(err, "Expected an error for test case: %s", tc.Name)

Line range hint 98-150: Consider refactoring remaining mock-based tests

The Test_CoinsToBridgeCallTokens and MockBridgeCallToken methods are still part of the KeeperMockSuite, while the refactored tests use KeeperTestSuite. To maintain consistency across the test file:

  1. Consider refactoring these methods to use the KeeperTestSuite approach.
  2. If mock-based testing is still necessary for these specific cases, consider moving them to a separate file dedicated to mock-based tests.

This refactoring would improve the overall consistency of the test suite and make it easier to maintain in the future.

x/crosschain/keeper/bridge_call_in.go (5)

28-32: Approved: Flexible receiver token address determination

The new logic for determining the receiver token address based on the memo content adds flexibility to the system. This change aligns well with the intended functionality.

Consider adding a brief comment explaining the significance of isMemoSendCallTo for better code readability:

// If memo indicates a send call, use sender address as receiver token address
isMemoSendCallTo := types.IsMemoSendCallTo(msg.MustMemo())

34-41: Approved: Improved token handling and error management

The token creation and conversion process has been implemented correctly. The error handling has been enhanced, which is a good practice.

Consider wrapping the error returned from BridgeTokenToERC20 with additional context:

if err != nil {
    return fmt.Errorf("failed to bridge token to ERC20: %w", err)
}

This will provide more informative error messages for debugging.


Line range hint 44-61: Approved: Enhanced bridge call execution and error handling

The use of a cache context for the bridge call execution is a good practice for ensuring atomic operations. The improved error handling and telemetry enhancements will greatly benefit system observability.

Consider adding a log statement before the telemetry call to provide more context in the logs:

if !ctx.IsCheckTx() {
    k.Logger(ctx).Info("Bridge call execution result", "success", err == nil, "module", k.moduleName)
    telemetry.IncrCounterWithLabels(
        // ... (existing code)
    )
}

This will provide more detailed logging information alongside the telemetry data.


96-124: Approved: Improved BridgeCallEvm function with enhanced flexibility

The updated BridgeCallEvm function now effectively handles both memo send calls and regular bridge calls. The addition of the contract check for the target address enhances security.

Consider adding a comment to explain the difference between memo send calls and regular bridge calls for better code readability:

// Handle memo send calls differently from regular bridge calls
if isMemoSendCallTo {
    // Memo send call logic
    args = data
    callEvmSender = sender
} else {
    // Regular bridge call logic
    var err error
    args, err = types.PackBridgeCallback(sender, refundAddr, tokens, amounts, data, memo)
    if err != nil {
        return err
    }
    callEvmSender = k.GetCallbackFrom()
}

This will help future developers understand the purpose of this conditional logic more easily.


126-136: Approved: New BridgeCallFailedRefund function for handling failed bridge calls

The addition of the BridgeCallFailedRefund function provides a crucial mechanism for handling failed bridge calls, improving user experience and system reliability. The event emission enhances the observability of refund operations.

Consider wrapping the error returned from AddOutgoingBridgeCall with additional context:

outCallNonce, err := k.AddOutgoingBridgeCall(ctx, refundAddr, refundAddr, erc20Token, common.Address{}, nil, nil, eventNonce)
if err != nil {
    return fmt.Errorf("failed to add outgoing bridge call for refund: %w", err)
}

This will provide more informative error messages for debugging purposes.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 94c7f1b and 33e8790.

📒 Files selected for processing (3)
  • testutil/helpers/suite.go (3 hunks)
  • x/crosschain/keeper/bridge_call_in.go (3 hunks)
  • x/crosschain/keeper/bridge_call_in_test.go (2 hunks)
🧰 Additional context used
🔇 Additional comments (5)
x/crosschain/keeper/bridge_call_in_test.go (3)

19-52: Improved test structure and readability

The refactoring of the TestBridgeCallHandler function has significantly improved the test structure:

  1. The change from KeeperMockSuite to KeeperTestSuite suggests a move towards more integrated testing.
  2. The new test case structure using a slice of structs with named fields enhances readability and maintainability.
  3. Additional fields in the test cases allow for more comprehensive test scenarios.

These changes will make it easier to add new test cases and understand existing ones.


74-96: Well-structured test initialization method

The new BridgeCallClaimInitialize method is a great addition to the test suite:

  1. It encapsulates complex setup logic, improving test readability and maintainability.
  2. The length check on line 75 addresses the potential index out of range issue raised in a previous review comment.
  3. The method covers all necessary setup steps for the test cases, including handling of native and non-native tokens.

This method effectively addresses the previous concern about potential index out of range errors and provides a clean, reusable way to initialize test data.


Line range hint 1-150: Overall improvement in test structure with opportunity for further refinement

The changes to this test file represent a significant improvement in test structure, readability, and maintainability:

  1. The refactoring of TestBridgeCallHandler and the introduction of BridgeCallClaimInitialize enhance the organization and reusability of test code.
  2. The new approach using KeeperTestSuite seems to move towards more integrated testing, which can provide better coverage.
  3. The changes address previous concerns about potential errors and improve error handling.

However, there's an opportunity to further refine the test suite by consistently applying the new approach across all test methods. Consider completing the transition from KeeperMockSuite to KeeperTestSuite for the remaining methods to achieve full consistency throughout the file.

These changes significantly improve the quality of the test suite, and with a bit more refactoring, it will be even more robust and maintainable.

x/crosschain/keeper/bridge_call_in.go (2)

23-27: Excellent implementation of the module account check

The addition of this check ensures that module accounts cannot be used as senders, which is a good security practice. The error message has also been improved as per the previous review suggestion.


64-93: Approved: New BridgeTokenToERC20 function with suggestions

The new BridgeTokenToERC20 function effectively handles the conversion of tokens to base coins and retrieves the corresponding ERC20 addresses and amounts.

  1. Address the TODO comment:

    // TODO: Replace convert coin operation with a more efficient method
    // that returns the token pair directly

    Consider creating a GitHub issue to track this improvement.

  2. Improve error handling when getting the token pair:

    pair, found := k.erc20Keeper.GetTokenPair(sdk.UnwrapSDKContext(ctx), coin.Denom)
    if !found {
        return nil, nil, nil, fmt.Errorf("token pair not found for denom: %s", coin.Denom)
    }

    This will prevent potential panics if the token pair is not found.

Run the following script to check for other occurrences of ignored errors from GetTokenPair:

testutil/helpers/suite.go Show resolved Hide resolved
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