refactor: simplify group dependency graph and align 0.52 and main (#22978)

This commit is contained in:
Julien Robert 2024-12-18 14:29:52 +01:00 committed by GitHub
parent cb56c6e47f
commit 4d6c991fb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 169 additions and 195 deletions

View File

@ -203,5 +203,4 @@ func (s *suite) registerMsgRouterService(router *integration.RouterService) {
}
func (f *suite) registerQueryRouterService(router *integration.RouterService) {
}

View File

@ -105,5 +105,4 @@ func (f *fixture) registerMsgRouterService(router *integration.RouterService) {
}
func (f *fixture) registerQueryRouterService(router *integration.RouterService) {
}

View File

@ -170,8 +170,7 @@ var (
_ event.Manager = &eventManager{}
)
type eventService struct {
}
type eventService struct{}
// EventManager implements event.Service.
func (e *eventService) EventManager(ctx context.Context) event.Manager {

View File

@ -381,7 +381,6 @@ func (bva *BaseLockup) checkUnbondingEntriesMature(ctx context.Context) error {
if !errorsmod.IsOf(err, stakingtypes.ErrNoUnbondingDelegation) {
return true, err
}
}
found := false

View File

@ -125,7 +125,6 @@ func newMockContext(t *testing.T) (context.Context, store.KVStoreService) {
default:
return nil, errors.New("unrecognized request type")
}
},
)
}

View File

