Skip to content

Implement protoreflect based amino JSON encoder #10993

Closed
@aaronc

Description

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:

  • work against any message that implements protoreflect.Message and not depend on go-amino at all, just using protoreflect not go struct reflection, and
  • use .proto file options to specify things like amino types names (ex: cosmos.msg.legagy_amino.v1.name) and omitempty for fields, ex:
message MsgSend {
  option (cosmos.msg.legacy_amino.v1.name) = "cosmos-sdk/MsgSend";
  ...

  // say we have an optional field that gets added
  string note = 4 [(cosmos.msg.legacy_amino.v1.omit_empty) = true];
}

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:

type AminoJSONEncoder interface {
  Marshal(proto.Message) ([]byte, error)
}

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 using cosmos.msg.v1 proto options. There is no need for RegisterConcrete, 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)

Metadata

Assignees

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions