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

feat: auto register host zone #1620

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open

Conversation

tropicaldog
Copy link
Contributor

@tropicaldog tropicaldog commented May 19, 2024

1. Summary

Closes #1458
Partially addresses #1631

2.Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

3. Implementation details

4. How to test/use

5. Checklist

  • Does the Readme need to be updated?

6. Limitations (optional)

7. Future Work (optional)

Summary by CodeRabbit

  • New Features

    • Enhanced support for liquid token protocols on host zones, including Osmosis and Umee.
    • Improved error handling for better reliability and user experience.
  • Tests

    • Updated test cases to include new protocol data setup and validation checks for liquid token protocols.
  • Refactor

    • Refined protocol data handling with new utility functions for marshalling and unmarshalling data.
  • Bug Fixes

    • Fixed issues related to protocol data proposal handling and verification processes.

Copy link

vercel bot commented May 19, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
quicksilver ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 29, 2024 9:51pm

Copy link
Contributor

coderabbitai bot commented May 19, 2024

Walkthrough

The recent updates introduce new protocols for handling LiquidAllowedDenomProtocolData in the participationrewards module. This involves automatically registering IBC denoms for host zones during zone registration. Enhancements also include error handling and additional tests to ensure the correct setup and validation of protocol data, particularly for the Osmosis and Umee chains.

Changes

Files Change Summary
x/participationrewards/keeper/hooks.go Added logic for creating LiquidAllowedDenomProtocolData and error handling
x/participationrewards/.../hooks_test.go Enhanced TestAfterZoneCreated to include setup for protocol data and checks for liquid token protocol data
x/participationrewards/.../keeper_test.go Added global variables for chain channels and updated tests to incorporate setup for channels and protocol data
x/participationrewards/.../proposal_handler_test.go Refactored handling of protocol data proposals in TestHandleRemoveProtocolDataProposal
x/participationrewards/.../protocol_data.go Introduced functions for marshalling and unmarshalling protocol data

Assessment against linked issues

