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(client/v2): support gov proposals #18461

Merged
merged 14 commits into from
Nov 15, 2023
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 { // TODO(@julienrbrt) remove and
return fmt.Errorf("invalid address: %w", err)
}

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

<!-- ## [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)).
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
76 changes: 71 additions & 5 deletions client/v2/autocli/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@ 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"
addresscodec "cosmossdk.io/core/address"
authtx "cosmossdk.io/x/auth/tx"
authtxconfig "cosmossdk.io/x/auth/tx/config"

// 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"
"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -111,7 +120,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 +149,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 +187,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 +203,51 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
cmd.SilenceUsage = true
}

// 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, err
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
}

// 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 %v: %w", signerFromFlag, err)
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
}

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)
}
10 changes: 7 additions & 3 deletions client/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ module cosmossdk.io/client/v2
go 1.21

require (
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54
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
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
github.com/cosmos/cosmos-sdk v0.51.0
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
google.golang.org/grpc v1.59.0
Expand Down Expand Up @@ -47,7 +50,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 @@ -132,7 +135,7 @@ require (
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/viper v1.17.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/stretchr/testify v1.8.4
github.com/subosito/gotenv v1.6.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
Expand Down Expand Up @@ -163,6 +166,7 @@ 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
Expand Down
13 changes: 11 additions & 2 deletions client/v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ 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=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54 h1:c7kl5S1ME0q2g/7cdxngOAZr6N/5L7vVibmrmQZrQ0U=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54/go.mod h1:7B/5XWh1HYwJk3DzWeNoxOSI+nGx1m5UyYfHLFuKzkw=
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=
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.12.0 h1:aFuvkG6eDv0IQC+UDjx86wxNWVAxdCFk7OABJ1Vh4RU=
Expand Down Expand Up @@ -128,8 +128,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 @@ -529,6 +535,8 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
Expand Down Expand Up @@ -1008,6 +1016,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 is a valid sdk.Coins
func ValidatePromptCoins(input string) error {
if _, err := sdk.ParseCoinsNormalized(input); err != nil {
return fmt.Errorf("invalid coins: %w", err)
}

return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The new validation functions introduced in the prompt package are well-defined and follow Go's idiomatic error handling. Each function provides a clear error message specific to the validation failure, which is good for debugging and user feedback. The use of %w in fmt.Errorf allows for error wrapping, which is a best practice for error handling in Go as it enables errors to be unwrapped and inspected if needed.

However, it's important to ensure that the error messages are consistent and user-friendly since they might be displayed to the end-user. For example, the message "invalid coins" in ValidatePromptCoins could be more descriptive, explaining what makes the coins invalid.

Additionally, consider adding unit tests for these functions to ensure they handle edge cases correctly, such as inputs with leading or trailing spaces, or unusual characters in URLs.

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")
Comment on lines +18 to +22
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 14, 2023

Choose a reason for hiding this comment

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

The test TestValidatePromptURL is checking for valid URLs. It would be beneficial to include more test cases to cover different types of URLs, including those with query parameters, fragments, and different schemes (http, https).

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

@julienrbrt I have reviewed the issue #17222 on the Cosmos SDK repository. If there are specific actions or changes you would like me to take in relation to this issue, please let me know, and I will be happy to assist.

}

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

require.NoError(prompt.ValidatePromptCoins("100stake"))
require.ErrorContains(prompt.ValidatePromptCoins("foo"), "invalid coins")
Comment on lines +25 to +29
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 14, 2023

Choose a reason for hiding this comment

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

The test TestValidatePromptCoins checks for valid coin input. It would be beneficial to include more test cases to cover various valid and invalid coin formats, such as multiple denominations, invalid characters, and missing amounts.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

@julienrbrt I've reviewed the issue you linked, and it seems to be related to the Cosmos SDK's governance capabilities. However, could you please clarify how this issue relates to the current pull request or the test cases for TestValidatePromptCoins? If there are specific test scenarios derived from this issue that you would like to see included, please let me know, and I'll work on adding those to the test suite.

}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ go 1.21
module github.com/cosmos/cosmos-sdk

require (
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54
cosmossdk.io/api v0.7.3-0.20231113122742-912390d5fc4a
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.12.0
cosmossdk.io/depinject v1.0.0-alpha.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ 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=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54 h1:c7kl5S1ME0q2g/7cdxngOAZr6N/5L7vVibmrmQZrQ0U=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54/go.mod h1:7B/5XWh1HYwJk3DzWeNoxOSI+nGx1m5UyYfHLFuKzkw=
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=
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.12.0 h1:aFuvkG6eDv0IQC+UDjx86wxNWVAxdCFk7OABJ1Vh4RU=
Expand Down
4 changes: 2 additions & 2 deletions simapp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module cosmossdk.io/simapp
go 1.21

require (
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54
cosmossdk.io/api v0.7.3-0.20231113122742-912390d5fc4a
cosmossdk.io/client/v2 v2.0.0-20230630094428-02b760776860
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.12.0
Expand Down Expand Up @@ -40,7 +40,7 @@ require (
cosmossdk.io/x/authz v0.0.0-00010101000000-000000000000
cosmossdk.io/x/bank v0.0.0-00010101000000-000000000000
cosmossdk.io/x/distribution v0.0.0-20230925135524-a1bc045b3190
cosmossdk.io/x/gov v0.0.0-20230925135524-a1bc045b3190
cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a
cosmossdk.io/x/group v0.0.0-00010101000000-000000000000
cosmossdk.io/x/mint v0.0.0-00010101000000-000000000000
cosmossdk.io/x/slashing v0.0.0-00010101000000-000000000000
Expand Down
Loading
Loading