-
Notifications
You must be signed in to change notification settings - Fork 78
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
DRAFTING: Amino Interface Proposal for proto3 compat version 2 #302
Comments
Thanks for sharing Jae. So it seems that if you need to know the namespace at field declaration then you theoretically already know all the concrete types in that namespace. Unless I'm misunderstanding something this doesn't actually allow extension of those interfaces with different concrete types in different apps. |
If however you let apps override the concrete types for a namespace that would allow extension. Is that what you're thinking? Wasn't clear from the proposal and the registry service idea makes it sound like they're fixed... |
Hi Aaron, not sure what you mean by "overhead" but did you mean "override"? The app is allowed to fork/override any namespace/Interface (e.g. the "canonical" So not only can any app define their own Interface<>Concrete mappings (e.g. small field num --> type mapping), but they can have multiple such mappings within the same codec ( Does that make sense? |
Sorry override - autocorrect on mobile. So what you're describing sounds like how l initially understood the proposal. And what l was commenting on is that this won't solve the problem we have because the namespace is chosen at field declaration and is tightly bound to a set of concrete types. We don't actually have cases where we need the same interface in two different fields with different concrete types - which is what your proposal seems to address. Interfaces are generally used once for one thing. We have a couple of cases where we need app level overrides of the whole interface - gov.Content and sdk.Msg. It would be useful to discuss proposals addressing actual known use cases. I know you are trying to do that with PubKey, but PubKey doesn't exist in the SDK on a struct called Example. It exists on Account and StdSignature. How would you extend it from there? I see no way with this approach other than forking the SDK and changing the namespace tag on those fields. |
Proposed solution:
becomes
The first option,
option (amino.interface) = true;
serves as a hint to code generators or other client libs, that this is an interface. The second option,option (amino.version) = 1
allows clients to keep track of changes and declare compatibility information between code and data over different versions. The third option,option (amino.namespace) = "cosmos-hub/x/amino-example";
tells the code generator and the programmer that the concrete types registered under this Animal interface are for the module "cosmos-hub/x/amino-example". But I don't think we should call them modules, I think we should just call them namespaces -- not that I prefer it that way, but that I believe we must make this distinction, but that's a separate conversation, maybe.To be specific with an example, let's talk about the PubKey interface in the Cosmos SDK. Concrete types of the standard PubKey interface include PubKeyEd25519 and PubKeySecp256k1. The Cosmos hub would probably register all usages of the PubKey interface under the same namespace of "tendermint".
The intent of the version is primarily to be explicit about code compatibility, but there may be other benefits too. For example, we could create tooling that scans code and automatically figures out if maybe the version & registered concrete types are not consistent with what is registered on some registry service, thus catching bugs... in the long future maybe this becomes part of dependency management, and project Makefiles etc can help fetch updates from a blockchain repository. Notice that we could support idempotency of concrete registrations per interface/version, so that all code that needs to use a particular namespaced interface can register it upon init() of that module without fear of panics or errors.
If there is no
namespace="..."
specified for an interface, then it should do something consistent. Maybe we can say that not specifying the namespace is the same as setting it to the default namespace, the global namespace.In any case, the biggest change is that registering concrete types happens on that interface (or at least a namespaced version of it).
Rationale/benefits.
From #267 (comment):
Thank you, responding in order:
(1) (assuming you mean prefix in the general sense, and not the current amino disamb/prefix sense), I think another way to express it is, "make the field number a composite of two things; the module and the type". And this would be helpful in the sense that it would provide something similar to what the amino disamb/prefix bytes tries to provide with interfaces -- some practical conflict prevention system, such that there is no/less need to worry about local codecs, because they can all be thrown in a global per-module namespace. But I'm not sure, is there as line number in the PR that you can point me to, so I can understand more? (Should I just read the whole PR?).
(2) I do want the latest version of the schemas used by a chain to be in the state as well for some clients. Also, using the state to keep track of duplicates or conflicts (or perhaps keeping a priority ordering of concrete types) seems like a good idea.
(3) is basically what I am about to propose.
Agreed!
I like the way you put it, or described it.
I don't think our standards will be adopted, if we had to use the proto.Any spec exactly, which isn't (AFAIK) fully supported in implementations, and doesn't quite suite needs of power users. Since power users already require an optimized standard, such a standard will emerge, so if we know how to, and it isn't hard to, we should go with that.
What are valid namespaces?
I think that namespaces should be in the form of a domain+path (I think maybe a https:// or cosmos:// spec is not needed yet, and could maybe default to a blockchain in the future). Maybe "tendermint" and a few other names can be special, and not require a "dot". Maybe "cosmos", "sdk", and "tendermint" are reserved? I dunno.
Proto4?
Going with the previous example, maybe in Protobuf4, we can have:
Other
The original proposal wording is here: https://gist.github.com/jaekwon/1b9dd3b2accd4b5f49661b49536232dc but I think the wording is confusing, so I tried to expand upon it here.
The text was updated successfully, but these errors were encountered: