Merge PR #6652: x/distribution: In-Process Testing & CLI Refactor

This commit is contained in:
Alexander Bezobchuk 2020-07-10 10:45:46 -04:00 committed by GitHub
parent 1e23679066
commit 400c3cb08e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1072 additions and 341 deletions

View File

@ -7,6 +7,7 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -79,6 +80,11 @@ func ValidateCmd(cmd *cobra.Command, args []string) error {
// flags that do not necessarily change with context. These must be checked if
// the caller explicitly changed the values.
func ReadPersistentCommandFlags(clientCtx Context, flagSet *pflag.FlagSet) (Context, error) {
if flagSet.Changed(cli.OutputFlag) {
output, _ := flagSet.GetString(cli.OutputFlag)
clientCtx = clientCtx.WithOutputFormat(output)
}
if flagSet.Changed(flags.FlagHome) {
homeDir, _ := flagSet.GetString(flags.FlagHome)
clientCtx = clientCtx.WithHomeDir(homeDir)

View File

@ -219,6 +219,12 @@ func (ctx Context) WithTrustNode(trustNode bool) Context {
return ctx
}
// WithOutputFormat returns a copy of the context with an updated OutputFormat field.
func (ctx Context) WithOutputFormat(format string) Context {
ctx.OutputFormat = format
return ctx
}
// WithNodeURI returns a copy of the context with an updated node URI.
func (ctx Context) WithNodeURI(nodeURI string) Context {
ctx.NodeURI = nodeURI

View File

@ -6,7 +6,6 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
tmcli "github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
@ -80,6 +79,7 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command {
c.Flags().String(FlagNode, "tcp://localhost:26657", "<host>:<port> to Tendermint RPC interface for this chain")
c.Flags().Int64(FlagHeight, 0, "Use a specific height to query state at (this can error if the node is pruning state)")
c.Flags().String(FlagKeyringBackend, DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
c.Flags().StringP(tmcli.OutputFlag, "o", "text", "Output format (text|json)")
// TODO: REMOVE VIPER CALLS!
viper.BindPFlag(FlagTrustNode, c.Flags().Lookup(FlagTrustNode))

View File

@ -31,6 +31,7 @@ type BufferReader interface {
type BufferWriter interface {
io.Writer
Reset()
Bytes() []byte
String() string
}

View File

@ -262,12 +262,15 @@ func New(t *testing.T, cfg Config) *Network {
genBalances = append(genBalances, banktypes.Balance{Address: addr, Coins: balances.Sort()})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))
commission, err := sdk.NewDecFromStr("0.5")
require.NoError(t, err)
createValMsg := stakingtypes.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
sdk.NewCoin(sdk.DefaultBondDenom, cfg.BondedTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
stakingtypes.NewCommissionRates(commission, sdk.OneDec(), sdk.OneDec()),
sdk.OneInt(),
)
@ -338,6 +341,21 @@ func (n *Network) WaitForHeight(h int64) (int64, error) {
return n.WaitForHeightWithTimeout(h, 10*time.Second)
}
// LatestHeight returns the latest height of the network or an error if the
// query fails or no validators exist.
func (n *Network) LatestHeight() (int64, error) {
if len(n.Validators) == 0 {
return 0, errors.New("no validators available")
}
status, err := n.Validators[0].RPCClient.Status()
if err != nil {
return 0, err
}
return status.SyncInfo.LatestBlockHeight, nil
}
// WaitForHeightWithTimeout is the same as WaitForHeight except the caller can
// provide a custom timeout.
func (n *Network) WaitForHeightWithTimeout(h int64, t time.Duration) (int64, error) {

View File

@ -1,126 +1,842 @@
// +build cli_test
package cli_test
import (
"path/filepath"
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/stretchr/testify/suite"
tmcli "github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/cosmos/cosmos-sdk/tests/cli"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/testutil"
testnet "github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/client/testutil"
"github.com/cosmos/cosmos-sdk/x/distribution/client/cli"
distrtestutil "github.com/cosmos/cosmos-sdk/x/distribution/client/testutil"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
)
func TestCLIWithdrawRewards(t *testing.T) {
t.SkipNow() // TODO: Bring back once viper is refactored.
t.Parallel()
f := cli.InitFixtures(t)
type IntegrationTestSuite struct {
suite.Suite
genesisState := f.GenesisState()
inflationMin := sdk.MustNewDecFromStr("1.0")
var mintData minttypes.GenesisState
f.Cdc.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData)
mintData.Minter.Inflation = inflationMin
mintData.Params.InflationMin = inflationMin
mintData.Params.InflationMax = sdk.MustNewDecFromStr("1.0")
mintDataBz, err := f.Cdc.MarshalJSON(mintData)
require.NoError(t, err)
genesisState[minttypes.ModuleName] = mintDataBz
genFile := filepath.Join(f.SimdHome, "config", "genesis.json")
genDoc, err := tmtypes.GenesisDocFromFile(genFile)
require.NoError(t, err)
genDoc.AppState, err = f.Cdc.MarshalJSON(genesisState)
require.NoError(t, genDoc.SaveAs(genFile))
// start simd server
proc := f.SDStart()
t.Cleanup(func() { proc.Stop(false) })
params := testutil.QueryParameters(f)
require.NotEmpty(t, params)
fooAddr := f.KeyAddress(cli.KeyFoo)
barAddr := f.KeyAddress(cli.KeyBar)
fooVal := sdk.ValAddress(fooAddr)
outstandingRewards := testutil.QueryValidatorOutstandingRewards(f, fooVal.String())
require.NotEmpty(t, outstandingRewards)
require.False(t, outstandingRewards.Rewards.IsZero())
commission := testutil.QueryCommission(f, fooVal.String())
require.NotEmpty(t, commission)
require.False(t, commission.Commission.IsZero())
rewards := testutil.QueryRewards(f, fooAddr)
require.Len(t, rewards.Rewards, 1)
require.NotEmpty(t, rewards.Total)
// withdrawing rewards of a delegation for a single validator
success := testutil.TxWithdrawRewards(f, fooVal, fooAddr.String(), "-y")
require.True(t, success)
rewards = testutil.QueryRewards(f, fooAddr)
require.Len(t, rewards.Rewards, 1)
require.Len(t, rewards.Total, 1)
// Setting up a new withdraw address
success, stdout, stderr := testutil.TxSetWithdrawAddress(f, fooAddr.String(), barAddr.String(), "--generate-only")
require.True(t, success)
require.Empty(t, stderr)
msg := cli.UnmarshalStdTx(t, f.Cdc, stdout)
require.NotZero(t, msg.Fee.Gas)
require.Len(t, msg.Msgs, 1)
require.Len(t, msg.GetSignatures(), 0)
success, _, stderr = testutil.TxSetWithdrawAddress(f, cli.KeyFoo, barAddr.String(), "-y")
require.True(t, success)
require.Empty(t, stderr)
tests.WaitForNextNBlocksTM(1, f.Port)
// Withdraw all delegation rewards from all validators
success, stdout, stderr = testutil.TxWithdrawAllRewards(f, fooAddr.String(), "--generate-only")
require.True(t, success)
require.Empty(t, stderr)
msg = cli.UnmarshalStdTx(t, f.Cdc, stdout)
require.NotZero(t, msg.Fee.Gas)
require.Len(t, msg.Msgs, 1)
require.Len(t, msg.GetSignatures(), 0)
success, _, stderr = testutil.TxWithdrawAllRewards(f, cli.KeyFoo, "-y")
require.True(t, success)
require.Empty(t, stderr)
tests.WaitForNextNBlocksTM(1, f.Port)
newTokens := sdk.NewCoin(cli.Denom, sdk.TokensFromConsensusPower(1))
// Withdraw all delegation rewards from all validators
success, stdout, stderr = testutil.TxFundCommunityPool(f, fooAddr.String(), newTokens, "--generate-only")
require.True(t, success)
require.Empty(t, stderr)
msg = cli.UnmarshalStdTx(t, f.Cdc, stdout)
require.NotZero(t, msg.Fee.Gas)
require.Len(t, msg.Msgs, 1)
require.Len(t, msg.GetSignatures(), 0)
success, _, stderr = testutil.TxFundCommunityPool(f, cli.KeyFoo, newTokens, "-y")
require.True(t, success)
require.Empty(t, stderr)
tests.WaitForNextNBlocksTM(1, f.Port)
amount := testutil.QueryCommunityPool(f)
require.False(t, amount.IsZero())
slashes := testutil.QuerySlashes(f, fooVal.String())
require.Nil(t, slashes, nil)
f.Cleanup()
cfg testnet.Config
network *testnet.Network
}
// SetupTest creates a new network for _each_ integration 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 *IntegrationTestSuite) SetupTest() {
s.T().Log("setting up integration test suite")
cfg := testnet.DefaultConfig()
genesisState := cfg.GenesisState
cfg.NumValidators = 1
var mintData minttypes.GenesisState
s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData))
inflation := sdk.MustNewDecFromStr("1.0")
mintData.Minter.Inflation = inflation
mintData.Params.InflationMin = inflation
mintData.Params.InflationMax = inflation
mintDataBz, err := cfg.Codec.MarshalJSON(mintData)
s.Require().NoError(err)
genesisState[minttypes.ModuleName] = mintDataBz
cfg.GenesisState = genesisState
s.cfg = cfg
s.network = testnet.New(s.T(), cfg)
_, err = s.network.WaitForHeight(1)
s.Require().NoError(err)
}
// TearDownTest cleans up the curret test network after _each_ test.
func (s *IntegrationTestSuite) TearDownTest() {
s.T().Log("tearing down integration test suite")
s.network.Cleanup()
}
func (s *IntegrationTestSuite) TestGetCmdQueryParams() {
val := s.network.Validators[0]
testCases := []struct {
name string
args []string
expectedOutput string
}{
{
"default output",
[]string{},
`{"community_tax":"0.020000000000000000","base_proposer_reward":"0.010000000000000000","bonus_proposer_reward":"0.040000000000000000","withdraw_addr_enabled":true}`,
},
{
"text output",
[]string{fmt.Sprintf("--%s=text", tmcli.OutputFlag)},
`base_proposer_reward: "0.010000000000000000"
bonus_proposer_reward: "0.040000000000000000"
community_tax: "0.020000000000000000"
withdraw_addr_enabled: true`,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.GetCommands(cli.GetCmdQueryParams())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
s.Require().NoError(cmd.ExecuteContext(ctx))
s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
})
}
}
func (s *IntegrationTestSuite) TestGetCmdQueryValidatorOutstandingRewards() {
val := s.network.Validators[0]
_, err := s.network.WaitForHeight(4)
s.Require().NoError(err)
testCases := []struct {
name string
args []string
expectErr bool
expectedOutput string
}{
{
"invalid validator address",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
"foo",
},
true,
"",
},
{
"default output",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(),
},
false,
`{"rewards":[{"denom":"stake","amount":"232.260000000000000000"}]}`,
},
{
"text output",
[]string{
fmt.Sprintf("--%s=text", tmcli.OutputFlag),
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(),
},
false,
`rewards:
- amount: "232.260000000000000000"
denom: stake`,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.GetCommands(cli.GetCmdQueryValidatorOutstandingRewards())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
}
})
}
}
func (s *IntegrationTestSuite) TestGetCmdQueryValidatorCommission() {
val := s.network.Validators[0]
_, err := s.network.WaitForHeight(4)
s.Require().NoError(err)
testCases := []struct {
name string
args []string
expectErr bool
expectedOutput string
}{
{
"invalid validator address",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
"foo",
},
true,
"",
},
{
"default output",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(),
},
false,
`{"commission":[{"denom":"stake","amount":"116.130000000000000000"}]}`,
},
{
"text output",
[]string{
fmt.Sprintf("--%s=text", tmcli.OutputFlag),
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(),
},
false,
`commission:
- amount: "116.130000000000000000"
denom: stake`,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.GetCommands(cli.GetCmdQueryValidatorCommission())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
}
})
}
}
func (s *IntegrationTestSuite) TestGetCmdQueryValidatorSlashes() {
val := s.network.Validators[0]
_, err := s.network.WaitForHeight(4)
s.Require().NoError(err)
testCases := []struct {
name string
args []string
expectErr bool
expectedOutput string
}{
{
"invalid validator address",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
"foo", "1", "3",
},
true,
"",
},
{
"invalid start height",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(), "-1", "3",
},
true,
"",
},
{
"invalid end height",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(), "1", "-3",
},
true,
"",
},
{
"default output",
[]string{
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(), "1", "3",
},
false,
"null",
},
{
"text output",
[]string{
fmt.Sprintf("--%s=text", tmcli.OutputFlag),
fmt.Sprintf("--%s=3", flags.FlagHeight),
sdk.ValAddress(val.Address).String(), "1", "3",
},
false,
"null",
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.GetCommands(cli.GetCmdQueryValidatorSlashes())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
}
})
}
}
func (s *IntegrationTestSuite) TestGetCmdQueryDelegatorRewards() {
val := s.network.Validators[0]
addr := val.Address
valAddr := sdk.ValAddress(addr)
_, err := s.network.WaitForHeightWithTimeout(11, time.Minute)
s.Require().NoError(err)
testCases := []struct {
name string
args []string
expectErr bool
expectedOutput string
}{
{
"invalid delegator address",
[]string{
fmt.Sprintf("--%s=5", flags.FlagHeight),
"foo", valAddr.String(),
},
true,
"",
},
{
"invalid validator address",
[]string{
fmt.Sprintf("--%s=5", flags.FlagHeight),
addr.String(), "foo",
},
true,
"",
},
{
"default output",
[]string{
fmt.Sprintf("--%s=10", flags.FlagHeight),
addr.String(),
},
false,
fmt.Sprintf(`{"rewards":[{"validator_address":"%s","reward":[{"denom":"stake","amount":"387.100000000000000000"}]}],"total":[{"denom":"stake","amount":"387.100000000000000000"}]}`, valAddr.String()),
},
{
"default output (specific validator)",
[]string{
fmt.Sprintf("--%s=10", flags.FlagHeight),
addr.String(), valAddr.String(),
},
false,
`[{"denom":"stake","amount":"387.100000000000000000"}]`,
},
{
"text output",
[]string{
fmt.Sprintf("--%s=text", tmcli.OutputFlag),
fmt.Sprintf("--%s=10", flags.FlagHeight),
addr.String(),
},
false,
fmt.Sprintf(`rewards:
- reward:
- amount: "387.100000000000000000"
denom: stake
validator_address: %s
total:
- amount: "387.100000000000000000"
denom: stake`, valAddr.String()),
},
{
"text output (specific validator)",
[]string{
fmt.Sprintf("--%s=text", tmcli.OutputFlag),
fmt.Sprintf("--%s=10", flags.FlagHeight),
addr.String(), valAddr.String(),
},
false,
`- amount: "387.100000000000000000"
denom: stake`,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.GetCommands(cli.GetCmdQueryDelegatorRewards())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
}
})
}
}
func (s *IntegrationTestSuite) TestGetCmdQueryCommunityPool() {
val := s.network.Validators[0]
_, err := s.network.WaitForHeight(3)
s.Require().NoError(err)
testCases := []struct {
name string
args []string
expectedOutput string
}{
{
"default output",
[]string{fmt.Sprintf("--%s=3", flags.FlagHeight)},
`[{"denom":"stake","amount":"4.740000000000000000"}]`,
},
{
"text output",
[]string{fmt.Sprintf("--%s=text", tmcli.OutputFlag), fmt.Sprintf("--%s=3", flags.FlagHeight)},
`- amount: "4.740000000000000000"
denom: stake`,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.GetCommands(cli.GetCmdQueryCommunityPool())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
s.Require().NoError(cmd.ExecuteContext(ctx))
s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
})
}
}
func (s *IntegrationTestSuite) TestNewWithdrawRewardsCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string
valAddr fmt.Stringer
args []string
expectErr bool
respType fmt.Stringer
expectedCode uint32
}{
{
"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.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
true, nil, 0,
},
{
"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.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
{
"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.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
clientCtx := val.ClientCtx
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
bz, err := distrtestutil.MsgWithdrawDelegatorRewardExec(clientCtx, tc.valAddr, tc.args...)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(bz, tc.respType), string(bz))
txResp := tc.respType.(*sdk.TxResponse)
s.Require().Equal(tc.expectedCode, txResp.Code)
}
})
}
}
func (s *IntegrationTestSuite) TestNewWithdrawAllRewardsCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string
args []string
expectErr bool
respType fmt.Stringer
expectedCode uint32
}{
{
"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.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
true, nil, 0,
},
{
"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.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.PostCommands(cli.NewWithdrawAllRewardsCmd())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
txResp := tc.respType.(*sdk.TxResponse)
s.Require().Equal(tc.expectedCode, txResp.Code)
}
})
}
}
func (s *IntegrationTestSuite) TestNewSetWithdrawAddrCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string
args []string
expectErr bool
respType fmt.Stringer
expectedCode uint32
}{
{
"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.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
true, nil, 0,
},
{
"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.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.PostCommands(cli.NewSetWithdrawAddrCmd())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
txResp := tc.respType.(*sdk.TxResponse)
s.Require().Equal(tc.expectedCode, txResp.Code)
}
})
}
}
func (s *IntegrationTestSuite) TestNewFundCommunityPoolCmd() {
val := s.network.Validators[0]
testCases := []struct {
name string
args []string
expectErr bool
respType fmt.Stringer
expectedCode uint32
}{
{
"invalid funding amount",
[]string{
"-43foocoin",
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
true, nil, 0,
},
{
"valid transaction",
[]string{
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431))).String(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.PostCommands(cli.NewFundCommunityPoolCmd())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
txResp := tc.respType.(*sdk.TxResponse)
s.Require().Equal(tc.expectedCode, txResp.Code)
}
})
}
}
func (s *IntegrationTestSuite) TestGetCmdSubmitProposal() {
val := s.network.Validators[0]
invalidPropFile, err := ioutil.TempFile(os.TempDir(), "invalid_community_spend_proposal.*.json")
s.Require().NoError(err)
defer os.Remove(invalidPropFile.Name())
invalidProp := `{
"title": "",
"description": "Pay me some Atoms!",
"recipient": "foo",
"amount": "-343foocoin",
"deposit": -324foocoin
}`
_, err = invalidPropFile.WriteString(invalidProp)
s.Require().NoError(err)
validPropFile, err := ioutil.TempFile(os.TempDir(), "valid_community_spend_proposal.*.json")
s.Require().NoError(err)
defer os.Remove(validPropFile.Name())
validProp := fmt.Sprintf(`{
"title": "Community Pool Spend",
"description": "Pay me some Atoms!",
"recipient": "%s",
"amount": "%s",
"deposit": "%s"
}`, val.Address.String(), sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)), sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)))
_, err = validPropFile.WriteString(validProp)
s.Require().NoError(err)
testCases := []struct {
name string
args []string
expectErr bool
respType fmt.Stringer
expectedCode uint32
}{
{
"invalid proposal",
[]string{
invalidPropFile.Name(),
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, sdk.NewInt(10))).String()),
},
true, nil, 0,
},
{
"valid transaction",
[]string{
validPropFile.Name(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), // sync mode as there are no funds yet
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, &sdk.TxResponse{}, 0,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := flags.PostCommands(cli.GetCmdSubmitProposal())[0]
_, out := testutil.ApplyMockIO(cmd)
clientCtx := val.ClientCtx.WithOutput(out)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
out.Reset()
cmd.SetArgs(tc.args)
err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
txResp := tc.respType.(*sdk.TxResponse)
s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
}
})
}
}
func TestIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}

