forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add collections key encoders and value encoders for common type…
…s. (cosmos#14760) Co-authored-by: testinginprod <[email protected]>
- Loading branch information
1 parent
ba5e8cb
commit ed17f2d
Showing
25 changed files
with
924 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package codec | ||
|
||
import ( | ||
"cosmossdk.io/collections" | ||
"github.com/cosmos/gogoproto/proto" | ||
) | ||
|
||
type protoMessage[T any] interface { | ||
*T | ||
proto.Message | ||
} | ||
|
||
// CollValue inits a collections.ValueCodec for a generic gogo protobuf message. | ||
func CollValue[T any, PT protoMessage[T]](cdc BinaryCodec) collections.ValueCodec[T] { | ||
return &collValue[T, PT]{cdc.(Codec)} | ||
} | ||
|
||
type collValue[T any, PT protoMessage[T]] struct{ cdc Codec } | ||
|
||
func (c collValue[T, PT]) Encode(value T) ([]byte, error) { | ||
return c.cdc.Marshal(PT(&value)) | ||
} | ||
|
||
func (c collValue[T, PT]) Decode(b []byte) (value T, err error) { | ||
err = c.cdc.Unmarshal(b, PT(&value)) | ||
return value, err | ||
} | ||
|
||
func (c collValue[T, PT]) EncodeJSON(value T) ([]byte, error) { | ||
return c.cdc.MarshalJSON(PT(&value)) | ||
} | ||
|
||
func (c collValue[T, PT]) DecodeJSON(b []byte) (value T, err error) { | ||
err = c.cdc.UnmarshalJSON(b, PT(&value)) | ||
return | ||
} | ||
|
||
func (c collValue[T, PT]) Stringify(value T) string { | ||
return PT(&value).String() | ||
} | ||
|
||
func (c collValue[T, PT]) ValueType() string { | ||
return "gogoproto/" + proto.MessageName(PT(new(T))) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package codec | ||
|
||
import ( | ||
"testing" | ||
|
||
"cosmossdk.io/collections/colltest" | ||
codectypes "github.com/cosmos/cosmos-sdk/codec/types" | ||
"github.com/cosmos/gogoproto/types" | ||
) | ||
|
||
func TestCollectionsCorrectness(t *testing.T) { | ||
cdc := NewProtoCodec(codectypes.NewInterfaceRegistry()) | ||
t.Run("CollValue", func(t *testing.T) { | ||
colltest.TestValueCodec(t, CollValue[types.UInt64Value](cdc), types.UInt64Value{ | ||
Value: 500, | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package colltest | ||
|
||
import ( | ||
"cosmossdk.io/collections" | ||
"github.com/stretchr/testify/require" | ||
"testing" | ||
) | ||
|
||
// TestKeyCodec asserts the correct behaviour of a KeyCodec over the type T. | ||
func TestKeyCodec[T any](t *testing.T, keyCodec collections.KeyCodec[T], key T) { | ||
buffer := make([]byte, keyCodec.Size(key)) | ||
written, err := keyCodec.Encode(buffer, key) | ||
require.NoError(t, err) | ||
require.Equal(t, len(buffer), written) | ||
read, decodedKey, err := keyCodec.Decode(buffer) | ||
require.NoError(t, err) | ||
require.Equal(t, len(buffer), read, "encoded key and read bytes must have same size") | ||
require.Equal(t, key, decodedKey, "encoding and decoding produces different keys") | ||
// test if terminality is correctly applied | ||
pairCodec := collections.PairKeyCodec(keyCodec, collections.StringKey) | ||
pairKey := collections.Join(key, "TEST") | ||
buffer = make([]byte, pairCodec.Size(pairKey)) | ||
written, err = pairCodec.Encode(buffer, pairKey) | ||
require.NoError(t, err) | ||
read, decodedPairKey, err := pairCodec.Decode(buffer) | ||
require.NoError(t, err) | ||
require.Equal(t, len(buffer), read, "encoded non terminal key and pair key read bytes must have same size") | ||
require.Equal(t, pairKey, decodedPairKey, "encoding and decoding produces different keys with non terminal encoding") | ||
|
||
// check JSON | ||
keyJSON, err := keyCodec.EncodeJSON(key) | ||
require.NoError(t, err) | ||
decoded, err := keyCodec.DecodeJSON(keyJSON) | ||
require.NoError(t, err) | ||
require.Equal(t, key, decoded, "json encoding and decoding did not produce the same results") | ||
} | ||
|
||
// TestValueCodec asserts the correct behaviour of a ValueCodec over the type T. | ||
func TestValueCodec[T any](t *testing.T, encoder collections.ValueCodec[T], value T) { | ||
encodedValue, err := encoder.Encode(value) | ||
require.NoError(t, err) | ||
decodedValue, err := encoder.Decode(encodedValue) | ||
require.NoError(t, err) | ||
require.Equal(t, value, decodedValue, "encoding and decoding produces different values") | ||
|
||
encodedJSONValue, err := encoder.EncodeJSON(value) | ||
require.NoError(t, err) | ||
decodedJSONValue, err := encoder.DecodeJSON(encodedJSONValue) | ||
require.NoError(t, err) | ||
require.Equal(t, value, decodedJSONValue, "encoding and decoding in json format produces different values") | ||
|
||
require.NotEmpty(t, encoder.ValueType()) | ||
|
||
_ = encoder.Stringify(value) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package collections_test | ||
|
||
import ( | ||
"cosmossdk.io/collections" | ||
"cosmossdk.io/collections/colltest" | ||
"testing" | ||
) | ||
|
||
func TestKeyCorrectness(t *testing.T) { | ||
t.Run("bytes", func(t *testing.T) { | ||
colltest.TestKeyCodec(t, collections.BytesKey, []byte("some_cool_bytes")) | ||
}) | ||
|
||
t.Run("string", func(t *testing.T) { | ||
colltest.TestKeyCodec(t, collections.StringKey, "some string") | ||
}) | ||
|
||
t.Run("uint64", func(t *testing.T) { | ||
colltest.TestKeyCodec(t, collections.Uint64Key, 5949485) | ||
}) | ||
|
||
t.Run("Pair", func(t *testing.T) { | ||
colltest.TestKeyCodec( | ||
t, | ||
collections.PairKeyCodec(collections.StringKey, collections.StringKey), | ||
collections.Join("hello", "testing"), | ||
) | ||
}) | ||
} | ||
|
||
func TestValueCorrectness(t *testing.T) { | ||
t.Run("string", func(t *testing.T) { | ||
colltest.TestValueCodec(t, collections.StringValue, "i am a string") | ||
}) | ||
t.Run("uint64", func(t *testing.T) { | ||
colltest.TestValueCodec(t, collections.Uint64Value, 5948459845) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.