Make JSONMarshaler methods require proto.Message (#7054)
* Make JSONMarshaler require proto.Message * Use &msg with MarshalJSON * Use *LegacyAmino in queriers instead of JSONMarshaler * Revert ABCIMessageLogs String() and coins tests * Use LegacyAmino in client/debug and fix subspace tests * Use LegacyAmino in all legacy queriers and adapt simulation * Make AminoCodec implement Marshaler and some godoc fixes * Test fixes * Remove unrelevant comment * Use TxConfig.TxJSONEncoder * Use encoding/json in genutil cli migrate/validate genesis cmds * Address simulation related comments * Use JSONMarshaler in cli tests * Use proto.Message as respType in cli tests * Use tmjson for tm GenesisDoc * Update types/module/simulation.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update types/module/module_test.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Add godoc comments * Remove unused InsertKeyJSON * Fix tests Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
co-authored by
Federico Kunze
Aaron Craelius
parent
b5bc864862
commit
7f59723d88
+5
-7
@@ -13,14 +13,12 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
)
|
||||
|
||||
// deprecated: Codec defines a wrapper for an Amino codec that properly handles protobuf
|
||||
// deprecated: LegacyAmino defines a wrapper for an Amino codec that properly handles protobuf
|
||||
// types with Any's
|
||||
type LegacyAmino struct {
|
||||
Amino *amino.Codec
|
||||
}
|
||||
|
||||
var _ JSONMarshaler = &LegacyAmino{}
|
||||
|
||||
func (cdc *LegacyAmino) Seal() {
|
||||
cdc.Amino.Seal()
|
||||
}
|
||||
@@ -43,8 +41,8 @@ func RegisterEvidences(cdc *LegacyAmino) {
|
||||
// MarshalJSONIndent provides a utility for indented JSON encoding of an object
|
||||
// via an Amino codec. It returns an error if it cannot serialize or indent as
|
||||
// JSON.
|
||||
func MarshalJSONIndent(m JSONMarshaler, obj interface{}) ([]byte, error) {
|
||||
bz, err := m.MarshalJSON(obj)
|
||||
func MarshalJSONIndent(cdc *LegacyAmino, obj interface{}) ([]byte, error) {
|
||||
bz, err := cdc.MarshalJSON(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -58,8 +56,8 @@ func MarshalJSONIndent(m JSONMarshaler, obj interface{}) ([]byte, error) {
|
||||
}
|
||||
|
||||
// MustMarshalJSONIndent executes MarshalJSONIndent except it panics upon failure.
|
||||
func MustMarshalJSONIndent(m JSONMarshaler, obj interface{}) []byte {
|
||||
bz, err := MarshalJSONIndent(m, obj)
|
||||
func MustMarshalJSONIndent(cdc *LegacyAmino, obj interface{}) []byte {
|
||||
bz, err := MarshalJSONIndent(cdc, obj)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to marshal JSON: %s", err))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package codec
|
||||
|
||||
import "github.com/gogo/protobuf/proto"
|
||||
|
||||
// AminoCodec defines a codec that utilizes Codec for both binary and JSON
|
||||
// encoding.
|
||||
type AminoCodec struct {
|
||||
@@ -8,38 +10,71 @@ type AminoCodec struct {
|
||||
|
||||
var _ Marshaler = &AminoCodec{}
|
||||
|
||||
// NewAminoCodec returns a reference to a new AminoCodec
|
||||
func NewAminoCodec(codec *LegacyAmino) *AminoCodec {
|
||||
return &AminoCodec{LegacyAmino: codec}
|
||||
}
|
||||
|
||||
// MarshalBinaryBare implements BinaryMarshaler.MarshalBinaryBare method.
|
||||
func (ac *AminoCodec) MarshalBinaryBare(o ProtoMarshaler) ([]byte, error) {
|
||||
return ac.LegacyAmino.MarshalBinaryBare(o)
|
||||
}
|
||||
|
||||
// MustMarshalBinaryBare implements BinaryMarshaler.MustMarshalBinaryBare method.
|
||||
func (ac *AminoCodec) MustMarshalBinaryBare(o ProtoMarshaler) []byte {
|
||||
return ac.LegacyAmino.MustMarshalBinaryBare(o)
|
||||
}
|
||||
|
||||
// MarshalBinaryLengthPrefixed implements BinaryMarshaler.MarshalBinaryLengthPrefixed method.
|
||||
func (ac *AminoCodec) MarshalBinaryLengthPrefixed(o ProtoMarshaler) ([]byte, error) {
|
||||
return ac.LegacyAmino.MarshalBinaryLengthPrefixed(o)
|
||||
}
|
||||
|
||||
// MustMarshalBinaryLengthPrefixed implements BinaryMarshaler.MustMarshalBinaryLengthPrefixed method.
|
||||
func (ac *AminoCodec) MustMarshalBinaryLengthPrefixed(o ProtoMarshaler) []byte {
|
||||
return ac.LegacyAmino.MustMarshalBinaryLengthPrefixed(o)
|
||||
}
|
||||
|
||||
// UnmarshalBinaryBare implements BinaryMarshaler.UnmarshalBinaryBare method.
|
||||
func (ac *AminoCodec) UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error {
|
||||
return ac.LegacyAmino.UnmarshalBinaryBare(bz, ptr)
|
||||
}
|
||||
|
||||
// MustUnmarshalBinaryBare implements BinaryMarshaler.MustUnmarshalBinaryBare method.
|
||||
func (ac *AminoCodec) MustUnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) {
|
||||
ac.LegacyAmino.MustUnmarshalBinaryBare(bz, ptr)
|
||||
}
|
||||
|
||||
// UnmarshalBinaryLengthPrefixed implements BinaryMarshaler.UnmarshalBinaryLengthPrefixed method.
|
||||
func (ac *AminoCodec) UnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) error {
|
||||
return ac.LegacyAmino.UnmarshalBinaryLengthPrefixed(bz, ptr)
|
||||
}
|
||||
|
||||
// MustUnmarshalBinaryLengthPrefixed implements BinaryMarshaler.MustUnmarshalBinaryLengthPrefixed method.
|
||||
func (ac *AminoCodec) MustUnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) {
|
||||
ac.LegacyAmino.MustUnmarshalBinaryLengthPrefixed(bz, ptr)
|
||||
}
|
||||
|
||||
// MarshalJSON implements JSONMarshaler.MarshalJSON method,
|
||||
// it marshals to JSON using legacy amino codec.
|
||||
func (ac *AminoCodec) MarshalJSON(o proto.Message) ([]byte, error) {
|
||||
return ac.LegacyAmino.MarshalJSON(o)
|
||||
}
|
||||
|
||||
// MustMarshalJSON implements JSONMarshaler.MustMarshalJSON method,
|
||||
// it executes MarshalJSON except it panics upon failure.
|
||||
func (ac *AminoCodec) MustMarshalJSON(o proto.Message) []byte {
|
||||
return ac.LegacyAmino.MustMarshalJSON(o)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements JSONMarshaler.UnmarshalJSON method,
|
||||
// it unmarshals from JSON using legacy amino codec.
|
||||
func (ac *AminoCodec) UnmarshalJSON(bz []byte, ptr proto.Message) error {
|
||||
return ac.LegacyAmino.UnmarshalJSON(bz, ptr)
|
||||
}
|
||||
|
||||
// MustUnmarshalJSON implements JSONMarshaler.MustUnmarshalJSON method,
|
||||
// it executes UnmarshalJSON except it panics upon failure.
|
||||
func (ac *AminoCodec) MustUnmarshalJSON(bz []byte, ptr proto.Message) {
|
||||
ac.LegacyAmino.MustUnmarshalJSON(bz, ptr)
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func TestAminoCodec(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
codec codec.Marshaler
|
||||
codec *codec.AminoCodec
|
||||
input codec.ProtoMarshaler
|
||||
recv codec.ProtoMarshaler
|
||||
marshalErr bool
|
||||
@@ -175,7 +175,7 @@ func TestAminoCodecMarshalJSONIndent(t *testing.T) {
|
||||
|
||||
if tc.marshalErr {
|
||||
require.Error(t, err)
|
||||
require.Panics(t, func() { codec.MustMarshalJSONIndent(cdc, tc.input) })
|
||||
require.Panics(t, func() { codec.MustMarshalJSONIndent(cdc.LegacyAmino, tc.input) })
|
||||
return
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ func TestAminoCodecMarshalJSONIndent(t *testing.T) {
|
||||
require.Equal(t, bz, []byte(tc.wantJSON))
|
||||
|
||||
var bz2 []byte
|
||||
require.NotPanics(t, func() { bz2 = codec.MustMarshalJSONIndent(cdc, tc.input) })
|
||||
require.NotPanics(t, func() { bz2 = codec.MustMarshalJSONIndent(cdc.LegacyAmino, tc.input) })
|
||||
require.Equal(t, bz2, []byte(tc.wantJSON))
|
||||
})
|
||||
}
|
||||
|
||||
+5
-5
@@ -10,7 +10,7 @@ type (
|
||||
// Marshaler defines the interface module codecs must implement in order to support
|
||||
// backwards compatibility with Amino while allowing custom Protobuf-based
|
||||
// serialization. Note, Amino can still be used without any dependency on
|
||||
// Protobuf. There are three typical implementations that fulfill this contract:
|
||||
// Protobuf. There are two typical implementations that fulfill this contract:
|
||||
//
|
||||
// 1. AminoCodec: Provides full Amino serialization compatibility.
|
||||
// 2. ProtoCodec: Provides full Protobuf serialization compatibility.
|
||||
@@ -36,11 +36,11 @@ type (
|
||||
}
|
||||
|
||||
JSONMarshaler interface {
|
||||
MarshalJSON(o interface{}) ([]byte, error)
|
||||
MustMarshalJSON(o interface{}) []byte
|
||||
MarshalJSON(o proto.Message) ([]byte, error)
|
||||
MustMarshalJSON(o proto.Message) []byte
|
||||
|
||||
UnmarshalJSON(bz []byte, ptr interface{}) error
|
||||
MustUnmarshalJSON(bz []byte, ptr interface{})
|
||||
UnmarshalJSON(bz []byte, ptr proto.Message) error
|
||||
MustUnmarshalJSON(bz []byte, ptr proto.Message)
|
||||
}
|
||||
|
||||
// ProtoMarshaler defines an interface a type must implement as protocol buffer
|
||||
|
||||
+25
-4
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// ProtoCodec defines a codec that utilizes Protobuf for both binary and JSON
|
||||
@@ -18,14 +19,17 @@ type ProtoCodec struct {
|
||||
|
||||
var _ Marshaler = &ProtoCodec{}
|
||||
|
||||
// NewProtoCodec returns a reference to a new ProtoCodec
|
||||
func NewProtoCodec(anyUnpacker types.AnyUnpacker) *ProtoCodec {
|
||||
return &ProtoCodec{anyUnpacker: anyUnpacker}
|
||||
}
|
||||
|
||||
// MarshalBinaryBare implements BinaryMarshaler.MarshalBinaryBare method.
|
||||
func (pc *ProtoCodec) MarshalBinaryBare(o ProtoMarshaler) ([]byte, error) {
|
||||
return o.Marshal()
|
||||
}
|
||||
|
||||
// MustMarshalBinaryBare implements BinaryMarshaler.MustMarshalBinaryBare method.
|
||||
func (pc *ProtoCodec) MustMarshalBinaryBare(o ProtoMarshaler) []byte {
|
||||
bz, err := pc.MarshalBinaryBare(o)
|
||||
if err != nil {
|
||||
@@ -35,6 +39,7 @@ func (pc *ProtoCodec) MustMarshalBinaryBare(o ProtoMarshaler) []byte {
|
||||
return bz
|
||||
}
|
||||
|
||||
// MarshalBinaryLengthPrefixed implements BinaryMarshaler.MarshalBinaryLengthPrefixed method.
|
||||
func (pc *ProtoCodec) MarshalBinaryLengthPrefixed(o ProtoMarshaler) ([]byte, error) {
|
||||
bz, err := pc.MarshalBinaryBare(o)
|
||||
if err != nil {
|
||||
@@ -46,6 +51,7 @@ func (pc *ProtoCodec) MarshalBinaryLengthPrefixed(o ProtoMarshaler) ([]byte, err
|
||||
return append(sizeBuf[:n], bz...), nil
|
||||
}
|
||||
|
||||
// MustMarshalBinaryLengthPrefixed implements BinaryMarshaler.MustMarshalBinaryLengthPrefixed method.
|
||||
func (pc *ProtoCodec) MustMarshalBinaryLengthPrefixed(o ProtoMarshaler) []byte {
|
||||
bz, err := pc.MarshalBinaryLengthPrefixed(o)
|
||||
if err != nil {
|
||||
@@ -55,6 +61,7 @@ func (pc *ProtoCodec) MustMarshalBinaryLengthPrefixed(o ProtoMarshaler) []byte {
|
||||
return bz
|
||||
}
|
||||
|
||||
// UnmarshalBinaryBare implements BinaryMarshaler.UnmarshalBinaryBare method.
|
||||
func (pc *ProtoCodec) UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error {
|
||||
err := ptr.Unmarshal(bz)
|
||||
if err != nil {
|
||||
@@ -67,12 +74,14 @@ func (pc *ProtoCodec) UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustUnmarshalBinaryBare implements BinaryMarshaler.MustUnmarshalBinaryBare method.
|
||||
func (pc *ProtoCodec) MustUnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) {
|
||||
if err := pc.UnmarshalBinaryBare(bz, ptr); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalBinaryLengthPrefixed implements BinaryMarshaler.UnmarshalBinaryLengthPrefixed method.
|
||||
func (pc *ProtoCodec) UnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) error {
|
||||
size, n := binary.Uvarint(bz)
|
||||
if n < 0 {
|
||||
@@ -89,13 +98,16 @@ func (pc *ProtoCodec) UnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshale
|
||||
return pc.UnmarshalBinaryBare(bz, ptr)
|
||||
}
|
||||
|
||||
// MustUnmarshalBinaryLengthPrefixed implements BinaryMarshaler.MustUnmarshalBinaryLengthPrefixed method.
|
||||
func (pc *ProtoCodec) MustUnmarshalBinaryLengthPrefixed(bz []byte, ptr ProtoMarshaler) {
|
||||
if err := pc.UnmarshalBinaryLengthPrefixed(bz, ptr); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (pc *ProtoCodec) MarshalJSON(o interface{}) ([]byte, error) {
|
||||
// MarshalJSON implements JSONMarshaler.MarshalJSON method,
|
||||
// it marshals to JSON using proto codec.
|
||||
func (pc *ProtoCodec) MarshalJSON(o proto.Message) ([]byte, error) {
|
||||
m, ok := o.(ProtoMarshaler)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot protobuf JSON encode unsupported type: %T", o)
|
||||
@@ -104,7 +116,9 @@ func (pc *ProtoCodec) MarshalJSON(o interface{}) ([]byte, error) {
|
||||
return ProtoMarshalJSON(m)
|
||||
}
|
||||
|
||||
func (pc *ProtoCodec) MustMarshalJSON(o interface{}) []byte {
|
||||
// MustMarshalJSON implements JSONMarshaler.MustMarshalJSON method,
|
||||
// it executes MarshalJSON except it panics upon failure.
|
||||
func (pc *ProtoCodec) MustMarshalJSON(o proto.Message) []byte {
|
||||
bz, err := pc.MarshalJSON(o)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -113,7 +127,9 @@ func (pc *ProtoCodec) MustMarshalJSON(o interface{}) []byte {
|
||||
return bz
|
||||
}
|
||||
|
||||
func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr interface{}) error {
|
||||
// UnmarshalJSON implements JSONMarshaler.UnmarshalJSON method,
|
||||
// it unmarshals from JSON using proto codec.
|
||||
func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr proto.Message) error {
|
||||
m, ok := ptr.(ProtoMarshaler)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot protobuf JSON decode unsupported type: %T", ptr)
|
||||
@@ -127,12 +143,17 @@ func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr interface{}) error {
|
||||
return types.UnpackInterfaces(ptr, pc.anyUnpacker)
|
||||
}
|
||||
|
||||
func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr interface{}) {
|
||||
// MustUnmarshalJSON implements JSONMarshaler.MustUnmarshalJSON method,
|
||||
// it executes UnmarshalJSON except it panics upon failure.
|
||||
func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr proto.Message) {
|
||||
if err := pc.UnmarshalJSON(bz, ptr); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// UnpackAny implements AnyUnpacker.UnpackAny method,
|
||||
// it unpacks the value in any to the interface pointer passed in as
|
||||
// iface.
|
||||
func (pc *ProtoCodec) UnpackAny(any *types.Any, iface interface{}) error {
|
||||
return pc.anyUnpacker.UnpackAny(any, iface)
|
||||
}
|
||||
|
||||
@@ -122,26 +122,6 @@ func TestProtoCodec(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProtoCodecMarshalAnyNonProtoErrors(t *testing.T) {
|
||||
cdc := codec.NewProtoCodec(createTestInterfaceRegistry())
|
||||
|
||||
input := "this one that one"
|
||||
_, err := cdc.MarshalJSON(input)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, err, errors.New("cannot protobuf JSON encode unsupported type: string"))
|
||||
|
||||
require.Panics(t, func() { cdc.MustMarshalJSON(input) })
|
||||
}
|
||||
|
||||
func TestProtoCodecUnmarshalAnyNonProtoErrors(t *testing.T) {
|
||||
cdc := codec.NewProtoCodec(createTestInterfaceRegistry())
|
||||
|
||||
recv := new(int)
|
||||
err := cdc.UnmarshalJSON([]byte("foo"), recv)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, err, errors.New("cannot protobuf JSON decode unsupported type: *int"))
|
||||
}
|
||||
|
||||
type lyingProtoMarshaler struct {
|
||||
codec.ProtoMarshaler
|
||||
falseSize int
|
||||
|
||||
Reference in New Issue
Block a user