From a527e05a3eba27be9ae21c81f55bc37f5091dfcf Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 4 Oct 2023 14:06:32 +0200 Subject: [PATCH 01/15] feat(client/v2): signing --- CHANGELOG.md | 4 +- client/flags/flags.go | 4 +- client/tx/factory.go | 7 +- client/tx/tx.go | 2 +- client/v2/Makefile | 2 +- client/v2/README.md | 25 +++- client/v2/autocli/app.go | 33 ++--- client/v2/autocli/builder.go | 49 ++++---- client/v2/autocli/common.go | 34 ++++- client/v2/autocli/common_test.go | 29 +++-- client/v2/autocli/flag/address.go | 11 +- client/v2/autocli/flag/builder.go | 119 +++++++++++++----- client/v2/autocli/flag/messager_binder.go | 26 ++-- client/v2/autocli/flags.go | 3 - client/v2/autocli/keyring/interface.go | 17 +++ client/v2/autocli/keyring/no_keyring.go | 24 +++- client/v2/autocli/msg.go | 59 +++++---- client/v2/autocli/query.go | 10 +- .../testdata/help-deprecated-msg.golden | 1 - .../v2/autocli/testdata/help-echo-msg.golden | 1 - client/v2/go.mod | 14 ++- client/v2/go.sum | 52 ++++++-- client/v2/internal/flags/flags.go | 19 +++ codec/bench_test.go | 14 ++- codec/types/any.go | 26 +++- codec/types/interface_registry.go | 2 +- codec/types/util.go | 15 +++ crypto/keyring/autocli.go | 86 +++++++++++++ crypto/keyring/keyring.go | 18 --- simapp/simd/cmd/root.go | 5 +- simapp/simd/cmd/root_v2.go | 19 ++- types/tx_msg.go | 9 +- x/auth/signing/sig_verifiable_tx.go | 2 +- x/bank/types/msgs.go | 6 - 34 files changed, 542 insertions(+), 205 deletions(-) delete mode 100644 client/v2/autocli/flags.go create mode 100644 client/v2/internal/flags/flags.go create mode 100644 codec/types/util.go create mode 100644 crypto/keyring/autocli.go diff --git a/CHANGELOG.md b/CHANGELOG.md index c322f4c07df4..72dc04203087 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* (keyring) [#17913](https://github.com/cosmos/cosmos-sdk/pull/17913) Add `NewAutoCLIKeyring` for creating an AutoCLI keyring from a SDK keyring. +* (codec) [#17913](https://github.com/cosmos/cosmos-sdk/pull/17913) `codectypes.NewAnyWithValue` supports proto v2 messages. * (client) [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503) Add `client.Context{}.WithAddressCodec`, `WithValidatorAddressCodec`, `WithConsensusAddressCodec` to provide address codecs to the client context. See the [UPGRADING.md](./UPGRADING.md) for more details. * (crypto/keyring) [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503) Simplify keyring interfaces to use `[]byte` instead of `sdk.Address` for addresses. * (all) [#16537](https://github.com/cosmos/cosmos-sdk/pull/16537) Properly propagated `fmt.Errorf` errors and using `errors.New` where appropriate. @@ -65,7 +67,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/distribution) [#17657](https://github.com/cosmos/cosmos-sdk/pull/17657) The `FundCommunityPool` and `DistributeFromFeePool` keeper methods are now removed from x/distribution. * (x/distribution) [#17657](https://github.com/cosmos/cosmos-sdk/pull/17657) The distribution module keeper now takes a new argument `PoolKeeper` in addition. * (app) [#17838](https://github.com/cosmos/cosmos-sdk/pull/17838) Params module was removed from simapp and all imports of the params module removed throughout the repo. - * The Cosmos SDK has migrated aay from using params, if you're app still uses it, then you can leave it plugged into your app + * The Cosmos SDK has migrated away from using params, if your app still uses it, then you can leave it plugged into your app * (x/staking) [#17778](https://github.com/cosmos/cosmos-sdk/pull/17778) Use collections for `Params` * remove from `Keeper`: `GetParams`, `SetParams` * (types/simulation) [#17737](https://github.com/cosmos/cosmos-sdk/pull/17737) Remove unused parameter from `RandomFees` diff --git a/client/flags/flags.go b/client/flags/flags.go index e58cabca6389..06458e2d4411 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -117,7 +117,9 @@ func AddQueryFlagsToCmd(cmd *cobra.Command) { func AddTxFlagsToCmd(cmd *cobra.Command) { f := cmd.Flags() f.StringP(FlagOutput, "o", OutputFormatJSON, "Output format (text|json)") - f.String(FlagFrom, "", "Name or address of private key with which to sign") + if cmd.Flag(FlagFrom) == nil { // avoid flag redefinition when it's already been added by AutoCLI + f.String(FlagFrom, "", "Name or address of private key with which to sign") + } f.Uint64P(FlagAccountNumber, "a", 0, "The account number of the signing account (offline mode only)") f.Uint64P(FlagSequence, "s", 0, "The sequence number of the signing account (offline mode only)") f.String(FlagNote, "", "Note to add a description to the transaction (previously --memo)") diff --git a/client/tx/factory.go b/client/tx/factory.go index f21d861f3bb5..81ce5784d5ac 100644 --- a/client/tx/factory.go +++ b/client/tx/factory.go @@ -419,7 +419,12 @@ func (f Factory) BuildSimTx(msgs ...sdk.Msg) ([]byte, error) { return nil, err } - return f.txConfig.TxEncoder()(txb.GetTx()) + encoder := f.txConfig.TxEncoder() + if encoder == nil { + return nil, fmt.Errorf("cannot simulate tx: tx encoder is nil") + } + + return encoder(txb.GetTx()) } // getSimPK gets the public key to use for building a simulation tx. diff --git a/client/tx/tx.go b/client/tx/tx.go index b7c665362358..8d905922cad8 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -107,7 +107,7 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error { txBytes, err := encoder(tx.GetTx()) if err != nil { - return err + return fmt.Errorf("failed to encode transaction: %w", err) } if err := clientCtx.PrintRaw(json.RawMessage(txBytes)); err != nil { diff --git a/client/v2/Makefile b/client/v2/Makefile index 6868d1941a36..1b4bb0cbe7f6 100644 --- a/client/v2/Makefile +++ b/client/v2/Makefile @@ -1,2 +1,2 @@ codegen: - @(cd internal; buf generate) + @(cd internal; buf generate) \ No newline at end of file diff --git a/client/v2/README.md b/client/v2/README.md index 516c7f49569e..e5458ea9a9a5 100644 --- a/client/v2/README.md +++ b/client/v2/README.md @@ -75,7 +75,7 @@ if err := rootCmd.Execute(); err != nil { ### Keyring -`autocli` supports a keyring for key name resolving and signing transactions. Providing a keyring is optional, but if you want to use the `autocli` generated commands to sign transactions, you must provide a keyring. +`autocli` uses a keyring for key name resolving and signing transactions. Providing a keyring is optional, but if you want to use the `autocli` generated commands to sign transactions, you must provide a keyring. :::tip This provides a better UX as it allows to resolve key names directly from the keyring in all transactions and commands. @@ -87,16 +87,23 @@ This provides a better UX as it allows to resolve key names directly from the ke ::: -The keyring to be provided to `client/v2` must match the `client/v2` keyring interface. The Cosmos SDK keyring and Hubl keyring both implement this interface. +The keyring to be provided to `client/v2` must match the `client/v2` keyring interface. The keyring should be provided in the `appOptions` struct as follows, and can be gotten from the client context: +:::tip +The Cosmos SDK keyring and Hubl keyring both implement the `client/v2/autocli/keyring` interface, thanks to the following wrapper: + +```go +keyring.NewAutoCLIKeyring(kb) +``` + +::: + :::warning When using AutoCLI the keyring will only be created once and before any command flag parsing. ::: ```go -// Get the keyring from the client context -keyring := ctx.Keyring // Set the keyring in the appOptions appOptions.Keyring = keyring @@ -104,6 +111,16 @@ err := autoCliOpts.EnhanceRootCommand(rootCmd) ... ``` +## Signing + +`autocli` supports signing transactions with the keyring. +The [`cosmos.msg.v1.signer` protobuf annotation](https://github.com/cosmos/cosmos-sdk/blob/9dd34510e27376005e7e7ff3628eab9dbc8ad6dc/docs/build/building-modules/05-protobuf-annotations.md#L9) defines the signer field of the message. +This field is automatically filled when using the `--from` flag or defining the signer as a positional argument. + +:::warning +AutoCLI currently supports only one signer per transaction. +::: + ## 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. diff --git a/client/v2/autocli/app.go b/client/v2/autocli/app.go index 5133d822c66a..052b660e1573 100644 --- a/client/v2/autocli/app.go +++ b/client/v2/autocli/app.go @@ -11,10 +11,10 @@ import ( "cosmossdk.io/client/v2/autocli/keyring" "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" - "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" + sdkflags "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/x/auth/tx" ) // AppOptions are autocli options for an app. These options can be built via depinject based on an app config. Ex: @@ -28,9 +28,6 @@ import ( type AppOptions struct { depinject.In - // Logger is the logger to use for client/v2. - Logger log.Logger - // Modules are the AppModule implementations for the modules in the app. Modules map[string]appmodule.AppModule @@ -40,11 +37,14 @@ type AppOptions struct { // module or need to be improved. ModuleOptions map[string]*autocliv1.ModuleOptions `optional:"true"` - // ClientCtx contains the necessary information needed to execute the commands. - ClientCtx *client.Context - // Keyring is the keyring to use for client/v2. Keyring keyring.Keyring `optional:"true"` + + // ClientCtx contains the necessary information needed to execute the commands. + ClientCtx client.Context + + // TxConfigOptions are the transactions config options. + TxConfigOpts tx.ConfigOptions } // EnhanceRootCommand enhances the provided root command with autocli AppOptions, @@ -64,18 +64,21 @@ type AppOptions struct { // err = autoCliOpts.EnhanceRootCommand(rootCmd) func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error { builder := &Builder{ - Logger: appOptions.Logger, Builder: flag.Builder{ - TypeResolver: protoregistry.GlobalTypes, - FileResolver: proto.HybridResolver, - ClientCtx: appOptions.ClientCtx, - Keyring: appOptions.Keyring, + TypeResolver: protoregistry.GlobalTypes, + FileResolver: proto.HybridResolver, + Keyring: appOptions.Keyring, + AddressCodec: appOptions.ClientCtx.AddressCodec, + ValidatorAddressCodec: appOptions.ClientCtx.ValidatorAddressCodec, + ConsensusAddressCodec: appOptions.ClientCtx.ConsensusAddressCodec, }, + ClientCtx: appOptions.ClientCtx, + TxConfigOpts: appOptions.TxConfigOpts, GetClientConn: func(cmd *cobra.Command) (grpc.ClientConnInterface, error) { return client.GetClientQueryContext(cmd) }, - AddQueryConnFlags: flags.AddQueryFlagsToCmd, - AddTxConnFlags: flags.AddTxFlagsToCmd, + AddQueryConnFlags: sdkflags.AddQueryFlagsToCmd, + AddTxConnFlags: sdkflags.AddTxFlagsToCmd, } return appOptions.EnhanceRootCommandWithBuilder(rootCmd, builder) diff --git a/client/v2/autocli/builder.go b/client/v2/autocli/builder.go index ef2299d32783..f92147df324b 100644 --- a/client/v2/autocli/builder.go +++ b/client/v2/autocli/builder.go @@ -8,7 +8,9 @@ import ( "cosmossdk.io/client/v2/autocli/flag" "cosmossdk.io/client/v2/autocli/keyring" - "cosmossdk.io/log" + + "github.com/cosmos/cosmos-sdk/client" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" ) // Builder manages options for building CLI commands. @@ -16,13 +18,16 @@ type Builder struct { // flag.Builder embeds the flag builder and its options. flag.Builder - // Logger is the logger used by the builder. - Logger log.Logger - // GetClientConn specifies how CLI commands will resolve a grpc.ClientConnInterface // from a given context. GetClientConn func(*cobra.Command) (grpc.ClientConnInterface, error) + // ClientCtx contains the necessary information needed to execute the commands. + ClientCtx client.Context + + // TxConfigOptions is required to support sign mode textual + TxConfigOpts authtx.ConfigOptions + // AddQueryConnFlags and AddTxConnFlags are functions that add flags to query and transaction commands AddQueryConnFlags func(*cobra.Command) AddTxConnFlags func(*cobra.Command) @@ -33,40 +38,28 @@ type Builder struct { // If the Logger is nil, it will be set to a nop logger. // If the keyring is nil, it will be set to a no keyring. func (b *Builder) ValidateAndComplete() error { - if b.Logger == nil { - b.Logger = log.NewNopLogger() - } - - if b.ClientCtx == nil { - return errors.New("client context is required in builder") - } - - if b.ClientCtx.AddressCodec == nil { - return errors.New("address codec is required in builder") + if b.Builder.AddressCodec == nil { + return errors.New("address codec is required in flag builder") } - if b.ClientCtx.ValidatorAddressCodec == nil { - return errors.New("validator address codec is required in builder") + if b.Builder.ValidatorAddressCodec == nil { + return errors.New("validator address codec is required in flag builder") } - if b.ClientCtx.ConsensusAddressCodec == nil { - return errors.New("consensus address codec is required in builder") + if b.Builder.ConsensusAddressCodec == nil { + return errors.New("consensus address codec is required in flag builder") } - if b.Keyring == nil { - if b.ClientCtx.Keyring != nil { - b.Keyring = b.ClientCtx.Keyring - } else { - b.Keyring = keyring.NoKeyring{} - } + if b.Builder.Keyring == nil { + b.Keyring = keyring.NoKeyring{} } - if b.TypeResolver == nil { - return errors.New("type resolver is required in builder") + if b.Builder.TypeResolver == nil { + return errors.New("type resolver is required in flag builder") } - if b.FileResolver == nil { - return errors.New("file resolver is required in builder") + if b.Builder.FileResolver == nil { + return errors.New("file resolver is required in flag builder") } return nil diff --git a/client/v2/autocli/common.go b/client/v2/autocli/common.go index 480faacd1eb2..f6aa375e0852 100644 --- a/client/v2/autocli/common.go +++ b/client/v2/autocli/common.go @@ -10,9 +10,8 @@ import ( "sigs.k8s.io/yaml" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + "cosmossdk.io/client/v2/internal/flags" "cosmossdk.io/client/v2/internal/util" - - "github.com/cosmos/cosmos-sdk/client/flags" ) type cmdType int @@ -67,6 +66,37 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip return err } + // signer related logic, triggers only when there is a signer defined + if binder.SignerInfo.FieldName != "" { + // mark the signer flag as required if defined + // TODO(@julienrbrt): UX improvement by only marking the flag as required when there is more than one key in the keyring; + // when there is only one key, use that key by default. + if binder.SignerInfo.IsFlag { + if err := cmd.MarkFlagRequired(binder.SignerInfo.FieldName); err != nil { + return err + } + + // the client context uses the from flag to determine the signer. + // this sets the signer flags to the from flag value if a custom signer flag is set. + if binder.SignerInfo.FieldName != flags.FlagFrom { + signer, err := cmd.Flags().GetString(binder.SignerInfo.FieldName) + if err != nil { + return fmt.Errorf("failed to get signer flag: %w", err) + } + + if err := cmd.Flags().Set(flags.FlagFrom, signer); err != nil { + return err + } + } + } else { + // if the signer is not a flag, it is a positional argument + // we need to get the correct positional arguments + if err := cmd.Flags().Set(flags.FlagFrom, args[binder.SignerInfo.PositionalArgIndex]); err != nil { + return err + } + } + } + return exec(cmd, input) } diff --git a/client/v2/autocli/common_test.go b/client/v2/autocli/common_test.go index 5c4e0f322e74..5926941d8bea 100644 --- a/client/v2/autocli/common_test.go +++ b/client/v2/autocli/common_test.go @@ -19,7 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" - "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" ) @@ -47,10 +47,16 @@ func initFixture(t *testing.T) *fixture { clientConn, err := grpc.Dial(listener.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) assert.NilError(t, err) - appCodec := moduletestutil.MakeTestEncodingConfig().Codec - kr, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, home, nil, appCodec) + encodingConfig := moduletestutil.MakeTestEncodingConfig() + kr, err := sdkkeyring.New(sdk.KeyringServiceName(), sdkkeyring.BackendMemory, home, nil, encodingConfig.Codec) assert.NilError(t, err) + akr, err := sdkkeyring.NewAutoCLIKeyring(kr) + assert.NilError(t, err) + + interfaceRegistry := encodingConfig.Codec.InterfaceRegistry() + interfaceRegistry.RegisterInterface(sdk.MsgTypeURL(&testpb.MsgRequest{}), (*sdk.Msg)(nil), &testpb.MsgRequest{}) + var initClientCtx client.Context initClientCtx = initClientCtx. WithAddressCodec(addresscodec.NewBech32Codec("cosmos")). @@ -59,21 +65,28 @@ func initFixture(t *testing.T) *fixture { WithKeyring(kr). WithKeyringDir(home). WithHomeDir(home). - WithViper("") + WithViper(""). + WithInterfaceRegistry(interfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithAccountRetriever(client.MockAccountRetriever{}). + WithChainID("autocli-test") conn := &testClientConn{ClientConn: clientConn} b := &Builder{ Builder: flag.Builder{ - TypeResolver: protoregistry.GlobalTypes, - FileResolver: protoregistry.GlobalFiles, - ClientCtx: &initClientCtx, - Keyring: kr, + TypeResolver: protoregistry.GlobalTypes, + FileResolver: protoregistry.GlobalFiles, + AddressCodec: initClientCtx.AddressCodec, + ValidatorAddressCodec: initClientCtx.ValidatorAddressCodec, + ConsensusAddressCodec: initClientCtx.ConsensusAddressCodec, + Keyring: akr, }, GetClientConn: func(*cobra.Command) (grpc.ClientConnInterface, error) { return conn, nil }, AddQueryConnFlags: flags.AddQueryFlagsToCmd, AddTxConnFlags: flags.AddTxFlagsToCmd, + ClientCtx: initClientCtx, } assert.NilError(t, b.ValidateAndComplete()) diff --git a/client/v2/autocli/flag/address.go b/client/v2/autocli/flag/address.go index 4d61e0f9dd23..ddc7e6bf2c08 100644 --- a/client/v2/autocli/flag/address.go +++ b/client/v2/autocli/flag/address.go @@ -19,7 +19,7 @@ import ( type addressStringType struct{} func (a addressStringType) NewValue(_ context.Context, b *Builder) Value { - return &addressValue{addressCodec: b.ClientCtx.AddressCodec, keyring: b.Keyring} + return &addressValue{addressCodec: b.AddressCodec, keyring: b.Keyring} } func (a addressStringType) DefaultValue() string { @@ -29,7 +29,7 @@ func (a addressStringType) DefaultValue() string { type validatorAddressStringType struct{} func (a validatorAddressStringType) NewValue(_ context.Context, b *Builder) Value { - return &addressValue{addressCodec: b.ClientCtx.ValidatorAddressCodec, keyring: b.Keyring} + return &addressValue{addressCodec: b.ValidatorAddressCodec, keyring: b.Keyring} } func (a validatorAddressStringType) DefaultValue() string { @@ -80,7 +80,12 @@ func (a addressValue) Type() string { type consensusAddressStringType struct{} func (a consensusAddressStringType) NewValue(ctx context.Context, b *Builder) Value { - return &consensusAddressValue{addressValue: addressValue{addressCodec: b.ClientCtx.ConsensusAddressCodec, keyring: b.Keyring}} + return &consensusAddressValue{ + addressValue: addressValue{ + addressCodec: b.ConsensusAddressCodec, + keyring: b.Keyring, + }, + } } func (a consensusAddressStringType) DefaultValue() string { diff --git a/client/v2/autocli/flag/builder.go b/client/v2/autocli/flag/builder.go index a97906029f9b..f0accc2e0971 100644 --- a/client/v2/autocli/flag/builder.go +++ b/client/v2/autocli/flag/builder.go @@ -14,10 +14,13 @@ import ( "google.golang.org/protobuf/reflect/protoregistry" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + msgv1 "cosmossdk.io/api/cosmos/msg/v1" "cosmossdk.io/client/v2/autocli/keyring" + "cosmossdk.io/client/v2/internal/flags" "cosmossdk.io/client/v2/internal/util" + "cosmossdk.io/core/address" - "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/runtime" ) // Builder manages options for building pflag flags for protobuf messages. @@ -39,11 +42,13 @@ type Builder struct { messageFlagTypes map[protoreflect.FullName]Type scalarFlagTypes map[string]Type - // Keyring implementation + // Keyring is the keyring to use for client/v2. Keyring keyring.Keyring - // ClientCtx contains the necessary information needed to execute the commands. - ClientCtx *client.Context + // Address Codecs are the address codecs to use for client/v2. + AddressCodec address.Codec + ValidatorAddressCodec runtime.ValidatorAddressCodec + ConsensusAddressCodec runtime.ConsensusAddressCodec } func (b *Builder) init() { @@ -62,35 +67,48 @@ func (b *Builder) init() { } } +// DefineMessageFlagType allows to extend custom protobuf message type handling for flags (and positional arguments). func (b *Builder) DefineMessageFlagType(messageName protoreflect.FullName, flagType Type) { b.init() b.messageFlagTypes[messageName] = flagType } +// DefineScalarFlagType allows to extend custom scalar type handling for flags (and positional arguments). func (b *Builder) DefineScalarFlagType(scalarName string, flagType Type) { b.init() b.scalarFlagTypes[scalarName] = flagType } +// AddMessageFlags adds flags for each field in the message to the flag set. func (b *Builder) AddMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, messageType protoreflect.MessageType, commandOptions *autocliv1.RpcCommandOptions) (*MessageBinder, error) { return b.addMessageFlags(ctx, flagSet, messageType, commandOptions, namingOptions{}) } -// AddMessageFlags adds flags for each field in the message to the flag set. +// addMessageFlags adds flags for each field in the message to the flag set. func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, messageType protoreflect.MessageType, commandOptions *autocliv1.RpcCommandOptions, options namingOptions) (*MessageBinder, error) { - fields := messageType.Descriptor().Fields() - numFields := fields.Len() - handler := &MessageBinder{ + messageBinder := &MessageBinder{ messageType: messageType, + // positional args are also parsed using a FlagSet so that we can reuse all the same parsers + positionalFlagSet: pflag.NewFlagSet("positional", pflag.ContinueOnError), } + fields := messageType.Descriptor().Fields() + signerFieldName := getSignerFieldName(messageType.Descriptor()) + isPositional := map[string]bool{} - n := len(commandOptions.PositionalArgs) - // positional args are also parsed using a FlagSet so that we can reuse all the same parsers - handler.positionalFlagSet = pflag.NewFlagSet("positional", pflag.ContinueOnError) + + lengthPositionalArgsOptions := len(commandOptions.PositionalArgs) for i, arg := range commandOptions.PositionalArgs { isPositional[arg.ProtoField] = true + // verify if a positional field is a signer field + if arg.ProtoField == signerFieldName { + messageBinder.SignerInfo = SignerInfo{ + PositionalArgIndex: i, + FieldName: arg.ProtoField, + } + } + field := fields.ByName(protoreflect.Name(arg.ProtoField)) if field == nil { return nil, fmt.Errorf("can't find field %s on %s", arg.ProtoField, messageType.Descriptor().FullName()) @@ -101,24 +119,24 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m } if arg.Varargs { - if i != n-1 { + if i != lengthPositionalArgsOptions-1 { return nil, fmt.Errorf("varargs positional argument %s must be the last argument", arg.ProtoField) } - handler.hasVarargs = true + messageBinder.hasVarargs = true } if arg.Optional { - if i != n-1 { + if i != lengthPositionalArgsOptions-1 { return nil, fmt.Errorf("optional positional argument %s must be the last argument", arg.ProtoField) } - handler.hasOptional = true + messageBinder.hasOptional = true } _, hasValue, err := b.addFieldFlag( ctx, - handler.positionalFlagSet, + messageBinder.positionalFlagSet, field, &autocliv1.FlagOptions{Name: fmt.Sprintf("%d", i)}, namingOptions{}, @@ -127,21 +145,21 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m return nil, err } - handler.positionalArgs = append(handler.positionalArgs, fieldBinding{ + messageBinder.positionalArgs = append(messageBinder.positionalArgs, fieldBinding{ field: field, hasValue: hasValue, }) } - if handler.hasVarargs { - handler.CobraArgs = cobra.MinimumNArgs(n - 1) - handler.MandatoryArgUntil = n - 1 - } else if handler.hasOptional { - handler.CobraArgs = cobra.RangeArgs(n-1, n) - handler.MandatoryArgUntil = n - 1 + if messageBinder.hasVarargs { + messageBinder.CobraArgs = cobra.MinimumNArgs(lengthPositionalArgsOptions - 1) + messageBinder.mandatoryArgUntil = lengthPositionalArgsOptions - 1 + } else if messageBinder.hasOptional { + messageBinder.CobraArgs = cobra.RangeArgs(lengthPositionalArgsOptions-1, lengthPositionalArgsOptions) + messageBinder.mandatoryArgUntil = lengthPositionalArgsOptions - 1 } else { - handler.CobraArgs = cobra.ExactArgs(n) - handler.MandatoryArgUntil = n + messageBinder.CobraArgs = cobra.ExactArgs(lengthPositionalArgsOptions) + messageBinder.mandatoryArgUntil = lengthPositionalArgsOptions } // validate flag options @@ -149,12 +167,41 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m if fields.ByName(protoreflect.Name(name)) == nil { return nil, fmt.Errorf("can't find field %s on %s specified as a flag", name, messageType.Descriptor().FullName()) } + + // verify if a flag is a signer field + if name == signerFieldName { + messageBinder.SignerInfo = SignerInfo{ + FieldName: name, + IsFlag: false, + } + } } + // if signer has not been specified as positional arguments, + // add it as `--from` flag (instead of --field-name flags) + if signerFieldName != "" && messageBinder.SignerInfo.FieldName == "" { + if commandOptions.FlagOptions == nil { + commandOptions.FlagOptions = make(map[string]*autocliv1.FlagOptions) + } + + commandOptions.FlagOptions[signerFieldName] = &autocliv1.FlagOptions{ + Name: flags.FlagFrom, + Usage: "Name or address with which to sign the message", + Shorthand: "f", + } + + messageBinder.SignerInfo = SignerInfo{ + FieldName: flags.FlagFrom, + IsFlag: true, + } + } + + // define all other fields as flags flagOptsByFlagName := map[string]*autocliv1.FlagOptions{} - for i := 0; i < numFields; i++ { + for i := 0; i < fields.Len(); i++ { field := fields.Get(i) - if isPositional[string(field.Name())] { + // skips positional args and signer field + if isPositional[string(field.Name())] || string(field.Name()) == signerFieldName { continue } @@ -165,7 +212,7 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m return nil, err } - handler.flagBindings = append(handler.flagBindings, fieldBinding{ + messageBinder.flagBindings = append(messageBinder.flagBindings, fieldBinding{ hasValue: hasValue, field: field, }) @@ -184,7 +231,7 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m } }) - return handler, nil + return messageBinder, nil } // bindPageRequest create a flag for pagination @@ -259,10 +306,11 @@ func (b *Builder) addFieldFlag(ctx context.Context, flagSet *pflag.FlagSet, fiel // This is a bit of hacking around the pflag API, but the // defaultValue is set in this way because this is much easier than trying - // to parse the string into the types that StringSliceP, Int32P, etc. expect + // to parse the string into the types that StringSliceP, Int32P, etc. if defaultValue != "" { err = flagSet.Set(name, defaultValue) } + return name, val, err } @@ -363,3 +411,14 @@ func (b *Builder) resolveFlagTypeBasic(field protoreflect.FieldDescriptor) Type return nil } } + +// getSignerFieldName gets signer field name of a message. +// AutoCLI supports only one signer field per message. +func getSignerFieldName(descriptor protoreflect.MessageDescriptor) string { + signersFields := proto.GetExtension(descriptor.Options(), msgv1.E_Signer).([]string) + if len(signersFields) == 0 { + return "" + } + + return signersFields[0] +} diff --git a/client/v2/autocli/flag/messager_binder.go b/client/v2/autocli/flag/messager_binder.go index 9053e90439bb..ecd822395030 100644 --- a/client/v2/autocli/flag/messager_binder.go +++ b/client/v2/autocli/flag/messager_binder.go @@ -8,15 +8,26 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" ) +// SignerInfo contains information about the signer field. +// That field is special because it needs to be known for signing. +// This struct keeps track of the field name and whether it is a flag. +// IsFlag and PositionalArgIndex are mutually exclusive. +type SignerInfo struct { + PositionalArgIndex int + IsFlag bool + FieldName string +} + // MessageBinder binds multiple flags in a flag set to a protobuf message. type MessageBinder struct { - MandatoryArgUntil int - CobraArgs cobra.PositionalArgs + CobraArgs cobra.PositionalArgs + SignerInfo SignerInfo positionalFlagSet *pflag.FlagSet positionalArgs []fieldBinding hasVarargs bool hasOptional bool + mandatoryArgUntil int flagBindings []fieldBinding messageType protoreflect.MessageType @@ -39,15 +50,14 @@ func (m MessageBinder) Bind(msg protoreflect.Message, positionalArgs []string) e } name := fmt.Sprintf("%d", i) - if i == m.MandatoryArgUntil && m.hasVarargs { + if i == m.mandatoryArgUntil && m.hasVarargs { for _, v := range positionalArgs[i:] { if err := m.positionalFlagSet.Set(name, v); err != nil { return err } } } else { - err := m.positionalFlagSet.Set(name, positionalArgs[i]) - if err != nil { + if err := m.positionalFlagSet.Set(name, positionalArgs[i]); err != nil { return err } } @@ -55,16 +65,14 @@ func (m MessageBinder) Bind(msg protoreflect.Message, positionalArgs []string) e // bind positional arg values to the message for _, arg := range m.positionalArgs { - err := arg.bind(msg) - if err != nil { + if err := arg.bind(msg); err != nil { return err } } // bind flag values to the message for _, binding := range m.flagBindings { - err := binding.bind(msg) - if err != nil { + if err := binding.bind(msg); err != nil { return err } } diff --git a/client/v2/autocli/flags.go b/client/v2/autocli/flags.go deleted file mode 100644 index e6e153fcc6fe..000000000000 --- a/client/v2/autocli/flags.go +++ /dev/null @@ -1,3 +0,0 @@ -package autocli - -var flagNoIndent = "no-indent" diff --git a/client/v2/autocli/keyring/interface.go b/client/v2/autocli/keyring/interface.go index fee5f3434ad3..fa448bd20599 100644 --- a/client/v2/autocli/keyring/interface.go +++ b/client/v2/autocli/keyring/interface.go @@ -1,6 +1,23 @@ package keyring +import ( + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" +) + +// Keyring is an interface used for signing transactions. +// It aims to be simplistic and easy to use. type Keyring interface { + // List returns the names of all keys stored in the keyring. + List() ([]string, error) + // LookupAddressByKeyName returns the address of the key with the given name. LookupAddressByKeyName(name string) ([]byte, error) + + // GetPubKey returns the public key of the key with the given name. + GetPubKey(name string) (cryptotypes.PubKey, error) + + // Sign signs the given bytes with the key with the given name. + Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error) } diff --git a/client/v2/autocli/keyring/no_keyring.go b/client/v2/autocli/keyring/no_keyring.go index 916fff4bd452..e14267cee5e3 100644 --- a/client/v2/autocli/keyring/no_keyring.go +++ b/client/v2/autocli/keyring/no_keyring.go @@ -1,11 +1,31 @@ package keyring -import "errors" +import ( + "errors" + + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" +) var _ Keyring = NoKeyring{} +var errNoKeyring = errors.New("no keyring configured") + type NoKeyring struct{} +func (k NoKeyring) List() ([]string, error) { + return nil, errNoKeyring +} + func (k NoKeyring) LookupAddressByKeyName(name string) ([]byte, error) { - return nil, errors.New("no keyring configured") + return nil, errNoKeyring +} + +func (k NoKeyring) GetPubKey(name string) (cryptotypes.PubKey, error) { + return nil, errNoKeyring +} + +func (k NoKeyring) Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error) { + return nil, errNoKeyring } diff --git a/client/v2/autocli/msg.go b/client/v2/autocli/msg.go index d97786be0519..c014d3aa500d 100644 --- a/client/v2/autocli/msg.go +++ b/client/v2/autocli/msg.go @@ -4,12 +4,20 @@ import ( "context" "fmt" - autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" "github.com/cockroachdb/errors" - "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/types/dynamicpb" + + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + + "github.com/cosmos/cosmos-sdk/client" + clienttx "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + authtxconfig "github.com/cosmos/cosmos-sdk/x/auth/tx/config" ) // BuildMsgCommand builds the msg commands for all the provided modules. If a custom command is provided for a @@ -97,46 +105,43 @@ 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) { - jsonMarshalOptions := protojson.MarshalOptions{ - Indent: " ", - UseProtoNames: true, - UseEnumNumbers: false, - EmitUnpopulated: true, - Resolver: b.TypeResolver, - } - cmd, err := b.buildMethodCommandCommon(descriptor, options, func(cmd *cobra.Command, input protoreflect.Message) error { - if noIdent, _ := cmd.Flags().GetBool(flagNoIndent); noIdent { - jsonMarshalOptions.Indent = "" - } + cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &b.ClientCtx)) - bz, err := jsonMarshalOptions.Marshal(input.Interface()) + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err } - clientCtx, err := client.ReadPersistentCommandFlags(*b.ClientCtx, cmd.Flags()) - if err != nil { - return err - } - - cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)) - if err = client.SetCmdClientContextHandler(clientCtx, cmd); err != nil { - return err - } + // enable sign mode textual and config tx options + b.TxConfigOpts.EnabledSignModes = append(b.TxConfigOpts.EnabledSignModes, signing.SignMode_SIGN_MODE_TEXTUAL) + b.TxConfigOpts.TextualCoinMetadataQueryFn = authtxconfig.NewGRPCCoinMetadataQueryFn(clientCtx) - clientCtx, err = client.GetClientTxContext(cmd) + txConfigWithTextual, err := authtx.NewTxConfigWithOptions( + codec.NewProtoCodec(clientCtx.InterfaceRegistry), + b.TxConfigOpts, + ) if err != nil { return err } + clientCtx = clientCtx.WithTxConfig(txConfigWithTextual) - return b.outOrStdoutFormat(cmd, bz) + // 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()) + + return clienttx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }) if b.AddTxConnFlags != nil { b.AddTxConnFlags(cmd) + } - cmd.Flags().BoolP(flagNoIndent, "", false, "Do not indent JSON output") + // silence usage only for inner txs & queries commands + if cmd != nil { + cmd.SilenceUsage = true } return cmd, err diff --git a/client/v2/autocli/query.go b/client/v2/autocli/query.go index da88d5b0d25a..d35a6e2101a0 100644 --- a/client/v2/autocli/query.go +++ b/client/v2/autocli/query.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/cobra" "google.golang.org/protobuf/reflect/protoreflect" + "cosmossdk.io/client/v2/internal/flags" "cosmossdk.io/client/v2/internal/util" ) @@ -111,7 +112,7 @@ func (b *Builder) BuildQueryMethodCommand(descriptor protoreflect.MethodDescript } cmd, err := b.buildMethodCommandCommon(descriptor, options, func(cmd *cobra.Command, input protoreflect.Message) error { - if noIndent, _ := cmd.Flags().GetBool(flagNoIndent); noIndent { + if noIndent, _ := cmd.Flags().GetBool(flags.FlagNoIndent); noIndent { encoderOptions.Indent = "" } @@ -140,7 +141,12 @@ func (b *Builder) BuildQueryMethodCommand(descriptor protoreflect.MethodDescript if b.AddQueryConnFlags != nil { b.AddQueryConnFlags(cmd) - cmd.Flags().BoolP(flagNoIndent, "", false, "Do not indent JSON output") + cmd.Flags().BoolP(flags.FlagNoIndent, "", false, "Do not indent JSON output") + } + + // silence usage only for inner txs & queries commands + if cmd != nil { + cmd.SilenceUsage = true } return cmd, nil diff --git a/client/v2/autocli/testdata/help-deprecated-msg.golden b/client/v2/autocli/testdata/help-deprecated-msg.golden index 4de93a2d067b..31d61d736cbe 100644 --- a/client/v2/autocli/testdata/help-deprecated-msg.golden +++ b/client/v2/autocli/testdata/help-deprecated-msg.golden @@ -37,7 +37,6 @@ Flags: --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) (default "os") --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used --ledger Use a connected Ledger device - --no-indent Do not indent JSON output --node string : to CometBFT rpc interface for this chain (default "tcp://localhost:26657") --note string Note to add a description to the transaction (previously --memo) --offline Offline mode (does not allow any online functionality) diff --git a/client/v2/autocli/testdata/help-echo-msg.golden b/client/v2/autocli/testdata/help-echo-msg.golden index 7a0905579ad9..0b5e9e69b756 100644 --- a/client/v2/autocli/testdata/help-echo-msg.golden +++ b/client/v2/autocli/testdata/help-echo-msg.golden @@ -41,7 +41,6 @@ Flags: --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) (default "os") --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used --ledger Use a connected Ledger device - --no-indent Do not indent JSON output --node string : to CometBFT rpc interface for this chain (default "tcp://localhost:26657") --note string Note to add a description to the transaction (previously --memo) --offline Offline mode (does not allow any online functionality) diff --git a/client/v2/go.mod b/client/v2/go.mod index e7ac8538e158..011065cb198e 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -3,10 +3,9 @@ module cosmossdk.io/client/v2 go 1.21 require ( - cosmossdk.io/api v0.7.1 + cosmossdk.io/api v0.7.2-0.20230927090904-9dd34510e273 cosmossdk.io/core v0.12.0 cosmossdk.io/depinject v1.0.0-alpha.4 - cosmossdk.io/log v1.2.1 cosmossdk.io/x/tx v0.10.0 github.com/cockroachdb/errors v1.11.1 github.com/cosmos/cosmos-proto v1.0.0-beta.3 @@ -23,6 +22,7 @@ require ( require ( cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/errors v1.0.0 // indirect + cosmossdk.io/log v1.2.1 // indirect cosmossdk.io/math v1.1.3-rc.1 // indirect cosmossdk.io/store v1.0.0-rc.0 // indirect filippo.io/edwards25519 v1.0.0 // indirect @@ -73,6 +73,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/orderedcode v0.0.1 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -95,18 +96,20 @@ require ( github.com/klauspost/compress v1.16.7 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/linxGnu/grocksdb v1.8.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce // indirect github.com/oklog/run v1.1.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.9 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -134,11 +137,12 @@ require ( golang.org/x/crypto v0.13.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/net v0.15.0 // indirect + golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.12.0 // indirect golang.org/x/term v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect @@ -146,3 +150,5 @@ require ( nhooyr.io/websocket v1.8.6 // indirect pgregory.net/rapid v1.1.0 // indirect ) + +replace github.com/cosmos/cosmos-sdk => ./../../ diff --git a/client/v2/go.sum b/client/v2/go.sum index 9244ba7ab9c2..819af0aca15e 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -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.1 h1:PNQ1xN8+/0hj/sSD0ANqjkgfXFys+bZ5L8Hg7uzoUTU= -cosmossdk.io/api v0.7.1/go.mod h1:ure9edhcROIHsngavM6mBLilMGFnfjhV/AaYhEMUkdo= +cosmossdk.io/api v0.7.2-0.20230927090904-9dd34510e273 h1:rNTYK/OQQ5B8jNY0wGSOv+64Fwm7DG8Yke5eRmdTPqk= +cosmossdk.io/api v0.7.2-0.20230927090904-9dd34510e273/go.mod h1:RgzIuGUBiX4E4imKHFyxl+uSKU+qs2v0W2ymVoGoyQQ= 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= @@ -51,6 +51,8 @@ cosmossdk.io/math v1.1.3-rc.1 h1:NebCNWDqb1MJRNfvxr4YY7d8FSYgkuB3L75K6xvM+Zo= cosmossdk.io/math v1.1.3-rc.1/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= cosmossdk.io/store v1.0.0-rc.0 h1:9DwOjuUYxDtYxn/REkTxGQAmxlIGfRroB35MQ8TrxF4= cosmossdk.io/store v1.0.0-rc.0/go.mod h1:FtBDOJmwtOZfmKKF65bKZbTYgS3bDNjjo3nP76dAegk= +cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o= +cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg= cosmossdk.io/x/tx v0.10.0 h1:LxWF/hksVDbeQmFj4voLM5ZCHyVZ1cCNIqKenfH9plc= cosmossdk.io/x/tx v0.10.0/go.mod h1:MKo9/b5wsoL8dd9y9pvD2yOP1CMvzHIWYxi1l2oLPFo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -60,18 +62,26 @@ github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMb github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= +github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -97,6 +107,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.9.0 h1:g1YivPG8jOtrN013Fe8OBXubkiTwvm7/vG2vXz03ANU= +github.com/bits-and-blooms/bitset v1.9.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= @@ -106,6 +118,7 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtyd github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= @@ -151,6 +164,8 @@ github.com/cometbft/cometbft v0.38.0 h1:ogKnpiPX7gxCvqTEF4ly25/wAxUqf181t30P3vqd github.com/cometbft/cometbft v0.38.0/go.mod h1:5Jz0Z8YsHSf0ZaAqGvi/ifioSdVFPtEGrm8Y9T/993k= github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -163,8 +178,6 @@ github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0 github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230915113003-c7e0bd7b54d0 h1:BNa8miwG4Aquqcz7ItXIWCao9e6OM+2HKXAPn96oDO8= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230915113003-c7e0bd7b54d0/go.mod h1:fuDAZLtTNCqYD0tZSJTNkB6DRjqC3t640i4lT6LAWxo= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= @@ -203,6 +216,10 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -461,8 +478,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jhump/protoreflect v1.15.2 h1:7YppbATX94jEt9KLAc5hICx4h6Yt3SaavhQRsIUEHP0= -github.com/jhump/protoreflect v1.15.2/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= +github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= +github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= @@ -594,6 +611,12 @@ github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9 github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -602,14 +625,16 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b h1:vab8deKC4QoIfm9fJM59iuNz1ELGsuLoYYpiF+pHiG8= @@ -688,6 +713,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -837,6 +864,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -916,6 +945,7 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1059,6 +1089,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1136,8 +1168,8 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA= google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44= -google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= +google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= diff --git a/client/v2/internal/flags/flags.go b/client/v2/internal/flags/flags.go new file mode 100644 index 000000000000..cd50a96be87b --- /dev/null +++ b/client/v2/internal/flags/flags.go @@ -0,0 +1,19 @@ +package flags + +// This defines flag names that can be used in autocli. +const ( + // FlagFrom is the flag to set the from address with which to sign the transaction. + FlagFrom = "from" + + // FlagOutput is the flag to set the output format. + FlagOutput = "output" + + // FlagNoIndent is the flag to not indent the output. + FlagNoIndent = "no-indent" +) + +// List of supported output formats +const ( + OutputFormatJSON = "json" + OutputFormatText = "text" +) diff --git a/codec/bench_test.go b/codec/bench_test.go index abbbbfccab24..d5b5fa132dc9 100644 --- a/codec/bench_test.go +++ b/codec/bench_test.go @@ -12,16 +12,26 @@ import ( codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) +type bankSendWrapper struct { + *banktypes.MsgSend +} + +func (msg bankSendWrapper) GetSigners() []sdk.AccAddress { + fromAddress, _ := sdk.AccAddressFromBech32(msg.FromAddress) + return []sdk.AccAddress{fromAddress} +} + func BenchmarkLegacyGetSigners(b *testing.B) { _, _, addr := testdata.KeyTestPubAddr() - msg := &banktypes.MsgSend{ + msg := bankSendWrapper{&banktypes.MsgSend{ FromAddress: addr.String(), ToAddress: "", Amount: nil, - } + }} b.ResetTimer() for i := 0; i < b.N; i++ { diff --git a/codec/types/any.go b/codec/types/any.go index c08b08d855be..ad9ba3bdc48e 100644 --- a/codec/types/any.go +++ b/codec/types/any.go @@ -4,6 +4,7 @@ import ( fmt "fmt" "github.com/cosmos/gogoproto/proto" + protov2 "google.golang.org/protobuf/proto" errorsmod "cosmossdk.io/errors" @@ -62,13 +63,21 @@ func NewAnyWithValue(v proto.Message) (*Any, error) { return nil, errorsmod.Wrap(sdkerrors.ErrPackAny, "Expecting non nil value to create a new Any") } - bz, err := proto.Marshal(v) + var ( + bz []byte + err error + ) + if msg, ok := v.(protov2.Message); ok { + bz, err = protov2.Marshal(msg) + } else { + bz, err = proto.Marshal(v) + } if err != nil { return nil, err } return &Any{ - TypeUrl: "/" + proto.MessageName(v), + TypeUrl: MsgTypeURL(v), Value: bz, cachedValue: v, }, nil @@ -93,8 +102,17 @@ func UnsafePackAny(x interface{}) *Any { // the packed value so that it can be retrieved from GetCachedValue without // unmarshaling func (any *Any) pack(x proto.Message) error { - any.TypeUrl = "/" + proto.MessageName(x) - bz, err := proto.Marshal(x) + any.TypeUrl = MsgTypeURL(x) + + var ( + bz []byte + err error + ) + if msg, ok := x.(protov2.Message); ok { + bz, err = protov2.Marshal(msg) + } else { + bz, err = proto.Marshal(x) + } if err != nil { return err } diff --git a/codec/types/interface_registry.go b/codec/types/interface_registry.go index 4790bf6ef664..99393fa2c57c 100644 --- a/codec/types/interface_registry.go +++ b/codec/types/interface_registry.go @@ -189,7 +189,7 @@ func (registry *interfaceRegistry) EnsureRegistered(impl interface{}) error { // same typeURL. func (registry *interfaceRegistry) RegisterImplementations(iface interface{}, impls ...proto.Message) { for _, impl := range impls { - typeURL := "/" + proto.MessageName(impl) + typeURL := MsgTypeURL(impl) registry.registerImpl(iface, typeURL, impl) } } diff --git a/codec/types/util.go b/codec/types/util.go new file mode 100644 index 000000000000..b29fb33b5034 --- /dev/null +++ b/codec/types/util.go @@ -0,0 +1,15 @@ +package types + +import ( + "github.com/cosmos/gogoproto/proto" + protov2 "google.golang.org/protobuf/proto" +) + +// MsgTypeURL returns the TypeURL of a `sdk.Msg`. +func MsgTypeURL(msg proto.Message) string { + if m, ok := msg.(protov2.Message); ok { + return "/" + string(m.ProtoReflect().Descriptor().FullName()) + } + + return "/" + proto.MessageName(msg) +} diff --git a/crypto/keyring/autocli.go b/crypto/keyring/autocli.go new file mode 100644 index 000000000000..0dd91ff60a43 --- /dev/null +++ b/crypto/keyring/autocli.go @@ -0,0 +1,86 @@ +package keyring + +import ( + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" +) + +// autoCLIKeyring represents the keyring interface used by the AutoCLI. +// It purposely does not import the AutoCLI package to avoid circular dependencies. +type autoCLIKeyring interface { + // List returns the names of all keys stored in the keyring. + List() ([]string, error) + + // LookupAddressByKeyName returns the address of the key with the given name. + LookupAddressByKeyName(name string) ([]byte, error) + + // GetPubKey returns the public key of the key with the given name. + GetPubKey(name string) (cryptotypes.PubKey, error) + + // Sign signs the given bytes with the key with the given name. + Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error) +} + +// NewAutoCLIKeyring wraps the SDK keyring and make it compatible with the AutoCLI keyring interfaces. +func NewAutoCLIKeyring(kr Keyring) (autoCLIKeyring, error) { + return &autoCLIKeyringAdapter{kr}, nil +} + +type autoCLIKeyringAdapter struct { + Keyring +} + +func (a *autoCLIKeyringAdapter) List() ([]string, error) { + list, err := a.Keyring.List() + if err != nil { + return nil, err + } + + names := make([]string, len(list)) + for i, key := range list { + names[i] = key.Name + } + + return names, nil +} + +// LookupAddressByKeyName returns the address of a key stored in the keyring +func (a *autoCLIKeyringAdapter) LookupAddressByKeyName(name string) ([]byte, error) { + record, err := a.Keyring.Key(name) + if err != nil { + return nil, err + } + + addr, err := record.GetAddress() + if err != nil { + return nil, err + } + + return addr, nil +} + +func (a *autoCLIKeyringAdapter) GetPubKey(name string) (cryptotypes.PubKey, error) { + record, err := a.Keyring.Key(name) + if err != nil { + return nil, err + } + + return record.GetPubKey() +} + +func (a *autoCLIKeyringAdapter) Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error) { + record, err := a.Keyring.Key(name) + if err != nil { + return nil, err + } + + sdkSignMode, err := authsigning.APISignModeToInternal(signMode) + if err != nil { + return nil, err + } + + signBytes, _, err := a.Keyring.Sign(record.Name, msg, sdkSignMode) + return signBytes, err +} diff --git a/crypto/keyring/keyring.go b/crypto/keyring/keyring.go index 91004aa91a45..2e92c484254e 100644 --- a/crypto/keyring/keyring.go +++ b/crypto/keyring/keyring.go @@ -102,9 +102,6 @@ type Keyring interface { Exporter Migrator - - // Implements client/v2 keyring interface - LookupAddressByKeyName(name string) ([]byte, error) } // Signer is implemented by key stores that want to provide signing capabilities. @@ -622,21 +619,6 @@ func (ks keystore) SupportedAlgorithms() (SigningAlgoList, SigningAlgoList) { return ks.options.SupportedAlgos, ks.options.SupportedAlgosLedger } -// LookupAddressByKeyName returns the address of a key stored in the keyring -func (ks keystore) LookupAddressByKeyName(name string) ([]byte, error) { - record, err := ks.Key(name) - if err != nil { - return nil, err - } - - addr, err := record.GetAddress() - if err != nil { - return nil, err - } - - return addr, nil -} - // SignWithLedger signs a binary message with the ledger device referenced by an Info object // and returns the signed bytes and the public key. It returns an error if the device could // not be queried or it returned an error. diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 6678166ad5ce..1b8291367900 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/codec" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" @@ -109,8 +110,8 @@ func NewRootCmd() *cobra.Command { } autoCliOpts := tempApp.AutoCliOpts() - autoCliOpts.Keyring = initClientCtx.Keyring - autoCliOpts.ClientCtx = &initClientCtx + autoCliOpts.Keyring, _ = keyring.NewAutoCLIKeyring(initClientCtx.Keyring) + autoCliOpts.ClientCtx = initClientCtx if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil { panic(err) diff --git a/simapp/simd/cmd/root_v2.go b/simapp/simd/cmd/root_v2.go index d22230b0face..170aa94b0fba 100644 --- a/simapp/simd/cmd/root_v2.go +++ b/simapp/simd/cmd/root_v2.go @@ -18,6 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/server" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" @@ -34,7 +35,7 @@ func NewRootCmd() *cobra.Command { txConfigOpts tx.ConfigOptions autoCliOpts autocli.AppOptions moduleBasicManager module.BasicManager - initClientCtx *client.Context + clientCtx client.Context ) if err := depinject.Inject( @@ -51,7 +52,7 @@ func NewRootCmd() *cobra.Command { &txConfigOpts, &autoCliOpts, &moduleBasicManager, - &initClientCtx, + &clientCtx, ); err != nil { panic(err) } @@ -65,7 +66,6 @@ func NewRootCmd() *cobra.Command { cmd.SetOut(cmd.OutOrStdout()) cmd.SetErr(cmd.ErrOrStderr()) - clientCtx := *initClientCtx clientCtx = clientCtx.WithCmdContext(cmd.Context()) clientCtx, err := client.ReadPersistentCommandFlags(clientCtx, cmd.Flags()) if err != nil { @@ -89,7 +89,6 @@ func NewRootCmd() *cobra.Command { return err } clientCtx = clientCtx.WithTxConfig(txConfigWithTextual) - if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil { return err } @@ -101,7 +100,7 @@ func NewRootCmd() *cobra.Command { }, } - initRootCmd(rootCmd, initClientCtx.TxConfig, initClientCtx.InterfaceRegistry, initClientCtx.Codec, moduleBasicManager) + initRootCmd(rootCmd, clientCtx.TxConfig, clientCtx.InterfaceRegistry, clientCtx.Codec, moduleBasicManager) if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil { panic(err) @@ -118,7 +117,7 @@ func ProvideClientContext( addressCodec address.Codec, validatorAddressCodec runtime.ValidatorAddressCodec, consensusAddressCodec runtime.ConsensusAddressCodec, -) *client.Context { +) client.Context { var err error clientCtx := client.Context{}. @@ -141,14 +140,14 @@ func ProvideClientContext( panic(err) } - return &clientCtx + return clientCtx } -func ProvideKeyring(clientCtx *client.Context, addressCodec address.Codec) (clientv2keyring.Keyring, error) { - kb, err := client.NewKeyringFromBackend(*clientCtx, clientCtx.Keyring.Backend()) +func ProvideKeyring(clientCtx client.Context, addressCodec address.Codec) (clientv2keyring.Keyring, error) { + kb, err := client.NewKeyringFromBackend(clientCtx, clientCtx.Keyring.Backend()) if err != nil { return nil, err } - return kb, nil + return keyring.NewAutoCLIKeyring(kb) } diff --git a/types/tx_msg.go b/types/tx_msg.go index 230092ad2181..399dafd4cc43 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -9,6 +9,7 @@ import ( protov2 "google.golang.org/protobuf/proto" "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) @@ -95,13 +96,7 @@ type TxDecoder func(txBytes []byte) (Tx, error) type TxEncoder func(tx Tx) ([]byte, error) // MsgTypeURL returns the TypeURL of a `sdk.Msg`. -func MsgTypeURL(msg proto.Message) string { - if m, ok := msg.(protov2.Message); ok { - return "/" + string(m.ProtoReflect().Descriptor().FullName()) - } - - return "/" + proto.MessageName(msg) -} +var MsgTypeURL = codectypes.MsgTypeURL // GetMsgFromTypeURL returns a `sdk.Msg` message type from a type URL func GetMsgFromTypeURL(cdc codec.Codec, input string) (Msg, error) { diff --git a/x/auth/signing/sig_verifiable_tx.go b/x/auth/signing/sig_verifiable_tx.go index 0b6da14aff50..c8a752e7e475 100644 --- a/x/auth/signing/sig_verifiable_tx.go +++ b/x/auth/signing/sig_verifiable_tx.go @@ -16,7 +16,7 @@ type SigVerifiableTx interface { } // Tx defines a transaction interface that supports all standard message, signature -// fee, memo, tips, and auxiliary interfaces. +// fee, memo and auxiliary interfaces. type Tx interface { SigVerifiableTx diff --git a/x/bank/types/msgs.go b/x/bank/types/msgs.go index 9ce68e48344d..05a23c280e2b 100644 --- a/x/bank/types/msgs.go +++ b/x/bank/types/msgs.go @@ -15,12 +15,6 @@ func NewMsgSend(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins) *MsgSend { return &MsgSend{FromAddress: fromAddr.String(), ToAddress: toAddr.String(), Amount: amount} } -// GetSigners Implements Msg. -func (msg MsgSend) GetSigners() []sdk.AccAddress { - fromAddress, _ := sdk.AccAddressFromBech32(msg.FromAddress) - return []sdk.AccAddress{fromAddress} -} - // NewMsgMultiSend - construct arbitrary multi-in, multi-out send msg. func NewMsgMultiSend(in Input, out []Output) *MsgMultiSend { return &MsgMultiSend{Inputs: []Input{in}, Outputs: out} From 77f5068ed453c5106754b619d64a1fc504a0c26b Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 4 Oct 2023 16:00:11 +0200 Subject: [PATCH 02/15] fix tests --- client/v2/autocli/common_test.go | 86 +++++- client/v2/autocli/msg.go | 1 + client/v2/autocli/msg_test.go | 285 ++---------------- client/v2/autocli/query_test.go | 6 +- .../testdata/help-deprecated-msg.golden | 64 ---- .../v2/autocli/testdata/help-echo-msg.golden | 90 ++---- .../autocli/testdata/help-toplevel-msg.golden | 12 +- client/v2/autocli/testdata/msg-output.golden | 1 + client/v2/go.mod | 1 + client/v2/go.sum | 4 + 10 files changed, 150 insertions(+), 400 deletions(-) delete mode 100644 client/v2/autocli/testdata/help-deprecated-msg.golden create mode 100644 client/v2/autocli/testdata/msg-output.golden diff --git a/client/v2/autocli/common_test.go b/client/v2/autocli/common_test.go index 5926941d8bea..f1472d486b7e 100644 --- a/client/v2/autocli/common_test.go +++ b/client/v2/autocli/common_test.go @@ -12,6 +12,7 @@ import ( "google.golang.org/protobuf/reflect/protoregistry" "gotest.tools/v3/assert" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv2alpha1 "cosmossdk.io/api/cosmos/base/reflection/v2alpha1" "cosmossdk.io/client/v2/autocli/flag" "cosmossdk.io/client/v2/internal/testpb" @@ -22,6 +23,8 @@ import ( sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/bank" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) type fixture struct { @@ -47,7 +50,7 @@ func initFixture(t *testing.T) *fixture { clientConn, err := grpc.Dial(listener.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) assert.NilError(t, err) - encodingConfig := moduletestutil.MakeTestEncodingConfig() + encodingConfig := moduletestutil.MakeTestEncodingConfig(bank.AppModuleBasic{}) kr, err := sdkkeyring.New(sdk.KeyringServiceName(), sdkkeyring.BackendMemory, home, nil, encodingConfig.Codec) assert.NilError(t, err) @@ -55,7 +58,7 @@ func initFixture(t *testing.T) *fixture { assert.NilError(t, err) interfaceRegistry := encodingConfig.Codec.InterfaceRegistry() - interfaceRegistry.RegisterInterface(sdk.MsgTypeURL(&testpb.MsgRequest{}), (*sdk.Msg)(nil), &testpb.MsgRequest{}) + banktypes.RegisterInterfaces(interfaceRegistry) var initClientCtx client.Context initClientCtx = initClientCtx. @@ -144,3 +147,82 @@ func (t testEchoServer) Echo(_ context.Context, request *testpb.EchoRequest) (*t } var _ testpb.QueryServer = testEchoServer{} + +func TestEnhanceCommand(t *testing.T) { + b := &Builder{} + // Test that the command has a subcommand + cmd := &cobra.Command{Use: "test"} + cmd.AddCommand(&cobra.Command{Use: "test"}) + + for i := 0; i < 2; i++ { + cmdTp := cmdType(i) + + appOptions := AppOptions{ + ModuleOptions: map[string]*autocliv1.ModuleOptions{ + "test": {}, + }, + } + + err := b.enhanceCommandCommon(cmd, cmdTp, appOptions, map[string]*cobra.Command{}) + assert.NilError(t, err) + + cmd = &cobra.Command{Use: "test"} + + appOptions = AppOptions{ + ModuleOptions: map[string]*autocliv1.ModuleOptions{}, + } + customCommands := map[string]*cobra.Command{ + "test2": {Use: "test"}, + } + err = b.enhanceCommandCommon(cmd, cmdTp, appOptions, customCommands) + assert.NilError(t, err) + + cmd = &cobra.Command{Use: "test"} + appOptions = AppOptions{ + ModuleOptions: map[string]*autocliv1.ModuleOptions{ + "test": {Tx: nil}, + }, + } + err = b.enhanceCommandCommon(cmd, cmdTp, appOptions, map[string]*cobra.Command{}) + assert.NilError(t, err) + } +} + +func TestErrorBuildCommand(t *testing.T) { + fixture := initFixture(t) + b := fixture.b + b.AddQueryConnFlags = nil + b.AddTxConnFlags = nil + + commandDescriptor := &autocliv1.ServiceCommandDescriptor{ + Service: testpb.Msg_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Send", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + { + ProtoField: "un-existent-proto-field", + }, + }, + }, + }, + } + + appOptions := AppOptions{ + ModuleOptions: map[string]*autocliv1.ModuleOptions{ + "test": { + Query: commandDescriptor, + Tx: commandDescriptor, + }, + }, + ClientCtx: b.ClientCtx, + } + + _, err := b.BuildMsgCommand(appOptions, nil) + assert.ErrorContains(t, err, "can't find field un-existent-proto-field") + + appOptions.ModuleOptions["test"].Tx = &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"} + appOptions.ModuleOptions["test"].Query = &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"} + _, err = b.BuildMsgCommand(appOptions, nil) + assert.ErrorContains(t, err, "can't find service un-existent-service") +} diff --git a/client/v2/autocli/msg.go b/client/v2/autocli/msg.go index c014d3aa500d..a2bd5eb9051a 100644 --- a/client/v2/autocli/msg.go +++ b/client/v2/autocli/msg.go @@ -125,6 +125,7 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor return err } clientCtx = clientCtx.WithTxConfig(txConfigWithTextual) + clientCtx.Output = cmd.OutOrStdout() // AutoCLI uses protov2 messages, while the SDK only supports proto v1 messages. // Here we use dynamicpb, to create a proto v1 compatible message. diff --git a/client/v2/autocli/msg_test.go b/client/v2/autocli/msg_test.go index 74d72933183a..86d328aaa4a6 100644 --- a/client/v2/autocli/msg_test.go +++ b/client/v2/autocli/msg_test.go @@ -2,135 +2,45 @@ package autocli import ( "fmt" - "strings" "testing" "github.com/spf13/cobra" - "google.golang.org/protobuf/encoding/protojson" "gotest.tools/v3/assert" "gotest.tools/v3/golden" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1" "cosmossdk.io/client/v2/internal/testpb" ) var buildModuleMsgCommand = func(moduleName string, b *Builder) (*cobra.Command, error) { cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName)) - err := b.AddMsgServiceCommands(cmd, testCmdMsgDesc) + err := b.AddMsgServiceCommands(cmd, bankAutoCLI) return cmd, err } -var testCmdMsgDesc = &autocliv1.ServiceCommandDescriptor{ - Service: testpb.Msg_ServiceDesc.ServiceName, +var bankAutoCLI = &autocliv1.ServiceCommandDescriptor{ + Service: bankv1beta1.Msg_ServiceDesc.ServiceName, RpcCommandOptions: []*autocliv1.RpcCommandOptions{ { - RpcMethod: "Send", - Use: "send [pos1] [pos2] [pos3...]", - Version: "1.0", - Alias: []string{"s"}, - SuggestFor: []string{"send"}, - Example: "send 1 abc {}", - Short: "send msg the value provided by the user", - Long: "send msg the value provided by the user as a proto JSON object with populated with the provided fields and positional arguments", - PositionalArgs: []*autocliv1.PositionalArgDescriptor{ - { - ProtoField: "positional1", - }, - { - ProtoField: "positional2", - }, - { - ProtoField: "positional3_varargs", - Varargs: true, - }, - }, - FlagOptions: map[string]*autocliv1.FlagOptions{ - "u32": { - Name: "uint32", - Shorthand: "u", - Usage: "some random uint32", - }, - "i32": { - Usage: "some random int32", - DefaultValue: "3", - }, - "u64": { - Usage: "some random uint64", - DefaultValue: "5", - }, - "deprecated_field": { - Deprecated: "don't use this", - }, - "shorthand_deprecated_field": { - Shorthand: "d", - Deprecated: "bad idea", - }, - "hidden_bool": { - Hidden: true, - }, - }, - }, - }, - SubCommands: map[string]*autocliv1.ServiceCommandDescriptor{ - // we test the sub-command functionality using the same service with different options - "deprecatedmsg": { - Service: testpb.Msg_ServiceDesc.ServiceName, - RpcCommandOptions: []*autocliv1.RpcCommandOptions{ - { - RpcMethod: "Send", - Deprecated: "dont use this", - Short: "deprecated subcommand", - }, - }, - }, - "skipmsg": { - Service: testpb.Msg_ServiceDesc.ServiceName, - RpcCommandOptions: []*autocliv1.RpcCommandOptions{ - { - RpcMethod: "Send", - Skip: true, - Short: "skip subcommand", - }, - }, + RpcMethod: "Send", + Use: "send [from_key_or_address] [to_address] [amount] [flags]", + Short: "Send coins from one account to another", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "from_address"}, {ProtoField: "to_address"}, {ProtoField: "amount"}}, }, }, + EnhanceCustomCommand: true, } -func TestMsgOptions(t *testing.T) { +func TestMsg(t *testing.T) { fixture := initFixture(t) out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send", - "5", "6", "1foo", - "--uint32", "7", - "--u64", "8", - "--output", "json", - ) - assert.NilError(t, err) - - response := out.String() - var output testpb.MsgRequest - err = protojson.Unmarshal([]byte(response), &output) - assert.NilError(t, err) - assert.Equal(t, output.GetU32(), uint32(7)) - assert.Equal(t, output.GetPositional1(), int32(5)) - assert.Equal(t, output.GetPositional2(), "6") -} - -func TestMsgOutputFormat(t *testing.T) { - fixture := initFixture(t) - - out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, - "send", "5", "6", "1foo", + "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo", + "--generate-only", "--output", "json", ) assert.NilError(t, err) - assert.Assert(t, strings.Contains(out.String(), "{")) - - out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, - "send", "5", "6", "1foo", - "--output", "text", - ) - assert.NilError(t, err) - assert.Assert(t, strings.Contains(out.String(), "positional1: 5")) + golden.Assert(t, out.String(), "msg-output.golden") } func TestMsgOptionsError(t *testing.T) { @@ -138,92 +48,13 @@ func TestMsgOptionsError(t *testing.T) { _, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send", "5", - "--uint32", "7", - "--u64", "8", ) - assert.ErrorContains(t, err, "requires at least 2 arg(s)") + assert.ErrorContains(t, err, "accepts 3 arg(s)") _, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, - "send", "5", "6", `{"denom":"foo","amount":"1"}`, - "--uint32", "7", - "--u64", "abc", + "send", "foo", "bar", "invalid", ) - assert.ErrorContains(t, err, "invalid argument ") -} - -func TestDeprecatedMsg(t *testing.T) { - fixture := initFixture(t) - - out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, - "send", "1", "abc", "--deprecated-field", "foo", - ) - assert.NilError(t, err) - assert.Assert(t, strings.Contains(out.String(), "--deprecated-field has been deprecated")) - - out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, - "send", "1", "abc", "5stake", "-d", "foo", - ) - assert.NilError(t, err) - assert.Assert(t, strings.Contains(out.String(), "--shorthand-deprecated-field has been deprecated")) -} - -func TestEverythingMsg(t *testing.T) { - fixture := initFixture(t) - - out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, - "send", - "1", - "abc", - "1234foo", - "4321foo", - "--output", "json", - "--a-bool", - "--an-enum", "two", - "--a-message", `{"bar":"abc", "baz":-3}`, - "--duration", "4h3s", - "--uint32", "27", - "--u64", "3267246890", - "--i32", "-253", - "--i64", "-234602347", - "--str", "def", - "--timestamp", "2019-01-02T00:01:02Z", - "--a-coin", "10000000foo", - "--an-address", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", - "--bz", "c2RncXdlZndkZ3NkZw==", - "--page-count-total", - "--page-key", "MTIzNTQ4N3NnaGRhcw==", - "--page-limit", "1000", - "--page-offset", "10", - "--page-reverse", - "--bools", "true", - "--bools", "false,false,true", - "--enums", "one", - "--enums", "five", - "--enums", "two", - "--strings", "abc", - "--strings", "xyz", - "--strings", "xyz,qrs", - "--durations", "3s", - "--durations", "5s", - "--durations", "10h", - "--some-messages", "{}", - "--some-messages", `{"bar":"baz"}`, - "--some-messages", `{"baz":-1}`, - "--uints", "1,2,3", - "--uints", "4", - ) - assert.NilError(t, err) - - response := out.String() - var output testpb.MsgRequest - err = protojson.Unmarshal([]byte(response), &output) - assert.NilError(t, err) - assert.Equal(t, output.GetU32(), uint32(27)) - assert.Equal(t, output.GetU64(), uint64(3267246890)) - assert.Equal(t, output.GetPositional1(), int32(1)) - assert.Equal(t, output.GetPositional2(), "abc") - assert.Equal(t, output.GetABool(), true) - assert.Equal(t, output.GetAnEnum(), testpb.Enum_ENUM_TWO) + assert.ErrorContains(t, err, "invalid argument") } func TestHelpMsg(t *testing.T) { @@ -236,19 +67,18 @@ func TestHelpMsg(t *testing.T) { out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send", "-h") assert.NilError(t, err) golden.Assert(t, out.String(), "help-echo-msg.golden") - - out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "deprecatedmsg", "send", "-h") - assert.NilError(t, err) - golden.Assert(t, out.String(), "help-deprecated-msg.golden") } -func TestBuildMsgCommand(t *testing.T) { +func TestBuildCustomMsgCommand(t *testing.T) { b := &Builder{} customCommandCalled := false appOptions := AppOptions{ ModuleOptions: map[string]*autocliv1.ModuleOptions{ "test": { - Tx: testCmdMsgDesc, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: testpb.Msg_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{}, + }, }, }, } @@ -264,44 +94,6 @@ func TestBuildMsgCommand(t *testing.T) { assert.Assert(t, customCommandCalled) } -func TestErrorBuildMsgCommand(t *testing.T) { - fixture := initFixture(t) - b := fixture.b - b.AddQueryConnFlags = nil - b.AddTxConnFlags = nil - - commandDescriptor := &autocliv1.ServiceCommandDescriptor{ - Service: testpb.Msg_ServiceDesc.ServiceName, - RpcCommandOptions: []*autocliv1.RpcCommandOptions{ - { - RpcMethod: "Send", - PositionalArgs: []*autocliv1.PositionalArgDescriptor{ - { - ProtoField: "un-existent-proto-field", - }, - }, - }, - }, - } - - appOptions := AppOptions{ - ModuleOptions: map[string]*autocliv1.ModuleOptions{ - "test": { - Tx: commandDescriptor, - }, - }, - ClientCtx: b.ClientCtx, - } - - _, err := b.BuildMsgCommand(appOptions, nil) - assert.ErrorContains(t, err, "can't find field un-existent-proto-field") - - nonExistentService := &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"} - appOptions.ModuleOptions["test"].Tx = nonExistentService - _, err = b.BuildMsgCommand(appOptions, nil) - assert.ErrorContains(t, err, "can't find service un-existent-service") -} - func TestNotFoundErrorsMsg(t *testing.T) { fixture := initFixture(t) b := fixture.b @@ -353,38 +145,3 @@ func TestNotFoundErrorsMsg(t *testing.T) { }) assert.ErrorContains(t, err, "can't find field un-existent-flag") } - -func TestEnhanceMessageCommand(t *testing.T) { - b := &Builder{} - // Test that the command has a subcommand - cmd := &cobra.Command{Use: "test"} - cmd.AddCommand(&cobra.Command{Use: "test"}) - - appOptions := AppOptions{ - ModuleOptions: map[string]*autocliv1.ModuleOptions{ - "test": {}, - }, - } - - err := b.enhanceCommandCommon(cmd, msgCmdType, appOptions, map[string]*cobra.Command{}) - assert.NilError(t, err) - - cmd = &cobra.Command{Use: "test"} - - appOptions.ModuleOptions = map[string]*autocliv1.ModuleOptions{} - customCommands := map[string]*cobra.Command{ - "test2": {Use: "test"}, - } - err = b.enhanceCommandCommon(cmd, msgCmdType, appOptions, customCommands) - assert.NilError(t, err) - - cmd = &cobra.Command{Use: "test"} - appOptions = AppOptions{ - ModuleOptions: map[string]*autocliv1.ModuleOptions{ - "test": {Tx: nil}, - }, - } - customCommands = map[string]*cobra.Command{} - err = b.enhanceCommandCommon(cmd, msgCmdType, appOptions, customCommands) - assert.NilError(t, err) -} diff --git a/client/v2/autocli/query_test.go b/client/v2/autocli/query_test.go index bc556af268a6..b1945f83995a 100644 --- a/client/v2/autocli/query_test.go +++ b/client/v2/autocli/query_test.go @@ -613,7 +613,7 @@ func TestOutputFormat(t *testing.T) { assert.Assert(t, strings.Contains(out.String(), " positional1: 1")) } -func TestHelp(t *testing.T) { +func TestHelpQuery(t *testing.T) { fixture := initFixture(t) out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "-h") @@ -633,7 +633,7 @@ func TestHelp(t *testing.T) { golden.Assert(t, out.String(), "help-skip.golden") } -func TestDeprecated(t *testing.T) { +func TestDeprecatedQuery(t *testing.T) { fixture := initFixture(t) out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "echo", @@ -670,7 +670,7 @@ func TestBuildCustomQueryCommand(t *testing.T) { assert.Assert(t, customCommandCalled) } -func TestNotFoundErrors(t *testing.T) { +func TestNotFoundErrorsQuery(t *testing.T) { fixture := initFixture(t) b := fixture.b b.AddQueryConnFlags = nil diff --git a/client/v2/autocli/testdata/help-deprecated-msg.golden b/client/v2/autocli/testdata/help-deprecated-msg.golden deleted file mode 100644 index 31d61d736cbe..000000000000 --- a/client/v2/autocli/testdata/help-deprecated-msg.golden +++ /dev/null @@ -1,64 +0,0 @@ -Command "send" is deprecated, dont use this -deprecated subcommand - -Usage: - test deprecatedmsg send [flags] - -Flags: - --a-bool - --a-coin cosmos.base.v1beta1.Coin - --a-message testpb.AMessage (json) - --a-validator-address account address or key name - -a, --account-number uint The account number of the signing account (offline mode only) - --an-address account address or key name - --an-enum Enum (unspecified | one | two | five | neg-three) (default unspecified) - --aux Generate aux signer data instead of sending a tx - --bools bools (default []) - -b, --broadcast-mode string Transaction broadcasting mode (sync|async) (default "sync") - --bz binary - --chain-id string The network chain ID - --deprecated-field string - --dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible) - --duration duration - --durations duration (repeated) - --enums Enum (unspecified | one | two | five | neg-three) (repeated) - --fee-granter string Fee granter grants fees for the transaction - --fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer - --fees string Fees to pay along with transaction; eg: 10uatom - --from string Name or address of private key with which to sign - --gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000) - --gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1) - --gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom) - --generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name) - -h, --help help for send - --hidden-bool - --i32 int32 - --i64 int - --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) (default "os") - --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used - --ledger Use a connected Ledger device - --node string : to CometBFT rpc interface for this chain (default "tcp://localhost:26657") - --note string Note to add a description to the transaction (previously --memo) - --offline Offline mode (does not allow any online functionality) - -o, --output string Output format (text|json) (default "json") - --page-count-total - --page-key binary - --page-limit uint - --page-offset uint - --page-reverse - --positional1 int32 - --positional2 string - --positional3-varargs cosmos.base.v1beta1.Coin (repeated) - -s, --sequence uint The sequence number of the signing account (offline mode only) - --shorthand-deprecated-field string - --sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature - --some-messages testpb.AMessage (json) (repeated) - --str string - --strings strings - --timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height - --timestamp timestamp (RFC 3339) - --tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator - --u32 uint32 - --u64 uint - --uints uints (default []) - -y, --yes Skip tx broadcasting prompt confirmation diff --git a/client/v2/autocli/testdata/help-echo-msg.golden b/client/v2/autocli/testdata/help-echo-msg.golden index 0b5e9e69b756..e082cd565f71 100644 --- a/client/v2/autocli/testdata/help-echo-msg.golden +++ b/client/v2/autocli/testdata/help-echo-msg.golden @@ -1,66 +1,32 @@ -send msg the value provided by the user as a proto JSON object with populated with the provided fields and positional arguments +Send coins from one account to another Usage: - test send [pos1] [pos2] [pos3...] [flags] - -Aliases: - send, s - -Examples: -send 1 abc {} + test send [from_key_or_address] [to_address] [amount] [flags] Flags: - --a-bool - --a-coin cosmos.base.v1beta1.Coin - --a-message testpb.AMessage (json) - --a-validator-address account address or key name - -a, --account-number uint The account number of the signing account (offline mode only) - --an-address account address or key name - --an-enum Enum (unspecified | one | two | five | neg-three) (default unspecified) - --aux Generate aux signer data instead of sending a tx - --bools bools (default []) - -b, --broadcast-mode string Transaction broadcasting mode (sync|async) (default "sync") - --bz binary - --chain-id string The network chain ID - --deprecated-field string (DEPRECATED: don't use this) - --dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible) - --duration duration - --durations duration (repeated) - --enums Enum (unspecified | one | two | five | neg-three) (repeated) - --fee-granter string Fee granter grants fees for the transaction - --fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer - --fees string Fees to pay along with transaction; eg: 10uatom - --from string Name or address of private key with which to sign - --gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000) - --gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1) - --gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom) - --generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name) - -h, --help help for send - --i32 int32 some random int32 - --i64 int - --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) (default "os") - --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used - --ledger Use a connected Ledger device - --node string : to CometBFT rpc interface for this chain (default "tcp://localhost:26657") - --note string Note to add a description to the transaction (previously --memo) - --offline Offline mode (does not allow any online functionality) - -o, --output string Output format (text|json) (default "json") - --page-count-total - --page-key binary - --page-limit uint - --page-offset uint - --page-reverse - -s, --sequence uint The sequence number of the signing account (offline mode only) - -d, --shorthand-deprecated-field string (DEPRECATED: bad idea) - --sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature - --some-messages testpb.AMessage (json) (repeated) - --str string - --strings strings - --timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height - --timestamp timestamp (RFC 3339) - --tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator - --u64 uint some random uint64 - -u, --uint32 uint32 some random uint32 - --uints uints (default []) - -v, --version version for send - -y, --yes Skip tx broadcasting prompt confirmation + -a, --account-number uint The account number of the signing account (offline mode only) + --aux Generate aux signer data instead of sending a tx + -b, --broadcast-mode string Transaction broadcasting mode (sync|async) (default "sync") + --chain-id string The network chain ID + --dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible) + --fee-granter string Fee granter grants fees for the transaction + --fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer + --fees string Fees to pay along with transaction; eg: 10uatom + --from string Name or address of private key with which to sign + --gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000) + --gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1) + --gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom) + --generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name) + -h, --help help for send + --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) (default "os") + --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used + --ledger Use a connected Ledger device + --node string : to CometBFT rpc interface for this chain (default "tcp://localhost:26657") + --note string Note to add a description to the transaction (previously --memo) + --offline Offline mode (does not allow any online functionality) + -o, --output string Output format (text|json) (default "json") + -s, --sequence uint The sequence number of the signing account (offline mode only) + --sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature + --timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height + --tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator + -y, --yes Skip tx broadcasting prompt confirmation diff --git a/client/v2/autocli/testdata/help-toplevel-msg.golden b/client/v2/autocli/testdata/help-toplevel-msg.golden index 0eac1e006f1f..51d33ed95e69 100644 --- a/client/v2/autocli/testdata/help-toplevel-msg.golden +++ b/client/v2/autocli/testdata/help-toplevel-msg.golden @@ -5,11 +5,13 @@ Usage: test [command] Available Commands: - completion Generate the autocompletion script for the specified shell - deprecatedmsg Tx commands for the testpb.Msg service - help Help about any command - send send msg the value provided by the user - skipmsg Tx commands for the testpb.Msg service + burn + completion Generate the autocompletion script for the specified shell + help Help about any command + multi-send + send Send coins from one account to another + set-send-enabled + update-params Flags: -h, --help help for test diff --git a/client/v2/autocli/testdata/msg-output.golden b/client/v2/autocli/testdata/msg-output.golden new file mode 100644 index 000000000000..73bddd4ad8ae --- /dev/null +++ b/client/v2/autocli/testdata/msg-output.golden @@ -0,0 +1 @@ +{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","to_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","amount":[{"denom":"foo","amount":"1"}]}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":[]} diff --git a/client/v2/go.mod b/client/v2/go.mod index 011065cb198e..1502b41bb691 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -69,6 +69,7 @@ require ( github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.1.0 // indirect + github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect diff --git a/client/v2/go.sum b/client/v2/go.sum index 819af0aca15e..9389960eaddc 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -785,6 +785,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= @@ -864,6 +865,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -934,6 +936,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1089,6 +1092,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From d0c4b434d4f1411e1ab8934f8936ea1b23154af1 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 4 Oct 2023 17:38:07 +0200 Subject: [PATCH 03/15] add tests for from flag --- client/v2/autocli/flag/builder.go | 11 ++++--- client/v2/autocli/msg.go | 13 ++++++++ client/v2/autocli/msg_test.go | 52 +++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/client/v2/autocli/flag/builder.go b/client/v2/autocli/flag/builder.go index f0accc2e0971..6c1dbe3b148b 100644 --- a/client/v2/autocli/flag/builder.go +++ b/client/v2/autocli/flag/builder.go @@ -93,7 +93,7 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m } fields := messageType.Descriptor().Fields() - signerFieldName := getSignerFieldName(messageType.Descriptor()) + signerFieldName := GetSignerFieldName(messageType.Descriptor()) isPositional := map[string]bool{} @@ -200,8 +200,9 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m flagOptsByFlagName := map[string]*autocliv1.FlagOptions{} for i := 0; i < fields.Len(); i++ { field := fields.Get(i) - // skips positional args and signer field - if isPositional[string(field.Name())] || string(field.Name()) == signerFieldName { + // skips positional args and signer field if already set + if isPositional[string(field.Name())] || + (string(field.Name()) == signerFieldName && messageBinder.SignerInfo.FieldName == flags.FlagFrom) { continue } @@ -412,9 +413,9 @@ func (b *Builder) resolveFlagTypeBasic(field protoreflect.FieldDescriptor) Type } } -// getSignerFieldName gets signer field name of a message. +// GetSignerFieldName gets signer field name of a message. // AutoCLI supports only one signer field per message. -func getSignerFieldName(descriptor protoreflect.MessageDescriptor) string { +func GetSignerFieldName(descriptor protoreflect.MessageDescriptor) string { signersFields := proto.GetExtension(descriptor.Options(), msgv1.E_Signer).([]string) if len(signersFields) == 0 { return "" diff --git a/client/v2/autocli/msg.go b/client/v2/autocli/msg.go index a2bd5eb9051a..79cd25b5265a 100644 --- a/client/v2/autocli/msg.go +++ b/client/v2/autocli/msg.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/types/dynamicpb" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + "cosmossdk.io/client/v2/autocli/flag" "github.com/cosmos/cosmos-sdk/client" clienttx "github.com/cosmos/cosmos-sdk/client/tx" @@ -127,6 +128,18 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor clientCtx = clientCtx.WithTxConfig(txConfigWithTextual) clientCtx.Output = cmd.OutOrStdout() + // 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 == "" { + signerFromFlag := clientCtx.GetFromAddress() + signer, err := b.ClientCtx.AddressCodec.BytesToString(signerFromFlag.Bytes()) + if err != nil { + return fmt.Errorf("failed to set signer on message, got %v: %w", signerFromFlag, err) + } + + input.Set(fd, protoreflect.ValueOfString(signer)) + } + // 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) diff --git a/client/v2/autocli/msg_test.go b/client/v2/autocli/msg_test.go index 86d328aaa4a6..96b930c33c52 100644 --- a/client/v2/autocli/msg_test.go +++ b/client/v2/autocli/msg_test.go @@ -19,6 +19,14 @@ var buildModuleMsgCommand = func(moduleName string, b *Builder) (*cobra.Command, return cmd, err } +func buildCustomModuleMsgCommand(cmdDescriptor *autocliv1.ServiceCommandDescriptor) func(moduleName string, b *Builder) (*cobra.Command, error) { + return func(moduleName string, b *Builder) (*cobra.Command, error) { + cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName)) + err := b.AddMsgServiceCommands(cmd, cmdDescriptor) + return cmd, err + } +} + var bankAutoCLI = &autocliv1.ServiceCommandDescriptor{ Service: bankv1beta1.Msg_ServiceDesc.ServiceName, RpcCommandOptions: []*autocliv1.RpcCommandOptions{ @@ -41,6 +49,50 @@ func TestMsg(t *testing.T) { ) assert.NilError(t, err) golden.Assert(t, out.String(), "msg-output.golden") + + out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{ + Service: bankv1beta1.Msg_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Send", + Use: "send [from_key_or_address] [to_address] [amount] [flags]", + Short: "Send coins from one account to another", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}}, + // from_address should be automatically added + }, + }, + EnhanceCustomCommand: true, + }), "send", + "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo", + "--from", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", + "--generate-only", + "--output", "json", + ) + assert.NilError(t, err) + golden.Assert(t, out.String(), "msg-output.golden") + + out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{ + Service: bankv1beta1.Msg_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Send", + Use: "send [from_key_or_address] [to_address] [amount] [flags]", + Short: "Send coins from one account to another", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}}, + FlagOptions: map[string]*autocliv1.FlagOptions{ + "from_address": {Name: "sender"}, // use a custom flag for signer + }, + }, + }, + EnhanceCustomCommand: true, + }), "send", + "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo", + "--sender", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", + "--generate-only", + "--output", "json", + ) + assert.NilError(t, err) + golden.Assert(t, out.String(), "msg-output.golden") } func TestMsgOptionsError(t *testing.T) { From 79a168ec0170cf6d3feb649afe79748bc7b575af Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 5 Oct 2023 00:51:49 +0200 Subject: [PATCH 04/15] feat(x/distribution): add autocli options for tx --- CHANGELOG.md | 2 + x/distribution/autocli.go | 52 +++++++++ x/distribution/client/cli/tx.go | 152 +-------------------------- x/distribution/client/cli/tx_test.go | 123 ---------------------- x/protocolpool/autocli.go | 2 +- 5 files changed, 59 insertions(+), 272 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c322f4c07df4..82e165ec6153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -155,6 +155,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### CLI Breaking Changes +* (x/distribution) [#](https://github.com/cosmos/cosmos-sdk/pull/) `appd tx distribution withdraw-rewards` now only withdraws rewards for the delegator's own delegations. For withdrawing validators commission, use `appd tx distribution withdraw-validator-commission`. + ### State Machine Breaking * (x/distribution) [#17657](https://github.com/cosmos/cosmos-sdk/pull/17657) Migrate community pool funds from x/distribution to x/protocolpool. diff --git a/x/distribution/autocli.go b/x/distribution/autocli.go index 8df238c8c203..055870a1b775 100644 --- a/x/distribution/autocli.go +++ b/x/distribution/autocli.go @@ -100,6 +100,58 @@ $ %s query distribution rewards %s [validator-address] }, Tx: &autocliv1.ServiceCommandDescriptor{ Service: distirbuitonv1beta1.Msg_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "SetWithdrawAddress", + Use: "set-withdraw-addr [withdraw-addr]", + Short: "Change the default withdraw address for rewards associated with an address", + Example: fmt.Sprintf("%s tx distribution set-withdraw-addr cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p --from mykey", version.AppName), + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "withdraw_address"}, + }, + }, + { + RpcMethod: "WithdrawDelegatorReward", + Use: "withdraw-rewards [validator-addr]", + Short: "Withdraw rewards from a given delegation address", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "validator_address"}, + }, + }, + { + RpcMethod: "WithdrawValidatorCommission", + Use: "withdraw-validator-commission [validator-addr]", + Short: "Withdraw comissions from a validator address (must be a validator operator)", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "validator_address"}, + }, + }, + { + RpcMethod: "DepositValidatorRewardsPool", + Use: "fund-validator-rewards-pool [validator-addr] [amount]", + Short: "Fund the validator rewards pool with the specified amount", + Example: fmt.Sprintf("%s tx distribution fund-validator-rewards-pool cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp 100uatom --from mykey", version.AppName), + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "validator_address"}, + {ProtoField: "amount"}, + }, + }, + { + RpcMethod: "FundCommunityPool", + Deprecated: fmt.Sprintf("Use %s tx protocolpool fund-community-pool", version.AppName), + Use: "fund-community-pool [amount]", + Short: "Funds the community pool with the specified amount", + Example: fmt.Sprintf(`$ %s tx distribution fund-community-pool 100uatom --from mykey`, version.AppName), + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "amount"}, + }, + }, + { + RpcMethod: "UpdateParams", + Skip: true, + }, + }, + EnhanceCustomCommand: true, }, } } diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index 80c137dd24ab..7a76596b6816 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "strings" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -38,10 +37,7 @@ func NewTxCmd(valAc, ac address.Codec) *cobra.Command { } distTxCmd.AddCommand( - NewWithdrawRewardsCmd(valAc, ac), NewWithdrawAllRewardsCmd(valAc, ac), - NewSetWithdrawAddrCmd(ac), - NewDepositValidatorRewardsPoolCmd(valAc, ac), ) return distTxCmd @@ -75,72 +71,13 @@ func newSplitAndApply( return nil } -// NewWithdrawRewardsCmd returns a CLI command handler for creating a MsgWithdrawDelegatorReward transaction. -func NewWithdrawRewardsCmd(valCodec, ac address.Codec) *cobra.Command { - bech32PrefixValAddr := sdk.GetConfig().GetBech32ValidatorAddrPrefix() - - cmd := &cobra.Command{ - Use: "withdraw-rewards [validator-addr]", - Short: "Withdraw rewards from a given delegation address, and optionally withdraw validator commission if the delegation address given is a validator operator", - Long: strings.TrimSpace( - fmt.Sprintf(`Withdraw rewards from a given delegation address, -and optionally withdraw validator commission if the delegation address given is a validator operator. - -Example: -$ %s tx distribution withdraw-rewards %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey -$ %s tx distribution withdraw-rewards %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --from mykey --commission -`, - version.AppName, bech32PrefixValAddr, version.AppName, bech32PrefixValAddr, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - delAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) - if err != nil { - return err - } - - _, err = valCodec.StringToBytes(args[0]) - if err != nil { - return err - } - - msgs := []sdk.Msg{types.NewMsgWithdrawDelegatorReward(delAddr, args[0])} - - if commission, _ := cmd.Flags().GetBool(FlagCommission); commission { - msgs = append(msgs, types.NewMsgWithdrawValidatorCommission(args[0])) - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgs...) - }, - } - - cmd.Flags().Bool(FlagCommission, false, "Withdraw the validator's commission in addition to the rewards") - flags.AddTxFlagsToCmd(cmd) - - return cmd -} - // NewWithdrawAllRewardsCmd returns a CLI command handler for creating a MsgWithdrawDelegatorReward transaction. func NewWithdrawAllRewardsCmd(valCodec, ac address.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "withdraw-all-rewards", - Short: "withdraw all delegations rewards for a delegator", - Long: strings.TrimSpace( - fmt.Sprintf(`Withdraw all rewards for a single delegator. -Note that if you use this command with --%[2]s=%[3]s or --%[2]s=%[4]s, the %[5]s flag will automatically be set to 0. - -Example: -$ %[1]s tx distribution withdraw-all-rewards --from mykey -`, - version.AppName, flags.FlagBroadcastMode, flags.BroadcastSync, flags.BroadcastAsync, FlagMaxMessagesPerTx, - ), - ), - Args: cobra.NoArgs, + Use: "withdraw-all-rewards", + Short: "withdraw all delegations rewards for a delegator", + Example: fmt.Sprintf("%s tx distribution withdraw-all-rewards --from mykey", version.AppName), + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientTxContext(cmd) if err != nil { @@ -187,84 +124,3 @@ $ %[1]s tx distribution withdraw-all-rewards --from mykey return cmd } - -// NewSetWithdrawAddrCmd returns a CLI command handler for creating a MsgSetWithdrawAddress transaction. -func NewSetWithdrawAddrCmd(ac address.Codec) *cobra.Command { - bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix() - - cmd := &cobra.Command{ - Use: "set-withdraw-addr [withdraw-addr]", - Short: "change the default withdraw address for rewards associated with an address", - Long: strings.TrimSpace( - fmt.Sprintf(`Set the withdraw address for rewards associated with a delegator address. - -Example: -$ %s tx distribution set-withdraw-addr %s1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p --from mykey -`, - version.AppName, bech32PrefixAccAddr, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - delAddr := clientCtx.GetFromAddress() - withdrawAddr, err := ac.StringToBytes(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgSetWithdrawAddress(delAddr, withdrawAddr) - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - - return cmd -} - -// NewDepositValidatorRewardsPoolCmd returns a CLI command handler for creating -// a MsgDepositValidatorRewardsPool transaction. -func NewDepositValidatorRewardsPoolCmd(valCodec, ac address.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "fund-validator-rewards-pool [val_addr] [amount]", - Args: cobra.ExactArgs(2), - Short: "Fund the validator rewards pool with the specified amount", - Example: fmt.Sprintf( - "%s tx distribution fund-validator-rewards-pool cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp 100uatom --from mykey", - version.AppName, - ), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - depositorAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) - if err != nil { - return err - } - - _, err = valCodec.StringToBytes(args[0]) - if err != nil { - return err - } - - amount, err := sdk.ParseCoinsNormalized(args[1]) - if err != nil { - return err - } - - msg := types.NewMsgDepositValidatorRewardsPool(depositorAddr, args[0], amount) - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - - return cmd -} diff --git a/x/distribution/client/cli/tx_test.go b/x/distribution/client/cli/tx_test.go index c0b7071700ae..838c90210706 100644 --- a/x/distribution/client/cli/tx_test.go +++ b/x/distribution/client/cli/tx_test.go @@ -1,14 +1,12 @@ package cli_test import ( - "context" "fmt" "io" "testing" abci "github.com/cometbft/cometbft/abci/types" rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock" - "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/suite" sdkmath "cosmossdk.io/math" @@ -17,7 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/crypto/keyring" - svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" @@ -84,76 +81,6 @@ func (s *CLITestSuite) SetupSuite() { cfg.GenesisState = genesisState } -func (s *CLITestSuite) TestTxWithdrawRewardsCmd() { - val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - valAddr fmt.Stringer - args []string - expectErrMsg string - }{ - { - "invalid validator address", - val[0].Address, - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - "hrp does not match bech32 prefix", - }, - { - "valid transaction", - sdk.ValAddress(val[0].Address), - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - "", - }, - { - "valid transaction (with commission)", - sdk.ValAddress(val[0].Address), - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=true", cli.FlagCommission), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - "", - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - args := append([]string{tc.valAddr.String()}, tc.args...) - - ctx := svrcmd.CreateExecuteContext(context.Background()) - cmd := cli.NewWithdrawRewardsCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) - cmd.SetContext(ctx) - cmd.SetArgs(args) - s.Require().NoError(client.SetCmdClientContextHandler(s.clientCtx, cmd)) - - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) - if tc.expectErrMsg != "" { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expectErrMsg) - } else { - s.Require().NoError(err) - msg := &sdk.TxResponse{} - s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String()) - } - }) - } -} - func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() { val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) @@ -202,53 +129,3 @@ func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() { }) } } - -func (s *CLITestSuite) TestTxSetWithdrawAddrCmd() { - val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - - testCases := []struct { - name string - args []string - expectErr bool - respType proto.Message - }{ - { - "invalid withdraw address", - []string{ - "foo", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - true, nil, - }, - { - "valid transaction", - []string{ - val[0].Address.String(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), - }, - false, &sdk.TxResponse{}, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.NewSetWithdrawAddrCmd(addresscodec.NewBech32Codec("cosmos")) - - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - } - }) - } -} diff --git a/x/protocolpool/autocli.go b/x/protocolpool/autocli.go index 39d4087afaea..f8fbaa4c6139 100644 --- a/x/protocolpool/autocli.go +++ b/x/protocolpool/autocli.go @@ -30,7 +30,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { RpcMethod: "FundCommunityPool", Use: "fund-community-pool [amount]", Short: "Funds the community pool with the specified amount", - Example: fmt.Sprintf(`$ %s tx pool fund-community-pool 100uatom --from mykey`, version.AppName), + Example: fmt.Sprintf(`$ %s tx protocolpool fund-community-pool 100uatom --from mykey`, version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "amount"}}, }, }, From 4db62731240f4c00e5165aa777eece760e539d80 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 5 Oct 2023 00:55:03 +0200 Subject: [PATCH 05/15] updates --- x/distribution/autocli.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x/distribution/autocli.go b/x/distribution/autocli.go index 055870a1b775..7a13fd242624 100644 --- a/x/distribution/autocli.go +++ b/x/distribution/autocli.go @@ -148,7 +148,11 @@ $ %s query distribution rewards %s [validator-address] }, { RpcMethod: "UpdateParams", - Skip: true, + Skip: true, // skipped because authority gated + }, + { + RpcMethod: "CommunityPoolSpend", + Skip: true, // skipped because authority gated }, }, EnhanceCustomCommand: true, From 7032ebc623ec8c984e4d85d479bed60fb3a3a5e8 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 5 Oct 2023 01:07:46 +0200 Subject: [PATCH 06/15] fix typo --- x/distribution/autocli.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/distribution/autocli.go b/x/distribution/autocli.go index 7a13fd242624..24720f9b527a 100644 --- a/x/distribution/autocli.go +++ b/x/distribution/autocli.go @@ -121,7 +121,7 @@ $ %s query distribution rewards %s [validator-address] { RpcMethod: "WithdrawValidatorCommission", Use: "withdraw-validator-commission [validator-addr]", - Short: "Withdraw comissions from a validator address (must be a validator operator)", + Short: "Withdraw commissions from a validator address (must be a validator operator)", PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "validator_address"}, }, From 6e8a3a65db380c79838740a43f07a971320ff0c1 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 5 Oct 2023 13:52:01 +0200 Subject: [PATCH 07/15] varargs --- x/distribution/autocli.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/distribution/autocli.go b/x/distribution/autocli.go index 24720f9b527a..a720b5ca3ccd 100644 --- a/x/distribution/autocli.go +++ b/x/distribution/autocli.go @@ -133,7 +133,7 @@ $ %s query distribution rewards %s [validator-address] Example: fmt.Sprintf("%s tx distribution fund-validator-rewards-pool cosmosvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqfyqnp 100uatom --from mykey", version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "validator_address"}, - {ProtoField: "amount"}, + {ProtoField: "amount", Varargs: true}, }, }, { @@ -143,7 +143,7 @@ $ %s query distribution rewards %s [validator-address] Short: "Funds the community pool with the specified amount", Example: fmt.Sprintf(`$ %s tx distribution fund-community-pool 100uatom --from mykey`, version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ - {ProtoField: "amount"}, + {ProtoField: "amount", Varargs: true}, }, }, { From 3adbecf574c86c1cfb7ffa948cfdd146dcb07583 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 5 Oct 2023 17:06:46 +0200 Subject: [PATCH 08/15] remove cli tests, todo add msg server tests --- tests/e2e/distribution/suite.go | 172 ----------------------- x/distribution/keeper/msg_server_test.go | 1 + 2 files changed, 1 insertion(+), 172 deletions(-) create mode 100644 x/distribution/keeper/msg_server_test.go diff --git a/tests/e2e/distribution/suite.go b/tests/e2e/distribution/suite.go index a133c0fc6672..b77051653237 100644 --- a/tests/e2e/distribution/suite.go +++ b/tests/e2e/distribution/suite.go @@ -1,7 +1,6 @@ package distribution import ( - "context" "encoding/hex" "fmt" "time" @@ -12,10 +11,8 @@ import ( "cosmossdk.io/math" "cosmossdk.io/simapp" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec/address" - svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" @@ -72,120 +69,6 @@ func (s *E2ETestSuite) TearDownSuite() { s.network.Cleanup() } -func (s *E2ETestSuite) TestNewWithdrawRewardsCmd() { - val := s.network.Validators[0] - - testCases := []struct { - name string - valAddr fmt.Stringer - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - expectedResponseType []string - }{ - { - "invalid validator address", - val.Address, - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - []string{}, - }, - { - "valid transaction", - sdk.ValAddress(val.Address), - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - []string{ - "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse", - }, - }, - { - "valid transaction (with commission)", - sdk.ValAddress(val.Address), - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=true", cli.FlagCommission), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - []string{ - "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse", - "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommissionResponse", - }, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - clientCtx := val.ClientCtx - - args := append([]string{tc.valAddr.String()}, tc.args...) - - _, _ = s.network.WaitForHeightWithTimeout(10, time.Minute) - - ctx := svrcmd.CreateExecuteContext(context.Background()) - cmd := cli.NewWithdrawRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) - cmd.SetContext(ctx) - cmd.SetArgs(args) - s.Require().NoError(client.SetCmdClientContextHandler(clientCtx, cmd)) - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - s.Require().NoError(s.network.WaitForNextBlock()) - - txResp, err := clitestutil.GetTxResponse(s.network, clientCtx, tc.respType.(*sdk.TxResponse).TxHash) - s.Require().NoError(err) - s.Require().Equal(tc.expectedCode, txResp.Code) - - data, err := hex.DecodeString(txResp.Data) - s.Require().NoError(err) - - txMsgData := sdk.TxMsgData{} - err = s.cfg.Codec.Unmarshal(data, &txMsgData) - s.Require().NoError(err) - for responseIdx, msgResponse := range txMsgData.MsgResponses { - s.Require().Equal(tc.expectedResponseType[responseIdx], msgResponse.TypeUrl) - switch msgResponse.TypeUrl { - case "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse": - var resp distrtypes.MsgWithdrawDelegatorRewardResponse - // can't use unpackAny as response types are not registered. - err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp) - s.Require().NoError(err) - s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))), - fmt.Sprintf("expected a positive coin value, got %v", resp.Amount)) - case "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommissionResponse": - var resp distrtypes.MsgWithdrawValidatorCommissionResponse - // can't use unpackAny as response types are not registered. - err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp) - s.Require().NoError(err) - s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))), - fmt.Sprintf("expected a positive coin value, got %v", resp.Amount)) - } - } - } - }) - } -} - func (s *E2ETestSuite) TestNewWithdrawAllRewardsCmd() { val := s.network.Validators[0] @@ -273,58 +156,3 @@ func (s *E2ETestSuite) TestNewWithdrawAllRewardsCmd() { }) } } - -func (s *E2ETestSuite) TestNewSetWithdrawAddrCmd() { - val := s.network.Validators[0] - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - }{ - { - "invalid withdraw address", - []string{ - "foo", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - }, - { - "valid transaction", - []string{ - val.Address.String(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.NewSetWithdrawAddrCmd(address.NewBech32Codec("cosmos")) - clientCtx := val.ClientCtx - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - - txResp := tc.respType.(*sdk.TxResponse) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode)) - } - }) - } -} diff --git a/x/distribution/keeper/msg_server_test.go b/x/distribution/keeper/msg_server_test.go new file mode 100644 index 000000000000..9429264902a9 --- /dev/null +++ b/x/distribution/keeper/msg_server_test.go @@ -0,0 +1 @@ +package keeper_test From 1ece1cc4b0166d2797461e204ce6c31b46b98b58 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 9 Oct 2023 15:58:44 +0200 Subject: [PATCH 09/15] updates --- tests/e2e/distribution/cli_test.go | 22 - tests/e2e/distribution/grpc_query_suite.go | 460 ------------------- tests/e2e/distribution/suite.go | 158 ------- tests/e2e/distribution/withdraw_all_suite.go | 146 ------ x/distribution/keeper/grpc_query_test.go | 1 + 5 files changed, 1 insertion(+), 786 deletions(-) delete mode 100644 tests/e2e/distribution/cli_test.go delete mode 100644 tests/e2e/distribution/grpc_query_suite.go delete mode 100644 tests/e2e/distribution/suite.go delete mode 100644 tests/e2e/distribution/withdraw_all_suite.go create mode 100644 x/distribution/keeper/grpc_query_test.go diff --git a/tests/e2e/distribution/cli_test.go b/tests/e2e/distribution/cli_test.go deleted file mode 100644 index 34d8cb0e0591..000000000000 --- a/tests/e2e/distribution/cli_test.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build e2e -// +build e2e - -package distribution - -import ( - "testing" - - "github.com/stretchr/testify/suite" -) - -func TestE2ETestSuite(t *testing.T) { - suite.Run(t, new(E2ETestSuite)) -} - -func TestGRPCQueryTestSuite(t *testing.T) { - suite.Run(t, new(GRPCQueryTestSuite)) -} - -func TestWithdrawAllSuite(t *testing.T) { - suite.Run(t, new(WithdrawAllTestSuite)) -} diff --git a/tests/e2e/distribution/grpc_query_suite.go b/tests/e2e/distribution/grpc_query_suite.go deleted file mode 100644 index 1ebe3862bbad..000000000000 --- a/tests/e2e/distribution/grpc_query_suite.go +++ /dev/null @@ -1,460 +0,0 @@ -package distribution - -import ( - "fmt" - - "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - - sdktestutil "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" - "github.com/cosmos/cosmos-sdk/types/query" - "github.com/cosmos/cosmos-sdk/x/distribution/types" -) - -type GRPCQueryTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network -} - -func (s *GRPCQueryTestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - s.cfg = cfg - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), cfg) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) -} - -// TearDownSuite cleans up the curret test network after _each_ test. -func (s *GRPCQueryTestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite1") - s.network.Cleanup() -} - -func (s *GRPCQueryTestSuite) TestQueryParamsGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - testCases := []struct { - name string - url string - respType proto.Message - expected proto.Message - }{ - { - "gRPC request params", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/params", baseURL), - &types.QueryParamsResponse{}, - &types.QueryParamsResponse{ - Params: types.DefaultParams(), - }, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequest(tc.url) - s.Run(tc.name, func() { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected, tc.respType) - }) - } -} - -func (s *GRPCQueryTestSuite) TestQueryValidatorDistributionInfoGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - testCases := []struct { - name string - url string - expErr bool - respType proto.Message - }{ - { - "gRPC request with wrong validator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s", baseURL, "wrongAddress"), - true, - &types.QueryValidatorDistributionInfoResponse{}, - }, - { - "gRPC request with valid validator address ", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s", baseURL, val.ValAddress.String()), - false, - &types.QueryValidatorDistributionInfoResponse{}, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequest(tc.url) - s.Run(tc.name, func() { - if tc.expErr { - s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } else { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } - }) - } -} - -func (s *GRPCQueryTestSuite) TestQueryOutstandingRewardsGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - rewards, err := sdk.ParseDecCoins("19.6stake") - s.Require().NoError(err) - - testCases := []struct { - name string - url string - headers map[string]string - expErr bool - respType proto.Message - expected proto.Message - }{ - { - "gRPC request params with wrong validator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/outstanding_rewards", baseURL, "wrongAddress"), - map[string]string{}, - true, - &types.QueryValidatorOutstandingRewardsResponse{}, - &types.QueryValidatorOutstandingRewardsResponse{}, - }, - { - "gRPC request params valid address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/outstanding_rewards", baseURL, val.ValAddress.String()), - map[string]string{ - grpctypes.GRPCBlockHeightHeader: "2", - }, - false, - &types.QueryValidatorOutstandingRewardsResponse{}, - &types.QueryValidatorOutstandingRewardsResponse{ - Rewards: types.ValidatorOutstandingRewards{ - Rewards: rewards, - }, - }, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequestWithHeaders(tc.url, tc.headers) - s.Run(tc.name, func() { - if tc.expErr { - s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } else { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected.String(), tc.respType.String()) - } - }) - } -} - -func (s *GRPCQueryTestSuite) TestQueryValidatorCommissionGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - commission, err := sdk.ParseDecCoins("9.8stake") - s.Require().NoError(err) - - testCases := []struct { - name string - url string - headers map[string]string - expErr bool - respType proto.Message - expected proto.Message - }{ - { - "gRPC request params with wrong validator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/commission", baseURL, "wrongAddress"), - map[string]string{}, - true, - &types.QueryValidatorCommissionResponse{}, - &types.QueryValidatorCommissionResponse{}, - }, - { - "gRPC request params valid address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/commission", baseURL, val.ValAddress.String()), - map[string]string{ - grpctypes.GRPCBlockHeightHeader: "2", - }, - false, - &types.QueryValidatorCommissionResponse{}, - &types.QueryValidatorCommissionResponse{ - Commission: types.ValidatorAccumulatedCommission{ - Commission: commission, - }, - }, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequestWithHeaders(tc.url, tc.headers) - s.Run(tc.name, func() { - if tc.expErr { - s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } else { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected.String(), tc.respType.String()) - } - }) - } -} - -func (s *GRPCQueryTestSuite) TestQuerySlashesGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - testCases := []struct { - name string - url string - expErr bool - respType proto.Message - expected proto.Message - }{ - { - "invalid validator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes", baseURL, ""), - true, - &types.QueryValidatorSlashesResponse{}, - nil, - }, - { - "invalid start height", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes?starting_height=%s&ending_height=%s", baseURL, val.ValAddress.String(), "-1", "3"), - true, - &types.QueryValidatorSlashesResponse{}, - nil, - }, - { - "invalid start height", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes?starting_height=%s&ending_height=%s", baseURL, val.ValAddress.String(), "1", "-3"), - true, - &types.QueryValidatorSlashesResponse{}, - nil, - }, - { - "valid request get slashes", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes?starting_height=%s&ending_height=%s", baseURL, val.ValAddress.String(), "1", "3"), - false, - &types.QueryValidatorSlashesResponse{}, - &types.QueryValidatorSlashesResponse{ - Pagination: &query.PageResponse{}, - }, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequest(tc.url) - - s.Run(tc.name, func() { - if tc.expErr { - s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } else { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected.String(), tc.respType.String()) - } - }) - } -} - -func (s *GRPCQueryTestSuite) TestQueryDelegatorRewardsGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - rewards, err := sdk.ParseDecCoins("9.8stake") - s.Require().NoError(err) - - testCases := []struct { - name string - url string - headers map[string]string - expErr bool - respType proto.Message - expected proto.Message - }{ - { - "wrong delegator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards", baseURL, "wrongDelegatorAddress"), - map[string]string{}, - true, - &types.QueryDelegationTotalRewardsResponse{}, - nil, - }, - { - "valid request", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards", baseURL, val.Address.String()), - map[string]string{ - grpctypes.GRPCBlockHeightHeader: "2", - }, - false, - &types.QueryDelegationTotalRewardsResponse{}, - &types.QueryDelegationTotalRewardsResponse{ - Rewards: []types.DelegationDelegatorReward{ - types.NewDelegationDelegatorReward(val.ValAddress.String(), rewards), - }, - Total: rewards, - }, - }, - { - "wrong validator address(specific validator rewards)", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards/%s", baseURL, val.Address.String(), "wrongValAddress"), - map[string]string{}, - true, - &types.QueryDelegationTotalRewardsResponse{}, - nil, - }, - { - "valid request(specific validator rewards)", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards/%s", baseURL, val.Address.String(), val.ValAddress.String()), - map[string]string{ - grpctypes.GRPCBlockHeightHeader: "2", - }, - false, - &types.QueryDelegationRewardsResponse{}, - &types.QueryDelegationRewardsResponse{ - Rewards: rewards, - }, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequestWithHeaders(tc.url, tc.headers) - - s.Run(tc.name, func() { - if tc.expErr { - s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } else { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected.String(), tc.respType.String()) - } - }) - } -} - -func (s *GRPCQueryTestSuite) TestQueryDelegatorValidatorsGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - testCases := []struct { - name string - url string - expErr bool - respType proto.Message - expected proto.Message - }{ - { - "empty delegator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/validators", baseURL, ""), - true, - &types.QueryDelegatorValidatorsResponse{}, - nil, - }, - { - "wrong delegator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/validators", baseURL, "wrongDelegatorAddress"), - true, - &types.QueryDelegatorValidatorsResponse{}, - nil, - }, - { - "valid request", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/validators", baseURL, val.Address.String()), - false, - &types.QueryDelegatorValidatorsResponse{}, - &types.QueryDelegatorValidatorsResponse{ - Validators: []string{val.ValAddress.String()}, - }, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequest(tc.url) - - s.Run(tc.name, func() { - if tc.expErr { - s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } else { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected.String(), tc.respType.String()) - } - }) - } -} - -func (s *GRPCQueryTestSuite) TestQueryWithdrawAddressGRPC() { - val := s.network.Validators[0] - baseURL := val.APIAddress - - testCases := []struct { - name string - url string - expErr bool - respType proto.Message - expected proto.Message - }{ - { - "empty delegator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", baseURL, ""), - true, - &types.QueryDelegatorWithdrawAddressResponse{}, - nil, - }, - { - "wrong delegator address", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", baseURL, "wrongDelegatorAddress"), - true, - &types.QueryDelegatorWithdrawAddressResponse{}, - nil, - }, - { - "valid request", - fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", baseURL, val.Address.String()), - false, - &types.QueryDelegatorWithdrawAddressResponse{}, - &types.QueryDelegatorWithdrawAddressResponse{ - WithdrawAddress: val.Address.String(), - }, - }, - } - - for _, tc := range testCases { - tc := tc - resp, err := sdktestutil.GetRequest(tc.url) - - s.Run(tc.name, func() { - if tc.expErr { - s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - } else { - s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) - s.Require().Equal(tc.expected.String(), tc.respType.String()) - } - }) - } -} diff --git a/tests/e2e/distribution/suite.go b/tests/e2e/distribution/suite.go deleted file mode 100644 index b77051653237..000000000000 --- a/tests/e2e/distribution/suite.go +++ /dev/null @@ -1,158 +0,0 @@ -package distribution - -import ( - "encoding/hex" - "fmt" - "time" - - "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" - - "cosmossdk.io/math" - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/address" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution/client/cli" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network -} - -func NewE2ETestSuite(cfg network.Config) *E2ETestSuite { - return &E2ETestSuite{cfg: cfg} -} - -// SetupSuite creates a new network for _each_ e2e test. We create a new -// network for each test because there are some state modifications that are -// needed to be made in order to make useful queries. However, we don't want -// these state changes to be present in other tests. -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - s.cfg = cfg - - genesisState := s.cfg.GenesisState - var mintData minttypes.GenesisState - s.Require().NoError(s.cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData)) - - inflation := math.LegacyMustNewDecFromStr("1.0") - mintData.Minter.Inflation = inflation - mintData.Params.InflationMin = inflation - mintData.Params.InflationMax = inflation - - mintDataBz, err := s.cfg.Codec.MarshalJSON(&mintData) - s.Require().NoError(err) - genesisState[minttypes.ModuleName] = mintDataBz - s.cfg.GenesisState = genesisState - - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) -} - -// TearDownSuite cleans up the curret test network after _each_ test. -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite1") - s.network.Cleanup() -} - -func (s *E2ETestSuite) TestNewWithdrawAllRewardsCmd() { - val := s.network.Validators[0] - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - expectedResponseType []string - }{ - { - "valid transaction (offline)", - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=true", flags.FlagOffline), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - []string{}, - }, - { - "valid transaction", - []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - []string{ - "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse", - }, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) - clientCtx := val.ClientCtx - - _, _ = s.network.WaitForHeightWithTimeout(10, time.Minute) - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - s.Require().NoError(s.network.WaitForNextBlock()) - - txResp, err := clitestutil.GetTxResponse(s.network, clientCtx, tc.respType.(*sdk.TxResponse).TxHash) - s.Require().NoError(err) - s.Require().Equal(tc.expectedCode, txResp.Code) - - data, err := hex.DecodeString(txResp.Data) - s.Require().NoError(err) - - txMsgData := sdk.TxMsgData{} - err = s.cfg.Codec.Unmarshal(data, &txMsgData) - s.Require().NoError(err) - for responseIdx, msgResponse := range txMsgData.MsgResponses { - s.Require().Equal(tc.expectedResponseType[responseIdx], msgResponse.TypeUrl) - switch msgResponse.TypeUrl { - case "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorRewardResponse": - var resp distrtypes.MsgWithdrawDelegatorRewardResponse - // can't use unpackAny as response types are not registered. - err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp) - s.Require().NoError(err) - s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))), - fmt.Sprintf("expected a positive coin value, got %v", resp.Amount)) - case "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommissionResponse": - var resp distrtypes.MsgWithdrawValidatorCommissionResponse - // can't use unpackAny as response types are not registered. - err = s.cfg.Codec.Unmarshal(msgResponse.Value, &resp) - s.Require().NoError(err) - s.Require().True(resp.Amount.IsAllGT(sdk.NewCoins(sdk.NewCoin("stake", math.OneInt()))), - fmt.Sprintf("expected a positive coin value, got %v", resp.Amount)) - } - } - } - }) - } -} diff --git a/tests/e2e/distribution/withdraw_all_suite.go b/tests/e2e/distribution/withdraw_all_suite.go deleted file mode 100644 index 4110f88bf077..000000000000 --- a/tests/e2e/distribution/withdraw_all_suite.go +++ /dev/null @@ -1,146 +0,0 @@ -package distribution - -import ( - "fmt" - "strings" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/math" - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/address" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/distribution/client/cli" - stakingcli "github.com/cosmos/cosmos-sdk/x/staking/client/cli" -) - -type WithdrawAllTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network -} - -func (s *WithdrawAllTestSuite) SetupSuite() { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 2 - s.cfg = cfg - - s.T().Log("setting up e2e test suite") - network, err := network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - s.network = network - - s.Require().NoError(s.network.WaitForNextBlock()) -} - -// TearDownSuite cleans up the curret test network after _each_ test. -func (s *WithdrawAllTestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -// This test requires multiple validators, if I add this test to `E2ETestSuite` by increasing -// `NumValidators` the existing tests are leading to non-determnism so created new suite for this test. -func (s *WithdrawAllTestSuite) TestNewWithdrawAllRewardsGenerateOnly() { - require := s.Require() - val := s.network.Validators[0] - val1 := s.network.Validators[1] - clientCtx := val.ClientCtx - - info, _, err := val.ClientCtx.Keyring.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - require.NoError(err) - - pubkey, err := info.GetPubKey() - require.NoError(err) - - newAddr := sdk.AccAddress(pubkey.Address()) - - msgSend := &banktypes.MsgSend{ - FromAddress: val.Address.String(), - ToAddress: newAddr.String(), - Amount: sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(2000))), - } - _, err = clitestutil.SubmitTestTx( - val.ClientCtx, - msgSend, - val.Address, - clitestutil.TestTxConfig{}, - ) - - require.NoError(err) - require.NoError(s.network.WaitForNextBlock()) - - // delegate 500 tokens to validator1 - args := []string{ - val.ValAddress.String(), - sdk.NewCoin(s.cfg.BondDenom, math.NewInt(500)).String(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - } - cmd := stakingcli.NewDelegateCmd(clientCtx.InterfaceRegistry.SigningContext().ValidatorAddressCodec(), clientCtx.InterfaceRegistry.SigningContext().AddressCodec()) - _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - require.NoError(err) - require.NoError(s.network.WaitForNextBlock()) - - // delegate 500 tokens to validator2 - args = []string{ - val1.ValAddress.String(), - sdk.NewCoin(s.cfg.BondDenom, math.NewInt(500)).String(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - } - _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - require.NoError(err) - - var out testutil.BufferWriter - err = s.network.RetryForBlocks(func() error { - args = []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - fmt.Sprintf("--%s=1", cli.FlagMaxMessagesPerTx), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - } - cmd = cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - if err != nil { - return err - } - - // expect 2 transactions in the generated file when --max-msgs in a tx set 1. - txLen := len(strings.Split(strings.Trim(out.String(), "\n"), "\n")) - if txLen != 2 { - return fmt.Errorf("expected 2 transactions in the generated file, got %d", txLen) - } - return nil - }, 3) - require.NoError(err) - - args = []string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - fmt.Sprintf("--%s=2", cli.FlagMaxMessagesPerTx), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - } - cmd = cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) - out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - require.NoError(err) - // expect 1 transaction in the generated file when --max-msgs in a tx set 2, since there are only delegations. - s.Require().Equal(1, len(strings.Split(strings.Trim(out.String(), "\n"), "\n"))) -} diff --git a/x/distribution/keeper/grpc_query_test.go b/x/distribution/keeper/grpc_query_test.go new file mode 100644 index 000000000000..9429264902a9 --- /dev/null +++ b/x/distribution/keeper/grpc_query_test.go @@ -0,0 +1 @@ +package keeper_test From ea48c4ee60876a22a827ceba262bea73ffa43c67 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 9 Oct 2023 19:03:07 +0200 Subject: [PATCH 10/15] updates --- tests/e2e/distribution/cli_test.go | 14 + tests/e2e/distribution/withdraw_all_suite.go | 146 ++++++++ x/distribution/keeper/grpc_query_test.go | 42 +++ x/distribution/keeper/keeper_test.go | 91 ++--- x/distribution/keeper/msg_server.go | 5 +- x/distribution/keeper/msg_server_test.go | 355 +++++++++++++++++++ 6 files changed, 590 insertions(+), 63 deletions(-) create mode 100644 tests/e2e/distribution/cli_test.go create mode 100644 tests/e2e/distribution/withdraw_all_suite.go diff --git a/tests/e2e/distribution/cli_test.go b/tests/e2e/distribution/cli_test.go new file mode 100644 index 000000000000..8883a5bc44c6 --- /dev/null +++ b/tests/e2e/distribution/cli_test.go @@ -0,0 +1,14 @@ +//go:build e2e +// +build e2e + +package distribution + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestWithdrawAllSuite(t *testing.T) { + suite.Run(t, new(WithdrawAllTestSuite)) +} diff --git a/tests/e2e/distribution/withdraw_all_suite.go b/tests/e2e/distribution/withdraw_all_suite.go new file mode 100644 index 000000000000..4110f88bf077 --- /dev/null +++ b/tests/e2e/distribution/withdraw_all_suite.go @@ -0,0 +1,146 @@ +package distribution + +import ( + "fmt" + "strings" + + "github.com/stretchr/testify/suite" + + "cosmossdk.io/math" + "cosmossdk.io/simapp" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/testutil" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/distribution/client/cli" + stakingcli "github.com/cosmos/cosmos-sdk/x/staking/client/cli" +) + +type WithdrawAllTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +func (s *WithdrawAllTestSuite) SetupSuite() { + cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) + cfg.NumValidators = 2 + s.cfg = cfg + + s.T().Log("setting up e2e test suite") + network, err := network.New(s.T(), s.T().TempDir(), s.cfg) + s.Require().NoError(err) + s.network = network + + s.Require().NoError(s.network.WaitForNextBlock()) +} + +// TearDownSuite cleans up the curret test network after _each_ test. +func (s *WithdrawAllTestSuite) TearDownSuite() { + s.T().Log("tearing down e2e test suite") + s.network.Cleanup() +} + +// This test requires multiple validators, if I add this test to `E2ETestSuite` by increasing +// `NumValidators` the existing tests are leading to non-determnism so created new suite for this test. +func (s *WithdrawAllTestSuite) TestNewWithdrawAllRewardsGenerateOnly() { + require := s.Require() + val := s.network.Validators[0] + val1 := s.network.Validators[1] + clientCtx := val.ClientCtx + + info, _, err := val.ClientCtx.Keyring.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) + require.NoError(err) + + pubkey, err := info.GetPubKey() + require.NoError(err) + + newAddr := sdk.AccAddress(pubkey.Address()) + + msgSend := &banktypes.MsgSend{ + FromAddress: val.Address.String(), + ToAddress: newAddr.String(), + Amount: sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(2000))), + } + _, err = clitestutil.SubmitTestTx( + val.ClientCtx, + msgSend, + val.Address, + clitestutil.TestTxConfig{}, + ) + + require.NoError(err) + require.NoError(s.network.WaitForNextBlock()) + + // delegate 500 tokens to validator1 + args := []string{ + val.ValAddress.String(), + sdk.NewCoin(s.cfg.BondDenom, math.NewInt(500)).String(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), + } + cmd := stakingcli.NewDelegateCmd(clientCtx.InterfaceRegistry.SigningContext().ValidatorAddressCodec(), clientCtx.InterfaceRegistry.SigningContext().AddressCodec()) + _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + require.NoError(err) + require.NoError(s.network.WaitForNextBlock()) + + // delegate 500 tokens to validator2 + args = []string{ + val1.ValAddress.String(), + sdk.NewCoin(s.cfg.BondDenom, math.NewInt(500)).String(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), + } + _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + require.NoError(err) + + var out testutil.BufferWriter + err = s.network.RetryForBlocks(func() error { + args = []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), + fmt.Sprintf("--%s=1", cli.FlagMaxMessagesPerTx), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), + } + cmd = cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + if err != nil { + return err + } + + // expect 2 transactions in the generated file when --max-msgs in a tx set 1. + txLen := len(strings.Split(strings.Trim(out.String(), "\n"), "\n")) + if txLen != 2 { + return fmt.Errorf("expected 2 transactions in the generated file, got %d", txLen) + } + return nil + }, 3) + require.NoError(err) + + args = []string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, newAddr.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), + fmt.Sprintf("--%s=2", cli.FlagMaxMessagesPerTx), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), + } + cmd = cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) + out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + require.NoError(err) + // expect 1 transaction in the generated file when --max-msgs in a tx set 2, since there are only delegations. + s.Require().Equal(1, len(strings.Split(strings.Trim(out.String(), "\n"), "\n"))) +} diff --git a/x/distribution/keeper/grpc_query_test.go b/x/distribution/keeper/grpc_query_test.go index 9429264902a9..a5e17badda58 100644 --- a/x/distribution/keeper/grpc_query_test.go +++ b/x/distribution/keeper/grpc_query_test.go @@ -1 +1,43 @@ package keeper_test + +import "testing" + +func TestQueryParams(t *testing.T) { + +} + +func TestQueryValidatorDistributionInfo(t *testing.T) { + +} + +func TestQueryValidatorOutstandingRewards(t *testing.T) { + +} + +func TestQueryValidatorCommission(t *testing.T) { + +} + +func TestQueryValidatorSlashes(t *testing.T) { + +} + +func TestQueryDelegationRewards(t *testing.T) { + +} + +func TestQueryDelegationTotalRewards(t *testing.T) { + +} + +func TestQueryDelegatorValidators(t *testing.T) { + +} + +func TestQueryDelegatorWithdrawAddress(t *testing.T) { + +} + +func TestQueryCommunityPool(t *testing.T) { + +} diff --git a/x/distribution/keeper/keeper_test.go b/x/distribution/keeper/keeper_test.go index 089e8f626341..dd08427cf933 100644 --- a/x/distribution/keeper/keeper_test.go +++ b/x/distribution/keeper/keeper_test.go @@ -11,6 +11,7 @@ import ( "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" @@ -23,7 +24,14 @@ import ( "github.com/cosmos/cosmos-sdk/x/distribution/types" ) -func TestSetWithdrawAddr(t *testing.T) { +type dep struct { + bankKeeper *distrtestutil.MockBankKeeper + stakingKeeper *distrtestutil.MockStakingKeeper + accountKeeper *distrtestutil.MockAccountKeeper + poolKeeper *distrtestutil.MockPoolKeeper +} + +func initFixture(t *testing.T) (sdk.Context, []sdk.AccAddress, keeper.Keeper, dep) { ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(types.StoreKey) storeService := runtime.NewKVStoreService(key) @@ -32,16 +40,17 @@ func TestSetWithdrawAddr(t *testing.T) { ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) addrs := simtestutil.CreateIncrementalAccounts(2) - delegatorAddr := addrs[0] - withdrawAddr := addrs[1] - bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) + accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() + + stakingKeeper.EXPECT().ValidatorAddressCodec().Return(address.NewBech32Codec("cosmosvaloper")).AnyTimes() + withdrawAddr := addrs[1] bankKeeper.EXPECT().BlockedAddr(withdrawAddr).Return(false).AnyTimes() bankKeeper.EXPECT().BlockedAddr(distrAcc.GetAddress()).Return(true).AnyTimes() @@ -56,10 +65,22 @@ func TestSetWithdrawAddr(t *testing.T) { authtypes.NewModuleAddress("gov").String(), ) + params := types.DefaultParams() + require.NoError(t, distrKeeper.Params.Set(ctx, params)) + + return ctx, addrs, distrKeeper, dep{bankKeeper, stakingKeeper, accountKeeper, poolKeeper} +} + +func TestSetWithdrawAddr(t *testing.T) { + ctx, addrs, distrKeeper, _ := initFixture(t) + params := types.DefaultParams() params.WithdrawAddrEnabled = false require.NoError(t, distrKeeper.Params.Set(ctx, params)) + delegatorAddr := addrs[0] + withdrawAddr := addrs[1] + err := distrKeeper.SetWithdrawAddr(ctx, delegatorAddr, withdrawAddr) require.NotNil(t, err) @@ -76,39 +97,14 @@ func TestSetWithdrawAddr(t *testing.T) { } func TestWithdrawValidatorCommission(t *testing.T) { - ctrl := gomock.NewController(t) - key := storetypes.NewKVStoreKey(types.StoreKey) - storeService := runtime.NewKVStoreService(key) - testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) - encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) - ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) - addrs := simtestutil.CreateIncrementalAccounts(1) + ctx, addrs, distrKeeper, dep := initFixture(t) valAddr := sdk.ValAddress(addrs[0]) - - bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) - stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) - accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) - - accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) - valCommission := sdk.DecCoins{ sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))), sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))), } - distrKeeper := keeper.NewKeeper( - encCfg.Codec, - storeService, - accountKeeper, - bankKeeper, - stakingKeeper, - poolKeeper, - "fee_collector", - authtypes.NewModuleAddress("gov").String(), - ) - // set outstanding rewards require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission})) @@ -118,7 +114,7 @@ func TestWithdrawValidatorCommission(t *testing.T) { // withdraw commission coins := sdk.NewCoins(sdk.NewCoin("mytoken", math.NewInt(1)), sdk.NewCoin("stake", math.NewInt(1))) // if SendCoinsFromModuleToAccount is called, we know that the withdraw was successful - bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), "distribution", addrs[0], coins).Return(nil) + dep.bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), "distribution", addrs[0], coins).Return(nil) _, err := distrKeeper.WithdrawValidatorCommission(ctx, valAddr) require.NoError(t, err) @@ -134,42 +130,15 @@ func TestWithdrawValidatorCommission(t *testing.T) { } func TestGetTotalRewards(t *testing.T) { - ctrl := gomock.NewController(t) - key := storetypes.NewKVStoreKey(types.StoreKey) - storeService := runtime.NewKVStoreService(key) - testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) - encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{}) - ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()}) - addrs := simtestutil.CreateIncrementalAccounts(2) - - valAddr0 := sdk.ValAddress(addrs[0]) - valAddr1 := sdk.ValAddress(addrs[1]) - - bankKeeper := distrtestutil.NewMockBankKeeper(ctrl) - stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl) - accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl) - poolKeeper := distrtestutil.NewMockPoolKeeper(ctrl) - - accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress()) - - distrKeeper := keeper.NewKeeper( - encCfg.Codec, - storeService, - accountKeeper, - bankKeeper, - stakingKeeper, - poolKeeper, - "fee_collector", - authtypes.NewModuleAddress("gov").String(), - ) + ctx, addrs, distrKeeper, _ := initFixture(t) valCommission := sdk.DecCoins{ sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))), sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))), } - require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, valAddr0, types.ValidatorOutstandingRewards{Rewards: valCommission})) - require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, valAddr1, types.ValidatorOutstandingRewards{Rewards: valCommission})) + require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, sdk.ValAddress(addrs[0]), types.ValidatorOutstandingRewards{Rewards: valCommission})) + require.NoError(t, distrKeeper.ValidatorOutstandingRewards.Set(ctx, sdk.ValAddress(addrs[1]), types.ValidatorOutstandingRewards{Rewards: valCommission})) expectedRewards := valCommission.MulDec(math.LegacyNewDec(2)) totalRewards := distrKeeper.GetTotalRewards(ctx) diff --git a/x/distribution/keeper/msg_server.go b/x/distribution/keeper/msg_server.go index 3feb052fbc34..77ec9db0db31 100644 --- a/x/distribution/keeper/msg_server.go +++ b/x/distribution/keeper/msg_server.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" "github.com/hashicorp/go-metrics" @@ -154,7 +155,7 @@ func (k msgServer) CommunityPoolSpend(ctx context.Context, msg *types.MsgCommuni recipient, err := k.authKeeper.AddressCodec().StringToBytes(msg.Recipient) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid recipient address: %w", err) } if err := k.poolKeeper.DistributeFromFeePool(ctx, msg.Amount, recipient); err != nil { @@ -170,7 +171,7 @@ func (k msgServer) CommunityPoolSpend(ctx context.Context, msg *types.MsgCommuni func (k msgServer) DepositValidatorRewardsPool(ctx context.Context, msg *types.MsgDepositValidatorRewardsPool) (*types.MsgDepositValidatorRewardsPoolResponse, error) { depositor, err := k.authKeeper.AddressCodec().StringToBytes(msg.Depositor) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid depositor address: %w", err) } // deposit coins from depositor's account to the distribution module diff --git a/x/distribution/keeper/msg_server_test.go b/x/distribution/keeper/msg_server_test.go index 9429264902a9..ecae0b5352d9 100644 --- a/x/distribution/keeper/msg_server_test.go +++ b/x/distribution/keeper/msg_server_test.go @@ -1 +1,356 @@ package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + "github.com/cosmos/cosmos-sdk/x/distribution/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestMsgSetWithdrawAddress(t *testing.T) { + ctx, addrs, distrKeeper, _ := initFixture(t) + msgServer := keeper.NewMsgServerImpl(distrKeeper) + + cases := []struct { + name string + msg *types.MsgSetWithdrawAddress + errMsg string + }{ + { + name: "success", + msg: &types.MsgSetWithdrawAddress{ + DelegatorAddress: addrs[0].String(), + WithdrawAddress: addrs[1].String(), + }, + errMsg: "", + }, + { + name: "invalid delegator address", + msg: &types.MsgSetWithdrawAddress{ + DelegatorAddress: "invalid", + WithdrawAddress: addrs[1].String(), + }, + errMsg: "invalid address", + }, + { + name: "invalid withdraw address", + msg: &types.MsgSetWithdrawAddress{ + DelegatorAddress: addrs[0].String(), + WithdrawAddress: "invalid", + }, + errMsg: "invalid address", + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := msgServer.SetWithdrawAddress(ctx, tc.msg) + if tc.errMsg == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } + }) + } +} + +func TestMsgWithdrawDelegatorReward(t *testing.T) { + ctx, addrs, distrKeeper, dep := initFixture(t) + dep.stakingKeeper.EXPECT().Validator(gomock.Any(), gomock.Any()).AnyTimes() + msgServer := keeper.NewMsgServerImpl(distrKeeper) + + cases := []struct { + name string + preRun func() + msg *types.MsgWithdrawDelegatorReward + errMsg string + }{ + { + name: "invalid delegator address", + msg: &types.MsgWithdrawDelegatorReward{ + DelegatorAddress: "invalid", + ValidatorAddress: sdk.ValAddress(addrs[1]).String(), + }, + errMsg: "invalid delegator address", + }, + { + name: "invalid validator address", + msg: &types.MsgWithdrawDelegatorReward{ + DelegatorAddress: addrs[0].String(), + ValidatorAddress: "invalid", + }, + errMsg: "invalid validator address", + }, + { + name: "no validator", + msg: &types.MsgWithdrawDelegatorReward{ + DelegatorAddress: addrs[0].String(), + ValidatorAddress: sdk.ValAddress(addrs[1]).String(), + }, + errMsg: "no validator distribution info", + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + if tc.preRun != nil { + tc.preRun() + } + _, err := msgServer.WithdrawDelegatorReward(ctx, tc.msg) + if tc.errMsg == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } + }) + } +} + +func TestMsgWithdrawValidatorCommission(t *testing.T) { + ctx, addrs, distrKeeper, _ := initFixture(t) + msgServer := keeper.NewMsgServerImpl(distrKeeper) + + cases := []struct { + name string + preRun func() + msg *types.MsgWithdrawValidatorCommission + errMsg string + }{ + { + name: "invalid validator address", + msg: &types.MsgWithdrawValidatorCommission{ + ValidatorAddress: "invalid", + }, + errMsg: "invalid validator address", + }, + { + name: "no validator commission to withdraw", + msg: &types.MsgWithdrawValidatorCommission{ + ValidatorAddress: sdk.ValAddress(addrs[1]).String(), + }, + errMsg: "no validator commission to withdraw", + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + if tc.preRun != nil { + tc.preRun() + } + _, err := msgServer.WithdrawValidatorCommission(ctx, tc.msg) + if tc.errMsg == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } + }) + } +} + +func TestMsgFundCommunityPool(t *testing.T) { + ctx, addrs, distrKeeper, dep := initFixture(t) + dep.poolKeeper.EXPECT().FundCommunityPool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + msgServer := keeper.NewMsgServerImpl(distrKeeper) + + cases := []struct { + name string + msg *types.MsgFundCommunityPool + errMsg string + }{ + { + name: "invalid depositor address", + msg: &types.MsgFundCommunityPool{ + Depositor: "invalid", + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), + }, + errMsg: "invalid depositor address", + }, + { + name: "success", + msg: &types.MsgFundCommunityPool{ + Depositor: addrs[0].String(), + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000))), + }, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := msgServer.FundCommunityPool(ctx, tc.msg) + if tc.errMsg == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } + }) + } +} + +func TestMsgUpdateParams(t *testing.T) { + ctx, addrs, distrKeeper, _ := initFixture(t) + msgServer := keeper.NewMsgServerImpl(distrKeeper) + + cases := []struct { + name string + msg *types.MsgUpdateParams + errMsg string + }{ + { + name: "invalid authority", + msg: &types.MsgUpdateParams{ + Authority: "invalid", + Params: types.DefaultParams(), + }, + errMsg: "invalid address", + }, + { + name: "incorrect authority", + msg: &types.MsgUpdateParams{ + Authority: addrs[0].String(), + Params: types.DefaultParams(), + }, + errMsg: "expected authority account as only signer for proposal message", + }, + { + name: "invalid params", + msg: &types.MsgUpdateParams{ + Authority: authtypes.NewModuleAddress("gov").String(), + Params: types.Params{CommunityTax: math.LegacyNewDec(-1)}, + }, + errMsg: "community tax must be positive", + }, + { + name: "success", + msg: &types.MsgUpdateParams{ + Authority: authtypes.NewModuleAddress("gov").String(), + Params: types.DefaultParams(), + }, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := msgServer.UpdateParams(ctx, tc.msg) + if tc.errMsg == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } + }) + } +} + +func TestMsgCommunityPoolSpend(t *testing.T) { + ctx, addrs, distrKeeper, dep := initFixture(t) + dep.poolKeeper.EXPECT().DistributeFromFeePool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + msgServer := keeper.NewMsgServerImpl(distrKeeper) + + cases := []struct { + name string + msg *types.MsgCommunityPoolSpend + errMsg string + }{ + { + name: "invalid authority", + msg: &types.MsgCommunityPoolSpend{ + Authority: "invalid", + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), + }, + errMsg: "invalid address", + }, + { + name: "incorrect authority", + msg: &types.MsgCommunityPoolSpend{ + Authority: addrs[0].String(), + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), + }, + errMsg: "expected authority account as only signer for proposal message", + }, + { + name: "invalid recipient address", + msg: &types.MsgCommunityPoolSpend{ + Authority: authtypes.NewModuleAddress("gov").String(), + Recipient: "invalid", + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), + }, + errMsg: "invalid recipient address", + }, + { + name: "invalid amount", + msg: &types.MsgCommunityPoolSpend{ + Authority: authtypes.NewModuleAddress("gov").String(), + Recipient: addrs[0].String(), + }, + errMsg: "invalid coins", + }, + { + name: "success", + msg: &types.MsgCommunityPoolSpend{ + Authority: authtypes.NewModuleAddress("gov").String(), + Recipient: addrs[0].String(), + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000))), + }, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := msgServer.CommunityPoolSpend(ctx, tc.msg) + if tc.errMsg == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } + }) + } +} + +func TestMsgDepositValidatorRewardsPool(t *testing.T) { + ctx, _, distrKeeper, _ := initFixture(t) + msgServer := keeper.NewMsgServerImpl(distrKeeper) + + cases := []struct { + name string + msg *types.MsgDepositValidatorRewardsPool + errMsg string + }{ + { + name: "invalid depositor address", + msg: &types.MsgDepositValidatorRewardsPool{ + Depositor: "invalid", + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), + }, + errMsg: "invalid depositor address", + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := msgServer.DepositValidatorRewardsPool(ctx, tc.msg) + if tc.errMsg == "" { + require.NoError(t, err) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } + }) + } +} From 5cb6f2fe2fff3c17bbd4474d22a03b2ea8494ff3 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 9 Oct 2023 21:58:03 +0200 Subject: [PATCH 11/15] updates --- tests/e2e/distribution/cli_test.go | 4 + tests/e2e/distribution/grpc_query_suite.go | 460 +++++++++++++++++++++ x/bank/client/cli/tx.go | 9 +- x/bank/client/cli/tx_test.go | 2 +- x/bank/module.go | 6 +- x/distribution/autocli.go | 19 +- x/distribution/client/cli/tx.go | 61 ++- x/distribution/client/cli/tx_test.go | 2 +- x/distribution/client/cli/util_test.go | 59 --- x/distribution/keeper/grpc_query_test.go | 156 ++++++- x/distribution/keeper/msg_server_test.go | 22 +- x/distribution/module.go | 6 +- x/slashing/client/cli/tx.go | 10 +- x/slashing/client/cli/tx_test.go | 2 +- x/slashing/module.go | 2 +- x/staking/client/cli/tx.go | 48 +-- x/staking/client/cli/tx_test.go | 12 +- x/staking/module.go | 5 +- 18 files changed, 694 insertions(+), 191 deletions(-) create mode 100644 tests/e2e/distribution/grpc_query_suite.go delete mode 100644 x/distribution/client/cli/util_test.go diff --git a/tests/e2e/distribution/cli_test.go b/tests/e2e/distribution/cli_test.go index 8883a5bc44c6..ad8e877d9611 100644 --- a/tests/e2e/distribution/cli_test.go +++ b/tests/e2e/distribution/cli_test.go @@ -12,3 +12,7 @@ import ( func TestWithdrawAllSuite(t *testing.T) { suite.Run(t, new(WithdrawAllTestSuite)) } + +func TestGRPCQueryTestSuite(t *testing.T) { + suite.Run(t, new(GRPCQueryTestSuite)) +} diff --git a/tests/e2e/distribution/grpc_query_suite.go b/tests/e2e/distribution/grpc_query_suite.go new file mode 100644 index 000000000000..1ebe3862bbad --- /dev/null +++ b/tests/e2e/distribution/grpc_query_suite.go @@ -0,0 +1,460 @@ +package distribution + +import ( + "fmt" + + "github.com/cosmos/gogoproto/proto" + "github.com/stretchr/testify/suite" + + "cosmossdk.io/simapp" + + sdktestutil "github.com/cosmos/cosmos-sdk/testutil" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/distribution/types" +) + +type GRPCQueryTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +func (s *GRPCQueryTestSuite) SetupSuite() { + s.T().Log("setting up e2e test suite") + + cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) + cfg.NumValidators = 1 + s.cfg = cfg + + var err error + s.network, err = network.New(s.T(), s.T().TempDir(), cfg) + s.Require().NoError(err) + + s.Require().NoError(s.network.WaitForNextBlock()) +} + +// TearDownSuite cleans up the curret test network after _each_ test. +func (s *GRPCQueryTestSuite) TearDownSuite() { + s.T().Log("tearing down e2e test suite1") + s.network.Cleanup() +} + +func (s *GRPCQueryTestSuite) TestQueryParamsGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + testCases := []struct { + name string + url string + respType proto.Message + expected proto.Message + }{ + { + "gRPC request params", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/params", baseURL), + &types.QueryParamsResponse{}, + &types.QueryParamsResponse{ + Params: types.DefaultParams(), + }, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequest(tc.url) + s.Run(tc.name, func() { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected, tc.respType) + }) + } +} + +func (s *GRPCQueryTestSuite) TestQueryValidatorDistributionInfoGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + testCases := []struct { + name string + url string + expErr bool + respType proto.Message + }{ + { + "gRPC request with wrong validator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s", baseURL, "wrongAddress"), + true, + &types.QueryValidatorDistributionInfoResponse{}, + }, + { + "gRPC request with valid validator address ", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s", baseURL, val.ValAddress.String()), + false, + &types.QueryValidatorDistributionInfoResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequest(tc.url) + s.Run(tc.name, func() { + if tc.expErr { + s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } else { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } + }) + } +} + +func (s *GRPCQueryTestSuite) TestQueryOutstandingRewardsGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + rewards, err := sdk.ParseDecCoins("19.6stake") + s.Require().NoError(err) + + testCases := []struct { + name string + url string + headers map[string]string + expErr bool + respType proto.Message + expected proto.Message + }{ + { + "gRPC request params with wrong validator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/outstanding_rewards", baseURL, "wrongAddress"), + map[string]string{}, + true, + &types.QueryValidatorOutstandingRewardsResponse{}, + &types.QueryValidatorOutstandingRewardsResponse{}, + }, + { + "gRPC request params valid address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/outstanding_rewards", baseURL, val.ValAddress.String()), + map[string]string{ + grpctypes.GRPCBlockHeightHeader: "2", + }, + false, + &types.QueryValidatorOutstandingRewardsResponse{}, + &types.QueryValidatorOutstandingRewardsResponse{ + Rewards: types.ValidatorOutstandingRewards{ + Rewards: rewards, + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequestWithHeaders(tc.url, tc.headers) + s.Run(tc.name, func() { + if tc.expErr { + s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } else { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected.String(), tc.respType.String()) + } + }) + } +} + +func (s *GRPCQueryTestSuite) TestQueryValidatorCommissionGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + commission, err := sdk.ParseDecCoins("9.8stake") + s.Require().NoError(err) + + testCases := []struct { + name string + url string + headers map[string]string + expErr bool + respType proto.Message + expected proto.Message + }{ + { + "gRPC request params with wrong validator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/commission", baseURL, "wrongAddress"), + map[string]string{}, + true, + &types.QueryValidatorCommissionResponse{}, + &types.QueryValidatorCommissionResponse{}, + }, + { + "gRPC request params valid address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/commission", baseURL, val.ValAddress.String()), + map[string]string{ + grpctypes.GRPCBlockHeightHeader: "2", + }, + false, + &types.QueryValidatorCommissionResponse{}, + &types.QueryValidatorCommissionResponse{ + Commission: types.ValidatorAccumulatedCommission{ + Commission: commission, + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequestWithHeaders(tc.url, tc.headers) + s.Run(tc.name, func() { + if tc.expErr { + s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } else { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected.String(), tc.respType.String()) + } + }) + } +} + +func (s *GRPCQueryTestSuite) TestQuerySlashesGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + testCases := []struct { + name string + url string + expErr bool + respType proto.Message + expected proto.Message + }{ + { + "invalid validator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes", baseURL, ""), + true, + &types.QueryValidatorSlashesResponse{}, + nil, + }, + { + "invalid start height", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes?starting_height=%s&ending_height=%s", baseURL, val.ValAddress.String(), "-1", "3"), + true, + &types.QueryValidatorSlashesResponse{}, + nil, + }, + { + "invalid start height", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes?starting_height=%s&ending_height=%s", baseURL, val.ValAddress.String(), "1", "-3"), + true, + &types.QueryValidatorSlashesResponse{}, + nil, + }, + { + "valid request get slashes", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/validators/%s/slashes?starting_height=%s&ending_height=%s", baseURL, val.ValAddress.String(), "1", "3"), + false, + &types.QueryValidatorSlashesResponse{}, + &types.QueryValidatorSlashesResponse{ + Pagination: &query.PageResponse{}, + }, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequest(tc.url) + + s.Run(tc.name, func() { + if tc.expErr { + s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } else { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected.String(), tc.respType.String()) + } + }) + } +} + +func (s *GRPCQueryTestSuite) TestQueryDelegatorRewardsGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + rewards, err := sdk.ParseDecCoins("9.8stake") + s.Require().NoError(err) + + testCases := []struct { + name string + url string + headers map[string]string + expErr bool + respType proto.Message + expected proto.Message + }{ + { + "wrong delegator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards", baseURL, "wrongDelegatorAddress"), + map[string]string{}, + true, + &types.QueryDelegationTotalRewardsResponse{}, + nil, + }, + { + "valid request", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards", baseURL, val.Address.String()), + map[string]string{ + grpctypes.GRPCBlockHeightHeader: "2", + }, + false, + &types.QueryDelegationTotalRewardsResponse{}, + &types.QueryDelegationTotalRewardsResponse{ + Rewards: []types.DelegationDelegatorReward{ + types.NewDelegationDelegatorReward(val.ValAddress.String(), rewards), + }, + Total: rewards, + }, + }, + { + "wrong validator address(specific validator rewards)", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards/%s", baseURL, val.Address.String(), "wrongValAddress"), + map[string]string{}, + true, + &types.QueryDelegationTotalRewardsResponse{}, + nil, + }, + { + "valid request(specific validator rewards)", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/rewards/%s", baseURL, val.Address.String(), val.ValAddress.String()), + map[string]string{ + grpctypes.GRPCBlockHeightHeader: "2", + }, + false, + &types.QueryDelegationRewardsResponse{}, + &types.QueryDelegationRewardsResponse{ + Rewards: rewards, + }, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequestWithHeaders(tc.url, tc.headers) + + s.Run(tc.name, func() { + if tc.expErr { + s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } else { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected.String(), tc.respType.String()) + } + }) + } +} + +func (s *GRPCQueryTestSuite) TestQueryDelegatorValidatorsGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + testCases := []struct { + name string + url string + expErr bool + respType proto.Message + expected proto.Message + }{ + { + "empty delegator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/validators", baseURL, ""), + true, + &types.QueryDelegatorValidatorsResponse{}, + nil, + }, + { + "wrong delegator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/validators", baseURL, "wrongDelegatorAddress"), + true, + &types.QueryDelegatorValidatorsResponse{}, + nil, + }, + { + "valid request", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/validators", baseURL, val.Address.String()), + false, + &types.QueryDelegatorValidatorsResponse{}, + &types.QueryDelegatorValidatorsResponse{ + Validators: []string{val.ValAddress.String()}, + }, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequest(tc.url) + + s.Run(tc.name, func() { + if tc.expErr { + s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } else { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected.String(), tc.respType.String()) + } + }) + } +} + +func (s *GRPCQueryTestSuite) TestQueryWithdrawAddressGRPC() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + testCases := []struct { + name string + url string + expErr bool + respType proto.Message + expected proto.Message + }{ + { + "empty delegator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", baseURL, ""), + true, + &types.QueryDelegatorWithdrawAddressResponse{}, + nil, + }, + { + "wrong delegator address", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", baseURL, "wrongDelegatorAddress"), + true, + &types.QueryDelegatorWithdrawAddressResponse{}, + nil, + }, + { + "valid request", + fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", baseURL, val.Address.String()), + false, + &types.QueryDelegatorWithdrawAddressResponse{}, + &types.QueryDelegatorWithdrawAddressResponse{ + WithdrawAddress: val.Address.String(), + }, + }, + } + + for _, tc := range testCases { + tc := tc + resp, err := sdktestutil.GetRequest(tc.url) + + s.Run(tc.name, func() { + if tc.expErr { + s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + } else { + s.Require().NoError(err) + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType)) + s.Require().Equal(tc.expected.String(), tc.respType.String()) + } + }) + } +} diff --git a/x/bank/client/cli/tx.go b/x/bank/client/cli/tx.go index d45db2b248f1..f39ef8398810 100644 --- a/x/bank/client/cli/tx.go +++ b/x/bank/client/cli/tx.go @@ -5,7 +5,6 @@ import ( "github.com/spf13/cobra" - "cosmossdk.io/core/address" sdkmath "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client" @@ -19,7 +18,7 @@ import ( var FlagSplit = "split" // NewTxCmd returns a root CLI command handler for all x/bank transaction commands. -func NewTxCmd(ac address.Codec) *cobra.Command { +func NewTxCmd() *cobra.Command { txCmd := &cobra.Command{ Use: types.ModuleName, Short: "Bank transaction subcommands", @@ -29,7 +28,7 @@ func NewTxCmd(ac address.Codec) *cobra.Command { } txCmd.AddCommand( - NewMultiSendTxCmd(ac), + NewMultiSendTxCmd(), ) return txCmd @@ -37,7 +36,7 @@ func NewTxCmd(ac address.Codec) *cobra.Command { // NewMultiSendTxCmd returns a CLI command handler for creating a MsgMultiSend transaction. // For a better UX this command is limited to send funds from one account to two or more accounts. -func NewMultiSendTxCmd(ac address.Codec) *cobra.Command { +func NewMultiSendTxCmd() *cobra.Command { cmd := &cobra.Command{ Use: "multi-send [from_key_or_address] [to_address_1 to_address_2 ...] [amount]", Short: "Send funds from one account to two or more accounts.", @@ -82,7 +81,7 @@ When using '--dry-run' a key name cannot be used, only a bech32 address.`, var output []types.Output for _, arg := range args[1 : len(args)-1] { - toAddr, err := ac.StringToBytes(arg) + toAddr, err := clientCtx.AddressCodec.StringToBytes(arg) if err != nil { return err } diff --git a/x/bank/client/cli/tx_test.go b/x/bank/client/cli/tx_test.go index e3f4e418ea01..e3b6378c535c 100644 --- a/x/bank/client/cli/tx_test.go +++ b/x/bank/client/cli/tx_test.go @@ -54,7 +54,7 @@ func (s *CLITestSuite) SetupSuite() { func (s *CLITestSuite) TestMultiSendTxCmd() { accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 3) - cmd := cli.NewMultiSendTxCmd(addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewMultiSendTxCmd() cmd.SetOutput(io.Discard) extraArgs := []string{ diff --git a/x/bank/module.go b/x/bank/module.go index 071897763279..e65b04dfd93b 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -10,7 +10,6 @@ import ( "github.com/spf13/cobra" modulev1 "cosmossdk.io/api/cosmos/bank/module/v1" - "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" corestore "cosmossdk.io/core/store" "cosmossdk.io/depinject" @@ -46,7 +45,6 @@ var ( // AppModuleBasic defines the basic application module used by the bank module. type AppModuleBasic struct { cdc codec.Codec - ac address.Codec } // Name returns the bank module's name. @@ -82,7 +80,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *g // GetTxCmd returns the root tx command for the bank module. func (ab AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd(ab.ac) + return cli.NewTxCmd() } // RegisterInterfaces registers interfaces and implementations of the bank module. @@ -127,7 +125,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { // NewAppModule creates a new AppModule object func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper) AppModule { return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc, ac: accountKeeper.AddressCodec()}, + AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, accountKeeper: accountKeeper, } diff --git a/x/distribution/autocli.go b/x/distribution/autocli.go index a720b5ca3ccd..61a4e7f8966e 100644 --- a/x/distribution/autocli.go +++ b/x/distribution/autocli.go @@ -2,7 +2,6 @@ package distribution import ( "fmt" - "strings" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" distirbuitonv1beta1 "cosmossdk.io/api/cosmos/distribution/v1beta1" @@ -17,11 +16,6 @@ var ( // AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { - exAccAddress, err := am.ac.BytesToString([]byte("A58856F0FD53BF058B4909A21AEC019107BA6A58856F0FD53BF058B4909A21AEC019107BA6")) - if err != nil { - panic(err) - } - return &autocliv1.ModuleOptions{ Query: &autocliv1.ServiceCommandDescriptor{ Service: distirbuitonv1beta1.Query_ServiceDesc.ServiceName, @@ -35,9 +29,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { RpcMethod: "ValidatorDistributionInfo", Use: "validator-distribution-info [validator]", Short: "Query validator distribution info", - Example: fmt.Sprintf(`Example: $ %s query distribution validator-distribution-info %s`, - version.AppName, exAccAddress, - ), + Example: fmt.Sprintf(`Example: $ %s query distribution validator-distribution-info [validator-addres]`, version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "validator_address"}, @@ -77,14 +69,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { Use: "rewards [delegator-addr] [validator-addr]", Short: "Query all distribution delegator rewards or rewards from a particular validator", Long: "Query all rewards earned by a delegator, optionally restrict to rewards from a single validator.", - Example: strings.TrimSpace( - fmt.Sprintf(` -$ %s query distribution rewards %s -$ %s query distribution rewards %s [validator-address] -`, - version.AppName, exAccAddress, version.AppName, exAccAddress, - ), - ), + Example: fmt.Sprintf("$ %s query distribution rewards [delegator-address] [validator-address]", version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "delegator_address"}, {ProtoField: "validator_address"}, diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index 7a76596b6816..2a10eaabdda8 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -4,9 +4,6 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/spf13/pflag" - - "cosmossdk.io/core/address" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -27,7 +24,7 @@ const ( ) // NewTxCmd returns a root CLI command handler for all x/distribution transaction commands. -func NewTxCmd(valAc, ac address.Codec) *cobra.Command { +func NewTxCmd() *cobra.Command { distTxCmd := &cobra.Command{ Use: types.ModuleName, Short: "Distribution transactions subcommands", @@ -37,42 +34,14 @@ func NewTxCmd(valAc, ac address.Codec) *cobra.Command { } distTxCmd.AddCommand( - NewWithdrawAllRewardsCmd(valAc, ac), + NewWithdrawAllRewardsCmd(), ) return distTxCmd } -type newGenerateOrBroadcastFunc func(client.Context, *pflag.FlagSet, ...sdk.Msg) error - -func newSplitAndApply( - genOrBroadcastFn newGenerateOrBroadcastFunc, clientCtx client.Context, - fs *pflag.FlagSet, msgs []sdk.Msg, chunkSize int, -) error { - if chunkSize == 0 { - return genOrBroadcastFn(clientCtx, fs, msgs...) - } - - // split messages into slices of length chunkSize - totalMessages := len(msgs) - for i := 0; i < len(msgs); i += chunkSize { - - sliceEnd := i + chunkSize - if sliceEnd > totalMessages { - sliceEnd = totalMessages - } - - msgChunk := msgs[i:sliceEnd] - if err := genOrBroadcastFn(clientCtx, fs, msgChunk...); err != nil { - return err - } - } - - return nil -} - // NewWithdrawAllRewardsCmd returns a CLI command handler for creating a MsgWithdrawDelegatorReward transaction. -func NewWithdrawAllRewardsCmd(valCodec, ac address.Codec) *cobra.Command { +func NewWithdrawAllRewardsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "withdraw-all-rewards", Short: "withdraw all delegations rewards for a delegator", @@ -83,7 +52,7 @@ func NewWithdrawAllRewardsCmd(valCodec, ac address.Codec) *cobra.Command { if err != nil { return err } - delAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) + delAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress()) if err != nil { return err } @@ -104,7 +73,7 @@ func NewWithdrawAllRewardsCmd(valCodec, ac address.Codec) *cobra.Command { // build multi-message transaction msgs := make([]sdk.Msg, 0, len(validators)) for _, valAddr := range validators { - _, err := valCodec.StringToBytes(valAddr) + _, err := clientCtx.ValidatorAddressCodec.StringToBytes(valAddr) if err != nil { return err } @@ -114,8 +83,26 @@ func NewWithdrawAllRewardsCmd(valCodec, ac address.Codec) *cobra.Command { } chunkSize, _ := cmd.Flags().GetInt(FlagMaxMessagesPerTx) + if chunkSize == 0 { + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgs...) + } + + // split messages into slices of length chunkSize + totalMessages := len(msgs) + for i := 0; i < len(msgs); i += chunkSize { + + sliceEnd := i + chunkSize + if sliceEnd > totalMessages { + sliceEnd = totalMessages + } + + msgChunk := msgs[i:sliceEnd] + if err := tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgChunk...); err != nil { + return err + } + } - return newSplitAndApply(tx.GenerateOrBroadcastTxCLI, clientCtx, cmd.Flags(), msgs, chunkSize) + return nil }, } diff --git a/x/distribution/client/cli/tx_test.go b/x/distribution/client/cli/tx_test.go index 838c90210706..2a4c1b331b66 100644 --- a/x/distribution/client/cli/tx_test.go +++ b/x/distribution/client/cli/tx_test.go @@ -115,7 +115,7 @@ func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() { tc := tc s.Run(tc.name, func() { - cmd := cli.NewWithdrawAllRewardsCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewWithdrawAllRewardsCmd() out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) if tc.expectErrMsg != "" { diff --git a/x/distribution/client/cli/util_test.go b/x/distribution/client/cli/util_test.go deleted file mode 100644 index 0c1ea11ff5f7..000000000000 --- a/x/distribution/client/cli/util_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package cli - -import ( - "testing" - - "github.com/spf13/pflag" - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func Test_splitAndCall_NoMessages(t *testing.T) { - clientCtx := client.Context{} - - err := newSplitAndApply(nil, clientCtx, nil, nil, 10) - require.NoError(t, err, "") -} - -func Test_splitAndCall_Splitting(t *testing.T) { - clientCtx := client.Context{} - - addr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) - - // Add five messages - msgs := []sdk.Msg{ - testdata.NewTestMsg(addr), - testdata.NewTestMsg(addr), - testdata.NewTestMsg(addr), - testdata.NewTestMsg(addr), - testdata.NewTestMsg(addr), - } - - // Keep track of number of calls - const chunkSize = 2 - - callCount := 0 - err := newSplitAndApply( - func(clientCtx client.Context, fs *pflag.FlagSet, msgs ...sdk.Msg) error { - callCount++ - - require.NotNil(t, clientCtx) - require.NotNil(t, msgs) - - if callCount < 3 { - require.Equal(t, len(msgs), 2) - } else { - require.Equal(t, len(msgs), 1) - } - - return nil - }, - clientCtx, nil, msgs, chunkSize) - - require.NoError(t, err, "") - require.Equal(t, 3, callCount) -} diff --git a/x/distribution/keeper/grpc_query_test.go b/x/distribution/keeper/grpc_query_test.go index a5e17badda58..b384c05c3265 100644 --- a/x/distribution/keeper/grpc_query_test.go +++ b/x/distribution/keeper/grpc_query_test.go @@ -1,43 +1,177 @@ package keeper_test -import "testing" +import ( + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + distrtestutil "github.com/cosmos/cosmos-sdk/x/distribution/testutil" + "github.com/cosmos/cosmos-sdk/x/distribution/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) func TestQueryParams(t *testing.T) { - + ctx, _, distrKeeper, _ := initFixture(t) + queryServer := keeper.NewQuerier(distrKeeper) + + cases := []struct { + name string + req *types.QueryParamsRequest + resp *types.QueryParamsResponse + errMsg string + }{ + { + name: "success", + req: &types.QueryParamsRequest{}, + resp: &types.QueryParamsResponse{ + Params: types.DefaultParams(), + }, + errMsg: "", + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + out, err := queryServer.Params(ctx, tc.req) + if tc.errMsg == "" { + require.NoError(t, err) + require.Equal(t, tc.resp, out) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + require.Nil(t, out) + } + }) + } } func TestQueryValidatorDistributionInfo(t *testing.T) { - + ctx, addrs, distrKeeper, dep := initFixture(t) + queryServer := keeper.NewQuerier(distrKeeper) + + val, err := distrtestutil.CreateValidator(valConsPk0, math.NewInt(100)) + require.NoError(t, err) + + del := stakingtypes.NewDelegation(addrs[0].String(), val.OperatorAddress, val.DelegatorShares) + + dep.stakingKeeper.EXPECT().Validator(gomock.Any(), gomock.Any()).Return(val, nil).AnyTimes() + dep.stakingKeeper.EXPECT().Delegation(gomock.Any(), gomock.Any(), gomock.Any()).Return(del, nil).AnyTimes() + + cases := []struct { + name string + req *types.QueryValidatorDistributionInfoRequest + resp *types.QueryValidatorDistributionInfoResponse + errMsg string + }{ + { + name: "invalid validator address", + req: &types.QueryValidatorDistributionInfoRequest{ + ValidatorAddress: "invalid address", + }, + resp: &types.QueryValidatorDistributionInfoResponse{}, + errMsg: "decoding bech32 failed", + }, + { + name: "not a validator", + req: &types.QueryValidatorDistributionInfoRequest{ + ValidatorAddress: addrs[0].String(), + }, + resp: &types.QueryValidatorDistributionInfoResponse{}, + errMsg: `expected 'cosmosvaloper' got 'cosmos'`, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + out, err := queryServer.ValidatorDistributionInfo(ctx, tc.req) + if tc.errMsg == "" { + require.NoError(t, err) + require.Equal(t, tc.resp, out) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + require.Nil(t, out) + } + }) + } } func TestQueryValidatorOutstandingRewards(t *testing.T) { - + // TODO https://github.com/cosmos/cosmos-sdk/issues/16757 + // currently tested in tests/e2e/distribution/grpc_query_suite.go } func TestQueryValidatorCommission(t *testing.T) { - + // TODO https://github.com/cosmos/cosmos-sdk/issues/16757 + // currently tested in tests/e2e/distribution/grpc_query_suite.go } func TestQueryValidatorSlashes(t *testing.T) { - + // TODO https://github.com/cosmos/cosmos-sdk/issues/16757 + // currently tested in tests/e2e/distribution/grpc_query_suite.go } func TestQueryDelegationRewards(t *testing.T) { - + // TODO https://github.com/cosmos/cosmos-sdk/issues/16757 + // currently tested in tests/e2e/distribution/grpc_query_suite.go } func TestQueryDelegationTotalRewards(t *testing.T) { - + // TODO https://github.com/cosmos/cosmos-sdk/issues/16757 + // currently tested in tests/e2e/distribution/grpc_query_suite.go } func TestQueryDelegatorValidators(t *testing.T) { - + // TODO https://github.com/cosmos/cosmos-sdk/issues/16757 + // currently tested in tests/e2e/distribution/grpc_query_suite.go } func TestQueryDelegatorWithdrawAddress(t *testing.T) { - + // TODO https://github.com/cosmos/cosmos-sdk/issues/16757 + // currently tested in tests/e2e/distribution/grpc_query_suite.go } func TestQueryCommunityPool(t *testing.T) { - + ctx, _, distrKeeper, dep := initFixture(t) + queryServer := keeper.NewQuerier(distrKeeper) + + coins := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))) + decCoins := sdk.NewDecCoinsFromCoins(coins...) + dep.poolKeeper.EXPECT().GetCommunityPool(gomock.Any()).Return(coins, nil).AnyTimes() + + cases := []struct { + name string + req *types.QueryCommunityPoolRequest //nolint:staticcheck // Testing deprecated method + resp *types.QueryCommunityPoolResponse //nolint:staticcheck // Testing deprecated method + errMsg string + }{ + { + name: "success", + req: &types.QueryCommunityPoolRequest{}, //nolint:staticcheck // Testing deprecated method + resp: &types.QueryCommunityPoolResponse{ //nolint:staticcheck // Testing deprecated method + Pool: decCoins, + }, + errMsg: "", + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + out, err := queryServer.CommunityPool(ctx, tc.req) + if tc.errMsg == "" { + require.NoError(t, err) + require.Equal(t, tc.resp, out) + } else { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + require.Nil(t, out) + } + }) + } } diff --git a/x/distribution/keeper/msg_server_test.go b/x/distribution/keeper/msg_server_test.go index ecae0b5352d9..df5b4616e9d8 100644 --- a/x/distribution/keeper/msg_server_test.go +++ b/x/distribution/keeper/msg_server_test.go @@ -165,12 +165,12 @@ func TestMsgFundCommunityPool(t *testing.T) { cases := []struct { name string - msg *types.MsgFundCommunityPool + msg *types.MsgFundCommunityPool //nolint:staticcheck // Testing deprecated method errMsg string }{ { name: "invalid depositor address", - msg: &types.MsgFundCommunityPool{ + msg: &types.MsgFundCommunityPool{ //nolint:staticcheck // Testing deprecated method Depositor: "invalid", Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), }, @@ -178,7 +178,7 @@ func TestMsgFundCommunityPool(t *testing.T) { }, { name: "success", - msg: &types.MsgFundCommunityPool{ + msg: &types.MsgFundCommunityPool{ //nolint:staticcheck // Testing deprecated method Depositor: addrs[0].String(), Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000))), }, @@ -188,7 +188,7 @@ func TestMsgFundCommunityPool(t *testing.T) { for _, tc := range cases { tc := tc t.Run(tc.name, func(t *testing.T) { - _, err := msgServer.FundCommunityPool(ctx, tc.msg) + _, err := msgServer.FundCommunityPool(ctx, tc.msg) //nolint:staticcheck // Testing deprecated method if tc.errMsg == "" { require.NoError(t, err) } else { @@ -262,12 +262,12 @@ func TestMsgCommunityPoolSpend(t *testing.T) { cases := []struct { name string - msg *types.MsgCommunityPoolSpend + msg *types.MsgCommunityPoolSpend //nolint:staticcheck // Testing deprecated method errMsg string }{ { name: "invalid authority", - msg: &types.MsgCommunityPoolSpend{ + msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method Authority: "invalid", Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), }, @@ -275,7 +275,7 @@ func TestMsgCommunityPoolSpend(t *testing.T) { }, { name: "incorrect authority", - msg: &types.MsgCommunityPoolSpend{ + msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method Authority: addrs[0].String(), Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), }, @@ -283,7 +283,7 @@ func TestMsgCommunityPoolSpend(t *testing.T) { }, { name: "invalid recipient address", - msg: &types.MsgCommunityPoolSpend{ + msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method Authority: authtypes.NewModuleAddress("gov").String(), Recipient: "invalid", Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(100))), @@ -292,7 +292,7 @@ func TestMsgCommunityPoolSpend(t *testing.T) { }, { name: "invalid amount", - msg: &types.MsgCommunityPoolSpend{ + msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method Authority: authtypes.NewModuleAddress("gov").String(), Recipient: addrs[0].String(), }, @@ -300,7 +300,7 @@ func TestMsgCommunityPoolSpend(t *testing.T) { }, { name: "success", - msg: &types.MsgCommunityPoolSpend{ + msg: &types.MsgCommunityPoolSpend{ //nolint:staticcheck // Testing deprecated method Authority: authtypes.NewModuleAddress("gov").String(), Recipient: addrs[0].String(), Amount: sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000))), @@ -311,7 +311,7 @@ func TestMsgCommunityPoolSpend(t *testing.T) { for _, tc := range cases { tc := tc t.Run(tc.name, func(t *testing.T) { - _, err := msgServer.CommunityPoolSpend(ctx, tc.msg) + _, err := msgServer.CommunityPoolSpend(ctx, tc.msg) //nolint:staticcheck // Testing deprecated method if tc.errMsg == "" { require.NoError(t, err) } else { diff --git a/x/distribution/module.go b/x/distribution/module.go index 6c179c537d83..b57b1925ebb2 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -9,7 +9,6 @@ import ( "github.com/spf13/cobra" modulev1 "cosmossdk.io/api/cosmos/distribution/module/v1" - "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "cosmossdk.io/core/store" "cosmossdk.io/depinject" @@ -45,7 +44,6 @@ var ( // AppModuleBasic defines the basic application module used by the distribution module. type AppModuleBasic struct { cdc codec.Codec - ac address.Codec } // Name returns the distribution module's name. @@ -83,7 +81,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux // GetTxCmd returns the root tx command for the distribution module. func (ab AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd(ab.cdc.InterfaceRegistry().SigningContext().ValidatorAddressCodec(), ab.cdc.InterfaceRegistry().SigningContext().AddressCodec()) + return cli.NewTxCmd() } // RegisterInterfaces implements InterfaceModule @@ -108,7 +106,7 @@ func NewAppModule( bankKeeper types.BankKeeper, stakingKeeper types.StakingKeeper, poolKeeper types.PoolKeeper, ) AppModule { return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc, ac: accountKeeper.AddressCodec()}, + AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, accountKeeper: accountKeeper, bankKeeper: bankKeeper, diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index 8e6ab0ead6d5..5a00d6329adf 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -3,8 +3,6 @@ package cli import ( "github.com/spf13/cobra" - "cosmossdk.io/core/address" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" @@ -12,7 +10,7 @@ import ( ) // NewTxCmd returns a root CLI command handler for all x/slashing transaction commands. -func NewTxCmd(ac address.Codec) *cobra.Command { +func NewTxCmd() *cobra.Command { slashingTxCmd := &cobra.Command{ Use: types.ModuleName, Short: "Slashing transaction subcommands", @@ -21,12 +19,12 @@ func NewTxCmd(ac address.Codec) *cobra.Command { RunE: client.ValidateCmd, } - slashingTxCmd.AddCommand(NewUnjailTxCmd(ac)) + slashingTxCmd.AddCommand(NewUnjailTxCmd()) return slashingTxCmd } // NewUnjailTxCmd returns a CLI command handler for creating a MsgUnjail transaction. -func NewUnjailTxCmd(valAc address.Codec) *cobra.Command { +func NewUnjailTxCmd() *cobra.Command { cmd := &cobra.Command{ Use: "unjail", Args: cobra.NoArgs, @@ -41,7 +39,7 @@ $ tx slashing unjail --from mykey return err } - valAddr, err := valAc.BytesToString(clientCtx.GetFromAddress()) + valAddr, err := clientCtx.ValidatorAddressCodec.BytesToString(clientCtx.GetFromAddress()) if err != nil { return err } diff --git a/x/slashing/client/cli/tx_test.go b/x/slashing/client/cli/tx_test.go index 603ea434a38b..177b5c8b90bc 100644 --- a/x/slashing/client/cli/tx_test.go +++ b/x/slashing/client/cli/tx_test.go @@ -100,7 +100,7 @@ func (s *CLITestSuite) TestNewUnjailTxCmd() { tc := tc s.Run(tc.name, func() { - cmd := cli.NewUnjailTxCmd(addresscodec.NewBech32Codec("cosmosvaloper")) + cmd := cli.NewUnjailTxCmd() clientCtx := s.clientCtx out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) diff --git a/x/slashing/module.go b/x/slashing/module.go index 5e71ec0d33b6..607c277416fd 100644 --- a/x/slashing/module.go +++ b/x/slashing/module.go @@ -85,7 +85,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *g // GetTxCmd returns the root tx command for the slashing module. func (amb AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd(amb.cdc.InterfaceRegistry().SigningContext().ValidatorAddressCodec()) + return cli.NewTxCmd() } // AppModule implements an application module for the slashing module. diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index ce4b57c6fa32..6b6381c5f539 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -34,7 +34,7 @@ var ( ) // NewTxCmd returns a root CLI command handler for all x/staking transaction commands. -func NewTxCmd(valAddrCodec, ac address.Codec) *cobra.Command { +func NewTxCmd() *cobra.Command { stakingTxCmd := &cobra.Command{ Use: types.ModuleName, Short: "Staking transaction subcommands", @@ -44,19 +44,19 @@ func NewTxCmd(valAddrCodec, ac address.Codec) *cobra.Command { } stakingTxCmd.AddCommand( - NewCreateValidatorCmd(valAddrCodec), - NewEditValidatorCmd(valAddrCodec), - NewDelegateCmd(valAddrCodec, ac), - NewRedelegateCmd(valAddrCodec, ac), - NewUnbondCmd(valAddrCodec, ac), - NewCancelUnbondingDelegation(valAddrCodec, ac), + NewCreateValidatorCmd(), + NewEditValidatorCmd(), + NewDelegateCmd(), + NewRedelegateCmd(), + NewUnbondCmd(), + NewCancelUnbondingDelegation(), ) return stakingTxCmd } // NewCreateValidatorCmd returns a CLI command handler for creating a MsgCreateValidator transaction. -func NewCreateValidatorCmd(ac address.Codec) *cobra.Command { +func NewCreateValidatorCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-validator [path/to/validator.json]", Short: "create new validator initialized with a self-delegation to it", @@ -100,7 +100,7 @@ where we can get the pubkey using "%s tendermint show-validator" return err } - txf, msg, err := newBuildCreateValidatorMsg(clientCtx, txf, cmd.Flags(), validator, ac) + txf, msg, err := newBuildCreateValidatorMsg(clientCtx, txf, cmd.Flags(), validator, clientCtx.ValidatorAddressCodec) if err != nil { return err } @@ -119,7 +119,7 @@ where we can get the pubkey using "%s tendermint show-validator" } // NewEditValidatorCmd returns a CLI command handler for creating a MsgEditValidator transaction. -func NewEditValidatorCmd(ac address.Codec) *cobra.Command { +func NewEditValidatorCmd() *cobra.Command { cmd := &cobra.Command{ Use: "edit-validator", Short: "edit an existing validator account", @@ -160,7 +160,7 @@ func NewEditValidatorCmd(ac address.Codec) *cobra.Command { newMinSelfDelegation = &msb } - valAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) + valAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress()) if err != nil { return err } @@ -180,7 +180,7 @@ func NewEditValidatorCmd(ac address.Codec) *cobra.Command { } // NewDelegateCmd returns a CLI command handler for creating a MsgDelegate transaction. -func NewDelegateCmd(valAddrCodec, ac address.Codec) *cobra.Command { +func NewDelegateCmd() *cobra.Command { cmd := &cobra.Command{ Use: "delegate [validator-addr] [amount]", Args: cobra.ExactArgs(2), @@ -204,12 +204,12 @@ $ %s tx staking delegate cosmosvalopers1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 1 return err } - delAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) + delAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress()) if err != nil { return err } - _, err = valAddrCodec.StringToBytes(args[0]) + _, err = clientCtx.ValidatorAddressCodec.StringToBytes(args[0]) if err != nil { return err } @@ -226,7 +226,7 @@ $ %s tx staking delegate cosmosvalopers1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 1 } // NewRedelegateCmd returns a CLI command handler for creating a MsgBeginRedelegate transaction. -func NewRedelegateCmd(valAddrCodec, ac address.Codec) *cobra.Command { +func NewRedelegateCmd() *cobra.Command { cmd := &cobra.Command{ Use: "redelegate [src-validator-addr] [dst-validator-addr] [amount]", Short: "Redelegate illiquid tokens from one validator to another", @@ -245,17 +245,17 @@ $ %s tx staking redelegate cosmosvalopers1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj if err != nil { return err } - delAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) + delAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress()) if err != nil { return err } - _, err = valAddrCodec.StringToBytes(args[0]) + _, err = clientCtx.ValidatorAddressCodec.StringToBytes(args[0]) if err != nil { return err } - _, err = valAddrCodec.StringToBytes(args[1]) + _, err = clientCtx.ValidatorAddressCodec.StringToBytes(args[1]) if err != nil { return err } @@ -277,7 +277,7 @@ $ %s tx staking redelegate cosmosvalopers1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj } // NewUnbondCmd returns a CLI command handler for creating a MsgUndelegate transaction. -func NewUnbondCmd(valAddrCodec, ac address.Codec) *cobra.Command { +func NewUnbondCmd() *cobra.Command { bech32PrefixValAddr := sdk.GetConfig().GetBech32ValidatorAddrPrefix() cmd := &cobra.Command{ @@ -299,11 +299,11 @@ $ %s tx staking unbond %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake --from return err } - delAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) + delAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress()) if err != nil { return err } - _, err = valAddrCodec.StringToBytes(args[0]) + _, err = clientCtx.ValidatorAddressCodec.StringToBytes(args[0]) if err != nil { return err } @@ -325,7 +325,7 @@ $ %s tx staking unbond %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake --from } // NewCancelUnbondingDelegation returns a CLI command handler for creating a MsgCancelUnbondingDelegation transaction. -func NewCancelUnbondingDelegation(valAddrCodec, ac address.Codec) *cobra.Command { +func NewCancelUnbondingDelegation() *cobra.Command { bech32PrefixValAddr := sdk.GetConfig().GetBech32ValidatorAddrPrefix() cmd := &cobra.Command{ @@ -348,12 +348,12 @@ $ %s tx staking cancel-unbond %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake if err != nil { return err } - delAddr, err := ac.BytesToString(clientCtx.GetFromAddress()) + delAddr, err := clientCtx.AddressCodec.BytesToString(clientCtx.GetFromAddress()) if err != nil { return err } - _, err = valAddrCodec.StringToBytes(args[0]) + _, err = clientCtx.ValidatorAddressCodec.StringToBytes(args[0]) if err != nil { return err } diff --git a/x/staking/client/cli/tx_test.go b/x/staking/client/cli/tx_test.go index e2c272cd3df9..c0dde9463486 100644 --- a/x/staking/client/cli/tx_test.go +++ b/x/staking/client/cli/tx_test.go @@ -169,7 +169,7 @@ func (s *CLITestSuite) TestPrepareConfigForTxCreateValidator() { func (s *CLITestSuite) TestNewCreateValidatorCmd() { require := s.Require() - cmd := cli.NewCreateValidatorCmd(addresscodec.NewBech32Codec("cosmosvaloper")) + cmd := cli.NewCreateValidatorCmd() validJSON := fmt.Sprintf(` { @@ -316,7 +316,7 @@ func (s *CLITestSuite) TestNewCreateValidatorCmd() { } func (s *CLITestSuite) TestNewEditValidatorCmd() { - cmd := cli.NewEditValidatorCmd(addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewEditValidatorCmd() moniker := "testing" details := "bio" @@ -439,7 +439,7 @@ func (s *CLITestSuite) TestNewEditValidatorCmd() { } func (s *CLITestSuite) TestNewDelegateCmd() { - cmd := cli.NewDelegateCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewDelegateCmd() testCases := []struct { name string @@ -502,7 +502,7 @@ func (s *CLITestSuite) TestNewDelegateCmd() { } func (s *CLITestSuite) TestNewRedelegateCmd() { - cmd := cli.NewRedelegateCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewRedelegateCmd() testCases := []struct { name string @@ -584,7 +584,7 @@ func (s *CLITestSuite) TestNewRedelegateCmd() { } func (s *CLITestSuite) TestNewUnbondCmd() { - cmd := cli.NewUnbondCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewUnbondCmd() testCases := []struct { name string @@ -647,7 +647,7 @@ func (s *CLITestSuite) TestNewUnbondCmd() { } func (s *CLITestSuite) TestNewCancelUnbondingDelegationCmd() { - cmd := cli.NewCancelUnbondingDelegation(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewCancelUnbondingDelegation() testCases := []struct { name string diff --git a/x/staking/module.go b/x/staking/module.go index 8c1cea7f69d2..b56294785711 100644 --- a/x/staking/module.go +++ b/x/staking/module.go @@ -49,7 +49,6 @@ var ( // AppModuleBasic defines the basic application module used by the staking module. type AppModuleBasic struct { cdc codec.Codec - ak types.AccountKeeper } // Name returns the staking module's name. @@ -92,7 +91,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *g // GetTxCmd returns the root tx command for the staking module. func (amb AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd(amb.cdc.InterfaceRegistry().SigningContext().ValidatorAddressCodec(), amb.cdc.InterfaceRegistry().SigningContext().AddressCodec()) + return cli.NewTxCmd() } // AppModule implements an application module for the staking module. @@ -112,7 +111,7 @@ func NewAppModule( bk types.BankKeeper, ) AppModule { return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc, ak: ak}, + AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, accountKeeper: ak, bankKeeper: bk, From b1408d06b372fd2c231b72cf2218cb6498db174f Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 9 Oct 2023 22:06:26 +0200 Subject: [PATCH 12/15] lint + fix --- tests/e2e/authz/tx.go | 3 +-- tests/e2e/bank/suite.go | 3 +-- tests/e2e/distribution/withdraw_all_suite.go | 7 +++---- tests/e2e/staking/suite.go | 3 +-- tests/e2e/staking/test_helpers.go | 5 ++--- x/distribution/autocli.go | 2 +- x/distribution/keeper/grpc_query_test.go | 6 ++++-- x/distribution/keeper/keeper_test.go | 2 ++ x/distribution/keeper/msg_server_test.go | 6 ++++-- 9 files changed, 19 insertions(+), 18 deletions(-) diff --git a/tests/e2e/authz/tx.go b/tests/e2e/authz/tx.go index a49ed06c7e25..0cac1f552a3b 100644 --- a/tests/e2e/authz/tx.go +++ b/tests/e2e/authz/tx.go @@ -12,7 +12,6 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client/flags" - addresscodec "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/testutil" @@ -179,7 +178,7 @@ var ( ) func execDelegate(val *network.Validator, args []string) (testutil.BufferWriter, error) { - cmd := stakingcli.NewDelegateCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) + cmd := stakingcli.NewDelegateCmd() clientCtx := val.ClientCtx return clitestutil.ExecTestCLICmd(clientCtx, cmd, args) } diff --git a/tests/e2e/bank/suite.go b/tests/e2e/bank/suite.go index 0cb3d837fe24..635c512251ac 100644 --- a/tests/e2e/bank/suite.go +++ b/tests/e2e/bank/suite.go @@ -10,7 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - addresscodec "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" @@ -387,5 +386,5 @@ func MsgMultiSendExec(clientCtx client.Context, from sdk.AccAddress, to []sdk.Ac args = append(args, amount.String()) args = append(args, extraArgs...) - return clitestutil.ExecTestCLICmd(clientCtx, cli.NewMultiSendTxCmd(addresscodec.NewBech32Codec("cosmos")), args) + return clitestutil.ExecTestCLICmd(clientCtx, cli.NewMultiSendTxCmd(), args) } diff --git a/tests/e2e/distribution/withdraw_all_suite.go b/tests/e2e/distribution/withdraw_all_suite.go index 4110f88bf077..6e1e76080e25 100644 --- a/tests/e2e/distribution/withdraw_all_suite.go +++ b/tests/e2e/distribution/withdraw_all_suite.go @@ -10,7 +10,6 @@ import ( "cosmossdk.io/simapp" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/testutil" @@ -88,7 +87,7 @@ func (s *WithdrawAllTestSuite) TestNewWithdrawAllRewardsGenerateOnly() { fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), } - cmd := stakingcli.NewDelegateCmd(clientCtx.InterfaceRegistry.SigningContext().ValidatorAddressCodec(), clientCtx.InterfaceRegistry.SigningContext().AddressCodec()) + cmd := stakingcli.NewDelegateCmd() _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) require.NoError(err) require.NoError(s.network.WaitForNextBlock()) @@ -115,7 +114,7 @@ func (s *WithdrawAllTestSuite) TestNewWithdrawAllRewardsGenerateOnly() { fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), } - cmd = cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) + cmd = cli.NewWithdrawAllRewardsCmd() out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) if err != nil { return err @@ -138,7 +137,7 @@ func (s *WithdrawAllTestSuite) TestNewWithdrawAllRewardsGenerateOnly() { fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), } - cmd = cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) + cmd = cli.NewWithdrawAllRewardsCmd() out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) require.NoError(err) // expect 1 transaction in the generated file when --max-msgs in a tx set 2, since there are only delegations. diff --git a/tests/e2e/staking/suite.go b/tests/e2e/staking/suite.go index fc5b3bb9277b..a7c61ebdda26 100644 --- a/tests/e2e/staking/suite.go +++ b/tests/e2e/staking/suite.go @@ -13,7 +13,6 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client/flags" - addresscodec "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" @@ -120,7 +119,7 @@ func (s *E2ETestSuite) TestBlockResults() { require.NoError(s.network.WaitForNextBlock()) // Use CLI to create a delegation from the new account to validator `val`. - cmd := cli.NewDelegateCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")) + cmd := cli.NewDelegateCmd() _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, []string{ val.ValAddress.String(), sdk.NewCoin(s.cfg.BondDenom, math.NewInt(150)).String(), diff --git a/tests/e2e/staking/test_helpers.go b/tests/e2e/staking/test_helpers.go index 6605dc867dae..e2951834d101 100644 --- a/tests/e2e/staking/test_helpers.go +++ b/tests/e2e/staking/test_helpers.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - addresscodec "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" sdk "github.com/cosmos/cosmos-sdk/types" @@ -32,7 +31,7 @@ func MsgRedelegateExec(clientCtx client.Context, from, src, dst, amount fmt.Stri args = append(args, extraArgs...) args = append(args, commonArgs...) - return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewRedelegateCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")), args) + return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewRedelegateCmd(), args) } // MsgUnbondExec creates a unbond message. @@ -48,5 +47,5 @@ func MsgUnbondExec(clientCtx client.Context, from, valAddress, args = append(args, commonArgs...) args = append(args, extraArgs...) - return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewUnbondCmd(addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos")), args) + return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewUnbondCmd(), args) } diff --git a/x/distribution/autocli.go b/x/distribution/autocli.go index 61a4e7f8966e..8984a58fdf01 100644 --- a/x/distribution/autocli.go +++ b/x/distribution/autocli.go @@ -29,7 +29,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { RpcMethod: "ValidatorDistributionInfo", Use: "validator-distribution-info [validator]", Short: "Query validator distribution info", - Example: fmt.Sprintf(`Example: $ %s query distribution validator-distribution-info [validator-addres]`, version.AppName), + Example: fmt.Sprintf(`Example: $ %s query distribution validator-distribution-info [validator-address]`, version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "validator_address"}, diff --git a/x/distribution/keeper/grpc_query_test.go b/x/distribution/keeper/grpc_query_test.go index b384c05c3265..b4860ba114b6 100644 --- a/x/distribution/keeper/grpc_query_test.go +++ b/x/distribution/keeper/grpc_query_test.go @@ -3,14 +3,16 @@ package keeper_test import ( "testing" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtestutil "github.com/cosmos/cosmos-sdk/x/distribution/testutil" "github.com/cosmos/cosmos-sdk/x/distribution/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func TestQueryParams(t *testing.T) { diff --git a/x/distribution/keeper/keeper_test.go b/x/distribution/keeper/keeper_test.go index dd08427cf933..69359ab91d28 100644 --- a/x/distribution/keeper/keeper_test.go +++ b/x/distribution/keeper/keeper_test.go @@ -32,6 +32,8 @@ type dep struct { } func initFixture(t *testing.T) (sdk.Context, []sdk.AccAddress, keeper.Keeper, dep) { + t.Helper() + ctrl := gomock.NewController(t) key := storetypes.NewKVStoreKey(types.StoreKey) storeService := runtime.NewKVStoreService(key) diff --git a/x/distribution/keeper/msg_server_test.go b/x/distribution/keeper/msg_server_test.go index df5b4616e9d8..1f136cd525d8 100644 --- a/x/distribution/keeper/msg_server_test.go +++ b/x/distribution/keeper/msg_server_test.go @@ -3,13 +3,15 @@ package keeper_test import ( "testing" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/distribution/keeper" "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func TestMsgSetWithdrawAddress(t *testing.T) { From 03f11e8a44103c8d6072a8438b09dc0bc34ffb8c Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 10 Oct 2023 11:41:31 +0200 Subject: [PATCH 13/15] explain why no autocli --- x/distribution/client/cli/tx.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index 2a10eaabdda8..d4e27f7df397 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -41,6 +41,7 @@ func NewTxCmd() *cobra.Command { } // NewWithdrawAllRewardsCmd returns a CLI command handler for creating a MsgWithdrawDelegatorReward transaction. +// This command is more powerful than AutoCLI generated command as it allows sending bacth of messages. func NewWithdrawAllRewardsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "withdraw-all-rewards", From 77088c699e4ed1d1916506b46191772032bcc4f1 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 10 Oct 2023 11:42:15 +0200 Subject: [PATCH 14/15] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d09d265671c..ff0299237e66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -163,7 +163,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### CLI Breaking Changes -* (x/distribution) [#](https://github.com/cosmos/cosmos-sdk/pull/) `appd tx distribution withdraw-rewards` now only withdraws rewards for the delegator's own delegations. For withdrawing validators commission, use `appd tx distribution withdraw-validator-commission`. +* (x/distribution) [#17963](https://github.com/cosmos/cosmos-sdk/pull/17963) `appd tx distribution withdraw-rewards` now only withdraws rewards for the delegator's own delegations. For withdrawing validators commission, use `appd tx distribution withdraw-validator-commission`. ### State Machine Breaking From 62f3e63aeae744dacf402881e2959a7a9d5b18b6 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 10 Oct 2023 20:08:22 +0200 Subject: [PATCH 15/15] fix typos --- x/distribution/client/cli/tx.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index d4e27f7df397..b9fac8b60daa 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -41,11 +41,11 @@ func NewTxCmd() *cobra.Command { } // NewWithdrawAllRewardsCmd returns a CLI command handler for creating a MsgWithdrawDelegatorReward transaction. -// This command is more powerful than AutoCLI generated command as it allows sending bacth of messages. +// This command is more powerful than AutoCLI generated command as it allows sending batch of messages. func NewWithdrawAllRewardsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "withdraw-all-rewards", - Short: "withdraw all delegations rewards for a delegator", + Short: "Withdraw all delegations rewards for a delegator", Example: fmt.Sprintf("%s tx distribution withdraw-all-rewards --from mykey", version.AppName), Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error {