Skip to content

Commit

Permalink
chore(client/v2): sync client/v2 with main (backport #22493, #22817) (#…
Browse files Browse the repository at this point in the history
…22820)

Co-authored-by: Julien Robert <[email protected]>
  • Loading branch information
mergify[bot] and julienrbrt authored Dec 10, 2024
1 parent 0cf6cd8 commit 3ba671f
Show file tree
Hide file tree
Showing 91 changed files with 1,400 additions and 503 deletions.
4 changes: 4 additions & 0 deletions client/v2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,22 @@ Ref: https://keepachangelog.com/en/1.0.0/
### API Breaking Changes

* [#17709](https://github.com/cosmos/cosmos-sdk/pull/17709) Address codecs have been removed from `autocli.AppOptions` and `flag.Builder`. Instead client/v2 uses the address codecs present in the context (introduced in [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503)).
* [#22493](https://github.com/cosmos/cosmos-sdk/pull/22493) Refactored `client/v2` package to remove v1 context dependencies, while introducing new packages for client configuration, context management, and formatted output with improved transaction handling and flag support.

### Bug Fixes

* [#21853](https://github.com/cosmos/cosmos-sdk/pull/21853) Fix `*big.Int` unmarshalling in txs.
* [#22576](https://github.com/cosmos/cosmos-sdk/pull/22576) Fix duplicate command addition in `autocli` when custom enhanced command has a different name than module name
* [#22817](https://github.com/cosmos/cosmos-sdk/pull/22817) Add DecCoin support in autocli flag builder.

## [v2.0.0-beta.5] - 2024-09-18

### Improvements

* [#21712](https://github.com/cosmos/cosmos-sdk/pull/21712) Marshal `type` field as proto message url in queries instead of amino name.

## [v2.0.0-beta.4] - 2024-07-16

### Bug Fixes

* [#20964](https://github.com/cosmos/cosmos-sdk/pull/20964) Fix `GetNodeHomeDirectory` helper in `client/v2/helpers` to respect the `(PREFIX)_HOME` environment variable.
Expand Down
34 changes: 21 additions & 13 deletions client/v2/autocli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ package autocli
import (
"github.com/cosmos/gogoproto/proto"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/protobuf/reflect/protoregistry"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/core/address"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/x/tx/signing"

"github.com/cosmos/cosmos-sdk/client"
sdkflags "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
)

// AppOptions are input options for an autocli enabled app. These options can be built via depinject based on an app config.
Expand All @@ -38,8 +39,15 @@ 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
AddressCodec address.Codec // AddressCodec is used to encode/decode account addresses.
ValidatorAddressCodec address.ValidatorAddressCodec // ValidatorAddressCodec is used to encode/decode validator addresses.
ConsensusAddressCodec address.ConsensusAddressCodec // ConsensusAddressCodec is used to encode/decode consensus addresses.

// Cdc is the codec used for binary encoding/decoding of messages.
Cdc codec.Codec

// TxConfigOpts contains options for configuring transaction handling.
TxConfigOpts authtx.ConfigOptions

skipValidation bool
}
Expand All @@ -63,19 +71,19 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
builder := &Builder{
Builder: flag.Builder{
TypeResolver: protoregistry.GlobalTypes,
FileResolver: appOptions.ClientCtx.InterfaceRegistry,
AddressCodec: appOptions.ClientCtx.AddressCodec,
ValidatorAddressCodec: appOptions.ClientCtx.ValidatorAddressCodec,
ConsensusAddressCodec: appOptions.ClientCtx.ConsensusAddressCodec,
},
GetClientConn: func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
return client.GetClientQueryContext(cmd)
FileResolver: appOptions.Cdc.InterfaceRegistry(),
AddressCodec: appOptions.AddressCodec,
ValidatorAddressCodec: appOptions.ValidatorAddressCodec,
ConsensusAddressCodec: appOptions.ConsensusAddressCodec,
},
GetClientConn: getQueryClientConn(appOptions.Cdc),
AddQueryConnFlags: func(c *cobra.Command) {
sdkflags.AddQueryFlagsToCmd(c)
sdkflags.AddKeyringFlags(c.Flags())
},
AddTxConnFlags: sdkflags.AddTxFlagsToCmd,
AddTxConnFlags: sdkflags.AddTxFlagsToCmd,
Cdc: appOptions.Cdc,
EnabledSignModes: appOptions.TxConfigOpts.EnabledSignModes,
}

return appOptions.EnhanceRootCommandWithBuilder(rootCmd, builder)
Expand Down Expand Up @@ -170,9 +178,9 @@ func NewAppOptionsFromConfig(

return AppOptions{
Modules: cfg.Modules,
ClientCtx: client.Context{InterfaceRegistry: interfaceRegistry},
ModuleOptions: moduleOptions,
skipValidation: true,
Cdc: codec.NewProtoCodec(interfaceRegistry),
}, nil
}

Expand Down
6 changes: 6 additions & 0 deletions client/v2/autocli/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"google.golang.org/grpc"

"cosmossdk.io/client/v2/autocli/flag"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
)

// Builder manages options for building CLI commands.
Expand All @@ -19,6 +22,9 @@ type Builder struct {
// AddQueryConnFlags and AddTxConnFlags are functions that add flags to query and transaction commands
AddQueryConnFlags func(*cobra.Command)
AddTxConnFlags func(*cobra.Command)

Cdc codec.Codec
EnabledSignModes []signing.SignMode
}

// ValidateAndComplete the builder fields.
Expand Down
157 changes: 139 additions & 18 deletions client/v2/autocli/common.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
package autocli

import (
"context"
"crypto/tls"
"fmt"
"strings"
"strconv"

"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
grpcinsecure "google.golang.org/grpc/credentials/insecure"
"google.golang.org/protobuf/reflect/protoreflect"
"sigs.k8s.io/yaml"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
apitxsigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
"cosmossdk.io/client/v2/autocli/config"
"cosmossdk.io/client/v2/autocli/keyring"
"cosmossdk.io/client/v2/broadcast/comet"
clientcontext "cosmossdk.io/client/v2/context"
"cosmossdk.io/client/v2/internal/flags"
"cosmossdk.io/client/v2/internal/print"
"cosmossdk.io/client/v2/internal/util"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
)

type cmdType int
Expand Down Expand Up @@ -62,8 +73,13 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip
}
cmd.Args = binder.CobraArgs

cmd.PreRunE = b.preRunE()

cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx = cmd.Context()
ctx, err = b.getContext(cmd)
if err != nil {
return err
}

input, err := binder.BuildMessage(args)
if err != nil {
Expand Down Expand Up @@ -237,27 +253,132 @@ func enhanceCustomCmd(builder *Builder, cmd *cobra.Command, cmdType cmdType, mod

// outOrStdoutFormat formats the output based on the output flag and writes it to the command's output stream.
func (b *Builder) outOrStdoutFormat(cmd *cobra.Command, out []byte) error {
clientCtx := client.Context{}
if v := cmd.Context().Value(client.ClientContextKey); v != nil {
clientCtx = *(v.(*client.Context))
p, err := print.NewPrinter(cmd)
if err != nil {
return err
}
return p.PrintBytes(out)
}

// getContext creates and returns a new context.Context with an autocli.Context value.
// It initializes a printer and, if necessary, a keyring based on command flags.
func (b *Builder) getContext(cmd *cobra.Command) (context.Context, error) {
// if the command uses the keyring this must be set
var (
k keyring.Keyring
err error
)
if cmd.Flags().Lookup(flags.FlagKeyringDir) != nil && cmd.Flags().Lookup(flags.FlagKeyringBackend) != nil {
k, err = keyring.NewKeyringFromFlags(cmd.Flags(), b.AddressCodec, cmd.InOrStdin(), b.Cdc)
if err != nil {
return nil, err
}
} else {
k = keyring.NoKeyring{}
}
flagSet := cmd.Flags()
if clientCtx.OutputFormat == "" || flagSet.Changed(flags.FlagOutput) {
output, _ := flagSet.GetString(flags.FlagOutput)
clientCtx = clientCtx.WithOutputFormat(output)

clientCtx := clientcontext.Context{
Flags: cmd.Flags(),
AddressCodec: b.AddressCodec,
ValidatorAddressCodec: b.ValidatorAddressCodec,
ConsensusAddressCodec: b.ConsensusAddressCodec,
Cdc: b.Cdc,
Keyring: k,
EnabledSignModes: signModesToApiSignModes(b.EnabledSignModes),
}

var err error
outputType := clientCtx.OutputFormat
// if the output type is text, convert the json to yaml
// if output type is json or nil, default to json
if outputType == flags.OutputFormatText {
out, err = yaml.JSONToYAML(out)
return clientcontext.SetInContext(cmd.Context(), clientCtx), nil
}

// preRunE returns a function that sets flags from the configuration before running a command.
// It is used as a PreRunE hook for cobra commands to ensure flags are properly initialized
// from the configuration before command execution.
func (b *Builder) preRunE() func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
err := b.setFlagsFromConfig(cmd)
if err != nil {
return err
}

return nil
}
}

// setFlagsFromConfig sets command flags from the provided configuration.
// It only sets flags that haven't been explicitly changed by the user.
func (b *Builder) setFlagsFromConfig(cmd *cobra.Command) error {
conf, err := config.CreateClientConfigFromFlags(cmd.Flags())
if err != nil {
return err
}

flagsToSet := map[string]string{
flags.FlagChainID: conf.ChainID,
flags.FlagKeyringBackend: conf.KeyringBackend,
flags.FlagFrom: conf.KeyringDefaultKeyName,
flags.FlagOutput: conf.Output,
flags.FlagNode: conf.Node,
flags.FlagBroadcastMode: conf.BroadcastMode,
flags.FlagGrpcAddress: conf.GRPC.Address,
flags.FlagGrpcInsecure: strconv.FormatBool(conf.GRPC.Insecure),
}

for flagName, value := range flagsToSet {
if flag := cmd.Flags().Lookup(flagName); flag != nil && !cmd.Flags().Changed(flagName) {
if err := cmd.Flags().Set(flagName, value); err != nil {
return err
}
}
}

cmd.Println(strings.TrimSpace(string(out)))
return nil
}

// getQueryClientConn returns a function that creates a gRPC client connection based on command flags.
// It handles the creation of secure or insecure connections and falls back to a CometBFT broadcaster
// if no gRPC address is specified.
func getQueryClientConn(cdc codec.Codec) func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
return func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
var err error
creds := grpcinsecure.NewCredentials()

insecure := true
if cmd.Flags().Lookup(flags.FlagGrpcInsecure) != nil {
insecure, err = cmd.Flags().GetBool(flags.FlagGrpcInsecure)
if err != nil {
return nil, err
}
}
if !insecure {
creds = credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12})
}

var addr string
if cmd.Flags().Lookup(flags.FlagGrpcAddress) != nil {
addr, err = cmd.Flags().GetString(flags.FlagGrpcAddress)
if err != nil {
return nil, err
}
}
if addr == "" {
// if grpc-addr has not been set, use the default clientConn
// TODO: default is comet
node, err := cmd.Flags().GetString(flags.FlagNode)
if err != nil {
return nil, err
}
return comet.NewCometBFTBroadcaster(node, comet.BroadcastSync, cdc)
}

return grpc.NewClient(addr, []grpc.DialOption{grpc.WithTransportCredentials(creds)}...)
}
}

// signModesToApiSignModes converts a slice of signing.SignMode to a slice of apitxsigning.SignMode.
func signModesToApiSignModes(modes []signing.SignMode) []apitxsigning.SignMode {
r := make([]apitxsigning.SignMode, len(modes))
for i, m := range modes {
r[i] = apitxsigning.SignMode(m)
}
return r
}
17 changes: 16 additions & 1 deletion client/v2/autocli/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type fixture struct {
conn *testClientConn
b *Builder
clientCtx client.Context

home string
chainID string
kBackend string
}

func initFixture(t *testing.T) *fixture {
Expand Down Expand Up @@ -85,17 +89,28 @@ func initFixture(t *testing.T) *fixture {
return conn, nil
},
AddQueryConnFlags: flags.AddQueryFlagsToCmd,
AddTxConnFlags: flags.AddTxFlagsToCmd,
AddTxConnFlags: addTxAndGlobalFlagsToCmd,
Cdc: encodingConfig.Codec,
}
assert.NilError(t, b.ValidateAndComplete())

return &fixture{
conn: conn,
b: b,
clientCtx: clientCtx,

home: home,
chainID: "autocli-test",
kBackend: sdkkeyring.BackendMemory,
}
}

func addTxAndGlobalFlagsToCmd(cmd *cobra.Command) {
f := cmd.Flags()
f.String("home", "", "home directory")
flags.AddTxFlagsToCmd(cmd)
}

func runCmd(fixture *fixture, command func(moduleName string, f *fixture) (*cobra.Command, error), args ...string) (*bytes.Buffer, error) {
out := &bytes.Buffer{}
cmd, err := command("test", fixture)
Expand Down
Loading

0 comments on commit 3ba671f

Please sign in to comment.