cosmos-sdk/codec/types/compat.go

212 lines
4.5 KiB
Go
Raw Normal View History

package types
import (
"fmt"
"reflect"
"runtime/debug"
"github.com/gogo/protobuf/jsonpb"
"github.com/gogo/protobuf/proto"
amino "github.com/tendermint/go-amino"
)
type anyCompat struct {
aminoBz []byte
jsonBz []byte
err error
}
var Debug = true
func anyCompatError(errType string, x interface{}) error {
if Debug {
debug.PrintStack()
}
return fmt.Errorf(
"%s marshaling error for %+v, this is likely because "+
"amino is being used directly (instead of codec.LegacyAmino which is preferred) "+
"or UnpackInterfacesMessage is not defined for some type which contains "+
"a protobuf Any either directly or via one of its members. To see a "+
"stacktrace of where the error is coming from, set the var Debug = true "+
"in codec/types/compat.go",
errType, x,
)
}
func (any Any) MarshalAmino() ([]byte, error) {
ac := any.compat
if ac == nil {
Remove bech32 PubKey support (#7477) * Move PubKey bech32 to legacy package and migrate the usage where possible * update /server * wip * move proto json encoding helper functions to internal * update internal/marshal * wip * update sections which needs legacybech32 * update validators output * fix conflicts * slashing update * add more tests and helper function for ANY JSON serialization * update slashing * Update function documentation * Rename code any-marshal helper functions * Update pubkey unpacking test * Update test comments * solve TestDecodeStore * solve legacytx issues * all code compiles * keyring tests * keyring cleanup * remove AssertMsg * fix some tests * fix add_ledger_test.go * update cli tests * debug cli test * rename clashed bech32 names * linter fixes * update tmservice tests * linter: update legacy deprecated checks * fix names * linting * legacybech32 pubkey type rename * fix staking client * fix test compilation * fix TestGetCmdQuerySigningInfo * rename NewIfcJSONAnyMarshaler * keyring: remove duplicated information from multinfo structure * todo cleanups * Update Changelog * remove some legacybech32 from tests * remove todos * remove printlnJSON from /server CLI and amino encoding * remove protocdc.MarshalJSON * client/show remove duplicated function * remove protocdc package * comment update * remove legacybech32.MustMarshalPubKey from a test * add todo * fix TestPublicKeyUnsafe test * review update * fix bech32 UnmarshalPubKey * Use codec.MarshalIfcJSON * fix linter issues * merging conflict: fix codec.Unmarshal calls * cleanups * Update CHANGELOG.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Reword changelog updates * use pubkey.String for comparison in Test_runAddCmdLedgerWithCustomCoinType * Update GetCmdQuerySigningInfo example * cli: update keys add docs * Add errors AsOf and errors.ErrIO type * restore multisigPubKeyInfo structure bring it back to multiInfo struct * Update codec/proto_codec.go Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * Update crypto/keys/ed25519/ed25519_test.go Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * Update codec/proto_codec.go Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * move pubkey any marshaling tests * Apply suggestions from code review Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * review updates * adding missing return * errors: use IsOf instead of AsOf * keyring: add a correct check for key not found in keyring.Get * add checkKeyNotFound * fix linter issues * fix: keyring key not found check * fix keyring tests * fix linting issues * cli tests * fix: 'simd keys show <key> -p' * fix: TestVerifyMultisignature * rename keyring Bech32... functions to Mk... * fix RunAddCmd * Update pubkey display * wip * add more tests * udate keyring output tests * remove todo from ledger tests * rename MkKeyOutput * Changelog update * solve liner issues * add link to github issue Co-authored-by: Aaron Craelius <aaron@regen.network> Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>
2021-03-25 07:53:22 -07:00
return nil, anyCompatError("amino binary marshal", any)
}
return ac.aminoBz, ac.err
}
func (any *Any) UnmarshalAmino(bz []byte) error {
any.compat = &anyCompat{
aminoBz: bz,
err: nil,
}
return nil
}
func (any *Any) MarshalJSON() ([]byte, error) {
ac := any.compat
if ac == nil {
return nil, anyCompatError("JSON marshal", any)
}
return ac.jsonBz, ac.err
}
func (any *Any) UnmarshalJSON(bz []byte) error {
any.compat = &anyCompat{
jsonBz: bz,
err: nil,
}
return nil
}
// AminoUnpacker is an AnyUnpacker provided for backwards compatibility with
// amino for the binary un-marshaling phase
type AminoUnpacker struct {
Cdc *amino.Codec
}
var _ AnyUnpacker = AminoUnpacker{}
func (a AminoUnpacker) UnpackAny(any *Any, iface interface{}) error {
ac := any.compat
if ac == nil {
return anyCompatError("amino binary unmarshal", reflect.TypeOf(iface))
}
err := a.Cdc.UnmarshalBinaryBare(ac.aminoBz, iface)
if err != nil {
return err
}
val := reflect.ValueOf(iface).Elem().Interface()
err = UnpackInterfaces(val, a)
if err != nil {
return err
}
if m, ok := val.(proto.Message); ok {
if err = any.pack(m); err != nil {
return err
}
} else {
any.cachedValue = val
}
// this is necessary for tests that use reflect.DeepEqual and compare
// proto vs amino marshaled values
any.compat = nil
return nil
}
// AminoUnpacker is an AnyUnpacker provided for backwards compatibility with
// amino for the binary marshaling phase
type AminoPacker struct {
Cdc *amino.Codec
}
var _ AnyUnpacker = AminoPacker{}
func (a AminoPacker) UnpackAny(any *Any, _ interface{}) error {
err := UnpackInterfaces(any.cachedValue, a)
if err != nil {
return err
}
bz, err := a.Cdc.MarshalBinaryBare(any.cachedValue)
any.compat = &anyCompat{
aminoBz: bz,
err: err,
}
return err
}
// AminoUnpacker is an AnyUnpacker provided for backwards compatibility with
// amino for the JSON marshaling phase
type AminoJSONUnpacker struct {
Cdc *amino.Codec
}
var _ AnyUnpacker = AminoJSONUnpacker{}
func (a AminoJSONUnpacker) UnpackAny(any *Any, iface interface{}) error {
ac := any.compat
if ac == nil {
return anyCompatError("JSON unmarshal", reflect.TypeOf(iface))
}
err := a.Cdc.UnmarshalJSON(ac.jsonBz, iface)
if err != nil {
return err
}
val := reflect.ValueOf(iface).Elem().Interface()
err = UnpackInterfaces(val, a)
if err != nil {
return err
}
if m, ok := val.(proto.Message); ok {
if err = any.pack(m); err != nil {
return err
}
} else {
any.cachedValue = val
}
// this is necessary for tests that use reflect.DeepEqual and compare
// proto vs amino marshaled values
any.compat = nil
return nil
}
// AminoUnpacker is an AnyUnpacker provided for backwards compatibility with
// amino for the JSON un-marshaling phase
type AminoJSONPacker struct {
Cdc *amino.Codec
}
var _ AnyUnpacker = AminoJSONPacker{}
func (a AminoJSONPacker) UnpackAny(any *Any, _ interface{}) error {
err := UnpackInterfaces(any.cachedValue, a)
if err != nil {
return err
}
bz, err := a.Cdc.MarshalJSON(any.cachedValue)
any.compat = &anyCompat{
jsonBz: bz,
err: err,
}
return err
}
// ProtoJSONPacker is an AnyUnpacker provided for compatibility with jsonpb
type ProtoJSONPacker struct {
JSONPBMarshaler *jsonpb.Marshaler
}
var _ AnyUnpacker = ProtoJSONPacker{}
func (a ProtoJSONPacker) UnpackAny(any *Any, _ interface{}) error {
if any == nil {
return nil
}
if any.cachedValue != nil {
err := UnpackInterfaces(any.cachedValue, a)
if err != nil {
return err
}
}
bz, err := a.JSONPBMarshaler.MarshalToString(any)
any.compat = &anyCompat{
jsonBz: []byte(bz),
err: err,
}
return err
}