Skip to content

Commit

Permalink
fix(client/v2): fix marshalling of queries with any (#18309)
Browse files Browse the repository at this point in the history
(cherry picked from commit 2caf00d)

# Conflicts:
#	client/debug/main.go
#	client/v2/autocli/app.go
#	client/v2/go.mod
#	x/tx/CHANGELOG.md
#	x/tx/signing/aminojson/json_marshal.go
  • Loading branch information
julienrbrt authored and mergify[bot] committed Nov 3, 2023
1 parent f6d4b2e commit 4f62b60
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 19 deletions.
58 changes: 58 additions & 0 deletions client/debug/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,64 @@ func Cmd() *cobra.Command {
return cmd
}

<<<<<<< HEAD

Check failure on line 46 in client/debug/main.go

View workflow job for this annotation

GitHub Actions / tests (00)

syntax error: non-declaration statement outside function body
=======
// CodecCmd creates and returns a new codec debug cmd.
func CodecCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "codec",
Short: "Tool for helping with debugging your application codec",
RunE: client.ValidateCmd,
}

cmd.AddCommand(getCodecInterfaces())
cmd.AddCommand(getCodecInterfaceImpls())

return cmd
}

// getCodecInterfaces creates and returns a new cmd used for listing all registered interfaces on the application codec.
func getCodecInterfaces() *cobra.Command {
return &cobra.Command{
Use: "list-interfaces",
Short: "List all registered interface type URLs",
Long: "List all registered interface type URLs using the application codec",
Example: fmt.Sprintf("%s debug codec list-interfaces", version.AppName),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
iFaces := clientCtx.Codec.InterfaceRegistry().ListAllInterfaces()

slices.Sort(iFaces)
for _, iFace := range iFaces {
cmd.Println(iFace)
}
return nil
},
}
}

// getCodecInterfaceImpls creates and returns a new cmd used for listing all registered implemenations of a given interface on the application codec.
func getCodecInterfaceImpls() *cobra.Command {
return &cobra.Command{
Use: "list-implementations [interface]",
Short: "List the registered type URLs for the provided interface",
Long: "List the registered type URLs that can be used for the provided interface name using the application codec",
Example: fmt.Sprintf("%s debug codec list-implementations cosmos.crypto.PubKey", version.AppName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
impls := clientCtx.Codec.InterfaceRegistry().ListImplementations(args[0])

slices.Sort(impls)
for _, imp := range impls {
cmd.Println(imp)
}
return nil
},
}
}