View File

@ -9,7 +9,6 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/distribution/client/common"
@ -17,7 +16,7 @@ import (
)
// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetQueryCmd() *cobra.Command {
distQueryCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Querying commands for the distribution module",
@ -27,25 +26,29 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
}
distQueryCmd.AddCommand(flags.GetCommands(
GetCmdQueryParams(queryRoute, cdc),
GetCmdQueryValidatorOutstandingRewards(queryRoute, cdc),
GetCmdQueryValidatorCommission(queryRoute, cdc),
GetCmdQueryValidatorSlashes(queryRoute, cdc),
GetCmdQueryDelegatorRewards(queryRoute, cdc),
GetCmdQueryCommunityPool(queryRoute, cdc),
GetCmdQueryParams(),
GetCmdQueryValidatorOutstandingRewards(),
GetCmdQueryValidatorCommission(),
GetCmdQueryValidatorSlashes(),
GetCmdQueryDelegatorRewards(),
GetCmdQueryCommunityPool(),
)...)
return distQueryCmd
}
// GetCmdQueryParams implements the query params command.
func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetCmdQueryParams() *cobra.Command {
return &cobra.Command{
Use: "params",
Args: cobra.NoArgs,
Short: "Query distribution params",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryParams)
res, _, err := clientCtx.QueryWithData(route, nil)
@ -54,7 +57,7 @@ func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
}
var params types.Params
if err := cdc.UnmarshalJSON(res, &params); err != nil {
if err := clientCtx.JSONMarshaler.UnmarshalJSON(res, &params); err != nil {
return fmt.Errorf("failed to unmarshal params: %w", err)
}
@ -63,15 +66,15 @@ func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
}
}
// GetCmdQueryValidatorOutstandingRewards implements the query validator outstanding rewards command.
func GetCmdQueryValidatorOutstandingRewards(queryRoute string, cdc *codec.Codec) *cobra.Command {
// GetCmdQueryValidatorOutstandingRewards implements the query validator
// outstanding rewards command.
func GetCmdQueryValidatorOutstandingRewards() *cobra.Command {
return &cobra.Command{
Use: "validator-outstanding-rewards [validator]",
Args: cobra.ExactArgs(1),
Short: "Query distribution outstanding (un-withdrawn) rewards for a validator and all their delegations",
Long: strings.TrimSpace(
fmt.Sprintf(`Query distribution outstanding (un-withdrawn) rewards
for a validator and all their delegations.
fmt.Sprintf(`Query distribution outstanding (un-withdrawn) rewards for a validator and all their delegations.
Example:
$ %s query distribution validator-outstanding-rewards cosmosvaloper1lwjmdnks33xwnmfayc64ycprww49n33mtm92ne
@ -80,7 +83,11 @@ $ %s query distribution validator-outstanding-rewards cosmosvaloper1lwjmdnks33xw
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
valAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
@ -88,13 +95,13 @@ $ %s query distribution validator-outstanding-rewards cosmosvaloper1lwjmdnks33xw
}
params := types.NewQueryValidatorOutstandingRewardsParams(valAddr)
bz, err := cdc.MarshalJSON(params)
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
if err != nil {
return err
}
resp, _, err := clientCtx.QueryWithData(
fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryValidatorOutstandingRewards),
fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryValidatorOutstandingRewards),
bz,
)
if err != nil {
@ -102,7 +109,7 @@ $ %s query distribution validator-outstanding-rewards cosmosvaloper1lwjmdnks33xw
}
var outstandingRewards types.ValidatorOutstandingRewards
if err := cdc.UnmarshalJSON(resp, &outstandingRewards); err != nil {
if err := clientCtx.JSONMarshaler.UnmarshalJSON(resp, &outstandingRewards); err != nil {
return err
}
@ -112,7 +119,7 @@ $ %s query distribution validator-outstanding-rewards cosmosvaloper1lwjmdnks33xw
}
// GetCmdQueryValidatorCommission implements the query validator commission command.
func GetCmdQueryValidatorCommission(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetCmdQueryValidatorCommission() *cobra.Command {
return &cobra.Command{
Use: "commission [validator]",
Args: cobra.ExactArgs(1),
@ -127,27 +134,34 @@ $ %s query distribution commission cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9l
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
validatorAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
res, err := common.QueryValidatorCommission(clientCtx, queryRoute, validatorAddr)
res, err := common.QueryValidatorCommission(clientCtx, validatorAddr)
if err != nil {
return err
}
var valCom types.ValidatorAccumulatedCommission
cdc.MustUnmarshalJSON(res, &valCom)
if err := clientCtx.JSONMarshaler.UnmarshalJSON(res, &valCom); err != nil {
return err
}
return clientCtx.PrintOutput(valCom)
},
}
}
// GetCmdQueryValidatorSlashes implements the query validator slashes command.
func GetCmdQueryValidatorSlashes(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetCmdQueryValidatorSlashes() *cobra.Command {
return &cobra.Command{
Use: "slashes [validator] [start-height] [end-height]",
Args: cobra.ExactArgs(3),
@ -162,7 +176,11 @@ $ %s query distribution slashes cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmq
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
validatorAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
@ -180,29 +198,30 @@ $ %s query distribution slashes cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmq
}
params := types.NewQueryValidatorSlashesParams(validatorAddr, startHeight, endHeight)
bz, err := cdc.MarshalJSON(params)
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
if err != nil {
return err
}
res, _, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/validator_slashes", queryRoute), bz)
res, _, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/validator_slashes", types.QuerierRoute), bz)
if err != nil {
return err
}
var slashes []types.ValidatorSlashEvent
if err = cdc.UnmarshalJSON(res, &slashes); err != nil {
if err = clientCtx.JSONMarshaler.UnmarshalJSON(res, &slashes); err != nil {
return fmt.Errorf("failed to unmarshal response: %w", err)
}
return clientCtx.PrintOutput(slashes)
},
}
}
// GetCmdQueryDelegatorRewards implements the query delegator rewards command.
func GetCmdQueryDelegatorRewards(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetCmdQueryDelegatorRewards() *cobra.Command {
return &cobra.Command{
Use: "rewards [delegator-addr] [<validator-addr>]",
Use: "rewards [delegator-addr] [validator-addr]",
Args: cobra.RangeArgs(1, 2),
Short: "Query all distribution delegator rewards or rewards from a particular validator",
Long: strings.TrimSpace(
@ -216,17 +235,21 @@ $ %s query distribution rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p co
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
// query for rewards from a particular delegation
if len(args) == 2 {
resp, _, err := common.QueryDelegationRewards(clientCtx, queryRoute, args[0], args[1])
resp, _, err := common.QueryDelegationRewards(clientCtx, args[0], args[1])
if err != nil {
return err
}
var result sdk.DecCoins
if err = cdc.UnmarshalJSON(resp, &result); err != nil {
if err = clientCtx.JSONMarshaler.UnmarshalJSON(resp, &result); err != nil {
return fmt.Errorf("failed to unmarshal response: %w", err)
}
@ -239,20 +262,20 @@ $ %s query distribution rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p co
}
params := types.NewQueryDelegatorParams(delegatorAddr)
bz, err := cdc.MarshalJSON(params)
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
if err != nil {
return fmt.Errorf("failed to marshal params: %w", err)
}
// query for delegator total rewards
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorTotalRewards)
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryDelegatorTotalRewards)
res, _, err := clientCtx.QueryWithData(route, bz)
if err != nil {
return err
}
var result types.QueryDelegatorTotalRewardsResponse
if err = cdc.UnmarshalJSON(res, &result); err != nil {
if err = clientCtx.JSONMarshaler.UnmarshalJSON(res, &result); err != nil {
return fmt.Errorf("failed to unmarshal response: %w", err)
}
@ -262,7 +285,7 @@ $ %s query distribution rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p co
}
// GetCmdQueryCommunityPool returns the command for fetching community pool info
func GetCmdQueryCommunityPool(queryRoute string, cdc *codec.Codec) *cobra.Command {
func GetCmdQueryCommunityPool() *cobra.Command {
return &cobra.Command{
Use: "community-pool",
Args: cobra.NoArgs,
@ -277,15 +300,22 @@ $ %s query distribution community-pool
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.NewContext().WithCodec(cdc).WithJSONMarshaler(cdc)
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
res, _, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/community_pool", queryRoute), nil)
res, _, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/community_pool", types.QuerierRoute), nil)
if err != nil {
return err
}
var result sdk.DecCoins
cdc.MustUnmarshalJSON(res, &result)
if err := clientCtx.JSONMarshaler.UnmarshalJSON(res, &result); err != nil {
return err
}
return clientCtx.PrintOutput(result)
},
}

View File

@ -1,4 +1,3 @@
// nolint
package cli
import (
@ -6,6 +5,7 @@ import (
"strings"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
@ -17,11 +17,10 @@ import (
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
)
// Transaction flags for the x/distribution module
var (
flagOnlyFromValidator = "only-from-validator"
flagIsValidator = "is-validator"
flagCommission = "commission"
flagMaxMessagesPerTx = "max-msgs"
FlagCommission = "commission"
FlagMaxMessagesPerTx = "max-msgs"
)
const (
@ -29,7 +28,7 @@ const (
)
// NewTxCmd returns a root CLI command handler for all x/distribution transaction commands.
func NewTxCmd(clientCtx client.Context) *cobra.Command {
func NewTxCmd() *cobra.Command {
distTxCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Distribution transactions subcommands",
@ -39,25 +38,24 @@ func NewTxCmd(clientCtx client.Context) *cobra.Command {
}
distTxCmd.AddCommand(flags.PostCommands(
NewWithdrawRewardsCmd(clientCtx),
NewWithdrawAllRewardsCmd(clientCtx),
NewSetWithdrawAddrCmd(clientCtx),
NewFundCommunityPoolCmd(clientCtx),
NewWithdrawRewardsCmd(),
NewWithdrawAllRewardsCmd(),
NewSetWithdrawAddrCmd(),
NewFundCommunityPoolCmd(),
)...)
return distTxCmd
}
type newGenerateOrBroadcastFunc func(clientCtx client.Context, msgs ...sdk.Msg) error
type newGenerateOrBroadcastFunc func(client.Context, *pflag.FlagSet, ...sdk.Msg) error
func newSplitAndApply(
newGenerateOrBroadcast newGenerateOrBroadcastFunc,
clientCtx client.Context,
msgs []sdk.Msg,
chunkSize int,
genOrBroadcastFn newGenerateOrBroadcastFunc, clientCtx client.Context,
fs *pflag.FlagSet, msgs []sdk.Msg, chunkSize int,
) error {
if chunkSize == 0 {
return newGenerateOrBroadcast(clientCtx, msgs...)
return genOrBroadcastFn(clientCtx, fs, msgs...)
}
// split messages into slices of length chunkSize
@ -70,7 +68,7 @@ func newSplitAndApply(
}
msgChunk := msgs[i:sliceEnd]
if err := newGenerateOrBroadcast(clientCtx, msgChunk...); err != nil {
if err := genOrBroadcastFn(clientCtx, fs, msgChunk...); err != nil {
return err
}
}
@ -78,7 +76,7 @@ func newSplitAndApply(
return nil
}
func NewWithdrawRewardsCmd(clientCtx client.Context) *cobra.Command {
func NewWithdrawRewardsCmd() *cobra.Command {
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",
@ -95,7 +93,11 @@ $ %s tx distribution withdraw-rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fx
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := clientCtx.InitWithInput(cmd.InOrStdin())
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
delAddr := clientCtx.GetFromAddress()
valAddr, err := sdk.ValAddressFromBech32(args[0])
@ -105,7 +107,7 @@ $ %s tx distribution withdraw-rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fx
msgs := []sdk.Msg{types.NewMsgWithdrawDelegatorReward(delAddr, valAddr)}
if commission, _ := cmd.Flags().GetBool(flagCommission); commission {
if commission, _ := cmd.Flags().GetBool(FlagCommission); commission {
msgs = append(msgs, types.NewMsgWithdrawValidatorCommission(valAddr))
}
@ -115,15 +117,15 @@ $ %s tx distribution withdraw-rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fx
}
}
return tx.GenerateOrBroadcastTx(clientCtx, msgs...)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgs...)
},
}
cmd.Flags().Bool(flagCommission, false, "also withdraw validator's commission")
cmd.Flags().Bool(FlagCommission, false, "Withdraw the validator's commission in addition to the rewards")
return cmd
}
func NewWithdrawAllRewardsCmd(clientCtx client.Context) *cobra.Command {
func NewWithdrawAllRewardsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "withdraw-all-rewards",
Short: "withdraw all delegations rewards for a delegator",
@ -137,8 +139,12 @@ $ %s tx distribution withdraw-all-rewards --from mykey
),
),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := clientCtx.InitWithInput(cmd.InOrStdin())
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
delAddr := clientCtx.GetFromAddress()
@ -148,22 +154,22 @@ $ %s tx distribution withdraw-all-rewards --from mykey
return fmt.Errorf("cannot generate tx in offline mode")
}
msgs, err := common.WithdrawAllDelegatorRewards(clientCtx, types.QuerierRoute, delAddr)
msgs, err := common.WithdrawAllDelegatorRewards(clientCtx, delAddr)
if err != nil {
return err
}
chunkSize, _ := cmd.Flags().GetInt(flagMaxMessagesPerTx)
return newSplitAndApply(tx.GenerateOrBroadcastTx, clientCtx, msgs, chunkSize)
chunkSize, _ := cmd.Flags().GetInt(FlagMaxMessagesPerTx)
return newSplitAndApply(tx.GenerateOrBroadcastTxCLI, clientCtx, cmd.Flags(), msgs, chunkSize)
},
}
cmd.Flags().Int(flagMaxMessagesPerTx, MaxMessagesPerTxDefault, "Limit the number of messages per tx (0 for unlimited)")
cmd.Flags().Int(FlagMaxMessagesPerTx, MaxMessagesPerTxDefault, "Limit the number of messages per tx (0 for unlimited)")
return cmd
}
func NewSetWithdrawAddrCmd(clientCtx client.Context) *cobra.Command {
cmd := &cobra.Command{
func NewSetWithdrawAddrCmd() *cobra.Command {
return &cobra.Command{
Use: "set-withdraw-addr [withdraw-addr]",
Short: "change the default withdraw address for rewards associated with an address",
Long: strings.TrimSpace(
@ -177,7 +183,11 @@ $ %s tx distribution set-withdraw-addr cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := clientCtx.InitWithInput(cmd.InOrStdin())
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
delAddr := clientCtx.GetFromAddress()
withdrawAddr, err := sdk.AccAddressFromBech32(args[0])
@ -190,14 +200,13 @@ $ %s tx distribution set-withdraw-addr cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75
return err
}
return tx.GenerateOrBroadcastTx(clientCtx, msg)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
return cmd
}
func NewFundCommunityPoolCmd(clientCtx client.Context) *cobra.Command {
cmd := &cobra.Command{
func NewFundCommunityPoolCmd() *cobra.Command {
return &cobra.Command{
Use: "fund-community-pool [amount]",
Args: cobra.ExactArgs(1),
Short: "Funds the community pool with the specified amount",
@ -211,7 +220,11 @@ $ %s tx distribution fund-community-pool 100uatom --from mykey
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := clientCtx.InitWithInput(cmd.InOrStdin())
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
depositorAddr := clientCtx.GetFromAddress()
amount, err := sdk.ParseCoins(args[0])
@ -224,16 +237,14 @@ $ %s tx distribution fund-community-pool 100uatom --from mykey
return err
}
return tx.GenerateOrBroadcastTx(clientCtx, msg)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
return cmd
}
// GetCmdSubmitProposal implements the command to submit a community-pool-spend proposal
func GetCmdSubmitProposal(clientCtx client.Context) *cobra.Command {
cmd := &cobra.Command{
func GetCmdSubmitProposal() *cobra.Command {
return &cobra.Command{
Use: "community-pool-spend [proposal-file]",
Args: cobra.ExactArgs(1),
Short: "Submit a community pool spend proposal",
@ -258,36 +269,40 @@ Where proposal.json contains:
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := clientCtx.InitWithInput(cmd.InOrStdin())
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
proposal, err := ParseCommunityPoolSpendProposalJSON(clientCtx.JSONMarshaler, args[0])
if err != nil {
return err
}
from := clientCtx.GetFromAddress()
amount, err := sdk.ParseCoins(proposal.Amount)
if err != nil {
return err
}
content := types.NewCommunityPoolSpendProposal(proposal.Title, proposal.Description, proposal.Recipient, amount)
deposit, err := sdk.ParseCoins(proposal.Deposit)
if err != nil {
return err
}
from := clientCtx.GetFromAddress()
content := types.NewCommunityPoolSpendProposal(proposal.Title, proposal.Description, proposal.Recipient, amount)
msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from)
if err != nil {
return err
}
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTx(clientCtx, msg)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
return cmd
}

View File

@ -3,6 +3,8 @@ package cli
import (
"testing"
"github.com/spf13/pflag"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/cosmos/cosmos-sdk/testutil"
@ -19,7 +21,7 @@ import (
func Test_splitAndCall_NoMessages(t *testing.T) {
clientCtx := client.Context{}
err := newSplitAndApply(nil, clientCtx, nil, 10)
err := newSplitAndApply(nil, clientCtx, nil, nil, 10)
assert.NoError(t, err, "")
}
@ -42,7 +44,7 @@ func Test_splitAndCall_Splitting(t *testing.T) {
callCount := 0
err := newSplitAndApply(
func(clientCtx client.Context, msgs ...sdk.Msg) error {
func(clientCtx client.Context, fs *pflag.FlagSet, msgs ...sdk.Msg) error {
callCount++
assert.NotNil(t, clientCtx)
@ -56,7 +58,7 @@ func Test_splitAndCall_Splitting(t *testing.T) {
return nil
},
clientCtx, msgs, chunkSize)
clientCtx, nil, msgs, chunkSize)
assert.NoError(t, err, "")
assert.Equal(t, 3, callCount)

View File

@ -10,7 +10,7 @@ import (
// QueryDelegationRewards queries a delegation rewards between a delegator and a
// validator.
func QueryDelegationRewards(clientCtx client.Context, queryRoute, delAddr, valAddr string) ([]byte, int64, error) {
func QueryDelegationRewards(clientCtx client.Context, delAddr, valAddr string) ([]byte, int64, error) {
delegatorAddr, err := sdk.AccAddressFromBech32(delAddr)
if err != nil {
return nil, 0, err
@ -27,24 +27,24 @@ func QueryDelegationRewards(clientCtx client.Context, queryRoute, delAddr, valAd
return nil, 0, fmt.Errorf("failed to marshal params: %w", err)
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegationRewards)
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryDelegationRewards)
return clientCtx.QueryWithData(route, bz)
}
// QueryDelegatorValidators returns delegator's list of validators
// it submitted delegations to.
func QueryDelegatorValidators(clientCtx client.Context, queryRoute string, delegatorAddr sdk.AccAddress) ([]byte, error) {
func QueryDelegatorValidators(clientCtx client.Context, delegatorAddr sdk.AccAddress) ([]byte, error) {
res, _, err := clientCtx.QueryWithData(
fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorValidators),
fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryDelegatorValidators),
clientCtx.JSONMarshaler.MustMarshalJSON(types.NewQueryDelegatorParams(delegatorAddr)),
)
return res, err
}
// QueryValidatorCommission returns a validator's commission.
func QueryValidatorCommission(clientCtx client.Context, queryRoute string, validatorAddr sdk.ValAddress) ([]byte, error) {
func QueryValidatorCommission(clientCtx client.Context, validatorAddr sdk.ValAddress) ([]byte, error) {
res, _, err := clientCtx.QueryWithData(
fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryValidatorCommission),
fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryValidatorCommission),
clientCtx.JSONMarshaler.MustMarshalJSON(types.NewQueryValidatorCommissionParams(validatorAddr)),
)
return res, err
@ -52,10 +52,10 @@ func QueryValidatorCommission(clientCtx client.Context, queryRoute string, valid
// WithdrawAllDelegatorRewards builds a multi-message slice to be used
// to withdraw all delegations rewards for the given delegator.
func WithdrawAllDelegatorRewards(clientCtx client.Context, queryRoute string, delegatorAddr sdk.AccAddress) ([]sdk.Msg, error) {
func WithdrawAllDelegatorRewards(clientCtx client.Context, delegatorAddr sdk.AccAddress) ([]sdk.Msg, error) {
// retrieve the comprehensive list of all validators which the
// delegator had submitted delegations to
bz, err := QueryDelegatorValidators(clientCtx, queryRoute, delegatorAddr)
bz, err := QueryDelegatorValidators(clientCtx, delegatorAddr)
if err != nil {
return nil, err
}

View File

@ -32,7 +32,7 @@ func TestQueryDelegationRewardsAddrValidation(t *testing.T) {
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
_, _, err := QueryDelegationRewards(clientCtx, "", tt.args.delAddr, tt.args.valAddr)
_, _, err := QueryDelegationRewards(clientCtx, tt.args.delAddr, tt.args.valAddr)
require.True(t, err != nil, tt.wantErr)
})
}

View File

@ -108,7 +108,7 @@ func delegationRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
valAddr := mux.Vars(r)["validatorAddr"]
// query for rewards from a particular delegation
res, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, types.QuerierRoute, delAddr, valAddr)
res, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, delAddr, valAddr)
if !ok {
return
}
@ -174,7 +174,7 @@ func validatorInfoHandlerFn(clientCtx client.Context) http.HandlerFunc {
}
// query commission
bz, err := common.QueryValidatorCommission(clientCtx, types.QuerierRoute, valAddr)
bz, err := common.QueryValidatorCommission(clientCtx, valAddr)
if rest.CheckInternalServerError(w, err) {
return
}
@ -186,7 +186,7 @@ func validatorInfoHandlerFn(clientCtx client.Context) http.HandlerFunc {
// self bond rewards
delAddr := sdk.AccAddress(valAddr)
bz, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, types.QuerierRoute, delAddr.String(), valAddr.String())
bz, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, delAddr.String(), valAddr.String())
if !ok {
return
}
@ -221,7 +221,7 @@ func validatorRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
}
delAddr := sdk.AccAddress(validatorAddr).String()
bz, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, types.QuerierRoute, delAddr, valAddr)
bz, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, delAddr, valAddr)
if !ok {
return
}
@ -297,10 +297,10 @@ func outstandingRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
}
func checkResponseQueryDelegationRewards(
w http.ResponseWriter, clientCtx client.Context, queryRoute, delAddr, valAddr string,
w http.ResponseWriter, clientCtx client.Context, delAddr, valAddr string,
) (res []byte, height int64, ok bool) {
res, height, err := common.QueryDelegationRewards(clientCtx, queryRoute, delAddr, valAddr)
res, height, err := common.QueryDelegationRewards(clientCtx, delAddr, valAddr)
if rest.CheckInternalServerError(w, err) {
return nil, 0, false
}

View File

@ -20,9 +20,9 @@ func RegisterHandlers(clientCtx client.Context, r *mux.Router) {
}
// RegisterRoutes register distribution REST routes.
func RegisterRoutes(clientCtx client.Context, r *mux.Router, queryRoute string) {
func RegisterRoutes(clientCtx client.Context, r *mux.Router) {
registerQueryRoutes(clientCtx, r)
registerTxRoutes(clientCtx, r, queryRoute)
registerTxRoutes(clientCtx, r)
}
// TODO add proto compatible Handler after x/gov migration

View File

@ -80,7 +80,7 @@ func newWithdrawDelegatorRewardsHandlerFn(clientCtx client.Context) http.Handler
return
}
msgs, err := common.WithdrawAllDelegatorRewards(clientCtx, types.QuerierRoute, delAddr)
msgs, err := common.WithdrawAllDelegatorRewards(clientCtx, delAddr)
if rest.CheckInternalServerError(w, err) {
return
}
@ -207,11 +207,11 @@ func newFundCommunityPoolHandlerFn(clientCtx client.Context) http.HandlerFunc {
//
// TODO: Remove once client-side Protobuf migration has been completed.
// ---------------------------------------------------------------------------
func registerTxRoutes(clientCtx client.Context, r *mux.Router, queryRoute string) {
func registerTxRoutes(clientCtx client.Context, r *mux.Router) {
// Withdraw all delegator rewards
r.HandleFunc(
"/distribution/delegators/{delegatorAddr}/rewards",
withdrawDelegatorRewardsHandlerFn(clientCtx, queryRoute),
withdrawDelegatorRewardsHandlerFn(clientCtx),
).Methods("POST")
// Withdraw delegation rewards
@ -241,7 +241,7 @@ func registerTxRoutes(clientCtx client.Context, r *mux.Router, queryRoute string
}
// Withdraw delegator rewards
func withdrawDelegatorRewardsHandlerFn(clientCtx client.Context, queryRoute string) http.HandlerFunc {
func withdrawDelegatorRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req withdrawRewardsReq
if !rest.ReadRESTReq(w, r, clientCtx.Codec, &req) {
@ -259,7 +259,7 @@ func withdrawDelegatorRewardsHandlerFn(clientCtx client.Context, queryRoute stri
return
}
msgs, err := common.WithdrawAllDelegatorRewards(clientCtx, queryRoute, delAddr)
msgs, err := common.WithdrawAllDelegatorRewards(clientCtx, delAddr)
if rest.CheckInternalServerError(w, err) {
return
}

View File

@ -1,103 +1,33 @@
package testutil
import (
"bytes"
"context"
"fmt"
"github.com/stretchr/testify/require"
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/cosmos/cosmos-sdk/tests/cli"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
distrcli "github.com/cosmos/cosmos-sdk/x/distribution/client/cli"
)
// TxWithdrawRewards raises a txn to withdraw rewards
func TxWithdrawRewards(f *cli.Fixtures, valAddr sdk.ValAddress, from string, flags ...string) bool {
cmd := fmt.Sprintf("%s tx distribution withdraw-rewards %s %v --keyring-backend=test --from=%s", f.SimdBinary, valAddr, f.Flags(), from)
return cli.ExecuteWrite(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass)
}
// TxSetWithdrawAddress helps to set the withdraw address for rewards associated with a delegator address
func TxSetWithdrawAddress(f *cli.Fixtures, from, withDrawAddr string, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx distribution set-withdraw-addr %s --from %s %v --keyring-backend=test", f.SimdBinary, withDrawAddr, from, f.Flags())
return cli.ExecuteWriteRetStdStreams(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass)
}
// TxWithdrawAllRewards raises a txn to withdraw all rewards of a delegator address
func TxWithdrawAllRewards(f *cli.Fixtures, from string, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx distribution withdraw-all-rewards %v --keyring-backend=test --from=%s", f.SimdBinary, f.Flags(), from)
return cli.ExecuteWriteRetStdStreams(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass)
}
// TxFundCommunityPool Funds the community pool with the specified amount
func TxFundCommunityPool(f *cli.Fixtures, from string, amount sdk.Coin, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx distribution fund-community-pool %v %v --keyring-backend=test --from=%s", f.SimdBinary, amount, f.Flags(), from)
return cli.ExecuteWriteRetStdStreams(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass)
}
// QueryRewards returns the rewards of a delegator
func QueryRewards(f *cli.Fixtures, delAddr sdk.AccAddress, flags ...string) types.QueryDelegatorTotalRewardsResponse {
cmd := fmt.Sprintf("%s query distribution rewards %s %s", f.SimdBinary, delAddr, f.Flags())
res, errStr := tests.ExecuteT(f.T, cmd, "")
require.Empty(f.T, errStr)
var rewards types.QueryDelegatorTotalRewardsResponse
require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(res), &rewards))
return rewards
}
// QueryValidatorOutstandingRewards distribution outstanding (un-withdrawn) rewards
func QueryValidatorOutstandingRewards(f *cli.Fixtures, valAddr string) types.ValidatorOutstandingRewards {
cmd := fmt.Sprintf("%s query distribution validator-outstanding-rewards %s %v", f.SimdBinary, valAddr, f.Flags())
res, errStr := tests.ExecuteT(f.T, cmd, "")
require.Empty(f.T, errStr)
var outstandingRewards types.ValidatorOutstandingRewards
require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(res), &outstandingRewards))
return outstandingRewards
}
// QueryParameters is simcli query distribution parameters
func QueryParameters(f *cli.Fixtures, flags ...string) types.Params {
cmd := fmt.Sprintf("%s query distribution params %v", f.SimdBinary, f.Flags())
out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "")
require.Empty(f.T, errStr)
var params types.Params
require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &params))
return params
}
// QueryCommission returns validator commission rewards from delegators to that validator.
func QueryCommission(f *cli.Fixtures, valAddr string, flags ...string) types.ValidatorAccumulatedCommission {
cmd := fmt.Sprintf("%s query distribution commission %s %v", f.SimdBinary, valAddr, f.Flags())
out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "")
require.Empty(f.T, errStr)
var commission types.ValidatorAccumulatedCommission
require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &commission))
return commission
}
// QuerySlashes returns all slashes of a validator for a given block range.
func QuerySlashes(f *cli.Fixtures, valAddr string, flags ...string) []types.ValidatorSlashEvent {
cmd := fmt.Sprintf("%s query distribution slashes %s 0 5 %v ", f.SimdBinary, valAddr, f.Flags())
out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "")
require.Empty(f.T, errStr)
var slashes []types.ValidatorSlashEvent
require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &slashes))
return slashes
}
// QueryCommunityPool returns the amount of coins in the community pool
func QueryCommunityPool(f *cli.Fixtures, flags ...string) sdk.DecCoins {
cmd := fmt.Sprintf("%s query distribution community-pool %v ", f.SimdBinary, f.Flags())
out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "")
require.Empty(f.T, errStr)
var amount sdk.DecCoins
require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &amount))
return amount
func MsgWithdrawDelegatorRewardExec(clientCtx client.Context, valAddr fmt.Stringer, extraArgs ...string) ([]byte, error) {
buf := new(bytes.Buffer)
clientCtx = clientCtx.WithOutput(buf)
ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
args := []string{valAddr.String()}
args = append(args, extraArgs...)
cmd := flags.PostCommands(distrcli.NewWithdrawRewardsCmd())[0]
cmd.SetErr(buf)
cmd.SetOut(buf)
cmd.SetArgs(args)
if err := cmd.ExecuteContext(ctx); err != nil {
return nil, err
}
return buf.Bytes(), nil
}

