Skip to content

Commit 0df0626

Browse files
authored
Generic 02-client cli cmds, removes light client specific ones (#8259)
* remove old light client cli cmds and replace with generic ones housed in client * remove print and add client cli getter cmds * use any as arguments * revert back to single pub key * fix tests * typo * remove todo * add upgrade cli cmd cc @AdityaSripal * register upgrade cmd
1 parent 2e8f5e5 commit 0df0626

File tree

13 files changed

+290
-534
lines changed

13 files changed

+290
-534
lines changed

x/auth/client/rest/rest_test.go

+15-5
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import (
2525
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
2626
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
2727
"github.com/cosmos/cosmos-sdk/x/bank/types"
28+
ibcclientcli "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/client/cli"
2829
ibccli "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/client/cli"
29-
ibcsolomachinecli "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/client/cli"
3030
)
3131

3232
type IntegrationTestSuite struct {
@@ -480,10 +480,20 @@ func (s *IntegrationTestSuite) testQueryIBCTx(txRes sdk.TxResponse, cmd *cobra.C
480480
func (s *IntegrationTestSuite) TestLegacyRestErrMessages() {
481481
val := s.network.Validators[0]
482482

483+
// Write client state json to temp file, used for an IBC message.
484+
// Generated by printing the result of cdc.MarshalIntefaceJSON on
485+
// a solo machine client state
486+
clientStateJSON := testutil.WriteToNewTempFile(
487+
s.T(),
488+
`{"@type":"/ibc.lightclients.solomachine.v1.ClientState","sequence":"1","frozen_sequence":"0","consensus_state":{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"},"allow_update_after_proposal":false}`,
489+
)
490+
483491
// Write consensus json to temp file, used for an IBC message.
492+
// Generated by printing the result of cdc.MarshalIntefaceJSON on
493+
// a solo machine consensus state
484494
consensusJSON := testutil.WriteToNewTempFile(
485495
s.T(),
486-
`{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A/3SXL2ONYaOkxpdR5P8tHTlSlPv1AwQwSFxKRee5JQW"},"diversifier":"diversifier","timestamp":"10"}`,
496+
`{"@type":"/ibc.lightclients.solomachine.v1.ConsensusState","public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"}`,
487497
)
488498

489499
testCases := []struct {
@@ -509,10 +519,10 @@ func (s *IntegrationTestSuite) TestLegacyRestErrMessages() {
509519
},
510520
{
511521
"Successful IBC message",
512-
ibcsolomachinecli.NewCreateClientCmd(),
522+
ibcclientcli.NewCreateClientCmd(),
513523
[]string{
514-
"1", // dummy sequence
515-
consensusJSON.Name(), // path to consensus json,
524+
clientStateJSON.Name(), // path to client state json
525+
consensusJSON.Name(), // path to consensus json,
516526
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
517527
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
518528
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),

x/ibc/core/02-client/client/cli/cli.go

+20
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,23 @@ func GetQueryCmd() *cobra.Command {
2929

3030
return queryCmd
3131
}
32+
33+
// NewTxCmd returns the command to create and handle IBC clients
34+
func NewTxCmd() *cobra.Command {
35+
txCmd := &cobra.Command{
36+
Use: types.SubModuleName,
37+
Short: "IBC client transaction subcommands",
38+
DisableFlagParsing: true,
39+
SuggestionsMinimumDistance: 2,
40+
RunE: client.ValidateCmd,
41+
}
42+
43+
txCmd.AddCommand(
44+
NewCreateClientCmd(),
45+
NewUpdateClientCmd(),
46+
NewSubmitMisbehaviourCmd(),
47+
NewUpgradeClientCmd(),
48+
)
49+
50+
return txCmd
51+
}

x/ibc/core/02-client/client/cli/query.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,11 @@ func GetCmdQueryHeader() *cobra.Command {
193193
if err != nil {
194194
return err
195195
}
196-
header, height, err := utils.QueryTendermintHeader(clientCtx)
196+
header, _, err := utils.QueryTendermintHeader(clientCtx)
197197
if err != nil {
198198
return err
199199
}
200200

201-
clientCtx = clientCtx.WithHeight(height)
202201
return clientCtx.PrintProto(&header)
203202
},
204203
}
@@ -222,12 +221,11 @@ func GetCmdNodeConsensusState() *cobra.Command {
222221
if err != nil {
223222
return err
224223
}
225-
state, height, err := utils.QueryNodeConsensusState(clientCtx)
224+
state, _, err := utils.QueryNodeConsensusState(clientCtx)
226225
if err != nil {
227226
return err
228227
}
229228

230-
clientCtx = clientCtx.WithHeight(height)
231229
return clientCtx.PrintProto(state)
232230
},
233231
}

x/ibc/core/02-client/client/cli/tx.go

+246
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
7+
"github.com/pkg/errors"
8+
"github.com/spf13/cobra"
9+
10+
"github.com/cosmos/cosmos-sdk/client"
11+
"github.com/cosmos/cosmos-sdk/client/flags"
12+
"github.com/cosmos/cosmos-sdk/client/tx"
13+
"github.com/cosmos/cosmos-sdk/codec"
14+
"github.com/cosmos/cosmos-sdk/version"
15+
"github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
16+
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
17+
)
18+
19+
// NewCreateClientCmd defines the command to create a new IBC light client.
20+
func NewCreateClientCmd() *cobra.Command {
21+
cmd := &cobra.Command{
22+
Use: "create [path/to/client_state.json] [path/to/consensus_state.json]",
23+
Short: "create new IBC client",
24+
Long: `create a new IBC client with the specified client state and consensus state
25+
- ClientState JSON example: {"@type":"/ibc.lightclients.solomachine.v1.ClientState","sequence":"1","frozen_sequence":"0","consensus_state":{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"},"allow_update_after_proposal":false}
26+
- ConsensusState JSON example: {"@type":"/ibc.lightclients.solomachine.v1.ConsensusState","public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"}`,
27+
Example: fmt.Sprintf("%s tx ibc %s create [path/to/client_state.json] [path/to/consensus_state.json] --from node0 --home ../node0/<app>cli --chain-id $CID", version.AppName, types.SubModuleName),
28+
Args: cobra.ExactArgs(2),
29+
RunE: func(cmd *cobra.Command, args []string) error {
30+
clientCtx, err := client.GetClientTxContext(cmd)
31+
if err != nil {
32+
return err
33+
}
34+
cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry)
35+
36+
// attempt to unmarshal client state argument
37+
var clientState exported.ClientState
38+
clientContentOrFileName := args[0]
39+
if err := cdc.UnmarshalInterfaceJSON([]byte(clientContentOrFileName), &clientState); err != nil {
40+
41+
// check for file path if JSON input is not provided
42+
contents, err := ioutil.ReadFile(clientContentOrFileName)
43+
if err != nil {
44+
return errors.Wrap(err, "neither JSON input nor path to .json file for client state were provided")
45+
}
46+
47+
if err := cdc.UnmarshalInterfaceJSON(contents, &clientState); err != nil {
48+
return errors.Wrap(err, "error unmarshalling client state file")
49+
}
50+
}
51+
52+
// attempt to unmarshal consensus state argument
53+
var consensusState exported.ConsensusState
54+
consensusContentOrFileName := args[1]
55+
if err := cdc.UnmarshalInterfaceJSON([]byte(consensusContentOrFileName), &consensusState); err != nil {
56+
57+
// check for file path if JSON input is not provided
58+
contents, err := ioutil.ReadFile(consensusContentOrFileName)
59+
if err != nil {
60+
return errors.Wrap(err, "neither JSON input nor path to .json file for consensus state were provided")
61+
}
62+
63+
if err := cdc.UnmarshalInterfaceJSON(contents, &consensusState); err != nil {
64+
return errors.Wrap(err, "error unmarshalling consensus state file")
65+
}
66+
}
67+
68+
msg, err := types.NewMsgCreateClient(clientState, consensusState, clientCtx.GetFromAddress())
69+
if err != nil {
70+
return err
71+
}
72+
73+
if err := msg.ValidateBasic(); err != nil {
74+
return err
75+
}
76+
77+
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
78+
},
79+
}
80+
81+
flags.AddTxFlagsToCmd(cmd)
82+
83+
return cmd
84+
}
85+
86+
// NewUpdateClientCmd defines the command to update an IBC client.
87+
func NewUpdateClientCmd() *cobra.Command {
88+
return &cobra.Command{
89+
Use: "update [client-id] [path/to/header.json]",
90+
Short: "update existing client with a header",
91+
Long: "update existing client with a header",
92+
Example: fmt.Sprintf("%s tx ibc %s update [client-id] [path/to/header.json] --from node0 --home ../node0/<app>cli --chain-id $CID", version.AppName, types.SubModuleName),
93+
Args: cobra.ExactArgs(2),
94+
RunE: func(cmd *cobra.Command, args []string) error {
95+
clientCtx, err := client.GetClientTxContext(cmd)
96+
if err != nil {
97+
return err
98+
}
99+
clientID := args[0]
100+
101+
cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry)
102+
103+
var header exported.Header
104+
headerContentOrFileName := args[1]
105+
if err := cdc.UnmarshalInterfaceJSON([]byte(headerContentOrFileName), &header); err != nil {
106+
107+
// check for file path if JSON input is not provided
108+
contents, err := ioutil.ReadFile(headerContentOrFileName)
109+
if err != nil {
110+
return errors.Wrap(err, "neither JSON input nor path to .json file for header were provided")
111+
}
112+
113+
if err := cdc.UnmarshalInterfaceJSON(contents, &header); err != nil {
114+
return errors.Wrap(err, "error unmarshalling header file")
115+
}
116+
}
117+
118+
msg, err := types.NewMsgUpdateClient(clientID, header, clientCtx.GetFromAddress())
119+
if err != nil {
120+
return err
121+
}
122+
123+
if err := msg.ValidateBasic(); err != nil {
124+
return err
125+
}
126+
127+
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
128+
},
129+
}
130+
}
131+
132+
// NewSubmitMisbehaviourCmd defines the command to submit a misbehaviour to prevent
133+
// future updates.
134+
func NewSubmitMisbehaviourCmd() *cobra.Command {
135+
return &cobra.Command{
136+
Use: "misbehaviour [path/to/misbehaviour.json]",
137+
Short: "submit a client misbehaviour",
138+
Long: "submit a client misbehaviour to prevent future updates",
139+
Example: fmt.Sprintf("%s tx ibc %s misbehaviour [path/to/misbehaviour.json] --from node0 --home ../node0/<app>cli --chain-id $CID", version.AppName, types.SubModuleName),
140+
Args: cobra.ExactArgs(1),
141+
RunE: func(cmd *cobra.Command, args []string) error {
142+
clientCtx, err := client.GetClientTxContext(cmd)
143+
if err != nil {
144+
return err
145+
}
146+
cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry)
147+
148+
var misbehaviour exported.Misbehaviour
149+
misbehaviourContentOrFileName := args[0]
150+
if err := cdc.UnmarshalInterfaceJSON([]byte(misbehaviourContentOrFileName), &misbehaviour); err != nil {
151+
152+
// check for file path if JSON input is not provided
153+
contents, err := ioutil.ReadFile(misbehaviourContentOrFileName)
154+
if err != nil {
155+
return errors.Wrap(err, "neither JSON input nor path to .json file for misbehaviour were provided")
156+
}
157+
158+
if err := cdc.UnmarshalInterfaceJSON(contents, misbehaviour); err != nil {
159+
return errors.Wrap(err, "error unmarshalling misbehaviour file")
160+
}
161+
}
162+
163+
msg, err := types.NewMsgSubmitMisbehaviour(misbehaviour.GetClientID(), misbehaviour, clientCtx.GetFromAddress())
164+
if err != nil {
165+
return err
166+
}
167+
168+
if err := msg.ValidateBasic(); err != nil {
169+
return err
170+
}
171+
172+
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
173+
},
174+
}
175+
}
176+
177+
// NewUpgradeClientCmd defines the command to upgrade an IBC light client.
178+
func NewUpgradeClientCmd() *cobra.Command {
179+
cmd := &cobra.Command{
180+
Use: "upgrade [client-identifier] [path/to/client_state.json] [path/to/consensus_state.json] [upgrade-client-proof] [upgrade-consensus-state-proof]",
181+
Short: "upgrade an IBC client",
182+
Long: `upgrade the IBC client associated with the provided client identifier while providing proof committed by the counterparty chain to the new client and consensus states
183+
- ClientState JSON example: {"@type":"/ibc.lightclients.solomachine.v1.ClientState","sequence":"1","frozen_sequence":"0","consensus_state":{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"},"allow_update_after_proposal":false}
184+
- ConsensusState JSON example: {"@type":"/ibc.lightclients.solomachine.v1.ConsensusState","public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"}`,
185+
Example: fmt.Sprintf("%s tx ibc %s upgrade [client-identifier] [path/to/client_state.json] [path/to/consensus_state.json] [client-state-proof] [consensus-state-proof] --from node0 --home ../node0/<app>cli --chain-id $CID", version.AppName, types.SubModuleName),
186+
Args: cobra.ExactArgs(5),
187+
RunE: func(cmd *cobra.Command, args []string) error {
188+
clientCtx, err := client.GetClientTxContext(cmd)
189+
if err != nil {
190+
return err
191+
}
192+
cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry)
193+
clientID := args[0]
194+
195+
// attempt to unmarshal client state argument
196+
var clientState exported.ClientState
197+
clientContentOrFileName := args[1]
198+
if err := cdc.UnmarshalInterfaceJSON([]byte(clientContentOrFileName), &clientState); err != nil {
199+
200+
// check for file path if JSON input is not provided
201+
contents, err := ioutil.ReadFile(clientContentOrFileName)
202+
if err != nil {
203+
return errors.Wrap(err, "neither JSON input nor path to .json file for client state were provided")
204+
}
205+
206+
if err := cdc.UnmarshalInterfaceJSON(contents, &clientState); err != nil {
207+
return errors.Wrap(err, "error unmarshalling client state file")
208+
}
209+
}
210+
211+
// attempt to unmarshal consensus state argument
212+
var consensusState exported.ConsensusState
213+
consensusContentOrFileName := args[2]
214+
if err := cdc.UnmarshalInterfaceJSON([]byte(consensusContentOrFileName), &consensusState); err != nil {
215+
216+
// check for file path if JSON input is not provided
217+
contents, err := ioutil.ReadFile(consensusContentOrFileName)
218+
if err != nil {
219+
return errors.Wrap(err, "neither JSON input nor path to .json file for consensus state were provided")
220+
}
221+
222+
if err := cdc.UnmarshalInterfaceJSON(contents, &consensusState); err != nil {
223+
return errors.Wrap(err, "error unmarshalling consensus state file")
224+
}
225+
}
226+
227+
proofUpgradeClient := []byte(args[3])
228+
proofUpgradeConsensus := []byte(args[4])
229+
230+
msg, err := types.NewMsgUpgradeClient(clientID, clientState, consensusState, proofUpgradeClient, proofUpgradeConsensus, clientCtx.GetFromAddress())
231+
if err != nil {
232+
return err
233+
}
234+
235+
if err := msg.ValidateBasic(); err != nil {
236+
return err
237+
}
238+
239+
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
240+
},
241+
}
242+
243+
flags.AddTxFlagsToCmd(cmd)
244+
245+
return cmd
246+
}

x/ibc/core/02-client/module.go

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ func GetQueryCmd() *cobra.Command {
1818
return cli.GetQueryCmd()
1919
}
2020

21+
// GetTxCmd returns the root tx command for 02-client.
22+
func GetTxCmd() *cobra.Command {
23+
return cli.NewTxCmd()
24+
}
25+
2126
// RegisterQueryService registers the gRPC query service for IBC client.
2227
func RegisterQueryService(server grpc.Server, queryServer types.QueryServer) {
2328
types.RegisterQueryServer(server, queryServer)

x/ibc/core/client/cli/cli.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
connection "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection"
99
channel "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel"
1010
host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
11-
solomachine "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine"
12-
tendermint "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint"
1311
)
1412

1513
// GetTxCmd returns the transaction commands for this module
@@ -23,8 +21,7 @@ func GetTxCmd() *cobra.Command {
2321
}
2422

2523
ibcTxCmd.AddCommand(
26-
solomachine.GetTxCmd(),
27-
tendermint.GetTxCmd(),
24+
ibcclient.GetTxCmd(),
2825
connection.GetTxCmd(),
2926
channel.GetTxCmd(),
3027
)

0 commit comments

Comments
 (0)