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(x/protocolpool)!: allow any coins in continuous funds #21916

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

Conversation

facundomedica
Copy link
Member

@facundomedica facundomedica commented Sep 25, 2024

Description

Previously only the bond denom could be used for continuous funds, now we allow any token. We might want to add a param with a whitelist of tokens to avoid spam.


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

Please see Pull Request Reviewer section in the contributing guide for more information on how to review a pull request.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

Summary by CodeRabbit

  • New Features

    • Introduced a new DistributionAmount structure for handling multiple coins.
    • Updated response messages to support multiple coin values for fund withdrawals and cancellations.
  • Improvements

    • Enhanced the handling of LastBalance and Amount fields to utilize structured types instead of primitive strings.
    • Improved validation logic for fund distributions to ensure robustness.
  • Bug Fixes

    • Adjusted tests to reflect changes in data types and ensure accurate comparisons.
  • Chores

    • Removed references to the StakingKeeper interface and its mock implementations, streamlining the codebase.

Copy link
Contributor

coderabbitai bot commented Sep 25, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes involve significant updates to the cosmos.protocolpool.v1 package, primarily focusing on the data structures used for handling balances and distributions. Key modifications include transitioning from primitive types like string and math.Int to more complex structures such as DistributionAmount, which allows for better representation of multiple coin types. Additionally, several methods and message definitions have been updated to accommodate these new structures, enhancing the overall functionality and flexibility of the protocol's financial handling.

Changes

File(s) Change Summary
api/cosmos/protocolpool/v1/genesis.pulsar.go, api/cosmos/protocolpool/v1/types.pulsar.go Updated GenesisState and Distribution structures to use DistributionAmount instead of string for balance fields, affecting multiple methods for handling these fields as messages.
api/cosmos/protocolpool/v1/tx.pulsar.go Modified MsgCancelContinuousFundResponse and MsgWithdrawContinuousFundResponse to change fund fields from single coins to slices of coins, enhancing the ability to represent multiple coin values.
x/protocolpool/depinject.go, x/protocolpool/keeper/genesis.go, x/protocolpool/keeper/keeper.go Removed StakingKeeper dependencies, updated fund distribution logic to utilize DistributionAmount, and adjusted methods accordingly to reflect changes in how balances and distributions are managed.
x/protocolpool/keeper/genesis_test.go, x/protocolpool/keeper/keeper_test.go, x/protocolpool/keeper/msg_server_test.go Updated tests to reflect changes in data types from math.Int and sdk.Coin to DistributionAmount and sdk.Coins, ensuring consistency with new structures in the main code.
x/protocolpool/proto/cosmos/protocolpool/v1/genesis.proto, x/protocolpool/proto/cosmos/protocolpool/v1/tx.proto, x/protocolpool/proto/cosmos/protocolpool/v1/types.proto Modified proto files to replace primitive types with DistributionAmount for financial fields, allowing for more complex data representation.
x/protocolpool/testutil/expected_keepers_mocks.go, x/protocolpool/types/expected_keepers.go Removed mock implementations for StakingKeeper and its interface, indicating a decoupling from staking-related functionalities.

Possibly related PRs

Suggested labels

C:x/mint, backport/v0.52.x

Suggested reviewers

  • julienrbrt
  • akhilkumarpilli
  • lucaslopezf
  • kocubinski
  • sontrinh16
  • testinginprod

📜 Recent review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 03b6445 and 6ac84b6.

📒 Files selected for processing (3)
  • simapp/app.go (1 hunks)
  • tests/integration/distribution/keeper/msg_server_test.go (1 hunks)
  • tests/integration/gov/keeper/keeper_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
simapp/app.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

tests/integration/distribution/keeper/msg_server_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

tests/integration/gov/keeper/keeper_test.go (3)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern tests/**/*: "Assess the integration and e2e test code assessing sufficient code coverage for the changes associated in the pull request"


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

🔇 Additional comments (10)
tests/integration/gov/keeper/keeper_test.go (1)

122-122: Verify the impact of removing stakingKeeper from poolKeeper instantiation

The removal of stakingKeeper from the poolkeeper.NewKeeper function call aligns with the PR objective of allowing any coins in continuous funds. This change decouples the pool keeper from staking-specific functionality, which is likely intentional.

However, please ensure that:

  1. This change doesn't break any existing functionality that might have depended on the interaction between the pool keeper and staking keeper.
  2. The tests in this file still provide adequate coverage for all scenarios, especially those that might have involved staking-related operations.
  3. Any documentation or comments related to the poolkeeper.NewKeeper function are updated to reflect this change.

To confirm that this change doesn't negatively impact other parts of the codebase, please run the following script:

If this search returns any results, those areas might need to be updated as well.

simapp/app.go (1)

380-380: LGTM. Verify PoolKeeper functionality and update documentation.

The removal of app.StakingKeeper from the poolkeeper.NewKeeper initialization aligns with the PR objective of allowing any coins in continuous funds. This change decouples the protocol pool from the staking module, increasing flexibility.

Please ensure that:

  1. The PoolKeeper's functionality is not negatively impacted by this change.
  2. All relevant documentation is updated to reflect this architectural change.
  3. Unit and integration tests are updated or added to cover the new behavior.

Run the following script to check for any remaining references to StakingKeeper in the PoolKeeper:

tests/integration/distribution/keeper/msg_server_test.go (8)

Line range hint 449-627: Verify TestMsgWithdrawDelegatorReward still passes

Although there are no direct changes to this function, the removal of stakingKeeper from poolKeeper initialization might affect this test indirectly.

Please ensure that this test still passes with the new changes. Run the following command to execute this specific test:

#!/bin/bash
# Description: Run TestMsgWithdrawDelegatorReward

# Test: Execute TestMsgWithdrawDelegatorReward
go test -v -run TestMsgWithdrawDelegatorReward ./x/distribution/keeper/...

Line range hint 756-885: Carefully verify TestMsgWithdrawValidatorCommission

This function interacts with validator commissions, which might be indirectly affected by the removal of stakingKeeper from poolKeeper.

Please run this test and pay special attention to parts related to validator operations:

#!/bin/bash
# Description: Run TestMsgWithdrawValidatorCommission and check for validator-related operations

# Test: Execute TestMsgWithdrawValidatorCommission
go test -v -run TestMsgWithdrawValidatorCommission ./x/distribution/keeper/...

# Check for validator-related operations in poolKeeper
rg --type go 'validator|commission' -C 5 $(fd -t f 'pool_keeper\.go')

Line range hint 887-981: Verify community pool operations in TestMsgFundCommunityPool

This function deals with the community pool, which is now managed by the poolKeeper. The removal of stakingKeeper might affect how funds are managed.

