[docs]: update building modules section to reflect ADR31 (#7702)

* 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>
This commit is contained in:
Marie Gauthier 2020-11-17 21:41:43 +01:00 committed by GitHub
parent b90bacb775
commit 1cc8af8d9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 178 additions and 156 deletions

View File

@ -158,7 +158,7 @@ Each module should also implement the `RegisterServices` method as part of the [
#### Handlers
The [handler](../building-modules/handler.md) refers to the part of the module responsible for processing the `Msg` after it is routed by `baseapp`. Handler functions of modules are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md).
The [handler](../building-modules/msg-services.md#handler-type) refers to the part of the module responsible for processing the `Msg` after it is routed by `baseapp`. Handler functions of modules are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md).
The `handler` of a module is generally defined in a file called `handler.go` and consists of:

View File

@ -44,7 +44,7 @@ By default, the Cosmos SDK makes use of two different gas meters, the [main gas
`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas consumption per-transaction.
Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`handler`](../building-modules/handler.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store).
Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`Msg` service](../building-modules/msg-services.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store).
### Block Gas Meter

View File

@ -179,7 +179,7 @@ explicitly ordered in the block proposal.
### DeliverTx
The `DeliverTx` ABCI function defined in [`baseapp`](../core/baseapp.md) does the bulk of the
The `DeliverTx` ABCI function defined in [`BaseApp`](../core/baseapp.md) does the bulk of the
state transitions: it is run for each transaction in the block in sequential order as committed
to during consensus. Under the hood, `DeliverTx` is almost identical to `CheckTx` but calls the
[`runTx`](../core/baseapp.md#runtx) function in deliver mode instead of check mode.
@ -194,15 +194,15 @@ Instead of using their `checkState`, full-nodes use `deliverState`:
`AnteHandler` will not compare `gas-prices` to the node's `min-gas-prices` since that value is local
to each node - differing values across nodes would yield nondeterministic results.
- **Route and Handler:** While `CheckTx` would have exited, `DeliverTx` continues to run
- **`MsgServiceRouter`:** While `CheckTx` would have exited, `DeliverTx` continues to run
[`runMsgs`](../core/baseapp.md#runtx-and-runmsgs) to fully execute each `Msg` within the transaction.
Since the transaction may have messages from different modules, `baseapp` needs to know which module
to find the appropriate Handler. Thus, the `route` function is called via the [module manager](../building-modules/module-manager.md) to
retrieve the route name and find the [`Handler`](../building-modules/handler.md) within the module.
Since the transaction may have messages from different modules, `BaseApp` needs to know which module
to find the appropriate handler. This is achieved using `BaseApp`'s `MsgServiceRouter` so that it can be processed by the module's [`Msg` service](../building-modules/msg-services.md).
For legacy `Msg` routing, the `Route` function is called via the [module manager](../building-modules/module-manager.md) to retrieve the route name and find the legacy [`Handler`](../building-modules/msg-services.md#handler-type) within the module.
- **Handler:** The `handler`, a step up from `AnteHandler`, is responsible for executing each
- **`Msg` service:** The `Msg` service, a step up from `AnteHandler`, is responsible for executing each
message in the `Tx` and causes state transitions to persist in `deliverTxState`. It is defined
within a `Msg`'s module and writes to the appropriate stores within the module.
within a module `Msg` protobuf service and writes to the appropriate stores within the module.
- **Gas:** While a `Tx` is being delivered, a `GasMeter` is used to keep track of how much
gas is being used; if execution completes, `GasUsed` is set and returned in the

View File

@ -11,7 +11,7 @@ This repository contains documentation on concepts developers need to know in or
1. [Introduction to Cosmos SDK Modules](./intro.md)
2. [`AppModule` Interface and Module Manager](./module-manager.md)
3. [Messages and Queries](./messages-and-queries.md)
4. [`Handler`s - Processing Messages](./handler.md)
4. [`Msg` services - Processing Messages](./msg-services.md)
5. [Query Services - Processing Queries](./query-services.md)
6. [BeginBlocker and EndBlocker](./beginblock-endblock.md)
7. [`Keeper`s](./keeper.md)

View File

@ -16,7 +16,7 @@ order: 6
When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`AppModule` interface](./module-manager.md#appmodule). The `BeginBlock` and `EndBlock` methods of the interface implemented in `module.go` generally defer to `BeginBlocker` and `EndBlocker` methods respectively, which are usually implemented in a **`abci.go`** file.
The actual implementation of `BeginBlocker` and `EndBlocker` in `./abci.go` are very similar to that of a [`handler`](./handler.md):
The actual implementation of `BeginBlocker` and `EndBlocker` in `./abci.go` are very similar to that of a [`Msg` service](./msg-services.md):
- They generally use the [`keeper`](./keeper.md) and [`ctx`](../core/context.md) to retrieve information about the latest state.
- If needed, they use the `keeper` and `ctx` to trigger state-transitions.

View File

@ -1,96 +0,0 @@
<!--
order: 4
-->
# Handlers
A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). {synopsis}
## Pre-requisite Readings
- [Module Manager](./module-manager.md) {prereq}
- [Messages and Queries](./messages-and-queries.md) {prereq}
## `handler` type
The `handler` type defined in the Cosmos SDK specifies the typical structure of a `handler` function.
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/handler.go#L4
Let us break it down:
- The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed.
- The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state.
- The [`*Result`] returned to `baseapp`, which contains (among other things) information on the execution of the `handler` and [`events`](../core/events.md).
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95
## Implementation of a module `handler`s
Module `handler`s are typically implemented in a `./handler.go` file inside the module's folder. The
[module manager](./module-manager.md) is used to add the module's `handler`s to the
[application's `router`](../core/baseapp.md#message-routing) via the `Route()` method. Typically,
the manager's `Route()` method simply constructs a Route that calls a `NewHandler()` method defined in `handler.go`,
which looks like the following:
```go
func NewHandler(keeper Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case *MsgType1:
return handleMsgType1(ctx, keeper, msg)
case *MsgType2:
return handleMsgType2(ctx, keeper, msg)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
}
}
}
```
First, the `handler` function sets a new `EventManager` to the context to isolate events per `msg`.
Then, this simple switch returns a `handler` function specific to the type of the received `message`. These `handler` functions are the ones that actually process `message`s, and usually follow the following 2 steps:
- First, they perform *stateful* checks to make sure the `message` is valid. At this stage, the `message`'s `ValidateBasic()` 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 the `handler` can be more expensive and require access to the state. For example, a `handler` for a `transfer` message might check that the sending account has enough funds to actually perform the transfer. To access the state, the `handler` needs to call the [`keeper`'s](./keeper.md) getter functions.
- Then, if the checks are successfull, the `handler` calls the [`keeper`'s](./keeper.md) setter functions to actually perform the state transition.
Before returning, `handler` functions generally emit one or multiple [`events`](../core/events.md) via the `EventManager` held in the `ctx`:
```go
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](../core/events.md) to learn more about `events`.
Finally, the `handler` function returns a `*sdk.Result` which contains the aforementioned `events` and an optional `Data` field.
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95
Next is an example of how to return a `*Result` from the `gov` module:
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/gov/handler.go#L67-L70
For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/gov/handler.go) from the `gov` module.
The `handler` can then be registered from [`AppModule.Route()`](./module-manager.md#appmodule) as shown in the example below:
+++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/x/gov/module.go#L143-L146
## Telemetry
New [telemetry metrics](../core/telemetry.md) can be created from the `handler` when handling messages for instance.
This is an example from the `auth` module:
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/auth/vesting/handler.go#L68-L80
## Next {hide}
Learn about [query services](./query-services.md) {hide}

View File

@ -17,7 +17,7 @@ The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It
On top of this core, the Cosmos SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications.
SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./messages-and-queries.md#messages). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them.
SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one or more `KVStore`s in the [main multistore](../core/store.md), as well as a subset of [message types](./messages-and-queries.md#messages). These messages are routed by one of the main component of SDK core, [`BaseApp`](../core/baseapp.md), to the [`Msg` service](./msg-services.md) of the module that define them.
```
+
@ -76,12 +76,11 @@ While there is no definitive guidelines for writing modules, here are some impor
## Main Components of SDK Modules
Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components:
Modules are by convention defined in the `./x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components:
- Custom [`message` types](./messages-and-queries.md#messages) to trigger state-transitions.
- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing).
- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state.
- A [query service](./query-services.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing).
- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state.
- A [`Msg` service](./messages-and-queries.md#messages) used to process messages when they are routed to the module by [`BaseApp`](../core/baseapp.md#message-routing) and trigger state-transitions.
- A [query service](./query-services.md), used to process user queries when they are routed to the module by [`BaseApp`](../core/baseapp.md#query-routing).
- Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module.
In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md).

View File

@ -46,7 +46,7 @@ Of course, it is possible to define different types of internal `keeper`s for th
## Implementing Methods
`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`handler`](./handler.md) when `keeper`s' methods are called.
`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`Msg` server](./msg-services.md) when `keeper`s' methods are called.
Typically, a *getter* method will present with the following signature

View File

@ -4,7 +4,7 @@ order: 3
# Messages and Queries
`Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`. {synopsis}
`Msg`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `Msg` services, `keeper`s and `Query` services, exist to process `message`s and `queries`. {synopsis}
## Pre-requisite Readings
@ -12,15 +12,36 @@ order: 3
## Messages
`Message`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions](../core/transactions.md), which may contain one or multiple of them.
`Msg`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions](../core/transactions.md), which may contain one or more of them.
When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../core/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module via `baseapp`'s `router` so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md).
When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`BaseApp`](../core/baseapp.md). Then, each message contained in the transaction is extracted and routed to the appropriate module via `BaseApp`'s `MsgServiceRouter` so that it can be processed by the module's [`Msg` service](./msg-services.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md).
Defining `message`s is the responsibility of module developers. Typically, they are defined as protobuf messages in a `proto/` directory (see more info about [conventions and naming](../core/encoding.md#faq)). The `message`'s definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`.
### `Msg` Services
Here's an example of a protobuf message definition:
Starting from v0.40, defining Protobuf `Msg` services is the recommended way to handle messages. A `Msg` protobuf service should be created per module, typically in `tx.proto` (see more info about [conventions and naming](../core/encoding.md#faq)). It must have an RPC service method defined for each message in the module.
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/gov/v1beta1/tx.proto#L15-L27
See an example of a `Msg` service definition from `x/bank` module:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L10-L17
For backwards compatibility with [legacy Amino `Msg`s](#legacy-amino-msgs), existing `Msg` types should be used as the request parameter for `service` definitions. Newer `Msg` types which only support `service` definitions should use the more canonical `Msg...Request` names.
`Msg` request types need to implement the `MsgRequest` interface which is a simplified version of the `Msg` interface described [below](#legacy-amino-msgs) with only `ValidateBasic()` and `GetSigners()` methods.
Defining such `Msg` services allow to specify return types as part of `Msg` response using the canonical `Msg...Response` names.
In addition, this generates client and server code.
The generated `MsgServer` interface defines the server API for the `Msg` service and its implementation is described as part of the [`Msg` services](./msg-services.md) documentation.
A `RegisterMsgServer` method is also generated and should be used to register the module's `MsgServer` implementation in `RegisterServices` method from the [`AppModule` interface](./module-manager.md#appmodule).
In order for clients (CLI and grpc-gateway) to have these URLs registered, the SDK provides the function `RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.ServiceDesc)` that should be called inside module's [`RegisterInterfaces`](module-manager.md#appmodulebasic) method, using the proto-generated `&_Msg_serviceDesc` as `*grpc.ServiceDesc` argument.
### Legacy Amino `Msg`s
This way of defining messages is deprecated and using [`Msg` services](#msg-services) is preferred.
Legacy `Msg`s can be defined as protobuf messages. The messages definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said message.
The `Msg` is typically accompanied by a standard constructor function, that is called from one of the [module's interface](./module-interfaces.md). `message`s also need to implement the [`Msg`] interface:
@ -30,17 +51,17 @@ It extends `proto.Message` and contains the following methods:
- `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name.
- `Type() string`: Type of the message, used primarly in [events](../core/events.md). This should return a message-specific `string`, typically the denomination of the message itself.
- `ValidateBasic() error`: This method is called by `baseapp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer).
- `ValidateBasic() error`: This method is called by `BaseApp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer).
- `GetSignBytes() []byte`: Return the canonical byte representation of the message. Used to generate a signature.
- `GetSigners() []AccAddress`: Return the list of signers. The SDK will make sure that each `message` contained in a transaction is signed by all the signers listed in the list returned by this method.
See an example implementation of a `message` from the `gov` module:
+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/gov/types/msgs.go#L94-L136
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/gov/types/msgs.go#L77-L125
## Queries
A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `baseapp`'s `queryrouter` so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md).
A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `BaseApp`'s `queryrouter` so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md).
### gRPC Queries
@ -52,7 +73,7 @@ Here's an example of such a `Query` service definition:
As `proto.Message`s, generated `Response` types implement by default `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer).
A `RegisterQueryServer` method is also generated and should be used to register the module's query server in `RegisterQueryService` method from the [`AppModule` interface](./module-manager.md#appmodule).
A `RegisterQueryServer` method is also generated and should be used to register the module's query server in the `RegisterServices` method from the [`AppModule` interface](./module-manager.md#appmodule).
### Legacy Queries
@ -64,8 +85,8 @@ queryCategory/queryRoute/queryType/arg1/arg2/...
where:
- `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `baseapp`'s [`Query` method](../core/baseapp.md#query).
- `queryRoute` is used by `baseapp`'s [`queryRouter`](../core/baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module.
- `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `BaseApp`'s [`Query` method](../core/baseapp.md#query).
- `queryRoute` is used by `BaseApp`'s [`queryRouter`](../core/baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module.
- `queryType` is used by the module's [`querier`](./query-services.md#legacy-queriers) to map the `query` to the appropriate `querier function` within the module.
- `args` are the actual arguments needed to process the `query`. They are filled out by the end-user. Note that for bigger queries, you might prefer passing arguments in the `Data` field of the request `req` instead of the `path`.
@ -87,4 +108,4 @@ See following examples:
## Next {hide}
Learn about [`handler`s](./handler.md) {hide}
Learn about [`Msg` services](./msg-services.md) {hide}

View File

@ -62,17 +62,17 @@ It does not have its own manager, and exists separately from [`AppModule`](#appm
The `AppModule` interface defines the inter-dependent methods modules need to implement.
+++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/types/module/module.go#L160-L182
+++ https://github.com/cosmos/cosmos-sdk/blob/b4cce159bcc6a32ac78245c6866dd87c73f3720d/types/module/module.go#L160-L182
`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter.
Let us go through the methods of `AppModule`:
- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted).
- `Route()`: Returns the route for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing).
- `QuerierRoute()` (deprecated): Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing).
- `Route()`: Returns the route for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`BaseApp`](../core/baseapp.md#message-routing).
- `QuerierRoute()` (deprecated): Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`BaseApp`](../core/baseapp.md#query-routing).
- `LegacyQuerierHandler(*codec.LegacyAmino)` (deprecated): Returns a [`querier`](./query-services.md#legacy-queriers) given the query `path`, in order to process the `query`.
- `RegisterQueryService(grpc.Server)`: Allows a module to register a gRPC query service.
- `RegisterServices(Configurator)`: Allows a module to register services.
- `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module.
- `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module.
@ -80,7 +80,7 @@ Let us go through the methods of `AppModule`:
Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`).
Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `Route()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter.
Almost every module needs to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `Route()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./msg-services.md#handler-type) and therefore needs to pass the module's [`keeper`](./keeper.md) as a parameter.
```go
// example
@ -134,12 +134,12 @@ The module manager is used throughout the application whenever an action on a co
- `SetOrderBeginBlockers(moduleNames ...string)`: Sets the order in which the `BeginBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function).
- `SetOrderEndBlockers(moduleNames ...string)`: Sets the order in which the `EndBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function).
- `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./invariants.md) of each module.
- `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino)`: Registers module routes to the application's `router`, in order to route [`message`s](./messages-and-queries.md#messages) to the appropriate [`handler`](./handler.md), and module query routes to the application's `queryRouter`, in order to route [`queries`](./messages-and-queries.md#queries) to the appropriate [`querier`](./query-services.md#legacy-queriers).
- `RegisterQueryServices(grpcRouter grpc.Server)`: Registers all module gRPC query services.
- `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino)`: Registers legacy [`Msg`](./messages-and-queries.md#messages) and [`querier`](./query-services.md#legacy-queriers) routes.
- `RegisterServices(cfg Configurator)`: Registers all module services.
- `InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates.
- `ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler)`: Calls the [`ExportGenesis`](./genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required.
- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`baseapp`](../core/baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events.
- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`baseapp`](../core/baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any).
- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`BaseApp`](../core/baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events.
- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`BaseApp`](../core/baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any).
Here's an example of a concrete integration within an application:

View File

@ -0,0 +1,97 @@
<!--
order: 4
-->
# `Msg` Services
A `Msg` Service processes [messages](./messages-and-queries.md#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`](../core/baseapp.md#delivertx). {synopsis}
## Pre-requisite Readings
- [Module Manager](./module-manager.md) {prereq}
- [Messages and Queries](./messages-and-queries.md) {prereq}
## Implementation of a module `Msg` service
All `Msg` processing is done by a [`Msg`](messages-and-queries.md#msg-services) protobuf service. Each module should define a `Msg` service, which will be responsible for request and response serialization.
As further described in [ADR 031](../architecture/adr-031-msg-service.md), this approach has the advantage of clearly specifying return types and generating server and client code.
When possible, the existing module's [`Keeper`](keeper.md) 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 `message` is valid. At this stage, the `message`'s `ValidateBasic()` 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 the `msgServer` method can be more expensive and require access to the state. For example, a `msgServer` method for a `transfer` message might check that the sending account has enough funds to actually perform the transfer. To access the state, the `msgServer` method needs to call the [`keeper`'s](./keeper.md) getter functions.
- Then, if the checks are successful, the `msgServer` method calls the [`keeper`'s](./keeper.md) setter functions to actually perform the state transition.
Before returning, `msgServer` methods generally emit one or more [events](../core/events.md) via the `EventManager` held in the `ctx`:
```go
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](../core/events.md) 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`.
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95
## Legacy Amino `Msg`s
### `handler` type
The `handler` type defined in the Cosmos SDK will be deprecated in favor of [`Msg` Services](#implementation-of-a-module-msg-service).
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 [`Msg`](./messages-and-queries.md#messages) is the actual object being processed.
- The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state.
- The [`*Result`] returned to `BaseApp` contains (among other things) information on the execution of the `handler` and [events](../core/events.md).
Module `handler`s are typically implemented in a `./handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the
[application's `router`](../core/baseapp.md#message-routing) via the `Route()` method. Typically,
the manager's `Route()` method simply constructs a Route that calls a `NewHandler()` method defined in `handler.go`.
+++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/x/gov/module.go#L143-L146
### Implementation
`NewHandler` function dispatches a `Msg` to appropriate handler function, usually by using a switch statement:
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/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, `handler`s functions need to be implemented for each module `Msg`. This will also involve manual handler registration of `Msg` types.
`handler`s functions should return a `*Result` and an `error`.
## Telemetry
New [telemetry metrics](../core/telemetry.md) 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](./query-services.md) {hide}

View File

@ -4,7 +4,7 @@ order: 5
# Query Services
A query service processes [`queries`](./messages-and-queries.md#queries). Query services are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). {synopsis}
A query service processes [`queries`](./messages-and-queries.md#queries). Query services are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `BaseApp`'s [`Query` method](../core/baseapp.md#query). {synopsis}
## Pre-requisite Readings
@ -22,7 +22,7 @@ Let us break it down:
- The `path` is an array of `string`s that contains the type of the query, and that can also contain `query` arguments. See [`queries`](./messages-and-queries.md#queries) for more information.
- The `req` itself is primarily used to retrieve arguments if they are too large to fit in the `path`. This is done using the `Data` field of `req`.
- The [`Context`](../core/context.md) contains all the necessary information needed to process the `query`, as well as a cache-wrapped copy of the latest state. It is primarily used by the [`keeper`](./keeper.md) to access the state.
- The result `res` returned to `baseapp`, marshalled using the application's [`codec`](../core/encoding.md).
- The result `res` returned to `BaseApp`, marshalled using the application's [`codec`](../core/encoding.md).
## Implementation of a module query service

View File

@ -25,6 +25,7 @@ x/{module}
│   ├── invariants.go
│   ├── genesis.go
│   ├── keeper.go
│   ├── msg_server.go
│   ├── ...
│   └── querier.go
│   └── grpc_query.go

View File

@ -192,7 +192,7 @@ When messages and queries are received by the application, they must be routed t
### Message Routing
[`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a `router` which maps `paths` (`string`) to the appropriate module [`handler`](../building-modules/handler.md) using the `.Route(ctx sdk.Context, path string)` function. Usually, the `path` is the name of the module.
[Messages](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `BaseApp` holds a router which maps string paths to the appropriate module [handler](../building-modules/msg-services.md#handler-type) using the `.Route(ctx sdk.Context, path string)` function. Usually, the `path` is the name of the module.
The [default router included in baseapp](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into the `Route` function of the [Router interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/router.go#L12). For a stateless router that doesn't want to make use of this, can just ignore the ctx.
@ -285,7 +285,7 @@ Before the first transaction of a given block is processed, a [volatile state](#
`DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step:
1. The `AnteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose.
2. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`.
2. For each message in the transaction, route to the appropriate module's [`handler`](../building-modules/msg-services.md#handler-type). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`.
During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation:
@ -342,7 +342,7 @@ Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`.
`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s.
First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns.
First, it retreives the message's `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/msg-services.md#handler-type) function for the message is executed, before `RunMsgs` returns.
## Other ABCI Messages

View File

@ -32,7 +32,7 @@ Events are returned to the underlying consensus engine in the response of the fo
- [`DeliverTx`](./baseapp.md#delivertx)
Events, the `type` and `attributes`, are defined on a **per-module basis** in the module's
`/types/events.go` file, and triggered from the module's [`handler`](../building-modules/handler.md)
`/types/events.go` file, and triggered from the module's [`Msg` service](../building-modules/msg-services.md)
via the [`EventManager`](#eventmanager). In addition, each module documents its events under
`spec/xx_events.md`.
@ -68,7 +68,7 @@ func NewHandler(keeper Keeper) sdk.Handler {
switch msg := msg.(type) {
```
See the [`Handler`](../building-modules/handler.md) concept doc for a more detailed
See the [`Msg` services](../building-modules/msg-services.md) concept doc for a more detailed
view on how to typically implement `Events` and use the `EventManager` in modules.
## Subscribing to Events

View File

@ -12,7 +12,7 @@ order: 2
## Transactions
Transactions are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [Handler](../building-modules/handler.md).
Transactions are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [`Msg` service](../building-modules/msg-services.md).
When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `message`s must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md).
@ -45,7 +45,7 @@ When users interact with the application's interfaces, they invoke the underlyin
### Messages
**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the `message`s for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/handler.md) to process them.
**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/msg-services.md#handler-type) to process them.
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L8-L29
@ -85,7 +85,7 @@ Every message in a transaction must be signed by the addresses specified by `Get
### Handlers
Since `message`s are module-specific types, each module needs a [`handler`](../building-modules/handler.md) to process all of its `message` types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/handler.md).
Since messages are module-specific types, each module needs a [`handler`](../building-modules/msg-services.md#handler-type) to process all of its message types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/msg-services.md#handler-type).
## Next {hide}

View File

@ -87,7 +87,7 @@ Note that **Tendermint only handles transaction bytes**. It has no knowledge of
Here are the most important messages of the ABCI:
- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam transactions. A special handler called the [`AnteHandler`](../basics/gas-fees.md#antehandler) is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the checks are valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet.
- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again along with the actual [`handler`s](../building-modules/handler.md) for each message in the transaction.
- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again along with the actual [`Msg` service methods](../building-modules/msg-services.md) for each message in the transaction.
- `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite.
Find a more detailed view of the ABCI methods from the [Tendermint docs](https://tendermint.com/docs/spec/abci/abci.html#overview).

View File

@ -162,13 +162,13 @@ type AppModule interface {
// registers
RegisterInvariants(sdk.InvariantRegistry)
// routes
// Deprecated: use RegisterServices
Route() sdk.Route
// Deprecated: use RegisterQueryService
// Deprecated: use RegisterServices
QuerierRoute() string
// Deprecated: use RegisterQueryService
// Deprecated: use RegisterServices
LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier
// RegisterServices allows a module to register services

View File

@ -125,7 +125,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
return keeper.NewQuerier(am.accountKeeper, legacyQuerierCdc)
}
// RegisterQueryService registers a GRPC query service to respond to the
// RegisterServices registers a GRPC query service to respond to the
// module-specific GRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterQueryServer(cfg.QueryServer(), am.accountKeeper)

View File

@ -111,7 +111,7 @@ func (AppModule) QuerierRoute() string { return "" }
// LegacyQuerierHandler returns the capability module's Querier.
func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil }
// RegisterQueryService registers a GRPC query service to respond to the
// RegisterServices registers a GRPC query service to respond to the
// module-specific GRPC queries.
func (am AppModule) RegisterServices(module.Configurator) {}

View File

@ -102,7 +102,7 @@ func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier {
return nil
}
// RegisterQueryService implements the AppModule interface.
// RegisterServices implements the AppModule interface.
func (am AppModule) RegisterServices(module.Configurator) {}
// InitGenesis implements the AppModule interface.

View File

@ -123,7 +123,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
return keeper.NewQuerier(am.keeper, legacyQuerierCdc)
}
// RegisterQueryService registers a gRPC query service to respond to the
// RegisterServices registers a gRPC query service to respond to the
// module-specific gRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)

View File

@ -109,7 +109,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
return keeper.NewQuerier(am.keeper, legacyQuerierCdc)
}
// RegisterQueryService registers a gRPC query service to respond to the
// RegisterServices registers a gRPC query service to respond to the
// module-specific gRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {
proposal.RegisterQueryServer(cfg.QueryServer(), am.keeper)

View File

@ -94,7 +94,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
return keeper.NewQuerier(am.keeper, legacyQuerierCdc)
}
// RegisterQueryService registers a GRPC query service to respond to the
// RegisterServices registers a GRPC query service to respond to the
// module-specific GRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)