Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

test: Add Proposal for multistaking module #131

Merged
merged 20 commits into from
Feb 28, 2024
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bu
### Protobuf ###
###############################################################################

protoVer=0.14.0
protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer)
protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName)
protoVer=v0.7
protoImageName=tendermintdev/sdk-proto-gen:$(protoVer)
protoImage=$(DOCKER) run --network host --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName)

proto-all: proto-format proto-lint proto-gen

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/cosmos/cosmos-proto v1.0.0-alpha8
github.com/cosmos/cosmos-sdk v0.46.12
github.com/cosmos/gogoproto v1.4.11
github.com/gogo/protobuf v1.3.3
github.com/golang/protobuf v1.5.3
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
Expand Down Expand Up @@ -71,7 +72,6 @@ require (
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/gateway v1.1.0 // indirect
github.com/gogo/protobuf v1.3.3 // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect
Expand Down
5 changes: 4 additions & 1 deletion test/simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ var (
distrclient.ProposalHandler,
upgradeclient.LegacyProposalHandler,
upgradeclient.LegacyCancelProposalHandler,
multistaking.AddMultiStakingProposalHandler,
multistaking.UpdateBondWeightProposalHandler,
},
),
groupmodule.AppModuleBasic{},
Expand Down Expand Up @@ -300,7 +302,8 @@ func NewSimApp(
govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(multistakingtypes.RouterKey, multistaking.NewMultiStakingProposalHandler(&app.MultiStakingKeeper))

govConfig := govtypes.DefaultConfig()
/*
Expand Down
85 changes: 85 additions & 0 deletions x/multi-staking/client/cli/proposal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package cli

import (
"github.com/realio-tech/multi-staking-module/x/multi-staking/types"
"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

func NewCmdSubmitAddMultiStakingCoinProposal() *cobra.Command {
cmd := &cobra.Command{
Use: "add-multistaking-coin [title] [description] [denom] [bond_weight] [deposit]",
Args: cobra.ExactArgs(5),
Short: "Submit an add multistaking coin proposal",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

bondWeight, err := sdk.NewDecFromStr(args[3])
if err != nil {
return err
}
from := clientCtx.GetFromAddress()
content := types.NewAddMultiStakingCoinProposal(
args[0], args[1], args[2], bondWeight,
)

deposit, err := sdk.ParseCoinsNormalized(args[4])
if err != nil {
return err
}

msg, err := govv1beta1.NewMsgSubmitProposal(content, deposit, from)
if err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

return cmd
}

func NewCmdUpdateBondWeightProposal() *cobra.Command {
cmd := &cobra.Command{
Use: "update-bond-weight [title] [description] [denom] [bond_weight] [deposit]",
Args: cobra.ExactArgs(5),
Short: "Submit update bond weight for bond coin proposal",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

bondWeight, err := sdk.NewDecFromStr(args[3])
if err != nil {
return err
}
from := clientCtx.GetFromAddress()
content := types.NewUpdateBondWeightProposal(
args[0], args[1], args[2], bondWeight,
)

deposit, err := sdk.ParseCoinsNormalized(args[4])
if err != nil {
return err
}

msg, err := govv1beta1.NewMsgSubmitProposal(content, deposit, from)
if err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

return cmd
}
4 changes: 3 additions & 1 deletion x/multi-staking/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
Expand All @@ -26,6 +27,7 @@ type KeeperTestSuite struct {
app *simapp.SimApp
ctx sdk.Context
msKeeper *multistakingkeeper.Keeper
govKeeper govkeeper.Keeper
msgServer stakingtypes.MsgServer
}

Expand All @@ -34,7 +36,7 @@ func (suite *KeeperTestSuite) SetupTest() {
ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: app.LastBlockHeight() + 1})
multiStakingMsgServer := multistakingkeeper.NewMsgServerImpl(app.MultiStakingKeeper)

suite.app, suite.ctx, suite.msKeeper, suite.msgServer = app, ctx, &app.MultiStakingKeeper, multiStakingMsgServer
suite.app, suite.ctx, suite.msKeeper, suite.govKeeper, suite.msgServer = app, ctx, &app.MultiStakingKeeper, app.GovKeeper, multiStakingMsgServer
}

func TestKeeperTestSuite(t *testing.T) {
Expand Down
62 changes: 62 additions & 0 deletions x/multi-staking/keeper/proposal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package keeper

import (
"fmt"

"github.com/realio-tech/multi-staking-module/x/multi-staking/types"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// AddMultiStakingCoinProposal handles the proposals to add a new bond token
func (k Keeper) AddMultiStakingCoinProposal(
ctx sdk.Context,
p *types.AddMultiStakingCoinProposal,
) error {
_, found := k.GetBondWeight(ctx, p.Denom)
if found {
return fmt.Errorf("Error MultiStakingCoin %s already exist", p.Denom) //nolint:stylecheck
}

bondWeight := *p.BondWeight
if bondWeight.LTE(sdk.ZeroDec()) {
return fmt.Errorf("Error MultiStakingCoin BondWeight %s invalid", bondWeight) //nolint:stylecheck
}

k.SetBondWeight(ctx, p.Denom, bondWeight)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAddMultiStakingCoin,
sdk.NewAttribute(types.AttributeKeyDenom, p.Denom),
sdk.NewAttribute(types.AttributeKeyBondWeight, p.BondWeight.String()),
),
)
return nil
}

func (k Keeper) BondWeightProposal(
ctx sdk.Context,
p *types.UpdateBondWeightProposal,
) error {
_, found := k.GetBondWeight(ctx, p.Denom)
if !found {
return fmt.Errorf("Error MultiStakingCoin %s not found", p.Denom) //nolint:stylecheck
}

bondWeight := *p.UpdatedBondWeight
if bondWeight.LTE(sdk.ZeroDec()) {
return fmt.Errorf("Error MultiStakingCoin BondWeight %s invalid", bondWeight) //nolint:stylecheck
}

k.SetBondWeight(ctx, p.Denom, bondWeight)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAddMultiStakingCoin,
sdk.NewAttribute(types.AttributeKeyDenom, p.Denom),
sdk.NewAttribute(types.AttributeKeyBondWeight, p.UpdatedBondWeight.String()),
),
)
return nil
}
141 changes: 141 additions & 0 deletions x/multi-staking/keeper/proposal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package keeper_test

import (
"github.com/realio-tech/multi-staking-module/x/multi-staking/types"

sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govv1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
)

func (suite *KeeperTestSuite) TestAddMultiStakingCoinProposal() {
bondWeight := sdk.NewDec(1)

for _, tc := range []struct {
desc string
malleate func(p *types.AddMultiStakingCoinProposal)
proposal *types.AddMultiStakingCoinProposal
shouldErr bool
}{
{
desc: "Success",
malleate: func(p *types.AddMultiStakingCoinProposal) {
_, found := suite.msKeeper.GetBondWeight(suite.ctx, p.Denom)
suite.Require().False(found)
},
proposal: &types.AddMultiStakingCoinProposal{
Title: "Add multistaking coin",
Description: "Add new multistaking coin",
Denom: "stake1",
BondWeight: &bondWeight,
},
shouldErr: false,
},
{
desc: "Error multistaking coin already exists",
malleate: func(p *types.AddMultiStakingCoinProposal) {
suite.msKeeper.SetBondWeight(suite.ctx, p.Denom, *p.BondWeight)
},
proposal: &types.AddMultiStakingCoinProposal{
Title: "Add multistaking coin",
Description: "Add new multistaking coin",
Denom: "stake2",
BondWeight: &bondWeight,
},
shouldErr: true,
},
} {
tc := tc
suite.Run(tc.desc, func() {
suite.SetupTest()
tc.malleate(tc.proposal)

legacyProposal, err := govv1types.NewLegacyContent(tc.proposal, authtypes.NewModuleAddress(govtypes.ModuleName).String())
suite.Require().NoError(err)

if !tc.shouldErr {
// store proposal
_, err = suite.govKeeper.SubmitProposal(suite.ctx, []sdk.Msg{legacyProposal}, "")
suite.Require().NoError(err)

// execute proposal
handler := suite.govKeeper.LegacyRouter().GetRoute(tc.proposal.ProposalRoute())
err = handler(suite.ctx, tc.proposal)
suite.Require().NoError(err)

_, found := suite.msKeeper.GetBondWeight(suite.ctx, tc.proposal.Denom)
suite.Require().True(found)
} else {
// store proposal
_, err = suite.govKeeper.SubmitProposal(suite.ctx, []sdk.Msg{legacyProposal}, "")
suite.Require().Error(err)
}
})
}
}

func (suite *KeeperTestSuite) TestUpdateBondWeightProposal() {
bondWeight := sdk.NewDec(1)

for _, tc := range []struct {
desc string
malleate func(p *types.UpdateBondWeightProposal)
proposal *types.UpdateBondWeightProposal
shouldErr bool
}{
{
desc: "Success",
malleate: func(p *types.UpdateBondWeightProposal) {
oldBondWeight := sdk.NewDec(2)
suite.msKeeper.SetBondWeight(suite.ctx, p.Denom, oldBondWeight)
},
proposal: &types.UpdateBondWeightProposal{
Title: "Add multistaking coin",
Description: "Add new multistaking coin",
Denom: "stake1",
UpdatedBondWeight: &bondWeight,
},
shouldErr: false,
},
{
desc: "Error multistaking coin not exists",
malleate: func(p *types.UpdateBondWeightProposal) {},
proposal: &types.UpdateBondWeightProposal{
Title: "Add multistaking coin",
Description: "Add new multistaking coin",
Denom: "stake2",
UpdatedBondWeight: &bondWeight,
},
shouldErr: true,
},
} {
tc := tc
suite.Run(tc.desc, func() {
suite.SetupTest()
tc.malleate(tc.proposal)

legacyProposal, err := govv1types.NewLegacyContent(tc.proposal, authtypes.NewModuleAddress(govtypes.ModuleName).String())
suite.Require().NoError(err)

if !tc.shouldErr {
// store proposal
_, err = suite.govKeeper.SubmitProposal(suite.ctx, []sdk.Msg{legacyProposal}, "")
suite.Require().NoError(err)

// execute proposal
handler := suite.govKeeper.LegacyRouter().GetRoute(tc.proposal.ProposalRoute())
err = handler(suite.ctx, tc.proposal)
suite.Require().NoError(err)

weight, found := suite.msKeeper.GetBondWeight(suite.ctx, tc.proposal.Denom)
suite.Require().True(found)
suite.Require().True(weight.Equal(bondWeight))
} else {
// store proposal
_, err = suite.govKeeper.SubmitProposal(suite.ctx, []sdk.Msg{legacyProposal}, "")
suite.Require().Error(err)
}
})
}
}
2 changes: 2 additions & 0 deletions x/multi-staking/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ func (AppModuleBasic) Name() string {

// RegisterLegacyAminoCodec register module codec
func (am AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
multistakingtypes.RegisterLegacyAminoCodec(cdc)
}

// RegisterInterfaces registers the module interface
func (am AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) {
multistakingtypes.RegisterInterfaces(reg)
}

// DefaultGenesis returns multi-staking module default genesis state.
Expand Down
Loading
Loading