diff --git a/x/accounts/defaults/lockup/lockup.go b/x/accounts/defaults/lockup/lockup.go index a1582bf5c625..7d5259d1151c 100644 --- a/x/accounts/defaults/lockup/lockup.go +++ b/x/accounts/defaults/lockup/lockup.go @@ -381,7 +381,6 @@ func (bva *BaseLockup) checkUnbondingEntriesMature(ctx context.Context) error { if !errorsmod.IsOf(err, stakingtypes.ErrNoUnbondingDelegation) { return true, err } - } found := false diff --git a/x/accounts/defaults/lockup/utils_test.go b/x/accounts/defaults/lockup/utils_test.go index 684e43b79bd3..18a8672467f5 100644 --- a/x/accounts/defaults/lockup/utils_test.go +++ b/x/accounts/defaults/lockup/utils_test.go @@ -125,7 +125,6 @@ func newMockContext(t *testing.T) (context.Context, store.KVStoreService) { default: return nil, errors.New("unrecognized request type") } - }, ) } diff --git a/x/bank/testutil/helpers.go b/x/bank/testutil/helpers.go index 8167097cc533..0305360ad5e3 100644 --- a/x/bank/testutil/helpers.go +++ b/x/bank/testutil/helpers.go @@ -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 } diff --git a/x/group/go.mod b/x/group/go.mod index 2440da3ddddc..18e809716ebb 100644 --- a/x/group/go.mod +++ b/x/group/go.mod @@ -10,12 +10,8 @@ require ( cosmossdk.io/log v1.5.0 cosmossdk.io/math v1.4.0 cosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43 - cosmossdk.io/x/accounts v0.0.0-20241218110910-47409028a73d cosmossdk.io/x/bank v0.0.0-20241218110910-47409028a73d - cosmossdk.io/x/consensus v0.0.0-20241218110910-47409028a73d cosmossdk.io/x/gov v0.0.0-20241218110910-47409028a73d - cosmossdk.io/x/mint v0.0.0-20241218110910-47409028a73d - cosmossdk.io/x/staking v0.0.0-20241218110910-47409028a73d github.com/cockroachdb/apd/v3 v3.2.1 github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/cosmos-sdk v0.52.0 @@ -26,6 +22,7 @@ require ( github.com/manifoldco/promptui v0.9.0 // indirect github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.10.0 + go.uber.org/mock v0.5.0 google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 google.golang.org/grpc v1.68.1 google.golang.org/protobuf v1.36.0 @@ -39,7 +36,7 @@ require ( cosmossdk.io/collections v1.0.0-rc.1 // indirect; main cosmossdk.io/core/testing v0.0.1 // main cosmossdk.io/schema v1.0.0 // indirect - cosmossdk.io/x/epochs v0.0.0-20241218110910-47409028a73d // indirect + cosmossdk.io/x/staking v0.0.0-20241218110910-47409028a73d // indirect cosmossdk.io/x/tx v1.0.0-alpha.3 // indirect; main filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect diff --git a/x/group/go.sum b/x/group/go.sum index 769b88231824..402d4f569b36 100644 --- a/x/group/go.sum +++ b/x/group/go.sum @@ -26,18 +26,10 @@ 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.0.20241218084712-ca559989da43 h1:glZ6MpmD+5AhwJYV4jzx+rn7cgUB2owHgk9o+93luz0= cosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43/go.mod h1:XCWpgfueHSBY+B7Cf2Aq/CcsU+6XoFH+EmseCKglFrU= -cosmossdk.io/x/accounts v0.0.0-20241218110910-47409028a73d h1:CKZrLb3TdsLndtgn/JW9714+yORLZUzMAStoMxO04vA= -cosmossdk.io/x/accounts v0.0.0-20241218110910-47409028a73d/go.mod h1:S3kRYNjtI43SoV8NMWHQURagS6YF6nI/GJavmO3qkZA= cosmossdk.io/x/bank v0.0.0-20241218110910-47409028a73d h1:8Sw9mmz+P/H0iURZkRHKmpkmr9Lm3eGM2yRZveU2GWs= cosmossdk.io/x/bank v0.0.0-20241218110910-47409028a73d/go.mod h1:C5yLe3vDDDHcWMSfa1lfgglczjjMGfOc4nYDmk69U2w= -cosmossdk.io/x/consensus v0.0.0-20241218110910-47409028a73d h1:QS4K8VcvPbvX830RYfhUpH+jxf4OPspf18ZGwGY2L7k= -cosmossdk.io/x/consensus v0.0.0-20241218110910-47409028a73d/go.mod h1:cAMIG6gRzZd3paDdXYjQTCK96nEDIgZcc/JDN/0Qf6Y= -cosmossdk.io/x/epochs v0.0.0-20241218110910-47409028a73d h1:EkjwLMsu4nD8c1lfMY7BHdgcrtB0fAI7W7CnwSeHwf4= -cosmossdk.io/x/epochs v0.0.0-20241218110910-47409028a73d/go.mod h1:F8AIIsAqDpWONRkIk6kOOtcTQ8rk/zsLCyaU34LacB8= cosmossdk.io/x/gov v0.0.0-20241218110910-47409028a73d h1:CCC1PbH/Xn+QI2CDw8+ejt+bYlPisJqecSnFnV8TYKQ= cosmossdk.io/x/gov v0.0.0-20241218110910-47409028a73d/go.mod h1:vvU5Fl4NY0m6r35xKxctzg4aYmRuEytfQwl1UFCyrlk= -cosmossdk.io/x/mint v0.0.0-20241218110910-47409028a73d h1:oMWZ3namACACVoUJYcHn6sXwKUFrSFGMSE/7yWiCKGs= -cosmossdk.io/x/mint v0.0.0-20241218110910-47409028a73d/go.mod h1:i2nMfOwxslF2o5y+tdbvphNcoIW/EnmY69x9NBpWdtk= 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/staking v0.0.0-20241218110910-47409028a73d h1:Ey5BddfuPEQACiDgeb9SqvHr533RH7rd2GDNIgV45hk= diff --git a/x/group/keeper/abci_test.go b/x/group/keeper/abci_test.go index 9cd40f8edb3d..a5110b63ada9 100644 --- a/x/group/keeper/abci_test.go +++ b/x/group/keeper/abci_test.go @@ -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 } diff --git a/x/group/keeper/keeper_test.go b/x/group/keeper/keeper_test.go index 449fe039407f..fc2febe42470 100644 --- a/x/group/keeper/keeper_test.go +++ b/x/group/keeper/keeper_test.go @@ -9,6 +9,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/suite" + 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) } diff --git a/x/group/keeper/msg_server_test.go b/x/group/keeper/msg_server_test.go index 3e90729856d5..f4ec497f7626 100644 --- a/x/group/keeper/msg_server_test.go +++ b/x/group/keeper/msg_server_test.go @@ -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 }, diff --git a/x/group/testutil/app_config.go b/x/group/testutil/app_config.go deleted file mode 100644 index 7d5c25768057..000000000000 --- a/x/group/testutil/app_config.go +++ /dev/null @@ -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(), -) diff --git a/x/group/testutil/expected_keepers.go b/x/group/testutil/expected_keepers.go index 04f9ac3d87f5..ca0b61c06892 100644 --- a/x/group/testutil/expected_keepers.go +++ b/x/group/testutil/expected_keepers.go @@ -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) +} diff --git a/x/group/testutil/expected_keepers_mocks.go b/x/group/testutil/expected_keepers_mocks.go index b957703406e7..f16a9a269b75 100644 --- a/x/group/testutil/expected_keepers_mocks.go +++ b/x/group/testutil/expected_keepers_mocks.go @@ -213,6 +213,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 interface{}) *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() @@ -256,3 +270,41 @@ func (mr *MockBankKeeperMockRecorder) UpdateParams(arg0, arg1 interface{}) *gomo 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 +} + +// 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 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BondDenom", reflect.TypeOf((*MockStakingKeeper)(nil).BondDenom), ctx) +}