>>>>>>> 2caf00deb (fix(client/v2): fix marshalling of queries with any (#18309))

Check failure on line 103 in client/debug/main.go

View workflow job for this annotation

GitHub Actions / tests (00)

syntax error: non-declaration statement outside function body

Check failure on line 103 in client/debug/main.go

View workflow job for this annotation

GitHub Actions / tests (00)

invalid character U+0023 '#'
// getPubKeyFromString decodes SDK PubKey using JSON marshaler.
func getPubKeyFromString(ctx client.Context, pkstr string) (cryptotypes.PubKey, error) {
var pk cryptotypes.PubKey
Expand Down
5 changes: 4 additions & 1 deletion client/v2/autocli/app.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package autocli

import (
"github.com/cosmos/gogoproto/proto"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/protobuf/reflect/protoregistry"
Expand Down Expand Up @@ -73,10 +72,14 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
builder := &Builder{
Builder: flag.Builder{
TypeResolver: protoregistry.GlobalTypes,
<<<<<<< HEAD
FileResolver: proto.HybridResolver,
AddressCodec: appOptions.AddressCodec,
ValidatorAddressCodec: appOptions.ValidatorAddressCodec,
ConsensusAddressCodec: appOptions.ConsensusAddressCodec,
=======
FileResolver: appOptions.ClientCtx.InterfaceRegistry,
>>>>>>> 2caf00deb (fix(client/v2): fix marshalling of queries with any (#18309))
Keyring: appOptions.Keyring,
},
ClientCtx: appOptions.ClientCtx,
Expand Down
5 changes: 5 additions & 0 deletions client/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ require (
cosmossdk.io/x/tx v0.11.0
github.com/cockroachdb/errors v1.11.1
github.com/cosmos/cosmos-proto v1.0.0-beta.3
<<<<<<< HEAD
github.com/cosmos/cosmos-sdk v0.50.0-rc.1.0.20231011110545-0863b5c5001c
github.com/cosmos/gogoproto v1.4.11
=======
github.com/cosmos/cosmos-sdk v0.51.0
>>>>>>> 2caf00deb (fix(client/v2): fix marshalling of queries with any (#18309))
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
google.golang.org/grpc v1.59.0
Expand Down Expand Up @@ -45,6 +49,7 @@ require (
github.com/cosmos/cosmos-db v1.0.0 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/gogoproto v1.4.11 // indirect
github.com/cosmos/iavl v1.0.0 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
Expand Down
40 changes: 40 additions & 0 deletions x/tx/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,46 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

<<<<<<< HEAD
=======
## v0.12.0

### Improvements

* [#18309](https://github.com/cosmos/cosmos-sdk/pull/18309) Update encoder so that amino types default to msg type url.

## v0.11.0

### Improvements

* [#17787](https://github.com/cosmos/cosmos-sdk/pull/17787) Drop tip support.

## v0.10.0

### Features

* [#17681](https://github.com/cosmos/cosmos-sdk/pull/17681) Add encoder `DefineTypeEncoding` method for defining custom type encodings.
* [#17600](https://github.com/cosmos/cosmos-sdk/pull/17600) Add encoder `DefineScalarEncoding` method for defining custom scalar encodings.
* [#17600](https://github.com/cosmos/cosmos-sdk/pull/17600) Add indent option to encoder.

## v0.9.1

### Improvements

* [#16936](https://github.com/cosmos/cosmos-sdk/pull/16936) Remove extra whitespace when marshalling module accounts.

## v0.9.0

### Bug Fixes

* [#16681](https://github.com/cosmos/cosmos-sdk/pull/16681): Catch and fix `(*Decoder).Decode` crash from invalid length prefix in Tx bytes.

### Improvements

* [#16846](https://github.com/cosmos/cosmos-sdk/pull/16846): Harmonize interface `signing.TypeResolver` with the rest of the codebase (orm and client/v2).
* [#16684](https://github.com/cosmos/cosmos-sdk/pull/16684): Use `io.WriteString`+`fmt.Fprintf` to remove unnecessary `string`->`[]byte` roundtrip.

>>>>>>> 2caf00deb (fix(client/v2): fix marshalling of queries with any (#18309))
## v0.8.0

### Improvements
Expand Down
2 changes: 1 addition & 1 deletion x/tx/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
cosmossdk.io/errors v1.0.0-beta.7
cosmossdk.io/math v1.1.3-rc.1
github.com/cosmos/cosmos-proto v1.0.0-beta.3
github.com/cosmos/gogoproto v1.4.11
github.com/google/go-cmp v0.6.0
github.com/iancoleman/strcase v0.2.0
github.com/pkg/errors v0.9.1
Expand All @@ -19,7 +20,6 @@ require (
)

require (
github.com/cosmos/gogoproto v1.4.11 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down
16 changes: 2 additions & 14 deletions x/tx/signing/aminojson/any.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,7 @@ func (enc Encoder) marshalAny(message protoreflect.Message, writer io.Writer) er
protoMessage = valueMsg.ProtoReflect()
}

_, named := getMessageAminoName(protoMessage.Descriptor().Options())
if !named {
return fmt.Errorf("message %s is packed into an any field, so requires an amino.name annotation",
anyMsg.TypeUrl)
}

return enc.beginMarshal(protoMessage, writer)
return enc.beginMarshal(protoMessage, writer, true)
}

const (
Expand All @@ -73,17 +67,11 @@ func (enc Encoder) marshalDynamic(message protoreflect.Message, writer io.Writer
return errors.Wrapf(err, "can't resolve type URL %s", msgName)
}

_, named := getMessageAminoName(desc.Options())
if !named {
return fmt.Errorf("message %s is packed into an any field, so requires an amino.name annotation",
msgName)
}

valueMsg := dynamicpb.NewMessageType(desc.(protoreflect.MessageDescriptor)).New().Interface()
err = proto.Unmarshal(msgBytes, valueMsg)
if err != nil {
return err
}

return enc.beginMarshal(valueMsg.ProtoReflect(), writer)
return enc.beginMarshal(valueMsg.ProtoReflect(), writer, true)
}
28 changes: 26 additions & 2 deletions x/tx/signing/aminojson/json_marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,36 @@ func (enc Encoder) DefineFieldEncoding(name string, encoder FieldEncoder) Encode
// Marshal serializes a protobuf message to JSON.
func (enc Encoder) Marshal(message proto.Message) ([]byte, error) {
buf := &bytes.Buffer{}
<<<<<<< HEAD
err := enc.beginMarshal(message.ProtoReflect(), buf)
=======
err := enc.beginMarshal(message.ProtoReflect(), buf, false)

if enc.indent != "" {
indentBuf := &bytes.Buffer{}
if err := json.Indent(indentBuf, buf.Bytes(), "", enc.indent); err != nil {
return nil, err
}

return indentBuf.Bytes(), err
}

>>>>>>> 2caf00deb (fix(client/v2): fix marshalling of queries with any (#18309))
return buf.Bytes(), err
}

func (enc Encoder) beginMarshal(msg protoreflect.Message, writer io.Writer) error {
name, named := getMessageAminoName(msg.Descriptor().Options())
func (enc Encoder) beginMarshal(msg protoreflect.Message, writer io.Writer, isAny bool) error {
var (
name string
named bool
)

if isAny {
name, named = getMessageAminoNameAny(msg), true
} else {
name, named = getMessageAminoName(msg)
}

if named {
_, err := writer.Write([]byte(fmt.Sprintf(`{"type":"%s","value":`, name)))
if err != nil {
Expand Down
27 changes: 26 additions & 1 deletion x/tx/signing/aminojson/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package aminojson

import (
cosmos_proto "github.com/cosmos/cosmos-proto"
gogoproto "github.com/cosmos/gogoproto/proto"
"github.com/iancoleman/strcase"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
Expand All @@ -12,14 +13,38 @@ import (

// getMessageAminoName returns the amino name of a message if it has been set by the `amino.name` option.
// If the message does not have an amino name, then the function returns false.
func getMessageAminoName(messageOptions proto.Message) (string, bool) {
func getMessageAminoName(msg protoreflect.Message) (string, bool) {
messageOptions := msg.Descriptor().Options()
if proto.HasExtension(messageOptions, amino.E_Name) {
name := proto.GetExtension(messageOptions, amino.E_Name)
return name.(string), true
}

return "", false
}

// getMessageAminoName returns the amino name of a message if it has been set by the `amino.name` option.
// If the message does not have an amino name, then it returns the msg url.
// If it cannot get the msg url, then it returns false.
func getMessageAminoNameAny(msg protoreflect.Message) string {
messageOptions := msg.Descriptor().Options()
if proto.HasExtension(messageOptions, amino.E_Name) {
name := proto.GetExtension(messageOptions, amino.E_Name)
return name.(string)
}

msgURL := "/" + string(msg.Descriptor().FullName())
if msgURL != "/" {
return msgURL
}

if m, ok := msg.(gogoproto.Message); ok {
return "/" + gogoproto.MessageName(m)
}

return ""
}

// omitEmpty returns true if the field should be omitted if empty. Empty field omission is the default behavior.
func omitEmpty(field protoreflect.FieldDescriptor) bool {
opts := field.Options()
Expand Down
30 changes: 30 additions & 0 deletions x/tx/signing/aminojson/options_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package aminojson

import (
"testing"

"github.com/stretchr/testify/require"

"cosmossdk.io/x/tx/signing/aminojson/internal/testpb"
)

func Test_getMessageAminoName(t *testing.T) {
msg := &testpb.ABitOfEverything{}
name, ok := getMessageAminoName(msg.ProtoReflect())
require.True(t, ok)
require.Equal(t, "ABitOfEverything", name)

secondMsg := &testpb.Duration{}
_, ok = getMessageAminoName(secondMsg.ProtoReflect())
require.False(t, ok)
}

func Test_getMessageAminoNameAny(t *testing.T) {
msg := &testpb.ABitOfEverything{}
name := getMessageAminoNameAny(msg.ProtoReflect())
require.Equal(t, "ABitOfEverything", name)

secondMsg := &testpb.Duration{}
name = getMessageAminoNameAny(secondMsg.ProtoReflect())
require.Equal(t, "/testpb.Duration", name)
}

0 comments on commit 4f62b60

Please sign in to comment.