Please run this test and verify that community pool operations are still functioning correctly:

#!/bin/bash
# Description: Run TestMsgFundCommunityPool and check community pool operations

# Test: Execute TestMsgFundCommunityPool
go test -v -run TestMsgFundCommunityPool ./x/distribution/keeper/...

# Check for community pool operations in poolKeeper
rg --type go 'CommunityPool|FundCommunityPool' -C 5 $(fd -t f 'pool_keeper\.go')

Line range hint 983-1134: Verify parameter handling in TestMsgUpdateParams

Although this function shouldn't be directly affected by the poolKeeper changes, it's important to ensure that all parameters are still properly handled.

Please run this test and verify that all parameters are correctly updated and retrieved:

#!/bin/bash
# Description: Run TestMsgUpdateParams and check parameter handling

# Test: Execute TestMsgUpdateParams
go test -v -run TestMsgUpdateParams ./x/distribution/keeper/...

# Check for parameter handling in poolKeeper
rg --type go 'Params|GetParams|SetParams' -C 5 $(fd -t f 'pool_keeper\.go')

Line range hint 1136-1207: Carefully verify community pool spend operations in TestMsgCommunityPoolSpend

This function deals with spending from the community pool, which is now managed by the poolKeeper. The removal of stakingKeeper might affect how these operations are handled.

Please run this test and pay special attention to the community pool spend operations:

#!/bin/bash
# Description: Run TestMsgCommunityPoolSpend and check community pool spend operations

# Test: Execute TestMsgCommunityPoolSpend
go test -v -run TestMsgCommunityPoolSpend ./x/distribution/keeper/...

# Check for community pool spend operations in poolKeeper
rg --type go 'CommunityPoolSpend|SpendCommunityPool' -C 5 $(fd -t f 'pool_keeper\.go')

Line range hint 1-1409: Comprehensive verification needed for distribution module tests

The main change in this file is the removal of stakingKeeper from poolKeeper initialization. While individual tests haven't been modified, this change could significantly affect how staking-related operations are handled in the distribution module.

To ensure the integrity of the distribution module after these changes, please run the entire test suite for the distribution module and closely monitor any failures or unexpected behaviors:

#!/bin/bash
# Description: Run all distribution module tests and check for any failures

# Test: Execute all distribution module tests
go test -v ./x/distribution/...

# Check for any test failures
go test -v ./x/distribution/... 2>&1 | grep -E "FAIL:|panic:"

Additionally, consider adding new tests or modifying existing ones to specifically target the interaction between poolKeeper and staking-related functionality to ensure everything works as expected after removing stakingKeeper from poolKeeper initialization.


Line range hint 629-754: Verify TestMsgSetWithdrawAddress still passes

Although this function doesn't seem to be directly affected by the poolKeeper changes, it's good practice to ensure it still works as expected.

Please run this specific test to confirm it still passes:

✅ Verification successful

Verify TestMsgSetWithdrawAddress still passes

Based on the analysis of the TestMsgSetWithdrawAddress function in both the unit tests and integration tests, it appears that this test is not directly affected by the poolKeeper changes. The test focuses on address validation and the WithdrawAddrEnabled parameter, which are not related to the community pool functionality handled by the poolKeeper.

While we cannot run the test directly, the code inspection suggests that TestMsgSetWithdrawAddress should continue to pass after the poolKeeper changes, as long as the basic functionality of the distribution module remains intact.

However, to ensure complete confidence in the system's integrity, it would be advisable for the development team to run the full test suite, including this test, in their local or CI environment.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Run TestMsgSetWithdrawAddress

# Test: Execute TestMsgSetWithdrawAddress
go test -v -run TestMsgSetWithdrawAddress ./x/distribution/keeper/...

Length of output: 345860


Script:

#!/bin/bash
# Search for TestMsgSetWithdrawAddress function
rg "func TestMsgSetWithdrawAddress" --type go

# Look for poolKeeper references in the same file or nearby
rg "poolKeeper" -C 10 $(rg "func TestMsgSetWithdrawAddress" --type go -l)

# Display the content of the TestMsgSetWithdrawAddress function
rg "func TestMsgSetWithdrawAddress" -A 50 --type go

Length of output: 15624


141-141: Verify impact of removing stakingKeeper from poolKeeper initialization

The stakingKeeper parameter has been removed from the poolkeeper.NewKeeper call. This change might affect how the poolKeeper interacts with staking-related functionality.

Please ensure that this change doesn't break any existing tests or functionality. Run the following script to check for any remaining references to stakingKeeper within the poolKeeper:

✅ Verification successful

Removal of stakingKeeper from poolKeeper initialization is verified and safe

The removal of stakingKeeper from the poolkeeper.NewKeeper call has been verified as safe and intentional. Our analysis shows:

  • No references to stakingKeeper remain in the pool module.
  • Staking-related functionality is properly contained within the x/staking module.
  • This change likely improves modularity and separation of concerns in the codebase.

The modification appears to be part of a deliberate effort to reduce coupling between the pool and staking modules.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to stakingKeeper within poolKeeper

# Test: Search for stakingKeeper usage in poolKeeper
rg --type go 'stakingKeeper' -C 5 $(fd -t f 'pool_keeper\.go')

Length of output: 345860


Script:

#!/bin/bash
# Search for any staking-related functions or methods within the pool module
rg --type go 'func.*Staking|func.*Stake|func.*Unbond|func.*Delegate' $(fd -t f '.*\.go' x/pool)

Length of output: 138142


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

x.Amount = *clv.list
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.DistributionAmount"))

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.DistributionAmount"))
}
panic(fmt.Errorf("message cosmos.protocolpool.v1.DistributionAmount does not contain field %s", fd.FullName()))

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
@facundomedica facundomedica marked this pull request as ready for review September 25, 2024 23:55
Copy link
Contributor

@facundomedica your pull request is missing a changelog!

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

🧹 Outside diff range and nitpick comments (16)
x/protocolpool/keeper/genesis_test.go (3)

35-35: LGTM! Consider adding a constant for the coin denom.

The change to use DistributionAmount with sdk.NewCoins aligns well with the PR objective of allowing any coins in continuous funds. This provides more flexibility in representing different coin types.

Consider defining a constant for the "stake" denom at the package level to improve maintainability:

const testDenom = "stake"

Then use it in the test:

Amount: types.DistributionAmount{Amount: sdk.NewCoins(sdk.NewCoin(testDenom, math.NewInt(100)))},

43-43: LGTM! Consider using a variable for consistency.

The change to use DistributionAmount for LastBalance is consistent with the previous change and aligns with the PR objectives.

For better consistency and to make the relationship between the distributed amount and last balance clearer, consider using a variable:

