cosmology-tech / telescope

A TypeScript Transpiler for Cosmos Protobufs ⚛️
https://cosmology.zone/products/telescope
Apache License 2.0
146 stars 43 forks source link

Interface decoders break Amino messages with nested Any protobufs #508

Closed NoahSaso closed 11 months ago

NoahSaso commented 1 year ago

Right now, the only way to utilize interface decoders is the global options.interfaces.enabled flag. When this is used, decoding a protobuf recursively decodes all nested Any interfaces inside. This is great UX for viewing the raw data of a message, but breaks Amino signing. Here's why...

This is how Amino signing works right now: image

The toAmino function uses its nested types' _ToAmino interface encoding functions when interfaces are enabled. The _ToAmino function uses toAmino(decode(nestedAny.value)) on the nested type to get the correct Amino data for it in a switch block. The decode function then uses _InterfaceDecoders when Anys with interfaces exist.

This path shows that encoding to Amino leads to decoding nested Any types. When interfaces are disabled, Any interfaces are decoded with Any.decode, which is the correct type that is expected by the chain. When interfaces are enabled, the default behavior becomes decoding with the nested type's decoding function.

I think the default behavior should always be to not use the interface, so that messages are decoded into the format expected by the chain. Then there can be an additional flag on the decode and toAmino functions called useInterfaces, which defaults to false, and setting it to true can then recursively decode Anys with interfaces. The key is that this flag is passed from toAmino through the _ToAmino interface encoder to both the toAmino and decode functions of nested types so that any recursive decode functions can decide to simply use Any.decode instead of one the _InterfaceDecoder functions.

Simply disabling the interface feature globally is insufficient because there are different times we want to richly decode a protobuf and other times we want to encode protobufs for Amino signing.

Zetazzz commented 1 year ago

Hi, I've figured out a good way of handling implements_interface, this can let people better use interface.enable: https://www.loom.com/share/33256b4ea33147cc9794e282a2902a52

A POC of handling implements_interface: https://github.com/cosmology-tech/telescope/tree/impl-interfaces/__fixtures__/misc/output-impl-interfaces

Even though toAmino is not included in the sample code, but I guess the idea would be alike. I'll be working on this, hopefully it can be done soon.

NoahSaso commented 1 year ago

Hi, I've figured out a good way of handling implements_interface, this can let people better use interface.enable: https://www.loom.com/share/33256b4ea33147cc9794e282a2902a52

A POC of handling implements_interface: https://github.com/cosmology-tech/telescope/tree/impl-interfaces/__fixtures__/misc/output-impl-interfaces

Even though toAmino is not included in the sample code, but I guess the idea would be alike. I'll be working on this, hopefully it can be done soon.

Oh cool. If another system exists to decode, then maybe I can stop using interfaces.enable entirely. For now, I submitted a PR that should satisfy my immediate needs.

Zetazzz commented 11 months ago

Hi, the PR's been merged and published: @cosmology/telescope@1.0.13