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(x/erc20): migrate legacy key store #756

Merged
merged 2 commits into from
Oct 18, 2024
Merged

refactor(x/erc20): migrate legacy key store #756

merged 2 commits into from
Oct 18, 2024

Conversation

zakir-code
Copy link
Contributor

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

Summary by CodeRabbit

  • New Features

    • Enhanced ERC20 functionality with improved migration processes.
    • Added a new test for validating outgoing transfer key conversions.
  • Bug Fixes

    • Corrected key management during upgrades to ensure proper ERC20 parameter handling.
  • Documentation

    • Updated comments and documentation related to new migration methods and key handling.

Copy link

coderabbitai bot commented Oct 18, 2024

Walkthrough

The changes in this pull request introduce enhancements to the ERC20 functionality and migration processes across multiple files. Key modifications include the addition of a new test function for ERC20 key validation, updates to the upgrade handler to manage ERC20 store keys, and the introduction of a Migrator struct for handling key migrations. Additionally, several key prefixes in the KVStore have been updated or removed to reflect the new migration logic.

Changes

File Path Change Summary
app/upgrade_test.go Added checkErc20Keys function to assert EnableErc20 parameter during upgrade testing.
app/upgrades/v8/upgrade.go Added imports for erc20v8 and erc20types; modified CreateUpgradeHandler for key removal.
x/erc20/keeper/keeper.go Updated NewKeeper to change the key for Params field in Keeper struct.
x/erc20/migrations/v8/keys.go Introduced Migrator struct with methods for migrating keys and parameters.
x/erc20/migrations/v8/keys_test.go Added TestOutgoingTransferKeyToOriginTokenKey to validate outgoing transfer key conversion.
x/erc20/migrations/v8/legacy.go Defined new global variables for key prefixes; added GetRemovedStoreKeys() function.
x/erc20/migrations/v8/migrations.go Updated Migrate3to4 to include a call to m.migrateKeys(ctx).
x/erc20/types/keys.go Modified key prefixes in KVStore, updating and removing several old prefixes.

Possibly related PRs

🐰 In the meadow where tokens play,
New keys hop and dance all day.
With migrations swift and bright,
ERC20 shines, a joyful sight!
So let’s cheer for changes made,
In our code, let’s parade! 🎉


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

🧹 Outside diff range and nitpick comments (7)
x/erc20/migrations/v8/keys_test.go (2)

14-21: LGTM: Well-structured test with random inputs.

The test function effectively validates the conversion from an outgoing transfer key to an origin token key. It uses random inputs for thorough testing and follows the Arrange-Act-Assert pattern.

Consider adding more test cases to cover edge cases, such as:

  1. Empty module name
  2. Maximum uint64 value for txID
  3. Minimum uint64 value for txID

This will ensure the function behaves correctly under various conditions.


1-21: Overall: Well-structured and focused test file.

This test file is well-organized and effectively tests the key conversion functionality for the v8 migration. It uses appropriate random inputs and assertions, following good testing practices.

To further improve the test coverage:

  1. Consider adding more test cases to cover edge cases and potential error scenarios.
  2. If there are other key conversion functions in the v8 migration, consider adding tests for them in this file as well.
  3. Think about potential integration tests that might be needed to ensure the migration process works correctly in a broader context.
x/erc20/migrations/v8/legacy.go (2)

11-19: LGTM! Consider adding comments for clarity.

The new key prefix variables are well-organized and follow a consistent naming convention. They appear to be part of a migration process, which aligns with the package name v8.

Consider adding brief comments for each variable to explain their purpose, especially for less obvious ones like ParamsKey. This would enhance code readability and maintainability.


21-25: LGTM! Consider adding a function comment.

The GetRemovedStoreKeys() function is well-implemented and serves a clear purpose in the migration process.

Consider adding a function comment to explain the purpose of this function and why these specific keys are being removed. This would provide valuable context for future developers working on migrations.

app/upgrades/v8/upgrade.go (1)

48-49: LGTM: ERC20 store keys removal added.

The addition of ERC20 store keys removal is consistent with the existing upgrade process for other modules. This ensures that obsolete ERC20-related keys are cleaned up during the upgrade.

For consistency with the other similar calls, consider adding a log message after this operation:

 removeStoreKeys(cacheCtx, app.GetKey(erc20types.StoreKey), erc20v8.GetRemovedStoreKeys())
+cacheCtx.Logger().Info("removed obsolete ERC20 store keys")
app/upgrade_test.go (2)