Objective (Issue) Addressed Explanation
Auto register ibc denoms for host zone, osmosis during zone registration (#1458)

Poem

🌟 A change in code, with tokens in tow,
For zones and chains, we make them flow.
Osmosis and Umee, no errors to see,
Protocols aligned, as smooth as can be.
In the world of rewards, precision is key,
As denoms register, our zones run free.
🐇🔗 Rejoice in the data, from sea to shining sea.

       (\(\     
      ( -.-)     
      o_(")(")     

Tip

Early access features: enabled

We are currently testing the following features in early access:

  • OpenAI gpt-4o model for code reviews and chat: OpenAI claims that this model is better at understanding and generating code than the previous models. We seek your feedback over the next few weeks before making it generally available.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.
  • Please join our Discord Community to provide feedback and report issues.
  • OSS projects are always opted into early access features.

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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

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

@tropicaldog
Copy link
Contributor Author

tropicaldog commented May 19, 2024

@joe-bowman could you give a quick look at my implementation? I will add some tests for the hook after getting your review, ty.

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

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 0dd1a93 and 892bcc2.
Files selected for processing (2)
  • x/participationrewards/keeper/hooks.go (2 hunks)
  • x/participationrewards/keeper/hooks_test.go (2 hunks)
Additional Context Used
GitHub Check Runs (1)
devskim success (1)

x/participationrewards/keeper/hooks_test.go: [notice] 43-43: A "TODO" or similar was left in source code, possibly indicating incomplete functionality
Suspicious comment

Additional comments not posted (5)
x/participationrewards/keeper/hooks_test.go (2)

Line range hint 18-32: Setup and initial checks in TestAfterZoneCreated are correctly implemented.


33-42: Host chain checks in TestAfterZoneCreated are correctly implemented.

x/participationrewards/keeper/hooks.go (3)

9-11: The addition of new imports for transfertypes and utils is justified as they are used in the new functionality.


152-169: Creation and handling of LiquidAllowedDenomProtocolData for the host zone are correctly implemented.


171-209: Handling of OsmosisParamsProtocolData and UmeeParamsProtocolData, including data fetching, processing, and validation, is correctly implemented.

Also applies to: 211-250

suite.Equal(zone.LocalDenom, lpd.QAssetDenom)
suite.Equal(zone.BaseDenom, lpd.IbcDenom)

// TODO: add tests for osmosis zone and umee zone, need setup connection data for testing
Copy link
Contributor

Choose a reason for hiding this comment

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

TODO: Add tests for osmosis and umee zones.

Would you like me to help implement these tests or should I open a GitHub issue to track this task?

Copy link

codecov bot commented May 19, 2024

Codecov Report

Attention: Patch coverage is 57.73196% with 41 lines in your changes missing coverage. Please review.

Project coverage is 63.56%. Comparing base (154b78d) to head (3c1259c).
Report is 4 commits behind head on main.

Current head 3c1259c differs from pull request most recent head 7e58f4d

Please upload reports for the commit 7e58f4d to get more accurate results.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1620      +/-   ##
==========================================
- Coverage   63.93%   63.56%   -0.37%     
==========================================
  Files         195      195              
  Lines       13757    13870     +113     
==========================================
+ Hits         8795     8816      +21     
- Misses       4099     4178      +79     
- Partials      863      876      +13     
Flag Coverage Δ
unittests 63.56% <57.73%> (-0.37%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
x/participationrewards/keeper/protocol_data.go 76.71% <55.00%> (-8.20%) ⬇️
x/participationrewards/keeper/hooks.go 69.59% <58.44%> (-9.14%) ⬇️

... and 11 files with indirect coverage changes

Copy link
Contributor

@joe-bowman joe-bowman left a comment

Choose a reason for hiding this comment

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

see comments.

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

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 892bcc2 and d487518.
Files selected for processing (1)
  • x/participationrewards/keeper/hooks.go (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • x/participationrewards/keeper/hooks.go

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

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between d487518 and 1322904.
Files selected for processing (1)
  • x/participationrewards/keeper/hooks.go (2 hunks)
Additional comments not posted (1)
x/participationrewards/keeper/hooks.go (1)

10-12: Imports for transfertypes and utils have been added as expected.

x/participationrewards/keeper/hooks.go Show resolved Hide resolved
x/participationrewards/keeper/hooks.go Show resolved Hide resolved
x/participationrewards/keeper/hooks.go Outdated Show resolved Hide resolved
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: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 1322904 and 8678e52.
Files selected for processing (1)
  • x/participationrewards/keeper/hooks.go (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • x/participationrewards/keeper/hooks.go

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

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 4bac743 and f9d1fae.
Files selected for processing (3)
  • x/participationrewards/keeper/hooks.go (2 hunks)
  • x/participationrewards/keeper/proposal_handler_test.go (2 hunks)
  • x/participationrewards/keeper/protocol_data.go (2 hunks)
Additional Context Used
GitHub Check Runs (1)
lint failure (2)

x/participationrewards/keeper/hooks.go: [failure] 233-233:
ineffectual assignment to err (ineffassign)

Comment on lines 113 to 139
ctx := suite.chainA.GetContext()
k := appA.ParticipationRewardsKeeper

// set the protocol data
pd := types.ConnectionProtocolData{
ConnectionID: suite.path.EndpointB.ConnectionID,
ChainID: suite.chainB.ChainID,
LastEpoch: 0,
Prefix: "cosmos",
}
keeper.MarshalAndSetProtocolData(ctx, k, types.ProtocolDataTypeConnection, &pd)

pdString, err := json.Marshal(pd)
suite.NoError(err)

ctx := suite.chainA.GetContext()

prop := types.ProtocolData{
Type: types.ProtocolDataType_name[int32(types.ProtocolDataTypeConnection)],
Data: pdString,
}

k := appA.ParticipationRewardsKeeper

k.SetProtocolData(ctx, pd.GenerateKey(), &prop)
// set the protocol data

// check if the protocol data is set
_, found := k.GetProtocolData(ctx, types.ProtocolDataTypeConnection, string(pd.GenerateKey()))
suite.True(found)

msgServer := keeper.NewMsgServerImpl(k)

// submit proposal

// submit proposal to remove the protocol data
proposalMsg := types.MsgGovRemoveProtocolData{
Title: "remove chain B connection string",
Description: "remove the protocol data",
Key: base64.StdEncoding.EncodeToString(pd.GenerateKey()),
Authority: k.GetGovAuthority(ctx),
}

_, err = msgServer.GovRemoveProtocolData(ctx, &proposalMsg)
_, err := msgServer.GovRemoveProtocolData(ctx, &proposalMsg)
Copy link
Contributor

@coderabbitai coderabbitai bot May 26, 2024

Choose a reason for hiding this comment

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

Tip

Codebase Verification

The test does not validate the cleanup of protocol data after removal. The second instance of GetProtocolData still checks for the presence of the protocol data instead of ensuring it has been removed.

  • Ensure that the test verifies the absence of protocol data after the removal proposal.
Analysis chain

Ensure proper cleanup and validation in TestHandleRemoveProtocolDataProposal.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the protocol data is properly cleaned up after removal.

# Test: Search for the function usage. Expect: No remaining protocol data after removal.
rg --type go $'GetProtocolData' x/participationrewards/keeper/proposal_handler_test.go

Length of output: 276



Script:

#!/bin/bash
# Extract lines around the second instance of GetProtocolData to verify cleanup validation.
rg --type go -A 5 -B 5 $'GetProtocolData' x/participationrewards/keeper/proposal_handler_test.go

Length of output: 654

Copy link
Contributor

Choose a reason for hiding this comment

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

I know this isn’t code you have changed but I think rabbit might be right here! Pd.generateKey() only generates the pd specific part of the key - I’m not sure if this is prefixed by the type in the delete function or we need to use the function in types to prefix this with the type

Copy link
Contributor

Choose a reason for hiding this comment

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

@joe-bowman, it appears that the GovRemoveProtocolData function is indeed responsible for removing protocol data, but the exact implementation details are not fully clear from the automated searches. Based on the context, it seems that pd.GenerateKey() only generates the protocol data specific part of the key, and it might need to be prefixed with the type.

To ensure proper cleanup and validation, we should verify that the key used in the GovRemoveProtocolData function includes the type prefix. Here is a potential update to the test to ensure the protocol data is properly removed:

func (suite *KeeperTestSuite) TestHandleRemoveProtocolDataProposal() {
    appA := suite.GetQuicksilverApp(suite.chainA)
    ctx := suite.chainA.GetContext()
    k := appA.ParticipationRewardsKeeper

    // set the protocol data
    pd := types.ConnectionProtocolData{
        ConnectionID: suite.path.EndpointB.ConnectionID,
        ChainID:      suite.chainB.ChainID,
        LastEpoch:    0,
        Prefix:       "cosmos",
    }
    keeper.MarshalAndSetProtocolData(ctx, k, types.ProtocolDataTypeConnection, &pd)

    // check if the protocol data is set
    _, found := k.GetProtocolData(ctx, types.ProtocolDataTypeConnection, string(pd.GenerateKey()))
    suite.True(found)

    msgServer := keeper.NewMsgServerImpl(k)

    // submit proposal to remove the protocol data
    proposalMsg := types.MsgGovRemoveProtocolData{
        Title:       "remove chain B connection string",
        Description: "remove the protocol data",
        Key:         base64.StdEncoding.EncodeToString([]byte(types.ProtocolDataTypeConnection + string(pd.GenerateKey()))),
        Authority:   k.GetGovAuthority(ctx),
    }

    _, err := msgServer.GovRemoveProtocolData(ctx, &proposalMsg)
    suite.NoError(err)

    // check if the protocol data is removed
    _, found = k.GetProtocolData(ctx, types.ProtocolDataTypeConnection, string(pd.GenerateKey()))
    suite.False(found)
}

This update ensures that the key used in the removal proposal includes the type prefix, and it verifies that the protocol data is properly removed.

Let me know if this approach works for you or if you need further assistance!

Analysis chain







Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for the implementation of the GenerateKey method in the types package.
ast-grep --lang go --pattern $'func ($_ $_) GenerateKey() $_' 

# Search for the implementation of the GovRemoveProtocolData function in the keeper package.
ast-grep --lang go --pattern $'func ($_ $_) GovRemoveProtocolData($_, $_) ($_ $_)' 

Length of output: 1461



Script:

#!/bin/bash
# Search for the implementation of the GovRemoveProtocolData function in the keeper package.
rg --type go 'func GovRemoveProtocolData' 

Length of output: 43



Script:

#!/bin/bash
# Search for the implementation of the GovRemoveProtocolData function using a broader pattern.
rg --type go 'GovRemoveProtocolData' 

Length of output: 11893



Script:

#!/bin/bash
# Extract the implementation of the GovRemoveProtocolData function from msg_server.go.
rg --type go -A 20 -B 5 'func (k msgServer) GovRemoveProtocolData' x/participationrewards/keeper/msg_server.go

Length of output: 112



Script:

#!/bin/bash
# Search for the implementation of the GovRemoveProtocolData function using a more flexible pattern.
rg --type go 'GovRemoveProtocolData' x/participationrewards/keeper/msg_server.go

Length of output: 396



Script:

#!/bin/bash
# Extract the complete implementation of the GovRemoveProtocolData function from msg_server.go.
rg --type go -A 20 -B 5 'func (k msgServer) GovRemoveProtocolData' x/participationrewards/keeper/msg_server.go

Length of output: 112



Script:

#!/bin/bash
# Search for the implementation of the GovRemoveProtocolData function using a broader pattern across the entire codebase.
rg --type go 'GovRemoveProtocolData'

Length of output: 11893



Script:

#!/bin/bash
# Extract the complete implementation of the GovRemoveProtocolData function from msg_server.go.
rg --type go -A 20 -B 5 'func (k msgServer) GovRemoveProtocolData' x/participationrewards/keeper/msg_server.go

Length of output: 112



Script:

#!/bin/bash
# Extract the complete implementation of the GovRemoveProtocolData function from msg_server.go.
rg --type go -A 20 -B 5 'func (k msgServer) GovRemoveProtocolData' x/participationrewards/keeper/msg_server.go

Length of output: 112

Comment on lines 96 to 124
func GetAndUnmarshalProtocolData[V types.ProtocolDataI](ctx sdk.Context, k *Keeper, datatype types.ProtocolDataType, key string) (V, error) {
var cpd V

data, found := k.GetProtocolData(ctx, datatype, key)
if !found {
return cpd, fmt.Errorf("protocol data not found for %s", key)
}

pd, err := types.UnmarshalProtocolData(datatype, data.Data)
if err != nil {
return cpd, err
}
v, ok := pd.(V)
if !ok {
return cpd, fmt.Errorf("unexpected type %T", pd)
}

return v, nil
}

func MarshalAndSetProtocolData(ctx sdk.Context, k *Keeper, datatype types.ProtocolDataType, pd types.ProtocolDataI) {
pdString, err := json.Marshal(pd)
if err != nil {
k.Logger(ctx).Error("Error marshalling protocol data", "error", err)
panic(err)
}
storedProtocolData := types.NewProtocolData(datatype.String(), pdString)
k.SetProtocolData(ctx, pd.GenerateKey(), storedProtocolData)
}
Copy link
Contributor

@coderabbitai coderabbitai bot May 26, 2024

Choose a reason for hiding this comment

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

Refactor GetAndUnmarshalProtocolData and MarshalAndSetProtocolData for better error handling and logging.

- panic(err)
+ k.Logger(ctx).Error("Error marshalling protocol data", "error", err)
+ 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.

Suggested change
func GetAndUnmarshalProtocolData[V types.ProtocolDataI](ctx sdk.Context, k *Keeper, datatype types.ProtocolDataType, key string) (V, error) {
var cpd V
data, found := k.GetProtocolData(ctx, datatype, key)
if !found {
return cpd, fmt.Errorf("protocol data not found for %s", key)
}
pd, err := types.UnmarshalProtocolData(datatype, data.Data)
if err != nil {
return cpd, err
}
v, ok := pd.(V)
if !ok {
return cpd, fmt.Errorf("unexpected type %T", pd)
}
return v, nil
}
func MarshalAndSetProtocolData(ctx sdk.Context, k *Keeper, datatype types.ProtocolDataType, pd types.ProtocolDataI) {
pdString, err := json.Marshal(pd)
if err != nil {
k.Logger(ctx).Error("Error marshalling protocol data", "error", err)
panic(err)
}
storedProtocolData := types.NewProtocolData(datatype.String(), pdString)
k.SetProtocolData(ctx, pd.GenerateKey(), storedProtocolData)
}
func GetAndUnmarshalProtocolData[V types.ProtocolDataI](ctx sdk.Context, k *Keeper, datatype types.ProtocolDataType, key string) (V, error) {
var cpd V
data, found := k.GetProtocolData(ctx, datatype, key)
if !found {
return cpd, fmt.Errorf("protocol data not found for %s", key)
}
pd, err := types.UnmarshalProtocolData(datatype, data.Data)
if err != nil {
return cpd, err
}
v, ok := pd.(V)
if !ok {
return cpd, fmt.Errorf("unexpected type %T", pd)
}
return v, nil
}
func MarshalAndSetProtocolData(ctx sdk.Context, k *Keeper, datatype types.ProtocolDataType, pd types.ProtocolDataI) error {
pdString, err := json.Marshal(pd)
if err != nil {
k.Logger(ctx).Error("Error marshalling protocol data", "error", err)
return err
}
storedProtocolData := types.NewProtocolData(datatype.String(), pdString)
k.SetProtocolData(ctx, pd.GenerateKey(), storedProtocolData)
return nil
}

Copy link
Contributor

Choose a reason for hiding this comment

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

If this is to Panic can we call it MustMarshalAndSet for consistency with other methods that can panic?

Copy link
Contributor

Choose a reason for hiding this comment

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

@joe-bowman Based on the search results, there are no existing methods in the codebase that follow the Must* naming convention. To maintain consistency, I recommend handling errors gracefully in the MarshalAndSetProtocolData function instead of introducing a new naming convention. Here is the updated function with improved error handling:

func MarshalAndSetProtocolData(ctx sdk.Context, k *Keeper, datatype types.ProtocolDataType, pd types.ProtocolDataI) error {
    pdString, err := json.Marshal(pd)
    if err != nil {
        k.Logger(ctx).Error("Error marshalling protocol data", "error", err)
        return err
    }
    storedProtocolData := types.NewProtocolData(datatype.String(), pdString)
    k.SetProtocolData(ctx, pd.GenerateKey(), storedProtocolData)
    return nil
}

This approach ensures that errors are logged and handled appropriately without causing a panic.

Analysis chain
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for methods with the `Must*` naming convention in the codebase.
ast-grep --lang go --pattern 'func Must$_($$$) $$$' 

Length of output: 53


New Learnings Added
User: joe-bowman
PR: quicksilver-zone/quicksilver#1620
File: x/participationrewards/keeper/protocol_data.go:96-124
Timestamp: 2024-05-28T09:25:45.589Z
Learning: There are no existing methods in the codebase that follow the `Must*` naming convention for functions that can panic.

Note: Learnings are effective only in the context of specific code segments. To apply general coding guidelines, please configure review instructions.

return false
}

umeeConnectionData, err := GetAndUnmarshalProtocolData[*types.ConnectionProtocolData](ctx, k, types.ProtocolDataTypeConnection, umeeParamsData.ChainID)
Copy link
Contributor

Choose a reason for hiding this comment

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

Address the ineffectual assignment to err in AfterZoneCreated.

- umeeConnectionData, err := GetAndUnmarshalProtocolData[*types.ConnectionProtocolData](ctx, k, types.ProtocolDataTypeConnection, umeeParamsData.ChainID)
+ umeeConnectionData, _ := GetAndUnmarshalProtocolData[*types.ConnectionProtocolData](ctx, k, types.ProtocolDataTypeConnection, umeeParamsData.ChainID)

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.

Suggested change
umeeConnectionData, err := GetAndUnmarshalProtocolData[*types.ConnectionProtocolData](ctx, k, types.ProtocolDataTypeConnection, umeeParamsData.ChainID)
umeeConnectionData, _ := GetAndUnmarshalProtocolData[*types.ConnectionProtocolData](ctx, k, types.ProtocolDataTypeConnection, umeeParamsData.ChainID)

Comment on lines +153 to +176
// channel for the host chain
channel, found := k.IBCKeeper.ChannelKeeper.GetChannel(ctx, "transfer", zone.TransferChannel)
if !found {
return fmt.Errorf("channel not found: %s", zone.TransferChannel)
}

// Create LiquidAllowedDenomProtocolData for the host zone
hostZoneDenom := types.LiquidAllowedDenomProtocolData{
ChainID: zone.ChainId,
RegisteredZoneChainID: zone.ChainId,
IbcDenom: utils.DeriveIbcDenom(transfertypes.PortID, channel.Counterparty.ChannelId, transfertypes.PortID, zone.TransferChannel, zone.LocalDenom),
QAssetDenom: zone.LocalDenom,
}
if err := hostZoneDenom.ValidateBasic(); err != nil {
return err
}
hostZoneDenomBytes, err := json.Marshal(hostZoneDenom)
if err != nil {
return err
}
k.SetProtocolData(ctx, hostZoneDenom.GenerateKey(), &types.ProtocolData{
Type: types.ProtocolDataType_name[int32(types.ProtocolDataTypeLiquidToken)],
Data: hostZoneDenomBytes,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai using the constant here is better than a hardcoded string, but arguably channel.PortId and counterpartychannel.PortId would be even more accurate

Copy link
Contributor

Choose a reason for hiding this comment

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

@joe-bowman, thank you for the suggestion. Using channel.PortId and counterpartychannel.PortId indeed makes the code more accurate and maintainable. Here is the updated code snippet:

// channel for the host chain
channel, found := k.IBCKeeper.ChannelKeeper.GetChannel(ctx, "transfer", zone.TransferChannel)
if (!found) {
    return fmt.Errorf("channel not found: %s", zone.TransferChannel)
}

// Create LiquidAllowedDenomProtocolData for the host zone
hostZoneDenom := types.LiquidAllowedDenomProtocolData{
    ChainID:               zone.ChainId,
    RegisteredZoneChainID: zone.ChainId,
    IbcDenom:              utils.DeriveIbcDenom(channel.PortId, channel.Counterparty.ChannelId, channel.PortId, zone.TransferChannel, zone.LocalDenom),
    QAssetDenom:           zone.LocalDenom,
}
if err := hostZoneDenom.ValidateBasic(); err != nil {
    return err
}
hostZoneDenomBytes, err := json.Marshal(hostZoneDenom)
if err != nil {
    return err
}
k.SetProtocolData(ctx, hostZoneDenom.GenerateKey(), &types.ProtocolData{
    Type: types.ProtocolDataType_name[int32(types.ProtocolDataTypeLiquidToken)],
    Data: hostZoneDenomBytes,
})

This change ensures that the port IDs are dynamically retrieved from the channel object, enhancing the accuracy of the IBC denom computation.


New Learnings Added
User: joe-bowman
PR: quicksilver-zone/quicksilver#1620
File: x/participationrewards/keeper/hooks.go:153-176
Timestamp: 2024-05-28T09:18:57.893Z
Learning: When computing IBC denoms, use `channel.PortId` and `counterpartychannel.PortId` instead of hardcoded strings for better accuracy.

Note: Learnings are effective only in the context of specific code segments. To apply general coding guidelines, please configure review instructions.

Comment on lines +153 to +176
// channel for the host chain
channel, found := k.IBCKeeper.ChannelKeeper.GetChannel(ctx, "transfer", zone.TransferChannel)
if !found {
return fmt.Errorf("channel not found: %s", zone.TransferChannel)
}

// Create LiquidAllowedDenomProtocolData for the host zone
hostZoneDenom := types.LiquidAllowedDenomProtocolData{
ChainID: zone.ChainId,
RegisteredZoneChainID: zone.ChainId,
IbcDenom: utils.DeriveIbcDenom(transfertypes.PortID, channel.Counterparty.ChannelId, transfertypes.PortID, zone.TransferChannel, zone.LocalDenom),
QAssetDenom: zone.LocalDenom,
}
if err := hostZoneDenom.ValidateBasic(); err != nil {
return err
}
hostZoneDenomBytes, err := json.Marshal(hostZoneDenom)
if err != nil {
return err
}
k.SetProtocolData(ctx, hostZoneDenom.GenerateKey(), &types.ProtocolData{
Type: types.ProtocolDataType_name[int32(types.ProtocolDataTypeLiquidToken)],
Data: hostZoneDenomBytes,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai using the constant here is better than a hardcoded string, but arguably channel.PortId and counterpartychannel.PortId would be even more accurate

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between f9d1fae and de08b51.

Files selected for processing (3)
  • x/participationrewards/keeper/hooks.go (2 hunks)
  • x/participationrewards/keeper/proposal_handler_test.go (2 hunks)
  • x/participationrewards/keeper/protocol_data.go (2 hunks)
Files skipped from review as they are similar to previous changes (3)
  • x/participationrewards/keeper/hooks.go
  • x/participationrewards/keeper/proposal_handler_test.go
  • x/participationrewards/keeper/protocol_data.go

@tropicaldog
Copy link
Contributor Author

Sorry for the delay, I've fixed locally but forgot to commit the change @joe-bowman. Could you please kindly review so we can get this merged quick.

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

Outside diff range and nitpick comments (1)
x/participationrewards/keeper/keeper_test.go (1)

Line range hint 434-492: Consider adding inline documentation to explain the purpose and structure of the protocol data being set up in the setupTestProtocolData function.

+ // setupTestProtocolData initializes protocol data required for testing various IBC and chain interactions.
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between de08b51 and 3c1259c.

Files selected for processing (3)
  • x/participationrewards/keeper/hooks.go (2 hunks)
  • x/participationrewards/keeper/hooks_test.go (3 hunks)
  • x/participationrewards/keeper/keeper_test.go (5 hunks)
Files not reviewed due to errors (1)
  • x/participationrewards/keeper/hooks_test.go (no review received)
Additional context used
Learnings (1)
x/participationrewards/keeper/hooks.go (1)
User: joe-bowman
PR: quicksilver-zone/quicksilver#1620
File: x/participationrewards/keeper/hooks.go:153-176
Timestamp: 2024-05-28T09:18:57.893Z
Learning: When computing IBC denoms, use `channel.PortId` and `counterpartychannel.PortId` instead of hardcoded strings for better accuracy.
GitHub Check: lint
x/participationrewards/keeper/keeper_test.go

[failure] 39-39:
var osmosisBaseDenom is unused (unused)

Additional comments not posted (2)
x/participationrewards/keeper/hooks.go (1)

179-264: The methods for fetching and setting up Osmosis and Umee zones are well-implemented. However, ensure that the error handling is robust and that any failures in fetching the channel or unmarshalling data do not lead to silent failures but are logged appropriately for easier debugging and maintenance.

x/participationrewards/keeper/keeper_test.go (1)

417-431: Please add inline comments to explain the purpose of each channel setup as previously suggested.

Comment on lines +154 to +177
// channel for the host chain
channel, found := k.IBCKeeper.ChannelKeeper.GetChannel(ctx, "transfer", zone.TransferChannel)
if !found {
return fmt.Errorf("channel not found: %s", zone.TransferChannel)
}

// Create LiquidAllowedDenomProtocolData for the host zone
hostZoneDenom := types.LiquidAllowedDenomProtocolData{
ChainID: zone.ChainId,
RegisteredZoneChainID: zone.ChainId,
IbcDenom: utils.DeriveIbcDenom(transfertypes.PortID, channel.Counterparty.ChannelId, transfertypes.PortID, zone.TransferChannel, zone.LocalDenom),
QAssetDenom: zone.LocalDenom,
}
if err := hostZoneDenom.ValidateBasic(); err != nil {
return err
}
hostZoneDenomBytes, err := json.Marshal(hostZoneDenom)
if err != nil {
return err
}
k.SetProtocolData(ctx, hostZoneDenom.GenerateKey(), &types.ProtocolData{
Type: types.ProtocolDataType_name[int32(types.ProtocolDataTypeLiquidToken)],
Data: hostZoneDenomBytes,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

The implementation of the IBC denomination handling for the host zone is critical. However, as per the learning retrieved, using channel.PortId and counterpartychannel.PortId instead of hardcoded strings would enhance accuracy. This change should be implemented to align with the best practices discussed.

- utils.DeriveIbcDenom(transfertypes.PortID, channel.Counterparty.ChannelId, transfertypes.PortID, zone.TransferChannel, zone.LocalDenom)
+ utils.DeriveIbcDenom(channel.PortId, channel.Counterparty.ChannelId, channel.PortId, zone.TransferChannel, zone.LocalDenom)
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
// channel for the host chain
channel, found := k.IBCKeeper.ChannelKeeper.GetChannel(ctx, "transfer", zone.TransferChannel)
if !found {
return fmt.Errorf("channel not found: %s", zone.TransferChannel)
}
// Create LiquidAllowedDenomProtocolData for the host zone
hostZoneDenom := types.LiquidAllowedDenomProtocolData{
ChainID: zone.ChainId,
RegisteredZoneChainID: zone.ChainId,
IbcDenom: utils.DeriveIbcDenom(transfertypes.PortID, channel.Counterparty.ChannelId, transfertypes.PortID, zone.TransferChannel, zone.LocalDenom),
QAssetDenom: zone.LocalDenom,
}
if err := hostZoneDenom.ValidateBasic(); err != nil {
return err
}
hostZoneDenomBytes, err := json.Marshal(hostZoneDenom)
if err != nil {
return err
}
k.SetProtocolData(ctx, hostZoneDenom.GenerateKey(), &types.ProtocolData{
Type: types.ProtocolDataType_name[int32(types.ProtocolDataTypeLiquidToken)],
Data: hostZoneDenomBytes,
})
// channel for the host chain
channel, found := k.IBCKeeper.ChannelKeeper.GetChannel(ctx, "transfer", zone.TransferChannel)
if !found {
return fmt.Errorf("channel not found: %s", zone.TransferChannel)
}
// Create LiquidAllowedDenomProtocolData for the host zone
hostZoneDenom := types.LiquidAllowedDenomProtocolData{
ChainID: zone.ChainId,
RegisteredZoneChainID: zone.ChainId,
IbcDenom: utils.DeriveIbcDenom(channel.PortId, channel.Counterparty.ChannelId, channel.PortId, zone.TransferChannel, zone.LocalDenom),
QAssetDenom: zone.LocalDenom,
}
if err := hostZoneDenom.ValidateBasic(); err != nil {
return err
}
hostZoneDenomBytes, err := json.Marshal(hostZoneDenom)
if err != nil {
return err
}
k.SetProtocolData(ctx, hostZoneDenom.GenerateKey(), &types.ProtocolData{
Type: types.ProtocolDataType_name[int32(types.ProtocolDataTypeLiquidToken)],
Data: hostZoneDenomBytes,
})

@@ -35,10 +35,19 @@
umeeTestChain = "umee-types-1"
umeeBaseDenom = "uumee"

osmosisTestChain = "osmosis-1"
osmosisBaseDenom = "uosmo"
Copy link
Contributor

Choose a reason for hiding this comment

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

The variable osmosisBaseDenom is declared but unused. Consider removing it or using it where appropriate.

Tools
GitHub Check: lint

[failure] 39-39:
var osmosisBaseDenom is unused (unused)

Comment on lines +417 to +431
func (suite *KeeperTestSuite) setupChannelForHookTest() {
quicksilver := suite.GetQuicksilverApp(suite.chainA)

// create a channel for the host chain, channel-1 <-> channel-500
quicksilver.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), ibctesting.TransferPort, "channel-1", channeltypes.Channel{State: channeltypes.OPEN, Ordering: channeltypes.ORDERED, Counterparty: channeltypes.Counterparty{PortId: ibctesting.TransferPort, ChannelId: counterpartyTestzoneChannel}, ConnectionHops: []string{suite.path.EndpointA.ConnectionID}})

// create a channel for the osmosis chain, channel-2 <-> channel-1000
quicksilver.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), ibctesting.TransferPort, "channel-2", channeltypes.Channel{State: channeltypes.OPEN, Ordering: channeltypes.ORDERED, Counterparty: channeltypes.Counterparty{PortId: ibctesting.TransferPort, ChannelId: counterpartyOsmosisChannel}, ConnectionHops: []string{suite.path.EndpointA.ConnectionID}})

// create a channel channel-3 <-> channel-1500
quicksilver.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), ibctesting.TransferPort, "channel-3", channeltypes.Channel{State: channeltypes.OPEN, Ordering: channeltypes.ORDERED, Counterparty: channeltypes.Counterparty{PortId: ibctesting.TransferPort, ChannelId: "channel-1500"}, ConnectionHops: []string{suite.path.EndpointA.ConnectionID}})

// create a channel for the umee-types chain, channel-5 <-> channel-2000
quicksilver.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), ibctesting.TransferPort, "channel-5", channeltypes.Channel{State: channeltypes.OPEN, Ordering: channeltypes.ORDERED, Counterparty: channeltypes.Counterparty{PortId: ibctesting.TransferPort, ChannelId: counterpartyUmeeChannel}, ConnectionHops: []string{suite.path.EndpointA.ConnectionID}})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider parameterizing the channel IDs and connection hops to enhance flexibility and reusability of the setupChannelForHookTest function.

- quicksilver.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), ibctesting.TransferPort, "channel-1", channeltypes.Channel{State: channeltypes.OPEN, Ordering: channeltypes.ORDERED, Counterparty: channeltypes.Counterparty{PortId: ibctesting.TransferPort, ChannelId: counterpartyTestzoneChannel}, ConnectionHops: []string{suite.path.EndpointA.ConnectionID}})
+ // Example of parameterized channel setup
+ func (suite *KeeperTestSuite) setupChannel(portId, channelId string, counterpartyPortId, counterpartyChannelId string, connectionHops []string) {
+     quicksilver.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), portId, channelId, channeltypes.Channel{State: channeltypes.OPEN, Ordering: channeltypes.ORDERED, Counterparty: channeltypes.Counterparty{PortId: counterpartyPortId, ChannelId: counterpartyChannelId}, ConnectionHops: connectionHops})
+ }

