diff --git a/codec/amino_codec.go b/codec/amino_codec.go index 8c1eb9f85c45..d77acbc7e8e0 100644 --- a/codec/amino_codec.go +++ b/codec/amino_codec.go @@ -18,42 +18,42 @@ func NewAminoCodec(codec *LegacyAmino) *AminoCodec { } // Marshal implements BinaryMarshaler.Marshal method. -func (ac *AminoCodec) Marshal(o ProtoMarshaler) ([]byte, error) { +func (ac *AminoCodec) Marshal(o proto.Message) ([]byte, error) { return ac.LegacyAmino.Marshal(o) } // MustMarshal implements BinaryMarshaler.MustMarshal method. -func (ac *AminoCodec) MustMarshal(o ProtoMarshaler) []byte { +func (ac *AminoCodec) MustMarshal(o proto.Message) []byte { return ac.LegacyAmino.MustMarshal(o) } // MarshalLengthPrefixed implements BinaryMarshaler.MarshalLengthPrefixed method. -func (ac *AminoCodec) MarshalLengthPrefixed(o ProtoMarshaler) ([]byte, error) { +func (ac *AminoCodec) MarshalLengthPrefixed(o proto.Message) ([]byte, error) { return ac.LegacyAmino.MarshalLengthPrefixed(o) } // MustMarshalLengthPrefixed implements BinaryMarshaler.MustMarshalLengthPrefixed method. -func (ac *AminoCodec) MustMarshalLengthPrefixed(o ProtoMarshaler) []byte { +func (ac *AminoCodec) MustMarshalLengthPrefixed(o proto.Message) []byte { return ac.LegacyAmino.MustMarshalLengthPrefixed(o) } // Unmarshal implements BinaryMarshaler.Unmarshal method. -func (ac *AminoCodec) Unmarshal(bz []byte, ptr ProtoMarshaler) error { +func (ac *AminoCodec) Unmarshal(bz []byte, ptr proto.Message) error { return ac.LegacyAmino.Unmarshal(bz, ptr) } // MustUnmarshal implements BinaryMarshaler.MustUnmarshal method. -func (ac *AminoCodec) MustUnmarshal(bz []byte, ptr ProtoMarshaler) { +func (ac *AminoCodec) MustUnmarshal(bz []byte, ptr proto.Message) { ac.LegacyAmino.MustUnmarshal(bz, ptr) } // UnmarshalLengthPrefixed implements BinaryMarshaler.UnmarshalLengthPrefixed method. -func (ac *AminoCodec) UnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) error { +func (ac *AminoCodec) UnmarshalLengthPrefixed(bz []byte, ptr proto.Message) error { return ac.LegacyAmino.UnmarshalLengthPrefixed(bz, ptr) } // MustUnmarshalLengthPrefixed implements BinaryMarshaler.MustUnmarshalLengthPrefixed method. -func (ac *AminoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) { +func (ac *AminoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr proto.Message) { ac.LegacyAmino.MustUnmarshalLengthPrefixed(bz, ptr) } diff --git a/codec/codec.go b/codec/codec.go index bd32928d9354..5fe0e98e89f3 100644 --- a/codec/codec.go +++ b/codec/codec.go @@ -22,28 +22,28 @@ type ( BinaryCodec interface { // Marshal returns binary encoding of v. - Marshal(o ProtoMarshaler) ([]byte, error) + Marshal(o proto.Message) ([]byte, error) // MustMarshal calls Marshal and panics if error is returned. - MustMarshal(o ProtoMarshaler) []byte + MustMarshal(o proto.Message) []byte // MarshalLengthPrefixed returns binary encoding of v with bytes length prefix. - MarshalLengthPrefixed(o ProtoMarshaler) ([]byte, error) + MarshalLengthPrefixed(o proto.Message) ([]byte, error) // MustMarshalLengthPrefixed calls MarshalLengthPrefixed and panics if // error is returned. - MustMarshalLengthPrefixed(o ProtoMarshaler) []byte + MustMarshalLengthPrefixed(o proto.Message) []byte // Unmarshal parses the data encoded with Marshal method and stores the result // in the value pointed to by v. - Unmarshal(bz []byte, ptr ProtoMarshaler) error + Unmarshal(bz []byte, ptr proto.Message) error // MustUnmarshal calls Unmarshal and panics if error is returned. - MustUnmarshal(bz []byte, ptr ProtoMarshaler) + MustUnmarshal(bz []byte, ptr proto.Message) // Unmarshal parses the data encoded with UnmarshalLengthPrefixed method and stores // the result in the value pointed to by v. - UnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) error + UnmarshalLengthPrefixed(bz []byte, ptr proto.Message) error // MustUnmarshalLengthPrefixed calls UnmarshalLengthPrefixed and panics if error // is returned. - MustUnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) + MustUnmarshalLengthPrefixed(bz []byte, ptr proto.Message) // MarshalInterface is a helper method which will wrap `i` into `Any` for correct // binary interface (de)serialization. @@ -78,6 +78,8 @@ type ( // ProtoMarshaler defines an interface a type must implement to serialize itself // as a protocol buffer defined message. + // + // Deprecated: Use proto.Message instead from github.com/cosmos/gogoproto/proto. ProtoMarshaler interface { proto.Message // for JSON serialization diff --git a/codec/codec_common_test.go b/codec/codec_common_test.go index e4730d671c05..6c793fe172e0 100644 --- a/codec/codec_common_test.go +++ b/codec/codec_common_test.go @@ -50,16 +50,16 @@ func testInterfaceMarshaling(require *require.Assertions, cdc interfaceMarshaler } type mustMarshaler struct { - marshal func(i codec.ProtoMarshaler) ([]byte, error) - mustMarshal func(i codec.ProtoMarshaler) []byte - unmarshal func(bz []byte, ptr codec.ProtoMarshaler) error - mustUnmarshal func(bz []byte, ptr codec.ProtoMarshaler) + marshal func(i proto.Message) ([]byte, error) + mustMarshal func(i proto.Message) []byte + unmarshal func(bz []byte, ptr proto.Message) error + mustUnmarshal func(bz []byte, ptr proto.Message) } type testCase struct { name string - input codec.ProtoMarshaler - recv codec.ProtoMarshaler + input proto.Message + recv proto.Message marshalErr bool unmarshalErr bool } @@ -121,10 +121,10 @@ func testMarshaling(t *testing.T, cdc codec.Codec) { m1 := mustMarshaler{cdc.Marshal, cdc.MustMarshal, cdc.Unmarshal, cdc.MustUnmarshal} m2 := mustMarshaler{cdc.MarshalLengthPrefixed, cdc.MustMarshalLengthPrefixed, cdc.UnmarshalLengthPrefixed, cdc.MustUnmarshalLengthPrefixed} m3 := mustMarshaler{ - func(i codec.ProtoMarshaler) ([]byte, error) { return cdc.MarshalJSON(i) }, - func(i codec.ProtoMarshaler) []byte { return cdc.MustMarshalJSON(i) }, - func(bz []byte, ptr codec.ProtoMarshaler) error { return cdc.UnmarshalJSON(bz, ptr) }, - func(bz []byte, ptr codec.ProtoMarshaler) { cdc.MustUnmarshalJSON(bz, ptr) }, + func(i proto.Message) ([]byte, error) { return cdc.MarshalJSON(i) }, + func(i proto.Message) []byte { return cdc.MustMarshalJSON(i) }, + func(bz []byte, ptr proto.Message) error { return cdc.UnmarshalJSON(bz, ptr) }, + func(bz []byte, ptr proto.Message) { cdc.MustUnmarshalJSON(bz, ptr) }, } t.Run(tc.name+"_BinaryBare", diff --git a/codec/proto_codec.go b/codec/proto_codec.go index b1d4eb45183e..ed71b8f897a3 100644 --- a/codec/proto_codec.go +++ b/codec/proto_codec.go @@ -6,7 +6,6 @@ import ( "fmt" "strings" - legacyproto "github.com/golang/protobuf/proto" //nolint:staticcheck "google.golang.org/grpc/encoding" "google.golang.org/protobuf/proto" @@ -42,19 +41,20 @@ func NewProtoCodec(interfaceRegistry types.InterfaceRegistry) *ProtoCodec { // Marshal implements BinaryMarshaler.Marshal method. // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.MarshalInterface -func (pc *ProtoCodec) Marshal(o ProtoMarshaler) ([]byte, error) { +func (pc *ProtoCodec) Marshal(o gogoproto.Message) ([]byte, error) { // Size() check can catch the typed nil value. - if o == nil || o.Size() == 0 { + if o == nil || gogoproto.Size(o) == 0 { // return empty bytes instead of nil, because nil has special meaning in places like store.Set return []byte{}, nil } - return o.Marshal() + + return gogoproto.Marshal(o) } // MustMarshal implements BinaryMarshaler.MustMarshal method. // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.MarshalInterface -func (pc *ProtoCodec) MustMarshal(o ProtoMarshaler) []byte { +func (pc *ProtoCodec) MustMarshal(o gogoproto.Message) []byte { bz, err := pc.Marshal(o) if err != nil { panic(err) @@ -64,19 +64,19 @@ func (pc *ProtoCodec) MustMarshal(o ProtoMarshaler) []byte { } // MarshalLengthPrefixed implements BinaryMarshaler.MarshalLengthPrefixed method. -func (pc *ProtoCodec) MarshalLengthPrefixed(o ProtoMarshaler) ([]byte, error) { +func (pc *ProtoCodec) MarshalLengthPrefixed(o gogoproto.Message) ([]byte, error) { bz, err := pc.Marshal(o) if err != nil { return nil, err } var sizeBuf [binary.MaxVarintLen64]byte - n := binary.PutUvarint(sizeBuf[:], uint64(o.Size())) + n := binary.PutUvarint(sizeBuf[:], uint64(len(bz))) return append(sizeBuf[:n], bz...), nil } // MustMarshalLengthPrefixed implements BinaryMarshaler.MustMarshalLengthPrefixed method. -func (pc *ProtoCodec) MustMarshalLengthPrefixed(o ProtoMarshaler) []byte { +func (pc *ProtoCodec) MustMarshalLengthPrefixed(o gogoproto.Message) []byte { bz, err := pc.MarshalLengthPrefixed(o) if err != nil { panic(err) @@ -88,8 +88,8 @@ func (pc *ProtoCodec) MustMarshalLengthPrefixed(o ProtoMarshaler) []byte { // Unmarshal implements BinaryMarshaler.Unmarshal method. // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.UnmarshalInterface -func (pc *ProtoCodec) Unmarshal(bz []byte, ptr ProtoMarshaler) error { - err := ptr.Unmarshal(bz) +func (pc *ProtoCodec) Unmarshal(bz []byte, ptr gogoproto.Message) error { + err := gogoproto.Unmarshal(bz, ptr) if err != nil { return err } @@ -103,14 +103,14 @@ func (pc *ProtoCodec) Unmarshal(bz []byte, ptr ProtoMarshaler) error { // MustUnmarshal implements BinaryMarshaler.MustUnmarshal method. // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.UnmarshalInterface -func (pc *ProtoCodec) MustUnmarshal(bz []byte, ptr ProtoMarshaler) { +func (pc *ProtoCodec) MustUnmarshal(bz []byte, ptr gogoproto.Message) { if err := pc.Unmarshal(bz, ptr); err != nil { panic(err) } } // UnmarshalLengthPrefixed implements BinaryMarshaler.UnmarshalLengthPrefixed method. -func (pc *ProtoCodec) UnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) error { +func (pc *ProtoCodec) UnmarshalLengthPrefixed(bz []byte, ptr gogoproto.Message) error { size, n := binary.Uvarint(bz) if n < 0 { return fmt.Errorf("invalid number of bytes read from length-prefixed encoding: %d", n) @@ -127,7 +127,7 @@ func (pc *ProtoCodec) UnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) err } // MustUnmarshalLengthPrefixed implements BinaryMarshaler.MustUnmarshalLengthPrefixed method. -func (pc *ProtoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) { +func (pc *ProtoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr gogoproto.Message) { if err := pc.UnmarshalLengthPrefixed(bz, ptr); err != nil { panic(err) } @@ -137,13 +137,13 @@ func (pc *ProtoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler) // it marshals to JSON using proto codec. // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.MarshalInterfaceJSON +// +//nolint:stdmethods func (pc *ProtoCodec) MarshalJSON(o gogoproto.Message) ([]byte, error) { - m, ok := o.(ProtoMarshaler) - if !ok { - return nil, fmt.Errorf("cannot protobuf JSON encode unsupported type: %T", o) + if o == nil { + return nil, fmt.Errorf("cannot protobuf JSON encode nil") } - - return ProtoMarshalJSON(m, pc.interfaceRegistry) + return ProtoMarshalJSON(o, pc.interfaceRegistry) } // MustMarshalJSON implements JSONCodec.MustMarshalJSON method, @@ -164,13 +164,11 @@ func (pc *ProtoCodec) MustMarshalJSON(o gogoproto.Message) []byte { // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.UnmarshalInterfaceJSON func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr gogoproto.Message) error { - m, ok := ptr.(ProtoMarshaler) - if !ok { + if ptr == nil { return fmt.Errorf("cannot protobuf JSON decode unsupported type: %T", ptr) } - unmarshaler := jsonpb.Unmarshaler{AnyResolver: pc.interfaceRegistry} - err := unmarshaler.Unmarshal(strings.NewReader(string(bz)), m) + err := unmarshaler.Unmarshal(strings.NewReader(string(bz)), ptr) if err != nil { return err } @@ -283,10 +281,8 @@ func (g grpcProtoCodec) Marshal(v interface{}) ([]byte, error) { switch m := v.(type) { case proto.Message: return proto.Marshal(m) - case ProtoMarshaler: + case gogoproto.Message: return g.cdc.Marshal(m) - case legacyproto.Message: - return legacyproto.Marshal(m) default: return nil, fmt.Errorf("%w: cannot marshal type %T", errUnknownProtoType, v) } @@ -296,10 +292,8 @@ func (g grpcProtoCodec) Unmarshal(data []byte, v interface{}) error { switch m := v.(type) { case proto.Message: return proto.Unmarshal(data, m) - case ProtoMarshaler: + case gogoproto.Message: return g.cdc.Unmarshal(data, m) - case legacyproto.Message: - return legacyproto.Unmarshal(data, m) default: return fmt.Errorf("%w: cannot unmarshal type %T", errUnknownProtoType, v) } diff --git a/codec/proto_codec_test.go b/codec/proto_codec_test.go index b661db1fe70c..fc2e97d000b3 100644 --- a/codec/proto_codec_test.go +++ b/codec/proto_codec_test.go @@ -1,8 +1,6 @@ package codec_test import ( - "errors" - "fmt" "math" "reflect" "testing" @@ -43,15 +41,6 @@ func TestProtoCodec(t *testing.T) { testMarshaling(t, cdc) } -type lyingProtoMarshaler struct { - codec.ProtoMarshaler - falseSize int -} - -func (lpm *lyingProtoMarshaler) Size() int { - return lpm.falseSize -} - func TestEnsureRegistered(t *testing.T) { interfaceRegistry := types.NewInterfaceRegistry() cat := &testdata.Cat{Moniker: "Garfield"} @@ -138,50 +127,6 @@ func grpcServerEncode(c encoding.Codec, msg interface{}) ([]byte, error) { return b, nil } -func TestProtoCodecUnmarshalLengthPrefixedChecks(t *testing.T) { - cdc := codec.NewProtoCodec(createTestInterfaceRegistry()) - - truth := &testdata.Cat{Lives: 9, Moniker: "glowing"} - realSize := len(cdc.MustMarshal(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.MustMarshalLengthPrefixed(lpm) }) - - recv := new(testdata.Cat) - gotErr := cdc.UnmarshalLengthPrefixed(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.UnmarshalLengthPrefixed(crafted, recv) - require.Equal(t, gotErr, errors.New("invalid number of bytes read from length-prefixed encoding: -10")) - - require.Panics(t, func() { cdc.MustUnmarshalLengthPrefixed(crafted, recv) }) - }) -} - func mustAny(msg proto.Message) *types.Any { any, err := types.NewAnyWithValue(msg) if err != nil { diff --git a/tests/e2e/gov/grpc.go b/tests/e2e/gov/grpc.go index a185d46e6a82..5dd5f59436ae 100644 --- a/tests/e2e/gov/grpc.go +++ b/tests/e2e/gov/grpc.go @@ -400,7 +400,6 @@ func (s *IntegrationTestSuite) TestGetParamsGRPC() { s.Run(tc.name, func() { resp, err := testutil.GetRequest(tc.url) s.Require().NoError(err) - err = val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType) if tc.expErr { diff --git a/types/query/filtered_pagination.go b/types/query/filtered_pagination.go index 50c85ac49a51..e2263b733b66 100644 --- a/types/query/filtered_pagination.go +++ b/types/query/filtered_pagination.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/types" + proto "github.com/cosmos/gogoproto/proto" ) // FilteredPaginate does pagination of all the results in the PrefixStore based on the @@ -128,7 +129,7 @@ func FilteredPaginate( // If offset is used, the pagination uses lazy filtering i.e., searches through all the records. // The resulting slice (of type F) can be of a different type than the one being iterated through // (type T), so it's possible to do any necessary transformation inside the onResult function. -func GenericFilteredPaginate[T codec.ProtoMarshaler, F codec.ProtoMarshaler]( +func GenericFilteredPaginate[T, F proto.Message]( cdc codec.BinaryCodec, prefixStore types.KVStore, pageRequest *PageRequest, @@ -189,7 +190,7 @@ func GenericFilteredPaginate[T codec.ProtoMarshaler, F codec.ProtoMarshaler]( return nil, nil, err } - if val.Size() != 0 { + if proto.Size(val) != 0 { results = append(results, val) numHits++ } @@ -227,7 +228,7 @@ func GenericFilteredPaginate[T codec.ProtoMarshaler, F codec.ProtoMarshaler]( return nil, nil, err } - if val.Size() != 0 { + if proto.Size(val) != 0 { // Previously this was the "accumulate" flag if numHits >= offset && numHits < end { results = append(results, val) diff --git a/x/group/internal/orm/auto_uint64.go b/x/group/internal/orm/auto_uint64.go index 01f1b326d816..f085a3dd1300 100644 --- a/x/group/internal/orm/auto_uint64.go +++ b/x/group/internal/orm/auto_uint64.go @@ -1,6 +1,8 @@ package orm import ( + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/errors" @@ -18,7 +20,7 @@ type AutoUInt64Table struct { } // NewAutoUInt64Table creates a new AutoUInt64Table. -func NewAutoUInt64Table(prefixData [2]byte, prefixSeq byte, model codec.ProtoMarshaler, cdc codec.Codec) (*AutoUInt64Table, error) { +func NewAutoUInt64Table(prefixData [2]byte, prefixSeq byte, model proto.Message, cdc codec.Codec) (*AutoUInt64Table, error) { table, err := newTable(prefixData, model, cdc) if err != nil { return nil, err @@ -34,7 +36,7 @@ func NewAutoUInt64Table(prefixData [2]byte, prefixSeq byte, model codec.ProtoMar // // Create iterates through the registered callbacks that may add secondary index // keys. -func (a AutoUInt64Table) Create(store sdk.KVStore, obj codec.ProtoMarshaler) (uint64, error) { +func (a AutoUInt64Table) Create(store sdk.KVStore, obj proto.Message) (uint64, error) { autoIncID := a.seq.NextVal(store) err := a.table.Create(store, EncodeSequence(autoIncID), obj) if err != nil { @@ -50,7 +52,7 @@ func (a AutoUInt64Table) Create(store sdk.KVStore, obj codec.ProtoMarshaler) (ui // // Update iterates through the registered callbacks that may add or remove // secondary index keys. -func (a AutoUInt64Table) Update(store sdk.KVStore, rowID uint64, newValue codec.ProtoMarshaler) error { +func (a AutoUInt64Table) Update(store sdk.KVStore, rowID uint64, newValue proto.Message) error { return a.table.Update(store, EncodeSequence(rowID), newValue) } @@ -70,7 +72,7 @@ func (a AutoUInt64Table) Has(store sdk.KVStore, rowID uint64) bool { // GetOne load the object persisted for the given RowID into the dest parameter. // If none exists `ErrNotFound` is returned instead. Parameters must not be nil. -func (a AutoUInt64Table) GetOne(store sdk.KVStore, rowID uint64, dest codec.ProtoMarshaler) (RowID, error) { +func (a AutoUInt64Table) GetOne(store sdk.KVStore, rowID uint64, dest proto.Message) (RowID, error) { rawRowID := EncodeSequence(rowID) if err := a.table.GetOne(store, rawRowID, dest); err != nil { return nil, err diff --git a/x/group/internal/orm/index.go b/x/group/internal/orm/index.go index ceb44bbf3c53..7239f4aafbab 100644 --- a/x/group/internal/orm/index.go +++ b/x/group/internal/orm/index.go @@ -3,7 +3,8 @@ package orm import ( "bytes" - "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -198,7 +199,7 @@ func getPrefixScanKeyBytes(keyI interface{}) ([]byte, error) { return key, nil } -func (i MultiKeyIndex) onSet(store sdk.KVStore, rowID RowID, newValue, oldValue codec.ProtoMarshaler) error { +func (i MultiKeyIndex) onSet(store sdk.KVStore, rowID RowID, newValue, oldValue proto.Message) error { pStore := prefix.NewStore(store, []byte{i.prefix}) if oldValue == nil { return i.indexer.OnCreate(pStore, rowID, newValue) @@ -206,7 +207,7 @@ func (i MultiKeyIndex) onSet(store sdk.KVStore, rowID RowID, newValue, oldValue return i.indexer.OnUpdate(pStore, rowID, newValue, oldValue) } -func (i MultiKeyIndex) onDelete(store sdk.KVStore, rowID RowID, oldValue codec.ProtoMarshaler) error { +func (i MultiKeyIndex) onDelete(store sdk.KVStore, rowID RowID, oldValue proto.Message) error { pStore := prefix.NewStore(store, []byte{i.prefix}) return i.indexer.OnDelete(pStore, rowID, oldValue) } @@ -241,7 +242,7 @@ type indexIterator struct { // LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there // are no more items the errors.ErrORMIteratorDone error is returned // The key is the rowID and not any MultiKeyIndex key. -func (i indexIterator) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { +func (i indexIterator) LoadNext(dest proto.Message) (RowID, error) { if !i.it.Valid() { return nil, errors.ErrORMIteratorDone } diff --git a/x/group/internal/orm/iterator.go b/x/group/internal/orm/iterator.go index 11fb4c64a014..09214ab345dc 100644 --- a/x/group/internal/orm/iterator.go +++ b/x/group/internal/orm/iterator.go @@ -4,7 +4,8 @@ import ( "fmt" "reflect" - "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/gogoproto/proto" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/x/group/errors" @@ -15,12 +16,12 @@ const defaultPageLimit = 100 // IteratorFunc is a function type that satisfies the Iterator interface // The passed function is called on LoadNext operations. -type IteratorFunc func(dest codec.ProtoMarshaler) (RowID, error) +type IteratorFunc func(dest proto.Message) (RowID, error) // LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there // are no more items the errors.ErrORMIteratorDone error is returned // The key is the rowID and not any MultiKeyIndex key. -func (i IteratorFunc) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { +func (i IteratorFunc) LoadNext(dest proto.Message) (RowID, error) { return i(dest) } @@ -31,7 +32,7 @@ func (i IteratorFunc) Close() error { func NewSingleValueIterator(rowID RowID, val []byte) Iterator { var closed bool - return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + return IteratorFunc(func(dest proto.Message) (RowID, error) { if dest == nil { return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination object must not be nil") } @@ -39,13 +40,13 @@ func NewSingleValueIterator(rowID RowID, val []byte) Iterator { return nil, errors.ErrORMIteratorDone } closed = true - return rowID, dest.Unmarshal(val) + return rowID, proto.Unmarshal(val, dest) }) } // Iterator that return ErrORMInvalidIterator only. func NewInvalidIterator() Iterator { - return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + return IteratorFunc(func(dest proto.Message) (RowID, error) { return nil, errors.ErrORMInvalidIterator }) } @@ -72,7 +73,7 @@ func LimitIterator(parent Iterator, max int) (*LimitedIterator, error) { // LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there // are no more items or the defined max number of elements was returned the `errors.ErrORMIteratorDone` error is returned // The key is the rowID and not any MultiKeyIndex key. -func (i *LimitedIterator) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { +func (i *LimitedIterator) LoadNext(dest proto.Message) (RowID, error) { if i.remainingCount == 0 { return nil, errors.ErrORMIteratorDone } @@ -87,7 +88,7 @@ func (i LimitedIterator) Close() error { // First loads the first element into the given destination type and closes the iterator. // When the iterator is closed or has no elements the according error is passed as return value. -func First(it Iterator, dest codec.ProtoMarshaler) (RowID, error) { +func First(it Iterator, dest proto.Message) (RowID, error) { if it == nil { return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "iterator must not be nil") } @@ -173,7 +174,7 @@ func Paginate( model = val } - modelProto, ok := model.Interface().(codec.ProtoMarshaler) + modelProto, ok := model.Interface().(proto.Message) if !ok { return nil, sdkerrors.Wrapf(errors.ErrORMInvalidArgument, "%s should implement codec.ProtoMarshaler", elemType) } @@ -255,7 +256,7 @@ func ReadAll(it Iterator, dest ModelSlicePtr) ([]RowID, error) { model = val } - binKey, err := it.LoadNext(model.Interface().(codec.ProtoMarshaler)) + binKey, err := it.LoadNext(model.Interface().(proto.Message)) switch { case err == nil: tmpSlice = reflect.Append(tmpSlice, val) @@ -294,7 +295,7 @@ func assertDest(dest ModelSlicePtr, destRef *reflect.Value, tmpSlice *reflect.Va elemType := reflect.TypeOf(dest).Elem().Elem() - protoMarshaler := reflect.TypeOf((*codec.ProtoMarshaler)(nil)).Elem() + protoMarshaler := reflect.TypeOf((*proto.Message)(nil)).Elem() if !elemType.Implements(protoMarshaler) && !reflect.PtrTo(elemType).Implements(protoMarshaler) { return nil, sdkerrors.Wrapf(errors.ErrORMInvalidArgument, "unsupported type :%s", elemType) diff --git a/x/group/internal/orm/iterator_property_test.go b/x/group/internal/orm/iterator_property_test.go index c1e5eaec8b90..2b3a0e565bac 100644 --- a/x/group/internal/orm/iterator_property_test.go +++ b/x/group/internal/orm/iterator_property_test.go @@ -3,13 +3,14 @@ package orm import ( "testing" - "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/gogoproto/proto" + "github.com/stretchr/testify/require" + "pgregory.net/rapid" + "github.com/cosmos/cosmos-sdk/testutil/testdata" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/x/group/errors" - "github.com/stretchr/testify/require" - "pgregory.net/rapid" ) func TestPaginationProperty(t *testing.T) { @@ -94,7 +95,7 @@ func testTableModelIterator(tms []*testdata.TableModel, key RowID) Iterator { if key != nil { index = int(DecodeSequence(key)) } - return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + return IteratorFunc(func(dest proto.Message) (RowID, error) { if dest == nil { return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination object must not be nil") } @@ -116,6 +117,6 @@ func testTableModelIterator(tms []*testdata.TableModel, key RowID) Iterator { index++ - return rowID, dest.Unmarshal(bytes) + return rowID, proto.Unmarshal(bytes, dest) }) } diff --git a/x/group/internal/orm/iterator_test.go b/x/group/internal/orm/iterator_test.go index bbafa34a11f7..54abe524576c 100644 --- a/x/group/internal/orm/iterator_test.go +++ b/x/group/internal/orm/iterator_test.go @@ -3,6 +3,10 @@ package orm import ( "testing" + "github.com/cosmos/gogoproto/proto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" @@ -10,8 +14,6 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/x/group/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestReadAll(t *testing.T) { @@ -150,11 +152,11 @@ func TestFirst(t *testing.T) { testCases := []struct { name string iterator Iterator - dest codec.ProtoMarshaler + dest proto.Message expectErr bool expectedErr string expectedRowID RowID - expectedDest codec.ProtoMarshaler + expectedDest proto.Message }{ { name: "nil iterator", @@ -342,8 +344,8 @@ func TestPaginate(t *testing.T) { } // mockIter encodes + decodes value object. -func mockIter(rowID RowID, val codec.ProtoMarshaler) Iterator { - b, err := val.Marshal() +func mockIter(rowID RowID, val proto.Message) Iterator { + b, err := proto.Marshal(val) if err != nil { panic(err) } @@ -351,7 +353,7 @@ func mockIter(rowID RowID, val codec.ProtoMarshaler) Iterator { } func noopIter() Iterator { - return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) { + return IteratorFunc(func(dest proto.Message) (RowID, error) { return nil, nil }) } diff --git a/x/group/internal/orm/primary_key.go b/x/group/internal/orm/primary_key.go index 5b3f257bb1ff..324b7f61b550 100644 --- a/x/group/internal/orm/primary_key.go +++ b/x/group/internal/orm/primary_key.go @@ -1,6 +1,8 @@ package orm import ( + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -40,7 +42,7 @@ type PrimaryKeyed interface { // IMPORTANT: []byte parts are encoded with a single byte length prefix, // so cannot be longer than 255 bytes. PrimaryKeyFields() []interface{} - codec.ProtoMarshaler + proto.Message } // PrimaryKey returns the immutable and serialized primary key of this object. @@ -111,7 +113,7 @@ func (a PrimaryKeyTable) Contains(store sdk.KVStore, obj PrimaryKeyed) bool { // GetOne loads the object persisted for the given primary Key into the dest parameter. // If none exists `ErrNotFound` is returned instead. Parameters must not be nil. -func (a PrimaryKeyTable) GetOne(store sdk.KVStore, primKey RowID, dest codec.ProtoMarshaler) error { +func (a PrimaryKeyTable) GetOne(store sdk.KVStore, primKey RowID, dest proto.Message) error { return a.table.GetOne(store, primKey, dest) } diff --git a/x/group/internal/orm/table.go b/x/group/internal/orm/table.go index d505927e85bb..4209cfb134f0 100644 --- a/x/group/internal/orm/table.go +++ b/x/group/internal/orm/table.go @@ -4,6 +4,8 @@ import ( "bytes" "reflect" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/store/types" @@ -36,7 +38,7 @@ type table struct { } // newTable creates a new table -func newTable(prefix [2]byte, model codec.ProtoMarshaler, cdc codec.Codec) (*table, error) { +func newTable(prefix [2]byte, model proto.Message, cdc codec.Codec) (*table, error) { if model == nil { return nil, errors.ErrORMInvalidArgument.Wrap("Model must not be nil") } @@ -71,7 +73,7 @@ func (a *table) AddAfterDeleteInterceptor(interceptor AfterDeleteInterceptor) { // // Create iterates through the registered callbacks that may add secondary index // keys. -func (a table) Create(store sdk.KVStore, rowID RowID, obj codec.ProtoMarshaler) error { +func (a table) Create(store sdk.KVStore, rowID RowID, obj proto.Message) error { if a.Has(store, rowID) { return errors.ErrORMUniqueConstraint } @@ -85,7 +87,7 @@ func (a table) Create(store sdk.KVStore, rowID RowID, obj codec.ProtoMarshaler) // nil. // // Update triggers all "after set" hooks that may add or remove secondary index keys. -func (a table) Update(store sdk.KVStore, rowID RowID, newValue codec.ProtoMarshaler) error { +func (a table) Update(store sdk.KVStore, rowID RowID, newValue proto.Message) error { if !a.Has(store, rowID) { return sdkerrors.ErrNotFound } @@ -98,7 +100,7 @@ func (a table) Update(store sdk.KVStore, rowID RowID, newValue codec.ProtoMarsha // // Set iterates through the registered callbacks that may add secondary index // keys. -func (a table) Set(store sdk.KVStore, rowID RowID, newValue codec.ProtoMarshaler) error { +func (a table) Set(store sdk.KVStore, rowID RowID, newValue proto.Message) error { if len(rowID) == 0 { return errors.ErrORMEmptyKey } @@ -111,9 +113,9 @@ func (a table) Set(store sdk.KVStore, rowID RowID, newValue codec.ProtoMarshaler pStore := prefix.NewStore(store, a.prefix[:]) - var oldValue codec.ProtoMarshaler + var oldValue proto.Message if a.Has(store, rowID) { - oldValue = reflect.New(a.model).Interface().(codec.ProtoMarshaler) + oldValue = reflect.New(a.model).Interface().(proto.Message) a.GetOne(store, rowID, oldValue) } @@ -131,7 +133,7 @@ func (a table) Set(store sdk.KVStore, rowID RowID, newValue codec.ProtoMarshaler return nil } -func assertValid(obj codec.ProtoMarshaler) error { +func assertValid(obj proto.Message) error { if v, ok := obj.(Validateable); ok { if err := v.ValidateBasic(); err != nil { return err @@ -149,7 +151,7 @@ func assertValid(obj codec.ProtoMarshaler) error { func (a table) Delete(store sdk.KVStore, rowID RowID) error { pStore := prefix.NewStore(store, a.prefix[:]) - oldValue := reflect.New(a.model).Interface().(codec.ProtoMarshaler) + oldValue := reflect.New(a.model).Interface().(proto.Message) if err := a.GetOne(store, rowID, oldValue); err != nil { return sdkerrors.Wrap(err, "load old value") } @@ -176,7 +178,7 @@ func (a table) Has(store sdk.KVStore, key RowID) bool { // GetOne load the object persisted for the given RowID into the dest parameter. // If none exists or `rowID==nil` then `sdkerrors.ErrNotFound` is returned instead. // Parameters must not be nil - we don't allow creation of values with empty keys. -func (a table) GetOne(store sdk.KVStore, rowID RowID, dest codec.ProtoMarshaler) error { +func (a table) GetOne(store sdk.KVStore, rowID RowID, dest proto.Message) error { if len(rowID) == 0 { return sdkerrors.ErrNotFound } @@ -298,7 +300,7 @@ type typeSafeIterator struct { it types.Iterator } -func (i typeSafeIterator) LoadNext(dest codec.ProtoMarshaler) (RowID, error) { +func (i typeSafeIterator) LoadNext(dest proto.Message) (RowID, error) { if !i.it.Valid() { return nil, errors.ErrORMIteratorDone } diff --git a/x/group/internal/orm/table_test.go b/x/group/internal/orm/table_test.go index 164fecda3648..633c4b1618be 100644 --- a/x/group/internal/orm/table_test.go +++ b/x/group/internal/orm/table_test.go @@ -4,14 +4,16 @@ import ( "fmt" "testing" + "github.com/cosmos/gogoproto/proto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/group/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestNewTable(t *testing.T) { @@ -20,7 +22,7 @@ func TestNewTable(t *testing.T) { testCases := []struct { name string - model codec.ProtoMarshaler + model proto.Message expectErr bool expectedErr string }{ @@ -54,7 +56,7 @@ func TestNewTable(t *testing.T) { func TestCreate(t *testing.T) { specs := map[string]struct { rowID RowID - src codec.ProtoMarshaler + src proto.Message expErr *sdkerrors.Error }{ "empty rowID": { @@ -122,7 +124,7 @@ func TestCreate(t *testing.T) { func TestUpdate(t *testing.T) { specs := map[string]struct { - src codec.ProtoMarshaler + src proto.Message expErr *sdkerrors.Error }{ "happy path": { diff --git a/x/group/internal/orm/types.go b/x/group/internal/orm/types.go index a98bcdee64ab..ffc43bf97816 100644 --- a/x/group/internal/orm/types.go +++ b/x/group/internal/orm/types.go @@ -7,6 +7,8 @@ import ( "io" "reflect" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -79,7 +81,7 @@ type Iterator interface { // LoadNext loads the next value in the sequence into the pointer passed as dest and returns the key. If there // are no more items the ErrORMIteratorDone error is returned // The key is the rowID. - LoadNext(dest codec.ProtoMarshaler) (RowID, error) + LoadNext(dest proto.Message) (RowID, error) // Close releases the iterator and should be called at the end of iteration io.Closer } @@ -93,18 +95,18 @@ type Indexable interface { } // AfterSetInterceptor defines a callback function to be called on Create + Update. -type AfterSetInterceptor func(store sdk.KVStore, rowID RowID, newValue, oldValue codec.ProtoMarshaler) error +type AfterSetInterceptor func(store sdk.KVStore, rowID RowID, newValue, oldValue proto.Message) error // AfterDeleteInterceptor defines a callback function to be called on Delete operations. -type AfterDeleteInterceptor func(store sdk.KVStore, rowID RowID, value codec.ProtoMarshaler) error +type AfterDeleteInterceptor func(store sdk.KVStore, rowID RowID, value proto.Message) error // RowGetter loads a persistent object by row ID into the destination object. The dest parameter must therefore be a pointer. // Any implementation must return `sdkerrors.ErrNotFound` when no object for the rowID exists -type RowGetter func(store sdk.KVStore, rowID RowID, dest codec.ProtoMarshaler) error +type RowGetter func(store sdk.KVStore, rowID RowID, dest proto.Message) error // NewTypeSafeRowGetter returns a `RowGetter` with type check on the dest parameter. func NewTypeSafeRowGetter(prefixKey [2]byte, model reflect.Type, cdc codec.Codec) RowGetter { - return func(store sdk.KVStore, rowID RowID, dest codec.ProtoMarshaler) error { + return func(store sdk.KVStore, rowID RowID, dest proto.Message) error { if len(rowID) == 0 { return sdkerrors.Wrap(errors.ErrORMEmptyKey, "key must not be nil") } @@ -122,7 +124,7 @@ func NewTypeSafeRowGetter(prefixKey [2]byte, model reflect.Type, cdc codec.Codec } } -func assertCorrectType(model reflect.Type, obj codec.ProtoMarshaler) error { +func assertCorrectType(model reflect.Type, obj proto.Message) error { tp := reflect.TypeOf(obj) if tp.Kind() != reflect.Ptr { return sdkerrors.Wrap(sdkerrors.ErrInvalidType, "model destination must be a pointer") diff --git a/x/group/proposal_test.go b/x/group/proposal_test.go index 8e741908db70..9162a70815eb 100644 --- a/x/group/proposal_test.go +++ b/x/group/proposal_test.go @@ -31,12 +31,11 @@ func TestGogoUnmarshalProposal(t *testing.T) { var p group.Proposal err = cdc.Unmarshal(p1Bz, &p) require.NoError(t, err) - err = cdc.Unmarshal(p2Bz, &p) + + var i group.Proposal + err = cdc.Unmarshal(p2Bz, &i) require.NoError(t, err) - // One would expect that unmarshalling into the same `&p` reference would - // clear the previous `p` value. But it seems that (at least for array - // fields), the values are not replaced, but concatenated, which - // is not an intuitive behavior. - require.Len(t, p.Proposers, 2) + require.Len(t, p.Proposers, 1) + require.Len(t, i.Proposers, 1) } diff --git a/x/group/types.go b/x/group/types.go index 49798968af46..af3c93cd3807 100644 --- a/x/group/types.go +++ b/x/group/types.go @@ -4,7 +4,8 @@ import ( "fmt" "time" - "github.com/cosmos/cosmos-sdk/codec" + proto "github.com/cosmos/gogoproto/proto" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -26,7 +27,7 @@ type DecisionPolicyResult struct { // DecisionPolicy is the persistent set of rules to determine the result of election on a proposal. type DecisionPolicy interface { - codec.ProtoMarshaler + proto.Message // GetVotingPeriod returns the duration after proposal submission where // votes are accepted.