Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove staking as a require module from mint #21858

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

Conversation

tac0turtle
Copy link
Member

@tac0turtle tac0turtle commented Sep 23, 2024

Description

this pr is part of the staking requirements in the repo. Reducing it allows more people to use the module without needing to use the default staking module


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 method SetMintFn to define the minting function for enhanced flexibility.
    • Updated the initialization of the MintKeeper and AppModule to simplify setup.
  • Bug Fixes

    • Added validation to ensure the minting function cannot be nil, preventing potential runtime errors.
  • Refactor

    • Removed unnecessary parameters and dependencies, streamlining the minting process and test setup.
    • Consolidated the handling of minting functions for consistency across the application.

Copy link
Contributor

coderabbitai bot commented Sep 23, 2024

Walkthrough

Walkthrough

The changes primarily involve modifications to the minting process within the Cosmos SDK's mint module. Key updates include the removal of the StakingKeeper from various components, the introduction of a new SetMintFn method for setting the minting function, and adjustments to method signatures across multiple files. These changes streamline the initialization and execution of minting operations, enhancing the modularity and flexibility of the minting functionality.

Changes

File Change Summary
simapp/app.go Modified MintKeeper initialization by removing app.StakingKeeper. Introduced SetMintFn for setting the minting function. Updated mint.NewAppModule call to remove the nil argument for StakingKeeper.
x/mint/depinject.go Added a panic condition for nil MintFn. Removed previous logic for handling MintFn and InflationCalculationFn. Simplified the function structure by excluding the MintFn parameter in NewAppModule.
x/mint/epoch_hooks.go Updated BeforeEpochStart method to call am.keeper.MintFn instead of am.mintFn, adjusting parameters to remove am.keeper.Environment.
x/mint/keeper/abci.go Changed BeginBlocker method to remove mintFn parameter, now using k.MintFn internally.
x/mint/keeper/genesis.go Introduced validation in InitGenesis to check if mintFn is nil, triggering a panic if true.
x/mint/keeper/genesis_test.go Removed stakingKeeper from keeper instantiation. Added SetMintFn method to the keeper instance, currently a no-op.
x/mint/keeper/grpc_query_test.go Removed stakingKeeper mock from mintKeeper instantiation, simplifying test setup.
x/mint/keeper/keeper.go Removed stakingKeeper field from Keeper. Added mintFn field for custom minting logic. Updated NewKeeper to require SetMintFn. Introduced MintFn method for minting operations. Modified DefaultMintFn to take a staking parameter.
x/mint/keeper/keeper_test.go Removed TestAliasFunctions method. Updated TestDefaultMintFn to use MintFn instead of DefaultMintFn. Simplified calls to BeginBlocker to not pass DefaultMintFn.
x/mint/module.go Updated AppModule to use mintKeeper.Keeper. Removed mintFn field and related logic from NewAppModule. Adjusted BeginBlock method to call am.keeper.BeginBlocker(ctx) without mintFn.
x/mint/module_test.go Updated SetupTest to initialize mintKeeper with SetMintFn. Simplified appmodule instantiation by removing the default minting function parameter.

Possibly related PRs

Suggested labels

C:x/staking, C:x/auth, backport/v0.52.x

Suggested reviewers

  • aaronc
  • kocubinski
  • facundomedica
  • sontrinh16
  • testinginprod
  • julienrbrt

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.

@tac0turtle tac0turtle marked this pull request as ready for review September 23, 2024 14:42
func (k Keeper) GetAuthority() string {
return k.authority
}
// SetMintFn sets the mint function.
Copy link
Member

Choose a reason for hiding this comment

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

That's meh, why not add this in the constructor?

Copy link
Member Author

Choose a reason for hiding this comment

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

then the mint module would take the staking keeper in the constructor, i wanted to avoid the staking keeper being required in the constructor to avoid optional parameters in the constructor. Also we dont know if the mintFn will require the mint module before its past to the constructor. It would be a weird look.

Copy link
Member

Choose a reason for hiding this comment

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

