Skip to content
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

Update Building Modules documentation #7473

Merged
merged 49 commits into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
cb87c4f
Update module-manager.md
blushi Oct 7, 2020
49bdfa0
Merge branch 'master' of github.com:cosmos/cosmos-sdk
blushi Oct 7, 2020
0bc40be
Update modules #messages doc
blushi Oct 7, 2020
916a80b
Fix typo
blushi Oct 7, 2020
340babe
Update message implementation example link
blushi Oct 8, 2020
844401d
Update messages-and-queries.md#queries doc
blushi Oct 8, 2020
0a8fa86
Update querier.md
blushi Oct 8, 2020
25bc998
Update handler.md
blushi Oct 8, 2020
2c7010b
Update links in beginblock-endblock.md
blushi Oct 8, 2020
201d442
Update keeper.md
blushi Oct 8, 2020
546aefc
Update invariants.md
blushi Oct 8, 2020
3918392
Update genesis.md
blushi Oct 8, 2020
d0bac01
Update module-interfaces.md#transaction-commands
blushi Oct 8, 2020
0686e5e
Update module-interfaces.md#query-commands
blushi Oct 8, 2020
e76bdaf
Merge branch 'master' into marie/6953-building-modules
blushi Oct 8, 2020
6dac9b2
Update module-interfaces.md#flags
blushi Oct 8, 2020
fadd8c1
Update module-interfaces.md#rest
blushi Oct 8, 2020
8b58c43
Update structure.md
blushi Oct 8, 2020
bcb17dd
Merge branch 'master' into marie/6953-building-modules
blushi Oct 9, 2020
2fed130
Update module-interfaces.md#grpc
blushi Oct 9, 2020
289e10e
Update errors.md
blushi Oct 9, 2020
d0d4b34
Update module-interfaces.md#grpc-gateway-rest
blushi Oct 9, 2020
757b711
Merge branch 'master' into marie/6953-building-modules
blushi Oct 9, 2020
0d26688
Add more info on swagger
blushi Oct 9, 2020
7e9db05
Merge branch 'marie/6953-building-modules' of github.com:cosmos/cosmo…
blushi Oct 9, 2020
fa8a9cf
Address comments
blushi Oct 13, 2020
9d1cc7f
Merge branch 'master' into marie/6953-building-modules
blushi Oct 13, 2020
84a520d
Fix go.sum
blushi Oct 13, 2020
cf8d497
Merge branch 'marie/6953-building-modules' of github.com:cosmos/cosmo…
blushi Oct 13, 2020
d86adc2
Fix app-anatomy.md
blushi Oct 13, 2020
5a69a8c
Update docs/building-modules/module-interfaces.md
blushi Oct 13, 2020
cd56931
Update docs/building-modules/querier.md
blushi Oct 13, 2020
5e02309
Update docs/building-modules/querier.md
blushi Oct 13, 2020
7bbc9b8
Update docs/building-modules/module-interfaces.md
blushi Oct 13, 2020
0635919
Update docs/building-modules/module-interfaces.md
blushi Oct 13, 2020
b19c8e1
Address part of review comments
blushi Oct 14, 2020
1ea1ea8
Update old ref of RegisterQueryService
blushi Oct 14, 2020
56f9e10
Add example code for Manager
blushi Oct 14, 2020
bbd52c1
Update queriers.md to query-services.md and refs
blushi Oct 14, 2020
447ebb7
Add new query-services.md
blushi Oct 14, 2020
03e4c56
Revert "Update old ref of RegisterQueryService"
blushi Oct 14, 2020
5ad70f4
Update keeper.md
blushi Oct 14, 2020
9201a1a
Update handler.md
blushi Oct 14, 2020
9d156fa
Update handler.md
blushi Oct 14, 2020
e8d6858
Update messages-and-queries.md
blushi Oct 14, 2020
6ef1db3
Update docs/basics/app-anatomy.md
blushi Oct 14, 2020
bd20a72
Update docs/building-modules/intro.md
blushi Oct 14, 2020
1d02539
Fix typo
blushi Oct 14, 2020
4288915
Merge branch 'master' into marie/6953-building-modules
fedekunze Oct 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/basics/app-anatomy.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ gRPC query services are defined in the module's Protobuf definition, specificall