View File

@ -69,13 +69,13 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx sdkclient.Context, rtr *mux.R
}
// GetTxCmd returns the root tx command for the distribution module.
func (AppModuleBasic) GetTxCmd(clientCtx sdkclient.Context) *cobra.Command {
return cli.NewTxCmd(clientCtx)
func (AppModuleBasic) GetTxCmd(_ sdkclient.Context) *cobra.Command {
return cli.NewTxCmd()
}
// GetQueryCmd returns the root query command for the distribution module.
func (AppModuleBasic) GetQueryCmd(clientCtx sdkclient.Context) *cobra.Command {
return cli.GetQueryCmd(types.StoreKey, clientCtx.Codec)
func (AppModuleBasic) GetQueryCmd(_ sdkclient.Context) *cobra.Command {
return cli.GetQueryCmd()
}
// RegisterInterfaceTypes implements InterfaceModule

View File

@ -11,7 +11,7 @@ import (
type RESTHandlerFn func(client.Context) rest.ProposalRESTHandler
// function to create the cli handler
type CLIHandlerFn func(client.Context) *cobra.Command
type CLIHandlerFn func() *cobra.Command
// The combined type for a proposal handler for both cli and rest
type ProposalHandler struct {

View File

@ -88,7 +88,7 @@ func (a AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Ro
func (a AppModuleBasic) GetTxCmd(clientCtx client.Context) *cobra.Command {
proposalCLIHandlers := make([]*cobra.Command, 0, len(a.proposalHandlers))
for _, proposalHandler := range a.proposalHandlers {
proposalCLIHandlers = append(proposalCLIHandlers, proposalHandler.CLIHandler(clientCtx))
proposalCLIHandlers = append(proposalCLIHandlers, proposalHandler.CLIHandler())
}
return cli.NewTxCmd(clientCtx, proposalCLIHandlers)

View File

@ -17,8 +17,8 @@ import (
// NewSubmitParamChangeProposalTxCmd returns a CLI command handler for creating
// a parameter change proposal governance transaction.
func NewSubmitParamChangeProposalTxCmd(clientCtx client.Context) *cobra.Command {
cmd := &cobra.Command{
func NewSubmitParamChangeProposalTxCmd() *cobra.Command {
return &cobra.Command{
Use: "param-change [proposal-file]",
Args: cobra.ExactArgs(1),
Short: "Submit a parameter change proposal",
@ -57,7 +57,11 @@ Where proposal.json contains:
),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := clientCtx.InitWithInput(cmd.InOrStdin())
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
proposal, err := paramscutils.ParseParamChangeProposalJSON(clientCtx.JSONMarshaler, args[0])
if err != nil {
@ -82,9 +86,7 @@ Where proposal.json contains:
return err
}
return tx.GenerateOrBroadcastTx(clientCtx, msg)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
return cmd
}

View File

@ -36,7 +36,7 @@ func GetTxCmd() *cobra.Command {
}
// NewCmdSubmitUpgradeProposal implements a command handler for submitting a software upgrade proposal transaction.
func NewCmdSubmitUpgradeProposal(clientCtx client.Context) *cobra.Command {
func NewCmdSubmitUpgradeProposal() *cobra.Command {
cmd := &cobra.Command{
Use: "software-upgrade [name] (--upgrade-height [height] | --upgrade-time [time]) (--upgrade-info [info]) [flags]",
Args: cobra.ExactArgs(1),
@ -45,13 +45,18 @@ func NewCmdSubmitUpgradeProposal(clientCtx client.Context) *cobra.Command {
"Please specify a unique name and height OR time for the upgrade to take effect.\n" +
"You may include info to reference a binary download link, in a format compatible with: https://github.com/regen-network/cosmosd",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
name := args[0]
content, err := parseArgsToContent(cmd, name)
if err != nil {
return err
}
clientCtx := clientCtx.InitWithInput(cmd.InOrStdin())
from := clientCtx.GetFromAddress()
depositStr, err := cmd.Flags().GetString(cli.FlagDeposit)
@ -72,7 +77,7 @@ func NewCmdSubmitUpgradeProposal(clientCtx client.Context) *cobra.Command {
return err
}
return tx.GenerateOrBroadcastTx(clientCtx, msg)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}