Still feels like a code smell. types.MintFn doesn't look like it requires the staking module.
That function only has access to state via the environment, how would you use staking or mint in there? Via the router? Then you already don't need the keepers.

Copy link
Member Author

@tac0turtle tac0turtle Sep 23, 2024

Choose a reason for hiding this comment

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

the default function requires staking and mint keeper context is passed to them. that is the caveat

if err != nil {

Copy link
Member

Choose a reason for hiding this comment

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

I see, I think we can still make it okay with depinject. Posted a comment below

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

Outside diff range and nitpick comments (6)
x/mint/epoch_hooks.go (1)

20-20: LGTM! Consider enhancing error handling.

The change from am.mintFn to am.keeper.MintFn aligns well with the PR objective of removing staking as a required module for minting. This refactoring improves encapsulation by moving the minting function into the keeper.

Consider wrapping the error returned from am.keeper.MintFn with additional context to aid in debugging:

-err = am.keeper.MintFn(ctx, &minter, epochIdentifier, epochNumber)
+err = am.keeper.MintFn(ctx, &minter, epochIdentifier, epochNumber)
+if err != nil {
+    return fmt.Errorf("failed to execute MintFn: %w", err)
+}

This change would provide more context in case of an error, making it easier to trace the source of the problem.

x/mint/keeper/abci.go (1)

12-12: Approve function signature change and suggest documentation update

The removal of the mintFn parameter from the BeginBlocker function signature aligns with the PR objective of decoupling the mint module from the staking module. This change improves encapsulation by making the minting function an internal part of the Keeper.

Consider updating the function's documentation to reflect this change in behavior, explaining that the minting function is now internal to the Keeper.

x/mint/depinject.go (1)

Line range hint 1-85: Overall assessment of changes in x/mint/depinject.go

The changes in this file successfully remove the dependency on the staking module for minting, aligning with the PR objectives. The modifications simplify the minting logic and make it more flexible by requiring a non-nil MintFn to be provided.

Key points:

  1. The addition of a nil check for MintFn ensures that a minting function is always provided, though the error handling could be improved.
  2. The direct setting of MintFn without a fallback mechanism simplifies the logic.
  3. The NewAppModule instantiation has been updated to reflect these changes.

These changes enhance the modularity of the minting functionality, allowing for greater flexibility in how minting is implemented. However, consider improving the error handling as suggested in the earlier comment.

x/mint/module_test.go (2)

67-67: LGTM! Consider adding a test for SetMintFn.

The addition of SetMintFn aligns with the PR objective of making the staking module optional for minting. This change enhances flexibility in setting the mint function.

To improve test coverage, consider adding a specific test case for SetMintFn to ensure it correctly sets the minting function.


78-78: LGTM! Consider adding a test for the new NewAppModule signature.

The simplification of NewAppModule initialization by removing the mintFn parameter aligns with the PR objective of decoupling the mint module from the staking module.

To ensure comprehensive test coverage, consider adding a specific test case for the new NewAppModule function signature to verify that it correctly initializes the AppModule without the mintFn parameter.

x/mint/keeper/genesis_test.go (1)

Line range hint 1-101: Improve test coverage for new functionality

While the existing tests cover the basic genesis functionality, they don't adequately test the new SetMintFn feature or its impact on the minting process. Consider adding the following test cases:

  1. Test different SetMintFn implementations and their effect on minting.
  2. Verify that genesis import/export correctly handles the new minting function.
  3. Test error scenarios, such as setting an invalid minting function.

Example additional test:

func (s *GenesisTestSuite) TestGenesisWithCustomMintFn() {
    customMintFn := func(ctx context.Context, env appmodule.Environment, minter *types.Minter, epochId string, epochNumber int64) error {
        // Custom minting logic
        return nil
    }
    err := s.keeper.SetMintFn(customMintFn)
    s.NoError(err)

    genesisState := types.DefaultGenesisState()
    err = s.keeper.InitGenesis(s.sdkCtx, s.accountKeeper, genesisState)
    s.NoError(err)

    // Verify that the custom mint function is used during minting operations
    // ...

    exportedState, err := s.keeper.ExportGenesis(s.sdkCtx)
    s.NoError(err)
    // Verify that the exported state reflects the use of the custom mint function
    // ...
}

These additional tests will help ensure that the new SetMintFn functionality is working as expected and properly integrated with the existing genesis operations.

Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4666e1d and a16eea6.

Files selected for processing (11)
  • simapp/app.go (2 hunks)
  • x/mint/depinject.go (1 hunks)
  • x/mint/epoch_hooks.go (1 hunks)
  • x/mint/keeper/abci.go (2 hunks)
  • x/mint/keeper/genesis.go (1 hunks)
  • x/mint/keeper/genesis_test.go (2 hunks)
  • x/mint/keeper/grpc_query_test.go (0 hunks)
  • x/mint/keeper/keeper.go (4 hunks)
  • x/mint/keeper/keeper_test.go (5 hunks)
  • x/mint/module.go (3 hunks)
  • x/mint/module_test.go (2 hunks)
Files not reviewed due to no reviewable changes (1)
  • x/mint/keeper/grpc_query_test.go
Additional context used
Path-based instructions (10)
simapp/app.go (1)

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

x/mint/depinject.go (1)

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

x/mint/epoch_hooks.go (1)

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

x/mint/keeper/abci.go (1)

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

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

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

x/mint/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/mint/keeper/keeper.go (1)

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

x/mint/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/mint/module.go (1)

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

x/mint/module_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"

Additional comments not posted (17)
x/mint/epoch_hooks.go (1)

Line range hint 35-37: Verify the intended behavior of AfterEpochEnd

The AfterEpochEnd method is currently a no-op. While this might be intentional, it's worth confirming that no actions are required after an epoch ends for the mint module.

Could you please confirm if this is the intended behavior? If actions are needed after an epoch ends, we should implement them here.

x/mint/keeper/abci.go (2)

Line range hint 1-34: Summary of changes and their impact

The modifications to x/mint/keeper/abci.go successfully remove the dependency on an external minting function, aligning with the PR objective of decoupling the mint module from the staking module. The changes are minimal, focused, and maintain the overall structure and logic of the BeginBlocker function.

Key points:

  1. The function signature has been updated to remove the mintFn parameter.
  2. The internal logic now uses k.MintFn instead of the passed mintFn.
  3. These changes improve encapsulation while potentially allowing for more flexibility in minting function implementation.

The code adheres to the Uber Golang style guide, and there are no apparent issues with naming conventions or code structure.


25-25: Approve internal logic change and suggest verification

The replacement of mintFn with k.MintFn is consistent with the function signature change and maintains the existing behavior. This modification enhances the modularity of the mint module.

Please ensure that k.MintFn is properly implemented within the Keeper struct and provides the same functionality as the previous mintFn. You can verify this by running the following command:

x/mint/depinject.go (2)

80-80: Simplified MintFn setting looks good

The direct setting of MintFn without a fallback mechanism aligns well with the new requirement of MintFn being non-nil. This change simplifies the logic and makes the code more straightforward.


82-82: Modified NewAppModule instantiation looks correct

The removal of the MintFn parameter from the NewAppModule call is consistent with the earlier changes and reflects the removal of the default minting function logic.

To ensure this change is consistent throughout the codebase, please run the following command:

This will help verify that all NewAppModule calls have been updated correctly.

Verification successful

Verification successful: No remaining NewAppModule calls with MintFn parameter found.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining NewAppModule calls with MintFn parameter
rg --type go 'NewAppModule.*MintFn'

Length of output: 37


Script:

#!/bin/bash
# Enhanced search for NewAppModule calls with MintFn parameter
rg --type go 'NewAppModule\s*\([^)]*MintFn[^)]*\)'

Length of output: 52

x/mint/module_test.go (1)

Line range hint 1-96: Enhance test coverage for the new changes.

While the existing tests provide good coverage for the basic functionality of the mint module, they don't specifically target the changes introduced in this PR. To ensure the robustness of the new implementation:

  1. Add test cases that verify the mint module's behavior without the staking module.
  2. Include tests that cover different scenarios of setting custom mint functions using SetMintFn.
  3. Ensure that the TestEpochHooks function adequately tests the module's behavior with the new changes.

These additions will help maintain high code quality and prevent potential regressions.

To assist in identifying areas that may need additional test coverage, you can run the following command:

This will generate a coverage report, helping to identify specific areas that may need more test cases.

x/mint/keeper/genesis_test.go (1)

62-62: LGTM: Keeper initialization updated

The NewKeeper function call has been updated to remove the stakingKeeper, which aligns with the PR objective of removing staking as a required module for minting.

x/mint/module.go (4)

14-14: LGTM: Import statement added correctly.

The new import statement for mintKeeper is necessary and correctly aligns with the changes made to the keeper field type in the AppModule struct.


43-43: LGTM: AppModule struct updated correctly.

The keeper field type has been appropriately updated to mintKeeper.Keeper, which is consistent with the new import statement and the overall refactoring goal. The removal of the mintFn field aligns with the PR objective of decoupling the mint module from the staking module.


151-151: LGTM: BeginBlock method updated correctly.

The BeginBlock method has been appropriately updated to call am.keeper.BeginBlocker(ctx) without passing am.mintFn, which is consistent with the removal of the mintFn field from the AppModule struct. This change aligns with the PR objective of decoupling the mint module from the staking module.

Please verify that the BeginBlocker method in the keeper package has been updated to handle this change:

#!/bin/bash
# Description: Verify that the BeginBlocker method in the keeper package has been updated.
rg --type go -A 10 'func \(k Keeper\) BeginBlocker\(' x/mint/keeper/

51-51: LGTM: NewAppModule function signature updated correctly.

The keeper parameter type has been appropriately updated to mintKeeper.Keeper, which is consistent with the changes in the AppModule struct. The removal of the mintFn parameter aligns with the PR objective of decoupling the mint module from the staking module.

Please verify that the function body has been updated to reflect these changes:

Verification successful

Verified: NewAppModule function has been correctly updated.

The keeper parameter type is now mintKeeper.Keeper, and the mintFn parameter has been successfully removed. The function body reflects these changes appropriately.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the NewAppModule function body has been updated.
rg --type go -A 10 'func NewAppModule\(' x/mint/module.go

Length of output: 598


Script:

#!/bin/bash
# Description: Verify that the NewAppModule function body has been updated.
rg --type go -A 10 'func NewAppModule\(' x/mint/module.go

Length of output: 244

simapp/app.go (2)

375-376: LGTM! Decoupling of MintKeeper from StakingKeeper

The changes successfully remove the direct dependency of MintKeeper on StakingKeeper during initialization, aligning with the PR objective. The new SetMintFn method provides a flexible way to set the minting function, allowing for easier customization and potential future changes to the minting logic.


471-471: LGTM! Simplified mint AppModule initialization

The removal of the StakingKeeper parameter (previously passed as nil) from the mint.NewAppModule function call is consistent with the decoupling of the mint module from the staking module. This change simplifies the AppModule initialization and reduces unnecessary dependencies.

To ensure this change is consistent with the mint module's internal implementation, please run the following command:

Verification successful

Verified: StakingKeeper parameter successfully removed

The NewAppModule function in x/mint/module.go no longer includes the StakingKeeper parameter. This confirms the decoupling of the mint module from the staking module, simplifying the AppModule initialization as intended.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that the mint module no longer requires StakingKeeper in its NewAppModule function
rg --type go 'func NewAppModule' x/mint/

Length of output: 78


Script:

#!/bin/bash
# Check if NewAppModule function includes StakingKeeper as a parameter
rg --type go 'func NewAppModule\(.*StakingKeeper' x/mint/module.go

Length of output: 68


Script:

#!/bin/bash
# Retrieve the NewAppModule function signature to verify its parameters
rg --type go 'func NewAppModule' x/mint/module.go -A 5

Length of output: 160

x/mint/keeper/keeper.go (2)

73-81: SetMintFn method correctly enforces non-nil 'mintFn'

The SetMintFn method appropriately checks for a nil mintFn and ensures that the Keeper has a valid mint function set, preventing potential runtime panics.


120-125: Error handling is properly implemented when retrieving staking data

The retrieval of stakingTokenSupply and bondedRatio includes appropriate error checks, ensuring that issues are caught and handled effectively.

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

125-126: Consistent Initialization of Mint Function

Setting the Mint function at the start of TestBeginBlocker is a good practice. This ensures that the test uses the correct Mint function and reduces the risk of unintended side effects from previous tests.


140-145: Confirm Minter State Remains Unchanged with No-op Mint Function

You've set a Mint function that performs no operation. It's good that you retrieve unchangedMinter after calling BeginBlocker. Ensure that your assertion s.Equal(newMinter, unchangedMinter) verifies that the minter's state remains unchanged, confirming the no-op Mint function behaves as intended.

Comment on lines +21 to +24
if keeper.mintFn == nil {
panic("mintFn cannot be nil")
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Approve the nil check for mintFn, but consider moving it.

The addition of a nil check for keeper.mintFn is a good safeguard against uninitialized minting functions. This aligns with the principle of failing fast and explicitly.

However, consider moving this check to the beginning of the function. This would prevent unnecessary operations if mintFn is nil and follows the pattern of validating inputs early. Here's a suggested refactor:

 func (keeper Keeper) InitGenesis(ctx context.Context, ak types.AccountKeeper, data *types.GenesisState) error {
+	if keeper.mintFn == nil {
+		panic("mintFn cannot be nil")
+	}
+
 	if err := keeper.Minter.Set(ctx, data.Minter); err != nil {
 		return err
 	}

 	if err := keeper.Params.Set(ctx, data.Params); err != nil {
 		return err
 	}

 	ak.GetModuleAccount(ctx, types.ModuleName)

-	if keeper.mintFn == nil {
-		panic("mintFn cannot be nil")
-	}

 	return nil
 }

This change would improve the function's efficiency and readability.

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 keeper.mintFn == nil {
panic("mintFn cannot be nil")
}
func (keeper Keeper) InitGenesis(ctx context.Context, ak types.AccountKeeper, data *types.GenesisState) error {
if keeper.mintFn == nil {
panic("mintFn cannot be nil")
}
if err := keeper.Minter.Set(ctx, data.Minter); err != nil {
return err
}
if err := keeper.Params.Set(ctx, data.Params); err != nil {
return err
}
ak.GetModuleAccount(ctx, types.ModuleName)
return nil
}

x/mint/depinject.go Show resolved Hide resolved
Comment on lines +63 to +66
err := s.keeper.SetMintFn(func(ctx context.Context, env appmodule.Environment, minter *types.Minter, epochId string, epochNumber int64) error {
return nil
})
s.NoError(err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Enhance test coverage for SetMintFn

While the SetMintFn is being set, the current implementation is a no-op function. Consider adding more comprehensive tests to verify the behavior of this new functionality.

Suggestions:

  1. Add test cases that use different SetMintFn implementations to ensure it's correctly integrated.
  2. Verify that the SetMintFn is called during relevant mint operations in other test cases.

Example test case:

func (s *GenesisTestSuite) TestSetMintFn() {
    called := false
    err := s.keeper.SetMintFn(func(ctx context.Context, env appmodule.Environment, minter *types.Minter, epochId string, epochNumber int64) error {
        called = true
        return nil
    })
    s.NoError(err)

    // Trigger a mint operation
    // ...

    s.True(called, "SetMintFn was not called during minting operation")
}

Comment on lines +34 to +37
// mintFn is used to mint new coins during BeginBlock. This function is in charge of
// minting new coins based on arbitrary logic, previously done through InflationCalculationFn.
// If mintFn is nil, the default minting logic is used.
mintFn types.MintFn
Copy link
Contributor

Choose a reason for hiding this comment

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

Clarify the behavior when 'mintFn' is nil to avoid inconsistency

The comment states: "If mintFn is nil, the default minting logic is used." However, the SetMintFn method prevents mintFn from being nil by returning an error if it is. This might cause confusion. Please update the comment to accurately reflect that mintFn must be set and cannot be nil.

Comment on lines +110 to +112
// DefaultMintFn returns a default mint function. It requires the Staking module and the mint keeper.
// The default Mintfn has a requirement on staking as it uses bond to calculate inflation.
func DefaultMintFn(ic types.InflationCalculationFn, staking types.StakingKeeper, k Keeper) types.MintFn {
Copy link
Contributor

Choose a reason for hiding this comment

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

Initialize 'mintFn' with default logic to improve safety

Consider initializing mintFn with a default mint function during Keeper construction. This provides a safe fallback and ensures that minting operations have valid logic even if SetMintFn is not called.

Apply this refactor to set a default mintFn:

func NewKeeper(
    cdc codec.BinaryCodec,
    env appmodule.Environment,
    ak types.AccountKeeper,
    bk types.BankKeeper,
    feeCollectorName string,
    authority string,
+   staking types.StakingKeeper,
) Keeper {
    // ensure mint module account is set
    if addr := ak.GetModuleAddress(types.ModuleName); addr == nil {
        panic(fmt.Sprintf("the x/%s module account has not been set", types.ModuleName))
    }

    sb := collections.NewSchemaBuilder(env.KVStoreService)
    k := Keeper{
        Environment:      env,
        cdc:              cdc,
        bankKeeper:       bk,
        feeCollectorName: feeCollectorName,
        authority:        authority,
        Params:           collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)),
        Minter:           collections.NewItem(sb, types.MinterKey, "minter", codec.CollValue[types.Minter](cdc)),
+       mintFn:           DefaultMintFn(DefaultInflationCalculationFn, staking, nil),
    }

    // [existing code]
    return k
}

This refactor requires passing staking to NewKeeper and sets mintFn to the default implementation if no custom function is provided.

Committable suggestion was skipped due to low confidence.

Comment on lines +83 to +84
err := s.mintKeeper.SetMintFn(keeper.DefaultMintFn(types.DefaultInflationCalculationFn, s.stakingKeeper, s.mintKeeper))
s.NoError(err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Add Assertions to Confirm Mint Function Is Set Correctly

While you are checking for errors after setting the Mint function, consider adding assertions to verify that the Mint function has been set as intended. This will ensure that SetMintFn has properly initialized the Mint function before proceeding with the test.


minter, err := s.mintKeeper.Minter.Get(s.ctx)
s.NoError(err)

err = s.mintKeeper.DefaultMintFn(types.DefaultInflationCalculationFn)(s.ctx, s.mintKeeper.Environment, &minter, "block", 0)
err = s.mintKeeper.MintFn(s.ctx, &minter, "block", 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Enhance Test by Verifying Mint Operation Results

After calling s.mintKeeper.MintFn(s.ctx, &minter, "block", 0), it's beneficial to add assertions to verify that the expected state changes have occurred. For example, you can check if the total supply has increased appropriately or if the minter's properties have been updated. This will strengthen the test by confirming the Mint function behaves as expected.

@@ -118,7 +96,7 @@
err = s.mintKeeper.Params.Set(s.ctx, params)
s.NoError(err)

err = s.mintKeeper.DefaultMintFn(types.DefaultInflationCalculationFn)(s.ctx, s.mintKeeper.Environment, &minter, "block", 0)
err = s.mintKeeper.MintFn(s.ctx, &minter, "block", 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Verify Behavior When Total Supply Exceeds Max Supply

In this scenario where the total supply exceeds the max supply, consider adding assertions to check that no additional coins are minted and that the minter's state reflects this condition. Confirming this behavior in your test ensures that the Mint function correctly handles cases where minting should be limited.

@@ -134,7 +112,7 @@
s.bankKeeper.EXPECT().MintCoins(s.ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(2000)))).Return(nil)
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(s.ctx, types.ModuleName, authtypes.FeeCollectorName, gomock.Any()).Return(nil)

err = s.mintKeeper.DefaultMintFn(types.DefaultInflationCalculationFn)(s.ctx, s.mintKeeper.Environment, &minter, "block", 0)
err = s.mintKeeper.MintFn(s.ctx, &minter, "block", 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Assert Minted Amount Matches Adjusted Parameters

Given the adjustments to MaxSupply and BlocksPerYear, after calling s.mintKeeper.MintFn(s.ctx, &minter, "block", 0), add assertions to verify that the minted amount is as expected (e.g., 2000 stake). This ensures the Mint function correctly calculates the mint amount based on the new parameters.

// get minter (it should get modified afterwards)
minter, err := s.mintKeeper.Minter.Get(s.ctx)
s.NoError(err)

err = s.mintKeeper.BeginBlocker(s.ctx, s.mintKeeper.DefaultMintFn(types.DefaultInflationCalculationFn))
err = s.mintKeeper.BeginBlocker(s.ctx)
Copy link
Contributor

Choose a reason for hiding this comment

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

Enhance Test by Asserting State Changes After BeginBlocker

After invoking s.mintKeeper.BeginBlocker(s.ctx), consider adding assertions to verify that the minter state has been updated appropriately. For instance, you can compare specific fields of newMinter and minter to confirm the expected changes occurred due to the BeginBlocker execution.

@@ -159,7 +148,7 @@

// BeginBlock returns the begin blocker for the mint module.
func (am AppModule) BeginBlock(ctx context.Context) error {
return am.keeper.BeginBlocker(ctx, am.mintFn)
return am.keeper.BeginBlocker(ctx)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

path flow from Begin/EndBlock to a panic call
path flow from Begin/EndBlock to a panic call
path flow from Begin/EndBlock to a panic call
path flow from Begin/EndBlock to a panic call
path flow from Begin/EndBlock to a panic call
@@ -64,31 +64,22 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
panic(err)
}

if in.MintFn == nil {
Copy link
Member

Choose a reason for hiding this comment

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

should not be marked as optional then.

func (k Keeper) GetAuthority() string {
return k.authority
}
// SetMintFn sets the mint function.
Copy link
Member

Choose a reason for hiding this comment

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

Still feels like a code smell. types.MintFn doesn't look like it requires the staking module.
That function only has access to state via the environment, how would you use staking or mint in there? Via the router? Then you already don't need the keepers.

Copy link
Member

@julienrbrt julienrbrt left a comment

Choose a reason for hiding this comment

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

Maybe that setter isn't that bad if we can optimize for depinject so the user notices no difference.

in.AccountKeeper,
in.BankKeeper,
feeCollectorName,
as,
)

if in.MintFn != nil && in.InflationCalculationFn != nil {
Copy link
Member

Choose a reason for hiding this comment

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

I am not fan of that setter, but we can get an OK UX with depinject.
IMHO we should keep most of this logic and just make the stakingkeeper optional.
If StakingKeeper && MintFn is nil, then we panic as well.
The rest of this can be brought back.

func (k Keeper) GetAuthority() string {
return k.authority
}
// SetMintFn sets the mint function.
Copy link
Member

Choose a reason for hiding this comment

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

I see, I think we can still make it okay with depinject. Posted a comment below

authKeeper types.AccountKeeper

// mintFn is used to mint new coins during BeginBlock. This function is in charge of
Copy link
Member

Choose a reason for hiding this comment

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

All of this go doc should be brought on SetMintFn

@@ -11,6 +11,7 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/registry"
"cosmossdk.io/x/mint/keeper"
mintKeeper "cosmossdk.io/x/mint/keeper"
Copy link
Member

Choose a reason for hiding this comment

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

can we just say keeper? we always do that for the keeper of the module we are in.

@@ -39,34 +40,22 @@ var (
// AppModule implements an application module for the mint module.
type AppModule struct {
cdc codec.Codec
keeper keeper.Keeper
keeper mintKeeper.Keeper
Copy link
Member

Choose a reason for hiding this comment

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

this could be k if the package shadowing was an issue

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

Successfully merging this pull request may close these issues.

4 participants