refactor: simplify group dependency graph (partial backport #22978) (#22982)

Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
mergify[bot] 2024-12-18 15:36:37 +01:00 committed by GitHub
parent 98acf3af8f
commit d2dd935351
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 150 additions and 181 deletions

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

@ -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

View File

@ -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=

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/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)
}

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

@ -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)
}