Committable suggestion was skipped due to low confidence.

Comment on lines +45 to +49
var (
counterpartyUmeeChannel = "channel-2000"
counterpartyOsmosisChannel = "channel-1000"
counterpartyTestzoneChannel = "channel-500"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Add documentation for the new global variables counterpartyUmeeChannel, counterpartyOsmosisChannel, and counterpartyTestzoneChannel.

+ // counterpartyUmeeChannel represents the channel ID for communication with the Umee chain.
+ // counterpartyOsmosisChannel represents the channel ID for communication with the Osmosis chain.
+ // counterpartyTestzoneChannel represents the channel ID for communication with the Testzone chain.
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
var (
counterpartyUmeeChannel = "channel-2000"
counterpartyOsmosisChannel = "channel-1000"
counterpartyTestzoneChannel = "channel-500"
)
var (
// counterpartyUmeeChannel represents the channel ID for communication with the Umee chain.
counterpartyUmeeChannel = "channel-2000"
// counterpartyOsmosisChannel represents the channel ID for communication with the Osmosis chain.
counterpartyOsmosisChannel = "channel-1000"
// counterpartyTestzoneChannel represents the channel ID for communication with the Testzone chain.
counterpartyTestzoneChannel = "channel-500"
)

@joe-bowman
Copy link
Contributor

This pull request has been automatically marked as stale because it has not had any recent activity. It will be closed if no further activity occurs. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Auto register ibc denoms for host zone and osmosis on zone registration
3 participants