feat(x/distribution): add autocli options for tx (#17963)

This commit is contained in:
Julien Robert 2023-10-11 08:10:10 +02:00 committed by GitHub
parent 28dbfecac5
commit 44934e3b68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 688 additions and 820 deletions

View File

@ -164,6 +164,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
### CLI Breaking Changes
* (x/distribution) [#17963](https://github.com/cosmos/cosmos-sdk/pull/17963) `appd tx distribution withdraw-rewards` now only withdraws rewards for the delegator's own delegations. For withdrawing validators commission, use `appd tx distribution withdraw-validator-commission`.
### State Machine Breaking
* (x/distribution) [#17657](https://github.com/cosmos/cosmos-sdk/pull/17657) Migrate community pool funds from x/distribution to x/protocolpool.

View File

@ -10,7 +10,6 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/testutil/network"
@ -387,5 +386,5 @@ func MsgMultiSendExec(clientCtx client.Context, from sdk.AccAddress, to []sdk.Ac
args = append(args, amount.String())
args = append(args, extraArgs...)
return clitestutil.ExecTestCLICmd(clientCtx, cli.NewMultiSendTxCmd(addresscodec.NewBech32Codec("cosmos")), args)
return clitestutil.ExecTestCLICmd(clientCtx, cli.NewMultiSendTxCmd(), args)
}

View File

@ -9,14 +9,10 @@ import (
"github.com/stretchr/testify/suite"
)
func TestE2ETestSuite(t *testing.T) {
suite.Run(t, new(E2ETestSuite))
func TestWithdrawAllSuite(t *testing.T) {
suite.Run(t, new(WithdrawAllTestSuite))
}
func TestGRPCQueryTestSuite(t *testing.T) {
suite.Run(t, new(GRPCQueryTestSuite))
}
func TestWithdrawAllSuite(t *testing.T) {
suite.Run(t, new(WithdrawAllTestSuite))
}

View File

@ -1,330 +0,0 @@
package distribution
import (
"context"
"encoding/hex"
"fmt"
"time"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/suite"
"cosmossdk.io/math"
"cosmossdk.io/simapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec/address"
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/client/cli"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
)
type E2ETestSuite struct {
suite.Suite
cfg network.Config
network *network.Network
}
func NewE2ETestSuite(cfg network.Config) *E2ETestSuite {
return &E2ETestSuite{cfg: cfg}
}
// SetupSuite creates a new network for _each_ e2e test. We create a new
// network for each test because there are some state modifications that are
// needed to be made in order to make useful queries. However, we don't want
// these state changes to be present in other tests.
func (s *E2ETestSuite) SetupSuite() {
s.T().Log("setting up e2e test suite")
cfg := network.DefaultConfig(simapp.NewTestNetworkFixture)
cfg.NumValidators = 1
s.cfg = cfg
genesisState := s.cfg.GenesisState
var mintData minttypes.GenesisState
s.Require().NoError(s.cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData))
inflation := math.LegacyMustNewDecFromStr("1.0")
mintData.Minter.Inflation = inflation
mintData.Params.InflationMin = inflation
mintData.Params.InflationMax = inflation
mintDataBz, err := s.cfg.Codec.MarshalJSON(&mintData)
s.Require().NoError(err)
genesisState[minttypes.ModuleName] = mintDataBz
s.cfg.GenesisState = genesisState
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
s.Require().NoError(err)
s.Require().NoError(s.network.WaitForNextBlock())
}
// TearDownSuite cleans up the curret test network after _each_ test.
func (s *E2ETestSuite) TearDownSuite() {
s.T().Log("tearing down e2e test suite1")
s.network.Cleanup()
}
func (s *E2ETestSuite) TestNewWithdrawRewardsCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string
valAddr fmt.Stringer
args []string
expectErr bool
expectedCode uint32
respType proto.Message
expectedResponseType []string
}{
{
"invalid validator address",
val.Address,
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
true, 0, nil,
[]string{},
},
{
"valid transaction",
sdk.ValAddress(val.Address),
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
false, 0, &sdk.TxResponse{},
[]string{
"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse",
},
},
{
"valid transaction (with commission)",
sdk.ValAddress(val.Address),
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=true", cli.FlagCommission),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
false, 0, &sdk.TxResponse{},
[]string{
"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse",
"/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommissionResponse",
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
clientCtx := val.ClientCtx
args := append([]string{tc.valAddr.String()}, tc.args...)
_, _ = s.network.WaitForHeightWithTimeout(10, time.Minute)
ctx := svrcmd.CreateExecuteContext(context.Background())
cmd := cli.NewWithdrawRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
cmd.SetContext(ctx)
cmd.SetArgs(args)
s.Require().NoError(client.SetCmdClientContextHandler(clientCtx, cmd))
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
s.Require().NoError(s.network.WaitForNextBlock())
txResp, err := clitestutil.GetTxResponse(s.network, clientCtx, tc.respType.(*sdk.TxResponse).TxHash)
s.Require().NoError(err)
s.Require().Equal(tc.expectedCode, txResp.Code)
data, err := hex.DecodeString(txResp.Data)
s.Require().NoError(err)
txMsgData := sdk.TxMsgData{}
err = s.cfg.Codec.Unmarshal(data, &txMsgData)
s.Require().NoError(err)
for responseIdx, msgResponse := range txMsgData.MsgResponses {
s.Require().Equal(tc.expectedResponseType[responseIdx], msgResponse.TypeUrl)
switch msgResponse.TypeUrl {
case "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse":
var resp distrtypes.MsgWithdrawDelegatorRewardResponse
// can't use unpackAny as response types are not registered.
err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp)
s.Require().NoError(err)
s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))),
fmt.Sprintf("expected a positive coin value, got %v", resp.Amount))
case "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommissionResponse":
var resp distrtypes.MsgWithdrawValidatorCommissionResponse
// can't use unpackAny as response types are not registered.
err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp)
s.Require().NoError(err)
s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))),
fmt.Sprintf("expected a positive coin value, got %v", resp.Amount))
}
}
}
})
}
}
func (s *E2ETestSuite) TestNewWithdrawAllRewardsCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string
args []string
expectErr bool
expectedCode uint32
respType proto.Message
expectedResponseType []string
}{
{
"valid transaction (offline)",
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagOffline),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
true, 0, nil,
[]string{},
},
{
"valid transaction",
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
false, 0, &sdk.TxResponse{},
[]string{
"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse",
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
clientCtx := val.ClientCtx
_, _ = s.network.WaitForHeightWithTimeout(10, time.Minute)
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
s.Require().NoError(s.network.WaitForNextBlock())
txResp, err := clitestutil.GetTxResponse(s.network, clientCtx, tc.respType.(*sdk.TxResponse).TxHash)
s.Require().NoError(err)
s.Require().Equal(tc.expectedCode, txResp.Code)
data, err := hex.DecodeString(txResp.Data)
s.Require().NoError(err)
txMsgData := sdk.TxMsgData{}
err = s.cfg.Codec.Unmarshal(data, &txMsgData)
s.Require().NoError(err)
for responseIdx, msgResponse := range txMsgData.MsgResponses {
s.Require().Equal(tc.expectedResponseType[responseIdx], msgResponse.TypeUrl)
switch msgResponse.TypeUrl {
case "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse":
var resp distrtypes.MsgWithdrawDelegatorRewardResponse
// can't use unpackAny as response types are not registered.
err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp)
s.Require().NoError(err)
s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))),
fmt.Sprintf("expected a positive coin value, got %v", resp.Amount))
case "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommissionResponse":
var resp distrtypes.MsgWithdrawValidatorCommissionResponse
// can't use unpackAny as response types are not registered.
err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp)
s.Require().NoError(err)
s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))),
fmt.Sprintf("expected a positive coin value, got %v", resp.Amount))
}
}
}
})
}
}
func (s *E2ETestSuite) TestNewSetWithdrawAddrCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string
args []string
expectErr bool
expectedCode uint32
respType proto.Message
}{
{
"invalid withdraw address",
[]string{
"foo",
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
true, 0, nil,
},
{
"valid transaction",
[]string{
val.Address.String(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
false, 0, &sdk.TxResponse{},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := cli.NewSetWithdrawAddrCmd(address.NewBech32Codec("cosmos"))
clientCtx := val.ClientCtx
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
txResp := tc.respType.(*sdk.TxResponse)
s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode))
}
})
}
}

