Skip to content

Commit

Permalink
add cli for MsgIBCSoftwareUpgrade (#4558)
Browse files Browse the repository at this point in the history
  • Loading branch information
charleenfei authored Sep 6, 2023
1 parent 7f3dd42 commit a374631
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 5 deletions.
3 changes: 2 additions & 1 deletion modules/core/02-client/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ func NewTxCmd() *cobra.Command {
NewUpdateClientCmd(),
NewSubmitMisbehaviourCmd(), // Deprecated
NewUpgradeClientCmd(),
NewCmdSubmitRecoverClientProposal(),
newSubmitRecoverClientProposalCmd(),
newScheduleIBCUpgradeProposalCmd(),
)

return txCmd
Expand Down
157 changes: 153 additions & 4 deletions modules/core/02-client/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@ func NewUpgradeClientCmd() *cobra.Command {
return cmd
}

// NewCmdSubmitRecoverClientProposal defines the command to recover an IBC light client
func NewCmdSubmitRecoverClientProposal() *cobra.Command {
// newSubmitRecoverClientProposalCmd defines the command to recover an IBC light client
func newSubmitRecoverClientProposalCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "recover-client [subject-client-id] [substitute-client-id] [flags]",
Args: cobra.ExactArgs(2),
Short: "recover an IBC client",
Long: "Submit a recover IBC client proposal along with an initial deposit.\n" +
"Please specify a subject client identifier you want to recover..\n" +
"Please specify a subject client identifier you want to recover.\n" +
"Please specify the substitute client the subject client will be recovered to.",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
Expand Down Expand Up @@ -310,7 +310,7 @@ func NewCmdSubmitUpdateClientProposal() *cobra.Command {
Args: cobra.ExactArgs(2),
Short: "Submit an update IBC client proposal",
Long: "Submit an update IBC client proposal along with an initial deposit.\n" +
"Please specify a subject client identifier you want to update..\n" +
"Please specify a subject client identifier you want to update.\n" +
"Please specify the substitute client the subject client will be updated to.",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
Expand Down Expand Up @@ -454,3 +454,152 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command {

return cmd
}

// newScheduleIBCUpgradeProposalCmd defines the command for submitting an IBC software upgrade proposal.
func newScheduleIBCUpgradeProposalCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "schedule-ibc-upgrade [name] [height] [path/to/upgraded_client_state.json] [flags]",
Args: cobra.ExactArgs(3),
Short: "Submit an IBC software upgrade proposal",
Long: `Please specify a unique name and height for the upgrade to take effect.
The client state specified is the upgraded client state representing the upgraded chain
Example Upgraded Client State JSON:
{
"@type":"/ibc.lightclients.tendermint.v1.ClientState",
"chain_id":"testchain1",
"unbonding_period":"1814400s",
"latest_height":{
"revision_number":"0",
"revision_height":"2"
},
"proof_specs":[
{
"leaf_spec":{
"hash":"SHA256",
"prehash_key":"NO_HASH",
"prehash_value":"SHA256",
"length":"VAR_PROTO",
"prefix":"AA=="
},
"inner_spec":{
"child_order":[
0,
1
],
"child_size":33,
"min_prefix_length":4,
"max_prefix_length":12,
"empty_child":null,
"hash":"SHA256"
},
"max_depth":0,
"min_depth":0
},
{
"leaf_spec":{
"hash":"SHA256",
"prehash_key":"NO_HASH",
"prehash_value":"SHA256",
"length":"VAR_PROTO",
"prefix":"AA=="
},
"inner_spec":{
"child_order":[
0,
1
],
"child_size":32,
"min_prefix_length":1,
"max_prefix_length":1,
"empty_child":null,
"hash":"SHA256"
},
"max_depth":0,
"min_depth":0
}
],
"upgrade_path":[
"upgrade",
"upgradedIBCState"
]
}
`,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

proposal, err := govcli.ReadGovPropFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}

cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry)

name := args[0]

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

plan := upgradetypes.Plan{
Name: name,
Height: height,
}

// attempt to unmarshal client state argument
var clientState exported.ClientState
clientContentOrFileName := args[2]
if err := cdc.UnmarshalInterfaceJSON([]byte(clientContentOrFileName), &clientState); err != nil {

// check for file path if JSON input is not provided
contents, err := os.ReadFile(clientContentOrFileName)
if err != nil {
return fmt.Errorf("neither JSON input nor path to .json file for client state were provided: %w", err)
}

if err := cdc.UnmarshalInterfaceJSON(contents, &clientState); err != nil {
return fmt.Errorf("error unmarshalling client state file: %w", err)
}
}

authority, _ := cmd.Flags().GetString(FlagAuthority)
if authority != "" {
if _, err = sdk.AccAddressFromBech32(authority); err != nil {
return fmt.Errorf("invalid authority address: %w", err)
}
} else {
authority = sdk.AccAddress(address.Module(govtypes.ModuleName)).String()
}

msg, err := types.NewMsgIBCSoftwareUpgrade(authority, plan, clientState)
if err != nil {
return fmt.Errorf("error in NewMsgIBCSoftwareUpgrade: %w", err)
}

if err = msg.ValidateBasic(); err != nil {
return fmt.Errorf("error validating MsgIBCSoftwareUpgrade: %w", err)
}

if err := proposal.SetMsgs([]sdk.Msg{msg}); err != nil {
return fmt.Errorf("failed to create proposal message for scheduling an IBC software upgrade: %w", err)
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), proposal)
},
}

cmd.Flags().String(FlagAuthority, "", "The address of the client module authority (defaults to gov)")

flags.AddTxFlagsToCmd(cmd)
govcli.AddGovPropFlagsToCmd(cmd)
err := cmd.MarkFlagRequired(govcli.FlagTitle)
if err != nil {
panic(err)
}

return cmd
}

0 comments on commit a374631

Please sign in to comment.