Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(auth,vesting): add autocli options for tx #18100

Merged
merged 6 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### CLI Breaking Changes

* (x/auth/vesting) [#18100](https://github.com/cosmos/cosmos-sdk/pull/18100) `appd tx vesting create-vesting-account` takes an amount of coin as last argument instead of second. Coins are space separated.
* (x/distribution) [#17963](https://github.com/cosmos/cosmos-sdk/pull/17963) `appd tx distribution withdraw-rewards` now only withdraws rewards for the delegator's own delegations. For withdrawing validators commission, use `appd tx distribution withdraw-validator-commission`.

### State Machine Breaking
Expand Down
10 changes: 5 additions & 5 deletions x/auth/client/cli/broadcast.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package cli

import (
"errors"
"fmt"
"strings"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/version"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
)

Expand All @@ -19,11 +21,9 @@ func GetBroadcastCommand() *cobra.Command {
Long: strings.TrimSpace(`Broadcast transactions created with the --generate-only
flag and signed with the sign command. Read a transaction from [file_path] and
broadcast it to a node. If you supply a dash (-) argument in place of an input
filename, the command reads from standard input.

$ <appd> tx broadcast ./mytxn.json
`),
Args: cobra.ExactArgs(1),
filename, the command reads from standard input.`),
Example: fmt.Sprintf("%s tx broadcast <file_path>", version.AppName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions x/auth/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"

gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra"

modulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
"cosmossdk.io/core/address"
Expand All @@ -22,6 +23,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/cosmos/cosmos-sdk/x/auth/simulation"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting/client/cli"
)

// ConsensusVersion defines the current x/auth module consensus version.
Expand Down Expand Up @@ -82,6 +84,11 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry)
types.RegisterInterfaces(registry)
}

// GetTxCmd returns the root tx command for the auth module.
func (ab AppModuleBasic) GetTxCmd() *cobra.Command {
return cli.GetTxCmd()
}

// AppModule implements an application module for the auth module.
type AppModule struct {
AppModuleBasic
Expand Down
48 changes: 48 additions & 0 deletions x/auth/vesting/autocli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package vesting

import (
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
vestingv1beta1 "cosmossdk.io/api/cosmos/vesting/v1beta1"
)

// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
return &autocliv1.ModuleOptions{
Tx: &autocliv1.ServiceCommandDescriptor{
Service: vestingv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "CreateVestingAccount",
Use: "create-vesting-account [to_address] [end_time] [amount]",
Short: "Create a new vesting account funded with an allocation of tokens.",
Long: `Create a new vesting account funded with an allocation of tokens. The
account can either be a delayed or continuous vesting account, which is determined
by the '--delayed' flag. All vesting accounts created will have their start time
set by the committed block's time. The end_time must be provided as a UNIX epoch
timestamp.`,
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "to_address"},
{ProtoField: "end_time"},
{ProtoField: "amount", Varargs: true},
},
FlagOptions: map[string]*autocliv1.FlagOptions{
"delayed": {Name: "delayed", Usage: "Create a delayed vesting account if true"},
},
},
{
RpcMethod: "CreatePermanentLockedAccount",
Use: "create-permanent-locked-account [to_address] [amount]",
Short: "Create a new permanently locked account funded with an allocation of tokens.",
Long: `Create a new account funded with an allocation of permanently locked tokens. These
tokens may be used for staking but are non-transferable. Staking rewards will acrue as liquid and transferable
tokens.`,
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "to_address"},
{ProtoField: "amount", Varargs: true},
},
},
},
EnhanceCustomCommand: true,
},
}
}
130 changes: 16 additions & 114 deletions x/auth/vesting/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package cli

import (
"encoding/json"
"errors"
"fmt"
"os"
"strconv"

"github.com/spf13/cobra"

Expand All @@ -16,11 +14,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
)

// Transaction command flags
const (
FlagDelayed = "delayed"
)

// GetTxCmd returns vesting module's transaction commands.
func GetTxCmd() *cobra.Command {
txCmd := &cobra.Command{
Expand All @@ -32,102 +25,12 @@ func GetTxCmd() *cobra.Command {
}

txCmd.AddCommand(
NewMsgCreateVestingAccountCmd(),
NewMsgCreatePermanentLockedAccountCmd(),
NewMsgCreatePeriodicVestingAccountCmd(),
)

return txCmd
}

// NewMsgCreateVestingAccountCmd returns a CLI command handler for creating a
// MsgCreateVestingAccount transaction.
func NewMsgCreateVestingAccountCmd() *cobra.Command {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since it is CLI breaking, can we keep the existing command with deprecated tag?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is minimally breaking (swapping two args), so I'd argue that this isn't necessary.

cmd := &cobra.Command{
Use: "create-vesting-account [to_address] [amount] [end_time]",
Short: "Create a new vesting account funded with an allocation of tokens.",
Long: `Create a new vesting account funded with an allocation of tokens. The
account can either be a delayed or continuous vesting account, which is determined
by the '--delayed' flag. All vesting accounts created will have their start time
set by the committed block's time. The end_time must be provided as a UNIX epoch
timestamp.`,
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
toAddr, err := clientCtx.AddressCodec.StringToBytes(args[0])
if err != nil {
return err
}

if args[1] == "" {
return errors.New("amount is empty")
}

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

endTime, err := strconv.ParseInt(args[2], 10, 64)
if err != nil {
return err
}

delayed, _ := cmd.Flags().GetBool(FlagDelayed)

msg := types.NewMsgCreateVestingAccount(clientCtx.GetFromAddress(), toAddr, amount, endTime, delayed)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().Bool(FlagDelayed, false, "Create a delayed vesting account if true")
flags.AddTxFlagsToCmd(cmd)

return cmd
}

// NewMsgCreatePermanentLockedAccountCmd returns a CLI command handler for creating a
// MsgCreatePermanentLockedAccount transaction.
func NewMsgCreatePermanentLockedAccountCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create-permanent-locked-account [to_address] [amount]",
Short: "Create a new permanently locked account funded with an allocation of tokens.",
Long: `Create a new account funded with an allocation of permanently locked tokens. These
tokens may be used for staking but are non-transferable. Staking rewards will acrue as liquid and transferable
tokens.`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
toAddr, err := clientCtx.AddressCodec.StringToBytes(args[0])
if err != nil {
return err
}

if args[1] == "" {
return errors.New("amount is empty")
}

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

msg := types.NewMsgCreatePermanentLockedAccount(clientCtx.GetFromAddress(), toAddr, amount)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}

type VestingData struct {
StartTime int64 `json:"start_time"`
Periods []InputPeriod `json:"periods"`
Expand All @@ -138,28 +41,27 @@ type InputPeriod struct {
Length int64 `json:"length_seconds"`
}

// NewMsgCreatePeriodicVestingAccountCmd returns a CLI command handler for creating a
// MsgCreatePeriodicVestingAccountCmd transaction.
// NewMsgCreatePeriodicVestingAccountCmd returns a CLI command handler for creating a MsgCreatePeriodicVestingAccountCmd transaction.
// This command can be migrated to AutoCLI but it would be CLI breaking to do so.
func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create-periodic-vesting-account [to_address] [periods_json_file]",
Short: "Create a new vesting account funded with an allocation of tokens.",
Long: `A sequence of coins and period length in seconds. Periods are sequential, in that the duration of of a period only starts at the end of the previous period. The duration of the first period starts upon account creation. For instance, the following periods.json file shows 20 "test" coins vesting 30 days apart from each other.
Where periods.json contains:

An array of coin strings and unix epoch times for coins to vest
{ "start_time": 1625204910,
"periods":[
{
"coins": "10test",
"length_seconds":2592000 //30 days
},
{
"coins": "10test",
"length_seconds":2592000 //30 days
},
]
}
Where periods.json contains an array of coin strings and unix epoch times for coins to vest:
{
"start_time": 1625204910,
"periods": [
{
"coins": "10test",
"length_seconds": 2592000 //30 days
},
{
"coins": "10test",
"length_seconds": 2592000 //30 days
}
]
}
`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
Loading
Loading