Skip to content

Commit

Permalink
Update Building Modules documentation (#7473)
Browse files Browse the repository at this point in the history
* Update module-manager.md

* Update modules #messages doc

* Fix typo

* Update message implementation example link

* Update messages-and-queries.md#queries doc

* Update querier.md

* Update handler.md

* Update links in beginblock-endblock.md

* Update keeper.md

* Update invariants.md

* Update genesis.md

* Update module-interfaces.md#transaction-commands

* Update module-interfaces.md#query-commands

* Update module-interfaces.md#flags

* Update module-interfaces.md#rest

* Update structure.md

* Update module-interfaces.md#grpc

* Update errors.md

* Update module-interfaces.md#grpc-gateway-rest

* Add more info on swagger

* Address comments

* Fix go.sum

* Fix app-anatomy.md

* Update docs/building-modules/module-interfaces.md

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Update docs/building-modules/querier.md

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Update docs/building-modules/querier.md

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Update docs/building-modules/module-interfaces.md

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Update docs/building-modules/module-interfaces.md

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Address part of review comments

* Update old ref of RegisterQueryService

* Add example code for Manager

* Update queriers.md to query-services.md and refs

* Add new query-services.md

* Revert "Update old ref of RegisterQueryService"

This reverts commit 1ea1ea8.

* Update keeper.md

* Update handler.md

* Update handler.md

* Update messages-and-queries.md

* Update docs/basics/app-anatomy.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>

* Fix typo

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com>
  • Loading branch information
3 people authored and clevinson committed Oct 19, 2020
1 parent 86b87c4 commit 9f3ad91
Show file tree
Hide file tree
Showing 20 changed files with 287 additions and 180 deletions.
4 changes: 2 additions & 2 deletions docs/basics/app-anatomy.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ Finally, each module should also implement the `RegisterQueryService` method as

Legacy queriers were queriers used before the introduction of Protobuf and gRPC in the SDK. They are present for existing modules, but will be deprecated in a future release of the SDK. If you are developing new modules, gRPC query services should be preferred, and you only need to implement the `LegacyQuerierHandler` interface if you wish to use legacy queriers.

[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#application-interface) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`:
[`Legacy queriers`](../building-modules/query-services.md#legacy-queriers) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#application-interface) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`:

+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/baseapp/abci.go#L388-L418

Expand Down Expand Up @@ -236,7 +236,7 @@ The SDK also provides a development endpoint to generate [Swagger](https://swagg

#### Legacy API REST Endpoints

The [module's Legacy REST interface](../building-modules/module-interfaces.md#rest) lets users generate transactions and query the state through REST calls to the application's Legacy API Service. REST routes are defined in a file `client/rest/rest.go`, which is composed of:
The [module's Legacy REST interface](../building-modules/module-interfaces.md#legacy-rest) lets users generate transactions and query the state through REST calls to the application's Legacy API Service. REST routes are defined in a file `client/rest/rest.go`, which is composed of:

- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux).
- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the base `request` type of the Cosmos SDK:
Expand Down
2 changes: 1 addition & 1 deletion docs/building-modules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This repository contains documentation on concepts developers need to know in or
2. [`AppModule` Interface and Module Manager](./module-manager.md)
3. [Messages and Queries](./messages-and-queries.md)
4. [`Handler`s - Processing Messages](./handler.md)
5. [`Querier`s - Processing Queries](./querier.md)
5. [Query Services - Processing Queries](./query-services.md)
6. [BeginBlocker and EndBlocker](./beginblock-endblock.md)
7. [`Keeper`s](./keeper.md)
8. [Invariants](./invariants.md)
Expand Down
4 changes: 2 additions & 2 deletions docs/building-modules/beginblock-endblock.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ It is possible for developers to defined the order of execution between the `Beg

See an example implementation of `BeginBlocker` from the `distr` module:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/distribution/abci.go#L10-L32
+++ https://github.com/cosmos/cosmos-sdk/blob/f33749263f4ecc796115ad6e789cb0f7cddf9148/x/distribution/abci.go#L14-L38

and an example implementation of `EndBlocker` from the `staking` module:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/handler.go#L44-L96
+++ https://github.com/cosmos/cosmos-sdk/blob/f33749263f4ecc796115ad6e789cb0f7cddf9148/x/staking/abci.go#L22-L27

## Next {hide}

Expand Down
2 changes: 1 addition & 1 deletion docs/building-modules/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ execution.

Example:

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.38.1/x/distribution/keeper/querier.go#L62-L80
+++ https://github.com/cosmos/cosmos-sdk/blob/b2d48a9e815fe534a7faeec6ca2adb0874252b81/x/bank/keeper/keeper.go#L85-L122

Regardless if an error is wrapped or not, the SDK's `errors` package provides an API to determine if
an error is of a particular kind via `Is`.
Expand Down
24 changes: 12 additions & 12 deletions docs/building-modules/genesis.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@ Modules generally handle a subset of the state and, as such, they need to define

## Type Definition

The subset of the genesis state defined from a given module is generally defined in a `./internal/types/genesis.go` file, along with the `DefaultGenesis` and `ValidateGenesis` methods. The struct defining the module's subset of the genesis state is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process.
The subset of the genesis state defined from a given module is generally defined in a `genesis.proto` file ([more info](../core/encoding.md#gogoproto) on how to define protobuf messages). The struct defining the module's subset of the genesis state is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process.

See an example of `GenesisState` type definition from the nameservice tutorial
See an example of `GenesisState` protobuf message definition from the `auth` module:

+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L10-L12
+++ https://github.com/cosmos/cosmos-sdk/blob/a9547b54ffac9729fe1393651126ddfc0d236cff/proto/cosmos/auth/v1beta1/genesis.proto

Next we present the main genesis-related methods that need to be implemented by module developers in order for their module to be used in Cosmos SDK applications.

### `DefaultGenesis`

The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example from the `nameservice` module:
The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example from the `auth` module:

+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L33-L37
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/module.go#L48-L52

### `ValidateGenesis`

The `ValidateGenesis(genesisState GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameter listed in `GenesisState`. See an example from the `nameservice` module:
The `ValidateGenesis(genesisState GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameter listed in `GenesisState`. See an example from the `auth` module:

+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L18-L31
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/types/genesis.go#L57-L70

## Other Genesis Methods

Expand All @@ -43,18 +43,18 @@ The `InitGenesis` method is executed during [`InitChain`](../core/baseapp.md#ini

The [module manager](./module-manager.md#manager) of the application is responsible for calling the `InitGenesis` method of each of the application's modules, in order. This order is set by the application developer via the manager's `SetOrderGenesisMethod`, which is called in the [application's constructor function](../basics/app-anatomy.md#constructor-function)

See an example of `InitGenesis` from the nameservice tutorial
See an example of `InitGenesis` from the `auth` module

+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L39-L44
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/genesis.go#L13-L28

### `ExportGenesis`

The `ExportGenesis` method is executed whenever an export of the state is made. It takes the latest known version of the subset of the state managed by the module and creates a new `GenesisState` out of it. This is mainly used when the chain needs to be upgraded via a hard fork.

See an example of `ExportGenesis` from the nameservice tutorial.
See an example of `ExportGenesis` from the `auth` module.

+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L46-L57
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/genesis.go#L31-L42

## Next {hide}

Learn about [modules interfaces](#module-interfaces.md) {hide}
Learn about [modules interfaces](module-interfaces.md) {hide}
32 changes: 22 additions & 10 deletions docs/building-modules/handler.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ 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`, [`gas`](../basics/gas-fees.md) consumption and [`events`](../core/events.md).
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40
- 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

Expand All @@ -37,10 +37,10 @@ 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:
case *MsgType1:
return handleMsgType1(ctx, keeper, msg)

case MsgType2:
case *MsgType2:
return handleMsgType2(ctx, keeper, msg)

default:
Expand Down Expand Up @@ -69,16 +69,28 @@ ctx.EventManager().EmitEvent(

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.
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/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40
+++ 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:
Next is an example of how to return a `*Result` from the `gov` module:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/gov/handler.go#L59-L62
+++ 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/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go) from the nameservice tutorial.
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 [queriers](./querier.md) {hide}
Learn about [query services](./query-services.md) {hide}
3 changes: 1 addition & 2 deletions docs/building-modules/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module
- 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 [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing).
- 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).
Expand All @@ -91,4 +91,3 @@ Please refer to the [structure document](./structure.md) to learn about the reco
## Next {hide}

Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) {hide}

4 changes: 2 additions & 2 deletions docs/building-modules/invariants.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ An `Invariant` is a function that checks for a particular invariant within a mod

where the `string` return value is the invariant message, which can be used when printing logs, and the `bool` return value is the actual result of the invariant check.

In practice, each module implements `Invariant`s in a `./internal/keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model:
In practice, each module implements `Invariant`s in a `./keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model:

```go
// Example for an Invariant that checks balance-related invariants
Expand Down Expand Up @@ -74,7 +74,7 @@ At its core, the `InvariantRegistry` is defined in the SDK as an interface:

Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the `crisis` module:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/crisis/internal/keeper/keeper.go#L45-L49
+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/keeper/keeper.go#L50-L54

The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../basics/app-anatomy.md#constructor-function).

Expand Down
Loading

0 comments on commit 9f3ad91

Please sign in to comment.