chore: update docs to use core (#20718)
This commit is contained in:
parent
600f7740cc
commit
6f22111ea4
54
docs/build/building-modules/01-module-manager.md
vendored
54
docs/build/building-modules/01-module-manager.md
vendored
@ -39,8 +39,6 @@ The above interfaces are mostly embedding smaller interfaces (extension interfac
|
||||
* [`appmodule.HasPreBlocker`](#haspreblocker): The extension interface that contains information about the `AppModule` and `PreBlock`.
|
||||
* [`appmodule.HasBeginBlocker`](#hasbeginblocker): The extension interface that contains information about the `AppModule` and `BeginBlock`.
|
||||
* [`appmodule.HasEndBlocker`](#hasendblocker): The extension interface that contains information about the `AppModule` and `EndBlock`.
|
||||
* [`appmodule.HasPrecommit`](#hasprecommit): The extension interface that contains information about the `AppModule` and `Precommit`.
|
||||
* [`appmodule.HasPrepareCheckState`](#haspreparecheckstate): The extension interface that contains information about the `AppModule` and `PrepareCheckState`.
|
||||
* [`appmodule.HasService` / `module.HasServices`](#hasservices): The extension interface for modules to register services.
|
||||
* [`module.HasABCIEndBlock`](#hasabciendblock): The extension interface that contains information about the `AppModule`, `EndBlock` and returns an updated validator set.
|
||||
* (legacy) [`module.HasInvariants`](#hasinvariants): The extension interface for registering invariants.
|
||||
@ -53,7 +51,7 @@ The usage of extension interfaces allows modules to define only the functionalit
|
||||
### `HasAminoCodec`
|
||||
|
||||
```go reference
|
||||
// TODO
|
||||
https://github.com/cosmos/cosmos-sdk/blob/eee5e21e1c8d0995b6d4f83b7f55ec0b58d27ba7/core/appmodule/module.go#L74-L78
|
||||
```
|
||||
|
||||
* `RegisterLegacyAminoCodec(*codec.LegacyAmino)`: Registers the `amino` codec for the module, which is used to marshal and unmarshal structs to/from `[]byte` in order to persist them in the module's `KVStore`.
|
||||
@ -61,7 +59,7 @@ The usage of extension interfaces allows modules to define only the functionalit
|
||||
### `HasRegisterInterfaces`
|
||||
|
||||
```go reference
|
||||
// TODO
|
||||
https://github.com/cosmos/cosmos-sdk/blob/eee5e21e1c8d0995b6d4f83b7f55ec0b58d27ba7/core/appmodule/v2/module.go#L103-L106
|
||||
```
|
||||
|
||||
* `RegisterInterfaces(codectypes.InterfaceRegistry)`: Registers a module's interface types and their concrete implementations as `proto.Message`.
|
||||
@ -69,7 +67,7 @@ The usage of extension interfaces allows modules to define only the functionalit
|
||||
### `HasGRPCGateway`
|
||||
|
||||
```go reference
|
||||
// TODO
|
||||
https://github.com/cosmos/cosmos-sdk/blob/eee5e21e1c8d0995b6d4f83b7f55ec0b58d27ba7/types/module/module.go#L84-L87
|
||||
```
|
||||
|
||||
* `RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC routes for the module.
|
||||
@ -105,7 +103,7 @@ Let us go through the methods:
|
||||
`HasGenesis` is an extension interface for allowing modules to implement genesis functionalities.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/6ce2505/types/module/module.go#L184-L189
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/types/module/module.go#L184-L189
|
||||
```
|
||||
|
||||
#### `module.HasABCIGenesis`
|
||||
@ -113,7 +111,7 @@ https://github.com/cosmos/cosmos-sdk/blob/6ce2505/types/module/module.go#L184-L1
|
||||
`HasABCIGenesis` is an extension interface for allowing modules to implement genesis functionalities and returns validator set updates.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/6ce2505/types/module/module.go#L191-L196
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/types/module/module.go#L94-L98
|
||||
```
|
||||
|
||||
### `AppModule`
|
||||
@ -124,7 +122,7 @@ The `AppModule` interface defines a module. Modules can declare their functional
|
||||
#### `appmodule.AppModule`
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/6afece6/core/appmodule/module.go#L11-L20
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/core/appmodule/module.go#L11-L20
|
||||
```
|
||||
|
||||
#### `module.AppModule`
|
||||
@ -134,7 +132,7 @@ Previously the `module.AppModule` interface was containing all the methods that
|
||||
:::
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L195-L199
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/core/appmodule/v2/module.go#L14-L20
|
||||
```
|
||||
|
||||
### `HasInvariants`
|
||||
@ -154,7 +152,7 @@ This interface defines one method. It allows to checks if a module can register
|
||||
#### `appmodule.HasService`
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/6afece6/core/appmodule/module.go#L22-L40
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/core/appmodule/module.go#L22-L40
|
||||
```
|
||||
|
||||
#### `module.HasServices`
|
||||
@ -170,7 +168,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go
|
||||
This interface defines one method for checking a module consensus version.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L214-L220
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/core/appmodule/v2/migrations.go#L6-L12
|
||||
```
|
||||
|
||||
* `ConsensusVersion() uint64`: Returns the consensus version of the module.
|
||||
@ -184,58 +182,38 @@ The `HasPreBlocker` is an extension interface from `appmodule.AppModule`. All mo
|
||||
The `HasBeginBlocker` is an extension interface from `appmodule.AppModule`. All modules that have an `BeginBlock` method implement this interface.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L56-L63
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8dfcb3208d3b1cfbae08eda519e4cc1560/core/appmodule/v2/module.go#L30-L38
|
||||
```
|
||||
|
||||
* `BeginBlock(context.Context) error`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block.
|
||||
|
||||
### `HasEndBlocker`
|
||||
|
||||
The `HasEndBlocker` is an extension interface from `appmodule.AppModule`. All modules that have an `EndBlock` method implement this interface. If a module need to return validator set updates (staking), they can use `HasABCIEndBlock`
|
||||
The `HasEndBlocker` is an extension interface from `appmodule.AppModule`. All modules that have an `EndBlock` method implement this interface. If a module needs to return validator set updates (staking), they can use `HasABCIEndBlock`
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L66-L72
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8dfcb3208d3b1cfbae08eda519e4cc1560/core/appmodule/v2/module.go#L40-L48
|
||||
```
|
||||
|
||||
* `EndBlock(context.Context) error`: This method gives module developers the option to implement logic that is automatically triggered at the end of each block.
|
||||
|
||||
### `HasABCIEndBlock`
|
||||
|
||||
The `HasABCIEndBlock` is an extension interface from `module.AppModule`. All modules that have an `EndBlock` which return validator set updates implement this interface.
|
||||
The `HasUpdateValidators` is an extension interface from `module.AppModule`. All modules that have an `EndBlock` which return validator set updates implement this interface.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L222-L225
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8dfcb3208d3b1cfbae08eda519e4cc1560/core/appmodule/v2/module.go#L87-L94
|
||||
```
|
||||
|
||||
* `EndBlock(context.Context) ([]abci.ValidatorUpdate, error)`: This method gives module developers the option to inform the underlying consensus engine of validator set changes (e.g. the `staking` module).
|
||||
* `UpdateValidators(context.Context) ([]abci.ValidatorUpdate, error)`: This method gives module developers the option to inform the underlying consensus engine of validator set changes (e.g. the `staking` module).
|
||||
|
||||
### `HasPrecommit`
|
||||
|
||||
`HasPrecommit` is an extension interface from `appmodule.AppModule`. All modules that have a `Precommit` method implement this interface.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L49-L52
|
||||
```
|
||||
|
||||
* `Precommit(context.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../../learn/advanced/00-baseapp.md#commit) of each block using the [`finalizeblockstate`](../../learn/advanced/00-baseapp.md#state-updates) of the block to be committed. Implement empty if no logic needs to be triggered during `Commit` of each block for this module.
|
||||
|
||||
### `HasPrepareCheckState`
|
||||
|
||||
`HasPrepareCheckState` is an extension interface from `appmodule.AppModule`. All modules that have a `PrepareCheckState` method implement this interface.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L49-L52
|
||||
```
|
||||
|
||||
* `PrepareCheckState(context.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../../learn/advanced/00-baseapp.md#commit) of each block using the [`checkState`](../../learn/advanced/00-baseapp.md#state-updates) of the next block. Implement empty if no logic needs to be triggered during `Commit` of each block for this module.
|
||||
|
||||
### Implementing the Application Module Interfaces
|
||||
|
||||
// TODO reword!
|
||||
|
||||
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 needs to implement the `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 `NewMsgServerImpl(k keeper)` function defined in `keeper/msg_server.go` and therefore needs to pass the module's [`keeper`](./06-keeper.md) as a parameter.
|
||||
Almost every module needs to implement the `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.
|
||||
|
||||
```go
|
||||
// example
|
||||
|
||||
@ -25,7 +25,7 @@ When a transaction is relayed from the underlying consensus engine to the Cosmos
|
||||
Defining Protobuf `Msg` services is the recommended way to handle messages. A Protobuf `Msg` service should be created for each module, typically in `tx.proto` (see more info about [conventions and naming](../../learn/advanced/05-encoding.md#faq)). It must have an RPC service method defined for each message in the module.
|
||||
|
||||
|
||||
Each `Msg` service method must have exactly one argument, which must implement the `sdk.Msg` interface, and a Protobuf response. The naming convention is to call the RPC argument `Msg<service-rpc-name>` and the RPC response `Msg<service-rpc-name>Response`. For example:
|
||||
Each `Msg` service method must have exactly one argument, which must implement the `transaction.Msg` interface, and a Protobuf response. The naming convention is to call the RPC argument `Msg<service-rpc-name>` and the RPC response `Msg<service-rpc-name>Response`. For example:
|
||||
|
||||
```protobuf
|
||||
rpc Send(MsgSend) returns (MsgSendResponse);
|
||||
@ -34,14 +34,18 @@ Each `Msg` service method must have exactly one argument, which must implement t
|
||||
See an example of a `Msg` service definition from `x/bank` module:
|
||||
|
||||
```protobuf reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/bank/v1beta1/tx.proto#L13-L36
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/x/bank/proto/cosmos/bank/v1beta1/tx.proto#L13-L41
|
||||
```
|
||||
|
||||
### `sdk.Msg` Interface
|
||||
### `transaction.Msg` Interface
|
||||
|
||||
`sdk.Msg` is a alias of `proto.Message`.
|
||||
`transaction.Msg` is an alias of `proto.Message`.
|
||||
|
||||
To attach a `ValidateBasic()` method to a message then you must add methods to the type adhereing to the `HasValidateBasic`.
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/main/core/transaction/transaction.go#L8
|
||||
```
|
||||
|
||||
To attach a `ValidateBasic()` method to a message, then you must add methods to the type adhereing to the `HasValidateBasic`.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/9c1e8b247cd47b5d3decda6e86fbc3bc996ee5d7/types/tx_msg.go#L84-L88
|
||||
@ -105,26 +109,6 @@ As `proto.Message`s, generated `Response` types implement by default `String()`
|
||||
|
||||
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](./01-module-manager.md#appmodule).
|
||||
|
||||
### Legacy Queries
|
||||
|
||||
Before the introduction of Protobuf and gRPC in the Cosmos SDK, there was usually no specific `query` object defined by module developers, contrary to `message`s. Instead, the Cosmos SDK took the simpler approach of using a simple `path` to define each `query`. The `path` contains the `query` type and all the arguments needed to process it. For most module queries, the `path` should look like the following:
|
||||
|
||||
```text
|
||||
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](../../learn/advanced/00-baseapp.md#query).
|
||||
* `queryRoute` is used by `BaseApp`'s [`queryRouter`](../../learn/advanced/00-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`](./04-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`.
|
||||
|
||||
The `path` for each `query` must be defined by the module developer in the module's [command-line interface file](./09-module-interfaces.md#query-commands).Overall, there are 3 mains components module developers need to implement in order to make the subset of the state defined by their module queryable:
|
||||
|
||||
* A [`querier`](./04-query-services.md#legacy-queriers), to process the `query` once it has been [routed to the module](../../learn/advanced/00-baseapp.md#query-routing).
|
||||
* [Query commands](./09-module-interfaces.md#query-commands) in the module's CLI file, where the `path` for each `query` is specified.
|
||||
* `query` return types. Typically defined in a file `types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://pkg.go.dev/fmt#Stringer).
|
||||
|
||||
### Store Queries
|
||||
|
||||
|
||||
66
docs/build/building-modules/03-msg-services.md
vendored
66
docs/build/building-modules/03-msg-services.md
vendored
@ -21,25 +21,33 @@ Each module should define a Protobuf `Msg` service, which will be responsible fo
|
||||
|
||||
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.
|
||||
|
||||
Protobuf generates a `MsgServer` interface based on a definition of `Msg` service. It is the role of the module developer to implement this interface, by implementing the state transition logic that should happen upon receival of each `sdk.Msg`. As an example, here is the generated `MsgServer` interface for `x/bank`, which exposes two `sdk.Msg`s:
|
||||
Protobuf generates a `MsgServer` interface based on the definition of `Msg` service. It is the role of the module developer to implement this interface, by implementing the state transition logic that should happen upon receival of each `transaction.Msg`. As an example, here is the generated `MsgServer` interface for `x/bank`, which exposes two `transaction.Msg`s:
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/types/tx.pb.go#L550-L568
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/x/bank/types/tx.pb.go#L564-L579
|
||||
```
|
||||
|
||||
When possible, the existing module's [`Keeper`](./06-keeper.md) should implement `MsgServer`, otherwise a `msgServer` struct that embeds the `Keeper` can be created, typically in `./keeper/msg_server.go`:
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/msg_server.go#L17-L19
|
||||
https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/x/bank/keeper/msg_server.go#L16-L19
|
||||
```
|
||||
|
||||
`msgServer` methods can retrieve the `context.Context` from the `context.Context` parameter method using the `sdk.UnwrapSDKContext`:
|
||||
`msgServer` methods can retrieve the auxillary information or services using the environment variable, it is always located in the keeper:
|
||||
|
||||
Environment:
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/07151304e2ec6a185243d083f59a2d543253cb15/core/appmodule/v2/environment.go#L14-L29
|
||||
```
|
||||
|
||||
Keeper Example:
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/msg_server.go#L56
|
||||
https://github.com/cosmos/cosmos-sdk/blob/07151304e2ec6a185243d083f59a2d543253cb15/x/bank/keeper/keeper.go#L56-L58
|
||||
```
|
||||
|
||||
`sdk.Msg` processing usually follows these 3 steps:
|
||||
`transaction.Msg` processing usually follows these 3 steps:
|
||||
|
||||
### Validation
|
||||
|
||||
@ -71,14 +79,18 @@ After the validation is successful, the `msgServer` method uses the [`keeper`](.
|
||||
|
||||
### Events
|
||||
|
||||
Before returning, `msgServer` methods generally emit one or more [events](../../learn/advanced/08-events.md) by using the `EventManager` held in the `ctx`. Use the new `EmitTypedEvent` function that uses protobuf-based event types:
|
||||
Before returning, `msgServer` methods generally emit one or more [events](../../learn/advanced/08-events.md) by using the `EventManager` held in `environment`.
|
||||
|
||||
There are two ways to emit events, typed events using protobuf or arbitrary key & values.
|
||||
|
||||
Typed Events:
|
||||
|
||||
```go
|
||||
ctx.EventManager().EmitTypedEvent(
|
||||
&group.EventABC{Key1: Value1, Key2, Value2})
|
||||
```
|
||||
|
||||
or the older `EmitEvent` function:
|
||||
Arbitrary Events:
|
||||
|
||||
```go
|
||||
ctx.EventManager().EmitEvent(
|
||||
@ -98,7 +110,7 @@ The invoked `msgServer` method returns a `proto.Message` response and an `error`
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/msg_service_router.go#L160
|
||||
```
|
||||
|
||||
This method takes care of marshaling the `res` parameter to protobuf and attaching any events on the `ctx.EventManager()` to the `sdk.Result`.
|
||||
This method takes care of marshaling the `res` parameter to protobuf and attaching any events on the `EventManager()` to the `sdk.Result`.
|
||||
|
||||
```protobuf reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/base/abci/v1beta1/abci.proto#L93-L113
|
||||
@ -106,7 +118,37 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/base/abci
|
||||
|
||||
This diagram shows a typical structure of a Protobuf `Msg` service, and how the message propagates through the module.
|
||||
|
||||

|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant baseApp
|
||||
participant router
|
||||
participant handler
|
||||
participant msgServer
|
||||
participant keeper
|
||||
participant EventManager
|
||||
|
||||
User->>baseApp: Transaction Type<Tx>
|
||||
baseApp->>router: Route(ctx, msgRoute)
|
||||
router->>handler: handler
|
||||
handler->>msgServer: Msg<Tx>(Context, Msg(..))
|
||||
|
||||
alt addresses invalid, denominations wrong, etc.
|
||||
msgServer->>handler: error
|
||||
handler->>router: error
|
||||
router->>baseApp: result, error code
|
||||
else
|
||||
msgServer->>keeper: perform action, update context
|
||||
keeper->>msgServer: results, error code
|
||||
msgServer->>EventManager: Emit relevant events
|
||||
msgServer->>msgServer: maybe wrap results in more structure
|
||||
msgServer->>handler: result, error code
|
||||
handler->>router: result, error code
|
||||
router->>baseApp: result, error code
|
||||
end
|
||||
|
||||
baseApp->>User: result, error code
|
||||
```
|
||||
|
||||
## Telemetry
|
||||
|
||||
@ -117,3 +159,7 @@ This is an example from the `x/auth/vesting` module:
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/vesting/msg_server.go#L76-L88
|
||||
```
|
||||
|
||||
:::Warning
|
||||
Telemetry adds a performance overhead to the chain. It is recommended to only use this in critical paths
|
||||
:::
|
||||
|
||||
@ -26,9 +26,9 @@ The actual implementation of `BeginBlocker` and `EndBlocker` in `abci.go` are ve
|
||||
|
||||
* They generally use the [`keeper`](./06-keeper.md) and [`ctx`](../../learn/advanced/02-context.md) to retrieve information about the latest state.
|
||||
* If needed, they use the `keeper` and `ctx` to trigger state-transitions.
|
||||
* If needed, they can emit [`events`](../../learn/advanced/08-events.md) via the `ctx`'s `EventManager`.
|
||||
* If needed, they can emit [`events`](../../learn/advanced/08-events.md) via the `environments`'s `EventManager`.
|
||||
|
||||
A specific type of `EndBlocker` is available to return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](https://docs.cometbft.com/v0.37/spec/abci/abci++_methods#endblock). This is the preferred way to implement custom validator changes.
|
||||
A specific method (`UpdateValidators`) is available to return validator updates to the underlying consensus engine in the form of an [`[]appmodule.ValidatorUpdates`](https://github.com/cosmos/cosmos-sdk/blob/07151304e2ec6a185243d083f59a2d543253cb15/core/appmodule/v2/module.go#L87-L101). This is the preferred way to implement custom validator changes.
|
||||
|
||||
It is possible for developers to define the order of execution between the `BeginBlocker`/`EndBlocker` functions of each of their application's modules via the module's manager `SetOrderBeginBlocker`/`SetOrderEndBlocker` methods. For more on the module manager, click [here](./01-module-manager.md#manager).
|
||||
|
||||
|
||||
40
docs/build/building-modules/06-keeper.md
vendored
40
docs/build/building-modules/06-keeper.md
vendored
@ -47,7 +47,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/keepe
|
||||
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 an `expected_keepers.go` file in the root of 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](../../learn/advanced/04-store.md) managed by the module. They should always remain unexposed to external modules.
|
||||
* `KVStoreService`s grant access to the store(s) of the [multistore](../../learn/advanced/04-store.md) managed by the module. They should always remain unexposed to external modules.
|
||||
* `cdc` is the [codec](../../learn/advanced/05-encoding.md) used to marshall and unmarshall structs to/from `[]byte`. The `cdc` can be any of `codec.BinaryCodec`, `codec.JSONCodec` or `codec.Codec` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces.
|
||||
* The authority listed is a module account or user account that has the right to change module level parameters. Previously this was handled by the param module, which has been deprecated.
|
||||
|
||||
@ -55,38 +55,8 @@ 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 by the [`Msg` server](./03-msg-services.md) when `keeper`s' methods are called.
|
||||
`Keeper`s primarily expose methods for business logic, as validity checks should have already been performed by the [`Msg` server](./03-msg-services.md) when `keeper`s' methods are called.
|
||||
|
||||
Typically, a *getter* method will have the following signature
|
||||
|
||||
```go
|
||||
func (k Keeper) Get(ctx context.Context, key string) returnType
|
||||
```
|
||||
|
||||
and the method will 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`. Then it's preferred to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety.
|
||||
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.
|
||||
|
||||
Similarly, a *setter* method will have the following signature
|
||||
|
||||
```go
|
||||
func (k Keeper) Set(ctx context.Context, key string, value valueType)
|
||||
```
|
||||
|
||||
and the method will 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`. It's preferred to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety.
|
||||
2. Marshal `value` to `[]byte` using the codec `cdc`.
|
||||
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 `staking` module](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/keeper.go).
|
||||
|
||||
The [module `KVStore`](../../learn/advanced/04-store.md#kvstore-and-commitkvstore-interfaces) also provides an `Iterator()` method which returns an `Iterator` object to iterate over a domain of keys.
|
||||
|
||||
This is an example from the `auth` module to iterate accounts:
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/keeper/account.go
|
||||
```
|
||||
<!-- markdown-link-check-disable -->
|
||||
State management is recommended to be done via [Collections](../packages/collections)
|
||||
<!-- The above link is created via the script to generate docs -->
|
||||
|
||||
2
docs/build/building-modules/07-invariants.md
vendored
2
docs/build/building-modules/07-invariants.md
vendored
@ -4,6 +4,8 @@ sidebar_position: 1
|
||||
|
||||
# Invariants
|
||||
|
||||
<!-- TODO: figure what is the future of invariants -->
|
||||
|
||||
:::note Synopsis
|
||||
An invariant is a property of the application that should always be true. In the context of the Cosmos SDK, an `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations.
|
||||
:::
|
||||
|
||||
4
docs/build/building-modules/08-genesis.md
vendored
4
docs/build/building-modules/08-genesis.md
vendored
@ -56,7 +56,7 @@ The [module manager](./01-module-manager.md#manager) of the application is respo
|
||||
See an example of `InitGenesis` from the `auth` module:
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/keeper/genesis.go#L8-L35
|
||||
https://github.com/cosmos/cosmos-sdk/blob/452129d6aa45134f598f05be13f3fd961ff9734e/x/auth/keeper/genesis.go#L12-L43
|
||||
```
|
||||
|
||||
### `ExportGenesis`
|
||||
@ -66,7 +66,7 @@ The `ExportGenesis` method is executed whenever an export of the state is made.
|
||||
See an example of `ExportGenesis` from the `auth` module.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/keeper/genesis.go#L37-L49
|
||||
https://github.com/cosmos/cosmos-sdk/blob/452129d6aa45134f598f05be13f3fd961ff9734e/x/auth/keeper/genesis.go#L45-L60
|
||||
```
|
||||
|
||||
### GenesisTxHandler
|
||||
|
||||
10
docs/build/building-modules/11-structure.md
vendored
10
docs/build/building-modules/11-structure.md
vendored
@ -2,10 +2,12 @@
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Recommended Folder Structure
|
||||
# Folder Structure
|
||||
|
||||
:::note Synopsis
|
||||
This document outlines the recommended structure of Cosmos SDK modules. These ideas are meant to be applied as suggestions. Application developers are encouraged to improve upon and contribute to module structure and development design.
|
||||
This document outlines the structure of Cosmos SDK modules. These ideas are meant to be applied as suggestions. Application developers are encouraged to improve upon and contribute to module structure and development design.
|
||||
|
||||
The required interface for a module is located in the module.go. Everything beyond this is suggestive.
|
||||
:::
|
||||
|
||||
## Structure
|
||||
@ -18,14 +20,12 @@ proto
|
||||
└── {module_name}
|
||||
└── {proto_version}
|
||||
├── {module_name}.proto
|
||||
├── event.proto
|
||||
├── genesis.proto
|
||||
├── query.proto
|
||||
└── tx.proto
|
||||
```
|
||||
|
||||
* `{module_name}.proto`: The module's common message type definitions.
|
||||
* `event.proto`: The module's message type definitions related to events.
|
||||
* `genesis.proto`: The module's message type definitions related to genesis state.
|
||||
* `query.proto`: The module's Query service and related message type definitions.
|
||||
* `tx.proto`: The module's Msg service and related message type definitions.
|
||||
@ -79,8 +79,8 @@ x/{module_name}
|
||||
* `client/`: The module's CLI client functionality implementation and the module's CLI testing suite.
|
||||
* `exported/`: The module's exported types - typically interface types. If a module relies on keepers from another module, it is expected to receive the keepers as interface contracts through the `expected_keepers.go` file (see below) in order to avoid a direct dependency on the module implementing the keepers. However, these interface contracts can define methods that operate on and/or return types that are specific to the module that is implementing the keepers and this is where `exported/` comes into play. The interface types that are defined in `exported/` use canonical types, allowing for the module to receive the keepers as interface contracts through the `expected_keepers.go` file. This pattern allows for code to remain DRY and also alleviates import cycle chaos.
|
||||
* `keeper/`: The module's `Keeper` and `MsgServer` implementation.
|
||||
* `module/`: The module's `AppModule` implementation.
|
||||
* `abci.go`: The module's `BeginBlocker` and `EndBlocker` implementations (this file is only required if `BeginBlocker` and/or `EndBlocker` need to be defined).
|
||||
* `module/`: The module's `AppModule` implementation.
|
||||
* `autocli.go`: The module [autocli](https://docs.cosmos.network/main/core/autocli) options.
|
||||
* `simulation/`: The module's [simulation](./14-simulator.md) package defines functions used by the blockchain simulator application (`simapp`).
|
||||
* `README.md`: The module's specification documents outlining important concepts, state storage structure, and message and event type definitions. Learn more how to write module specs in the [spec guidelines](../../spec/SPEC_MODULE.md).
|
||||
|
||||
17
docs/build/building-modules/12-errors.md
vendored
17
docs/build/building-modules/12-errors.md
vendored
@ -10,8 +10,13 @@ This document outlines the recommended usage and APIs for error handling in Cosm
|
||||
|
||||
Modules are encouraged to define and register their own errors to provide better
|
||||
context on failed message or handler execution. Typically, these errors should be
|
||||
common or general errors which can be further wrapped to provide additional specific
|
||||
execution context.
|
||||
common or general errors which can be further wrapped to provide additional specific execution context.
|
||||
|
||||
There are two ways to return errors. You can register custom errors with a codespace that is meant to provide more information to clients and normal go errors. The Cosmos SDK uses a mixture of both.
|
||||
|
||||
:::Warning
|
||||
If errors are registered they are part of consensus and cannot be changed in a minor release
|
||||
:::
|
||||
|
||||
## Registration
|
||||
|
||||
@ -32,13 +37,10 @@ necessarily have to be. The only restrictions on error codes are the following:
|
||||
* Must be greater than one, as a code value of one is reserved for internal errors.
|
||||
* Must be unique within the module.
|
||||
|
||||
Note, the Cosmos SDK provides a core set of *common* errors. These errors are defined in [`types/errors/errors.go`](https://github.com/cosmos/cosmos-sdk/blob/main/types/errors/errors.go).
|
||||
|
||||
## Wrapping
|
||||
|
||||
The custom module errors can be returned as their concrete type as they already fulfill the `error`
|
||||
interface. However, module errors can be wrapped to provide further context and meaning to failed
|
||||
execution.
|
||||
interface. However, module errors can be wrapped to provide further context and meaning to failed execution.
|
||||
|
||||
Example:
|
||||
|
||||
@ -46,9 +48,6 @@ Example:
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/keeper.go#L141-L182
|
||||
```
|
||||
|
||||
Regardless if an error is wrapped or not, the Cosmos SDK's `errors` package provides a function to determine if
|
||||
an error is of a particular kind via `Is`.
|
||||
|
||||
## ABCI
|
||||
|
||||
If a module error is registered, the Cosmos SDK `errors` package allows ABCI information to be extracted
|
||||
|
||||
3
docs/build/building-modules/14-simulator.md
vendored
3
docs/build/building-modules/14-simulator.md
vendored
@ -71,6 +71,7 @@ Here is how one can override the above package `simappparams`.
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/release/v0.51.x/Makefile#L292-L334
|
||||
```
|
||||
|
||||
The SDK simulations can be executed like normal tests in Go from the shell or within an IDE.
|
||||
Make sure that you pass the `-tags='sims` parameter to enable them and other params that make sense for your scenario.
|
||||
|
||||
@ -133,4 +134,4 @@ can be done at a high level with the deterministic pseudo random number generato
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/release/v0.51.x/Makefile#L352-L355
|
||||
```
|
||||
```
|
||||
|
||||
13
docs/build/building-modules/17-preblock.md
vendored
13
docs/build/building-modules/17-preblock.md
vendored
@ -18,14 +18,7 @@ sidebar_position: 1
|
||||
|
||||
There are two semantics around the new lifecycle method:
|
||||
|
||||
- It runs before the `BeginBlocker` of all modules
|
||||
- It can modify consensus parameters in storage, and signal the caller through the return value.
|
||||
* It runs before the `BeginBlocker` of all modules
|
||||
* It can modify consensus parameters in storage, and signal the caller through the return value.
|
||||
|
||||
When it returns `ConsensusParamsChanged=true`, the caller must refresh the consensus parameter in the deliver context:
|
||||
```
|
||||
app.finalizeBlockState.ctx = app.finalizeBlockState.ctx.WithConsensusParams(app.GetConsensusParams())
|
||||
```
|
||||
|
||||
The new ctx must be passed to all the other lifecycle methods.
|
||||
|
||||
<!-- TODO: leaving this here to update docs with core api changes -->
|
||||
Modules are required to get the consensus params from the consensus module. Consensus params located in `sdk.Context` were depreacted and should be treated as unsafe. `sdk.Context` is deprecated due to it being a global state within the entire state machine, it has been replaced with `appmodule.Environment`.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user