@ -3,19 +3,26 @@ package testutil
import (
"context"
bankkeeper "cosmossdk.io/x/bank/keeper"
"cosmossdk.io/x/bank/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// minimalBankKeeper is a subset of the bankkeeper.Keeper interface that is used
// for the bank testing utilities.
type minimalBankKeeper interface {
MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error
SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error
}
// FundAccount is a utility function that funds an account by minting and
// sending the coins to the address. This should be used for testing purposes
// only!
//
// TODO: Instead of using the mint module account, which has the
// permission of minting, create a "faucet" account. (@fdymylja)
func FundAccount(ctx context.Context, bankKeeper bankkeeper.Keeper, addr sdk.AccAddress, amounts sdk.Coins) error {
func FundAccount(ctx context.Context, bankKeeper minimalBankKeeper, addr sdk.AccAddress, amounts sdk.Coins) error {
if err := bankKeeper.MintCoins(ctx, types.MintModuleName, amounts); err != nil {
return err
}
@ -29,7 +36,7 @@ func FundAccount(ctx context.Context, bankKeeper bankkeeper.Keeper, addr sdk.Acc
//
// TODO: Instead of using the mint module account, which has the
// permission of minting, create a "faucet" account. (@fdymylja)
func FundModuleAccount(ctx context.Context, bankKeeper bankkeeper.Keeper, recipientMod string, amounts sdk.Coins) error {
func FundModuleAccount(ctx context.Context, bankKeeper minimalBankKeeper, recipientMod string, amounts sdk.Coins) error {
if err := bankKeeper.MintCoins(ctx, types.MintModuleName, amounts); err != nil {
return err
}

View File

@ -175,6 +175,5 @@ replace github.com/cosmos/cosmos-sdk => ../../.
// TODO remove post spinning out all modules
replace (
cosmossdk.io/x/bank => ../bank
cosmossdk.io/x/protocolpool => ../protocolpool
cosmossdk.io/x/staking => ../staking
)

View File

@ -12,12 +12,8 @@ require (
cosmossdk.io/log v1.5.0
cosmossdk.io/math v1.4.0
cosmossdk.io/store v1.10.0-rc.1
cosmossdk.io/x/accounts v0.0.0-20240913065641-0064ccbce64e
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000
cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a
cosmossdk.io/x/mint v0.0.0-00010101000000-000000000000
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000
github.com/cockroachdb/apd/v3 v3.2.1
github.com/cosmos/cosmos-proto v1.0.0-beta.5
github.com/cosmos/cosmos-sdk v0.53.0
@ -38,7 +34,7 @@ require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.0-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/collections v1.0.0-rc.1 // indirect
cosmossdk.io/schema v1.0.0 // indirect
cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.3 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
@ -184,13 +180,7 @@ replace github.com/cosmos/cosmos-sdk => ../../
// TODO remove post spinning out all modules
replace (
cosmossdk.io/client/v2 => ../../client/v2
cosmossdk.io/x/accounts => ../accounts
cosmossdk.io/x/bank => ../bank
cosmossdk.io/x/consensus => ../consensus
cosmossdk.io/x/epochs => ../epochs
cosmossdk.io/x/gov => ../gov
cosmossdk.io/x/mint => ../mint
cosmossdk.io/x/protocolpool => ../protocolpool
cosmossdk.io/x/slashing => ../slashing
cosmossdk.io/x/staking => ../staking
)

View File

@ -24,6 +24,8 @@ cosmossdk.io/schema v1.0.0 h1:/diH4XJjpV1JQwuIozwr+A4uFuuwanFdnw2kKeiXwwQ=
cosmossdk.io/schema v1.0.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.10.0-rc.1 h1:/YVPJLre7lt/QDbl90k95TLt+IvafF1sHaU6WHd/rpc=
cosmossdk.io/store v1.10.0-rc.1/go.mod h1:eZNgZKvZRlDUk8CE3LTDVMAcSM7zLOet2S8fByQkF3s=
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o=
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg=
cosmossdk.io/x/tx v1.0.0-alpha.3 h1:+55/JFH5QRqnFhOI2heH3DKsaNL0RpXcJOQNzUvHiaQ=
cosmossdk.io/x/tx v1.0.0-alpha.3/go.mod h1:h4pQ/j6Gfu8goB1R3Jbl4qY4RjYVNAsoylcleTXdSRg=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=

View File

@ -2,98 +2,35 @@ package keeper_test
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/suite"
"go.uber.org/mock/gomock"
"cosmossdk.io/core/address"
"cosmossdk.io/core/header"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/math"
bankkeeper "cosmossdk.io/x/bank/keeper"
"cosmossdk.io/x/bank/testutil"
banktypes "cosmossdk.io/x/bank/types"
"cosmossdk.io/x/group"
"cosmossdk.io/x/group/keeper"
grouptestutil "cosmossdk.io/x/group/testutil"
stakingkeeper "cosmossdk.io/x/staking/keeper"
codecaddress "github.com/cosmos/cosmos-sdk/codec/address"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type IntegrationTestSuite struct {
suite.Suite
app *runtime.App
ctx sdk.Context
addrs []sdk.AccAddress
groupKeeper keeper.Keeper
bankKeeper bankkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
interfaceRegistry codectypes.InterfaceRegistry
addressCodec address.Codec
}
func TestIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}
func (s *IntegrationTestSuite) SetupTest() {
app, err := simtestutil.Setup(
depinject.Configs(
grouptestutil.AppConfig,
depinject.Supply(log.NewNopLogger()),
),
&s.interfaceRegistry,
&s.bankKeeper,
&s.stakingKeeper,
&s.groupKeeper,
)
s.Require().NoError(err)
ctx := app.BaseApp.NewContext(false)
ctx = ctx.WithHeaderInfo(header.Info{Time: time.Now()})
s.ctx = ctx
s.addrs = simtestutil.AddTestAddrsIncremental(s.bankKeeper, s.stakingKeeper, ctx, 4, math.NewInt(30000000))
s.addressCodec = codecaddress.NewBech32Codec("cosmos")
}
func (s *IntegrationTestSuite) TestEndBlockerPruning() {
ctx := s.ctx
addr1, err := s.addressCodec.BytesToString(s.addrs[0])
s.Require().NoError(err)
addr2, err := s.addressCodec.BytesToString(s.addrs[1])
s.Require().NoError(err)
addr3, err := s.addressCodec.BytesToString(s.addrs[2])
s.Require().NoError(err)
addr1st, err := s.addressCodec.BytesToString(s.addrs[0])
s.Require().NoError(err)
func (s *TestSuite) TestEndBlockerPruning() {
ctx := s.sdkCtx
s.bankKeeper.EXPECT().Send(gomock.Any(), gomock.Any()).Return(&banktypes.MsgSendResponse{}, nil).AnyTimes()
// Initial group, group policy and balance setup
members := []group.MemberRequest{
{Address: addr1st, Weight: "1"}, {Address: addr2, Weight: "2"},
{Address: s.addrsStr[0], Weight: "1"}, {Address: s.addrsStr[1], Weight: "2"},
}
groupRes, err := s.groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{
Admin: addr1st,
Admin: s.addrsStr[0],
Members: members,
})
s.Require().NoError(err)
groupRes2, err := s.groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{
Admin: addr2,
Admin: s.addrsStr[1],
Members: members,
})
s.Require().NoError(err)
@ -108,12 +45,15 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
)
policyReq := &group.MsgCreateGroupPolicy{
Admin: addr1,
Admin: s.addrsStr[0],
GroupId: groupID,
}
err = policyReq.SetDecisionPolicy(policy)
s.Require().NoError(err)
s.setNextAccount()
policyRes, err := s.groupKeeper.CreateGroupPolicy(ctx, policyReq)
s.Require().NoError(err)
@ -124,12 +64,15 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
)
policyReq2 := &group.MsgCreateGroupPolicy{
Admin: addr2,
Admin: s.addrsStr[1],
GroupId: groupID2,
}
err = policyReq2.SetDecisionPolicy(policy2)
s.Require().NoError(err)
s.setNextAccount()
policyRes2, err := s.groupKeeper.CreateGroupPolicy(ctx, policyReq2)
s.Require().NoError(err)
@ -145,15 +88,15 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
msgSend1 := &banktypes.MsgSend{
FromAddress: policyRes.Address,
ToAddress: addr2,
ToAddress: s.addrsStr[1],
Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)},
}
msgSend2 := &banktypes.MsgSend{
FromAddress: policyRes2.Address,
ToAddress: addr2,
ToAddress: s.addrsStr[1],
Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)},
}
proposers := []string{addr2}
proposers := []string{s.addrsStr[1]}
specs := map[string]struct {
setupProposal func(ctx sdk.Context) uint64
@ -166,9 +109,9 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
"proposal pruned after executor result success": {
setupProposal: func(ctx sdk.Context) uint64 {
msgs := []sdk.Msg{msgSend1}
pID, err := submitProposalAndVoteHelper(s, s.app, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
pID, err := submitProposalAndVoteHelper(s, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
s.Require().NoError(err)
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: addr3, ProposalId: pID})
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: s.addrsStr[2], ProposalId: pID})
s.Require().NoError(err)
s.Require().NoError(testutil.FundAccount(ctx, s.bankKeeper, groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10002)}))
@ -181,9 +124,9 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
"proposal with multiple messages pruned when executed with result success": {
setupProposal: func(ctx sdk.Context) uint64 {
msgs := []sdk.Msg{msgSend1, msgSend1}
pID, err := submitProposalAndVoteHelper(s, s.app, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
pID, err := submitProposalAndVoteHelper(s, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
s.Require().NoError(err)
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: addr3, ProposalId: pID})
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: s.addrsStr[2], ProposalId: pID})
s.Require().NoError(err)
s.Require().NoError(testutil.FundAccount(ctx, s.bankKeeper, groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10002)}))
@ -196,9 +139,9 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
"proposal not pruned when not executed and rejected": {
setupProposal: func(ctx sdk.Context) uint64 {
msgs := []sdk.Msg{msgSend1}
pID, err := submitProposalAndVoteHelper(s, s.app, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_NO)
pID, err := submitProposalAndVoteHelper(s, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_NO)
s.Require().NoError(err)
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: addr3, ProposalId: pID})
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: s.addrsStr[2], ProposalId: pID})
s.Require().NoError(err)
s.Require().NoError(testutil.FundAccount(ctx, s.bankKeeper, groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10002)}))
@ -211,9 +154,9 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
},
"open proposal is not pruned which must not fail ": {
setupProposal: func(ctx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, s.app, ctx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
pID, err := submitProposalHelper(s, ctx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
s.Require().NoError(err)
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: addr3, ProposalId: pID})
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: s.addrsStr[2], ProposalId: pID})
s.Require().NoError(err)
s.Require().NoError(testutil.FundAccount(ctx, s.bankKeeper, groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10002)}))
@ -225,14 +168,14 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
},
"proposal not pruned with group policy modified before tally": {
setupProposal: func(ctx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, s.app, ctx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
pID, err := submitProposalHelper(s, ctx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
s.Require().NoError(err)
_, err = s.groupKeeper.UpdateGroupPolicyMetadata(ctx, &group.MsgUpdateGroupPolicyMetadata{
Admin: addr1,
Admin: s.addrsStr[0],
GroupPolicyAddress: policyRes.Address,
})
s.Require().NoError(err)
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: addr3, ProposalId: pID})
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: s.addrsStr[2], ProposalId: pID})
s.Require().Error(err) // since proposal with status Aborted cannot be executed
s.Require().NoError(testutil.FundAccount(ctx, s.bankKeeper, groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10002)}))
@ -245,9 +188,9 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
"pruned when proposal is executable when failed before": {
setupProposal: func(ctx sdk.Context) uint64 {
msgs := []sdk.Msg{msgSend1}
pID, err := submitProposalAndVoteHelper(s, s.app, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
pID, err := submitProposalAndVoteHelper(s, ctx, msgs, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
s.Require().NoError(err)
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: addr3, ProposalId: pID})
_, err = s.groupKeeper.Exec(ctx, &group.MsgExec{Executor: s.addrsStr[2], ProposalId: pID})
s.Require().NoError(err)
return pID
},
@ -257,7 +200,7 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
},
"proposal with status withdrawn is pruned after voting period end": {
setupProposal: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, s.app, sdkCtx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
pID, err := submitProposalHelper(s, sdkCtx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
s.Require().NoError(err)
_, err = s.groupKeeper.WithdrawProposal(ctx, &group.MsgWithdrawProposal{
ProposalId: pID,
@ -272,7 +215,7 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
},
"proposal with status withdrawn is not pruned (before voting period)": {
setupProposal: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, s.app, sdkCtx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
pID, err := submitProposalHelper(s, sdkCtx, []sdk.Msg{msgSend1}, proposers, groupPolicyAddr)
s.Require().NoError(err)
_, err = s.groupKeeper.WithdrawProposal(ctx, &group.MsgWithdrawProposal{
ProposalId: pID,
@ -288,12 +231,12 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
},
"proposal with status aborted is pruned after voting period end (due to updated group policy decision policy)": {
setupProposal: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, s.app, sdkCtx, []sdk.Msg{msgSend2}, proposers, groupPolicyAddr2)
pID, err := submitProposalHelper(s, sdkCtx, []sdk.Msg{msgSend2}, proposers, groupPolicyAddr2)
s.Require().NoError(err)
policy := group.NewThresholdDecisionPolicy("3", time.Second, 0)
msg := &group.MsgUpdateGroupPolicyDecisionPolicy{
Admin: addr2,
Admin: s.addrsStr[1],
GroupPolicyAddress: policyRes2.Address,
}
err = msg.SetDecisionPolicy(policy)
@ -310,12 +253,12 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
},
"proposal with status aborted is not pruned before voting period end (due to updated group policy)": {
setupProposal: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, s.app, sdkCtx, []sdk.Msg{msgSend2}, proposers, groupPolicyAddr2)
pID, err := submitProposalHelper(s, sdkCtx, []sdk.Msg{msgSend2}, proposers, groupPolicyAddr2)
s.Require().NoError(err)
policy := group.NewThresholdDecisionPolicy("3", time.Second, 0)
msg := &group.MsgUpdateGroupPolicyDecisionPolicy{
Admin: addr2,
Admin: s.addrsStr[1],
GroupPolicyAddress: policyRes2.Address,
}
err = msg.SetDecisionPolicy(policy)
@ -369,27 +312,17 @@ func (s *IntegrationTestSuite) TestEndBlockerPruning() {
}
}
func (s *IntegrationTestSuite) TestEndBlockerTallying() {
app := s.app
ctx := s.ctx
addrs := s.addrs
addr0, err := s.addressCodec.BytesToString(addrs[0])
s.Require().NoError(err)
addr1, err := s.addressCodec.BytesToString(addrs[1])
s.Require().NoError(err)
addr2, err := s.addressCodec.BytesToString(addrs[2])
s.Require().NoError(err)
addr3, err := s.addressCodec.BytesToString(addrs[3])
s.Require().NoError(err)
func (s *TestSuite) TestEndBlockerTallying() {
ctx := s.sdkCtx
s.bankKeeper.EXPECT().Send(gomock.Any(), gomock.Any()).Return(&banktypes.MsgSendResponse{}, nil).AnyTimes()
// Initial group, group policy and balance setup
members := []group.MemberRequest{
{Address: addr1, Weight: "1"}, {Address: addr2, Weight: "2"},
{Address: s.addrsStr[1], Weight: "1"}, {Address: s.addrsStr[2], Weight: "2"},
}
groupRes, err := s.groupKeeper.CreateGroup(ctx, &group.MsgCreateGroup{
Admin: addr0,
Admin: s.addrsStr[0],
Members: members,
})
s.Require().NoError(err)
@ -403,12 +336,15 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
)
policyReq := &group.MsgCreateGroupPolicy{
Admin: addr0,
Admin: s.addrsStr[0],
GroupId: groupID,
}
err = policyReq.SetDecisionPolicy(policy)
s.Require().NoError(err)
s.setNextAccount()
policyRes, err := s.groupKeeper.CreateGroupPolicy(ctx, policyReq)
s.Require().NoError(err)
@ -419,11 +355,11 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
msgSend := &banktypes.MsgSend{
FromAddress: policyRes.Address,
ToAddress: addr3,
ToAddress: s.addrsStr[3],
Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)},
}
proposers := []string{addr2}
proposers := []string{s.addrsStr[2]}
specs := map[string]struct {
preRun func(sdkCtx sdk.Context) uint64
@ -435,7 +371,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
}{
"tally updated after voting period end": {
preRun: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, app, sdkCtx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr)
pID, err := submitProposalHelper(s, sdkCtx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr)
s.Require().NoError(err)
return pID
},
@ -446,7 +382,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
},
"tally within voting period": {
preRun: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, app, sdkCtx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr)
pID, err := submitProposalHelper(s, sdkCtx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr)
s.Require().NoError(err)
return pID
@ -458,7 +394,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
},
"tally within voting period(with votes)": {
preRun: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalAndVoteHelper(s, app, ctx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
pID, err := submitProposalAndVoteHelper(s, ctx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
s.Require().NoError(err)
return pID
@ -471,7 +407,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
"tally after voting period (not passing)": {
preRun: func(sdkCtx sdk.Context) uint64 {
// `addrs[1]` has weight 1
pID, err := submitProposalAndVoteHelper(s, app, ctx, []sdk.Msg{msgSend}, []string{addr1}, groupPolicyAddr, group.VOTE_OPTION_YES)
pID, err := submitProposalAndVoteHelper(s, ctx, []sdk.Msg{msgSend}, []string{s.addrsStr[1]}, groupPolicyAddr, group.VOTE_OPTION_YES)
s.Require().NoError(err)
return pID
@ -488,7 +424,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
},
"tally after voting period(with votes)": {
preRun: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalAndVoteHelper(s, app, ctx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
pID, err := submitProposalAndVoteHelper(s, ctx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
s.Require().NoError(err)
return pID
@ -505,7 +441,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
},
"tally of withdrawn proposal": {
preRun: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalHelper(s, app, sdkCtx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr)
pID, err := submitProposalHelper(s, sdkCtx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr)
s.Require().NoError(err)
_, err = s.groupKeeper.WithdrawProposal(ctx, &group.MsgWithdrawProposal{
@ -523,7 +459,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
},
"tally of withdrawn proposal (with votes)": {
preRun: func(sdkCtx sdk.Context) uint64 {
pID, err := submitProposalAndVoteHelper(s, app, ctx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
pID, err := submitProposalAndVoteHelper(s, ctx, []sdk.Msg{msgSend}, proposers, groupPolicyAddr, group.VOTE_OPTION_YES)
s.Require().NoError(err)
_, err = s.groupKeeper.WithdrawProposal(ctx, &group.MsgWithdrawProposal{
@ -564,7 +500,7 @@ func (s *IntegrationTestSuite) TestEndBlockerTallying() {
}
}
func submitProposalHelper(s *IntegrationTestSuite, app *runtime.App, ctx context.Context, msgs []sdk.Msg, proposers []string, groupPolicyAddr sdk.AccAddress) (uint64, error) {
func submitProposalHelper(s *TestSuite, ctx context.Context, msgs []sdk.Msg, proposers []string, groupPolicyAddr sdk.AccAddress) (uint64, error) {
gpAddr, err := s.addressCodec.BytesToString(groupPolicyAddr)
s.Require().NoError(err)
proposalReq := &group.MsgSubmitProposal{
@ -585,10 +521,10 @@ func submitProposalHelper(s *IntegrationTestSuite, app *runtime.App, ctx context
}
func submitProposalAndVoteHelper(
s *IntegrationTestSuite, app *runtime.App, ctx context.Context, msgs []sdk.Msg,
s *TestSuite, ctx context.Context, msgs []sdk.Msg,
proposers []string, groupPolicyAddr sdk.AccAddress, voteOption group.VoteOption,
) (uint64, error) {
myProposalID, err := submitProposalHelper(s, app, ctx, msgs, proposers, groupPolicyAddr)
myProposalID, err := submitProposalHelper(s, ctx, msgs, proposers, groupPolicyAddr)
if err != nil {
return 0, err
}
@ -600,5 +536,6 @@ func submitProposalAndVoteHelper(
if err != nil {
return 0, err
}
return myProposalID, nil
}

View File

@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/suite"
"go.uber.org/mock/gomock"
coreaddress "cosmossdk.io/core/address"
"cosmossdk.io/core/header"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
@ -18,7 +19,6 @@ import (
"cosmossdk.io/x/group/keeper"
"cosmossdk.io/x/group/module"
grouptestutil "cosmossdk.io/x/group/testutil"
minttypes "cosmossdk.io/x/mint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec/address"
@ -46,6 +46,7 @@ type TestSuite struct {
policy group.DecisionPolicy
groupKeeper keeper.Keeper
blockTime time.Time
addressCodec coreaddress.Codec
bankKeeper *grouptestutil.MockBankKeeper
accountKeeper *grouptestutil.MockAccountKeeper
}
@ -56,7 +57,7 @@ func (s *TestSuite) SetupTest() {
testCtx := testutil.DefaultContextWithDB(s.T(), key, storetypes.NewTransientStoreKey("transient_test"))
encCfg := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, module.AppModule{}, bank.AppModule{})
addressCodec := address.NewBech32Codec("cosmos")
s.addressCodec = address.NewBech32Codec("cosmos")
s.addrs = simtestutil.CreateIncrementalAccounts(6)
s.addrsStr = make([]string, len(s.addrs))
@ -64,14 +65,18 @@ func (s *TestSuite) SetupTest() {
ctrl := gomock.NewController(s.T())
s.accountKeeper = grouptestutil.NewMockAccountKeeper(ctrl)
var err error
for i := range s.addrs {
s.accountKeeper.EXPECT().GetAccount(gomock.Any(), s.addrs[i]).Return(authtypes.NewBaseAccountWithAddress(s.addrs[i])).AnyTimes()
s.addrsStr[i], err = addressCodec.BytesToString(s.addrs[i])
s.addrsStr[i], err = s.addressCodec.BytesToString(s.addrs[i])
s.Require().NoError(err)
}
s.accountKeeper.EXPECT().AddressCodec().Return(addressCodec).AnyTimes()
s.accountKeeper.EXPECT().AddressCodec().Return(s.addressCodec).AnyTimes()
s.accountKeeper.EXPECT().GetAccount(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
s.bankKeeper = grouptestutil.NewMockBankKeeper(ctrl)
s.bankKeeper.EXPECT().MintCoins(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
s.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
bApp := baseapp.NewBaseApp(
"group",
@ -85,6 +90,7 @@ func (s *TestSuite) SetupTest() {
env := runtime.NewEnvironment(runtime.NewKVStoreService(key), log.NewNopLogger(), runtime.EnvWithQueryRouterService(bApp.GRPCQueryRouter()), runtime.EnvWithMsgRouterService(bApp.MsgServiceRouter()))
config := group.DefaultConfig()
s.groupKeeper = keeper.NewKeeper(env, encCfg.Codec, s.accountKeeper, config)
s.ctx = testCtx.Ctx.WithHeaderInfo(header.Info{Time: s.blockTime})
s.sdkCtx = sdk.UnwrapSDKContext(s.ctx)
@ -121,17 +127,17 @@ func (s *TestSuite) SetupTest() {
policyRes, err := s.groupKeeper.CreateGroupPolicy(s.ctx, policyReq)
s.Require().NoError(err)
addrbz, err := addressCodec.StringToBytes(policyRes.Address)
addrbz, err := s.addressCodec.StringToBytes(policyRes.Address)
s.Require().NoError(err)
s.policy = policy
s.groupPolicyAddr = addrbz
s.groupPolicyStrAddr, err = addressCodec.BytesToString(s.groupPolicyAddr)
s.groupPolicyStrAddr, err = s.addressCodec.BytesToString(s.groupPolicyAddr)
s.Require().NoError(err)
s.bankKeeper.EXPECT().MintCoins(s.sdkCtx, minttypes.ModuleName, sdk.Coins{sdk.NewInt64Coin("test", 100000)}).Return(nil).AnyTimes()
err = s.bankKeeper.MintCoins(s.sdkCtx, minttypes.ModuleName, sdk.Coins{sdk.NewInt64Coin("test", 100000)})
s.bankKeeper.EXPECT().MintCoins(s.sdkCtx, testutil.MintModuleName, sdk.Coins{sdk.NewInt64Coin("test", 100000)}).Return(nil).AnyTimes()
err = s.bankKeeper.MintCoins(s.sdkCtx, testutil.MintModuleName, sdk.Coins{sdk.NewInt64Coin("test", 100000)})
s.Require().NoError(err)
s.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(s.sdkCtx, minttypes.ModuleName, s.groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10000)}).Return(nil).AnyTimes()
err = s.bankKeeper.SendCoinsFromModuleToAccount(s.sdkCtx, minttypes.ModuleName, s.groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10000)})
s.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(s.sdkCtx, testutil.MintModuleName, s.groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10000)}).Return(nil).AnyTimes()
err = s.bankKeeper.SendCoinsFromModuleToAccount(s.sdkCtx, testutil.MintModuleName, s.groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10000)})
s.Require().NoError(err)
}

View File

@ -15,9 +15,9 @@ import (
"cosmossdk.io/x/group"
"cosmossdk.io/x/group/internal/math"
"cosmossdk.io/x/group/keeper"
minttypes "cosmossdk.io/x/mint/types"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/testutil"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -2054,8 +2054,8 @@ func (s *TestSuite) TestVote() {
s.Require().NoError(err)
s.Require().NotNil(groupPolicy)
s.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(s.sdkCtx, minttypes.ModuleName, groupPolicy, sdk.Coins{sdk.NewInt64Coin("test", 10000)}).Return(nil).AnyTimes()
s.Require().NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.sdkCtx, minttypes.ModuleName, groupPolicy, sdk.Coins{sdk.NewInt64Coin("test", 10000)}))
s.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(s.sdkCtx, testutil.MintModuleName, groupPolicy, sdk.Coins{sdk.NewInt64Coin("test", 10000)}).Return(nil).AnyTimes()
s.Require().NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.sdkCtx, testutil.MintModuleName, groupPolicy, sdk.Coins{sdk.NewInt64Coin("test", 10000)}))
req := &group.MsgSubmitProposal{
GroupPolicyAddress: accountAddr,
@ -2719,7 +2719,7 @@ func (s *TestSuite) TestExecProposal() {
s.bankKeeper.EXPECT().Send(gomock.Any(), msgSend2).Return(&banktypes.MsgSendResponse{}, nil)
s.Require().NoError(err)
s.Require().NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.sdkCtx, minttypes.ModuleName, s.groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10000)}))
s.Require().NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.sdkCtx, testutil.MintModuleName, s.groupPolicyAddr, sdk.Coins{sdk.NewInt64Coin("test", 10000)}))
return myProposalID
},

View File

@ -1,26 +0,0 @@
package testutil
import (
_ "cosmossdk.io/x/accounts" // import as blank for app wiring
_ "cosmossdk.io/x/bank" // import as blank for app wiring
_ "cosmossdk.io/x/consensus" // import as blank for app wiring
_ "cosmossdk.io/x/group/module" // import as blank for app wiring
_ "cosmossdk.io/x/mint" // import as blank for app wiring
_ "cosmossdk.io/x/staking" // import as blank for app wiring
"github.com/cosmos/cosmos-sdk/testutil/configurator"
_ "github.com/cosmos/cosmos-sdk/x/auth" // import as blank for app wiring
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import as blank for app wiring
_ "github.com/cosmos/cosmos-sdk/x/genutil" // import as blank for app wiring
)
var AppConfig = configurator.NewAppConfig(
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.BankModule(),
configurator.StakingModule(),
configurator.TxModule(),
configurator.ConsensusModule(),
configurator.GenutilModule(),
configurator.GroupModule(),
)

View File

@ -5,7 +5,7 @@ package testutil
import (
"context"
address "cosmossdk.io/core/address"
"cosmossdk.io/core/address"
bank "cosmossdk.io/x/bank/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -35,5 +35,11 @@ type BankKeeper interface {
SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins
MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error
SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error
GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins
}
// StakingKeeper defines the expected staking keeper interface for tests
type StakingKeeper interface {
BondDenom(ctx context.Context) (string, error)
}

View File

@ -220,6 +220,20 @@ func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToAccount(ctx, senderMo
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToAccount", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToAccount), ctx, senderModule, recipientAddr, amt)
}
// SendCoinsFromModuleToModule mocks base method.
func (m *MockBankKeeper) SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt types0.Coins) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SendCoinsFromModuleToModule", ctx, senderModule, recipientModule, amt)
ret0, _ := ret[0].(error)
return ret0
}
// SendCoinsFromModuleToModule indicates an expected call of SendCoinsFromModuleToModule.
func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToModule(ctx, senderModule, recipientModule, amt any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToModule", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToModule), ctx, senderModule, recipientModule, amt)
}
// SetSendEnabled mocks base method.
func (m *MockBankKeeper) SetSendEnabled(arg0 context.Context, arg1 *types.MsgSetSendEnabled) (*types.MsgSetSendEnabledResponse, error) {
m.ctrl.T.Helper()
@ -263,3 +277,42 @@ func (mr *MockBankKeeperMockRecorder) UpdateParams(arg0, arg1 any) *gomock.Call
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateParams", reflect.TypeOf((*MockBankKeeper)(nil).UpdateParams), arg0, arg1)
}
// MockStakingKeeper is a mock of StakingKeeper interface.
type MockStakingKeeper struct {
ctrl *gomock.Controller
recorder *MockStakingKeeperMockRecorder
isgomock struct{}
}
// MockStakingKeeperMockRecorder is the mock recorder for MockStakingKeeper.
type MockStakingKeeperMockRecorder struct {
mock *MockStakingKeeper
}
// NewMockStakingKeeper creates a new mock instance.
func NewMockStakingKeeper(ctrl *gomock.Controller) *MockStakingKeeper {
mock := &MockStakingKeeper{ctrl: ctrl}
mock.recorder = &MockStakingKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder {
return m.recorder
}
// BondDenom mocks base method.
func (m *MockStakingKeeper) BondDenom(ctx context.Context) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BondDenom", ctx)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BondDenom indicates an expected call of BondDenom.
func (mr *MockStakingKeeperMockRecorder) BondDenom(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BondDenom", reflect.TypeOf((*MockStakingKeeper)(nil).BondDenom), ctx)
}

View File

@ -39,6 +39,5 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#20363](https://github.com/cosmos/cosmos-sdk/pull/20363) Deprecated InflationCalculationFn in favor of MintFn, `keeper.DefaultMintFn` wrapper must be used in order to continue using it in `NewAppModule`. This is not breaking for depinject users, as both `MintFn` and `InflationCalculationFn` are accepted.
* [#19367](https://github.com/cosmos/cosmos-sdk/pull/19398) `appmodule.Environment` is received on the Keeper to get access to different application services.
* [#21858](https://github.com/cosmos/cosmos-sdk/pull/21858) `NewKeeper` now returns a pointer to `Keeper`.
* [#21858](https://github.com/cosmos/cosmos-sdk/pull/21858) `DefaultMintFn` now takes `StakingKeeper` and `MintKeeper` as arguments to avoid staking keeper being required by mint.
* [#21858](https://github.com/cosmos/cosmos-sdk/pull/21858), [#22979](https://github.com/cosmos/cosmos-sdk/pull/22979) `DefaultMintFn` now takes `StakingKeeper` and `MintKeeper` as arguments to avoid staking keeper being required by mint.
* `SetMintFn` is used to replace the default minting function.
* `InflationCalculationFn` is not passed through depinject any longer, a MintFn is required instead.

View File

@ -77,11 +77,22 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
return ModuleOutputs{MintKeeper: k, Module: m, EpochHooks: epochstypes.EpochHooksWrapper{EpochHooks: m}}
}
func InvokeSetMintFn(mintKeeper *keeper.Keeper, mintFn types.MintFn, stakingKeeper types.StakingKeeper) error {
if mintFn == nil && stakingKeeper == nil {
return fmt.Errorf("custom minting function or staking keeper must be supplied or available")
func InvokeSetMintFn(
mintKeeper *keeper.Keeper,
stakingKeeper types.StakingKeeper,
mintFn types.MintFn,
inflationCalculationFn types.InflationCalculationFn,
) error {
if mintFn == nil && stakingKeeper == nil && inflationCalculationFn == nil {
return fmt.Errorf("custom minting function, inflation calculation function or staking keeper must be supplied or available")
} else if mintFn != nil && inflationCalculationFn != nil {
return fmt.Errorf("cannot set both custom minting function and inflation calculation function")
} else if mintFn == nil {
mintFn = keeper.DefaultMintFn(types.DefaultInflationCalculationFn, stakingKeeper, mintKeeper)
if inflationCalculationFn != nil && stakingKeeper != nil {
mintFn = keeper.DefaultMintFn(inflationCalculationFn, stakingKeeper, mintKeeper)
} else {
mintFn = keeper.DefaultMintFn(types.DefaultInflationCalculationFn, stakingKeeper, mintKeeper)
}
}
return mintKeeper.SetMintFn(mintFn)

View File

@ -179,7 +179,6 @@ replace github.com/cosmos/cosmos-sdk => ../../.
// TODO remove post spinning out all modules
replace (
cosmossdk.io/x/bank => ../bank
cosmossdk.io/x/consensus => ../consensus
cosmossdk.io/x/epochs => ../epochs
cosmossdk.io/x/staking => ../staking
)

View File

@ -168,10 +168,6 @@ replace github.com/cosmos/cosmos-sdk => ../..
// TODO remove post spinning out all modules
replace (
cosmossdk.io/x/bank => ../bank
cosmossdk.io/x/distribution => ../distribution
cosmossdk.io/x/gov => ../gov
cosmossdk.io/x/mint => ../mint
cosmossdk.io/x/protocolpool => ../protocolpool
cosmossdk.io/x/slashing => ../slashing
cosmossdk.io/x/staking => ../staking
)