2019-11-08 06:40:56 -08:00
package cli
import (
2021-11-12 09:44:33 -08:00
"os"
"path/filepath"
2019-11-08 06:40:56 -08:00
"github.com/spf13/cobra"
2020-06-01 05:46:03 -07:00
"github.com/cosmos/cosmos-sdk/client"
2020-07-08 15:00:56 -07:00
"github.com/cosmos/cosmos-sdk/client/tx"
2019-11-08 06:40:56 -08:00
sdk "github.com/cosmos/cosmos-sdk/types"
2020-07-08 15:00:56 -07:00
"github.com/cosmos/cosmos-sdk/x/gov/client/cli"
2021-12-13 10:48:44 -08:00
gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
2021-11-12 09:44:33 -08:00
"github.com/cosmos/cosmos-sdk/x/upgrade/plan"
2020-02-24 09:14:19 -08:00
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
2019-11-08 06:40:56 -08:00
)
const (
FlagUpgradeHeight = "upgrade-height"
2020-10-28 03:41:55 -07:00
FlagUpgradeInfo = "upgrade-info"
2021-11-12 09:44:33 -08:00
FlagNoValidate = "no-validate"
FlagDaemonName = "daemon-name"
2019-11-08 06:40:56 -08:00
)
2020-07-08 15:00:56 -07:00
// GetTxCmd returns the transaction commands for this module
func GetTxCmd ( ) * cobra . Command {
cmd := & cobra . Command {
Use : types . ModuleName ,
Short : "Upgrade transaction subcommands" ,
}
return cmd
}
2020-04-16 12:33:57 -07:00
// NewCmdSubmitUpgradeProposal implements a command handler for submitting a software upgrade proposal transaction.
2020-07-10 07:45:46 -07:00
func NewCmdSubmitUpgradeProposal ( ) * cobra . Command {
2020-04-16 12:33:57 -07:00
cmd := & cobra . Command {
2021-03-13 17:03:01 -08:00
Use : "software-upgrade [name] (--upgrade-height [height]) (--upgrade-info [info]) [flags]" ,
2020-04-16 12:33:57 -07:00
Args : cobra . ExactArgs ( 1 ) ,
Short : "Submit a software upgrade proposal" ,
Long : "Submit a software upgrade along with an initial deposit.\n" +
2021-03-13 17:03:01 -08:00
"Please specify a unique name and height for the upgrade to take effect.\n" +
2021-01-05 14:52:49 -08:00
"You may include info to reference a binary download link, in a format compatible with: https://github.com/cosmos/cosmos-sdk/tree/master/cosmovisor" ,
2020-04-16 12:33:57 -07:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-12-14 14:09:51 -08:00
clientCtx , err := client . GetClientTxContext ( cmd )
2020-07-10 07:45:46 -07:00
if err != nil {
return err
}
2020-04-16 12:33:57 -07:00
name := args [ 0 ]
content , err := parseArgsToContent ( cmd , name )
if err != nil {
return err
}
2021-11-12 09:44:33 -08:00
noValidate , err := cmd . Flags ( ) . GetBool ( FlagNoValidate )
if err != nil {
return err
}
if ! noValidate {
prop := content . ( * types . SoftwareUpgradeProposal )
var daemonName string
if daemonName , err = cmd . Flags ( ) . GetString ( FlagDaemonName ) ; err != nil {
return err
}
var planInfo * plan . Info
if planInfo , err = plan . ParseInfo ( prop . Plan . Info ) ; err != nil {
return err
}
if err = planInfo . ValidateFull ( daemonName ) ; err != nil {
return err
}
}
2020-04-16 12:33:57 -07:00
2020-06-01 05:46:03 -07:00
from := clientCtx . GetFromAddress ( )
2020-04-16 12:33:57 -07:00
depositStr , err := cmd . Flags ( ) . GetString ( cli . FlagDeposit )
if err != nil {
return err
}
2020-11-16 03:34:54 -08:00
deposit , err := sdk . ParseCoinsNormalized ( depositStr )
2020-04-16 12:33:57 -07:00
if err != nil {
return err
}
2020-05-21 14:29:34 -07:00
msg , err := gov . NewMsgSubmitProposal ( content , deposit , from )
2020-04-16 12:33:57 -07:00
if err != nil {
return err
}
2021-05-07 02:31:20 -07:00
return tx . GenerateOrBroadcastTxCLI ( clientCtx , cmd . Flags ( ) , msg )
2020-04-16 12:33:57 -07:00
} ,
}
cmd . Flags ( ) . String ( cli . FlagTitle , "" , "title of proposal" )
cmd . Flags ( ) . String ( cli . FlagDescription , "" , "description of proposal" )
cmd . Flags ( ) . String ( cli . FlagDeposit , "" , "deposit of proposal" )
2021-03-13 17:03:01 -08:00
cmd . Flags ( ) . Int64 ( FlagUpgradeHeight , 0 , "The height at which the upgrade must happen" )
2021-11-12 09:44:33 -08:00
cmd . Flags ( ) . String ( FlagUpgradeInfo , "" , "Info for the upgrade plan such as new version download urls, etc." )
cmd . Flags ( ) . Bool ( FlagNoValidate , false , "Skip validation of the upgrade info" )
cmd . Flags ( ) . String ( FlagDaemonName , getDefaultDaemonName ( ) , "The name of the executable being upgraded (for upgrade-info validation). Default is the DAEMON_NAME env var if set, or else this executable" )
2020-04-16 12:33:57 -07:00
return cmd
}
// NewCmdSubmitCancelUpgradeProposal implements a command handler for submitting a software upgrade cancel proposal transaction.
2020-07-20 09:42:46 -07:00
func NewCmdSubmitCancelUpgradeProposal ( ) * cobra . Command {
2020-04-16 12:33:57 -07:00
cmd := & cobra . Command {
Use : "cancel-software-upgrade [flags]" ,
Args : cobra . ExactArgs ( 0 ) ,
2020-10-09 09:28:58 -07:00
Short : "Cancel the current software upgrade proposal" ,
2020-04-16 12:33:57 -07:00
Long : "Cancel a software upgrade along with an initial deposit." ,
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-12-14 14:09:51 -08:00
clientCtx , err := client . GetClientTxContext ( cmd )
2020-07-20 09:42:46 -07:00
if err != nil {
return err
}
2020-06-01 05:46:03 -07:00
from := clientCtx . GetFromAddress ( )
2020-04-16 12:33:57 -07:00
depositStr , err := cmd . Flags ( ) . GetString ( cli . FlagDeposit )
if err != nil {
return err
}
2020-11-16 03:34:54 -08:00
deposit , err := sdk . ParseCoinsNormalized ( depositStr )
2020-04-16 12:33:57 -07:00
if err != nil {
return err
}
title , err := cmd . Flags ( ) . GetString ( cli . FlagTitle )
if err != nil {
return err
}
description , err := cmd . Flags ( ) . GetString ( cli . FlagDescription )
if err != nil {
return err
}
content := types . NewCancelSoftwareUpgradeProposal ( title , description )
2020-05-21 14:29:34 -07:00
msg , err := gov . NewMsgSubmitProposal ( content , deposit , from )
2020-04-16 12:33:57 -07:00
if err != nil {
return err
}
2021-05-07 02:31:20 -07:00
return tx . GenerateOrBroadcastTxCLI ( clientCtx , cmd . Flags ( ) , msg )
2020-04-16 12:33:57 -07:00
} ,
}
cmd . Flags ( ) . String ( cli . FlagTitle , "" , "title of proposal" )
cmd . Flags ( ) . String ( cli . FlagDescription , "" , "description of proposal" )
cmd . Flags ( ) . String ( cli . FlagDeposit , "" , "deposit of proposal" )
2020-07-24 10:39:52 -07:00
cmd . MarkFlagRequired ( cli . FlagTitle )
cmd . MarkFlagRequired ( cli . FlagDescription )
2020-04-16 12:33:57 -07:00
return cmd
}
2019-11-08 06:40:56 -08:00
func parseArgsToContent ( cmd * cobra . Command , name string ) ( gov . Content , error ) {
title , err := cmd . Flags ( ) . GetString ( cli . FlagTitle )
if err != nil {
return nil , err
}
description , err := cmd . Flags ( ) . GetString ( cli . FlagDescription )
if err != nil {
return nil , err
}
height , err := cmd . Flags ( ) . GetInt64 ( FlagUpgradeHeight )
if err != nil {
return nil , err
}
info , err := cmd . Flags ( ) . GetString ( FlagUpgradeInfo )
if err != nil {
return nil , err
}
2021-03-13 17:03:01 -08:00
plan := types . Plan { Name : name , Height : height , Info : info }
2020-02-24 09:14:19 -08:00
content := types . NewSoftwareUpgradeProposal ( title , description , plan )
2019-11-08 06:40:56 -08:00
return content , nil
}
2021-11-12 09:44:33 -08:00
// getDefaultDaemonName gets the default name to use for the daemon.
// If a DAEMON_NAME env var is set, that is used.
// Otherwise, the last part of the currently running executable is used.
func getDefaultDaemonName ( ) string {
// DAEMON_NAME is specifically used here to correspond with the Comsovisor setup env vars.
name := os . Getenv ( "DAEMON_NAME" )
if len ( name ) == 0 {
_ , name = filepath . Split ( os . Args [ 0 ] )
}
return name
}