107-111: LGTM: ERC20 key check implementation looks good.

The checkErc20Keys function correctly retrieves and verifies the ERC20 parameters. The check for EnableErc20 being true is appropriate for ensuring ERC20 functionality is enabled after the upgrade.

Consider expanding this function to check other relevant ERC20 parameters or states if they exist, to provide a more comprehensive verification of the ERC20 subsystem post-upgrade.


103-111: Consider adding a comment to explain the ERC20 check.

The addition of the ERC20 check enhances the upgrade test process. To improve code documentation and maintainability, consider adding a brief comment explaining the purpose and importance of this new check in the context of the upgrade process.

Here's a suggested comment to add above the checkErc20Keys function:

// checkErc20Keys verifies that the ERC20 functionality is properly enabled after the upgrade.
// This ensures that the migration of ERC20-related data and settings was successful.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 0a123f8 and 24db824.

📒 Files selected for processing (8)
  • app/upgrade_test.go (1 hunks)
  • app/upgrades/v8/upgrade.go (2 hunks)
  • x/erc20/keeper/keeper.go (1 hunks)
  • x/erc20/migrations/v8/keys.go (1 hunks)
  • x/erc20/migrations/v8/keys_test.go (1 hunks)
  • x/erc20/migrations/v8/legacy.go (1 hunks)
  • x/erc20/migrations/v8/migrations.go (1 hunks)
  • x/erc20/types/keys.go (1 hunks)
🧰 Additional context used
🪛 GitHub Check: lint
app/upgrades/v8/upgrade.go

