feat(x/tx): add custom type encoder (#19786)
This commit is contained in:
@@ -31,6 +31,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Features
|
||||
|
||||
* [#19786](https://github.com/cosmos/cosmos-sdk/pull/19786) Add bytes as string option to encoder.
|
||||
|
||||
### Improvements
|
||||
|
||||
* [#19845](https://github.com/cosmos/cosmos-sdk/pull/19845) Use hybrid resolver instead of only protov2 registry
|
||||
|
||||
@@ -81,6 +81,22 @@ func nullSliceAsEmptyEncoder(enc *Encoder, v protoreflect.Value, w io.Writer) er
|
||||
}
|
||||
}
|
||||
|
||||
// cosmosBytesAsString replicates the behavior at:
|
||||
// https://github.com/CosmWasm/wasmd/blob/08567ff20e372e4f4204a91ca64a371538742bed/x/wasm/types/tx.go#L20-L22
|
||||
func cosmosBytesAsString(_ *Encoder, v protoreflect.Value, w io.Writer) error {
|
||||
switch bz := v.Interface().(type) {
|
||||
case []byte:
|
||||
blob, err := json.RawMessage(bz).MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(blob)
|
||||
return err
|
||||
default:
|
||||
return fmt.Errorf("unsupported type %T", bz)
|
||||
}
|
||||
}
|
||||
|
||||
// keyFieldEncoder replicates the behavior at described at:
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/b49f948b36bc991db5be431607b475633aed697e/proto/cosmos/crypto/secp256k1/keys.proto#L16
|
||||
// The message is treated if it were bytes directly without the key field specified.
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package aminojson
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestCosmosBytesAsString(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
value protoreflect.Value
|
||||
wantErr bool
|
||||
wantOutput string
|
||||
}{
|
||||
"valid bytes - json": {
|
||||
value: protoreflect.ValueOfBytes([]byte(`{"test":"value"}`)),
|
||||
wantErr: false,
|
||||
wantOutput: `{"test":"value"}`,
|
||||
},
|
||||
"valid bytes - string": {
|
||||
value: protoreflect.ValueOfBytes([]byte(`foo`)),
|
||||
wantErr: false,
|
||||
wantOutput: `foo`,
|
||||
},
|
||||
"unsupported type - bool": {
|
||||
value: protoreflect.ValueOfBool(true),
|
||||
wantErr: true,
|
||||
},
|
||||
"unsupported type - int64": {
|
||||
value: protoreflect.ValueOfInt64(1),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
err := cosmosBytesAsString(nil, tc.value, &buf)
|
||||
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.wantOutput, buf.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,8 @@ func NewEncoder(options EncoderOptions) Encoder {
|
||||
"threshold_string": thresholdStringEncoder,
|
||||
},
|
||||
aminoFieldEncoders: map[string]FieldEncoder{
|
||||
"legacy_coins": nullSliceAsEmptyEncoder,
|
||||
"legacy_coins": nullSliceAsEmptyEncoder,
|
||||
"bytes_as_string": cosmosBytesAsString,
|
||||
},
|
||||
protoTypeEncoders: map[string]MessageEncoder{
|
||||
"google.protobuf.Timestamp": marshalTimestamp,
|
||||
|
||||
Reference in New Issue
Block a user