* Revert "Revert "Update old ref of RegisterQueryService"" This reverts commit 03e4c56de53938ccbf025a441e54b9842f7c4544. * Update intro, module-manager and messages-and-queries * Update messages-and-queries * Update handler * Update structure * Add doc related to RegisterMsgServiceDesc * Update docs/building-modules/handler.md Co-authored-by: Robert Zaremba <robert@zaremba.ch> * Update docs/building-modules/handler.md Co-authored-by: Robert Zaremba <robert@zaremba.ch> * Update docs/building-modules/handler.md Co-authored-by: Robert Zaremba <robert@zaremba.ch> * Update docs/building-modules/messages-and-queries.md * Update handler.md * Rename handler.md to msg-services.md * Update legacy msgs wording * Update messages-and-queries.md * Update docs/building-modules/msg-services.md Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> * Update docs/building-modules/intro.md Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> * Remove handler mention from intro.md * Update docs/building-modules/messages-and-queries.md Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> * Update docs/building-modules/msg-services.md Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> * Update docs/building-modules/keeper.md Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> * Update docs/building-modules/msg-services.md Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> * Address review comments * Use tag * Update docs/building-modules/intro.md Co-authored-by: Cory <cjlevinson@gmail.com> * Update docs/building-modules/intro.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/core/transactions.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Remove framework related explanation from docs * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/module-manager.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/module-manager.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/core/baseapp.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/core/baseapp.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update beginblock-endblock.md * Update docs/core/baseapp.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Update docs/core/transactions.md Co-authored-by: Aaron Craelius <aaron@regen.network> * Add deprecated notice * Update tx-lifecycle.md Co-authored-by: Robert Zaremba <robert@zaremba.ch> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: Aaron Craelius <aaron@regen.network> Co-authored-by: Cory <cjlevinson@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
5.7 KiB
Msg Services
A Msg Service processes messages. Msg Services are specific to the module in which they are defined, and only process messages defined within the said module. They are called from BaseApp during DeliverTx. {synopsis}
Pre-requisite Readings
- Module Manager {prereq}
- Messages and Queries {prereq}
Implementation of a module Msg service
All Msg processing is done by a Msg protobuf service. Each module should define a Msg service, which will be responsible for request and response serialization.
As further described in ADR 031, this approach has the advantage of clearly specifying return types and generating server and client code.
When possible, the existing module's Keeper should implement MsgServer, otherwise a msgServer struct that embeds the Keeper can be created, typically in ./keeper/msg_server.go:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/keeper/msg_server.go#L14-L16
msgServer methods can retrieve the sdk.Context from the context.Context parameter method using the sdk.UnwrapSDKContext:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/keeper/msg_server.go#L27
Msg processing usually follows these 2 steps:
- First, they perform stateful checks to make sure the
messageis valid. At this stage, themessage'sValidateBasic()method has already been called, meaning stateless checks on the message (like making sure parameters are correctly formatted) have already been performed. Checks performed in themsgServermethod can be more expensive and require access to the state. For example, amsgServermethod for atransfermessage might check that the sending account has enough funds to actually perform the transfer. To access the state, themsgServermethod needs to call thekeeper's getter functions. - Then, if the checks are successful, the
msgServermethod calls thekeeper's setter functions to actually perform the state transition.
Before returning, msgServer methods generally emit one or more events via the EventManager held in the ctx:
ctx.EventManager().EmitEvent(
sdk.NewEvent(
eventType, // e.g. sdk.EventTypeMessage for a message, types.CustomEventType for a custom event defined in the module
sdk.NewAttribute(attributeKey, attributeValue),
),
)
These events are relayed back to the underlying consensus engine and can be used by service providers to implement services around the application. Click here to learn more about events.
The invoked msgServer method returns a proto.Message response and an error. These return values are then wrapped into an *sdk.Result or an error using sdk.WrapServiceResult(ctx sdk.Context, res proto.Message, err error):
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc2/baseapp/msg_service_router.go#L104
This method takes care of marshaling the res parameter to protobuf and attaching any events on the ctx.EventManager() to the sdk.Result.
+++ d55c1a2665/proto/cosmos/base/abci/v1beta1/abci.proto (L81-L95)
Legacy Amino Msgs
handler type
The handler type defined in the Cosmos SDK will be deprecated in favor of Msg Services.
Here is the typical structure of a handler function:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc2/types/handler.go#L4
Let us break it down:
- The
Msgis the actual object being processed. - The
Contextcontains all the necessary information needed to process themsg, as well as a cache-wrapped copy of the latest state. If themsgis succesfully processed, the modified version of the temporary state contained in thectxwill be written to the main state. - The [
*Result] returned toBaseAppcontains (among other things) information on the execution of thehandlerand events.
Module handlers are typically implemented in a ./handler.go file inside the module's folder. The module manager is used to add the module's handlers to the
application's router via the Route() method. Typically,
the manager's Route() method simply constructs a Route that calls a NewHandler() method defined in handler.go.
+++ 228728cce2/x/gov/module.go (L143-L146)
Implementation
NewHandler function dispatches a Msg to appropriate handler function, usually by using a switch statement:
+++ d55c1a2665/x/bank/handler.go (L13-L29)
First, NewHandler function sets a new EventManager to the context to isolate events per msg.
Then, a simple switch calls the appropriate handler based on the Msg type.
In this regard, handlers functions need to be implemented for each module Msg. This will also involve manual handler registration of Msg types.
handlers functions should return a *Result and an error.
Telemetry
New telemetry metrics can be created from msgServer methods when handling messages.
This is an example from the x/auth/vesting module:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/auth/vesting/msg_server.go#L73-L85
Next {hide}
Learn about query services {hide}