Skip to content

Commit

Permalink
feat(client/v2): support gov proposals (#18461)
Browse files Browse the repository at this point in the history
(cherry picked from commit 9c3386f)

# Conflicts:
#	client/v2/CHANGELOG.md
#	client/v2/autocli/msg.go
#	client/v2/go.mod
#	client/v2/go.sum
#	go.mod
#	go.sum
#	simapp/go.mod
#	tests/go.mod
#	tests/starship/tests/go.mod
#	x/accounts/go.mod
#	x/auth/go.mod
#	x/auth/go.sum
#	x/authz/go.mod
#	x/bank/autocli.go
#	x/bank/go.mod
#	x/bank/go.sum
#	x/circuit/go.mod
#	x/circuit/go.sum
#	x/distribution/go.mod
#	x/distribution/go.sum
#	x/evidence/go.mod
#	x/evidence/go.sum
#	x/feegrant/go.mod
#	x/feegrant/go.sum
#	x/gov/go.mod
#	x/group/go.mod
#	x/group/go.sum
#	x/mint/go.mod
#	x/mint/go.sum
#	x/nft/go.mod
#	x/nft/go.sum
#	x/params/go.mod
#	x/params/go.sum
#	x/protocolpool/go.mod
#	x/protocolpool/go.sum
#	x/slashing/go.mod
#	x/slashing/go.sum
#	x/staking/go.mod
#	x/staking/go.sum
#	x/upgrade/client/cli/tx.go
#	x/upgrade/go.mod
#	x/upgrade/go.sum
  • Loading branch information
julienrbrt authored and mergify[bot] committed Nov 15, 2023
1 parent dc30a6a commit 5fdd53e
Show file tree
Hide file tree
Showing 60 changed files with 14,271 additions and 37 deletions.
2 changes: 1 addition & 1 deletion client/prompt_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func ValidatePromptAddress(input string) error {
return fmt.Errorf("invalid address: %w", err)
}

// ValidatePromptYesNo validates that the input is valid sdk.COins
// ValidatePromptCoins validates that the input contains valid sdk.Coins
func ValidatePromptCoins(input string) error {
if _, err := sdk.ParseCoinsNormalized(input); err != nil {
return fmt.Errorf("invalid coins: %w", err)
Expand Down
13 changes: 13 additions & 0 deletions client/v2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

<<<<<<< HEAD
=======
<!-- ## [v2.1.0-beta.1] to be tagged after v0.51 final or in SDK agnostic version -->

### Features

* [#18461](https://github.com/cosmos/cosmos-sdk/pull/18461) Support governance proposals.

### API Breaking Changes

* [#17709](https://github.com/cosmos/cosmos-sdk/pull/17709) Address codecs have been removed from `autocli.AppOptions` and `flag.Builder`. Instead client/v2 uses the address codecs present in the context (introduced in [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503)).

>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))
## [v2.0.0-beta.1] - 2023-11-07

This is the first tagged version of client/v2.
Expand Down
7 changes: 6 additions & 1 deletion client/v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ This field is automatically filled when using the `--from` flag or defining the
AutoCLI currently supports only one signer per transaction.
:::

## Module Wiring & Customization
## Module wiring & Customization

The `AutoCLIOptions()` method on your module allows to specify custom commands, sub-commands or flags for each service, as it was a `cobra.Command` instance, within the `RpcCommandOptions` struct. Defining such options will customize the behavior of the `autocli` command generation, which by default generates a command for each method in your gRPC service.

Expand All @@ -137,6 +137,11 @@ The `AutoCLIOptions()` method on your module allows to specify custom commands,
}
```

:::tip
AutoCLI can create a gov proposal of any tx by simply setting the `GovProposal` field to `true` in the `autocli.RpcCommandOptions` struct.
Users can however use the `--no-proposal` flag to disable the proposal creation (which is useful if the authority isn't the gov module on a chain).
:::

### Specifying Subcommands

By default, `autocli` generates a command for each method in your gRPC service. However, you can specify subcommands to group related commands together. To specify subcommands, use the `autocliv1.ServiceCommandDescriptor` struct.
Expand Down
2 changes: 1 addition & 1 deletion client/v2/autocli/flag/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,10 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m

flagOpts := commandOptions.FlagOptions[string(field.Name())]
name, hasValue, err := b.addFieldFlag(ctx, flagSet, field, flagOpts, options)
flagOptsByFlagName[name] = flagOpts
if err != nil {
return nil, err
}
flagOptsByFlagName[name] = flagOpts

messageBinder.flagBindings = append(messageBinder.flagBindings, fieldBinding{
hasValue: hasValue,
Expand Down
83 changes: 77 additions & 6 deletions client/v2/autocli/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,28 @@ import (
"fmt"

"github.com/cockroachdb/errors"
gogoproto "github.com/cosmos/gogoproto/proto"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/dynamicpb"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/client/v2/internal/flags"
"cosmossdk.io/client/v2/internal/util"
<<<<<<< HEAD
=======
addresscodec "cosmossdk.io/core/address"
authtx "cosmossdk.io/x/auth/tx"
authtxconfig "cosmossdk.io/x/auth/tx/config"
>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))

// the following will be extracted to a separate module
// https://github.com/cosmos/cosmos-sdk/issues/14403
authtypes "cosmossdk.io/x/auth/types"
govcli "cosmossdk.io/x/gov/client/cli"
govtypes "cosmossdk.io/x/gov/types"

"github.com/cosmos/cosmos-sdk/client"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
Expand Down Expand Up @@ -111,7 +125,7 @@ func (b *Builder) AddMsgServiceCommands(cmd *cobra.Command, cmdDescriptor *autoc

// BuildMsgMethodCommand returns a command that outputs the JSON representation of the message.
func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor, options *autocliv1.RpcCommandOptions) (*cobra.Command, error) {
cmd, err := b.buildMethodCommandCommon(descriptor, options, func(cmd *cobra.Command, input protoreflect.Message) error {
execFunc := func(cmd *cobra.Command, input protoreflect.Message) error {
cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &b.ClientCtx))

clientCtx, err := client.GetClientTxContext(cmd)
Expand Down Expand Up @@ -140,11 +154,17 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
clientCtx = clientCtx.WithTxConfig(txConfig)
}

// set signer to signer field if empty
fd := input.Descriptor().Fields().ByName(protoreflect.Name(flag.GetSignerFieldName(input.Descriptor())))
if addr := input.Get(fd).String(); addr == "" {
addressCodec := b.Builder.AddressCodec
addressCodec := b.Builder.AddressCodec

// handle gov proposals commands
skipProposal, _ := cmd.Flags().GetBool(flags.FlagNoProposal)
if options.GovProposal && !skipProposal {
return b.handleGovProposal(options, cmd, input, clientCtx, addressCodec, fd)
}

// set signer to signer field if empty
if addr := input.Get(fd).String(); addr == "" {
scalarType, ok := flag.GetScalarType(fd)
if ok {
// override address codec if validator or consensus address
Expand Down Expand Up @@ -172,7 +192,12 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
proto.Merge(msg, input.Interface())

return clienttx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
})
}

cmd, err := b.buildMethodCommandCommon(descriptor, options, execFunc)
if err != nil {
return nil, err
}

if b.AddTxConnFlags != nil {
b.AddTxConnFlags(cmd)
Expand All @@ -183,5 +208,51 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
cmd.SilenceUsage = true
}

return cmd, err
// set gov proposal flags if command is a gov proposal
if options.GovProposal {
govcli.AddGovPropFlagsToCmd(cmd)
cmd.Flags().Bool(flags.FlagNoProposal, false, "Skip gov proposal and submit a normal transaction")
}

return cmd, nil
}

// handleGovProposal sets the authority field of the message to the gov module address and creates a gov proposal.
func (b *Builder) handleGovProposal(
options *autocliv1.RpcCommandOptions,
cmd *cobra.Command,
input protoreflect.Message,
clientCtx client.Context,
addressCodec addresscodec.Codec,
fd protoreflect.FieldDescriptor,
) error {
govAuthority := authtypes.NewModuleAddress(govtypes.ModuleName)
authority, err := addressCodec.BytesToString(govAuthority.Bytes())
if err != nil {
return fmt.Errorf("failed to convert gov authority: %w", err)
}
input.Set(fd, protoreflect.ValueOfString(authority))

signerFromFlag := clientCtx.GetFromAddress()
signer, err := addressCodec.BytesToString(signerFromFlag.Bytes())
if err != nil {
return fmt.Errorf("failed to set signer on message, got %q: %w", signerFromFlag, err)
}

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

// AutoCLI uses protov2 messages, while the SDK only supports proto v1 messages.
// Here we use dynamicpb, to create a proto v1 compatible message.
// The SDK codec will handle protov2 -> protov1 (marshal)
msg := dynamicpb.NewMessage(input.Descriptor())
proto.Merge(msg, input.Interface())

if err := proposal.SetMsgs([]gogoproto.Message{msg}); err != nil {
return fmt.Errorf("failed to set msg in proposal %w", err)
}

return clienttx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), proposal)
}
39 changes: 38 additions & 1 deletion client/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,29 @@ module cosmossdk.io/client/v2
go 1.21

require (
<<<<<<< HEAD
cosmossdk.io/api v0.7.2
cosmossdk.io/core v0.11.0
cosmossdk.io/depinject v1.0.0-alpha.4
=======
cosmossdk.io/api v0.7.3-0.20231113122742-912390d5fc4a
cosmossdk.io/core v0.12.0
cosmossdk.io/depinject v1.0.0-alpha.4
cosmossdk.io/x/bank v0.0.0-00010101000000-000000000000
cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a
>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))
cosmossdk.io/x/tx v0.12.0
github.com/chzyer/readline v1.5.1 // indirect
github.com/cockroachdb/errors v1.11.1
github.com/cosmos/cosmos-proto v1.0.0-beta.3
<<<<<<< HEAD
github.com/cosmos/cosmos-sdk v0.50.1
github.com/spf13/cobra v1.7.0
=======
github.com/cosmos/cosmos-sdk v0.51.0
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/spf13/cobra v1.8.0
>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))
github.com/spf13/pflag v1.0.5
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
Expand Down Expand Up @@ -44,7 +59,7 @@ require (
github.com/cosmos/cosmos-db v1.0.0 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/gogoproto v1.4.11 // indirect
github.com/cosmos/gogoproto v1.4.11
github.com/cosmos/iavl v1.0.0 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
Expand Down Expand Up @@ -125,10 +140,16 @@ require (
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
<<<<<<< HEAD
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.16.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
=======
github.com/spf13/viper v1.17.0 // indirect
github.com/stretchr/testify v1.8.4
github.com/subosito/gotenv v1.6.0 // indirect
>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
Expand All @@ -152,3 +173,19 @@ require (
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v1.1.0 // indirect
)
<<<<<<< HEAD
=======

replace github.com/cosmos/cosmos-sdk => ./../../

replace (
cosmossdk.io/x/auth => ./../../x/auth
cosmossdk.io/x/bank => ./../../x/bank
cosmossdk.io/x/distribution => ./../../x/distribution
cosmossdk.io/x/gov => ./../../x/gov
cosmossdk.io/x/mint => ./../../x/mint
cosmossdk.io/x/protocolpool => ./../../x/protocolpool
cosmossdk.io/x/slashing => ./../../x/slashing
cosmossdk.io/x/staking => ./../../x/staking
)
>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))
10 changes: 10 additions & 0 deletions client/v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
<<<<<<< HEAD
cosmossdk.io/api v0.7.2 h1:BO3i5fvKMKvfaUiMkCznxViuBEfyWA/k6w2eAF6q1C4=
cosmossdk.io/api v0.7.2/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38=
=======
cosmossdk.io/api v0.7.3-0.20231113122742-912390d5fc4a h1:Zr++x1RCJWi+K8bTZsQKdjtL4SzyHBLGM3Fcn75iWf0=
cosmossdk.io/api v0.7.3-0.20231113122742-912390d5fc4a/go.mod h1:7B/5XWh1HYwJk3DzWeNoxOSI+nGx1m5UyYfHLFuKzkw=
>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo=
Expand Down Expand Up @@ -128,10 +133,14 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
Expand Down Expand Up @@ -1016,6 +1025,7 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
7 changes: 7 additions & 0 deletions client/v2/internal/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ const (

// FlagNoIndent is the flag to not indent the output.
FlagNoIndent = "no-indent"

// FlagNoPrompt is the flag to not use a prompt for commands.
FlagNoPrompt = "no-prompt"

// FlagNoProposal is the flag convert a gov proposal command into a normal command.
// This is used to allow user of chains with custom authority to not use gov submit proposals for usual proposal commands.
FlagNoProposal = "no-proposal"
)

// List of supported output formats
Expand Down
36 changes: 36 additions & 0 deletions client/v2/internal/prompt/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package prompt

import (
"fmt"
"net/url"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// ValidatePromptNotEmpty validates that the input is not empty.
func ValidatePromptNotEmpty(input string) error {
if input == "" {
return fmt.Errorf("input cannot be empty")
}

return nil
}

// ValidatePromptURL validates that the input is a valid URL.
func ValidatePromptURL(input string) error {
_, err := url.ParseRequestURI(input)
if err != nil {
return fmt.Errorf("invalid URL: %w", err)
}

return nil
}

// ValidatePromptCoins validates that the input contains valid sdk.Coins
func ValidatePromptCoins(input string) error {
if _, err := sdk.ParseCoinsNormalized(input); err != nil {
return fmt.Errorf("invalid coins: %w", err)
}

return nil
}
30 changes: 30 additions & 0 deletions client/v2/internal/prompt/validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package prompt_test

import (
"testing"

"github.com/stretchr/testify/require"

"cosmossdk.io/client/v2/internal/prompt"
)

func TestValidatePromptNotEmpty(t *testing.T) {
require := require.New(t)

require.NoError(prompt.ValidatePromptNotEmpty("foo"))
require.ErrorContains(prompt.ValidatePromptNotEmpty(""), "input cannot be empty")
}

func TestValidatePromptURL(t *testing.T) {
require := require.New(t)

require.NoError(prompt.ValidatePromptURL("https://example.com"))
require.ErrorContains(prompt.ValidatePromptURL("foo"), "invalid URL")
}

func TestValidatePromptCoins(t *testing.T) {
require := require.New(t)

require.NoError(prompt.ValidatePromptCoins("100stake"))
require.ErrorContains(prompt.ValidatePromptCoins("foo"), "invalid coins")
}
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ toolchain go1.21.0
module github.com/cosmos/cosmos-sdk

require (
<<<<<<< HEAD
cosmossdk.io/api v0.7.2
=======
cosmossdk.io/api v0.7.3-0.20231113122742-912390d5fc4a
>>>>>>> 9c3386ffd (feat(client/v2): support gov proposals (#18461))
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.11.0
cosmossdk.io/depinject v1.0.0-alpha.4
Expand Down
Loading

0 comments on commit 5fdd53e

Please sign in to comment.