Skip to content

Commit 319e6e4

Browse files
authored
feat: Integrate grpc configuration into client.toml (#19905)
1 parent f4af84f commit 319e6e4

File tree

4 files changed

+80
-8
lines changed

4 files changed

+80
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
4242

4343
### Features
4444

45+
* (client) [#19905](https://github.com/cosmos/cosmos-sdk/pull/19905) Add grpc client config to `client.toml`.
4546
* (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).
4647
* (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.
4748
* (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`.

client/config/config.go

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package config
22

33
import (
4+
"crypto/tls"
45
"fmt"
56
"os"
67
"path/filepath"
78

9+
"google.golang.org/grpc"
10+
"google.golang.org/grpc/credentials"
11+
"google.golang.org/grpc/credentials/insecure"
12+
813
"github.com/cosmos/cosmos-sdk/client"
914
"github.com/cosmos/cosmos-sdk/client/flags"
1015
)
@@ -26,12 +31,19 @@ func DefaultConfig() *Config {
2631
type ClientConfig Config
2732

2833
type Config struct {
29-
ChainID string `mapstructure:"chain-id" json:"chain-id"`
30-
KeyringBackend string `mapstructure:"keyring-backend" json:"keyring-backend"`
31-
KeyringDefaultKeyName string `mapstructure:"keyring-default-keyname" json:"keyring-default-keyname"`
32-
Output string `mapstructure:"output" json:"output"`
33-
Node string `mapstructure:"node" json:"node"`
34-
BroadcastMode string `mapstructure:"broadcast-mode" json:"broadcast-mode"`
34+
ChainID string `mapstructure:"chain-id" json:"chain-id"`
35+
KeyringBackend string `mapstructure:"keyring-backend" json:"keyring-backend"`
36+
KeyringDefaultKeyName string `mapstructure:"keyring-default-keyname" json:"keyring-default-keyname"`
37+
Output string `mapstructure:"output" json:"output"`
38+
Node string `mapstructure:"node" json:"node"`
39+
BroadcastMode string `mapstructure:"broadcast-mode" json:"broadcast-mode"`
40+
GRPC GRPCConfig `mapstructure:",squash"`
41+
}
42+
43+
// GRPCConfig holds the gRPC client configuration.
44+
type GRPCConfig struct {
45+
Address string `mapstructure:"grpc-address" json:"grpc-address"`
46+
Insecure bool `mapstructure:"grpc-insecure" json:"grpc-insecure"`
3547
}
3648

3749
// 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
138150
WithClient(client).
139151
WithKeyring(keyring)
140152

153+
if conf.GRPC.Address != "" {
154+
grpcClient, err := getGRPCClient(conf.GRPC)
155+
if err != nil {
156+
return ctx, fmt.Errorf("couldn't get grpc client: %w", err)
157+
}
158+
159+
ctx = ctx.WithGRPCClient(grpcClient)
160+
}
161+
141162
return ctx, nil
142163
}
164+
165+
// getGRPCClient creates and returns a new gRPC client connection based on the GRPCConfig.
166+
// It determines the type of connection (secure or insecure) from the GRPCConfig and
167+
// uses the specified server address to establish the connection.
168+
func getGRPCClient(grpcConfig GRPCConfig) (*grpc.ClientConn, error) {
169+
transport := grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
170+
MinVersion: tls.VersionTLS12,
171+
}))
172+
173+
if grpcConfig.Insecure {
174+
transport = grpc.WithTransportCredentials(insecure.NewCredentials())
175+
}
176+
177+
dialOptions := []grpc.DialOption{transport}
178+
grpcClient, err := grpc.Dial(grpcConfig.Address, dialOptions...)
179+
if err != nil {
180+
return nil, fmt.Errorf("failed to dial gRPC server at %s: %w", grpcConfig.Address, err)
181+
}
182+
183+
return grpcClient, nil
184+
}

client/config/config_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ gas-adjustment = {{ .GasConfig.GasAdjustment }}
8787
# Memo to include in all transactions.
8888
note = "{{ .Note }}"
8989
`
90-
9190
t.Run("custom template and config provided", func(t *testing.T) {
9291
clientCtx, cleanup, err := initClientContextWithTemplate(t, "", customClientConfigTemplate, customClientConfig)
9392
defer func() {
@@ -181,3 +180,23 @@ func TestConfigCmdEnvFlag(t *testing.T) {
181180
})
182181
}
183182
}
183+
184+
func TestGRPCConfig(t *testing.T) {
185+
expectedGRPCConfig := config.GRPCConfig{
186+
Address: "localhost:7070",
187+
Insecure: true,
188+
}
189+
190+
clientCfg := config.DefaultConfig()
191+
clientCfg.GRPC = expectedGRPCConfig
192+
193+
t.Run("custom template with gRPC config", func(t *testing.T) {
194+
clientCtx, cleanup, err := initClientContextWithTemplate(t, "", config.DefaultClientConfigTemplate, clientCfg)
195+
defer cleanup()
196+
197+
require.NoError(t, err)
198+
199+
require.Equal(t, expectedGRPCConfig.Address, clientCtx.Viper.GetString("grpc-address"))
200+
require.Equal(t, expectedGRPCConfig.Insecure, clientCtx.Viper.GetBool("grpc-insecure"))
201+
})
202+
}

client/config/toml.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import (
88
"github.com/spf13/viper"
99
)
1010

11-
const DefaultClientConfigTemplate = `# This is a TOML config file.
11+
const (
12+
DefaultClientConfigTemplate = `# This is a TOML config file.
1213
# For more information, see https://github.com/toml-lang/toml
1314
1415
###############################################################################
@@ -27,7 +28,16 @@ output = "{{ .Output }}"
2728
node = "{{ .Node }}"
2829
# Transaction broadcasting mode (sync|async)
2930
broadcast-mode = "{{ .BroadcastMode }}"
31+
32+
# gRPC server endpoint to which the client will connect.
33+
# It can be overwritten by the --grpc-addr flag in each command.
34+
grpc-address = "{{ .GRPC.Address }}"
35+
36+
# Allow the gRPC client to connect over insecure channels.
37+
# It can be overwritten by the --grpc-insecure flag in each command.
38+
grpc-insecure = {{ .GRPC.Insecure }}
3039
`
40+
)
3141

3242
var configTemplate *template.Template
3343

0 commit comments

Comments
 (0)