Protobuf generates a `QueryServer` interface for each module, containing all the service methods. A module's [`keeper`](#keeper) then needs to implement this `QueryServer` interface, by providing the concrete implementation of each service method. This concrete implementation is the handler of the corresponding gRPC query endpoint.

Finally, each module should also implement the `RegisterQueryService` method as part of the [`AppModule` interface](#application-module-interface). This method should call the `RegisterQueryServer` function provided by the generated Protobuf code.
Finally, each module should also implement the `RegisterServices` method as part of the [`AppModule` interface](#application-module-interface). This method should call the `RegisterQueryServer` function provided by the generated Protobuf code.

### Legacy Querier

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
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`
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

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:
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

+++ 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}
18 changes: 9 additions & 9 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
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

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,15 +69,15 @@ 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.

## Next {hide}
blushi marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
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
18 changes: 9 additions & 9 deletions docs/building-modules/keeper.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The core idea behind the object-capabilities approach is to only reveal what is

## Type Definition

`keeper`s are generally implemented in a `internal/keeper/keeper.go` file located in the module's folder. By convention, the type `keeper` of a module is simply named `Keeper` and usually follows the following structure:
`keeper`s are generally implemented in a `/keeper/keeper.go` file located in the module's folder. By convention, the type `keeper` of a module is simply named `Keeper` and usually follows the following structure:

```go
type Keeper struct {
Expand All @@ -32,15 +32,15 @@ type Keeper struct {
}
```

For example, here is the [type definition of the `keeper` from the nameservice tutorial:
For example, here is the type definition of the `keeper` from the `staking` module:

+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/keeper.go#L10-L17
+++ https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/staking/keeper/keeper.go#L23-L33

Let us go through the different parameters:

- An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in a `internal/types/expected_keepers.go` file within the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself.
- An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in a `types/expected_keepers.go` file within the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself.
- `storeKey`s grant access to the store(s) of the [multistore](../core/store.md) managed by the module. They should always remain unexposed to external modules.
- A [codec `cdc`](../core/encoding.md), used to marshall and unmarshall struct to/from `[]byte`.
- A [codec `cdc`](../core/encoding.md), used to marshall and unmarshall struct to/from `[]byte`, that can be any of `codec.BinaryMarshaler`,`codec.JSONMarshaler` or `codec.Marshaler` based on your requirements.
blushi marked this conversation as resolved.
Show resolved Hide resolved

Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../basics/app-anatomy.md). This is where `keeper`s are instantiated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require it.

Expand All @@ -56,7 +56,7 @@ func (k Keeper) Get(ctx sdk.Context, key string) returnType

and go through the following steps:

1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey` method of the `ctx`.
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey)` method of the `ctx`.
2. If it exists, get the `[]byte` value stored at location `[]byte(key)` using the `Get(key []byte)` method of the store.
3. Unmarshall the retrieved value from `[]byte` to `returnType` using the codec `cdc`. Return the value.

Expand All @@ -68,11 +68,11 @@ func (k Keeper) Set(ctx sdk.Context, key string, value valueType)

and go through the following steps:

1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey` method of the `ctx`.
2. Marhsall `value` to `[]byte` using the codec `cdc`.
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey)` method of the `ctx`.
2. Marshall `value` to `[]byte` using the codec `cdc`.
blushi marked this conversation as resolved.
Show resolved Hide resolved
3. Set the encoded value in the store at location `key` using the `Set(key []byte, value []byte)` method of the store.

For more, see an example of `keeper`'s [methods implementation from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/keeper.go).
For more, see an example of `keeper`'s [methods implementation from the `staking` module](https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/staking/keeper/keeper.go).

## Next {hide}
blushi marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
Loading