[failure] 19-19:
could not import github.com/functionx/fx-core/v8/x/erc20/migrations/v8 (-: # github.com/functionx/fx-core/v8/x/erc20/migrations/v8

x/erc20/migrations/v8/keys.go

[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set (typecheck)


[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set) (typecheck)


[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set) (typecheck)

🪛 GitHub Check: test
x/erc20/migrations/v8/keys.go

[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set

🔇 Additional comments (9)
x/erc20/types/keys.go (1)

17-22: Significant changes to key prefixes require careful consideration.

The consistent use of collections.NewPrefix() for all key definitions is good for maintainability. However, these changes raise some important points:

  1. The shift in prefix numbers from 1-6 to 11-16 and the removal of several key prefixes (as mentioned in the AI summary) indicate a significant change in how data is stored or accessed in the ERC20 module.

  2. These changes will likely require a data migration strategy for existing chains. Ensure that a proper migration plan is in place and thoroughly tested.

  3. The removal of key prefixes (KeyPrefixTokenPair, KeyPrefixTokenPairByERC20, etc.) needs verification. Please confirm that the functionality previously associated with these keys is either no longer needed or has been refactored elsewhere.

  4. Update the module's documentation to reflect these changes, including any migration steps required for users of this module.

To verify the impact of these changes, please run the following script:

This script will help ensure that all old key prefixes have been properly removed and new ones are correctly implemented. It will also check for any migration logic related to these changes.

✅ Verification successful

Key prefix updates are properly handled through migration.

The old key prefixes are correctly maintained within the migration scripts to ensure smooth data transition. New key prefixes are consistently implemented, and no usages of old prefixes remain in the active codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usage of old key prefixes and verify the implementation of new prefixes

# Test 1: Check for any remaining usage of old key prefixes
echo "Checking for usage of old key prefixes:"
rg --type go "KeyPrefixTokenPair|KeyPrefixTokenPairByERC20|KeyPrefixTokenPairByDenom|KeyPrefixIBCTransfer|KeyPrefixAliasDenom|KeyPrefixOutgoingTransfer" ./x/erc20

# Test 2: Verify the implementation of new prefixes
echo "Verifying implementation of new prefixes:"
rg --type go "DenomIndexKey|ParamsKey|ERC20TokenKey|BridgeTokenKey|IBCTokenKey|CacheKey" ./x/erc20

# Test 3: Check for any migration logic related to these changes
echo "Checking for migration logic:"
rg --type go "migrate|migration|upgrade" ./x/erc20

Length of output: 5114

x/erc20/migrations/v8/keys_test.go (1)

3-12: LGTM: Imports are well-organized and relevant.

The imports are logically structured and include all necessary packages for the test function. The organization follows good practices by grouping standard library imports, third-party libraries, and internal packages.

x/erc20/migrations/v8/migrations.go (1)

33-35: Approve: Key migration step added with proper error handling.

The addition of m.migrateKeys(ctx) with error handling improves the robustness of the migration process. This ensures that key migration is successful before proceeding to token migration.

Consider the following suggestions:

  1. Document the new migration step in the method's comments to clarify the process for other developers.
  2. Assess the impact on migration performance, especially for large datasets.
  3. Update any existing migration documentation or guides to reflect this new step.
  4. Ensure comprehensive error logging is in place to facilitate debugging in case of migration failures.

To verify the implementation of the migrateKeys method and its usage, run the following script:

x/erc20/migrations/v8/legacy.go (1)

29-30: LGTM! Verify consistency across the codebase.

The changes to LegacyIsNativeERC20 correctly use the newly defined key prefixes, maintaining the function's logic while aligning with the migration process.

To ensure consistency, let's verify that all occurrences of the old key prefixes have been updated:

✅ Verification successful

Migration Consistency Verified

The migration process correctly removed all old key prefix usages. No issues found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usage of old key prefixes

# Test: Search for old key prefix usage
echo "Searching for old key prefix usage..."
rg --type go "types\.KeyPrefixTokenPairByDenom|types\.KeyPrefixTokenPair" ./x/erc20

# If no results are found, the migration is complete
if [ $? -ne 0 ]; then
    echo "No old key prefix usage found. Migration appears complete."
fi

Length of output: 315

app/upgrades/v8/upgrade.go (2)

Line range hint 1-114: Summary: ERC20 migration functionality successfully integrated.

The changes in this file effectively integrate ERC20 migration functionality into the upgrade process. The additions are consistent with the existing code structure and follow established patterns for module upgrades. These modifications ensure that the ERC20 module's data is properly migrated and cleaned up during the v8 upgrade.

Key points:

  1. New imports for ERC20-related packages have been added.
  2. The CreateUpgradeHandler function now includes the removal of obsolete ERC20 store keys.

These changes appear to be well-implemented and necessary for the successful upgrade of the ERC20 module.

🧰 Tools
🪛 GitHub Check: lint

[failure] 19-19:
could not import github.com/functionx/fx-core/v8/x/erc20/migrations/v8 (-: # github.com/functionx/fx-core/v8/x/erc20/migrations/v8


19-20: LGTM: New imports for ERC20 migration.

The new imports for ERC20-related packages are correctly added and necessary for the migration functionality introduced in this upgrade.

Regarding the lint error for the erc20v8 import, let's verify if the package exists:

If the script returns a path containing erc20/migrations/v8, the lint error is likely a false positive.

✅ Verification successful

Verified: ERC20 migration imports are correct, and the lint error for erc20v8 is a false positive.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence of the erc20v8 package
fd -t d "migrations" | xargs -I {} find {} -type d -name "v8"

Length of output: 129

🧰 Tools
🪛 GitHub Check: lint

[failure] 19-19:
could not import github.com/functionx/fx-core/v8/x/erc20/migrations/v8 (-: # github.com/functionx/fx-core/v8/x/erc20/migrations/v8

x/erc20/keeper/keeper.go (1)

68-68: LGTM. Verify data migration and update documentation.

This change aligns with the PR objective of migrating the legacy key store. The update from types.ParamsKey2 to types.ParamsKey for the Params item is a step in the right direction.

However, to ensure a smooth transition:

  1. Verify that any existing data stored under ParamsKey2 has been or will be migrated to ParamsKey.
  2. Ensure backwards compatibility if any part of the system still references ParamsKey2.
  3. Update any related documentation or comments that might reference the old key.

To verify the usage of the new key and check for any remaining references to the old key, run the following script:

✅ Verification successful

Verified: ParamsKey2 is no longer used, and the migration is handled by the migrateParams function. Ensure that related documentation is updated accordingly.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of ParamsKey and ParamsKey2

# Test 1: Check for usage of the new ParamsKey
echo "Occurrences of ParamsKey:"
rg --type go "ParamsKey[^2]" -g '!vendor'

# Test 2: Check for any remaining usage of the old ParamsKey2
echo "Occurrences of ParamsKey2:"
rg --type go "ParamsKey2" -g '!vendor'

# Test 3: Check for any migration functions that might handle the key change
echo "Potential migration functions:"
rg --type go "func.*(migrate|upgrade).*Params" -g '!vendor'

Length of output: 1832

app/upgrade_test.go (2)

103-105: LGTM: Addition of ERC20 key check is appropriate.

The inclusion of checkErc20Keys in the checkAppUpgrade function is a good addition. It ensures that ERC20-related parameters are verified as part of the post-upgrade checks, which is consistent with the function's purpose.


103-111: Overall, the changes enhance the upgrade test process.

The addition of ERC20-related checks in the upgrade test process is a positive improvement. It ensures that the ERC20 functionality is properly verified after an upgrade, which can help catch potential issues early. The changes are minimal and focused, integrating well with the existing test structure.

To further improve the code:

  1. Consider expanding the ERC20 checks to cover more parameters if applicable.
  2. Add comments to explain the purpose of the new ERC20 check for better documentation.

These suggestions aside, the implementation is sound and achieves its intended purpose.

Comment on lines +31 to +33
if err := m.keeper.Cache.Set(ctx, string(newKey), sdkmath.ZeroInt()); err != nil {
return err
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Type Mismatch in m.keeper.Cache.Set: Incorrect Value Type

The call to m.keeper.Cache.Set is passing sdkmath.ZeroInt() as the value argument. However, m.keeper.Cache expects a value of type collections.NoValue. Passing sdkmath.ZeroInt() results in a type mismatch, as indicated by the static analysis tools.

To fix the issue, omit the value argument if Cache.Set only requires a key, or pass the appropriate value type expected by the method.

Apply this diff to correct the issue:

-        if err := m.keeper.Cache.Set(ctx, string(newKey), sdkmath.ZeroInt()); err != nil {
+        if err := m.keeper.Cache.Set(ctx, string(newKey)); err != nil {
             return err
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err := m.keeper.Cache.Set(ctx, string(newKey), sdkmath.ZeroInt()); err != nil {
return err
}
if err := m.keeper.Cache.Set(ctx, string(newKey)); err != nil {
return err
}
🧰 Tools
🪛 GitHub Check: test

[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set

🪛 GitHub Check: lint

[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set

Comment on lines +43 to +45
if err := m.keeper.Cache.Set(ctx, originTokenKey, sdkmath.ZeroInt()); err != nil {
return err
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Type Mismatch in m.keeper.Cache.Set: Incorrect Value Type

Similar to the issue above, the call to m.keeper.Cache.Set uses sdkmath.ZeroInt() as the value argument, leading to a type mismatch. The method expects a value of type collections.NoValue.

Apply this diff to correct the issue:

-        if err := m.keeper.Cache.Set(ctx, originTokenKey, sdkmath.ZeroInt()); err != nil {
+        if err := m.keeper.Cache.Set(ctx, originTokenKey); err != nil {
             return err
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err := m.keeper.Cache.Set(ctx, originTokenKey, sdkmath.ZeroInt()); err != nil {
return err
}
if err := m.keeper.Cache.Set(ctx, originTokenKey); err != nil {
return err
}
🧰 Tools
🪛 GitHub Check: test

[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set

🪛 GitHub Check: lint

[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set (typecheck)


[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set) (typecheck)


[failure] 43-43:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set) (typecheck)

Comment on lines +63 to +73
func OutgoingTransferKeyToOriginTokenKey(key []byte) string {
// key = prefix + moduleName(string-) + sdk.Uint64ToBigEndian(id)(len = 8)
// 1. remove prefix
key = key[len(KeyPrefixOutgoingTransfer):]
// 2. get moduleName
moduleName := string(key[:len(key)-8])
// 3. get id
id := sdk.BigEndianToUint64(key[len(key)-8:])
// 4. new originTokenKey
return crosschaintypes.NewOriginTokenKey(moduleName, id)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential Slice Bounds Out of Range in OutgoingTransferKeyToOriginTokenKey

In the function OutgoingTransferKeyToOriginTokenKey, slicing the key byte slice without validating its length could lead to a runtime panic if key is shorter than expected. Specifically, accessing key[:len(key)-8] and key[len(key)-8:] assumes that key has a minimum length of 8 bytes.

To prevent possible runtime errors, add a length check to ensure that key has at least the required length before performing slice operations.

Apply this diff to add length checks:

 func OutgoingTransferKeyToOriginTokenKey(key []byte) string {
     // key = prefix + moduleName(string-) + sdk.Uint64ToBigEndian(id)(len = 8)
     // 1. remove prefix
+    if len(key) < len(KeyPrefixOutgoingTransfer)+8 {
+        // Handle error appropriately, e.g., log or return an error/empty string
+        return ""
+    }
     key = key[len(KeyPrefixOutgoingTransfer):]
     // 2. get moduleName
     moduleName := string(key[:len(key)-8])
     // 3. get id
     id := sdk.BigEndianToUint64(key[len(key)-8:])
     // 4. new originTokenKey
     return crosschaintypes.NewOriginTokenKey(moduleName, id)
 }

Consider returning an error instead of an empty string to handle invalid keys appropriately.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func OutgoingTransferKeyToOriginTokenKey(key []byte) string {
// key = prefix + moduleName(string-) + sdk.Uint64ToBigEndian(id)(len = 8)
// 1. remove prefix
key = key[len(KeyPrefixOutgoingTransfer):]
// 2. get moduleName
moduleName := string(key[:len(key)-8])
// 3. get id
id := sdk.BigEndianToUint64(key[len(key)-8:])
// 4. new originTokenKey
return crosschaintypes.NewOriginTokenKey(moduleName, id)
}
func OutgoingTransferKeyToOriginTokenKey(key []byte) string {
// key = prefix + moduleName(string-) + sdk.Uint64ToBigEndian(id)(len = 8)
// 1. remove prefix
if len(key) < len(KeyPrefixOutgoingTransfer)+8 {
// Handle error appropriately, e.g., log or return an error/empty string
return ""
}
key = key[len(KeyPrefixOutgoingTransfer):]
// 2. get moduleName
moduleName := string(key[:len(key)-8])
// 3. get id
id := sdk.BigEndianToUint64(key[len(key)-8:])
// 4. new originTokenKey
return crosschaintypes.NewOriginTokenKey(moduleName, id)
}

Comment on lines +26 to +39
iterator := storetypes.KVStorePrefixIterator(store, KeyPrefixIBCTransfer)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
key := iterator.Key()
newKey := key[len(KeyPrefixIBCTransfer):]
if err := m.keeper.Cache.Set(ctx, string(newKey), sdkmath.ZeroInt()); err != nil {
return err
}
store.Delete(key)
}

// 2. migrate outgoing transfer relation
iterator = storetypes.KVStorePrefixIterator(store, KeyPrefixOutgoingTransfer)
defer iterator.Close()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incorrect Use of Defer with Reassigned Iterator

The iterator variable is reused and reassigned in the same function, with defer iterator.Close() called after each assignment. In Go, deferred calls to a method capture the variables at the time the function is executed, not when the defer is declared. This means both deferred calls will attempt to close the last assigned iterator, potentially leaving the first iterator unclosed and causing resource leaks.

To fix this issue, avoid reusing the iterator variable when deferring its Close() method. Use separate variables for each iterator.

Apply this diff to correct the issue:

 func (m Migrator) migrateRelationToCache(ctx sdk.Context, store storetypes.KVStore) error {
     // 1. migrate ibc transfer relation
-    iterator := storetypes.KVStorePrefixIterator(store, KeyPrefixIBCTransfer)
-    defer iterator.Close()
-    for ; iterator.Valid(); iterator.Next() {
+    iterator1 := storetypes.KVStorePrefixIterator(store, KeyPrefixIBCTransfer)
+    defer iterator1.Close()
+    for ; iterator1.Valid(); iterator1.Next() {
+        key := iterator1.Key()
+        newKey := key[len(KeyPrefixIBCTransfer):]
+        if err := m.keeper.Cache.Set(ctx, string(newKey)); err != nil {
             return err
         }
         store.Delete(key)
     }

     // 2. migrate outgoing transfer relation
-    iterator = storetypes.KVStorePrefixIterator(store, KeyPrefixOutgoingTransfer)
-    defer iterator.Close()
-    for ; iterator.Valid(); iterator.Next() {
+    iterator2 := storetypes.KVStorePrefixIterator(store, KeyPrefixOutgoingTransfer)
+    defer iterator2.Close()
+    for ; iterator2.Valid(); iterator2.Next() {
+        key := iterator2.Key()
+        originTokenKey := OutgoingTransferKeyToOriginTokenKey(key)
+        if err := m.keeper.Cache.Set(ctx, originTokenKey); err != nil {
             return err
         }
         store.Delete(key)
     }
     return nil
 }

Committable suggestion was skipped due to low confidence.

🧰 Tools
🪛 GitHub Check: test

[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set

🪛 GitHub Check: lint

[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set


[failure] 31-31:
cannot use sdkmath.ZeroInt() (value of type "cosmossdk.io/math".Int) as collections.NoValue value in argument to m.keeper.Cache.Set

@fx0x55
Copy link
Contributor

fx0x55 commented Oct 18, 2024

@coderabbitai full review

Copy link

coderabbitai bot commented Oct 18, 2024

✅ Actions performed

Full review triggered.

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 (5)
x/erc20/types/keys.go (1)

17-22: Acknowledge the benefits of this refactoring while emphasizing careful migration

While the changes to the key prefixes are significant and potentially disruptive, they appear to be part of a larger refactoring effort to improve the organization of the KVStore. The new sequential numbering (11-16) suggests a more structured approach to key management, which could lead to better maintainability in the long run.

However, it's crucial to reiterate:

  1. Ensure thorough testing of all affected components.
  2. Implement and test a robust data migration strategy.
  3. Update all relevant documentation.
  4. Communicate these changes clearly to other developers and users of the module.

Consider documenting the rationale behind this refactoring and the new numbering scheme (e.g., why start at 11?) in a comment within this file or in the module's documentation. This will help future maintainers understand the design decisions made here.

x/erc20/migrations/v8/keys_test.go (1)

14-21: LGTM: Test function is well-implemented, with room for enhancement.

The test function TestOutgoingTransferKeyToOriginTokenKey effectively verifies the conversion of an outgoing transfer key to an origin token key. It uses random generation for inputs, which is a good practice for robust testing.

Suggestions for improvement:

  1. Consider adding test cases for edge cases, such as empty module names or extreme transaction ID values.
  2. It might be beneficial to add a test case for invalid input to ensure proper error handling.
  3. To increase test coverage, you could add multiple test cases within this function or create separate test functions for different scenarios.

Here's an example of how you could enhance the test function:

func TestOutgoingTransferKeyToOriginTokenKey(t *testing.T) {
	testCases := []struct {
		name       string
		moduleName string
		txID       uint64
	}{
		{"random values", tmrand.Str(5), uint64(tmrand.Int63n(100000))},
		{"empty module name", "", uint64(tmrand.Int63n(100000))},
		{"max txID", "module", math.MaxUint64},
		{"min txID", "module", 0},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			oldKey := append(append(v8.KeyPrefixOutgoingTransfer, []byte(tc.moduleName)...), sdk.Uint64ToBigEndian(tc.txID)...)
			expectKey := types.NewOriginTokenKey(tc.moduleName, tc.txID)
			actual := v8.OutgoingTransferKeyToOriginTokenKey(oldKey)
			require.EqualValues(t, expectKey, actual)
		})
	}
}

This enhancement adds multiple test cases, including edge cases, and uses subtests for better organization and reporting.

x/erc20/keeper/keeper.go (1)

Line range hint 1-124: Summary: Ensure this change is part of a comprehensive migration plan.

The change from ParamsKey2 to ParamsKey appears to be part of a larger refactoring or migration process. While the change itself is straightforward, it's important to consider the following:

  1. Migration strategy: Ensure that there's a clear migration strategy in place to handle any existing data that might be stored using the old key.
  2. Version compatibility: If this is a breaking change, make sure it's properly documented and that version compatibility is maintained or handled appropriately.
  3. Testing: Comprehensive testing should be performed to ensure that this change doesn't introduce any regressions in the ERC20 module functionality.

Consider adding a comment in the code explaining the reason for this change and referencing any relevant migration documentation or issues. This will help future maintainers understand the context of this modification.

app/upgrade_test.go (1)

108-111: LGTM with suggestion: Implementation of checkErc20Keys

The implementation of checkErc20Keys is correct and concise:

  • It properly retrieves ERC20 parameters from the keeper.
  • Error handling is implemented for parameter retrieval.
  • The essential check for ERC20 functionality being enabled is present.

Suggestion for improvement:
Consider adding a more descriptive error message to the assertion for better debugging. For example:

require.True(t, params.EnableErc20, "ERC20 functionality should be enabled after the upgrade")

This will provide more context if the test fails in the future.

app/upgrades/v8/upgrade.go (1)

Line range hint 76-79: Avoid logging potentially sensitive key information

Logging the actual keys using string(iterator.Key()) could expose sensitive data in the logs. Consider omitting the key details or using a hashed representation to enhance security.

You can apply the following diff to adjust the logging:

-            ctx.Logger().Info("remove store key", "kvStore", storeKey.Name(),
-                "prefix", hex.EncodeToString(key), "key", string(iterator.Key()))
+            ctx.Logger().Info("remove store key", "kvStore", storeKey.Name(),
+                "prefix", hex.EncodeToString(key))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6a7784a and a0b182b.

📒 Files selected for processing (8)
  • app/upgrade_test.go (1 hunks)
  • app/upgrades/v8/upgrade.go (2 hunks)
  • x/erc20/keeper/keeper.go (1 hunks)
  • x/erc20/migrations/v8/keys.go (1 hunks)
  • x/erc20/migrations/v8/keys_test.go (1 hunks)
  • x/erc20/migrations/v8/legacy.go (1 hunks)
  • x/erc20/migrations/v8/migrations.go (1 hunks)
  • x/erc20/types/keys.go (1 hunks)
🧰 Additional context used
🔇 Additional comments (18)
x/erc20/types/keys.go (1)

17-22: ⚠️ Potential issue

Significant changes to key prefixes require careful consideration

The modifications to the key prefixes in this file have far-reaching implications:

  1. Several key prefixes have been removed (e.g., KeyPrefixTokenPair, KeyPrefixTokenPairByERC20, etc.). This could break existing code that relies on these prefixes.

  2. The remaining key prefixes have been updated with new prefix numbers (11-16 instead of 1-6). This changes the storage layout, which could affect data migration and compatibility with existing data.

  3. The new prefix numbers are sequential (11-16), which is good for maintainability and readability.

These changes will likely require updates in other parts of the codebase that use these keys. Please ensure that:

  • All code using the removed prefixes is updated or removed.
  • A data migration plan is in place to handle the change in storage layout.
  • Documentation is updated to reflect these changes.

To check for any remaining usage of the removed prefixes, run the following script:

This script will help identify any remaining usage of the removed prefixes in the Go files of the project.

✅ Verification successful

Verified: Removed key prefixes are only used in migration scripts

The removed key prefixes are exclusively referenced within the migration files (legacy.go, keys.go, and keys_test.go) in the x/erc20/migrations/v8/ directory. This is expected behavior, as migration scripts are responsible for handling data transformations and ensuring compatibility with existing data structures.

  • Migration Integrity: Ensure that all migration scripts correctly handle the removed prefixes to maintain data integrity during the migration process.
  • Testing: Verify that the migration tests (keys_test.go) cover scenarios involving these prefixes to prevent potential data issues.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of removed key prefixes in the codebase

# List of removed prefixes
removed_prefixes=(
  "KeyPrefixTokenPair"
  "KeyPrefixTokenPairByERC20"
  "KeyPrefixTokenPairByDenom"
  "KeyPrefixIBCTransfer"
  "KeyPrefixAliasDenom"
  "KeyPrefixOutgoingTransfer"
)

# Search for usage of removed prefixes
for prefix in "${removed_prefixes[@]}"; do
  echo "Searching for usage of $prefix:"
  rg "$prefix" --type go
  echo
done

Length of output: 3214

x/erc20/migrations/v8/keys_test.go (1)

3-12: LGTM: Imports are appropriate and well-organized.

The imports include all necessary packages for testing, including the standard testing package, Cosmos SDK types, and project-specific packages. The use of aliases is clear and follows common conventions.

x/erc20/migrations/v8/migrations.go (1)

33-35: LGTM! Consider adding a comment for clarity.

The addition of m.migrateKeys(ctx) with proper error handling is a good improvement to the migration process. It ensures that key migration is performed before token migration, maintaining a clear separation of concerns.

Consider adding a brief comment explaining the purpose of the key migration step for better code documentation.

To ensure the migrateKeys method is properly implemented, let's verify its existence and basic structure:

✅ Verification successful

migrateKeys Method Verified and Properly Implemented

The migrateKeys method exists and is correctly integrated into the migration process with appropriate error handling. Consider adding a brief comment explaining the purpose of the key migration step for better code documentation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and basic structure of the migrateKeys method

# Test: Search for the migrateKeys method definition
ast-grep --lang go --pattern 'func (m Migrator) migrateKeys(ctx $_) error {
  $$$
}'

# Test: Check for any usage of the migrateKeys method
rg --type go 'migrateKeys\(ctx\)'

Length of output: 816

x/erc20/keeper/keeper.go (1)

69-69: Verify the consistency of the ParamsKey change.

The change from types.ParamsKey2 to types.ParamsKey looks good, but it's important to ensure this change is consistent across the codebase and doesn't break existing functionality.

Please run the following script to verify the consistency of this change:

This script will help ensure that:

  1. There are no remaining uses of ParamsKey2 that might have been missed.
  2. ParamsKey is properly defined.
  3. ParamsKey is used consistently in other parts of the code.

Please review the results and make any necessary adjustments to ensure consistency across the codebase.

✅ Verification successful

ParamsKey change is consistent and verified.

The update from ParamsKey2 to ParamsKey in x/erc20/keeper/keeper.go has been successfully verified:

  • No remaining instances of ParamsKey2 were found.
  • ParamsKey is correctly defined and used consistently within the erc20 module.
  • Other modules maintain their own ParamsKey definitions without conflict.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining uses of ParamsKey2 and verify the definition of ParamsKey

# Check for any remaining uses of ParamsKey2
echo "Checking for any remaining uses of ParamsKey2:"
rg --type go "ParamsKey2"

# Verify the definition of ParamsKey
echo "Verifying the definition of ParamsKey:"
rg --type go "ParamsKey\s*=.*"

# Check for any other uses of ParamsKey
echo "Checking for other uses of ParamsKey:"
rg --type go "ParamsKey[^2]"

Length of output: 2112

app/upgrade_test.go (3)

103-105: LGTM: ERC20 key check added to upgrade verification

The addition of checkErc20Keys(t, ctx, myApp) to the checkAppUpgrade function is appropriate. This ensures that ERC20 functionality is verified as part of the upgrade process, which is consistent with the overall purpose of this test function.


107-107: LGTM: New function checkErc20Keys declared

The declaration of checkErc20Keys is consistent with other check functions in this file. The parameters (t *testing.T, ctx sdk.Context, myApp *app.App) are appropriate for a test function that needs to interact with the app context.


103-111: Overall assessment: ERC20 upgrade checks successfully implemented

The changes in this file effectively integrate ERC20 functionality checks into the upgrade verification process. The new checkErc20Keys function is well-implemented and properly integrated into the existing checkAppUpgrade function. These additions enhance the robustness of the upgrade tests by ensuring that ERC20 functionality is correctly enabled after the upgrade.

The implementation follows the existing patterns in the file, maintaining consistency and readability. No major issues were found, and the changes align well with the purpose of the upgrade tests.

x/erc20/migrations/v8/legacy.go (2)

11-19: Constants for Key Prefixes Defined Correctly

The key prefixes are appropriately defined and will aid in the migration process. This ensures that the keys are managed consistently across the migration logic.


21-25: Verify All Store Keys Are Included in GetRemovedStoreKeys()

Ensure that all store keys that need to be removed during migration are included in the GetRemovedStoreKeys() function. Currently, keys such as KeyPrefixIBCTransfer, ParamsKey, and KeyPrefixOutgoingTransfer are not included. If these keys are also obsolete or need to be cleaned up, consider adding them to the list.

Run the following script to identify all key prefixes and verify their inclusion:

x/erc20/migrations/v8/keys.go (7)

12-22: LGTM: Correct Management of Migration Steps

The migrateKeys function accurately orchestrates the migration by sequentially invoking migrateParams and migrateRelationToCache. Error handling is properly handled.


26-35: Reusing Iterator Variable with Defer May Cause Resource Leaks


31-33: Type Mismatch in m.keeper.Cache.Set: Incorrect Value Type


38-47: Reusing Iterator Variable with Defer May Cause Resource Leaks


43-45: Type Mismatch in m.keeper.Cache.Set: Incorrect Value Type


63-73: Potential Slice Bounds Out of Range in OutgoingTransferKeyToOriginTokenKey


52-61: Verify if All Parameters Are Properly Migrated

The migrateParams function currently only migrates the EnableErc20 parameter. If there are additional fields in types.Params, they should be included to ensure a complete migration and prevent potential issues with default values.

Run the following script to list all fields in the Params struct:

✅ Verification successful

All Parameters Are Properly Migrated

All parameters in the types.Params struct have been successfully migrated. No additional fields detected.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: List all fields in the Params struct within the erc20 module.

# Expected Result: Display all the fields in the Params struct to verify if additional parameters exist.

# Command:
ast-grep --lang go --pattern 'type Params struct {
    $$$
}' x/erc20/types/ | cat

Length of output: 336

app/upgrades/v8/upgrade.go (2)

19-20: New imports for ERC20 migration added correctly

The additions of erc20v8 and erc20types imports are necessary for the ERC20 migration logic in the upgrade handler.


48-48: Proper removal of ERC20 store keys during upgrade

The call to removeStoreKeys for the ERC20 module ensures that obsolete store keys are cleaned up during the upgrade process, similar to the handling of staking and governance modules.

x/erc20/migrations/v8/legacy.go Show resolved Hide resolved
@fx0x55 fx0x55 merged commit e7675af into main Oct 18, 2024
9 checks passed
@fx0x55 fx0x55 deleted the fx0x55/erc20 branch October 18, 2024 10:29
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