distributionAmount := math.NewInt(100)
lastBalanceAmount := math.NewInt(1)

gs.Distributions = append(gs.Distributions, &types.Distribution{
    Amount: types.DistributionAmount{Amount: sdk.NewCoins(sdk.NewCoin(testDenom, distributionAmount))},
    Time:   &time.Time{},
})

gs.LastBalance = types.DistributionAmount{Amount: sdk.NewCoins(sdk.NewCoin(testDenom, lastBalanceAmount))}

This makes it easier to adjust the test scenario and clearly shows that the last balance is less than the distribution amount.


52-52: LGTM! Consider using a variable for the expected amount.

The updated assertion correctly checks the specific coin amount in the new LastBalance structure.

To improve clarity and maintain consistency with the earlier suggestions, consider using a variable for the expected amount:

expectedLastBalance := math.OneInt()
suite.Require().Equal(expectedLastBalance, exportedGenState.LastBalance.Amount.AmountOf(testDenom))

This makes the expected value more explicit and easier to update if needed.

x/protocolpool/types/genesis.go (1)

Line range hint 1-78: Overall assessment: Changes look good, but ensure comprehensive testing.

The modifications to the NewGenesisState function, particularly the LastBalance field initialization, are consistent with the PR objectives of allowing any coins in continuous funds. The changes adhere to Golang coding standards and the Uber Golang style guide.

However, given that this change affects a fundamental structure (GenesisState), it's crucial to:

  1. Thoroughly test the impact of this change on all components that interact with GenesisState.
  2. Update any relevant documentation to reflect the new LastBalance type and initialization.
  3. Consider adding or updating unit tests to cover the new LastBalance behavior.

Consider adding a comment above the NewGenesisState function explaining the rationale behind initializing LastBalance with an empty set of coins, as this might not be immediately obvious to other developers.

x/protocolpool/proto/cosmos/protocolpool/v1/types.proto (1)

46-54: LGTM: New DistributionAmount message added with appropriate options.

The new DistributionAmount message is well-structured and aligns with the PR objective of allowing any coins in continuous funds. The use of repeated cosmos.base.v1beta1.Coin with appropriate Gogoproto and Amino options ensures compatibility and consistent behavior.

