Rename stake/ to staking/ (#3280)

This commit is contained in:
frog power 4000
2019-01-11 12:08:01 -08:00
committed by Jack Zampolin
parent df567616a9
commit 78a21353da
132 changed files with 1024 additions and 1021 deletions
+69
View File
@@ -0,0 +1,69 @@
package cli
import (
flag "github.com/spf13/pflag"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// nolint
const (
FlagAddressDelegator = "address-delegator"
FlagAddressValidator = "validator"
FlagAddressValidatorSrc = "addr-validator-source"
FlagAddressValidatorDst = "addr-validator-dest"
FlagPubKey = "pubkey"
FlagAmount = "amount"
FlagSharesAmount = "shares-amount"
FlagSharesFraction = "shares-fraction"
FlagMoniker = "moniker"
FlagIdentity = "identity"
FlagWebsite = "website"
FlagDetails = "details"
FlagCommissionRate = "commission-rate"
FlagCommissionMaxRate = "commission-max-rate"
FlagCommissionMaxChangeRate = "commission-max-change-rate"
FlagGenesisFormat = "genesis-format"
FlagNodeID = "node-id"
FlagIP = "ip"
)
// common flagsets to add to various functions
var (
FsPk = flag.NewFlagSet("", flag.ContinueOnError)
FsAmount = flag.NewFlagSet("", flag.ContinueOnError)
fsShares = flag.NewFlagSet("", flag.ContinueOnError)
fsDescriptionCreate = flag.NewFlagSet("", flag.ContinueOnError)
FsCommissionCreate = flag.NewFlagSet("", flag.ContinueOnError)
fsCommissionUpdate = flag.NewFlagSet("", flag.ContinueOnError)
fsDescriptionEdit = flag.NewFlagSet("", flag.ContinueOnError)
fsValidator = flag.NewFlagSet("", flag.ContinueOnError)
fsDelegator = flag.NewFlagSet("", flag.ContinueOnError)
fsRedelegation = flag.NewFlagSet("", flag.ContinueOnError)
)
func init() {
FsPk.String(FlagPubKey, "", "The Bech32 encoded PubKey of the validator")
FsAmount.String(FlagAmount, "", "Amount of coins to bond")
fsShares.String(FlagSharesAmount, "", "Amount of source-shares to either unbond or redelegate as a positive integer or decimal")
fsShares.String(FlagSharesFraction, "", "Fraction of source-shares to either unbond or redelegate as a positive integer or decimal >0 and <=1")
fsDescriptionCreate.String(FlagMoniker, "", "The validator's name")
fsDescriptionCreate.String(FlagIdentity, "", "The optional identity signature (ex. UPort or Keybase)")
fsDescriptionCreate.String(FlagWebsite, "", "The validator's (optional) website")
fsDescriptionCreate.String(FlagDetails, "", "The validator's (optional) details")
fsCommissionUpdate.String(FlagCommissionRate, "", "The new commission rate percentage")
FsCommissionCreate.String(FlagCommissionRate, "", "The initial commission rate percentage")
FsCommissionCreate.String(FlagCommissionMaxRate, "", "The maximum commission rate percentage")
FsCommissionCreate.String(FlagCommissionMaxChangeRate, "", "The maximum commission change rate percentage (per day)")
fsDescriptionEdit.String(FlagMoniker, types.DoNotModifyDesc, "The validator's name")
fsDescriptionEdit.String(FlagIdentity, types.DoNotModifyDesc, "The (optional) identity signature (ex. UPort or Keybase)")
fsDescriptionEdit.String(FlagWebsite, types.DoNotModifyDesc, "The validator's (optional) website")
fsDescriptionEdit.String(FlagDetails, types.DoNotModifyDesc, "The validator's (optional) details")
fsValidator.String(FlagAddressValidator, "", "The Bech32 address of the validator")
fsDelegator.String(FlagAddressDelegator, "", "The Bech32 address of the delegator")
fsRedelegation.String(FlagAddressValidatorSrc, "", "The Bech32 address of the source validator")
fsRedelegation.String(FlagAddressValidatorDst, "", "The Bech32 address of the destination validator")
}
+603
View File
@@ -0,0 +1,603 @@
package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// GetCmdQueryValidator implements the validator query command.
func GetCmdQueryValidator(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "validator [operator-addr]",
Short: "Query a validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
addr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetValidatorKey(addr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
} else if len(res) == 0 {
return fmt.Errorf("No validator found with address %s", args[0])
}
validator := types.MustUnmarshalValidator(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
human, err := validator.HumanReadableString()
if err != nil {
return err
}
fmt.Println(human)
case "json":
// parse out the validator
output, err := codec.MarshalJSONIndent(cdc, validator)
if err != nil {
return err
}
fmt.Println(string(output))
}
// TODO: output with proofs / machine parseable etc.
return nil
},
}
return cmd
}
// GetCmdQueryValidators implements the query all validators command.
func GetCmdQueryValidators(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "validators",
Short: "Query for all validators",
RunE: func(cmd *cobra.Command, args []string) error {
key := staking.ValidatorsKey
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
if err != nil {
return err
}
// parse out the validators
var validators []staking.Validator
for _, kv := range resKVs {
validator := types.MustUnmarshalValidator(cdc, kv.Value)
validators = append(validators, validator)
}
switch viper.Get(cli.OutputFlag) {
case "text":
for _, validator := range validators {
resp, err := validator.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
}
case "json":
output, err := codec.MarshalJSONIndent(cdc, validators)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
// TODO: output with proofs / machine parseable etc.
return nil
},
}
return cmd
}
// GetCmdQueryValidatorUnbondingDelegations implements the query all unbonding delegatations from a validator command.
func GetCmdQueryValidatorUnbondingDelegations(storeKey string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unbonding-delegations-from [operator-addr]",
Short: "Query all unbonding delegatations from a validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
valAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
params := staking.NewQueryValidatorParams(valAddr)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
res, err := cliCtx.QueryWithData(
fmt.Sprintf("custom/%s/validatorUnbondingDelegations", storeKey),
bz)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
},
}
return cmd
}
// GetCmdQueryValidatorRedelegations implements the query all redelegatations from a validator command.
func GetCmdQueryValidatorRedelegations(storeKey string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "redelegations-from [operator-addr]",
Short: "Query all outgoing redelegatations from a validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
valAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
params := staking.NewQueryValidatorParams(valAddr)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
res, err := cliCtx.QueryWithData(
fmt.Sprintf("custom/%s/validatorRedelegations", storeKey),
bz)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
},
}
return cmd
}
// GetCmdQueryDelegation the query delegation command.
func GetCmdQueryDelegation(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "delegation",
Short: "Query a delegation based on address and validator address",
RunE: func(cmd *cobra.Command, args []string) error {
valAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidator))
if err != nil {
return err
}
delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator))
if err != nil {
return err
}
key := staking.GetDelegationKey(delAddr, valAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
}
// parse out the delegation
delegation, err := types.UnmarshalDelegation(cdc, res)
if err != nil {
return err
}
switch viper.Get(cli.OutputFlag) {
case "text":
resp, err := delegation.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
case "json":
output, err := codec.MarshalJSONIndent(cdc, delegation)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
return nil
},
}
cmd.Flags().AddFlagSet(fsValidator)
cmd.Flags().AddFlagSet(fsDelegator)
return cmd
}
// GetCmdQueryDelegations implements the command to query all the delegations
// made from one delegator.
func GetCmdQueryDelegations(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "delegations [delegator-addr]",
Short: "Query all delegations made from one delegator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
delegatorAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetDelegationsKey(delegatorAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
if err != nil {
return err
}
// parse out the validators
var delegations []staking.Delegation
for _, kv := range resKVs {
delegation := types.MustUnmarshalDelegation(cdc, kv.Value)
delegations = append(delegations, delegation)
}
output, err := codec.MarshalJSONIndent(cdc, delegations)
if err != nil {
return err
}
fmt.Println(string(output))
// TODO: output with proofs / machine parseable etc.
return nil
},
}
return cmd
}
// GetCmdQueryValidatorDelegations implements the command to query all the
// delegations to a specific validator.
func GetCmdQueryValidatorDelegations(storeKey string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "delegations-to [validator-addr]",
Short: "Query all delegations made to one validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
validatorAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
params := staking.NewQueryValidatorParams(validatorAddr)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/validatorDelegations", storeKey), bz)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
},
}
return cmd
}
// GetCmdQueryUnbondingDelegation implements the command to query a single
// unbonding-delegation record.
func GetCmdQueryUnbondingDelegation(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unbonding-delegation",
Short: "Query an unbonding-delegation record based on delegator and validator address",
RunE: func(cmd *cobra.Command, args []string) error {
valAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidator))
if err != nil {
return err
}
delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator))
if err != nil {
return err
}
key := staking.GetUBDKey(delAddr, valAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
}
// parse out the unbonding delegation
ubd := types.MustUnmarshalUBD(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
resp, err := ubd.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
case "json":
output, err := codec.MarshalJSONIndent(cdc, ubd)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
return nil
},
}
cmd.Flags().AddFlagSet(fsValidator)
cmd.Flags().AddFlagSet(fsDelegator)
return cmd
}
// GetCmdQueryUnbondingDelegations implements the command to query all the
// unbonding-delegation records for a delegator.
func GetCmdQueryUnbondingDelegations(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unbonding-delegations [delegator-addr]",
Short: "Query all unbonding-delegations records for one delegator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
delegatorAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetUBDsKey(delegatorAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
if err != nil {
return err
}
// parse out the unbonding delegations
var ubds []staking.UnbondingDelegation
for _, kv := range resKVs {
ubd := types.MustUnmarshalUBD(cdc, kv.Value)
ubds = append(ubds, ubd)
}
output, err := codec.MarshalJSONIndent(cdc, ubds)
if err != nil {
return err
}
fmt.Println(string(output))
// TODO: output with proofs / machine parseable etc.
return nil
},
}
return cmd
}
// GetCmdQueryRedelegation implements the command to query a single
// redelegation record.
func GetCmdQueryRedelegation(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "redelegation",
Short: "Query a redelegation record based on delegator and a source and destination validator address",
RunE: func(cmd *cobra.Command, args []string) error {
valSrcAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidatorSrc))
if err != nil {
return err
}
valDstAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidatorDst))
if err != nil {
return err
}
delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator))
if err != nil {
return err
}
key := staking.GetREDKey(delAddr, valSrcAddr, valDstAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
}
// parse out the unbonding delegation
red := types.MustUnmarshalRED(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
resp, err := red.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
case "json":
output, err := codec.MarshalJSONIndent(cdc, red)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
return nil
},
}
cmd.Flags().AddFlagSet(fsRedelegation)
cmd.Flags().AddFlagSet(fsDelegator)
return cmd
}
// GetCmdQueryRedelegations implements the command to query all the
// redelegation records for a delegator.
func GetCmdQueryRedelegations(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "redelegations [delegator-addr]",
Short: "Query all redelegations records for one delegator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
delegatorAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetREDsKey(delegatorAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
if err != nil {
return err
}
// parse out the validators
var reds []staking.Redelegation
for _, kv := range resKVs {
red := types.MustUnmarshalRED(cdc, kv.Value)
reds = append(reds, red)
}
output, err := codec.MarshalJSONIndent(cdc, reds)
if err != nil {
return err
}
fmt.Println(string(output))
// TODO: output with proofs / machine parseable etc.
return nil
},
}
return cmd
}
// GetCmdQueryPool implements the pool query command.
func GetCmdQueryPool(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "pool",
Short: "Query the current staking pool values",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
key := staking.PoolKey
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
}
pool := types.MustUnmarshalPool(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
human := pool.HumanReadableString()
fmt.Println(human)
case "json":
// parse out the pool
output, err := codec.MarshalJSONIndent(cdc, pool)
if err != nil {
return err
}
fmt.Println(string(output))
}
return nil
},
}
return cmd
}
// GetCmdQueryPool implements the params query command.
func GetCmdQueryParams(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "parameters",
Short: "Query the current staking parameters information",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
bz, err := cliCtx.QueryWithData("custom/staking/"+staking.QueryParameters, nil)
if err != nil {
return err
}
var params staking.Params
err = cdc.UnmarshalJSON(bz, &params)
if err != nil {
return err
}
switch viper.Get(cli.OutputFlag) {
case "text":
human := params.HumanReadableString()
fmt.Println(human)
case "json":
// parse out the params
output, err := codec.MarshalJSONIndent(cdc, params)
if err != nil {
return err
}
fmt.Println(string(output))
}
return nil
},
}
return cmd
}
+321
View File
@@ -0,0 +1,321 @@
package cli
import (
"fmt"
"os"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/utils"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// GetCmdCreateValidator implements the create validator command handler.
func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "create-validator",
Short: "create new validator initialized with a self-delegation to it",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
txBldr, msg, err := BuildCreateValidatorMsg(cliCtx, txBldr)
if err != nil {
return err
}
if viper.GetBool(FlagGenesisFormat) || cliCtx.GenerateOnly {
return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, true)
}
// build and sign the transaction, then broadcast to Tendermint
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
},
}
cmd.Flags().AddFlagSet(FsPk)
cmd.Flags().AddFlagSet(FsAmount)
cmd.Flags().AddFlagSet(fsDescriptionCreate)
cmd.Flags().AddFlagSet(FsCommissionCreate)
cmd.Flags().AddFlagSet(fsDelegator)
cmd.Flags().Bool(FlagGenesisFormat, false, "Export the transaction in gen-tx format; it implies --generate-only")
cmd.Flags().String(FlagIP, "", fmt.Sprintf("The node's public IP. It takes effect only when used in combination with --%s", FlagGenesisFormat))
cmd.Flags().String(FlagNodeID, "", "The node's ID")
cmd.MarkFlagRequired(client.FlagFrom)
cmd.MarkFlagRequired(FlagAmount)
cmd.MarkFlagRequired(FlagPubKey)
cmd.MarkFlagRequired(FlagMoniker)
return cmd
}
// GetCmdEditValidator implements the create edit validator command.
func GetCmdEditValidator(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "edit-validator",
Short: "edit an existing validator account",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
valAddr, err := cliCtx.GetFromAddress()
if err != nil {
return err
}
description := staking.Description{
Moniker: viper.GetString(FlagMoniker),
Identity: viper.GetString(FlagIdentity),
Website: viper.GetString(FlagWebsite),
Details: viper.GetString(FlagDetails),
}
var newRate *sdk.Dec
commissionRate := viper.GetString(FlagCommissionRate)
if commissionRate != "" {
rate, err := sdk.NewDecFromStr(commissionRate)
if err != nil {
return fmt.Errorf("invalid new commission rate: %v", err)
}
newRate = &rate
}
msg := staking.NewMsgEditValidator(sdk.ValAddress(valAddr), description, newRate)
if cliCtx.GenerateOnly {
return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false)
}
// build and sign the transaction, then broadcast to Tendermint
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
},
}
cmd.Flags().AddFlagSet(fsDescriptionEdit)
cmd.Flags().AddFlagSet(fsCommissionUpdate)
return cmd
}
// GetCmdDelegate implements the delegate command.
func GetCmdDelegate(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "delegate",
Short: "delegate liquid tokens to a validator",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
amount, err := sdk.ParseCoin(viper.GetString(FlagAmount))
if err != nil {
return err
}
delAddr, err := cliCtx.GetFromAddress()
if err != nil {
return err
}
valAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidator))
if err != nil {
return err
}
msg := staking.NewMsgDelegate(delAddr, valAddr, amount)
if cliCtx.GenerateOnly {
return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false)
}
// build and sign the transaction, then broadcast to Tendermint
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
},
}
cmd.Flags().AddFlagSet(FsAmount)
cmd.Flags().AddFlagSet(fsValidator)
return cmd
}
// GetCmdRedelegate the begin redelegation command.
func GetCmdRedelegate(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "redelegate",
Short: "redelegate illiquid tokens from one validator to another",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
var err error
delAddr, err := cliCtx.GetFromAddress()
if err != nil {
return err
}
valSrcAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidatorSrc))
if err != nil {
return err
}
valDstAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidatorDst))
if err != nil {
return err
}
// get the shares amount
sharesAmountStr := viper.GetString(FlagSharesAmount)
sharesFractionStr := viper.GetString(FlagSharesFraction)
sharesAmount, err := getShares(
storeName, cdc, sharesAmountStr, sharesFractionStr,
delAddr, valSrcAddr,
)
if err != nil {
return err
}
msg := staking.NewMsgBeginRedelegate(delAddr, valSrcAddr, valDstAddr, sharesAmount)
if cliCtx.GenerateOnly {
return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false)
}
// build and sign the transaction, then broadcast to Tendermint
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
},
}
cmd.Flags().AddFlagSet(fsShares)
cmd.Flags().AddFlagSet(fsRedelegation)
return cmd
}
// GetCmdUnbond implements the unbond validator command.
func GetCmdUnbond(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unbond",
Short: "unbond shares from a validator",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
delAddr, err := cliCtx.GetFromAddress()
if err != nil {
return err
}
valAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidator))
if err != nil {
return err
}
// get the shares amount
sharesAmountStr := viper.GetString(FlagSharesAmount)
sharesFractionStr := viper.GetString(FlagSharesFraction)
sharesAmount, err := getShares(
storeName, cdc, sharesAmountStr, sharesFractionStr,
delAddr, valAddr,
)
if err != nil {
return err
}
msg := staking.NewMsgBeginUnbonding(delAddr, valAddr, sharesAmount)
if cliCtx.GenerateOnly {
return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false)
}
// build and sign the transaction, then broadcast to Tendermint
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
},
}
cmd.Flags().AddFlagSet(fsShares)
cmd.Flags().AddFlagSet(fsValidator)
return cmd
}
// BuildCreateValidatorMsg makes a new MsgCreateValidator.
func BuildCreateValidatorMsg(cliCtx context.CLIContext, txBldr authtxb.TxBuilder) (authtxb.TxBuilder, sdk.Msg, error) {
amounstStr := viper.GetString(FlagAmount)
amount, err := sdk.ParseCoin(amounstStr)
if err != nil {
return txBldr, nil, err
}
valAddr, err := cliCtx.GetFromAddress()
if err != nil {
return txBldr, nil, err
}
pkStr := viper.GetString(FlagPubKey)
pk, err := sdk.GetConsPubKeyBech32(pkStr)
if err != nil {
return txBldr, nil, err
}
description := staking.NewDescription(
viper.GetString(FlagMoniker),
viper.GetString(FlagIdentity),
viper.GetString(FlagWebsite),
viper.GetString(FlagDetails),
)
// get the initial validator commission parameters
rateStr := viper.GetString(FlagCommissionRate)
maxRateStr := viper.GetString(FlagCommissionMaxRate)
maxChangeRateStr := viper.GetString(FlagCommissionMaxChangeRate)
commissionMsg, err := buildCommissionMsg(rateStr, maxRateStr, maxChangeRateStr)
if err != nil {
return txBldr, nil, err
}
delAddr := viper.GetString(FlagAddressDelegator)
var msg sdk.Msg
if delAddr != "" {
delAddr, err := sdk.AccAddressFromBech32(delAddr)
if err != nil {
return txBldr, nil, err
}
msg = staking.NewMsgCreateValidatorOnBehalfOf(
delAddr, sdk.ValAddress(valAddr), pk, amount, description, commissionMsg,
)
} else {
msg = staking.NewMsgCreateValidator(
sdk.ValAddress(valAddr), pk, amount, description, commissionMsg,
)
}
if viper.GetBool(FlagGenesisFormat) {
ip := viper.GetString(FlagIP)
nodeID := viper.GetString(FlagNodeID)
if nodeID != "" && ip != "" {
txBldr = txBldr.WithMemo(fmt.Sprintf("%s@%s:26656", nodeID, ip))
}
}
return txBldr, msg, nil
}
+88
View File
@@ -0,0 +1,88 @@
package cli
import (
"github.com/pkg/errors"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func getShares(
storeName string, cdc *codec.Codec, sharesAmountStr,
sharesPercentStr string, delAddr sdk.AccAddress, valAddr sdk.ValAddress,
) (sharesAmount sdk.Dec, err error) {
switch {
case sharesAmountStr != "" && sharesPercentStr != "":
return sharesAmount, errors.Errorf("can either specify the amount OR the percent of the shares, not both")
case sharesAmountStr == "" && sharesPercentStr == "":
return sharesAmount, errors.Errorf("can either specify the amount OR the percent of the shares, not both")
case sharesAmountStr != "":
sharesAmount, err = sdk.NewDecFromStr(sharesAmountStr)
if err != nil {
return sharesAmount, err
}
if !sharesAmount.GT(sdk.ZeroDec()) {
return sharesAmount, errors.Errorf("shares amount must be positive number (ex. 123, 1.23456789)")
}
case sharesPercentStr != "":
var sharesPercent sdk.Dec
sharesPercent, err = sdk.NewDecFromStr(sharesPercentStr)
if err != nil {
return sharesAmount, err
}
if !sharesPercent.GT(sdk.ZeroDec()) || !sharesPercent.LTE(sdk.OneDec()) {
return sharesAmount, errors.Errorf("shares percent must be >0 and <=1 (ex. 0.01, 0.75, 1)")
}
// make a query to get the existing delegation shares
key := staking.GetDelegationKey(delAddr, valAddr)
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
resQuery, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return sharesAmount, errors.Errorf("cannot find delegation to determine percent Error: %v", err)
}
delegation, err := types.UnmarshalDelegation(cdc, resQuery)
if err != nil {
return sdk.ZeroDec(), err
}
sharesAmount = sharesPercent.Mul(delegation.Shares)
}
return
}
func buildCommissionMsg(rateStr, maxRateStr, maxChangeRateStr string) (commission types.CommissionMsg, err error) {
if rateStr == "" || maxRateStr == "" || maxChangeRateStr == "" {
return commission, errors.Errorf("must specify all validator commission parameters")
}
rate, err := sdk.NewDecFromStr(rateStr)
if err != nil {
return commission, err
}
maxRate, err := sdk.NewDecFromStr(maxRateStr)
if err != nil {
return commission, err
}
maxChangeRate, err := sdk.NewDecFromStr(maxChangeRateStr)
if err != nil {
return commission, err
}
commission = types.NewCommissionMsg(rate, maxRate, maxChangeRate)
return commission, nil
}