-
Notifications
You must be signed in to change notification settings - Fork 57
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
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe recent updates introduce new protocols for handling Changes
Assessment against linked issues
Poem
Tip Early access features: enabledWe are currently testing the following features in early access:
Note:
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? TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Additionally, you can add CodeRabbit Configration File (
|
@joe-bowman could you give a quick look at my implementation? I will add some tests for the hook after getting your review, ty. |
There was a problem hiding this 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
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 inTestAfterZoneCreated
are correctly implemented.
33-42
: Host chain checks inTestAfterZoneCreated
are correctly implemented.x/participationrewards/keeper/hooks.go (3)
9-11
: The addition of new imports fortransfertypes
andutils
is justified as they are used in the new functionality.
152-169
: Creation and handling ofLiquidAllowedDenomProtocolData
for the host zone are correctly implemented.
171-209
: Handling ofOsmosisParamsProtocolData
andUmeeParamsProtocolData
, 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 |
There was a problem hiding this comment.
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?
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comments.
There was a problem hiding this 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
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
There was a problem hiding this 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
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 fortransfertypes
andutils
have been added as expected.
…zone/quicksilver into tuan/auto-register-hostzone
There was a problem hiding this 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
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
There was a problem hiding this 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
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)
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
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) | ||
} |
There was a problem hiding this comment.
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.
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 | |
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
umeeConnectionData, err := GetAndUnmarshalProtocolData[*types.ConnectionProtocolData](ctx, k, types.ProtocolDataTypeConnection, umeeParamsData.ChainID) | |
umeeConnectionData, _ := GetAndUnmarshalProtocolData[*types.ConnectionProtocolData](ctx, k, types.ProtocolDataTypeConnection, umeeParamsData.ChainID) |
// 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, | ||
}) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
// 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, | ||
}) |
There was a problem hiding this comment.
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
There was a problem hiding this 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
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
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. |
There was a problem hiding this 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 thesetupTestProtocolData
function.+ // setupTestProtocolData initializes protocol data required for testing various IBC and chain interactions.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
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:
varosmosisBaseDenom
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.
// 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, | ||
}) |
There was a problem hiding this comment.
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.
// 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" |
There was a problem hiding this comment.
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:
varosmosisBaseDenom
is unused (unused)
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}}) | ||
} |
There was a problem hiding this comment.
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.
var ( | ||
counterpartyUmeeChannel = "channel-2000" | ||
counterpartyOsmosisChannel = "channel-1000" | ||
counterpartyTestzoneChannel = "channel-500" | ||
) |
There was a problem hiding this comment.
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.
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" | |
) |
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! |
1. Summary
Closes #1458
Partially addresses #1631
2.Type of change
3. Implementation details
4. How to test/use
5. Checklist
6. Limitations (optional)
7. Future Work (optional)
Summary by CodeRabbit
New Features
Tests
Refactor
Bug Fixes