feat: Integrate grpc configuration into client.toml (#19905)

This commit is contained in:
Lucas Francisco López 2024-04-02 16:24:45 +02:00 committed by GitHub
parent f4af84f89f
commit 319e6e4f5e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 80 additions and 8 deletions

View File

@ -42,6 +42,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
### Features
* (client) [#19905](https://github.com/cosmos/cosmos-sdk/pull/19905) Add grpc client config to `client.toml`.
* (runtime) [#19571](https://github.com/cosmos/cosmos-sdk/pull/19571) Implement `core/router.Service` it in runtime. This service is present in all modules (when using depinject).
* (types) [#19164](https://github.com/cosmos/cosmos-sdk/pull/19164) Add a ValueCodec for the math.Uint type that can be used in collections maps.
* (types) [#19281](https://github.com/cosmos/cosmos-sdk/pull/19281) Added a new method, `IsGT`, for `types.Coin`. This method is used to check if a `types.Coin` is greater than another `types.Coin`.

View File

@ -1,10 +1,15 @@
package config
import (
"crypto/tls"
"fmt"
"os"
"path/filepath"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
)
@ -26,12 +31,19 @@ func DefaultConfig() *Config {
type ClientConfig Config
type Config struct {
ChainID string `mapstructure:"chain-id" json:"chain-id"`
KeyringBackend string `mapstructure:"keyring-backend" json:"keyring-backend"`
KeyringDefaultKeyName string `mapstructure:"keyring-default-keyname" json:"keyring-default-keyname"`
Output string `mapstructure:"output" json:"output"`
Node string `mapstructure:"node" json:"node"`
BroadcastMode string `mapstructure:"broadcast-mode" json:"broadcast-mode"`
ChainID string `mapstructure:"chain-id" json:"chain-id"`
KeyringBackend string `mapstructure:"keyring-backend" json:"keyring-backend"`
KeyringDefaultKeyName string `mapstructure:"keyring-default-keyname" json:"keyring-default-keyname"`
Output string `mapstructure:"output" json:"output"`
Node string `mapstructure:"node" json:"node"`
BroadcastMode string `mapstructure:"broadcast-mode" json:"broadcast-mode"`
GRPC GRPCConfig `mapstructure:",squash"`
}
// GRPCConfig holds the gRPC client configuration.
type GRPCConfig struct {
Address string `mapstructure:"grpc-address" json:"grpc-address"`
Insecure bool `mapstructure:"grpc-insecure" json:"grpc-insecure"`
}
// ReadFromClientConfig reads values from client.toml file and updates them in client.Context
@ -138,5 +150,35 @@ func CreateClientConfig(ctx client.Context, customClientTemplate string, customC
WithClient(client).
WithKeyring(keyring)
if conf.GRPC.Address != "" {
grpcClient, err := getGRPCClient(conf.GRPC)
if err != nil {
return ctx, fmt.Errorf("couldn't get grpc client: %w", err)
}
ctx = ctx.WithGRPCClient(grpcClient)
}
return ctx, nil
}
// getGRPCClient creates and returns a new gRPC client connection based on the GRPCConfig.
// It determines the type of connection (secure or insecure) from the GRPCConfig and
// uses the specified server address to establish the connection.
func getGRPCClient(grpcConfig GRPCConfig) (*grpc.ClientConn, error) {
transport := grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
MinVersion: tls.VersionTLS12,
}))
if grpcConfig.Insecure {
transport = grpc.WithTransportCredentials(insecure.NewCredentials())
}
dialOptions := []grpc.DialOption{transport}
grpcClient, err := grpc.Dial(grpcConfig.Address, dialOptions...)
if err != nil {
return nil, fmt.Errorf("failed to dial gRPC server at %s: %w", grpcConfig.Address, err)
}
return grpcClient, nil
}

View File

@ -87,7 +87,6 @@ gas-adjustment = {{ .GasConfig.GasAdjustment }}
# Memo to include in all transactions.
note = "{{ .Note }}"
`
t.Run("custom template and config provided", func(t *testing.T) {
clientCtx, cleanup, err := initClientContextWithTemplate(t, "", customClientConfigTemplate, customClientConfig)
defer func() {
@ -181,3 +180,23 @@ func TestConfigCmdEnvFlag(t *testing.T) {
})
}
}
func TestGRPCConfig(t *testing.T) {
expectedGRPCConfig := config.GRPCConfig{
Address: "localhost:7070",
Insecure: true,
}
clientCfg := config.DefaultConfig()
clientCfg.GRPC = expectedGRPCConfig
t.Run("custom template with gRPC config", func(t *testing.T) {
clientCtx, cleanup, err := initClientContextWithTemplate(t, "", config.DefaultClientConfigTemplate, clientCfg)
defer cleanup()
require.NoError(t, err)
require.Equal(t, expectedGRPCConfig.Address, clientCtx.Viper.GetString("grpc-address"))
require.Equal(t, expectedGRPCConfig.Insecure, clientCtx.Viper.GetBool("grpc-insecure"))
})
}

View File

@ -8,7 +8,8 @@ import (
"github.com/spf13/viper"
)
const DefaultClientConfigTemplate = `# This is a TOML config file.
const (
DefaultClientConfigTemplate = `# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
###############################################################################
@ -27,7 +28,16 @@ output = "{{ .Output }}"
node = "{{ .Node }}"
# Transaction broadcasting mode (sync|async)
broadcast-mode = "{{ .BroadcastMode }}"
# gRPC server endpoint to which the client will connect.
# It can be overwritten by the --grpc-addr flag in each command.
grpc-address = "{{ .GRPC.Address }}"
# Allow the gRPC client to connect over insecure channels.
# It can be overwritten by the --grpc-insecure flag in each command.
grpc-insecure = {{ .GRPC.Insecure }}
`
)
var configTemplate *template.Template