From 8b29f3eb2d241772ef147c4bd34d8cae39680204 Mon Sep 17 00:00:00 2001 From: codchen Date: Tue, 25 Apr 2023 20:52:03 +0800 Subject: [PATCH] Use HexBytes with Marshal/UnmarshalJSON functions --- go.mod | 1 - proto/cosmwasm/wasm/v1/types.proto | 3 +- x/wasm/keeper/test_fuzz.go | 5 +- x/wasm/types/bytes.go | 77 ++++++++++++++++++++++++++++++ x/wasm/types/types.pb.go | 3 +- 5 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 x/wasm/types/bytes.go diff --git a/go.mod b/go.mod index 7a99fc1..eaf7274 100644 --- a/go.mod +++ b/go.mod @@ -132,5 +132,4 @@ replace ( // the following version across all dependencies. github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 google.golang.org/grpc => google.golang.org/grpc v1.33.2 - ) diff --git a/proto/cosmwasm/wasm/v1/types.proto b/proto/cosmwasm/wasm/v1/types.proto index 739aed2..5bbdedb 100644 --- a/proto/cosmwasm/wasm/v1/types.proto +++ b/proto/cosmwasm/wasm/v1/types.proto @@ -131,8 +131,7 @@ message AbsoluteTxPosition { // Model is a struct that holds a KV pair message Model { // hex-encode key to read it better (this is often ascii) - bytes key = 1 [ (gogoproto.casttype) = - "github.com/tendermint/tendermint/libs/bytes.HexBytes" ]; + bytes key = 1 [ (gogoproto.casttype) = "HexBytes" ]; // base64-encode raw value bytes value = 2; } diff --git a/x/wasm/keeper/test_fuzz.go b/x/wasm/keeper/test_fuzz.go index d6a2ce8..184ca51 100644 --- a/x/wasm/keeper/test_fuzz.go +++ b/x/wasm/keeper/test_fuzz.go @@ -5,7 +5,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" fuzz "github.com/google/gofuzz" - tmBytes "github.com/tendermint/tendermint/libs/bytes" "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -50,9 +49,9 @@ func FuzzContractCodeHistory(m *types.ContractCodeHistoryEntry, c fuzz.Continue) } func FuzzStateModel(m *types.Model, c fuzz.Continue) { - m.Key = tmBytes.HexBytes(c.RandString()) + m.Key = types.HexBytes(c.RandString()) if len(m.Key) == 0 { - m.Key = tmBytes.HexBytes("non empty key") + m.Key = types.HexBytes("non empty key") } c.Fuzz(&m.Value) } diff --git a/x/wasm/types/bytes.go b/x/wasm/types/bytes.go new file mode 100644 index 0000000..ada1dee --- /dev/null +++ b/x/wasm/types/bytes.go @@ -0,0 +1,77 @@ +package types + +import ( + "encoding/base64" + "encoding/hex" + "fmt" + "strings" +) + +// HexBytes is a wrapper around []byte that encodes data as hexadecimal strings +// for use in JSON. +type HexBytes []byte + +// Marshal needed for protobuf compatibility +func (bz HexBytes) Marshal() ([]byte, error) { + return bz, nil +} + +// Unmarshal needed for protobuf compatibility +func (bz *HexBytes) Unmarshal(data []byte) error { + *bz = data + return nil +} + +// MarshalText encodes a HexBytes value as hexadecimal digits. +// This method is used by json.Marshal. +func (bz HexBytes) MarshalText() ([]byte, error) { + enc := hex.EncodeToString([]byte(bz)) + return []byte(strings.ToUpper(enc)), nil +} + +// UnmarshalText handles decoding of HexBytes from JSON strings. +// This method is used by json.Unmarshal. +// It allows decoding of both hex and base64-encoded byte arrays. +func (bz *HexBytes) UnmarshalText(data []byte) error { + input := string(data) + if input == "" || input == "null" { + return nil + } + dec, err := hex.DecodeString(input) + if err != nil { + dec, err = base64.StdEncoding.DecodeString(input) + if err != nil { + return err + } + } + *bz = HexBytes(dec) + return nil +} + +// Bytes fulfills various interfaces in light-client, etc... +func (bz HexBytes) Bytes() []byte { + return bz +} +func (bz HexBytes) String() string { + return strings.ToUpper(hex.EncodeToString(bz)) +} + +// Format writes either address of 0th element in a slice in base 16 notation, +// with leading 0x (%p), or casts HexBytes to bytes and writes as hexadecimal +// string to s. +func (bz HexBytes) Format(s fmt.State, verb rune) { + switch verb { + case 'p': + s.Write([]byte(fmt.Sprintf("%p", bz))) + default: + s.Write([]byte(fmt.Sprintf("%X", []byte(bz)))) + } +} + +func (bz HexBytes) MarshalJSON() ([]byte, error) { + return bz.MarshalText() +} + +func (bz *HexBytes) UnmarshalJSON(data []byte) error { + return bz.UnmarshalText(data) +} diff --git a/x/wasm/types/types.pb.go b/x/wasm/types/types.pb.go index 05ff057..6dd14c2 100644 --- a/x/wasm/types/types.pb.go +++ b/x/wasm/types/types.pb.go @@ -14,7 +14,6 @@ import ( _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" _ "github.com/regen-network/cosmos-proto" - github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes" ) // Reference imports to suppress errors if they are not otherwise used. @@ -434,7 +433,7 @@ var xxx_messageInfo_AbsoluteTxPosition proto.InternalMessageInfo // Model is a struct that holds a KV pair type Model struct { // hex-encode key to read it better (this is often ascii) - Key github_com_tendermint_tendermint_libs_bytes.HexBytes `protobuf:"bytes,1,opt,name=key,proto3,casttype=github.com/tendermint/tendermint/libs/bytes.HexBytes" json:"key,omitempty"` + Key HexBytes `protobuf:"bytes,1,opt,name=key,proto3,casttype=HexBytes" json:"key,omitempty"` // base64-encode raw value Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` }