View File

@ -10,7 +10,6 @@ import (
"cosmossdk.io/simapp"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
@ -109,7 +108,7 @@ func (s *WithdrawAllTestSuite) TestNewWithdrawAllRewardsGenerateOnly() {
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
}
cmd := cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
cmd := cli.NewWithdrawAllRewardsCmd()
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
if err != nil {
return err
@ -132,7 +131,7 @@ func (s *WithdrawAllTestSuite) TestNewWithdrawAllRewardsGenerateOnly() {
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
}
cmd := cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
cmd := cli.NewWithdrawAllRewardsCmd()
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
require.NoError(err)
// expect 1 transaction in the generated file when --max-msgs in a tx set 2, since there are only delegations.

View File

@ -5,7 +5,6 @@ import (
"github.com/spf13/cobra"
"cosmossdk.io/core/address"
sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client"
@ -19,7 +18,7 @@ import (
var FlagSplit = "split"
// NewTxCmd returns a root CLI command handler for all x/bank transaction commands.
func NewTxCmd(ac address.Codec) *cobra.Command {
func NewTxCmd() *cobra.Command {
txCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Bank transaction subcommands",
@ -29,7 +28,7 @@ func NewTxCmd(ac address.Codec) *cobra.Command {
}
txCmd.AddCommand(
NewMultiSendTxCmd(ac),
NewMultiSendTxCmd(),
)
return txCmd
@ -37,7 +36,7 @@ func NewTxCmd(ac address.Codec) *cobra.Command {
// NewMultiSendTxCmd returns a CLI command handler for creating a MsgMultiSend transaction.
// For a better UX this command is limited to send funds from one account to two or more accounts.
func NewMultiSendTxCmd(ac address.Codec) *cobra.Command {
func NewMultiSendTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "multi-send [from_key_or_address] [to_address_1 to_address_2 ...] [amount]",
Short: "Send funds from one account to two or more accounts.",
@ -82,7 +81,7 @@ When using '--dry-run' a key name cannot be used, only a bech32 address.`,
var output []types.Output
for _, arg := range args[1 : len(args)-1] {
toAddr, err := ac.StringToBytes(arg)
toAddr, err := clientCtx.AddressCodec.StringToBytes(arg)
if err != nil {
return err
}

View File

@ -54,7 +54,7 @@ func (s *CLITestSuite) SetupSuite() {
func (s *CLITestSuite) TestMultiSendTxCmd() {
accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 3)
cmd := cli.NewMultiSendTxCmd(addresscodec.NewBech32Codec("cosmos"))
cmd := cli.NewMultiSendTxCmd()
cmd.SetOutput(io.Discard)
extraArgs := []string{

View File

@ -10,7 +10,6 @@ import (
"github.com/spf13/cobra"
modulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
"cosmossdk.io/core/address"
"cosmossdk.io/core/appmodule"
corestore "cosmossdk.io/core/store"
"cosmossdk.io/depinject"
@ -46,7 +45,6 @@ var (
// AppModuleBasic defines the basic application module used by the bank module.
type AppModuleBasic struct {
cdc codec.Codec
ac address.Codec
}
// Name returns the bank module's name.
@ -82,7 +80,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *g
// GetTxCmd returns the root tx command for the bank module.
func (ab AppModuleBasic) GetTxCmd() *cobra.Command {
return cli.NewTxCmd(ab.ac)
return cli.NewTxCmd()
}
// RegisterInterfaces registers interfaces and implementations of the bank module.
@ -127,7 +125,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
// NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc, ac: accountKeeper.AddressCodec()},
AppModuleBasic: AppModuleBasic{cdc: cdc},
keeper: keeper,
accountKeeper: accountKeeper,
}

View File

@ -2,7 +2,6 @@ package distribution
import (
"fmt"
"strings"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
distirbuitonv1beta1 "cosmossdk.io/api/cosmos/distribution/v1beta1"
@ -17,11 +16,6 @@ var (
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
exAccAddress, err := am.ac.BytesToString([]byte("A58856F0FD53BF058B4909A21AEC019107BA6A58856F0FD53BF058B4909A21AEC019107BA6"))
if err != nil {
panic(err)
}
return &autocliv1.ModuleOptions{
Query: &autocliv1.ServiceCommandDescriptor{
Service: distirbuitonv1beta1.Query_ServiceDesc.ServiceName,
@ -35,9 +29,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
RpcMethod: "ValidatorDistributionInfo",
Use: "validator-distribution-info [validator]",
Short: "Query validator distribution info",
Example: fmt.Sprintf(`Example: $ %s query distribution validator-distribution-info %s`,
version.AppName, exAccAddress,
),
Example: fmt.Sprintf(`Example: $ %s query distribution validator-distribution-info [validator-address]`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "validator_address"},
@ -77,14 +69,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
Use: "rewards [delegator-addr] [validator-addr]",
Short: "Query all distribution delegator rewards or rewards from a particular validator",
Long: "Query all rewards earned by a delegator, optionally restrict to rewards from a single validator.",
Example: strings.TrimSpace(
fmt.Sprintf(`
$ %s query distribution rewards %s
$ %s query distribution rewards %s [validator-address]
`,
version.AppName, exAccAddress, version.AppName, exAccAddress,
),
),
Example: fmt.Sprintf("$ %s query distribution rewards [delegator-address] [validator-address]", version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "delegator_address"},
{ProtoField: "validator_address"},
@ -100,6 +85,62 @@ $ %s query distribution rewards %s [validator-address]
},
Tx: &autocliv1.ServiceCommandDescriptor{
Service: distirbuitonv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "SetWithdrawAddress",
Use: "set-withdraw-addr [withdraw-addr]",
Short: "Change the default withdraw address for rewards associated with an address",
Example: fmt.Sprintf("%s tx distribution set-withdraw-addr cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p --from mykey", version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "withdraw_address"},
},
},
{
RpcMethod: "WithdrawDelegatorReward",
Use: "withdraw-rewards [validator-addr]",
Short: "Withdraw rewards from a given delegation address",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "validator_address"},
},
},
{
RpcMethod: "WithdrawValidatorCommission",
Use: "withdraw-validator-commission [validator-addr]",
Short: "Withdraw commissions from a validator address (must be a validator operator)",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "validator_address"},
},
},
{
RpcMethod: "DepositValidatorRewardsPool",
Use: "fund-validator-rewards-pool [validator-addr] [amount]",
Short: "Fund the validator rewards pool with the specified amount",
Example: fmt.Sprintf("%s tx distribution fund-validator-rewards-pool cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp 100uatom --from mykey", version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "validator_address"},
{ProtoField: "amount", Varargs: true},
},
},
{
RpcMethod: "FundCommunityPool",
Deprecated: fmt.Sprintf("Use %s tx protocolpool fund-community-pool", version.AppName),
Use: "fund-community-pool [amount]",
Short: "Funds the community pool with the specified amount",
Example: fmt.Sprintf(`$ %s tx distribution fund-community-pool 100uatom --from mykey`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "amount", Varargs: true},
},
},
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
},
{
RpcMethod: "CommunityPoolSpend",
Skip: true, // skipped because authority gated
},
},
EnhanceCustomCommand: true,
},
}
}

View File

@ -2,12 +2,8 @@ package cli
import (
"fmt"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"cosmossdk.io/core/address"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
@ -28,7 +24,7 @@ const (
)
// NewTxCmd returns a root CLI command handler for all x/distribution transaction commands.
func NewTxCmd(valAc, ac address.Codec) *cobra.Command {
func NewTxCmd() *cobra.Command {
distTxCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Distribution transactions subcommands",
@ -38,115 +34,26 @@ func NewTxCmd(valAc, ac address.Codec) *cobra.Command {
}
distTxCmd.AddCommand(
NewWithdrawRewardsCmd(valAc, ac),
NewWithdrawAllRewardsCmd(valAc, ac),
NewSetWithdrawAddrCmd(ac),
NewDepositValidatorRewardsPoolCmd(valAc, ac),
NewWithdrawAllRewardsCmd(),
)
return distTxCmd
}
type newGenerateOrBroadcastFunc func(client.Context, *pflag.FlagSet, ...sdk.Msg) error
func newSplitAndApply(
genOrBroadcastFn newGenerateOrBroadcastFunc, clientCtx client.Context,
fs *pflag.FlagSet, msgs []sdk.Msg, chunkSize int,
) error {
if chunkSize == 0 {
return genOrBroadcastFn(clientCtx, fs, msgs...)
}
// split messages into slices of length chunkSize
totalMessages := len(msgs)
for i := 0; i < len(msgs); i += chunkSize {
sliceEnd := i + chunkSize
if sliceEnd > totalMessages {
sliceEnd = totalMessages
}
msgChunk := msgs[i:sliceEnd]
if err := genOrBroadcastFn(clientCtx, fs, msgChunk...); err != nil {
return err
}
}
return nil
}
// NewWithdrawRewardsCmd returns a CLI command handler for creating a MsgWithdrawDelegatorReward transaction.
func NewWithdrawRewardsCmd(valCodec, ac address.Codec) *cobra.Command {
bech32PrefixValAddr := sdk.GetConfig().GetBech32ValidatorAddrPrefix()
cmd := &cobra.Command{
Use: "withdraw-rewards [validator-addr]",
Short: "Withdraw rewards from a given delegation address, and optionally withdraw validator commission if the delegation address given is a validator operator",
Long: strings.TrimSpace(
fmt.Sprintf(`Withdraw rewards from a given delegation address,
and optionally withdraw validator commission if the delegation address given is a validator operator.
Example:
$ %s tx distribution withdraw-rewards %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey
$ %s tx distribution withdraw-rewards %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey --commission
`,
version.AppName, bech32PrefixValAddr, version.AppName, bech32PrefixValAddr,
),
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
delAddr, err := ac.BytesToString(clientCtx.GetFromAddress())
if err != nil {
return err
}
_, err = valCodec.StringToBytes(args[0])
if err != nil {
return err
}
msgs := []sdk.Msg{types.NewMsgWithdrawDelegatorReward(delAddr, args[0])}
if commission, _ := cmd.Flags().GetBool(FlagCommission); commission {
msgs = append(msgs, types.NewMsgWithdrawValidatorCommission(args[0]))
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgs...)
},
}
cmd.Flags().Bool(FlagCommission, false, "Withdraw the validator's commission in addition to the rewards")
flags.AddTxFlagsToCmd(cmd)
return cmd
}
// NewWithdrawAllRewardsCmd returns a CLI command handler for creating a MsgWithdrawDelegatorReward transaction.
func NewWithdrawAllRewardsCmd(valCodec, ac address.Codec) *cobra.Command {
// This command is more powerful than AutoCLI generated command as it allows sending batch of messages.
func NewWithdrawAllRewardsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "withdraw-all-rewards",
Short: "withdraw all delegations rewards for a delegator",
Long: strings.TrimSpace(
fmt.Sprintf(`Withdraw all rewards for a single delegator.
Note that if you use this command with --%[2]s=%[3]s or --%[2]s=%[4]s, the %[5]s flag will automatically be set to 0.
Example:
$ %[1]s tx distribution withdraw-all-rewards --from mykey
`,
version.AppName, flags.FlagBroadcastMode, flags.BroadcastSync, flags.BroadcastAsync, FlagMaxMessagesPerTx,
),
),
Args: cobra.NoArgs,
Use: "withdraw-all-rewards",
Short: "Withdraw all delegations rewards for a delegator",
Example: fmt.Sprintf("%s tx distribution withdraw-all-rewards --from mykey", version.AppName),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
delAddr, err := ac.BytesToString(clientCtx.GetFromAddress())
delAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress())
if err != nil {
return err
}
@ -167,7 +74,7 @@ $ %[1]s tx distribution withdraw-all-rewards --from mykey
// build multi-message transaction
msgs := make([]sdk.Msg, 0, len(validators))
for _, valAddr := range validators {
_, err := valCodec.StringToBytes(valAddr)
_, err := clientCtx.ValidatorAddressCodec.StringToBytes(valAddr)
if err != nil {
return err
}
@ -177,8 +84,26 @@ $ %[1]s tx distribution withdraw-all-rewards --from mykey
}
chunkSize, _ := cmd.Flags().GetInt(FlagMaxMessagesPerTx)
if chunkSize == 0 {
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgs...)
}
return newSplitAndApply(tx.GenerateOrBroadcastTxCLI, clientCtx, cmd.Flags(), msgs, chunkSize)
// split messages into slices of length chunkSize
totalMessages := len(msgs)
for i := 0; i < len(msgs); i += chunkSize {
sliceEnd := i + chunkSize
if sliceEnd > totalMessages {
sliceEnd = totalMessages
}
msgChunk := msgs[i:sliceEnd]
if err := tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgChunk...); err != nil {
return err
}
}
return nil
},
}
@ -187,84 +112,3 @@ $ %[1]s tx distribution withdraw-all-rewards --from mykey
return cmd
}
// NewSetWithdrawAddrCmd returns a CLI command handler for creating a MsgSetWithdrawAddress transaction.
func NewSetWithdrawAddrCmd(ac address.Codec) *cobra.Command {
bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix()
cmd := &cobra.Command{
Use: "set-withdraw-addr [withdraw-addr]",
Short: "change the default withdraw address for rewards associated with an address",
Long: strings.TrimSpace(
fmt.Sprintf(`Set the withdraw address for rewards associated with a delegator address.
Example:
$ %s tx distribution set-withdraw-addr %s1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p --from mykey
`,
version.AppName, bech32PrefixAccAddr,
),
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
delAddr := clientCtx.GetFromAddress()
withdrawAddr, err := ac.StringToBytes(args[0])
if err != nil {
return err
}
msg := types.NewMsgSetWithdrawAddress(delAddr, withdrawAddr)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
flags.AddTxFlagsToCmd(cmd)
return cmd
}
// NewDepositValidatorRewardsPoolCmd returns a CLI command handler for creating
// a MsgDepositValidatorRewardsPool transaction.
func NewDepositValidatorRewardsPoolCmd(valCodec, ac address.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "fund-validator-rewards-pool [val_addr] [amount]",
Args: cobra.ExactArgs(2),
Short: "Fund the validator rewards pool with the specified amount",
Example: fmt.Sprintf(
"%s tx distribution fund-validator-rewards-pool cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp 100uatom --from mykey",
version.AppName,
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
depositorAddr, err := ac.BytesToString(clientCtx.GetFromAddress())
if err != nil {
return err
}
_, err = valCodec.StringToBytes(args[0])
if err != nil {
return err
}
amount, err := sdk.ParseCoinsNormalized(args[1])
if err != nil {
return err
}
msg := types.NewMsgDepositValidatorRewardsPool(depositorAddr, args[0], amount)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
flags.AddTxFlagsToCmd(cmd)
return cmd
}

View File

@ -1,14 +1,12 @@
package cli_test
import (
"context"
"fmt"
"io"
"testing"
abci "github.com/cometbft/cometbft/abci/types"
rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/suite"
sdkmath "cosmossdk.io/math"
@ -17,7 +15,6 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/testutil/network"
@ -84,76 +81,6 @@ func (s *CLITestSuite) SetupSuite() {
cfg.GenesisState = genesisState
}
func (s *CLITestSuite) TestTxWithdrawRewardsCmd() {
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
testCases := []struct {
name string
valAddr fmt.Stringer
args []string
expectErrMsg string
}{
{
"invalid validator address",
val[0].Address,
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
},
"hrp does not match bech32 prefix",
},
{
"valid transaction",
sdk.ValAddress(val[0].Address),
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
},
"",
},
{
"valid transaction (with commission)",
sdk.ValAddress(val[0].Address),
[]string{
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=true", cli.FlagCommission),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
},
"",
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
args := append([]string{tc.valAddr.String()}, tc.args...)
ctx := svrcmd.CreateExecuteContext(context.Background())
cmd := cli.NewWithdrawRewardsCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
cmd.SetContext(ctx)
cmd.SetArgs(args)
s.Require().NoError(client.SetCmdClientContextHandler(s.clientCtx, cmd))
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
if tc.expectErrMsg != "" {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expectErrMsg)
} else {
s.Require().NoError(err)
msg := &sdk.TxResponse{}
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
}
})
}
}
func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() {
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
@ -188,7 +115,7 @@ func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() {
tc := tc
s.Run(tc.name, func() {
cmd := cli.NewWithdrawAllRewardsCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
cmd := cli.NewWithdrawAllRewardsCmd()
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
if tc.expectErrMsg != "" {
@ -202,53 +129,3 @@ func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() {
})
}
}
func (s *CLITestSuite) TestTxSetWithdrawAddrCmd() {
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
testCases := []struct {
name string
args []string
expectErr bool
respType proto.Message
}{
{
"invalid withdraw address",
[]string{
"foo",
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
},
true, nil,
},
{
"valid transaction",
[]string{
val[0].Address.String(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
},
false, &sdk.TxResponse{},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := cli.NewSetWithdrawAddrCmd(addresscodec.NewBech32Codec("cosmos"))
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
}
})
}
}

View File

@ -1,59 +0,0 @@
package cli
import (
"testing"
"github.com/spf13/pflag"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func Test_splitAndCall_NoMessages(t *testing.T) {
clientCtx := client.Context{}
err := newSplitAndApply(nil, clientCtx, nil, nil, 10)
require.NoError(t, err, "")
}
func Test_splitAndCall_Splitting(t *testing.T) {
clientCtx := client.Context{}
addr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
// Add five messages
msgs := []sdk.Msg{
testdata.NewTestMsg(addr),
testdata.NewTestMsg(addr),
testdata.NewTestMsg(addr),
testdata.NewTestMsg(addr),
testdata.NewTestMsg(addr),
}
// Keep track of number of calls
const chunkSize = 2
callCount := 0
err := newSplitAndApply(
func(clientCtx client.Context, fs *pflag.FlagSet, msgs ...sdk.Msg) error {
callCount++
require.NotNil(t, clientCtx)
require.NotNil(t, msgs)
if callCount < 3 {
require.Equal(t, len(msgs), 2)
} else {
require.Equal(t, len(msgs), 1)
}
return nil
},
clientCtx, nil, msgs, chunkSize)
require.NoError(t, err, "")
require.Equal(t, 3, callCount)
}

View File

@ -0,0 +1,179 @@
package keeper_test
import (
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
distrtestutil "github.com/cosmos/cosmos-sdk/x/distribution/testutil"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestQueryParams(t *testing.T) {
ctx, _, distrKeeper, _ := initFixture(t)
queryServer := keeper.NewQuerier(distrKeeper)
cases := []struct {
name string
req *types.QueryParamsRequest
resp *types.QueryParamsResponse
errMsg string
}{
{
name: "success",
req: &types.QueryParamsRequest{},
resp: &types.QueryParamsResponse{
Params: types.DefaultParams(),
},
errMsg: "",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
out, err := queryServer.Params(ctx, tc.req)
if tc.errMsg == "" {
require.NoError(t, err)
require.Equal(t, tc.resp, out)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
require.Nil(t, out)
}
})
}
}
func TestQueryValidatorDistributionInfo(t *testing.T) {
ctx, addrs, distrKeeper, dep := initFixture(t)
queryServer := keeper.NewQuerier(distrKeeper)
val, err := distrtestutil.CreateValidator(valConsPk0, math.NewInt(100))
require.NoError(t, err)
del := stakingtypes.NewDelegation(addrs[0].String(), val.OperatorAddress, val.DelegatorShares)
dep.stakingKeeper.EXPECT().Validator(gomock.Any(), gomock.Any()).Return(val, nil).AnyTimes()
dep.stakingKeeper.EXPECT().Delegation(gomock.Any(), gomock.Any(), gomock.Any()).Return(del, nil).AnyTimes()
cases := []struct {
name string
req *types.QueryValidatorDistributionInfoRequest
resp *types.QueryValidatorDistributionInfoResponse
errMsg string
}{
{
name: "invalid validator address",
req: &types.QueryValidatorDistributionInfoRequest{
ValidatorAddress: "invalid address",
},
resp: &types.QueryValidatorDistributionInfoResponse{},
errMsg: "decoding bech32 failed",
},
{
name: "not a validator",
req: &types.QueryValidatorDistributionInfoRequest{
ValidatorAddress: addrs[0].String(),
},
resp: &types.QueryValidatorDistributionInfoResponse{},
errMsg: `expected 'cosmosvaloper' got 'cosmos'`,
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
out, err := queryServer.ValidatorDistributionInfo(ctx, tc.req)
if tc.errMsg == "" {
require.NoError(t, err)
require.Equal(t, tc.resp, out)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
require.Nil(t, out)
}
})
}
}
func TestQueryValidatorOutstandingRewards(t *testing.T) {
// TODO https://github.com/cosmos/cosmos-sdk/issues/16757
// currently tested in tests/e2e/distribution/grpc_query_suite.go
}
func TestQueryValidatorCommission(t *testing.T) {
// TODO https://github.com/cosmos/cosmos-sdk/issues/16757
// currently tested in tests/e2e/distribution/grpc_query_suite.go
}
func TestQueryValidatorSlashes(t *testing.T) {
// TODO https://github.com/cosmos/cosmos-sdk/issues/16757
// currently tested in tests/e2e/distribution/grpc_query_suite.go
}
func TestQueryDelegationRewards(t *testing.T) {
// TODO https://github.com/cosmos/cosmos-sdk/issues/16757
// currently tested in tests/e2e/distribution/grpc_query_suite.go
}
func TestQueryDelegationTotalRewards(t *testing.T) {
// TODO https://github.com/cosmos/cosmos-sdk/issues/16757
// currently tested in tests/e2e/distribution/grpc_query_suite.go
}
func TestQueryDelegatorValidators(t *testing.T) {
// TODO https://github.com/cosmos/cosmos-sdk/issues/16757
// currently tested in tests/e2e/distribution/grpc_query_suite.go
}
func TestQueryDelegatorWithdrawAddress(t *testing.T) {
// TODO https://github.com/cosmos/cosmos-sdk/issues/16757
// currently tested in tests/e2e/distribution/grpc_query_suite.go
}
func TestQueryCommunityPool(t *testing.T) {
ctx, _, distrKeeper, dep := initFixture(t)
queryServer := keeper.NewQuerier(distrKeeper)
coins := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100)))
decCoins := sdk.NewDecCoinsFromCoins(coins...)
dep.poolKeeper.EXPECT().GetCommunityPool(gomock.Any()).Return(coins, nil).AnyTimes()
cases := []struct {
name string
req *types.QueryCommunityPoolRequest //nolint:staticcheck // Testing deprecated method
resp *types.QueryCommunityPoolResponse //nolint:staticcheck // Testing deprecated method
errMsg string
}{
{
name: "success",
req: &types.QueryCommunityPoolRequest{}, //nolint:staticcheck // Testing deprecated method
resp: &types.QueryCommunityPoolResponse{ //nolint:staticcheck // Testing deprecated method
Pool: decCoins,
},
errMsg: "",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
out, err := queryServer.CommunityPool(ctx, tc.req)
if tc.errMsg == "" {
require.NoError(t, err)
require.Equal(t, tc.resp, out)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
require.Nil(t, out)
}
})
}
}

View File

@ -11,6 +11,7 @@ import (
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
@ -23,7 +24,16 @@ import (
"github.com/cosmos/cosmos-sdk/x/distribution/types"
)
func TestSetWithdrawAddr(t *testing.T) {
type dep struct {
bankKeeper *distrtestutil.MockBankKeeper
stakingKeeper *distrtestutil.MockStakingKeeper
accountKeeper *distrtestutil.MockAccountKeeper
poolKeeper *distrtestutil.MockPoolKeeper
}
func initFixture(t *testing.T) (sdk.Context, []sdk.AccAddress, keeper.Keeper, dep) {
t.Helper()
ctrl := gomock.NewController(t)
key := storetypes.NewKVStoreKey(types.StoreKey)
storeService := runtime.NewKVStoreService(key)
@ -32,16 +42,17 @@ func TestSetWithdrawAddr(t *testing.T) {
ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()})
addrs := simtestutil.CreateIncrementalAccounts(2)
delegatorAddr := addrs[0]
withdrawAddr := addrs[1]
bankKeeper := distrtestutil.NewMockBankKeeper(ctrl)
stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl)
accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl)
poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl)
accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress())
accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes()
stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec("cosmosvaloper")).AnyTimes()
withdrawAddr := addrs[1]
bankKeeper.EXPECT().BlockedAddr(withdrawAddr).Return(false).AnyTimes()
bankKeeper.EXPECT().BlockedAddr(distrAcc.GetAddress()).Return(true).AnyTimes()
@ -56,10 +67,22 @@ func TestSetWithdrawAddr(t *testing.T) {
authtypes.NewModuleAddress("gov").String(),
)
params := types.DefaultParams()
require.NoError(t, distrKeeper.Params.Set(ctx, params))
return ctx, addrs, distrKeeper, dep{bankKeeper, stakingKeeper, accountKeeper, poolKeeper}
}
func TestSetWithdrawAddr(t *testing.T) {
ctx, addrs, distrKeeper, _ := initFixture(t)
params := types.DefaultParams()
params.WithdrawAddrEnabled = false
require.NoError(t, distrKeeper.Params.Set(ctx, params))
delegatorAddr := addrs[0]
withdrawAddr := addrs[1]
err := distrKeeper.SetWithdrawAddr(ctx, delegatorAddr, withdrawAddr)
require.NotNil(t, err)
@ -76,39 +99,14 @@ func TestSetWithdrawAddr(t *testing.T) {
}
func TestWithdrawValidatorCommission(t *testing.T) {
ctrl := gomock.NewController(t)
key := storetypes.NewKVStoreKey(types.StoreKey)
storeService := runtime.NewKVStoreService(key)
testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{})
ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()})
addrs := simtestutil.CreateIncrementalAccounts(1)
ctx, addrs, distrKeeper, dep := initFixture(t)
valAddr := sdk.ValAddress(addrs[0])
bankKeeper := distrtestutil.NewMockBankKeeper(ctrl)
stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl)
accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl)
poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl)
accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress())
valCommission := sdk.DecCoins{
sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))),
sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))),
}
distrKeeper := keeper.NewKeeper(
encCfg.Codec,
storeService,
accountKeeper,
bankKeeper,
stakingKeeper,
poolKeeper,
"fee_collector",
authtypes.NewModuleAddress("gov").String(),
)
// set outstanding rewards
require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}))
@ -118,7 +116,7 @@ func TestWithdrawValidatorCommission(t *testing.T) {
// withdraw commission
coins := sdk.NewCoins(sdk.NewCoin("mytoken", math.NewInt(1)), sdk.NewCoin("stake", math.NewInt(1)))
// if SendCoinsFromModuleToAccount is called, we know that the withdraw was successful
bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), "distribution", addrs[0], coins).Return(nil)
dep.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), "distribution", addrs[0], coins).Return(nil)
_, err := distrKeeper.WithdrawValidatorCommission(ctx, valAddr)
require.NoError(t, err)
@ -134,42 +132,15 @@ func TestWithdrawValidatorCommission(t *testing.T) {
}
func TestGetTotalRewards(t *testing.T) {
ctrl := gomock.NewController(t)
key := storetypes.NewKVStoreKey(types.StoreKey)
storeService := runtime.NewKVStoreService(key)
testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{})
ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()})
addrs := simtestutil.CreateIncrementalAccounts(2)
valAddr0 := sdk.ValAddress(addrs[0])
valAddr1 := sdk.ValAddress(addrs[1])
bankKeeper := distrtestutil.NewMockBankKeeper(ctrl)
stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl)
accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl)
poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl)
accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress())
distrKeeper := keeper.NewKeeper(
encCfg.Codec,
storeService,
accountKeeper,
bankKeeper,
stakingKeeper,
poolKeeper,
"fee_collector",
authtypes.NewModuleAddress("gov").String(),
)
ctx, addrs, distrKeeper, _ := initFixture(t)
valCommission := sdk.DecCoins{
sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))),
sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))),
}
require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, valAddr0, types.ValidatorOutstandingRewards{Rewards: valCommission}))
require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, valAddr1, types.ValidatorOutstandingRewards{Rewards: valCommission}))
require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, sdk.ValAddress(addrs[0]), types.ValidatorOutstandingRewards{Rewards: valCommission}))
require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, sdk.ValAddress(addrs[1]), types.ValidatorOutstandingRewards{Rewards: valCommission}))
expectedRewards := valCommission.MulDec(math.LegacyNewDec(2))
totalRewards := distrKeeper.GetTotalRewards(ctx)

View File

@ -2,6 +2,7 @@ package keeper
import (
"context"
"fmt"
"github.com/hashicorp/go-metrics"
@ -154,7 +155,7 @@ func (k msgServer) CommunityPoolSpend(ctx context.Context, msg *types.MsgCommuni
recipient, err := k.authKeeper.AddressCodec().StringToBytes(msg.Recipient)
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid recipient address: %w", err)
}
if err := k.poolKeeper.DistributeFromFeePool(ctx, msg.Amount, recipient); err != nil {
@ -170,7 +171,7 @@ func (k msgServer) CommunityPoolSpend(ctx context.Context, msg *types.MsgCommuni
func (k msgServer) DepositValidatorRewardsPool(ctx context.Context, msg *types.MsgDepositValidatorRewardsPool) (*types.MsgDepositValidatorRewardsPoolResponse, error) {
depositor, err := k.authKeeper.AddressCodec().StringToBytes(msg.Depositor)
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid depositor address: %w", err)
}
// deposit coins from depositor's account to the distribution module

View File

@ -0,0 +1,358 @@
package keeper_test
import (
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
)
func TestMsgSetWithdrawAddress(t *testing.T) {
ctx, addrs, distrKeeper, _ := initFixture(t)
msgServer := keeper.NewMsgServerImpl(distrKeeper)
cases := []struct {
name string
msg *types.MsgSetWithdrawAddress
errMsg string
}{
{
name: "success",
msg: &types.MsgSetWithdrawAddress{
DelegatorAddress: addrs[0].String(),
WithdrawAddress: addrs[1].String(),
},
errMsg: "",
},
{
name: "invalid delegator address",
msg: &types.MsgSetWithdrawAddress{
DelegatorAddress: "invalid",
WithdrawAddress: addrs[1].String(),
},
errMsg: "invalid address",
},
{
name: "invalid withdraw address",
msg: &types.MsgSetWithdrawAddress{
DelegatorAddress: addrs[0].String(),
WithdrawAddress: "invalid",
},
errMsg: "invalid address",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
_, err := msgServer.SetWithdrawAddress(ctx, tc.msg)
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
}
})
}
}
func TestMsgWithdrawDelegatorReward(t *testing.T) {
ctx, addrs, distrKeeper, dep := initFixture(t)
dep.stakingKeeper.EXPECT().Validator(gomock.Any(), gomock.Any()).AnyTimes()
msgServer := keeper.NewMsgServerImpl(distrKeeper)
cases := []struct {
name string
preRun func()
msg *types.MsgWithdrawDelegatorReward
errMsg string
}{
{
name: "invalid delegator address",
msg: &types.MsgWithdrawDelegatorReward{
DelegatorAddress: "invalid",
ValidatorAddress: sdk.ValAddress(addrs[1]).String(),
},
errMsg: "invalid delegator address",
},
{
name: "invalid validator address",
msg: &types.MsgWithdrawDelegatorReward{
DelegatorAddress: addrs[0].String(),
ValidatorAddress: "invalid",
},
errMsg: "invalid validator address",
},
{
name: "no validator",
msg: &types.MsgWithdrawDelegatorReward{
DelegatorAddress: addrs[0].String(),
ValidatorAddress: sdk.ValAddress(addrs[1]).String(),
},
errMsg: "no validator distribution info",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
if tc.preRun != nil {
tc.preRun()
}
_, err := msgServer.WithdrawDelegatorReward(ctx, tc.msg)
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
}
})
}
}
func TestMsgWithdrawValidatorCommission(t *testing.T) {
ctx, addrs, distrKeeper, _ := initFixture(t)
msgServer := keeper.NewMsgServerImpl(distrKeeper)
cases := []struct {
name string
preRun func()
msg *types.MsgWithdrawValidatorCommission
errMsg string
}{
{
name: "invalid validator address",
msg: &types.MsgWithdrawValidatorCommission{
ValidatorAddress: "invalid",
},
errMsg: "invalid validator address",
},
{
name: "no validator commission to withdraw",
msg: &types.MsgWithdrawValidatorCommission{
ValidatorAddress: sdk.ValAddress(addrs[1]).String(),
},
errMsg: "no validator commission to withdraw",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
if tc.preRun != nil {
tc.preRun()
}
_, err := msgServer.WithdrawValidatorCommission(ctx, tc.msg)
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
}
})
}
}
func TestMsgFundCommunityPool(t *testing.T) {
ctx, addrs, distrKeeper, dep := initFixture(t)
dep.poolKeeper.EXPECT().FundCommunityPool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
msgServer := keeper.NewMsgServerImpl(distrKeeper)
cases := []struct {
name string
msg *types.MsgFundCommunityPool //nolint:staticcheck // Testing deprecated method
errMsg string
}{
{
name: "invalid depositor address",
msg: &types.MsgFundCommunityPool{ //nolint:staticcheck // Testing deprecated method
Depositor: "invalid",
Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))),
},
errMsg: "invalid depositor address",
},
{
name: "success",
msg: &types.MsgFundCommunityPool{ //nolint:staticcheck // Testing deprecated method
Depositor: addrs[0].String(),
Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000))),
},
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
_, err := msgServer.FundCommunityPool(ctx, tc.msg) //nolint:staticcheck // Testing deprecated method
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
}
})
}
}
func TestMsgUpdateParams(t *testing.T) {
ctx, addrs, distrKeeper, _ := initFixture(t)
msgServer := keeper.NewMsgServerImpl(distrKeeper)
cases := []struct {
name string
msg *types.MsgUpdateParams
errMsg string
}{
{
name: "invalid authority",
msg: &types.MsgUpdateParams{
Authority: "invalid",
Params: types.DefaultParams(),
},
errMsg: "invalid address",
},
{
name: "incorrect authority",
msg: &types.MsgUpdateParams{
Authority: addrs[0].String(),
Params: types.DefaultParams(),
},
errMsg: "expected authority account as only signer for proposal message",
},
{
name: "invalid params",
msg: &types.MsgUpdateParams{
Authority: authtypes.NewModuleAddress("gov").String(),
Params: types.Params{CommunityTax: math.LegacyNewDec(-1)},
},
errMsg: "community tax must be positive",
},
{
name: "success",
msg: &types.MsgUpdateParams{
Authority: authtypes.NewModuleAddress("gov").String(),
Params: types.DefaultParams(),
},
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
_, err := msgServer.UpdateParams(ctx, tc.msg)
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
}
})
}
}
func TestMsgCommunityPoolSpend(t *testing.T) {
ctx, addrs, distrKeeper, dep := initFixture(t)
dep.poolKeeper.EXPECT().DistributeFromFeePool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
msgServer := keeper.NewMsgServerImpl(distrKeeper)
cases := []struct {
name string
msg *types.MsgCommunityPoolSpend //nolint:staticcheck // Testing deprecated method
errMsg string
}{
{
name: "invalid authority",
msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method
Authority: "invalid",
Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))),
},
errMsg: "invalid address",
},
{
name: "incorrect authority",
msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method
Authority: addrs[0].String(),
Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))),
},
errMsg: "expected authority account as only signer for proposal message",
},
{
name: "invalid recipient address",
msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method
Authority: authtypes.NewModuleAddress("gov").String(),
Recipient: "invalid",
Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))),
},
errMsg: "invalid recipient address",
},
{
name: "invalid amount",
msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method
Authority: authtypes.NewModuleAddress("gov").String(),
Recipient: addrs[0].String(),
},
errMsg: "invalid coins",
},
{
name: "success",
msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method
Authority: authtypes.NewModuleAddress("gov").String(),
Recipient: addrs[0].String(),
Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000))),
},
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
_, err := msgServer.CommunityPoolSpend(ctx, tc.msg) //nolint:staticcheck // Testing deprecated method
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
}
})
}
}
func TestMsgDepositValidatorRewardsPool(t *testing.T) {
ctx, _, distrKeeper, _ := initFixture(t)
msgServer := keeper.NewMsgServerImpl(distrKeeper)
cases := []struct {
name string
msg *types.MsgDepositValidatorRewardsPool
errMsg string
}{
{
name: "invalid depositor address",
msg: &types.MsgDepositValidatorRewardsPool{
Depositor: "invalid",
Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))),
},
errMsg: "invalid depositor address",
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
_, err := msgServer.DepositValidatorRewardsPool(ctx, tc.msg)
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMsg)
}
})
}
}

View File

@ -9,7 +9,6 @@ import (
"github.com/spf13/cobra"
modulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
"cosmossdk.io/core/address"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/store"
"cosmossdk.io/depinject"
@ -45,7 +44,6 @@ var (
// AppModuleBasic defines the basic application module used by the distribution module.
type AppModuleBasic struct {
cdc codec.Codec
ac address.Codec
}
// Name returns the distribution module's name.
@ -83,7 +81,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux
// GetTxCmd returns the root tx command for the distribution module.
func (ab AppModuleBasic) GetTxCmd() *cobra.Command {
return cli.NewTxCmd(ab.cdc.InterfaceRegistry().SigningContext().ValidatorAddressCodec(), ab.cdc.InterfaceRegistry().SigningContext().AddressCodec())
return cli.NewTxCmd()
}
// RegisterInterfaces implements InterfaceModule
@ -108,7 +106,7 @@ func NewAppModule(
bankKeeper types.BankKeeper, stakingKeeper types.StakingKeeper, poolKeeper types.PoolKeeper,
) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc, ac: accountKeeper.AddressCodec()},
AppModuleBasic: AppModuleBasic{cdc: cdc},
keeper: keeper,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,

View File

@ -30,7 +30,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
RpcMethod: "FundCommunityPool",
Use: "fund-community-pool [amount]",
Short: "Funds the community pool with the specified amount",
Example: fmt.Sprintf(`$ %s tx pool fund-community-pool 100uatom --from mykey`, version.AppName),
Example: fmt.Sprintf(`$ %s tx protocolpool fund-community-pool 100uatom --from mykey`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "amount"}},
},
},

View File

@ -33,7 +33,7 @@ var (
)
// NewTxCmd returns a root CLI command handler for all x/staking transaction commands.
func NewTxCmd(valAddrCodec, ac address.Codec) *cobra.Command {
func NewTxCmd() *cobra.Command {
stakingTxCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Staking transaction subcommands",
@ -43,17 +43,15 @@ func NewTxCmd(valAddrCodec, ac address.Codec) *cobra.Command {
}
stakingTxCmd.AddCommand(
NewCreateValidatorCmd(valAddrCodec),
NewEditValidatorCmd(valAddrCodec),
NewCreateValidatorCmd(),
NewEditValidatorCmd(),
)
return stakingTxCmd
}
// NewCreateValidatorCmd returns a CLI command handler for creating a MsgCreateValidator transaction.
//
// cannot give autocli support, can be CLI breaking
func NewCreateValidatorCmd(ac address.Codec) *cobra.Command {
func NewCreateValidatorCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create-validator [path/to/validator.json]",
Short: "create new validator initialized with a self-delegation to it",
@ -97,7 +95,7 @@ where we can get the pubkey using "%s tendermint show-validator"
return err
}
txf, msg, err := newBuildCreateValidatorMsg(clientCtx, txf, cmd.Flags(), validator, ac)
txf, msg, err := newBuildCreateValidatorMsg(clientCtx, txf, cmd.Flags(), validator, clientCtx.ValidatorAddressCodec)
if err != nil {
return err
}
@ -116,9 +114,7 @@ where we can get the pubkey using "%s tendermint show-validator"
}
// NewEditValidatorCmd returns a CLI command handler for creating a MsgEditValidator transaction.
//
// cannot give autocli support, can be CLI breaking
func NewEditValidatorCmd(ac address.Codec) *cobra.Command {
func NewEditValidatorCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "edit-validator",
Short: "edit an existing validator account",
@ -159,7 +155,7 @@ func NewEditValidatorCmd(ac address.Codec) *cobra.Command {
newMinSelfDelegation = &msb
}
valAddr, err := ac.BytesToString(clientCtx.GetFromAddress())
valAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress())
if err != nil {
return err
}

View File

@ -169,7 +169,7 @@ func (s *CLITestSuite) TestPrepareConfigForTxCreateValidator() {
func (s *CLITestSuite) TestNewCreateValidatorCmd() {
require := s.Require()
cmd := cli.NewCreateValidatorCmd(addresscodec.NewBech32Codec("cosmosvaloper"))
cmd := cli.NewCreateValidatorCmd()
validJSON := fmt.Sprintf(`
{
@ -316,7 +316,7 @@ func (s *CLITestSuite) TestNewCreateValidatorCmd() {
}
func (s *CLITestSuite) TestNewEditValidatorCmd() {
cmd := cli.NewEditValidatorCmd(addresscodec.NewBech32Codec("cosmos"))
cmd := cli.NewEditValidatorCmd()
moniker := "testing"
details := "bio"

View File

@ -49,7 +49,6 @@ var (
// AppModuleBasic defines the basic application module used by the staking module.
type AppModuleBasic struct {
cdc codec.Codec
ak types.AccountKeeper
}
// Name returns the staking module's name.
@ -92,7 +91,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *g
// GetTxCmd returns the root tx command for the staking module.
func (amb AppModuleBasic) GetTxCmd() *cobra.Command {
return cli.NewTxCmd(amb.cdc.InterfaceRegistry().SigningContext().ValidatorAddressCodec(), amb.cdc.InterfaceRegistry().SigningContext().AddressCodec())
return cli.NewTxCmd()
}
// AppModule implements an application module for the staking module.
@ -112,7 +111,7 @@ func NewAppModule(
bk types.BankKeeper,
) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc, ak: ak},
AppModuleBasic: AppModuleBasic{cdc: cdc},
keeper: keeper,
accountKeeper: ak,
bankKeeper: bk,