Skip to content

Commit

Permalink
feat(hubl): cache bech32 prefix (#15954)
Browse files Browse the repository at this point in the history
  • Loading branch information
julienrbrt authored Apr 26, 2023
1 parent 6a8251a commit 1179285
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 71 deletions.
16 changes: 9 additions & 7 deletions client/v2/autocli/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package autocli

import (
"errors"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/core/address"
Expand All @@ -19,8 +21,8 @@ import (
// var autoCliOpts autocli.AppOptions
// err := depinject.Inject(appConfig, &encodingConfig.InterfaceRegistry, &autoCliOpts)
//
// If depinject isn't used, options can be provided manually or extracted from modules. One method for extracting autocli
// options is via the github.com/cosmos/cosmos-sdk/runtime/services.ExtractAutoCLIOptions function.
// If depinject isn't used, options can be provided manually or extracted from modules and the address codec can be provided by the auth keeper.
// One method for extracting autocli options is via the github.com/cosmos/cosmos-sdk/runtime/services.ExtractAutoCLIOptions function.
type AppOptions struct {
depinject.In

Expand All @@ -34,8 +36,7 @@ type AppOptions struct {
ModuleOptions map[string]*autocliv1.ModuleOptions `optional:"true"`

// AddressCodec is the address codec to use for the app.
// If not provided the default address prefix will be fetched from the reflection client.
AddressCodec address.Codec `optional:"true"`
AddressCodec address.Codec
}

// EnhanceRootCommand enhances the provided root command with autocli AppOptions,
Expand All @@ -57,9 +58,6 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
builder := &Builder{
Builder: flag.Builder{
AddressCodec: appOptions.AddressCodec,
GetClientConn: func() (grpc.ClientConnInterface, error) {
return client.GetClientQueryContext(rootCmd)
},
},
GetClientConn: func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
return client.GetClientQueryContext(cmd)
Expand All @@ -72,6 +70,10 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
}

func (appOptions AppOptions) EnhanceRootCommandWithBuilder(rootCmd *cobra.Command, builder *Builder) error {
if builder.AddressCodec == nil {
return errors.New("address codec is required in builder")
}

// extract any custom commands from modules
customQueryCmds, customMsgCmds := map[string]*cobra.Command{}, map[string]*cobra.Command{}
for name, module := range appOptions.Modules {
Expand Down
16 changes: 8 additions & 8 deletions client/v2/autocli/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import (
"net"
"testing"

reflectionv2alpha1 "cosmossdk.io/api/cosmos/base/reflection/v2alpha1"
"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/client/v2/internal/testpb"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"gotest.tools/v3/assert"

"google.golang.org/grpc/credentials/insecure"
reflectionv2alpha1 "cosmossdk.io/api/cosmos/base/reflection/v2alpha1"
"github.com/cosmos/cosmos-sdk/client/flags"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"

"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/client/v2/internal/testpb"
)

func testExecCommon(t *testing.T, buildModuleCommand func(string, *Builder) (*cobra.Command, error), args ...string) *testClientConn {
Expand Down Expand Up @@ -47,9 +49,7 @@ func testExecCommon(t *testing.T, buildModuleCommand func(string, *Builder) (*co
}
b := &Builder{
Builder: flag.Builder{
GetClientConn: func() (grpc.ClientConnInterface, error) {
return conn, nil
},
AddressCodec: addresscodec.NewBech32Codec("cosmos"),
},
GetClientConn: func(*cobra.Command) (grpc.ClientConnInterface, error) {
return conn, nil
Expand Down
21 changes: 1 addition & 20 deletions client/v2/autocli/flag/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,14 @@ import (
"context"
"fmt"

reflectionv2alpha1 "cosmossdk.io/api/cosmos/base/reflection/v2alpha1"
"cosmossdk.io/core/address"
"google.golang.org/protobuf/reflect/protoreflect"

addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
"cosmossdk.io/core/address"
)

type addressStringType struct{}

func (a addressStringType) NewValue(ctx context.Context, b *Builder) Value {
if b.AddressCodec == nil {
conn, err := b.GetClientConn()
if err != nil {
panic(err)
}
reflectionClient := reflectionv2alpha1.NewReflectionServiceClient(conn)
resp, err := reflectionClient.GetConfigurationDescriptor(ctx, &reflectionv2alpha1.GetConfigurationDescriptorRequest{})
if err != nil {
panic(err)
}
if resp == nil || resp.Config == nil {
panic("bech32 account address prefix is not set")
}

b.AddressCodec = addresscodec.NewBech32Codec(resp.Config.Bech32AccountAddressPrefix)
}

return &addressValue{addressCodec: b.AddressCodec}
}

Expand Down
4 changes: 0 additions & 4 deletions client/v2/autocli/flag/builder.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package flag

import (
"google.golang.org/grpc"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
Expand All @@ -27,9 +26,6 @@ type Builder struct {

// AddressCodec is the address codec used for the address flag
AddressCodec address.Codec

// GetClientConn is the reflection client for the address flag
GetClientConn func() (grpc.ClientConnInterface, error)
}

func (b *Builder) init() {
Expand Down
9 changes: 8 additions & 1 deletion codec/address/bech32_codec.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package address

import (
"errors"
"strings"

"cosmossdk.io/core/address"
errorsmod "cosmossdk.io/errors"

Expand All @@ -21,13 +24,17 @@ func NewBech32Codec(prefix string) address.Codec {

// StringToBytes encodes text to bytes
func (bc Bech32Codec) StringToBytes(text string) ([]byte, error) {
if len(strings.TrimSpace(text)) == 0 {
return []byte{}, errors.New("empty address string is not allowed")
}

hrp, bz, err := bech32.DecodeAndConvert(text)
if err != nil {
return nil, err
}

if hrp != bc.Bech32Prefix {
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "hrp does not match bech32Prefix")
return nil, errorsmod.Wrapf(sdkerrors.ErrLogic, "hrp does not match bech32 prefix: expected '%s' got '%s'", bc.Bech32Prefix, hrp)
}

if err := sdk.VerifyAddressFormat(bz); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions tools/hubl/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ go 1.20

require (
cosmossdk.io/api v0.4.1
cosmossdk.io/client/v2 v2.0.0-20230320224637-dca0e7374a1d
cosmossdk.io/client/v2 v2.0.0-20230426154441-2037a26d1235
cosmossdk.io/errors v1.0.0-beta.7
github.com/cockroachdb/errors v1.9.1
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230426154441-2037a26d1235
github.com/hashicorp/go-multierror v1.1.1
github.com/manifoldco/promptui v0.9.0
github.com/pelletier/go-toml/v2 v2.0.7
Expand All @@ -17,7 +18,7 @@ require (

require (
cosmossdk.io/collections v0.1.0 // indirect
cosmossdk.io/core v0.6.1 // indirect
cosmossdk.io/core v0.6.2-0.20230323161322-ccd8d40119e4 // indirect
cosmossdk.io/depinject v1.0.0-alpha.3 // indirect
cosmossdk.io/log v1.0.0 // indirect
cosmossdk.io/math v1.0.0 // indirect
Expand All @@ -42,7 +43,6 @@ require (
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.0-rc.1 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230424095137-b73c17cb9cc8 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogoproto v1.4.8 // indirect
github.com/cosmos/iavl v0.21.0-beta.1 // indirect
Expand Down
12 changes: 6 additions & 6 deletions tools/hubl/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cosmossdk.io/api v0.4.1 h1:0ikaYM6GyxTYYcfBiyR8YnLCfhNnhKpEFnaSepCTmqg=
cosmossdk.io/api v0.4.1/go.mod h1:jR7k5ok90LxW2lFUXvd8Vpo/dr4PpiyVegxdm7b1ZdE=
cosmossdk.io/client/v2 v2.0.0-20230320224637-dca0e7374a1d h1:9mBIeO0ZhCalqS3pJiZ1fs+Nn93E7rU4+Hv7QVINbNM=
cosmossdk.io/client/v2 v2.0.0-20230320224637-dca0e7374a1d/go.mod h1:qX4UABq4VI1ccJn4H4MIJx5/HvjRiaVaImovbnPXNXc=
cosmossdk.io/client/v2 v2.0.0-20230426154441-2037a26d1235 h1:6aGhtjUgmacucrKMC9ZdF9G96YoxZqkTC2ZyxaAg1GE=
cosmossdk.io/client/v2 v2.0.0-20230426154441-2037a26d1235/go.mod h1:ydI6QS3A+K2px6O8QpM0JtNaVV6lLeCJ5LVwtQXIMAg=
cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8=
cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo=
cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s=
cosmossdk.io/core v0.6.1/go.mod h1:g3MMBCBXtxbDWBURDVnJE7XML4BG5qENhs0gzkcpuFA=
cosmossdk.io/core v0.6.2-0.20230323161322-ccd8d40119e4 h1:l1scDTT2VX18ZuR6P0irvT/bAP0h4297D/Lka5nz2vE=
cosmossdk.io/core v0.6.2-0.20230323161322-ccd8d40119e4/go.mod h1:J8R0E7soOpQFVqFiFd7EKepXCPpINa2n2t2EqbEsXnY=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=
cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU=
cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w=
Expand Down Expand Up @@ -146,8 +146,8 @@ github.com/cosmos/cosmos-db v1.0.0-rc.1 h1:SjnT8B6WKMW9WEIX32qMhnEEKcI7ZP0+G1Sa9
github.com/cosmos/cosmos-db v1.0.0-rc.1/go.mod h1:Dnmk3flSf5lkwCqvvjNpoxjpXzhxnCAFzKHlbaForso=
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.20230424095137-b73c17cb9cc8 h1:zIl1WnrW5ZP1VwhpbwVBZtCntkNKYNIkg4233/dZ3BU=
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230424095137-b73c17cb9cc8/go.mod h1:JicgV9n3SAu5uuoyDvQ2gSHYLyFvyRrIUYB5T2Q4HRw=
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230426154441-2037a26d1235 h1:EQM4Ewp62TpQ141W0IJL84qJ8zyvGeqA75r++81JKGc=
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230426154441-2037a26d1235/go.mod h1:1pnJEQxrWXGGijISBNKkisAuMlohZROsazmj+JYkBc0=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
Expand Down
1 change: 1 addition & 0 deletions tools/hubl/internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Config struct {

type ChainConfig struct {
GRPCEndpoints []GRPCEndpoint `toml:"trusted-grpc-endpoints"`
Bech32Prefix string `toml:"bech32-prefix"`
}

type GRPCEndpoint struct {
Expand Down
52 changes: 34 additions & 18 deletions tools/hubl/internal/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"os"
"path"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
"github.com/cockroachdb/errors"
"github.com/hashicorp/go-multierror"
"google.golang.org/grpc"
Expand All @@ -18,27 +16,32 @@ import (
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/descriptorpb"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
reflectionv2alpha1 "cosmossdk.io/api/cosmos/base/reflection/v2alpha1"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
)

const DefaultConfigDirName = ".hubl"

type ChainInfo struct {
client *grpc.ClientConn

ConfigDir string
Chain string
ModuleOptions map[string]*autocliv1.ModuleOptions
Context context.Context
ConfigDir string
Chain string
Config *ChainConfig

ProtoFiles *protoregistry.Files
Context context.Context
Config *ChainConfig
ModuleOptions map[string]*autocliv1.ModuleOptions
}

func NewChainInfo(configDir, chain string, config *ChainConfig) *ChainInfo {
return &ChainInfo{
ConfigDir: configDir,
Chain: chain,
Config: config,
Context: context.Background(),
Config: config,
Chain: chain,
ConfigDir: configDir,
}
}

Expand Down Expand Up @@ -123,31 +126,29 @@ func (c *ChainInfo) Load(reload bool) error {
}

autocliQueryClient := autocliv1.NewQueryClient(client)
appOptionsRes, err := autocliQueryClient.AppOptions(c.Context, &autocliv1.AppOptionsRequest{})
appOptsRes, err := autocliQueryClient.AppOptions(c.Context, &autocliv1.AppOptionsRequest{})
if err != nil {
appOptionsRes = guessAutocli(c.ProtoFiles)
appOptsRes = guessAutocli(c.ProtoFiles)
}

bz, err := proto.Marshal(appOptionsRes)
bz, err := proto.Marshal(appOptsRes)
if err != nil {
return err
}

err = os.WriteFile(appOptsFilename, bz, 0o600)
if err != nil {
if err := os.WriteFile(appOptsFilename, bz, 0o600); err != nil {
return err
}

c.ModuleOptions = appOptionsRes.ModuleOptions
c.ModuleOptions = appOptsRes.ModuleOptions
} else {
bz, err := os.ReadFile(appOptsFilename)
if err != nil {
return err
}

var appOptsRes autocliv1.AppOptionsResponse
err = proto.Unmarshal(bz, &appOptsRes)
if err != nil {
if err := proto.Unmarshal(bz, &appOptsRes); err != nil {
return err
}

Expand Down Expand Up @@ -185,3 +186,18 @@ func (c *ChainInfo) OpenClient() (*grpc.ClientConn, error) {

return nil, errors.Wrapf(res, "error loading gRPC client")
}

// getAddressPrefix returns the address prefix of the chain.
func getAddressPrefix(ctx context.Context, conn grpc.ClientConnInterface) (string, error) {
reflectionClient := reflectionv2alpha1.NewReflectionServiceClient(conn)
resp, err := reflectionClient.GetConfigurationDescriptor(ctx, &reflectionv2alpha1.GetConfigurationDescriptorRequest{})
if err != nil {
return "", err
}

if resp == nil || resp.Config == nil || resp.Config.Bech32AccountAddressPrefix == "" {
return "", errors.New("bech32 account address prefix is not set")
}

return resp.Config.Bech32AccountAddressPrefix, nil
}
Loading

0 comments on commit 1179285

Please sign in to comment.