-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Consider protobuf service definitions for Msg's #7122
Comments
+1 This makes a lot of sense. If we can agree on replacing the concrete |
As I mentioned in #7421, I think this could play really nicely with #7093 and create a viable approach to stable v1.0 modules as well as have other benefits. I wonder if you have any thoughts on this from either the cosmjs or cosmwasm perspectives @ethanfrey ? |
I love the auto-generated I have some doubts on the client side of things:
Does If not using |
Good questions @amaurymartiny
No it wouldn't be a network request with gRPC directly. It would still go through the same broadcast And clients are of course not forced to use the generated client/server code, they can pack the
Yes, you would need to use some sort of reflection on the client interface if you're packing the I think though, if your protobuf library generates asynchronous client interfaces (protobuf.js does this, but golang doesn't), you can use the generated code with multiple messages. You would just need some sort of batch tx RPC implementation. In protobuf.js this might look like: var batchTx = newBatchTxRPCImpl()
var govClient = gov.Msg.create(batchTx)
govClient.submitProposal({...}, function(err, response) {
...
})
var fooClient = foo.Msg.create(batchTx)
fooClient.bar({...}, function(err, response) {
...
})
// broadcast both messages queued in the batch as a single tx
batchTx.broadcast(function(err, response) {
...
} In this example, because it's an async API, each msg could receive a separate callback even though they're broadcast as a single tx. |
Summary
This issue proposes a complementary or alternative way of representing
sdk.Msg
s using protobufservice
definitions. It’s just an idea, and something to think about after Stargate. We can totally throw it out if it makes no sense! But it might also provide some nice UX improvements...Context
When we initially designed protobuf support for
sdk.Msg
s it was proposed thatMsg
return types be captured with a protobuf extension field, ex:This was never adopted, however, and we currently don’t have a mechanism for specifying the return type of a
Msg
.Having a well-specified return value for
Msg
s would improve client UX. For instance, inx/gov
,MsgSubmitProposal
returns the proposal ID as a big-endianuint64
. This isn’t really documented anywhere and clients would need to know the internals of the SDK to parse that value and return it to users.Also, there may be cases where we want to use these return values programatically. For instance, #7093 proposes a method for doing inter-module Ocaps using the
Msg
router. A well-defined return type would improve the developer UX for this approach.Proposal
Protobuf
service
definitions could be used instead of concrete protobufmessage
types. This would have more or less the same over-the-wire representation but improve developer UX.Ex:
Note that overloading protobuf
service
definitions like this does not violate the intent of the protobuf spec which says:Currently, we are encoding
Msg
s asAny
inTx
s which involves packing the binary-encodedMsg
with its type URL.The type URL for
MsgSubmitProposal
is/cosmos.gov.MsgSubmitProposal
.The fully-qualified RPC name for the
SubmitProposal
RPC call above is/cosmos.gov.Msg/SubmitProposal
which is varies by a single/
character. We could also pack this type URL into anAny
with the sameMsgSubmitProposal
contents and handle it like a “packed RPC” call.With this approach, we would get an auto-generated
MsgServer
interface:This is almost like an automatically generated
Keeper
interface. It does more or less the same thing… Instead of needing to manually register handlers withhandler.go
files and manually marshal return types, theMsgServer
interface would just need to be implemented and registered and that’s it.Also,
MsgClient
interfaces would be generated so theoretically some client code could send transactions simply by callinggovClient.SubmitProposal(ctx, msg)
. Obviously a lot of transaction stuff would need to happen in the background… but it could be useful for client devs.This approach could live alongside the current concrete
Msg
type approach, or even replace it if we wanted. In the example above,MsgSubmitProposal
is used as the request type so that we can either send/cosmos.gov.MsgSubmitProposal
as a concreteMsg
or/cosmos.gov.Msg/SubmitProposal
as an RPC call… (Hope that’s not too confusing…)Consequences
Pros
Cons
Msg
type approach could be confusingservice
definitions outside the context of gRPC could be confusing (but doesn’t violate the proto3 spec)References
Any
Msg
designs: https://docs.google.com/document/d/1eEgYgvgZqLE45vETjhwIw4VOqK-5hwQtZtjVbiXnIGcThe text was updated successfully, but these errors were encountered: