Skip to content

Commit

Permalink
Merge branch 'master' into am-6213-xauthante
Browse files Browse the repository at this point in the history
  • Loading branch information
amaury1093 authored Jul 10, 2020
2 parents f6d1265 + 59cd065 commit 1f79c24
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 25 deletions.
3 changes: 2 additions & 1 deletion codec/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package codec
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"

Expand Down Expand Up @@ -171,7 +172,7 @@ func (cdc *Codec) MustUnmarshalJSON(bz []byte, ptr interface{}) {
}

func (*Codec) UnpackAny(*types.Any, interface{}) error {
return fmt.Errorf("AminoCodec can't handle unpack protobuf Any's")
return errors.New("AminoCodec can't handle unpack protobuf Any's")
}

func (cdc *Codec) RegisterInterface(ptr interface{}, iopts *amino.InterfaceOptions) {
Expand Down
81 changes: 81 additions & 0 deletions codec/amino_codec_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package codec_test

import (
"bytes"
"errors"
"testing"

"github.com/cosmos/cosmos-sdk/codec/types"
Expand Down Expand Up @@ -129,3 +131,82 @@ func TestAminoCodec(t *testing.T) {
})
}
}

func TestAminoCodecMarshalJSONIndent(t *testing.T) {
any, err := types.NewAnyWithValue(&testdata.Dog{Name: "rufus"})
require.NoError(t, err)

testCases := []struct {
name string
input interface{}
marshalErr bool
wantJSON string
}{
{
name: "valid encoding and decoding",
input: &testdata.Dog{Name: "rufus"},
wantJSON: `{
"type": "testdata/Dog",
"value": {
"name": "rufus"
}
}`,
},
{
name: "any marshaling",
input: &testdata.HasAnimal{Animal: any},
wantJSON: `{
"animal": {
"type": "testdata/Dog",
"value": {
"name": "rufus"
}
}
}`,
},
}

for _, tc := range testCases {
tc := tc

t.Run(tc.name, func(t *testing.T) {
cdc := codec.NewAminoCodec(createTestCodec())
bz, err := cdc.MarshalJSONIndent(tc.input, "", " ")

if tc.marshalErr {
require.Error(t, err)
require.Panics(t, func() { codec.MustMarshalJSONIndent(cdc, tc.input) })
return
}

// Otherwise these are expected to pass.
require.NoError(t, err)
require.Equal(t, bz, []byte(tc.wantJSON))

var bz2 []byte
require.NotPanics(t, func() { bz2 = codec.MustMarshalJSONIndent(cdc, tc.input) })
require.Equal(t, bz2, []byte(tc.wantJSON))
})
}
}

func TestAminoCodecPrintTypes(t *testing.T) {
cdc := codec.NewAminoCodec(createTestCodec())
buf := new(bytes.Buffer)
require.NoError(t, cdc.PrintTypes(buf))
lines := bytes.Split(buf.Bytes(), []byte("\n"))
require.True(t, len(lines) > 1)
wantHeader := "| Type | Name | Prefix | Length | Notes |"
require.Equal(t, lines[0], []byte(wantHeader))

// Expecting the types to be listed in the order that they were registered.
require.True(t, bytes.HasPrefix(lines[2], []byte("| Dog | testdata/Dog |")))
require.True(t, bytes.HasPrefix(lines[3], []byte("| Cat | testdata/Cat |")))
}

func TestAminoCodecUnpackAnyFails(t *testing.T) {
cdc := codec.NewAminoCodec(createTestCodec())
err := cdc.UnpackAny(new(types.Any), &testdata.Cat{})
require.Error(t, err)
require.Equal(t, err, errors.New("AminoCodec can't handle unpack protobuf Any's"))
}
10 changes: 10 additions & 0 deletions codec/any_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package codec_test

import (
"errors"
"testing"

"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -54,3 +55,12 @@ func TestMarshalAny(t *testing.T) {
err = codec.UnmarshalAny(cdc, nil, bz)
require.Error(t, err)
}

func TestMarshalAnyNonProtoErrors(t *testing.T) {
registry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(registry)

_, err := codec.MarshalAny(cdc, 29)
require.Error(t, err)
require.Equal(t, err, errors.New("can't proto marshal int"))
}
18 changes: 0 additions & 18 deletions codec/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,3 @@ func ProtoMarshalJSON(msg proto.Message) ([]byte, error) {

return buf.Bytes(), nil
}

// ProtoMarshalJSONIndent provides an auxiliary function to return Proto3 indented
// JSON encoded bytes of a message.
func ProtoMarshalJSONIndent(msg proto.Message) ([]byte, error) {
jm := &jsonpb.Marshaler{EmitDefaults: false, OrigName: false, Indent: " "}
err := types.UnpackInterfaces(msg, types.ProtoJSONPacker{JSONPBMarshaler: jm})
if err != nil {
return nil, err
}

buf := new(bytes.Buffer)

if err := jm.Marshal(buf, msg); err != nil {
return nil, err
}

return buf.Bytes(), nil
}
75 changes: 75 additions & 0 deletions codec/proto_codec_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package codec_test

import (
"errors"
"fmt"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -118,3 +120,76 @@ 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
}

func (lpm *lyingProtoMarshaler) Size() int {
return lpm.falseSize
}

func TestProtoCodecUnmarshalBinaryLengthPrefixedChecks(t *testing.T) {
cdc := codec.NewProtoCodec(createTestInterfaceRegistry())

truth := &testdata.Cat{Lives: 9, Moniker: "glowing"}
realSize := len(cdc.MustMarshalBinaryBare(truth))

falseSizes := []int{
100,
5,
}

for _, falseSize := range falseSizes {
falseSize := falseSize

t.Run(fmt.Sprintf("ByMarshaling falseSize=%d", falseSize), func(t *testing.T) {
lpm := &lyingProtoMarshaler{
ProtoMarshaler: &testdata.Cat{Lives: 9, Moniker: "glowing"},
falseSize: falseSize,
}
var serialized []byte
require.NotPanics(t, func() { serialized = cdc.MustMarshalBinaryLengthPrefixed(lpm) })

recv := new(testdata.Cat)
gotErr := cdc.UnmarshalBinaryLengthPrefixed(serialized, recv)
var wantErr error
if falseSize > realSize {
wantErr = fmt.Errorf("not enough bytes to read; want: %d, got: %d", falseSize, realSize)
} else {
wantErr = fmt.Errorf("too many bytes to read; want: %d, got: %d", falseSize, realSize)
}
require.Equal(t, gotErr, wantErr)
})
}

t.Run("Crafted bad uvarint size", func(t *testing.T) {
crafted := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}
recv := new(testdata.Cat)
gotErr := cdc.UnmarshalBinaryLengthPrefixed(crafted, recv)
require.Equal(t, gotErr, errors.New("invalid number of bytes read from length-prefixed encoding: -10"))

require.Panics(t, func() { cdc.MustUnmarshalBinaryLengthPrefixed(crafted, recv) })
})
}
12 changes: 8 additions & 4 deletions types/coin_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ import (
"testing"
)

func coinName(suffix int) string {
return fmt.Sprintf("COINZ_%d", suffix)
}

func BenchmarkCoinsAdditionIntersect(b *testing.B) {
benchmarkingFunc := func(numCoinsA int, numCoinsB int) func(b *testing.B) {
return func(b *testing.B) {
coinsA := Coins(make([]Coin, numCoinsA))
coinsB := Coins(make([]Coin, numCoinsB))

for i := 0; i < numCoinsA; i++ {
coinsA[i] = NewCoin("COINZ_"+string(i), NewInt(int64(i)))
coinsA[i] = NewCoin(coinName(i), NewInt(int64(i)))
}
for i := 0; i < numCoinsB; i++ {
coinsB[i] = NewCoin("COINZ_"+string(i), NewInt(int64(i)))
coinsB[i] = NewCoin(coinName(i), NewInt(int64(i)))
}

b.ResetTimer()
Expand All @@ -41,10 +45,10 @@ func BenchmarkCoinsAdditionNoIntersect(b *testing.B) {
coinsB := Coins(make([]Coin, numCoinsB))

for i := 0; i < numCoinsA; i++ {
coinsA[i] = NewCoin("COINZ_"+string(numCoinsB+i), NewInt(int64(i)))
coinsA[i] = NewCoin(coinName(numCoinsB+i), NewInt(int64(i)))
}
for i := 0; i < numCoinsB; i++ {
coinsB[i] = NewCoin("COINZ_"+string(i), NewInt(int64(i)))
coinsB[i] = NewCoin(coinName(i), NewInt(int64(i)))
}

b.ResetTimer()
Expand Down
4 changes: 2 additions & 2 deletions x/auth/types/txbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ func NewTxBuilder(
}
}

// NewTxBuilderFromCLI returns a new initialized TxBuilder with parameters extracted from
// FlagSet (It should deprecate NewTxBuilderFromCLI).
// NewTxBuilderFromFlags returns a new initialized TxBuilder with parameters extracted from
// FlagSet.
func NewTxBuilderFromFlags(input io.Reader, fs *pflag.FlagSet, keyringPath string) (TxBuilder, error) {
backend, _ := fs.GetString(flags.FlagKeyringBackend)
kb, _ := keyring.New(sdk.KeyringServiceName(), backend, keyringPath, input)
Expand Down

0 comments on commit 1f79c24

Please sign in to comment.