From cb87c4fb9a0326389bbb1d492174909f7ad3a6e9 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 7 Oct 2020 14:49:13 +0200 Subject: [PATCH 01/41] Update module-manager.md --- docs/building-modules/module-manager.md | 44 ++++++++++++++----------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index dad35a9da3aa..97217601a100 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -29,15 +29,17 @@ are only used for genesis can take advantage of the `Module` patterns without ha The `AppModuleBasic` interface defines the independent methods modules need to implement. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L46-L59 ++++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L49-L63 Let us go through the methods: - `Name()`: Returns the name of the module as a `string`. -- `RegisterLegacyAminoCodec(*codec.LegacyAmino)`: Registers the `amino` codec for the module, which is used to marhsal and unmarshal structs to/from `[]byte` in order to persist them in the moduel's `KVStore`. -- `DefaultGenesis()`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. -- `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. +- `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`. +- `RegisterInterfaces(codectypes.InterfaceRegistry)`: Registers a module's interface types and their concrete implementations as `proto.Message`. +- `DefaultGenesis(codec.JSONMarshaler)`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. +- `ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. - `RegisterRESTRoutes(client.Context, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. +- `RegisterGRPCRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC Gateway routes for the module. - `GetTxCmd()`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. - `GetQueryCmd()`: Return the root [`query` command](./module-interfaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. @@ -47,20 +49,20 @@ All the `AppModuleBasic` of an application are managed by the [`BasicManager`](# The `AppModuleGenesis` interface is a simple embedding of the `AppModuleBasic` interface with two added methods. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L126-L131 ++++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L152-L158 Let us go through the two added methods: -- `InitGenesis(sdk.Context, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started). -- `ExportGenesis(sdk.Context)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain. +- `InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started). +- `ExportGenesis(sdk.Context, codec.JSONMarshaler)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain. -It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, json.RawMessage)` and `ExportGenesis(sdk.Context)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface. +It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage)` and `ExportGenesis(sdk.Context, codec.JSONMarshaler)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface. ### `AppModule` The `AppModule` interface defines the inter-dependent methods modules need to implement. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L133-L149 ++++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/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. @@ -68,8 +70,9 @@ 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()`: 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). -- `NewQuerierHandler()`: Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`. +- `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`](./querier.md) given the query `path`, in order to process the `query`. +- `RegisterQueryService(grpc.Server)`: Allows a module to register a gRPC query service. - `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. @@ -103,15 +106,17 @@ Module managers are used to manage collections of `AppModuleBasic` and `AppModul The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L61-L63 ++++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L65-L66 It implements the following methods: - `NewBasicManager(modules ...AppModuleBasic)`: Constructor function. It takes a list of the application's `AppModuleBasic` and builds a new `BasicManager`. This function is generally called in the `init()` function of [`app.go`](../basics/app-anatomy.md#core-application-file) to quickly initialize the independent elements of the application's modules (click [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L59-L74) to see an example). -- `RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)`: Registers the [`codec`s](../core/encoding.md) of each of the application's `AppModuleBasic`. This function is usually called early on in the [application's construction](../basics/app-anatomy.md#constructor). -- `DefaultGenesis()`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis()`](./genesis.md#defaultgenesis) function of each module. It is used to construct a default genesis file for the application. -- `ValidateGenesis(genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis()`](./genesis.md#validategenesis) function of each module. +- `RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)`: Registers the [`codec.LegacyAmino`s](../core/encoding.md#amino) of each of the application's `AppModuleBasic`. This function is usually called early on in the [application's construction](../basics/app-anatomy.md#constructor). +- `RegisterInterfaces(registry codectypes.InterfaceRegistry)`: Registers interface types and implementations of each of the application's `AppModuleBasic`. +- `DefaultGenesis(cdc codec.JSONMarshaler)`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis(cdc codec.JSONMarshaler)`](./genesis.md#defaultgenesis) function of each module. It is used to construct a default genesis file for the application. +- `ValidateGenesis(cdc codec.JSONMarshaler, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`](./genesis.md#validategenesis) function of each module. - `RegisterRESTRoutes(ctx client.Context, rtr *mux.Router)`: Registers REST routes for modules by calling the [`RegisterRESTRoutes`](./module-interfaces.md#register-routes) function of each module. This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). +- `RegisterGRPCRoutes(clientCtx client.Context, rtr *runtime.ServeMux)`: Registers gRPC Gateway routes for modules. - `AddTxCommands(rootTxCmd *cobra.Command)`: Adds modules' transaction commands to the application's [`rootTxCommand`](../interfaces/cli.md#transaction-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). - `AddQueryCommands(rootQueryCmd *cobra.Command)`: Adds modules' query commands to the application's [`rootQueryCommand`](../interfaces/cli.md#query-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). @@ -119,7 +124,7 @@ It implements the following methods: The `Manager` is a structure that holds all the `AppModule` of an application, and defines the order of execution between several key components of these modules: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L190-L198 ++++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L223-L231 The module manager is used throughout the application whenever an action on a collection of modules is required. It implements the following methods: @@ -129,9 +134,10 @@ 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)`: 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`](./querier.md). -- `InitGenesis(ctx sdk.Context, 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)`: 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. +- `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`](./querier.md). +- `RegisterQueryServices(grpcRouter grpc.Server)`: Registers all module gRPC query 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). From 0bc40be2974dfd87e2abfd954d8b1d048ca2c37e Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 7 Oct 2020 15:23:34 +0200 Subject: [PATCH 02/41] Update modules #messages doc --- docs/building-modules/messages-and-queries.md | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 30ea4f344d9f..9f41fc22f3c5 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -16,33 +16,39 @@ order: 3 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). -Defining `message`s is the responsibility of module developers. Typically, they are defined in a `./internal/types/msgs.go` file inside the module's folder. The `message`'s type 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`. +Defining `message`s is the responsibility of module developers. Typically, they are defined in 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`. -```go -// Example of a message type definition +```proto +// Example of a protobuf message definition -type MsgSubmitProposal struct { - Content Content `json:"content" yaml:"content"` - InitialDeposit sdk.Coins `json:"initial_deposit" yaml:"initial_deposit"` - Proposer sdk.AccAddress `json:"proposer" yaml:"proposer"` +message MsgSubmitProposal { + option (gogoproto.equal) = false; + + google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"]; + repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"initial_deposit\"" + ]; + string proposer = 3; } ``` 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: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L7-L29 ++++ https://github.com/cosmos/cosmos-sdk/blob/4a1b2fba43b1052ca162b3a1e0b6db6db9c26656/types/tx_msg.go#L10-L33 -It contains the following methods: +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 `nameservice` module: +See an example implementation of a `message` from the `gov` module: -+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/types/msgs.go#L10-L51 ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/gov/v1beta1/tx.proto#L15-L27 ## Queries From 916a80b55c168edcd6946bde5b880a057144f26f Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 7 Oct 2020 15:23:58 +0200 Subject: [PATCH 03/41] Fix typo --- docs/building-modules/messages-and-queries.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 9f41fc22f3c5..fd70b8c0fb31 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -16,7 +16,7 @@ order: 3 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). -Defining `message`s is the responsibility of module developers. Typically, they are defined in 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`. +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`. ```proto // Example of a protobuf message definition From 340babe1693706d502315bf70f5d94e3947637cb Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 11:06:48 +0200 Subject: [PATCH 04/41] Update message implementation example link --- docs/building-modules/messages-and-queries.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index fd70b8c0fb31..6f8641e8ab28 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -48,7 +48,7 @@ It extends `proto.Message` and contains the following methods: See an example implementation of a `message` from the `gov` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/gov/v1beta1/tx.proto#L15-L27 ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/gov/types/msgs.go#L94-L136 ## Queries From 844401d55942ea4c3e63e5cca7ab0713bfef92c9 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 12:53:39 +0200 Subject: [PATCH 05/41] Update messages-and-queries.md#queries doc --- docs/building-modules/messages-and-queries.md | 31 ++++++++++++++++--- go.sum | 1 + 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 6f8641e8ab28..d37cf3fdd213 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -54,7 +54,33 @@ See an example implementation of a `message` from the `gov` module: 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 [`querier`](./querier.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md). -Contrary to `message`s, there is usually no specific `query` object defined by module developers. Instead, the SDK takes the simpler approach of using a simple `path` to define each `query`. The `path` contains the `query` type and all the arguments needed in order to process it. For most module queries, the `path` should look like the following: +### gRPC Queries + +Starting from v0.40, developers can define queries as [Protobuf services](https://developers.google.com/protocol-buffers/docs/proto#services), by creating a `Query` service per module in `query.proto`. This service lists endpoints starting with `rpc`. + +Here's an example of such a `Query` service definition: +```proto + +// Query defines the gRPC querier service. +service Query { + // Account returns account details based on address. + rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; + } + + // Params queries all parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/params"; + } +} + +``` + +As `proto.Message`s, generated `Response` types implement by default `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). + +### Legacy Queries + +Before the introduction of Protobuf and gRPC in the SDK, there was usually no specific `query` object defined by module developers, contrary to `message`s. Instead, the 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 in order to process it. For most module queries, the `path` should look like the following: ``` queryCategory/queryRoute/queryType/arg1/arg2/... @@ -73,9 +99,6 @@ The `path` for each `query` must be defined by the module developer in the modul - [Query commands](./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 `internal/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://golang.org/pkg/fmt/#Stringer). -See an example of `query` return types from the `nameservice` module: - -+++ https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/types/querier.go#L5-L21 ## Next {hide} diff --git a/go.sum b/go.sum index fa49f96b6aba..4b9848beb78e 100644 --- a/go.sum +++ b/go.sum @@ -579,6 +579,7 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= +github.com/tendermint/tendermint v0.33.8 h1:Xxu4QhpqcomSE0iQDw1MqLgfsa8fqtPtWFJK6zZOVso= github.com/tendermint/tendermint v0.34.0-rc3 h1:d7Fsd5rdbxq4GmJ0kRfx7l7LesQM7e70f0ytWLTQ/Go= github.com/tendermint/tendermint v0.34.0-rc3/go.mod h1:BoHcEpjfpBHc1Be7RQz3AHaXFNObcDG7SNHCev6Or4g= github.com/tendermint/tendermint v0.34.0-rc4 h1:fnPyDFz9QGAU6tjExoQ8ZY63eHkzdBg5StQgDoeuK0s= From 0a8fa868e332b62f0b8904754f51abf30f5fcab0 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 13:51:23 +0200 Subject: [PATCH 06/41] Update querier.md --- docs/building-modules/messages-and-queries.md | 4 ++- docs/building-modules/querier.md | 33 +++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index d37cf3fdd213..8693526bd7e4 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -56,7 +56,7 @@ A `query` is a request for information made by end-users of applications through ### gRPC Queries -Starting from v0.40, developers can define queries as [Protobuf services](https://developers.google.com/protocol-buffers/docs/proto#services), by creating a `Query` service per module in `query.proto`. This service lists endpoints starting with `rpc`. +Starting from v0.40, the prefered way to define queries is by using [Protobuf services](https://developers.google.com/protocol-buffers/docs/proto#services). A `Query` service should be created per module in `query.proto`. This service lists endpoints starting with `rpc`. Here's an example of such a `Query` service definition: ```proto @@ -78,6 +78,8 @@ service Query { 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). + ### Legacy Queries Before the introduction of Protobuf and gRPC in the SDK, there was usually no specific `query` object defined by module developers, contrary to `message`s. Instead, the 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 in order to process it. For most module queries, the `path` should look like the following: diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 61eb1c5e10df..49783f1bc98e 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -15,18 +15,39 @@ A `Querier` designates a function that processes [`queries`](./messages-and-quer The `querier` type defined in the Cosmos SDK specifies the typical structure of a `querier` function: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/queryable.go#L6 ++++ https://github.com/cosmos/cosmos-sdk/blob/9a183ffbcc0163c8deb71c7fd5f8089a83e58f05/types/queryable.go#L9 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`, marhsalled using the application's [`codec`](../core/encoding.md). +- 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). ## Implementation of a module `querier`s -Module `querier`s are typically implemented in a `./internal/keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: +### gRPC Queriers + +When defining a Protobuf `Query` service, a `QueryServer` interface is generated for each module with all the service methods: + +```go +type QueryServer interface { + QueryBalance(context.Context, *QueryBalanceParams) (*types.Coin, error) + QueryAllBalances(context.Context, *QueryAllBalancesParams) (*QueryAllBalancesResponse, error) +} +``` + +These custom queries methods should be implemented by a module's keeper. The first parameter of these methods is a generic `context.Context`, whereas querier methods generally need an instance of `sdk.Context` to read +from the store. Therefore, the SDK provides a function `sdk.UnwrapSDKContext` to retrieve the `sdk.Context` from the provided +`context.Context`. + +Here's an example implementation for the bank module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/bank/keeper/grpc_query.go + +### Legacy Queriers + +Module legacy `querier`s are typically implemented in a `./internal/keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: ```go func NewQuerier(keeper Keeper) sdk.Querier { @@ -49,7 +70,7 @@ This simple switch returns a `querier` function specific to the type of the rece The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result. -For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/querier.go) from the nameservice tutorial. +For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/gov/keeper/querier.go) from the bank module. ## Next {hide} From 25bc99808f2e90709e80a2acca17d3d4b08803d8 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 14:22:42 +0200 Subject: [PATCH 07/41] Update handler.md --- docs/building-modules/handler.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 88f114f390bd..2e31b62576a6 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -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 @@ -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: @@ -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} From 2c7010b373260a5402232ff3cfc01a7f2e7ccca8 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 14:32:05 +0200 Subject: [PATCH 08/41] Update links in beginblock-endblock.md --- docs/building-modules/beginblock-endblock.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index fc9c93302660..b4f3abaff971 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -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} From 201d44256b9fa27201b457422f5c8a5a718cd49f Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 14:46:04 +0200 Subject: [PATCH 09/41] Update keeper.md --- docs/building-modules/keeper.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index ee373d8b567f..b354624e231e 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -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. - `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. 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. @@ -72,7 +72,7 @@ and go through the following steps: 2. Marhsall `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 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} From 546aefce91d3b44b1721ebc3c94e00f4ce124780 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 14:52:59 +0200 Subject: [PATCH 10/41] Update invariants.md --- docs/building-modules/genesis.md | 2 +- docs/building-modules/invariants.md | 4 ++-- docs/building-modules/keeper.md | 4 ++-- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/querier.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index a95064dc0369..c6f03b31cfdb 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -13,7 +13,7 @@ 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 `./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. See an example of `GenesisState` type definition from the nameservice tutorial diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index 576baa796b96..d21100cb24b5 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -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 @@ -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). diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index b354624e231e..750b5a7351ae 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -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 { @@ -38,7 +38,7 @@ For example, here is the type definition of the `keeper` from the `staking` modu 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`, that can be any of `codec.BinaryMarshaler`,`codec.JSONMarshaler` or `codec.Marshaler` based on your requirements. diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 8693526bd7e4..3909d2c98812 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -99,7 +99,7 @@ The `path` for each `query` must be defined by the module developer in the modul - A [`querier`](./querier.md), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing). - [Query commands](./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 `internal/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://golang.org/pkg/fmt/#Stringer). +- `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://golang.org/pkg/fmt/#Stringer). ## Next {hide} diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 49783f1bc98e..5100e54f15d7 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -47,7 +47,7 @@ Here's an example implementation for the bank module: ### Legacy Queriers -Module legacy `querier`s are typically implemented in a `./internal/keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: +Module legacy `querier`s are typically implemented in a `./keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: ```go func NewQuerier(keeper Keeper) sdk.Querier { From 3918392405491710df36c48883d3b536b5d98626 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 15:15:39 +0200 Subject: [PATCH 11/41] Update genesis.md --- docs/building-modules/genesis.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index c6f03b31cfdb..8ac41e85d63d 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -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 `./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 @@ -43,17 +43,17 @@ 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} From d0bac0188f8e75fe86de0183d3b49eb9dc338773 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 15:49:13 +0200 Subject: [PATCH 12/41] Update module-interfaces.md#transaction-commands --- docs/building-modules/genesis.md | 2 +- docs/building-modules/module-interfaces.md | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index 8ac41e85d63d..7314442969a2 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -57,4 +57,4 @@ See an example of `ExportGenesis` from the `auth` module. ## Next {hide} -Learn about [modules interfaces](#module-interfaces.md) {hide} \ No newline at end of file +Learn about [modules interfaces](module-interfaces.md) {hide} \ No newline at end of file diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index d2761248d94b..2fa6d6f9a4e2 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -16,13 +16,13 @@ One of the main interfaces for an application is the [command-line interface](.. ### Transaction Commands -[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. +[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions and include the name of the command. -Here is an example from the `nameservice` module: +Here is an example from the `auth` module: -+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/client/cli/tx.go#L33-L58 ++++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/client/cli/tx_sign.go#L160-L194 -This getter function creates the command for the Buy Name transaction. It does the following: +This getter function creates the command for the Sign transaction. It does the following: - **Construct the command:** Read the [Cobra Documentation](https://github.com/spf13/cobra) for details on how to create commands. - **Use:** Specifies the format of a command-line entry users should type in order to invoke this command. In this case, the user uses `buy-name` as the name of the transaction command and provides the `name` the user wishes to buy and the `amount` the user is willing to pay. @@ -30,16 +30,16 @@ This getter function creates the command for the Buy Name transaction. It does t - **Short and Long:** A description for the function is provided here. A `Short` description is expected, and `Long` can be used to provide a more detailed description when a user uses the `--help` flag to ask for more information. - **RunE:** Defines a function that can return an error, called when the command is executed. Using `Run` would do the same thing, but would not allow for errors to be returned. - **`RunE` Function Body:** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new transaction that is ready to be relayed to nodes. - - The function should first initialize a [`TxBuilder`](../core/transactions.md#txbuilder) with the application `codec`'s `TxEncoder`, as well as a new [`Context`](../interfaces/query-lifecycle.md#context) with the `codec` and `AccountDecoder`. These contexts contain all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). - - If applicable, the command's arguments are parsed. Here, the `amount` given by the user is parsed into a denomination of `coins`. - - If applicable, the `Context` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `cliCtx.getFromAddress()`. + - The function should first get the `clientCtx` with `client.GetClientContextFromCmd(cmd)` and `client.ReadTxCommandFlags(clientCtx, cmd.Flags())`.This context contains all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). + - If applicable, the command's arguments are parsed. + - If applicable, the `Context` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `clientCtx.GetFromAddress()`. - A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `Context`. The constructor function of the specific message type is called directly. It is good practice to call `ValidateBasic()` on the newly created message to run a sanity check and check for invalid arguments. - Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `GenerateOrBroadcastMsgs()`. -- **Flags.** Add any [flags](#flags) to the command. No flags were specified here, but all transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These _persistent_ [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands. +- **Flags.** Add any [flags](#flags) to the command. All transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These _persistent_ [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands. -Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the `auth` `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. +Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the `auth` `GetTxCmd()` function, which adds the `Sign`, `MultiSign`, `ValidateSignatures` and `SignBatch` commands. -+++ https://github.com/cosmos/cosmos-sdk/blob/67f6b021180c7ef0bcf25b6597a629aca27766b8/x/auth/client/cli/tx.go#L11-L25 ++++ https://github.com/cosmos/cosmos-sdk/blob/351192aa0b52a42b66ff06e81cfa7a9e26667a7f/x/auth/client/cli/tx.go#L10-L26 An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. From 0686e5e592295ad9395d60329f4fff1b52e9178a Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 16:10:37 +0200 Subject: [PATCH 13/41] Update module-interfaces.md#query-commands --- docs/building-modules/module-interfaces.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 2fa6d6f9a4e2..846b1618c64f 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -45,20 +45,18 @@ An application using this module likely adds `auth` module commands to its root ### Query Commands -[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the `nameservice` module: +[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions. Here is an example of a query command from the `auth` module: -+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/client/cli/query.go#L52-L73 ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/auth/client/cli/query.go#L76-L108 -This query returns the address that owns a particular name. The getter function does the following: +This query returns the account at a given address. The getter function does the following: -- **`codec` and `queryRoute`.** In addition to taking in the application `codec`, query command getters also take a `queryRoute` used to construct a path [Baseapp](../core/baseapp.md#query-routing) uses to route the query in the application. -- **Construct the command.** Read the [Cobra Documentation](https://github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `whois` and provide the `name` they are querying for as the only argument. +- **Construct the command.** Read the [Cobra Documentation](https://github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `account` and provide the `address` they are querying for as the only argument. - **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. - - The function should first initialize a new [`Context`](../interfaces/query-lifecycle.md#context) with the application `codec`. + - The function should first initialize a new client [`Context`](../interfaces/query-lifecycle.md#context) as described in the [previous section](#transaction-commands) - If applicable, the `Context` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `Context` parameters in this case because the query does not involve any information about the user. - - The `queryRoute` is used to construct a `path` [`baseapp`](../core/baseapp.md) will use to route the query to the appropriate [querier](./querier.md). The expected format for a query `path` is "queryCategory/queryRoute/queryType/arg1/arg2/...", where `queryCategory` can be `p2p`, `store`, `app`, or `custom`, `queryRoute` is the name of the module, and `queryType` is the name of the query type defined within the module. [`baseapp`](../core/baseapp.md) can handle each type of `queryCategory` by routing it to a module querier or retrieving results directly from stores and functions for querying peer nodes. Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). - - The `Context` `QueryWithData()` function is used to relay the query to a node and retrieve the response. It requires the `path`. It returns the result and height of the query upon success or an error if the query fails. - - The `codec` is used to nmarshal the response and the `Context` is used to print the output back to the user. + - A new `queryClient` should be initialized using the `clientCtx`. Then it can be used to call the appropriate [querier](./querier.md). + - The `clientCtx.PrintOutput` method is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the `GetTxCmd` command shown above. From 6dac9b273af11caebe319ec2838e5da90b7ab8d8 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 16:23:38 +0200 Subject: [PATCH 14/41] Update module-interfaces.md#flags --- docs/building-modules/module-interfaces.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 846b1618c64f..be0ae7fab264 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -69,9 +69,9 @@ The flags for a module are typically found in a `flags.go` file in the `./x/modu For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). -For example, the SDK `./client/flags` package includes a `PostCommands()` function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. +For example, the SDK `./client/flags` package includes a `AddTxFlagsToCmd(cmd *cobra.Command)` function that adds necessary flags to a transaction command, such as the `from` flag to indicate which address the transaction originates from. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/flags/flags.go#L85-L116 ++++ https://github.com/cosmos/cosmos-sdk/blob/cfb5fc03e5092395403d10156c0ee96e6ff1ddbe/client/flags/flags.go#L85-L112 Here is an example of how to add a flag using the `from` flag from this function. @@ -87,7 +87,7 @@ A flag can be marked as _required_ so that an error is automatically thrown if t cmd.MarkFlagRequired(FlagFrom) ``` -Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). +Since `AddTxFlagsToCmd(cmd *cobra.Command)` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). ## REST From fadd8c12351fcff43ac68a9e3deade53e6fdacd8 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 16:53:02 +0200 Subject: [PATCH 15/41] Update module-interfaces.md#rest --- docs/basics/app-anatomy.md | 2 +- docs/building-modules/module-interfaces.md | 29 ++++++++++++++-------- docs/core/transactions.md | 2 +- docs/interfaces/rest.md | 4 +-- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index fc64b772423f..ee0bb391ad8a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -197,7 +197,7 @@ Generally, the [commands related to a module](../building-modules/module-interfa #### REST -The [module's REST interface](../building-modules/module-interfaces.md#rest) lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The [module's REST interface](../building-modules/module-interfaces.md#legacy-rest) lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). 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: diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index be0ae7fab264..25d4aa9648b3 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -89,7 +89,15 @@ cmd.MarkFlagRequired(FlagFrom) Since `AddTxFlagsToCmd(cmd *cobra.Command)` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). -## REST +Similarly, there is a `AddQueryFlagsToCmd(cmd *cobra.Command)` to add common flags to a module query command. + +## gRPC +TODO + +## gRPC-gateway REST +TODO + +## Legacy REST Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](https://lunie.io). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. @@ -99,11 +107,11 @@ To support HTTP requests, the module developer needs to define possible request Request types, which define structured interactions from users, must be defined for all _transaction_ requests. Users using this method to interact with an application will send HTTP Requests with the required fields in order to trigger state changes in the application. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. -Here is an example of a request to buy a name from the `nameservice` module: +Here is an example of a request to send coins from the `bank` module: -+++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/client/rest/tx.go#L14-L19 ++++ https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/bank/client/rest/tx.go#L15-L19 -The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. +The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the argument `Amount` fields in the body. #### BaseReq @@ -114,6 +122,7 @@ The `BaseReq` includes basic information that every request needs to have, simil - `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. - `AccountNumber` is an identifier for the account. - `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +- `TimeoutHeight` allows a transaction to be rejected if it's committed at a height greater than the timeout. - `Gas` refers to how much [gas](../basics/gas-fees.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. - `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. - `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. @@ -122,17 +131,17 @@ The `BaseReq` includes basic information that every request needs to have, simil ### Request Handlers -Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`Context`](../interfaces/query-lifecycle.md#context) created in the user interaction. +Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the [client `Context`](../interfaces/query-lifecycle.md#context). -Here is an example of a request handler for the nameservice module `buyNameReq` request (the same one shown above): +Here is an example of a request handler for the `bank` module `SendReq` request (the same one shown above): -+++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/client/rest/tx.go#L21-L57 ++++ https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/bank/client/rest/tx.go#L21-L51 The request handler can be broken down as follows: -- **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively. -- **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it. -- **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`Context`](../interfaces/query-lifecycle.md#context), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. +- **Parse Request:** First, it tries to parse the argument `address` into a `AccountAddress`. Then, the request handler attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Finally, it attempts to parse `BaseReq.From` to the type `AccountAddress`. +- **Message:** Then, a [message](./messages-and-queries.md#messages) of the type `MsgSend` (defined by the module developer to trigger the state changes for this transaction) is created from the values. +- **Generate Transaction:** Finally, the HTTP `ResponseWriter`, client `Context`, request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGeneratedTxResponse` to further process the request. To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). diff --git a/docs/core/transactions.md b/docs/core/transactions.md index b5ae3bc57fb1..507f47e6b1f0 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -39,7 +39,7 @@ A transaction is created by an end-user through one of the possible [interfaces] Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/module-interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/module-interfaces.md#legacy-rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 6db69bc8bf81..00e94b1d9a9d 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -4,7 +4,7 @@ order: 4 # REST Interface -This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). {synopsis} +This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#legacy-rest). {synopsis} ## Pre-requisite Readings @@ -41,7 +41,7 @@ In order to enable the REST Server in an SDK application, the `rest.ServeCommand ## Registering Routes -To include routes for each module in an application, the CLI must have some kind of function to register routes in its REST Server. This function is called `RegisterRoutes()`, and is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules/module-interfaces.md#rest) function, application developers simply use the [Module Manager](../building-modules/module-manager.md) to call this function for each module (this is done in the [application's constructor](../basics/app-anatomy.md#constructor-function)). +To include routes for each module in an application, the CLI must have some kind of function to register routes in its REST Server. This function is called `RegisterRoutes()`, and is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules/module-interfaces.md#legacy-rest) function, application developers simply use the [Module Manager](../building-modules/module-manager.md) to call this function for each module (this is done in the [application's constructor](../basics/app-anatomy.md#constructor-function)). At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules. This is done in the `main.go` file of the CLI (typically located in `./cmd/appcli/main.go`). From 8b58c4379996ead85ff174289f661f6894ff0dc5 Mon Sep 17 00:00:00 2001 From: blushi Date: Thu, 8 Oct 2020 16:55:18 +0200 Subject: [PATCH 16/41] Update structure.md --- docs/building-modules/structure.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index 15e9c4bcede2..9110bb0d71e6 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -27,6 +27,7 @@ x/{module} │   ├── keeper.go │   ├── ... │   └── querier.go +│   └── grpc_query.go ├── types │ ├── codec.go │ ├── errors.go @@ -40,6 +41,8 @@ x/{module} │ ├── types.proto │ ├── ... │ └── querier.go +│ └── query.pb.go +│ └── genesis.pb.go ├── simulation │   ├── decoder.go │   ├── genesis.go From 2fed1300172b5403243ad221bab012e7c149e89a Mon Sep 17 00:00:00 2001 From: blushi Date: Fri, 9 Oct 2020 14:44:45 +0200 Subject: [PATCH 17/41] Update module-interfaces.md#grpc --- docs/building-modules/module-interfaces.md | 42 +++++++++++++++++++--- docs/building-modules/module-manager.md | 4 +-- docs/building-modules/querier.md | 2 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 25d4aa9648b3..fc117bee4917 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -55,7 +55,7 @@ This query returns the account at a given address. The getter function does the - **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. - The function should first initialize a new client [`Context`](../interfaces/query-lifecycle.md#context) as described in the [previous section](#transaction-commands) - If applicable, the `Context` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `Context` parameters in this case because the query does not involve any information about the user. - - A new `queryClient` should be initialized using the `clientCtx`. Then it can be used to call the appropriate [querier](./querier.md). + - A new `queryClient` should be initialized using `NewQueryClient(clientCtx)`, this method being generated from `query.proto`. Then it can be used to call the appropriate [querier](./querier.md). - The `clientCtx.PrintOutput` method is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. @@ -92,14 +92,48 @@ Since `AddTxFlagsToCmd(cmd *cobra.Command)` includes all of the basic flags requ Similarly, there is a `AddQueryFlagsToCmd(cmd *cobra.Command)` to add common flags to a module query command. ## gRPC -TODO + +[gRPC](https://grpc.io/) is the prefered way for external clients like wallets and exchanges to interact with a node. + +In addition to providing an ABCI query pathway, modules [custom queries](./messages-and-queries.md#grpc-queries) can provide a GRPC proxy server that routes requests in the GRPC protocol to ABCI query requests under the hood. + +In order to do that, module should implement `RegisterGRPCRoutes(clientCtx client.Context, mux *runtime.ServeMux)` on `AppModuleBasic` to wire the client gRPC requests to the correct handler inside the module. + +Here's an example from the `auth` module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/module.go#L69-L72 ## gRPC-gateway REST -TODO + +Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](https://lunie.io). Thus, application developers can also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. + +[grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) translates REST calls into gRPC calls, which might be useful for clients that do not use gRPC. + +Modules that want to expose REST queries should add `google.api.http` annotations to their `rpc` methods, such as in the example below from the `auth` module: + +```proto + +// Query defines the gRPC querier service. +service Query{ + // Account returns account details based on address. + rpc Account (QueryAccountRequest) returns (QueryAccountResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; + } + + // Params queries all parameters. + rpc Params (QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/params"; + } +} +``` + +The SDK provides CLI commands for apps to start GRPC gateway either in a separate process or the same process as the ABCI app, as well as provides a command for generating grpc-gateway proxy `.proto` files and Swagger definition files. ## Legacy REST -Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](https://lunie.io). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. +Developers may choose to keep using legacy REST endpoints for backward compatibility, although the recommended way is to use [gRPC](#grpc) and [gRPC-gateway](#grpc-gateway-rest). + +With this implementation, module developers need to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. To support HTTP requests, the module developer needs to define possible request types, how to handle them, and provide a way to register them with a provided router. diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 97217601a100..2dd801101415 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -39,7 +39,7 @@ Let us go through the methods: - `DefaultGenesis(codec.JSONMarshaler)`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. - `ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. - `RegisterRESTRoutes(client.Context, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. -- `RegisterGRPCRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC Gateway routes for the module. +- `RegisterGRPCRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC routes for the module. - `GetTxCmd()`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. - `GetQueryCmd()`: Return the root [`query` command](./module-interfaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. @@ -116,7 +116,7 @@ It implements the following methods: - `DefaultGenesis(cdc codec.JSONMarshaler)`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis(cdc codec.JSONMarshaler)`](./genesis.md#defaultgenesis) function of each module. It is used to construct a default genesis file for the application. - `ValidateGenesis(cdc codec.JSONMarshaler, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`](./genesis.md#validategenesis) function of each module. - `RegisterRESTRoutes(ctx client.Context, rtr *mux.Router)`: Registers REST routes for modules by calling the [`RegisterRESTRoutes`](./module-interfaces.md#register-routes) function of each module. This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). -- `RegisterGRPCRoutes(clientCtx client.Context, rtr *runtime.ServeMux)`: Registers gRPC Gateway routes for modules. +- `RegisterGRPCRoutes(clientCtx client.Context, rtr *runtime.ServeMux)`: Registers gRPC routes for modules. - `AddTxCommands(rootTxCmd *cobra.Command)`: Adds modules' transaction commands to the application's [`rootTxCommand`](../interfaces/cli.md#transaction-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). - `AddQueryCommands(rootQueryCmd *cobra.Command)`: Adds modules' query commands to the application's [`rootQueryCommand`](../interfaces/cli.md#query-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 5100e54f15d7..0df692c454e7 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -37,7 +37,7 @@ type QueryServer interface { } ``` -These custom queries methods should be implemented by a module's keeper. The first parameter of these methods is a generic `context.Context`, whereas querier methods generally need an instance of `sdk.Context` to read +These custom queries methods should be implemented by a module's keeper, typically in `./keeper/grpc_query.go`. The first parameter of these methods is a generic `context.Context`, whereas querier methods generally need an instance of `sdk.Context` to read from the store. Therefore, the SDK provides a function `sdk.UnwrapSDKContext` to retrieve the `sdk.Context` from the provided `context.Context`. From 289e10e57eafc12db554d27630cc91830d5a679f Mon Sep 17 00:00:00 2001 From: blushi Date: Fri, 9 Oct 2020 14:58:09 +0200 Subject: [PATCH 18/41] Update errors.md --- docs/building-modules/errors.md | 2 +- docs/building-modules/module-interfaces.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/building-modules/errors.md b/docs/building-modules/errors.md index 5e3c31bca0d8..06ee2de01e46 100644 --- a/docs/building-modules/errors.md +++ b/docs/building-modules/errors.md @@ -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/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/distribution/keeper/querier.go#L62-L80 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`. diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index fc117bee4917..c4b719112a0a 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -127,7 +127,7 @@ service Query{ } ``` -The SDK provides CLI commands for apps to start GRPC gateway either in a separate process or the same process as the ABCI app, as well as provides a command for generating grpc-gateway proxy `.proto` files and Swagger definition files. +The SDK provides CLI commands for apps to start GRPC gateway either in a separate process or the same process as the ABCI app, as well as provides a command for generating grpc-gateway proxy `.proto` files and Swagger definition files (`protoc-gen-swagger`). ## Legacy REST From d0d4b34170b5b72837e47a4c5f5346497f468fa8 Mon Sep 17 00:00:00 2001 From: blushi Date: Fri, 9 Oct 2020 17:16:56 +0200 Subject: [PATCH 19/41] Update module-interfaces.md#grpc-gateway-rest --- docs/building-modules/module-interfaces.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c4b719112a0a..72d8736f12bc 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -127,7 +127,9 @@ service Query{ } ``` -The SDK provides CLI commands for apps to start GRPC gateway either in a separate process or the same process as the ABCI app, as well as provides a command for generating grpc-gateway proxy `.proto` files and Swagger definition files (`protoc-gen-swagger`). +gRPC gateway is started in-process along with the application and Tendermint. + +The SDK provides a command for generating [Swagger](https://swagger.io/) documentation (`protoc-gen-swagger`). ## Legacy REST From 0d26688685e209d6b152d2070626b8b148131124 Mon Sep 17 00:00:00 2001 From: blushi Date: Fri, 9 Oct 2020 17:45:31 +0200 Subject: [PATCH 20/41] Add more info on swagger --- docs/building-modules/module-interfaces.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 72d8736f12bc..af08b5585cbc 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -129,7 +129,7 @@ service Query{ gRPC gateway is started in-process along with the application and Tendermint. -The SDK provides a command for generating [Swagger](https://swagger.io/) documentation (`protoc-gen-swagger`). +The SDK provides a command for generating [Swagger](https://swagger.io/) documentation (`protoc-gen-swagger`). Setting `swagger` in `app.toml` defines if swagger documentation should be automatically registered. ## Legacy REST From fa8a9cf8a9ac64443af090fd178f53ad0498fd16 Mon Sep 17 00:00:00 2001 From: blushi Date: Tue, 13 Oct 2020 14:10:42 +0200 Subject: [PATCH 21/41] Address comments --- docs/building-modules/messages-and-queries.md | 34 +++---------------- docs/building-modules/structure.md | 2 +- 2 files changed, 5 insertions(+), 31 deletions(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 3909d2c98812..e087bd130db6 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -18,21 +18,9 @@ When a transaction is relayed from the underlying consensus engine to the SDK ap 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`. -```proto -// Example of a protobuf message definition - -message MsgSubmitProposal { - option (gogoproto.equal) = false; - - google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"]; - repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"initial_deposit\"" - ]; - string proposer = 3; -} -``` +Here's an example of a protobuf message definition: + ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/gov/v1beta1/tx.proto#L15-L27 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: @@ -59,22 +47,8 @@ A `query` is a request for information made by end-users of applications through Starting from v0.40, the prefered way to define queries is by using [Protobuf services](https://developers.google.com/protocol-buffers/docs/proto#services). A `Query` service should be created per module in `query.proto`. This service lists endpoints starting with `rpc`. Here's an example of such a `Query` service definition: -```proto - -// Query defines the gRPC querier service. -service Query { - // Account returns account details based on address. - rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; - } - // Params queries all parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/params"; - } -} - -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/auth/v1beta1/query.proto#L12-L23 As `proto.Message`s, generated `Response` types implement by default `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index 9110bb0d71e6..cdc2c6983c8c 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -37,10 +37,10 @@ x/{module} │ ├── keys.go │ ├── msgs.go │ ├── params.go -│ ├── types.pb.go │ ├── types.proto │ ├── ... │ └── querier.go +│ └── {module_name}.pb.go │ └── query.pb.go │ └── genesis.pb.go ├── simulation From 84a520d325c596ba1904c53b7a0de4f2b747273a Mon Sep 17 00:00:00 2001 From: blushi Date: Tue, 13 Oct 2020 14:17:05 +0200 Subject: [PATCH 22/41] Fix go.sum --- go.sum | 1 - 1 file changed, 1 deletion(-) diff --git a/go.sum b/go.sum index db7bc2c8509f..b395dd5f6653 100644 --- a/go.sum +++ b/go.sum @@ -579,7 +579,6 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.33.8 h1:Xxu4QhpqcomSE0iQDw1MqLgfsa8fqtPtWFJK6zZOVso= github.com/tendermint/tendermint v0.34.0-rc3 h1:d7Fsd5rdbxq4GmJ0kRfx7l7LesQM7e70f0ytWLTQ/Go= github.com/tendermint/tendermint v0.34.0-rc3/go.mod h1:BoHcEpjfpBHc1Be7RQz3AHaXFNObcDG7SNHCev6Or4g= github.com/tendermint/tendermint v0.34.0-rc4.0.20201005135527-d7d0ffea13c6 h1:gqZ0WDpDYgMm/iaiMEXvI1nt/GoWCuwtBomVpUMiAIs= From d86adc223a0b9f78b7236d9288f75929c3bc38ee Mon Sep 17 00:00:00 2001 From: blushi Date: Tue, 13 Oct 2020 16:42:03 +0200 Subject: [PATCH 23/41] Fix app-anatomy.md --- docs/basics/app-anatomy.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 7f523a07f34d..74b32a6d466b 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -228,8 +228,6 @@ Each module can expose gRPC endpoints, called [service methods](https://grpc.io/ #### gRPC-gateway REST Endpoints -The [module's REST interface](../building-modules/module-interfaces.md#legacy-rest) lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - Some external clients may not wish to use gRPC. The SDK provides in this case a gRPC gateway service, which exposes each gRPC service as a correspoding REST endpoint. Please refer to the [grpc-gateway](https://grpc-ecosystem.github.io/grpc-gateway/) documentation to learn more. The REST endpoints are defined in the Protobuf files, along with the gRPC services, using Protobuf annotations. Modules that want to expose REST queries should add `google.api.http` annotations to their `rpc` methods. By default, all REST endpoints defined in the SDK have an URL starting with the `/cosmos/` prefix. From 5a69a8c9db6a7148a4d9369042f00bb341d0b6a8 Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Tue, 13 Oct 2020 16:56:06 +0200 Subject: [PATCH 24/41] Update docs/building-modules/module-interfaces.md Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- docs/building-modules/module-interfaces.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index af08b5585cbc..dfd4e0a43df0 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -30,7 +30,7 @@ This getter function creates the command for the Sign transaction. It does the f - **Short and Long:** A description for the function is provided here. A `Short` description is expected, and `Long` can be used to provide a more detailed description when a user uses the `--help` flag to ask for more information. - **RunE:** Defines a function that can return an error, called when the command is executed. Using `Run` would do the same thing, but would not allow for errors to be returned. - **`RunE` Function Body:** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new transaction that is ready to be relayed to nodes. - - The function should first get the `clientCtx` with `client.GetClientContextFromCmd(cmd)` and `client.ReadTxCommandFlags(clientCtx, cmd.Flags())`.This context contains all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). + - The function should first get the `clientCtx` with `client.GetClientContextFromCmd(cmd)` and `client.ReadTxCommandFlags(clientCtx, cmd.Flags())`. This context contains all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). - If applicable, the command's arguments are parsed. - If applicable, the `Context` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `clientCtx.GetFromAddress()`. - A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `Context`. The constructor function of the specific message type is called directly. It is good practice to call `ValidateBasic()` on the newly created message to run a sanity check and check for invalid arguments. From cd56931d1843bbc03fdc8eb99c188a818f66533f Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Tue, 13 Oct 2020 16:56:51 +0200 Subject: [PATCH 25/41] Update docs/building-modules/querier.md Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- docs/building-modules/querier.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 0df692c454e7..bd9b9cf14a5d 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -24,7 +24,7 @@ Let us break it down: - 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). -## Implementation of a module `querier`s +## Implementation of a module query service ### gRPC Queriers From 5e02309e7b70004b17dbc71096b8b47c528530ce Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Tue, 13 Oct 2020 16:57:11 +0200 Subject: [PATCH 26/41] Update docs/building-modules/querier.md Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- docs/building-modules/querier.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index bd9b9cf14a5d..a8ccd43b26bd 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -26,7 +26,7 @@ Let us break it down: ## Implementation of a module query service -### gRPC Queriers +### gRPC Service When defining a Protobuf `Query` service, a `QueryServer` interface is generated for each module with all the service methods: From 7bbc9b87065f5ab47a82633854f401d68484de9a Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Tue, 13 Oct 2020 16:58:39 +0200 Subject: [PATCH 27/41] Update docs/building-modules/module-interfaces.md Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- docs/building-modules/module-interfaces.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index dfd4e0a43df0..4b780150346b 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -22,7 +22,7 @@ Here is an example from the `auth` module: +++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/client/cli/tx_sign.go#L160-L194 -This getter function creates the command for the Sign transaction. It does the following: +This getter function creates the command for the `Sign` transaction. It does the following: - **Construct the command:** Read the [Cobra Documentation](https://github.com/spf13/cobra) for details on how to create commands. - **Use:** Specifies the format of a command-line entry users should type in order to invoke this command. In this case, the user uses `buy-name` as the name of the transaction command and provides the `name` the user wishes to buy and the `amount` the user is willing to pay. From 0635919cf503bbcc7d5f3990ed99b99f6832b74f Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Tue, 13 Oct 2020 16:59:46 +0200 Subject: [PATCH 28/41] Update docs/building-modules/module-interfaces.md Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- docs/building-modules/module-interfaces.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 4b780150346b..ae203eef56ac 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -112,7 +112,6 @@ Applications typically support web services that use HTTP requests (e.g. a web w Modules that want to expose REST queries should add `google.api.http` annotations to their `rpc` methods, such as in the example below from the `auth` module: ```proto - // Query defines the gRPC querier service. service Query{ // Account returns account details based on address. From b19c8e1c751f4826db9e313a3013020db3e262d7 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 09:50:55 +0200 Subject: [PATCH 29/41] Address part of review comments --- docs/building-modules/errors.md | 2 +- docs/building-modules/keeper.md | 6 +++--- docs/building-modules/module-interfaces.md | 10 +++++----- docs/building-modules/module-manager.md | 2 +- docs/building-modules/querier.md | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/building-modules/errors.md b/docs/building-modules/errors.md index 06ee2de01e46..3b6d90535e45 100644 --- a/docs/building-modules/errors.md +++ b/docs/building-modules/errors.md @@ -38,7 +38,7 @@ execution. Example: -+++ https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/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`. diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 750b5a7351ae..1fecb6152146 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -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. @@ -68,8 +68,8 @@ 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`. 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/3bafd8255a502e5a9cee07391cf8261538245dfd/x/staking/keeper/keeper.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index ae203eef56ac..cf47a567bfcf 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -24,7 +24,7 @@ Here is an example from the `auth` module: This getter function creates the command for the `Sign` transaction. It does the following: -- **Construct the command:** Read the [Cobra Documentation](https://github.com/spf13/cobra) for details on how to create commands. +- **Construct the command:** Read the [Cobra Documentation](https://godoc.org/github.com/spf13/cobra) for details on how to create commands. - **Use:** Specifies the format of a command-line entry users should type in order to invoke this command. In this case, the user uses `buy-name` as the name of the transaction command and provides the `name` the user wishes to buy and the `amount` the user is willing to pay. - **Args:** The number of arguments the user provides, in this case exactly two: `name` and `amount`. - **Short and Long:** A description for the function is provided here. A `Short` description is expected, and `Long` can be used to provide a more detailed description when a user uses the `--help` flag to ask for more information. @@ -51,7 +51,7 @@ An application using this module likely adds `auth` module commands to its root This query returns the account at a given address. The getter function does the following: -- **Construct the command.** Read the [Cobra Documentation](https://github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `account` and provide the `address` they are querying for as the only argument. +- **Construct the command.** Read the [Cobra Documentation](https://godoc.org/github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `account` and provide the `address` they are querying for as the only argument. - **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. - The function should first initialize a new client [`Context`](../interfaces/query-lifecycle.md#context) as described in the [previous section](#transaction-commands) - If applicable, the `Context` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `Context` parameters in this case because the query does not involve any information about the user. @@ -67,7 +67,7 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as _required_ so that an error is thrown if the user does not provide values for them. -For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). +For full details on flags, visit the [Cobra Documentation](https://godoc.org/github.com/spf13/cobra). For example, the SDK `./client/flags` package includes a `AddTxFlagsToCmd(cmd *cobra.Command)` function that adds necessary flags to a transaction command, such as the `from` flag to indicate which address the transaction originates from. @@ -126,13 +126,13 @@ service Query{ } ``` -gRPC gateway is started in-process along with the application and Tendermint. +gRPC gateway is started in-process along with the application and Tendermint. It can be enabled or disabled by setting gRPC Configuration `enable` in `app.toml`. The SDK provides a command for generating [Swagger](https://swagger.io/) documentation (`protoc-gen-swagger`). Setting `swagger` in `app.toml` defines if swagger documentation should be automatically registered. ## Legacy REST -Developers may choose to keep using legacy REST endpoints for backward compatibility, although the recommended way is to use [gRPC](#grpc) and [gRPC-gateway](#grpc-gateway-rest). +Legacy REST endpoints will be deprecated. But developers may choose to keep using legacy REST endpoints for backward compatibility, although the recommended way is to use [gRPC](#grpc) and [gRPC-gateway](#grpc-gateway-rest). With this implementation, module developers need to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 2dd801101415..a9130ef740ff 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -62,7 +62,7 @@ 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/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L160-L182 ++++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/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. diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index a8ccd43b26bd..464f01f888c0 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -13,7 +13,7 @@ A `Querier` designates a function that processes [`queries`](./messages-and-quer ## `Querier` type -The `querier` type defined in the Cosmos SDK specifies the typical structure of a `querier` function: +The `querier` type defined in the Cosmos SDK will be deprecated in favor of [gRPC Services](#grpc-service). It specifies the typical structure of a `querier` function: +++ https://github.com/cosmos/cosmos-sdk/blob/9a183ffbcc0163c8deb71c7fd5f8089a83e58f05/types/queryable.go#L9 From 1ea1ea8559604d5c0aa13951b3016967438da2a5 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 10:02:22 +0200 Subject: [PATCH 30/41] Update old ref of RegisterQueryService --- docs/basics/app-anatomy.md | 2 +- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/module-manager.md | 4 ++-- types/module/module.go | 4 ++-- x/auth/module.go | 2 +- x/auth/vesting/module.go | 2 +- x/bank/module.go | 2 +- x/capability/module.go | 2 +- x/crisis/module.go | 2 +- x/distribution/module.go | 2 +- x/evidence/module.go | 2 +- x/gov/module.go | 2 +- x/ibc/applications/transfer/module.go | 2 +- x/ibc/core/module.go | 2 +- x/ibc/testing/mock/mock.go | 2 +- x/mint/module.go | 2 +- x/params/module.go | 2 +- x/slashing/module.go | 2 +- x/staking/module.go | 2 +- x/upgrade/module.go | 2 +- 20 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 74b32a6d466b..a69ae50529f4 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -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 diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index e087bd130db6..40694a84464c 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -52,7 +52,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 `RegisterServices` method from the [`AppModule` interface](./module-manager.md#appmodule). ### Legacy Queries diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index a9130ef740ff..b72fd37fb705 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -72,7 +72,7 @@ Let us go through the methods of `AppModule`: - `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`](./querier.md) 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. @@ -135,7 +135,7 @@ The module manager is used throughout the application whenever an action on a co - `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`](./querier.md). -- `RegisterQueryServices(grpcRouter grpc.Server)`: Registers all module gRPC query services. +- `RegisterServices(cfg Configurator)`: Registers all module gRPC query 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. diff --git a/types/module/module.go b/types/module/module.go index ec9c1c77b5d3..f149fd5f3739 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -166,10 +166,10 @@ type AppModule interface { // routes 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 diff --git a/x/auth/module.go b/x/auth/module.go index 21e43bef262b..85971d18651f 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -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) diff --git a/x/auth/vesting/module.go b/x/auth/vesting/module.go index b4997d60e4bd..bea4d3946867 100644 --- a/x/auth/vesting/module.go +++ b/x/auth/vesting/module.go @@ -100,7 +100,7 @@ func (am AppModule) Route() sdk.Route { // functionality. func (AppModule) QuerierRoute() string { return "" } -// RegisterQueryService performs a no-op. +// RegisterServices performs a no-op. func (am AppModule) RegisterServices(_ module.Configurator) {} // LegacyQuerierHandler performs a no-op. diff --git a/x/bank/module.go b/x/bank/module.go index 1b3d68f4607d..02615c464820 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -94,7 +94,7 @@ type AppModule struct { accountKeeper types.AccountKeeper } -// 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) diff --git a/x/capability/module.go b/x/capability/module.go index cc1d6272eb0f..1e84a6f13cca 100644 --- a/x/capability/module.go +++ b/x/capability/module.go @@ -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) {} diff --git a/x/crisis/module.go b/x/crisis/module.go index fdc2ffb03d6f..67a074bd7165 100644 --- a/x/crisis/module.go +++ b/x/crisis/module.go @@ -112,7 +112,7 @@ func (AppModule) QuerierRoute() string { return "" } // LegacyQuerierHandler returns no sdk.Querier. func (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) {} diff --git a/x/distribution/module.go b/x/distribution/module.go index 9c53d5619170..addc416f2a10 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -139,7 +139,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) diff --git a/x/evidence/module.go b/x/evidence/module.go index 1ac32c2148b7..620db7f6eee7 100644 --- a/x/evidence/module.go +++ b/x/evidence/module.go @@ -148,7 +148,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) diff --git a/x/gov/module.go b/x/gov/module.go index 31c0e5c05d80..1187fedc4680 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -155,7 +155,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) diff --git a/x/ibc/applications/transfer/module.go b/x/ibc/applications/transfer/module.go index 4d73f693cd2a..b92aaa676bd4 100644 --- a/x/ibc/applications/transfer/module.go +++ b/x/ibc/applications/transfer/module.go @@ -120,7 +120,7 @@ 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(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), am.keeper) diff --git a/x/ibc/core/module.go b/x/ibc/core/module.go index 35a734ccf959..032ee755a751 100644 --- a/x/ibc/core/module.go +++ b/x/ibc/core/module.go @@ -130,7 +130,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return nil } -// RegisterQueryService registers the gRPC query service for the ibc module. +// RegisterServices registers the gRPC query service for the ibc module. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryService(cfg.QueryServer(), am.keeper) } diff --git a/x/ibc/testing/mock/mock.go b/x/ibc/testing/mock/mock.go index 89ed2a4dd468..25bc5e953ede 100644 --- a/x/ibc/testing/mock/mock.go +++ b/x/ibc/testing/mock/mock.go @@ -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. diff --git a/x/mint/module.go b/x/mint/module.go index 0a29598add2c..c9ed5f01e8ff 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -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) diff --git a/x/params/module.go b/x/params/module.go index b95f76947ddb..2dd7967b16aa 100644 --- a/x/params/module.go +++ b/x/params/module.go @@ -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) diff --git a/x/slashing/module.go b/x/slashing/module.go index f74c4a84dfd2..e644b87a1cd6 100644 --- a/x/slashing/module.go +++ b/x/slashing/module.go @@ -137,7 +137,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) diff --git a/x/staking/module.go b/x/staking/module.go index 6a344265b74a..860d717e64f1 100644 --- a/x/staking/module.go +++ b/x/staking/module.go @@ -133,7 +133,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) { querier := keeper.Querier{Keeper: am.keeper} diff --git a/x/upgrade/module.go b/x/upgrade/module.go index df5e23a2f4f2..bf467340f201 100644 --- a/x/upgrade/module.go +++ b/x/upgrade/module.go @@ -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) From 56f9e10f8623ce76605eb1f1acebb14ff30ab5ae Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 10:06:49 +0200 Subject: [PATCH 31/41] Add example code for Manager --- docs/building-modules/module-manager.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index b72fd37fb705..c252937d4dc2 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -141,6 +141,10 @@ The module manager is used throughout the application whenever an action on a co - `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: + ++++ https://github.com/cosmos/cosmos-sdk/blob/2323f1ac0e9a69a0da6b43693061036134193464/simapp/app.go#L315-L362 + ## Next {hide} Learn more about [`message`s and `queries`](./messages-and-queries.md) {hide} From bbd52c17895c1234892c7bbf284ac8e30d79a631 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 10:29:19 +0200 Subject: [PATCH 32/41] Update queriers.md to query-services.md and refs --- docs/basics/app-anatomy.md | 2 +- docs/building-modules/README.md | 2 +- docs/building-modules/handler.md | 2 +- docs/building-modules/intro.md | 2 +- docs/building-modules/messages-and-queries.md | 6 +- docs/building-modules/module-interfaces.md | 4 +- docs/building-modules/module-manager.md | 4 +- docs/building-modules/querier.md | 77 ------------------- docs/core/baseapp.md | 2 +- docs/core/encoding.md | 2 +- docs/interfaces/query-lifecycle.md | 6 +- 11 files changed, 16 insertions(+), 93 deletions(-) delete mode 100644 docs/building-modules/querier.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index a69ae50529f4..ffd56017c1b7 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -182,7 +182,7 @@ Finally, each module should also implement the `RegisterServices` method as part 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`: +[`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 diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md index 12dd140f89ad..43b8638ca96b 100644 --- a/docs/building-modules/README.md +++ b/docs/building-modules/README.md @@ -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) diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 2e31b62576a6..e394cb5ed207 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -81,4 +81,4 @@ For a deeper look at `handler`s, see this [example implementation of a `handler` ## Next {hide} -Learn about [queriers](./querier.md) {hide} +Learn about [query services](./query-services.md) {hide} diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 99a9a57caafd..e0c94d60ba4a 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -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). diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 40694a84464c..45aa11cbb9c4 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -40,7 +40,7 @@ See an example implementation of a `message` from the `gov` module: ## 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 [`querier`](./querier.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 @@ -66,12 +66,12 @@ 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. -- `queryType` is used by the module's [`querier`](./querier.md) to map the `query` to the appropriate `querier function` within 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`. The `path` for each `query` must be defined by the module developer in the module's [command-line interface file](./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`](./querier.md), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing). +- A [`querier`](./query-services.md#legacy-queriers), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing). - [Query commands](./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://golang.org/pkg/fmt/#Stringer). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index cf47a567bfcf..1c8dcdbce26e 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -55,7 +55,7 @@ This query returns the account at a given address. The getter function does the - **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. - The function should first initialize a new client [`Context`](../interfaces/query-lifecycle.md#context) as described in the [previous section](#transaction-commands) - If applicable, the `Context` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `Context` parameters in this case because the query does not involve any information about the user. - - A new `queryClient` should be initialized using `NewQueryClient(clientCtx)`, this method being generated from `query.proto`. Then it can be used to call the appropriate [querier](./querier.md). + - A new `queryClient` should be initialized using `NewQueryClient(clientCtx)`, this method being generated from `query.proto`. Then it can be used to call the appropriate [query](./messages-and-queries.md#grpc-queries). - The `clientCtx.PrintOutput` method is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. @@ -67,7 +67,7 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as _required_ so that an error is thrown if the user does not provide values for them. -For full details on flags, visit the [Cobra Documentation](https://godoc.org/github.com/spf13/cobra). +For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). For example, the SDK `./client/flags` package includes a `AddTxFlagsToCmd(cmd *cobra.Command)` function that adds necessary flags to a transaction command, such as the `from` flag to indicate which address the transaction originates from. diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index c252937d4dc2..ae31a6329057 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -71,7 +71,7 @@ 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). -- `LegacyQuerierHandler(*codec.LegacyAmino)` (deprecated): Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`. +- `LegacyQuerierHandler(*codec.LegacyAmino)` (deprecated): Returns a [`querier`](./query-services.md#legacy-queriers) given the query `path`, in order to process the `query`. - `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. @@ -134,7 +134,7 @@ 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`](./querier.md). +- `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). - `RegisterServices(cfg Configurator)`: Registers all module gRPC query 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. diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md deleted file mode 100644 index 464f01f888c0..000000000000 --- a/docs/building-modules/querier.md +++ /dev/null @@ -1,77 +0,0 @@ - - -# Queriers - -A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s 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 - -- [Module Manager](./module-manager.md) {prereq} -- [Messages and Queries](./messages-and-queries.md) {prereq} - -## `Querier` type - -The `querier` type defined in the Cosmos SDK will be deprecated in favor of [gRPC Services](#grpc-service). It specifies the typical structure of a `querier` function: - -+++ https://github.com/cosmos/cosmos-sdk/blob/9a183ffbcc0163c8deb71c7fd5f8089a83e58f05/types/queryable.go#L9 - -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). - -## Implementation of a module query service - -### gRPC Service - -When defining a Protobuf `Query` service, a `QueryServer` interface is generated for each module with all the service methods: - -```go -type QueryServer interface { - QueryBalance(context.Context, *QueryBalanceParams) (*types.Coin, error) - QueryAllBalances(context.Context, *QueryAllBalancesParams) (*QueryAllBalancesResponse, error) -} -``` - -These custom queries methods should be implemented by a module's keeper, typically in `./keeper/grpc_query.go`. The first parameter of these methods is a generic `context.Context`, whereas querier methods generally need an instance of `sdk.Context` to read -from the store. Therefore, the SDK provides a function `sdk.UnwrapSDKContext` to retrieve the `sdk.Context` from the provided -`context.Context`. - -Here's an example implementation for the bank module: - -+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/bank/keeper/grpc_query.go - -### Legacy Queriers - -Module legacy `querier`s are typically implemented in a `./keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: - -```go -func NewQuerier(keeper Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { - switch path[0] { - case QueryType1: - return queryType1(ctx, path[1:], req, keeper) - - case QueryType2: - return queryType2(ctx, path[1:], req, keeper) - - default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) - } - } -} -``` - -This simple switch returns a `querier` function specific to the type of the received `query`. At this point of the [query lifecycle](../interfaces/query-lifecycle.md), the first element of the `path` (`path[0]`) contains the type of the query. The following elements are either empty or contain arguments needed to process the query. - -The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result. - -For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/gov/keeper/querier.go) from the bank module. - -## Next {hide} - -Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md) {hide} diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index beaba8b5e8b3..c4ea2c9faf08 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -200,7 +200,7 @@ The application's `router` is initilalized with all the routes using the applica ### Query Routing -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a `query router`, which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query). +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/query-services.md). To do so, `baseapp` holds a `query router`, which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query). Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 2e0012407fab..69059b39c6a0 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -80,7 +80,7 @@ Modules are encouraged to utilize Protobuf encoding for their respective types. Protobuf types can be defined to encode: - state - [`Msg`s](../building-modules/messages-and-queries.md#messages) - - [queries](../building-modules/querier.md) + - [Query services](../building-modules/query-services.md) - [genesis](../building-modules/genesis.md) **Naming and conventions** diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 26fe4df978fe..ae4a2e800b50 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -107,7 +107,7 @@ params := types.NewQueryDelegatorParams(delegatorAddr) #### Query Route Creation -Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application `baseapp`, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [`baseapp`](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application `baseapp`, then module, then [querier](../building-modules/query-services.md#legacy-queriers), and each will understand the `route` and pass it to the appropriate next step. [`baseapp`](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. Here is what the code looks like: @@ -133,9 +133,9 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation ## Application Query Handling -When a query is received by the full-node after it has been relayed from the underlying consensus engine, it is now being handled within an environment that understands application-specific types and has a copy of the state. [`baseapp`](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by `baseapp` or the stores, but the `custom` query type requires `baseapp` to route the query to a module's [querier](../building-modules/querier.md). +When a query is received by the full-node after it has been relayed from the underlying consensus engine, it is now being handled within an environment that understands application-specific types and has a copy of the state. [`baseapp`](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by `baseapp` or the stores, but the `custom` query type requires `baseapp` to route the query to a module's [query service](../building-modules/query-services.md). -Since `Query` is a custom query type from the `staking` module, `baseapp` first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier, and routes the query to the module. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md). +Since `Query` is a custom query type from the `staking` module, `baseapp` first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier, and routes the query to the module. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about query services [here](../building-modules/query-services.md). Once a result is received from the querier, `baseapp` begins the process of returning a response to the user. From 447ebb7129e6429560f72d8961e135f0453513c0 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 11:35:23 +0200 Subject: [PATCH 33/41] Add new query-services.md --- docs/building-modules/query-services.md | 77 +++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 docs/building-modules/query-services.md diff --git a/docs/building-modules/query-services.md b/docs/building-modules/query-services.md new file mode 100644 index 000000000000..fa7a6e0bae4f --- /dev/null +++ b/docs/building-modules/query-services.md @@ -0,0 +1,77 @@ + + +# 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} + +## Pre-requisite Readings + +- [Module Manager](./module-manager.md) {prereq} +- [Messages and Queries](./messages-and-queries.md) {prereq} + +## `Querier` type + +The `querier` type defined in the Cosmos SDK will be deprecated in favor of [gRPC Services](#grpc-service). It specifies the typical structure of a `querier` function: + ++++ https://github.com/cosmos/cosmos-sdk/blob/9a183ffbcc0163c8deb71c7fd5f8089a83e58f05/types/queryable.go#L9 + +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). + +## Implementation of a module query service + +### gRPC Service + +When defining a Protobuf `Query` service, a `QueryServer` interface is generated for each module with all the service methods: + +```go +type QueryServer interface { + QueryBalance(context.Context, *QueryBalanceParams) (*types.Coin, error) + QueryAllBalances(context.Context, *QueryAllBalancesParams) (*QueryAllBalancesResponse, error) +} +``` + +These custom queries methods should be implemented by a module's keeper, typically in `./keeper/grpc_query.go`. The first parameter of these methods is a generic `context.Context`, whereas querier methods generally need an instance of `sdk.Context` to read +from the store. Therefore, the SDK provides a function `sdk.UnwrapSDKContext` to retrieve the `sdk.Context` from the provided +`context.Context`. + +Here's an example implementation for the bank module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/bank/keeper/grpc_query.go + +### Legacy Queriers + +Module legacy `querier`s are typically implemented in a `./keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: + +```go +func NewQuerier(keeper Keeper) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { + switch path[0] { + case QueryType1: + return queryType1(ctx, path[1:], req, keeper) + + case QueryType2: + return queryType2(ctx, path[1:], req, keeper) + + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0]) + } + } +} +``` + +This simple switch returns a `querier` function specific to the type of the received `query`. At this point of the [query lifecycle](../interfaces/query-lifecycle.md), the first element of the `path` (`path[0]`) contains the type of the query. The following elements are either empty or contain arguments needed to process the query. + +The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result. + +For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/gov/keeper/querier.go) from the bank module. + +## Next {hide} + +Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md) {hide} From 03e4c56de53938ccbf025a441e54b9842f7c4544 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 11:38:14 +0200 Subject: [PATCH 34/41] Revert "Update old ref of RegisterQueryService" This reverts commit 1ea1ea8559604d5c0aa13951b3016967438da2a5. --- docs/basics/app-anatomy.md | 2 +- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/module-manager.md | 4 ++-- types/module/module.go | 4 ++-- x/auth/module.go | 2 +- x/auth/vesting/module.go | 2 +- x/bank/module.go | 2 +- x/capability/module.go | 2 +- x/crisis/module.go | 2 +- x/distribution/module.go | 2 +- x/evidence/module.go | 2 +- x/gov/module.go | 2 +- x/ibc/applications/transfer/module.go | 2 +- x/ibc/core/module.go | 2 +- x/ibc/testing/mock/mock.go | 2 +- x/mint/module.go | 2 +- x/params/module.go | 2 +- x/slashing/module.go | 2 +- x/staking/module.go | 2 +- x/upgrade/module.go | 2 +- 20 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index ffd56017c1b7..cd8cf18e77b5 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -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 `RegisterServices` 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 `RegisterQueryService` 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 diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 45aa11cbb9c4..74b7c7ac38f9 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -52,7 +52,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 `RegisterServices` 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 `RegisterQueryService` method from the [`AppModule` interface](./module-manager.md#appmodule). ### Legacy Queries diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index ae31a6329057..1c034bde7157 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -72,7 +72,7 @@ Let us go through the methods of `AppModule`: - `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`. -- `RegisterServices(Configurator)`: Allows a module to register services. +- `RegisterQueryService(grpc.Server)`: Allows a module to register a gRPC query service. - `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. @@ -135,7 +135,7 @@ The module manager is used throughout the application whenever an action on a co - `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). -- `RegisterServices(cfg Configurator)`: Registers all module gRPC query services. +- `RegisterQueryServices(grpcRouter grpc.Server)`: Registers all module gRPC query 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. diff --git a/types/module/module.go b/types/module/module.go index f149fd5f3739..ec9c1c77b5d3 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -166,10 +166,10 @@ type AppModule interface { // routes Route() sdk.Route - // Deprecated: use RegisterServices + // Deprecated: use RegisterQueryService QuerierRoute() string - // Deprecated: use RegisterServices + // Deprecated: use RegisterQueryService LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier // RegisterServices allows a module to register services diff --git a/x/auth/module.go b/x/auth/module.go index 85971d18651f..21e43bef262b 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -125,7 +125,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.accountKeeper, legacyQuerierCdc) } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/auth/vesting/module.go b/x/auth/vesting/module.go index bea4d3946867..b4997d60e4bd 100644 --- a/x/auth/vesting/module.go +++ b/x/auth/vesting/module.go @@ -100,7 +100,7 @@ func (am AppModule) Route() sdk.Route { // functionality. func (AppModule) QuerierRoute() string { return "" } -// RegisterServices performs a no-op. +// RegisterQueryService performs a no-op. func (am AppModule) RegisterServices(_ module.Configurator) {} // LegacyQuerierHandler performs a no-op. diff --git a/x/bank/module.go b/x/bank/module.go index 02615c464820..1b3d68f4607d 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -94,7 +94,7 @@ type AppModule struct { accountKeeper types.AccountKeeper } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/capability/module.go b/x/capability/module.go index 1e84a6f13cca..cc1d6272eb0f 100644 --- a/x/capability/module.go +++ b/x/capability/module.go @@ -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 } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(module.Configurator) {} diff --git a/x/crisis/module.go b/x/crisis/module.go index 67a074bd7165..fdc2ffb03d6f 100644 --- a/x/crisis/module.go +++ b/x/crisis/module.go @@ -112,7 +112,7 @@ func (AppModule) QuerierRoute() string { return "" } // LegacyQuerierHandler returns no sdk.Querier. func (AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(module.Configurator) {} diff --git a/x/distribution/module.go b/x/distribution/module.go index addc416f2a10..9c53d5619170 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -139,7 +139,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/evidence/module.go b/x/evidence/module.go index 620db7f6eee7..1ac32c2148b7 100644 --- a/x/evidence/module.go +++ b/x/evidence/module.go @@ -148,7 +148,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/gov/module.go b/x/gov/module.go index 1187fedc4680..31c0e5c05d80 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -155,7 +155,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/ibc/applications/transfer/module.go b/x/ibc/applications/transfer/module.go index b92aaa676bd4..4d73f693cd2a 100644 --- a/x/ibc/applications/transfer/module.go +++ b/x/ibc/applications/transfer/module.go @@ -120,7 +120,7 @@ func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/ibc/core/module.go b/x/ibc/core/module.go index 032ee755a751..35a734ccf959 100644 --- a/x/ibc/core/module.go +++ b/x/ibc/core/module.go @@ -130,7 +130,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return nil } -// RegisterServices registers the gRPC query service for the ibc module. +// RegisterQueryService registers the gRPC query service for the ibc module. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryService(cfg.QueryServer(), am.keeper) } diff --git a/x/ibc/testing/mock/mock.go b/x/ibc/testing/mock/mock.go index 25bc5e953ede..89ed2a4dd468 100644 --- a/x/ibc/testing/mock/mock.go +++ b/x/ibc/testing/mock/mock.go @@ -102,7 +102,7 @@ func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } -// RegisterServices implements the AppModule interface. +// RegisterQueryService implements the AppModule interface. func (am AppModule) RegisterServices(module.Configurator) {} // InitGenesis implements the AppModule interface. diff --git a/x/mint/module.go b/x/mint/module.go index c9ed5f01e8ff..0a29598add2c 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -123,7 +123,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a gRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/params/module.go b/x/params/module.go index 2dd7967b16aa..b95f76947ddb 100644 --- a/x/params/module.go +++ b/x/params/module.go @@ -109,7 +109,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a gRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/slashing/module.go b/x/slashing/module.go index e644b87a1cd6..f74c4a84dfd2 100644 --- a/x/slashing/module.go +++ b/x/slashing/module.go @@ -137,7 +137,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) diff --git a/x/staking/module.go b/x/staking/module.go index 860d717e64f1..6a344265b74a 100644 --- a/x/staking/module.go +++ b/x/staking/module.go @@ -133,7 +133,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { querier := keeper.Querier{Keeper: am.keeper} diff --git a/x/upgrade/module.go b/x/upgrade/module.go index bf467340f201..df5e23a2f4f2 100644 --- a/x/upgrade/module.go +++ b/x/upgrade/module.go @@ -94,7 +94,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterServices registers a GRPC query service to respond to the +// RegisterQueryService 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) From 5ad70f40a81c43e8399a55a9fb659d9110ae61b6 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 12:14:13 +0200 Subject: [PATCH 35/41] Update keeper.md --- docs/building-modules/keeper.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 1fecb6152146..71042f2a7ec2 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -40,7 +40,7 @@ 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 `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`, that can be any of `codec.BinaryMarshaler`,`codec.JSONMarshaler` or `codec.Marshaler` based on your requirements. +- 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. It can be either a proto or amino codec as long as they implement these interfaces. 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. @@ -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`. Then it's prefered 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. @@ -68,11 +68,17 @@ 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`. +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 prefered to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety. 2. Marshall `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/3bafd8255a502e5a9cee07391cf8261538245dfd/x/staking/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). + +The [module `KVStore`](../core/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: + ++++ https://github.com/cosmos/cosmos-sdk/blob/bf8809ef9840b4f5369887a38d8345e2380a567f/x/auth/keeper/account.go#L70-L83 ## Next {hide} From 9201a1ae2510c3f668b68a2aa0654526f61765ba Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 12:31:02 +0200 Subject: [PATCH 36/41] Update handler.md --- docs/building-modules/handler.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index e394cb5ed207..1e88d830df5a 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -79,6 +79,10 @@ Next is an example of how to return a `*Result` from the `gov` module: 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 + ## Next {hide} Learn about [query services](./query-services.md) {hide} From 9d156fabb252bf98ef224d24c888406abf5b7bfd Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 13:51:37 +0200 Subject: [PATCH 37/41] Update handler.md --- docs/building-modules/handler.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 1e88d830df5a..45e9a4c11944 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -83,6 +83,14 @@ The `handler` can then be registered from [`AppModule.Route()`](./module-manager +++ 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} From e8d68581da570d12280c9f2c86bcbe53a9d2bb91 Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 14:07:37 +0200 Subject: [PATCH 38/41] Update messages-and-queries.md --- docs/building-modules/messages-and-queries.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 74b7c7ac38f9..71390449812e 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -75,6 +75,15 @@ The `path` for each `query` must be defined by the module developer in the modul - [Query commands](./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://golang.org/pkg/fmt/#Stringer). +### Store Queries + +Store queries query directly for store keys. They use `clientCtx.QueryABCI(req abci.RequestQuery)` to return the full `abci.ResponseQuery` with inclusion Merkle proofs. + +See following examples: + ++++ https://github.com/cosmos/cosmos-sdk/blob/080fcf1df25ccdf97f3029b6b6f83caaf5a235e4/x/ibc/core/client/query.go#L36-L46 + ++++ https://github.com/cosmos/cosmos-sdk/blob/080fcf1df25ccdf97f3029b6b6f83caaf5a235e4/baseapp/abci.go#L722-L749 ## Next {hide} From 6ef1db392736f42bfab3c8184bdaf38892f43135 Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Wed, 14 Oct 2020 14:28:31 +0200 Subject: [PATCH 39/41] Update docs/basics/app-anatomy.md Co-authored-by: Amaury Martiny --- docs/basics/app-anatomy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index cd8cf18e77b5..529ec9b27567 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -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/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`: +[`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 From bd20a7222bce25d159fc0c877a4e64367d3deb50 Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Wed, 14 Oct 2020 14:30:10 +0200 Subject: [PATCH 40/41] Update docs/building-modules/intro.md Co-authored-by: Amaury Martiny --- docs/building-modules/intro.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index e0c94d60ba4a..7b3a4c3faa5e 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -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 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 [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). @@ -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} - From 1d0253909e766543ce8c7c103a39e9efbf54845f Mon Sep 17 00:00:00 2001 From: blushi Date: Wed, 14 Oct 2020 14:30:48 +0200 Subject: [PATCH 41/41] Fix typo --- docs/building-modules/keeper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 71042f2a7ec2..5c57faef1fe5 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -69,7 +69,7 @@ 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`. Then it's prefered to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety. -2. Marshall `value` to `[]byte` using the codec `cdc`. +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/3bafd8255a502e5a9cee07391cf8261538245dfd/x/staking/keeper/keeper.go).