Consider adding a brief comment above the amount field to describe its purpose and any constraints (e.g., "Stores multiple coin types for distribution. Must not be empty."). This would enhance the self-documentation of the proto file.

 message DistributionAmount {
+  // Stores multiple coin types for distribution. Must not be empty.
   repeated cosmos.base.v1beta1.Coin amount = 1 [
     (gogoproto.nullable)     = false,
     (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
     (amino.dont_omitempty)   = true,
     (amino.encoding)         = "legacy_coins"
   ];
 }
x/protocolpool/keeper/msg_server.go (1)

160-162: LGTM with a minor suggestion for clarity.

The initialization of RecipientFundDistribution with an empty coin set is correct and aligns with the new flexibility to handle multiple coin types. This change supports the PR objective of allowing any coins in continuous funds.

For improved clarity and consistency with Go conventions, consider using a composite literal directly:

err = k.RecipientFundDistribution.Set(ctx, recipient, types.DistributionAmount{Amount: sdk.Coins{}})

This minor change eliminates the need for the NewCoins() function call while achieving the same result.

x/protocolpool/keeper/keeper_test.go (2)

143-150: LGTM: Updated type handling in TestIterateAndUpdateFundsDistribution

The changes correctly reflect the transition from math.Int to types.DistributionAmount. The test logic has been appropriately updated to check the Amount field of the new type.

Consider adding a test case for a DistributionAmount with multiple coins to ensure the new type is fully exercised.


211-220: LGTM: Updated type handling in TestSetToDistribute

The changes correctly reflect the transition to using DistributionAmount. The test logic has been appropriately updated to check the Amount field of the new type.

Consider adding a test case with multiple coins in the DistributionAmount to ensure the new type is fully tested.

x/protocolpool/keeper/genesis.go (2)

58-58: Consider renaming fields for clarity

In lines 58 and 60, the code references distribution.Amount.Amount, which can be confusing due to the repeated use of Amount. To improve readability and maintainability, consider renaming one of the Amount fields in the DistributionAmount struct. For example, you could rename the inner Amount field to Coins, resulting in distribution.Amount.Coins.

Apply this diff to rename the field:

-type DistributionAmount struct {
-    Amount sdk.Coins
-}
+type DistributionAmount struct {
+    Coins sdk.Coins
+}

This change will require updating all usages of distribution.Amount.Amount to distribution.Amount.Coins.

Also applies to: 60-60


Line range hint 121-127: Avoid variable shadowing of the err variable in the closure

In the anonymous function passed to k.Distributions.Walk, the named return parameter err error shadows the err variable in the outer scope. This can lead to confusion and potential errors. According to the Uber Go Style Guide, it's recommended to avoid shadowing variables.

Consider removing the named return parameters or renaming them to prevent shadowing.

Apply this diff:

-err = k.Distributions.Walk(ctx, nil, func(key time.Time, value types.DistributionAmount) (stop bool, err error) {
+err = k.Distributions.Walk(ctx, nil, func(key time.Time, value types.DistributionAmount) (stop bool, walkErr error) {

Since the err variable is not used inside the function body, you could also omit the named return parameter:

-err = k.Distributions.Walk(ctx, nil, func(key time.Time, value types.DistributionAmount) (stop bool, err error) {
+err = k.Distributions.Walk(ctx, nil, func(key time.Time, value types.DistributionAmount) (bool, error) {

This avoids shadowing the outer err variable and improves code clarity.

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

153-154: Address the TODO comment regarding allowed denominations

There is a TODO comment indicating the need to handle cases where the balance does not contain any of the allowed denominations. Please implement this logic to ensure proper functioning and prevent potential issues with unsupported denominations.

Would you like assistance in implementing this check? I can help draft the necessary code or open a GitHub issue to track this task.

x/protocolpool/keeper/msg_server_test.go (2)

486-488: Redundant Setting of Zero Distribution Amounts

In lines 486-488, both RecipientFundDistribution and Distributions are set to sdk.NewCoins(), which represents an empty coin set. Since these are default zero values, consider removing these explicit initializations to reduce redundancy.


Line range hint 832-847: Optimize Redundant Initializations in Test Setup

In lines 832-847, RecipientFundDistribution is set to sdk.NewCoins() for multiple recipients during test setup. Since the distributions default to empty, these explicit initializations might be unnecessary. Removing them could simplify the test setup.

api/cosmos/protocolpool/v1/types.pulsar.go (1)

1370-1370: Avoid leading underscores and underscores in type names; prefer CamelCase.

The type _DistributionAmount_1_list begins with an underscore and uses underscores in its name, which goes against Go naming conventions. According to the Uber Go Style Guide, underscores should be avoided in names. Consider renaming the type to distributionAmountList or DistributionAmountList.

Apply this diff to rename the type:

-type _DistributionAmount_1_list struct {
+type distributionAmountList struct {
     // fields...
 }

Ensure all references to this type are updated accordingly.

api/cosmos/protocolpool/v1/tx.pulsar.go (2)

7467-7469: Fix the indentation of the withdrawn_allocated_fund field.

The withdrawn_allocated_fund field is not properly indented. It should be aligned with the other fields in the MsgCancelContinuousFundResponse message.

Apply this diff to fix the indentation:

-    WithdrawnAllocatedFund []*v1beta1.Coin `protobuf:"bytes,4,rep,name=withdrawn_allocated_fund,json=withdrawnAllocatedFund,proto3" json:"withdrawn_allocated_fund,omitempty"`
+	WithdrawnAllocatedFund []*v1beta1.Coin `protobuf:"bytes,4,rep,name=withdrawn_allocated_fund,json=withdrawnAllocatedFund,proto3" json:"withdrawn_allocated_fund,omitempty"`

7561-7563: Fix the indentation of the amount field.

The amount field is not properly indented. It should be aligned with the other fields in the MsgWithdrawContinuousFundResponse message.

Apply this diff to fix the indentation:

-    Amount []*v1beta1.Coin `protobuf:"bytes,1,rep,name=amount,proto3" json:"amount,omitempty"`
+	Amount []*v1beta1.Coin `protobuf:"bytes,1,rep,name=amount,proto3" json:"amount,omitempty"`
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3856e77 and 03b6445.

🔇 Files ignored due to path filters (3)
  • x/protocolpool/types/genesis.pb.go is excluded by !**/*.pb.go
  • x/protocolpool/types/tx.pb.go is excluded by !**/*.pb.go
  • x/protocolpool/types/types.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (16)
  • api/cosmos/protocolpool/v1/genesis.pulsar.go (32 hunks)
  • api/cosmos/protocolpool/v1/tx.pulsar.go (26 hunks)
  • api/cosmos/protocolpool/v1/types.pulsar.go (6 hunks)
  • x/protocolpool/depinject.go (1 hunks)
  • x/protocolpool/keeper/genesis.go (2 hunks)
  • x/protocolpool/keeper/genesis_test.go (2 hunks)
  • x/protocolpool/keeper/keeper.go (10 hunks)
  • x/protocolpool/keeper/keeper_test.go (4 hunks)
  • x/protocolpool/keeper/msg_server.go (1 hunks)
  • x/protocolpool/keeper/msg_server_test.go (18 hunks)
  • x/protocolpool/proto/cosmos/protocolpool/v1/genesis.proto (2 hunks)
  • x/protocolpool/proto/cosmos/protocolpool/v1/tx.proto (2 hunks)
  • x/protocolpool/proto/cosmos/protocolpool/v1/types.proto (2 hunks)
  • x/protocolpool/testutil/expected_keepers_mocks.go (0 hunks)
  • x/protocolpool/types/expected_keepers.go (0 hunks)
  • x/protocolpool/types/genesis.go (1 hunks)
💤 Files not reviewed due to no reviewable changes (2)
  • x/protocolpool/testutil/expected_keepers_mocks.go
  • x/protocolpool/types/expected_keepers.go
🧰 Additional context used
📓 Path-based instructions (11)
api/cosmos/protocolpool/v1/genesis.pulsar.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

api/cosmos/protocolpool/v1/tx.pulsar.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

api/cosmos/protocolpool/v1/types.pulsar.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

x/protocolpool/depinject.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

x/protocolpool/keeper/genesis.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

x/protocolpool/keeper/genesis_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

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

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

x/protocolpool/keeper/keeper_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

x/protocolpool/keeper/msg_server.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

x/protocolpool/keeper/msg_server_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

x/protocolpool/types/genesis.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

📓 Learnings (1)
x/protocolpool/keeper/genesis.go (1)
Learnt from: likhita-809
PR: cosmos/cosmos-sdk#18471
File: x/protocolpool/keeper/genesis.go:12-51
Timestamp: 2023-11-22T12:32:39.368Z
Learning: - The user `likhita-809` has confirmed the changes suggested in the previous interaction.
- The file in question is `x/protocolpool/keeper/genesis.go` from a Cosmos SDK module.
- The changes involve optimizing the `InitGenesis` function by removing redundant code and ensuring proper handling of start times for budget proposals.
🔇 Additional comments not posted (64)
x/protocolpool/keeper/genesis_test.go (1)

Line range hint 1-52: Overall, the changes effectively test the new multi-coin functionality.

The updates to TestInitGenesis align well with the PR objective of allowing any coins in continuous funds. The test now uses DistributionAmount with sdk.NewCoins for both Distributions and LastBalance, which provides more flexibility in representing different coin types.

The test scenario effectively checks the case where the total to be distributed is greater than the last balance, and the assertion has been updated to check the specific coin amount in the new structure.

These changes ensure that the genesis functionality is properly tested with the new multi-coin support.

x/protocolpool/types/genesis.go (2)

9-10: LGTM: Import changes are appropriate and well-structured.

The addition of the SDK types import is consistent with the changes in the NewGenesisState function. The import statement follows the Uber Golang style guide recommendations for import grouping and aliasing.


17-17: LGTM: LastBalance initialization updated correctly, but verify impact.

The change from math.ZeroInt() to DistributionAmount{Amount: sdk.NewCoins()} for LastBalance initialization is correct and aligns with the PR objectives of allowing any coins in continuous funds. This modification reflects the transition from a simple integer to a more flexible coin-based structure.

To ensure this change doesn't introduce any issues, please run the following verification:

This will help identify any other parts of the codebase that might need to be updated to accommodate this change.

x/protocolpool/proto/cosmos/protocolpool/v1/types.proto (2)

11-11: LGTM: Import statement for Amino codec added.

The addition of the Amino import is appropriate for maintaining backwards compatibility in the Cosmos SDK ecosystem. This import will allow the use of Amino-specific annotations in the protocol definitions.


Line range hint 14-54: Verify integration of DistributionAmount with existing messages.

While the new DistributionAmount message allows for multiple coin types, the existing Budget and ContinuousFund messages still use single-coin fields (e.g., claimed_amount, budget_per_tranche). This might lead to inconsistencies in how funds are handled across different parts of the protocol.

Please review and confirm:

  1. Whether Budget and ContinuousFund messages should be updated to use DistributionAmount for consistency.
  2. How DistributionAmount will be integrated with existing functionality.

To assist in this verification, you can run the following script to check for potential inconsistencies:

This script will help identify areas where the new DistributionAmount might need to be integrated or where existing single-coin usage might need to be reviewed.

x/protocolpool/depinject.go (1)

61-61: LGTM. Verify impact on dependent modules.

The removal of StakingKeeper from the NewKeeper function call aligns with the changes in the ModuleInputs struct. This modification appears intentional and consistent with the module's new design.

However, this is a breaking change that may affect other parts of the system relying on the old Keeper structure.

To ensure this change doesn't introduce unintended side effects, please run the following script to check for any remaining references to StakingKeeper in the protocolpool module:

Additionally, verify that all dependent modules have been updated to accommodate this change in the Keeper structure.

✅ Verification successful

Change Verified: No remaining references to StakingKeeper in x/protocolpool.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for remaining references to StakingKeeper in the protocolpool module

# Test: Search for StakingKeeper references in the protocolpool module
rg --type go 'StakingKeeper' x/protocolpool

Length of output: 43


Script:

#!/bin/bash
# Description: Search the entire codebase for references to StakingKeeper

rg --type go 'StakingKeeper'

Length of output: 43919

x/protocolpool/proto/cosmos/protocolpool/v1/tx.proto (3)

158-160: Approved: Enhanced flexibility for withdrawn funds

The change from a single coin to a repeated field of coins for withdrawn_allocated_fund aligns well with the PR objective. This modification allows for multiple types of coins to be withdrawn when canceling a continuous fund, increasing the flexibility of the protocol.

Note that this is a breaking change, as mentioned in the PR title, and will require updates to any code interacting with this message.


172-174: Approved: Multi-coin support for withdrawals

The modification of the amount field to a repeated field of coins in MsgWithdrawContinuousFundResponse is consistent with the PR's goal. This change enables the withdrawal of multiple types of coins from a continuous fund, enhancing the protocol's flexibility.

As with the previous change, this is a breaking change that will require updates to dependent code.


Line range hint 1-176: Verify related code updates

The changes in this file successfully implement multi-coin support for continuous funds in both cancellation and withdrawal operations. These modifications align well with the PR objectives and are correctly implemented in the Protocol Buffers definitions.

However, as these are breaking changes, it's crucial to ensure that:

  1. The corresponding Go code generated from these Proto definitions is updated accordingly.
  2. All parts of the codebase that interact with MsgCancelContinuousFundResponse and MsgWithdrawContinuousFundResponse are updated to handle multiple coins.
  3. Tests are updated or added to cover these new multi-coin scenarios.
  4. Documentation is updated to reflect these changes.

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

This script will help identify areas of the codebase that might need to be updated in light of these changes.

x/protocolpool/keeper/keeper_test.go (3)

38-42: LGTM: Removal of stakingKeeper field

The removal of the stakingKeeper field from the KeeperTestSuite struct is consistent with the changes described in the AI summary. This modification streamlines the test suite by removing unnecessary dependencies.


Line range hint 231-235: LGTM: Consistent type update in TestSetToDistribute

The change to use types.DistributionAmount in the Walk function is consistent with the previous modifications. The test logic remains valid and continues to provide good coverage.


Line range hint 1-238: Overall assessment: Changes are well-implemented and sufficiently tested

The modifications in this file consistently reflect the transition from using math.Int to types.DistributionAmount for handling distribution amounts. The test coverage has been appropriately updated to accommodate these changes, and the overall structure of the tests remains sound.

Key points:

  1. Removal of stakingKeeper dependency aligns with the PR objectives.
  2. Test logic has been correctly updated to work with the new DistributionAmount type.
  3. Existing test coverage appears sufficient for the changes made.

Suggestions for improvement:

  1. Consider adding test cases that exercise DistributionAmount with multiple coins to ensure comprehensive coverage of the new type's capabilities.

The changes adhere to Golang style guidelines and maintain the overall quality of the test suite.

x/protocolpool/keeper/keeper.go (16)

24-25: LGTM!

The definitions of authKeeper and bankKeeper in the Keeper struct are appropriate and follow standard conventions.


36-38: LGTM!

The addition of RecipientFundDistribution, Distributions, and LastBalance fields to the Keeper struct is correctly implemented, and their types are appropriately defined using the collections package.


70-72: LGTM!

The initialization of the new collections maps and items in the NewKeeper function aligns with the existing code patterns and is correctly implemented.


165-168: LGTM!

The calculation of amountToDistribute using SafeSub and the handling of potential negative results are correctly implemented.


183-188: LGTM!

The logic for transferring funds to the community pool when there are no continuous funds, and resetting LastBalance, is correctly implemented.


194-194: LGTM!

Recording the distribution amount with the current block time is appropriate and correctly implemented.


199-199: LGTM!

Updating LastBalance with the current balance ensures accurate tracking for future distributions.


221-223: LGTM!

Initialization of variables toDistribute, poolFunds, and fullAmountToDistribute is properly set up for subsequent calculations.


225-225: LGTM!

Iterating over k.Distributions to calculate allocations is correctly implemented.


266-266: LGTM!

Resetting LastBalance after clearing distributions ensures consistent state for future calculations.


271-271: LGTM!

Transferring streamAmt to the stream account is correctly handled.


279-279: LGTM!

Transferring poolFunds to the community pool is appropriately implemented.


301-301: LGTM!

Initializing toClaim with zero coins for new recipients is correct.


307-308: LGTM!

Updating the recipient's claimable amount in RecipientFundDistribution is correctly implemented.


115-135: Verify callers handle new return type of withdrawRecipientFunds

The withdrawRecipientFunds function now returns sdk.Coins instead of sdk.Coin. Ensure that all callers of this function have been updated to handle the new return type to avoid potential runtime errors.

Run the following script to find all usages of withdrawRecipientFunds and check for proper handling:

#!/bin/bash
# Description: Find all calls to `withdrawRecipientFunds` and verify they handle `sdk.Coins`.

# Test: Search for function calls to `withdrawRecipientFunds`. Expect: Callers expect `sdk.Coins`.
rg --type go 'withdrawRecipientFunds\(' -A 5

45-45: Verify that stakingKeeper is no longer used in the codebase

The stakingKeeper parameter has been removed from the NewKeeper function signature. Ensure that all references to stakingKeeper have been removed throughout the codebase to prevent any undefined references or build errors.

Run the following script to confirm that stakingKeeper is not referenced elsewhere:

x/protocolpool/keeper/msg_server_test.go (5)

398-398: Correct Update to withdrawnAmount Type

The variable withdrawnAmount has been appropriately updated from sdk.Coin to sdk.Coins to handle multiple coin types, aligning with the new data structures introduced in the codebase.


Line range hint 426-442: Consistent Initialization of RecipientFundDistribution

The initialization of RecipientFundDistribution with sdk.NewCoins() ensures that the distribution amounts are correctly represented as empty coin sets for multiple coin types. This change maintains consistency across the codebase.


628-631: Ensure Accurate Assertions After Multiple Withdrawals

At lines 628-631, assertions are made on toClaim.Amount for recipient2 and recipient3. Verify that these assertions correctly reflect the expected state after withdrawals, and ensure that funds are accurately distributed among all recipients.


991-1007: Correct Handling of Expired Continuous Funds

In the TestWithdrawExpiredFunds function (lines 991-1007), the logic correctly prevents withdrawal of expired funds and handles cancellations without errors. The test accurately verifies that repeated cancellations do not result in errors or unintended fund distribution.


508-508: Confirm Necessity of Empty Expiry in Test Case

In line 508, the test case sets an empty expiry for the continuous fund. Verify whether an empty expiry is acceptable in the business logic and that it does not introduce unintended behavior.

Run the following script to search for uses of continuous funds without expiry:

api/cosmos/protocolpool/v1/genesis.pulsar.go (25)

265-266: Handling of LastBalance in Range method is appropriate

The check for x.LastBalance != nil and subsequent processing ensures that the LastBalance field is correctly included during iteration. This follows standard practice and is compliant with the Uber Go Style Guide.


297-297: Correct implementation of Has method for LastBalance

The Has method accurately checks the presence of LastBalance by verifying if it is not nil. This is the appropriate way to handle optional fields in Go.


321-321: Proper clearing of LastBalance in Clear method

Setting x.LastBalance = nil correctly clears the field, ensuring that subsequent calls recognize it as unset. This adheres to best practices for managing optional fields.


354-354: Accurate retrieval of LastBalance in Get method

The Get method correctly retrieves the LastBalance field by returning its proto message representation. This implementation is standard and effective.


390-390: Type assertion in Set method is safe and appropriate

Assigning x.LastBalance after asserting the value's type to *DistributionAmount is appropriate here, assuming correct usage of the API. There is no immediate risk of a type assertion panic in this context.


427-431: Correct initialization of LastBalance in Mutable method

The method ensures that LastBalance is initialized when nil, which prevents potential nil pointer dereferences when accessing it later. Returning the proto message reflects standard practice.


458-459: Proper creation of new DistributionAmount in NewField

The creation of a new DistributionAmount instance and returning its proto message is correct and follows the expected pattern for this method.


544-545: Efficient size calculation of LastBalance in ProtoMethods

The Size function accurately includes the size of LastBalance when it is not nil. This contributes to correct serialization behavior.


599-609: Correct marshaling of LastBalance

The code properly marshals LastBalance when it is not nil, handling errors appropriately. The implementation aligns with the standard serialization process.


Line range hint 766-796: Accurate unmarshaling of LastBalance

During unmarshaling, the code correctly initializes LastBalance if it's nil and unmarshals data into it. Error handling is properly managed, ensuring robustness.


870-870: Initialization of fd_Distribution_amount is correct

The field descriptor for amount in the Distribution message is properly declared and initialized, which is essential for reflection operations.

Also applies to: 877-877


951-956: Appropriate handling of Amount in Range method of Distribution

The method correctly checks if x.Amount is not nil and processes it accordingly during iteration. This conforms to best practices.


974-975: Correct implementation of Has method for Amount

The Has method properly determines the presence of the Amount field by checking for nil, which is appropriate for optional fields.


994-995: Proper clearing of Amount in Clear method

Setting x.Amount = nil effectively clears the Amount field, ensuring it's unset in subsequent operations.


1040-1041: Safe type assertion in Set method for Amount

The assignment to x.Amount with type assertion to *DistributionAmount is appropriate and assumes correct usage of proto reflection.


1068-1071: Proper initialization of Amount in Mutable method

Ensuring x.Amount is initialized when nil prevents nil pointer exceptions and is a correct approach in the Mutable method.


1088-1090: Correct instantiation in NewField method

Creating a new DistributionAmount instance and returning its proto message aligns with standard implementation for creating new fields.


1164-1167: Accurate size calculation of Amount

Including the size of x.Amount in the total size when not nil is essential for accurate serialization.


1197-1198: Proper marshaling of Amount

The code marshals x.Amount correctly when it is present, handling potential errors suitably.


1211-1223: Correct marshaling of Time in Distribution

Marshaling of x.Time is handled appropriately, ensuring that the timestamp is correctly serialized.


Line range hint 1274-1342: Robust unmarshaling logic in Distribution

The unmarshaling code properly handles both Time and Amount fields, initializing them when necessary and managing errors effectively.


1406-1406: Definition of LastBalance field is appropriate

Changing LastBalance to be of type *DistributionAmount allows for richer data representation and aligns with the intended functionality.


1447-1451: Correct implementation of GetLastBalance method

The getter method accurately returns x.LastBalance and handles the case where x is nil, ensuring reliability.


1466-1467: Proper definition of Time and Amount fields in Distribution

Defining Time and Amount as pointers allows for optional fields and aligns with protobuf conventions.


1490-1499: Correct getter methods for Distribution fields

The GetTime and GetAmount methods correctly return their respective fields, handling nil cases appropriately.

api/cosmos/protocolpool/v1/tx.pulsar.go (6)

5511-5515: Verify the cardinality of withdrawn_allocated_fund.

The withdrawn_allocated_fund field is defined as a repeated field. Ensure that it is semantically correct for this field to contain multiple coins. If it should only hold a single coin amount, consider changing it to a non-repeated field.


Line range hint 7511-7515: Verify the cardinality of withdrawn_allocated_fund.

Similar to the previous comment, ensure that the withdrawn_allocated_fund field should indeed be a repeated field semantically. If it should only hold a single coin amount, change it to a non-repeated field.


Line range hint 7584-7588: Verify the cardinality of amount.

The amount field is defined as a repeated field. Ensure that it is semantically correct for this field to contain multiple coins. If it should only hold a single coin amount, consider changing it to a non-repeated field.


7728-7730: Fix the indentation of the withdrawn_allocated_fund field.

The withdrawn_allocated_fund field is not properly indented. It should be aligned with the other fields in the MsgCancelContinuousFundResponse message.

Apply this diff to fix the indentation:

-        WithdrawnAllocatedFund []*v1beta1.Coin `protobuf:"bytes,4,rep,name=withdrawn_allocated_fund,json=withdrawnAllocatedFund,proto3" json:"withdrawn_allocated_fund,omitempty"`
+	WithdrawnAllocatedFund []*v1beta1.Coin `protobuf:"bytes,4,rep,name=withdrawn_allocated_fund,json=withdrawnAllocatedFund,proto3" json:"withdrawn_allocated_fund,omitempty"`

7746-7748: Fix the indentation of the amount field.

The amount field is not properly indented. It should be aligned with the other fields in the MsgWithdrawContinuousFundResponse message.

Apply this diff to fix the indentation:

-        Amount []*v1beta1.Coin `protobuf:"bytes,1,rep,name=amount,proto3" json:"amount,omitempty"`
+	Amount []*v1beta1.Coin `protobuf:"bytes,1,rep,name=amount,proto3" json:"amount,omitempty"`

6465-6514: 🛠️ Refactor suggestion

Refactor the internal list type into a reusable utility.

Similar to the previous comment, consider extracting the _MsgWithdrawContinuousFundResponse_1_list type and its methods into a reusable utility type to improve code modularity and reduce duplication.

(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];
DistributionAmount last_balance = 3 [(gogoproto.nullable) = false];
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Changing field type of last_balance may cause backward compatibility issues

Modifying the type of the last_balance field from string to DistributionAmount in the GenesisState message can lead to serialization and deserialization issues with existing clients and persisted data that expect a string. This can cause failures when parsing genesis files or communicating with nodes that haven't updated.

To preserve backward compatibility, consider deprecating the existing field and introducing a new field with a new field number and the desired type.

(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];
google.protobuf.Timestamp time = 1 [(gogoproto.stdtime) = true];
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Altering field numbers in Protobuf messages breaks compatibility

Changing the field number of time from 6 to 1 in the Distribution message can result in data corruption or parsing errors. Field numbers in Protobuf are used to identify fields in the binary format, and modifying them disrupts compatibility with existing data and clients that use the previous numbering.

Instead of renumbering existing fields, add new fields with new field numbers, and, if necessary, deprecate the old fields to maintain backward compatibility.


google.protobuf.Timestamp time = 6 [(gogoproto.stdtime) = true];
DistributionAmount amount = 2 [(gogoproto.nullable) = false];
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Changing field type of amount may cause backward compatibility issues

Updating the type of the amount field from string to DistributionAmount in the Distribution message may lead to deserialization problems with existing data and clients expecting a string. This could cause runtime errors or data loss when processing distributions.

It's advisable to add a new field with a new field number and the new type DistributionAmount. You can retain the old amount field for compatibility purposes and mark it as deprecated.

Comment on lines +68 to +70
if data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}
Copy link
Contributor

@coderabbitai coderabbitai bot Sep 26, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the logical inconsistency in the condition and error message

There's a mismatch between the condition being checked and the error message returned. The condition data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) checks if the last balance amount is greater than the total to be distributed. However, the error message states "total to be distributed is greater than the last balance," which implies the opposite.

To correct this, the condition should check if totalToBeDistributed.IsAnyGT(data.LastBalance.Amount) instead.

Apply this diff to fix the condition:

-if data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
+if totalToBeDistributed.IsAnyGT(data.LastBalance.Amount) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
    return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}

This change ensures that the error is returned when the total to be distributed exceeds the last balance, aligning the condition with the error message.

📝 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 data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}
if totalToBeDistributed.IsAnyGT(data.LastBalance.Amount) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused a bit about the 1st condition, should return an error when totalToBeDistributed > lastBalance?

Copy link
Contributor

Choose a reason for hiding this comment

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

@hieuvubk, you're correct. The error should be returned when totalToBeDistributed is greater than data.LastBalance.Amount. Currently, the condition:

if data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
    return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}

checks if data.LastBalance.Amount is greater than totalToBeDistributed, which is the opposite of the intended logic based on the error message.

To fix this inconsistency, the condition should be:

if totalToBeDistributed.IsAnyGT(data.LastBalance.Amount) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
    return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}

This change ensures that an error is returned when totalToBeDistributed exceeds data.LastBalance.Amount, aligning the condition with the error message and the expected behavior.

/_/\
( •.• )

🚀<
A curious rabbit pondering over the code!

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not simply go with fmt.Errorf instead which is typically used in these scenarios? For example:

fmt.Errorf("an amount to be distributed is greater than the last balance: %s > %s", totalToBeDistributed, data.LastBalance.Amount))

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Member Author

Choose a reason for hiding this comment

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

This was actually for testing, but I think it can be useful if we ever encounter this, I'll modify it.

Comment on lines +239 to +242
for _, denom := range amount.Amount.Denoms() {
am := sdk.NewCoin(denom, f.Percentage.MulInt(amount.Amount.AmountOf(denom)).TruncateInt())
toDistribute[f.Recipient] = toDistribute[f.Recipient].Add(am)
fullAmountToDistribute = fullAmountToDistribute.Add(am)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Review the use of TruncateInt() in distribution calculations

When calculating each recipient's share, TruncateInt() is used after multiplying by the percentage. This could lead to loss of fractional amounts. Consider whether this aligns with the expected financial logic, or if using RoundInt() would be more appropriate to minimize discrepancies.

suite.Require().NoError(err)
suite.mockStreamFunds(math.NewInt(0))
},
recipientAddress: []sdk.AccAddress{recipient},
expErr: false,
withdrawnAmount: sdk.NewCoin(sdk.DefaultBondDenom, math.ZeroInt()),
withdrawnAmount: nil,
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Clarify Representation of Zero withdrawnAmount

The withdrawnAmount is set to nil on line 494. To maintain consistency and clarity, consider using sdk.NewCoins() to represent zero amounts instead of nil.

Apply this diff to standardize the representation:

-   withdrawnAmount:  nil,
+   withdrawnAmount:  sdk.NewCoins(),
📝 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
withdrawnAmount: nil,
withdrawnAmount: sdk.NewCoins(),

Comment on lines +1015 to +1017
case "cosmos.protocolpool.v1.Distribution.amount":
value := x.Amount
return protoreflect.ValueOfMessage(value.ProtoReflect())
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Possible copy-paste error in Get method for Distribution struct

In the Get method, the second case for "cosmos.protocolpool.v1.Distribution.time" incorrectly assigns x.Amount instead of x.Time. Additionally, there is no case handling for "cosmos.protocolpool.v1.Distribution.amount", which is required for proper functionality.

Apply the following diff to fix the issue:

 func (x *fastReflection_Distribution) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value {
     switch descriptor.FullName() {
     case "cosmos.protocolpool.v1.Distribution.time":
         value := x.Time
         return protoreflect.ValueOfMessage(value.ProtoReflect())
-    case "cosmos.protocolpool.v1.Distribution.time":
+    case "cosmos.protocolpool.v1.Distribution.amount":
         value := x.Amount
         return protoreflect.ValueOfMessage(value.ProtoReflect())
     default:

Committable suggestion was skipped due to low confidence.

Comment on lines +1370 to +1372
type _DistributionAmount_1_list struct {
list *[]*v1beta1.Coin
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid using pointers to slices; slices are reference types in Go.

In the struct _DistributionAmount_1_list, the field list is declared as *[]*v1beta1.Coin. Since slices in Go are reference types, using a pointer to a slice is unnecessary and adds complexity. Consider changing the field to use a slice directly.

Apply this diff to simplify the struct definition:

 type _DistributionAmount_1_list struct {
-    list *[]*v1beta1.Coin
+    list []*v1beta1.Coin
 }

Adjust the methods accordingly to reflect this change.

📝 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
type _DistributionAmount_1_list struct {
list *[]*v1beta1.Coin
}
type _DistributionAmount_1_list struct {
list []*v1beta1.Coin
}

Comment on lines +1606 to +1613
value := &_DistributionAmount_1_list{list: &x.Amount}
return protoreflect.ValueOfList(value)
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.protocolpool.v1.DistributionAmount"))
}
panic(fmt.Errorf("message cosmos.protocolpool.v1.DistributionAmount does not contain field %s", fd.FullName()))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid using panic for error handling; return errors instead.

Using panic in the Mutable method for handling invalid field descriptors is discouraged. Panics can cause unexpected crashes and are harder to recover from. Instead, modify the method to return an error or handle the situation gracefully without panicking.

Consider refactoring the code as follows:

 func (x *fastReflection_DistributionAmount) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
     switch fd.FullName() {
     case "cosmos.protocolpool.v1.DistributionAmount.amount":
         if x.Amount == nil {
             x.Amount = []*v1beta1.Coin{}
         }
         value := &_DistributionAmount_1_list{list: &x.Amount}
         return protoreflect.ValueOfList(value)
     default:
         if fd.IsExtension() {
-            panic(fmt.Errorf("proto3 declared messages do not support extensions: %s", fd.FullName()))
+            // Handle the error appropriately without panicking
+            return protoreflect.Value{}
         }
-        panic(fmt.Errorf("message cosmos.protocolpool.v1.DistributionAmount does not contain field %s", fd.FullName()))
+        // Handle the error appropriately without panicking
+        return protoreflect.Value{}
     }
 }

Adjust the method's return type and callers as necessary to handle the absence of a valid value.

Committable suggestion was skipped due to low confidence.

Comment on lines +5360 to +5409
var _ protoreflect.List = (*_MsgCancelContinuousFundResponse_4_list)(nil)

type _MsgCancelContinuousFundResponse_4_list struct {
list *[]*v1beta1.Coin
}

func (x *_MsgCancelContinuousFundResponse_4_list) Len() int {
if x.list == nil {
return 0
}
return len(*x.list)
}

func (x *_MsgCancelContinuousFundResponse_4_list) Get(i int) protoreflect.Value {
return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect())
}

func (x *_MsgCancelContinuousFundResponse_4_list) Set(i int, value protoreflect.Value) {
valueUnwrapped := value.Message()
concreteValue := valueUnwrapped.Interface().(*v1beta1.Coin)
(*x.list)[i] = concreteValue
}

func (x *_MsgCancelContinuousFundResponse_4_list) Append(value protoreflect.Value) {
valueUnwrapped := value.Message()
concreteValue := valueUnwrapped.Interface().(*v1beta1.Coin)
*x.list = append(*x.list, concreteValue)
}

func (x *_MsgCancelContinuousFundResponse_4_list) AppendMutable() protoreflect.Value {
v := new(v1beta1.Coin)
*x.list = append(*x.list, v)
return protoreflect.ValueOfMessage(v.ProtoReflect())
}

func (x *_MsgCancelContinuousFundResponse_4_list) Truncate(n int) {
for i := n; i < len(*x.list); i++ {
(*x.list)[i] = nil
}
*x.list = (*x.list)[:n]
}

func (x *_MsgCancelContinuousFundResponse_4_list) NewElement() protoreflect.Value {
v := new(v1beta1.Coin)
return protoreflect.ValueOfMessage(v.ProtoReflect())
}

func (x *_MsgCancelContinuousFundResponse_4_list) IsValid() bool {
return x.list != nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor the internal list type into a reusable utility.

Consider extracting the _MsgCancelContinuousFundResponse_4_list type and its methods into a reusable utility type. This will make the code more modular and reduce duplication if similar list types are needed elsewhere.

Copy link
Contributor

@hieuvubk hieuvubk left a comment

Choose a reason for hiding this comment

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

overall lgtm, one condition in genesis need to check

Comment on lines +68 to +70
if data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused a bit about the 1st condition, should return an error when totalToBeDistributed > lastBalance?

Copy link
Contributor

@alpe alpe left a comment

Choose a reason for hiding this comment

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

Nice work!
I am not very familiar with the module but I added some comments that may be helpful.
Are you planning to add a migration? That would be very helpful for existing chains.

You also mentioned an accept list to prevent spam. How is this going to be implemented and maintained?


if data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
Copy link
Contributor

Choose a reason for hiding this comment

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

last balance should always be >= total to be distributed.

Simplest thing would be to flip the check: totalToBeDistributed.IsAnyGT(last balance)
This includes the denoms implicite so that you can drop the DenomsSubsetOf check

Comment on lines +68 to +70
if data.LastBalance.Amount.IsAnyGT(totalToBeDistributed) || !totalToBeDistributed.DenomsSubsetOf(data.LastBalance.Amount) {
return errors.New("total to be distributed is greater than the last balance" + fmt.Sprint(data.LastBalance.Amount, totalToBeDistributed))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not simply go with fmt.Errorf instead which is typically used in these scenarios? For example:

fmt.Errorf("an amount to be distributed is greater than the last balance: %s > %s", totalToBeDistributed, data.LastBalance.Amount))

remaining := math.LegacyOneDec().Sub(percentageToDistribute).MulInt(amount).RoundInt()
poolFunds = poolFunds.Add(remaining)
for _, denom := range amount.Amount.Denoms() {
remaining := sdk.NewCoin(denom, math.LegacyOneDec().Sub(percentageToDistribute).MulInt(amount.Amount.AmountOf(denom)).TruncateInt())
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar code was used before but is another round down which has a rest that is not distributed.
Better remaining = amount - distributed amount

@julienrbrt julienrbrt added the backport/v0.52.x PR scheduled for inclusion in the v0.52's next stable release label Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport/v0.52.x PR scheduled for inclusion in the v0.52's next stable release C:x/protocolpool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants