Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hubl): cache bech32 prefix #15954

Merged
merged 8 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
}

// 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