diff --git a/x/staking/client/cli/cli_test.go b/x/staking/client/cli/cli_test.go index 24ee0026ce..0032f49837 100644 --- a/x/staking/client/cli/cli_test.go +++ b/x/staking/client/cli/cli_test.go @@ -26,6 +26,14 @@ func TestCLICreateValidator(t *testing.T) { barAddr := f.KeyAddress(cli.KeyBar) barVal := sdk.ValAddress(barAddr) + // Check for the params + params := testutil.QueryStakingParameters(f) + require.NotEmpty(t, params) + + // Query for the staking pool + pool := testutil.QueryStakingPool(f) + require.NotEmpty(t, pool) + consPubKey := sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, ed25519.GenPrivKey().PubKey()) sendTokens := sdk.TokensFromConsensusPower(10) @@ -34,15 +42,15 @@ func TestCLICreateValidator(t *testing.T) { require.Equal(t, sendTokens, bankclienttestutil.QueryBalances(f, barAddr).AmountOf(cli.Denom)) - //Generate a create validator transaction and ensure correctness + // Generate a create validator transaction and ensure correctness success, stdout, stderr := testutil.TxStakingCreateValidator(f, barAddr.String(), consPubKey, sdk.NewInt64Coin(cli.Denom, 2), "--generate-only") - require.True(f.T, success) - require.Empty(f.T, stderr) + require.True(t, success) + require.Empty(t, stderr) - msg := cli.UnmarshalStdTx(f.T, f.Cdc, stdout) + msg := cli.UnmarshalStdTx(t, f.Cdc, stdout) require.NotZero(t, msg.Fee.Gas) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 0, len(msg.GetSignatures())) + require.Len(t, msg.Msgs, 1) + require.Len(t, msg.GetSignatures(), 0) // Test --dry-run newValTokens := sdk.TokensFromConsensusPower(2) @@ -66,7 +74,38 @@ func TestCLICreateValidator(t *testing.T) { require.Len(t, validatorDelegations, 1) require.NotZero(t, validatorDelegations[0].Shares) + // Edit validator + // params to be changed in edit validator (NOTE: a validator can only change its commission once per day) + newMoniker := "test-moniker" + newWebsite := "https://cosmos.network" + newIdentity := "6A0D65E29A4CBC8D" + newDetails := "To-infinity-and-beyond!" + + // Test --generate-only" + success, stdout, stderr = testutil.TxStakingEditValidator(f, barAddr.String(), newMoniker, newWebsite, newIdentity, newDetails, "--generate-only") + require.True(t, success) + 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, _, _ = testutil.TxStakingEditValidator(f, cli.KeyBar, newMoniker, newWebsite, newIdentity, newDetails, "-y") + require.True(t, success) + tests.WaitForNextNBlocksTM(1, f.Port) + + udpatedValidator := testutil.QueryStakingValidator(f, barVal) + require.Equal(t, udpatedValidator.Description.Moniker, newMoniker) + require.Equal(t, udpatedValidator.Description.Identity, newIdentity) + require.Equal(t, udpatedValidator.Description.Website, newWebsite) + require.Equal(t, udpatedValidator.Description.Details, newDetails) + // unbond a single share + validators := testutil.QueryStakingValidators(f) + require.Len(t, validators, 2) + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(1)) success = testutil.TxStakingUnbond(f, cli.KeyBar, unbondAmt.String(), barVal, "-y") require.True(t, success) @@ -77,11 +116,78 @@ func TestCLICreateValidator(t *testing.T) { validator = testutil.QueryStakingValidator(f, barVal) require.Equal(t, remainingTokens, validator.Tokens) + // Query for historical info + require.NotEmpty(t, testutil.QueryStakingHistoricalInfo(f, 1)) + // Get unbonding delegations from the validator validatorUbds := testutil.QueryStakingUnbondingDelegationsFrom(f, barVal) require.Len(t, validatorUbds, 1) require.Len(t, validatorUbds[0].Entries, 1) require.Equal(t, remainingTokens.String(), validatorUbds[0].Entries[0].Balance.String()) + // Query staking unbonding delegation + ubd := testutil.QueryStakingUnbondingDelegation(f, barAddr.String(), barVal.String()) + require.NotEmpty(t, ubd) + + // Query staking unbonding delegations + ubds := testutil.QueryStakingUnbondingDelegations(f, barAddr.String()) + require.Len(t, ubds, 1) + + fooAddr := f.KeyAddress(cli.KeyFoo) + + delegateTokens := sdk.TokensFromConsensusPower(2) + delegateAmount := sdk.NewCoin(cli.Denom, delegateTokens) + + // Delegate txn + // Generate a create validator transaction and ensure correctness + success, stdout, stderr = testutil.TxStakingDelegate(f, fooAddr.String(), barVal.String(), delegateAmount, "--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) + + // Delegate + success, _, err := testutil.TxStakingDelegate(f, cli.KeyFoo, barVal.String(), delegateAmount, "-y") + tests.WaitForNextNBlocksTM(1, f.Port) + require.Empty(t, err) + require.True(t, success) + + // Query the delegation from foo address to barval + delegation := testutil.QueryStakingDelegation(f, fooAddr.String(), barVal) + require.NotZero(t, delegation.Shares) + + // Query the delegations from foo address to barval + delegations := testutil.QueryStakingDelegations(f, barAddr.String()) + require.Len(t, delegations, 1) + + fooVal := sdk.ValAddress(fooAddr) + + // Redelegate + success, stdout, stderr = testutil.TxStakingRedelegate(f, fooAddr.String(), barVal.String(), fooVal.String(), delegateAmount, "--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, _, err = testutil.TxStakingRedelegate(f, cli.KeyFoo, barVal.String(), fooVal.String(), delegateAmount, "-y") + tests.WaitForNextNBlocksTM(1, f.Port) + require.Empty(t, err) + require.True(t, success) + + redelegation := testutil.QueryStakingRedelegation(f, fooAddr.String(), barVal.String(), fooVal.String()) + require.Len(t, redelegation, 1) + + redelegations := testutil.QueryStakingRedelegations(f, fooAddr.String()) + require.Len(t, redelegations, 1) + + redelegationsFrom := testutil.QueryStakingRedelegationsFrom(f, barVal.String()) + require.Len(t, redelegationsFrom, 1) + f.Cleanup() } diff --git a/x/staking/client/cli/query.go b/x/staking/client/cli/query.go index a93ee34ae5..9d61801aae 100644 --- a/x/staking/client/cli/query.go +++ b/x/staking/client/cli/query.go @@ -399,8 +399,8 @@ $ %s query staking unbonding-delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld7 return err } - ubd, err := types.UnmarshalUBD(types.ModuleCdc, res) - if err != nil { + var ubd types.UnbondingDelegation + if err = cdc.UnmarshalJSON(res, &ubd); err != nil { return err } @@ -419,7 +419,7 @@ func GetCmdQueryUnbondingDelegations(queryRoute string, cdc *codec.Codec) *cobra fmt.Sprintf(`Query unbonding delegations for an individual delegator. Example: -$ %s query staking unbonding-delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p +$ %s query staking unbonding-delegations cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p `, version.ClientName, ), diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index efafb272b6..b685ea943b 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -136,6 +136,10 @@ func NewEditValidatorCmd(clientCtx client.Context) *cobra.Command { }, } + cmd.Flags().AddFlagSet(fsDescriptionEdit) + cmd.Flags().AddFlagSet(fsCommissionUpdate) + cmd.Flags().AddFlagSet(FsMinSelfDelegation) + return cmd } @@ -175,9 +179,6 @@ $ %s tx staking delegate cosmosvaloper1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 10 return tx.GenerateOrBroadcastTx(clientCtx, msg) }, } - cmd.Flags().AddFlagSet(fsDescriptionEdit) - cmd.Flags().AddFlagSet(fsCommissionUpdate) - cmd.Flags().AddFlagSet(FsMinSelfDelegation) return cmd } diff --git a/x/staking/client/testutil/helpers.go b/x/staking/client/testutil/helpers.go index 7a0ddffb8e..ace7c49bb9 100644 --- a/x/staking/client/testutil/helpers.go +++ b/x/staking/client/testutil/helpers.go @@ -9,7 +9,7 @@ import ( "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/staking/types" + staking "github.com/cosmos/cosmos-sdk/x/staking/types" ) // TxStakingCreateValidator is simcli tx staking create-validator @@ -23,6 +23,15 @@ func TxStakingCreateValidator(f *cli.Fixtures, from, consPubKey string, amount s return cli.ExecuteWriteRetStdStreams(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass) } +// TxStakingEditValidator is simcli tx staking update validator info +func TxStakingEditValidator(f *cli.Fixtures, from, moniker, website, identity, details string, flags ...string) (bool, string, string) { + cmd := fmt.Sprintf("%s tx staking edit-validator %v --keyring-backend=test --from=%s", f.SimcliBinary, f.Flags(), from) + cmd += fmt.Sprintf(" --moniker=%v --website=%s", moniker, website) + cmd += fmt.Sprintf(" --identity=%s --details=%s", identity, details) + + return cli.ExecuteWriteRetStdStreams(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass) +} + // TxStakingUnbond is simcli tx staking unbond func TxStakingUnbond(f *cli.Fixtures, from, shares string, validator sdk.ValAddress, flags ...string) bool { cmd := fmt.Sprintf("%s tx staking unbond --keyring-backend=test %s %v --from=%s %v", @@ -30,67 +39,182 @@ func TxStakingUnbond(f *cli.Fixtures, from, shares string, validator sdk.ValAddr return cli.ExecuteWrite(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass) } +// TxStakingDelegate is simcli tx staking delegate +func TxStakingDelegate(f *cli.Fixtures, from, valOperAddr string, amount sdk.Coin, flags ...string) (bool, string, string) { + cmd := fmt.Sprintf("%s tx staking delegate %s %v --keyring-backend=test --from=%s %v", f.SimcliBinary, valOperAddr, amount, from, f.Flags()) + return cli.ExecuteWriteRetStdStreams(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass) +} + +// TxStakingRedelegate is simcli tx staking redelegate +func TxStakingRedelegate(f *cli.Fixtures, from, srcVal, dstVal string, amount sdk.Coin, flags ...string) (bool, string, string) { + cmd := fmt.Sprintf("%s tx staking redelegate %s %s %v --keyring-backend=test --from=%s %v", f.SimcliBinary, srcVal, dstVal, amount, from, f.Flags()) + return cli.ExecuteWriteRetStdStreams(f.T, cli.AddFlags(cmd, flags), clientkeys.DefaultKeyPass) +} + // QueryStakingValidator is simcli query staking validator -func QueryStakingValidator(f *cli.Fixtures, valAddr sdk.ValAddress, flags ...string) types.Validator { +func QueryStakingValidator(f *cli.Fixtures, valAddr sdk.ValAddress, flags ...string) staking.Validator { cmd := fmt.Sprintf("%s query staking validator %s %v", f.SimcliBinary, valAddr, f.Flags()) - out, _ := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) - var validator types.Validator - - err := f.Cdc.UnmarshalJSON([]byte(out), &validator) - require.NoError(f.T, err, "out %v\n, err %v", out, err) + var validator staking.Validator + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &validator)) return validator } +// QueryStakingValidators is simcli query staking validators +func QueryStakingValidators(f *cli.Fixtures, flags ...string) []staking.Validator { + cmd := fmt.Sprintf("%s query staking validators %v", f.SimcliBinary, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var validators []staking.Validator + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &validators)) + + return validators +} + // QueryStakingUnbondingDelegationsFrom is simcli query staking unbonding-delegations-from -func QueryStakingUnbondingDelegationsFrom(f *cli.Fixtures, valAddr sdk.ValAddress, flags ...string) []types.UnbondingDelegation { +func QueryStakingUnbondingDelegationsFrom(f *cli.Fixtures, valAddr sdk.ValAddress, flags ...string) []staking.UnbondingDelegation { cmd := fmt.Sprintf("%s query staking unbonding-delegations-from %s %v", f.SimcliBinary, valAddr, f.Flags()) - out, _ := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) - var ubds []types.UnbondingDelegation - - err := f.Cdc.UnmarshalJSON([]byte(out), &ubds) - require.NoError(f.T, err, "out %v\n, err %v", out, err) + var ubds []staking.UnbondingDelegation + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &ubds)) return ubds } // QueryStakingDelegationsTo is simcli query staking delegations-to -func QueryStakingDelegationsTo(f *cli.Fixtures, valAddr sdk.ValAddress, flags ...string) []types.Delegation { +func QueryStakingDelegationsTo(f *cli.Fixtures, valAddr sdk.ValAddress, flags ...string) []staking.Delegation { cmd := fmt.Sprintf("%s query staking delegations-to %s %v", f.SimcliBinary, valAddr, f.Flags()) - out, _ := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) - var delegations []types.Delegation - - err := f.Cdc.UnmarshalJSON([]byte(out), &delegations) - require.NoError(f.T, err, "out %v\n, err %v", out, err) + var delegations []staking.Delegation + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &delegations)) return delegations } // QueryStakingPool is simcli query staking pool -func QueryStakingPool(f *cli.Fixtures, flags ...string) types.Pool { +func QueryStakingPool(f *cli.Fixtures, flags ...string) staking.Pool { cmd := fmt.Sprintf("%s query staking pool %v", f.SimcliBinary, f.Flags()) - out, _ := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) - var pool types.Pool - - err := f.Cdc.UnmarshalJSON([]byte(out), &pool) - require.NoError(f.T, err, "out %v\n, err %v", out, err) + var pool staking.Pool + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &pool)) return pool } // QueryStakingParameters is simcli query staking parameters -func QueryStakingParameters(f *cli.Fixtures, flags ...string) types.Params { +func QueryStakingParameters(f *cli.Fixtures, flags ...string) staking.Params { cmd := fmt.Sprintf("%s query staking params %v", f.SimcliBinary, f.Flags()) - out, _ := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) - var params types.Params - - err := f.Cdc.UnmarshalJSON([]byte(out), ¶ms) - require.NoError(f.T, err, "out %v\n, err %v", out, err) + var params staking.Params + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), ¶ms)) return params } + +// QueryStakingDelegation is simcli query staking delegation +func QueryStakingDelegation(f *cli.Fixtures, from string, valAddr sdk.ValAddress, flags ...string) staking.Delegation { + cmd := fmt.Sprintf("%s query staking delegation %s %s %v", f.SimcliBinary, from, valAddr, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var delegation staking.Delegation + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &delegation)) + + return delegation +} + +// QueryStakingDelegations is simcli query staking delegations +func QueryStakingDelegations(f *cli.Fixtures, from string, flags ...string) []staking.Delegation { + cmd := fmt.Sprintf("%s query staking delegations %s %v", f.SimcliBinary, from, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var delegations []staking.Delegation + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &delegations)) + + return delegations +} + +// QueryStakingRedelegation is simcli query staking redelegation +func QueryStakingRedelegation(f *cli.Fixtures, delAdrr, srcVal, dstVal string, flags ...string) []staking.RedelegationResponse { + cmd := fmt.Sprintf("%s query staking redelegation %v %v %v %v", f.SimcliBinary, delAdrr, srcVal, dstVal, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var redelegations []staking.RedelegationResponse + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &redelegations)) + + return redelegations +} + +// QueryStakingRedelegations is simcli query staking redelegation +func QueryStakingRedelegations(f *cli.Fixtures, delAdrr string, flags ...string) []staking.RedelegationResponse { + cmd := fmt.Sprintf("%s query staking redelegations %v %v", f.SimcliBinary, delAdrr, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var redelegations []staking.RedelegationResponse + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &redelegations)) + + return redelegations +} + +// QueryStakingRedelegationsFrom is simcli query staking redelegations-from +func QueryStakingRedelegationsFrom(f *cli.Fixtures, valAddr string, flags ...string) []staking.RedelegationResponse { + cmd := fmt.Sprintf("%s query staking redelegations-from %v %v", f.SimcliBinary, valAddr, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var redelegations []staking.RedelegationResponse + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &redelegations)) + + return redelegations +} + +// QueryStakingUnbondingDelegation is simcli query staking unbonding-delegation +func QueryStakingUnbondingDelegation(f *cli.Fixtures, delAdrr, valAddr string, flags ...string) staking.UnbondingDelegation { + cmd := fmt.Sprintf("%s query staking unbonding-delegation %v %v %v", f.SimcliBinary, delAdrr, valAddr, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var ubd staking.UnbondingDelegation + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &ubd)) + + return ubd +} + +// QueryStakingUnbondingDelegations is simcli query staking unbonding-delegations +func QueryStakingUnbondingDelegations(f *cli.Fixtures, delAdrr string, flags ...string) []staking.UnbondingDelegation { + cmd := fmt.Sprintf("%s query staking unbonding-delegations %v %v", f.SimcliBinary, delAdrr, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var ubds []staking.UnbondingDelegation + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &ubds)) + + return ubds +} + +// QueryStakingHistoricalInfo is simcli query staking historical-info +func QueryStakingHistoricalInfo(f *cli.Fixtures, height uint, flags ...string) staking.HistoricalInfo { + cmd := fmt.Sprintf("%s query staking historical-info %d %v", f.SimcliBinary, height, f.Flags()) + out, errStr := tests.ExecuteT(f.T, cli.AddFlags(cmd, flags), "") + require.Empty(f.T, errStr) + + var historicalInfo staking.HistoricalInfo + require.NoError(f.T, f.Cdc.UnmarshalJSON([]byte(out), &historicalInfo)) + + return historicalInfo +}