-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement protoreflect based amino JSON encoder #10993
Comments
To add on to this, Tendermint Is deprecating tmjson in 0.36, we should be prepared to include this in 0.46 in this case, or copy over tmjson if needed. |
This would be a state machine breaking changes for existing messages, correct @aaronc? |
No state machine nor protocol breaking changes. We're just talking about making amino JSON work for new protobuf generated code. Same proto types, same amino JSON, different code generator. |
Ok, I see. If what you say is indeed true, then I think this is pretty high priority. We should speak about this in terms of approach and implementation details. |
We chatted about it in our last framework WG and tried to capture as many details as possible in the issue description |
In |
See cosmos/cosmos-proto#83 for some prior work that may be useful for how to structure this encoder |
I'm going for feature parity between this implementation and the current/legacy amino.MarshalJSON, however the legacy implementation can sometimes produce bytes which are invalid to google.golang.org/protobuf/encoding/protojson.Unmarshal. One such case is illustrated below. https://github.com/cosmos/cosmos-sdk/blob/e001be7f17909ce7f2c369becd4657b47c11c6f7/codec/aminojson/marshal_test.go#L45 The legacy implementation encodes this as Another example is the handling of Any types whose marshaling differs like; // aminojson
{"any":{"type_url":"type.googleapis.com/testpb.NestedMessage","value":"Cg9hbnkgdHlwZSBuZXN0ZWQQCw=="}}
// protojson
{"any":{"@type":"type.googleapis.com/testpb.NestedMessage","foo":"any type nested","bar":11}} The full test covering these cases can be seen here. Is this a problem? If not, is there another unmarshaller I should be using in test instead? |
It should definitely be incompatible with protojson.Unmarshal. It's amino json not proto json. It should be possible to unmarshal with amino unmarshaling to the existing gogo proto types |
Background
Currently amino 1) only works on golang structs and 2) doesn't work with the new pulsar protobuf generated code, only gogo because of some hacks. Amino JSON is still needed for ledger signing for the forseeable future so we need to support this.
To enable both the new protobuf generated code to work with Amino and dynamic clients such as lens which may not have generated code for all proto descriptors, we will need a dynamic Amino JSON encoder. Also proto descriptors on their own do not include amino names.
Design
This encoder should:
protoreflect.Message
and not depend on go-amino at all, just using protoreflect not go struct reflection, andcosmos.msg.legagy_amino.v1.name
) andomitempty
for fields, ex:Once this done, we may be able to get rid of the amino golang dependency. Note that adding these annotations will also help clients such as CosmJS.
Concretely, let's create a type in the
codec/amino
package:We don't need to use any of the existing
codec
registration infrastructure as all amino encoding info would be stored in the .proto files usingcosmos.msg.v1
proto options. There is no need forRegisterConcrete
,RegisterInterface
, etc. We don't need any binary encoding/decoding or JSON decoding, just JSON encoding.Tests should compare encoding of a number of different SDK messages using gogo codegen + go-amino with the same messages using pulsar + the new encoder. We can avoid manual copying in these tests by proto marshaling between gogo and pulsar. Tests should leverage rapid to generate data and must test all custom types (int, dec, timestamps) used in SDK messages.
TODO (in separate PRs)
AminoJSONEncoder
interface above (do this first!) - we probably want to leverage Rapid proto message generator #14704 for thiscosmos.msg.legacy_amino.v1
proto package (name
,omit_empty
, etc.) feat: Add proto annotations for Amino JSON #13501AminoJSONEncoder
based on https://github.com/tendermint/go-amino/blob/master/json-encode.go but without using go reflection, just protoreflect (tests for structs which don't use custom types should pass now)AminoJSONEncoder
based oncosmos_proto.scalar
(some tests will likely fail until this is done)The text was updated successfully, but these errors were encountered: